SVN 에서 받아 서버로 올리는 배포 스크립트를 만들면서 대상을 인자로 받게 했다. 인자를 안 주고 실행했는데 아무 말 없이 돌았다. 그 대상이 운영 서버였다.
Table of contents
Open Table of contents
기본값이 운영이었다
스크립트 앞부분에서 인자가 없으면 운영을 쓰게 돼 있었다.
TARGET=${1:-prod}
만들 때는 대개 운영에 배포하니까 그게 편하겠다고 생각했다. 그런데 이러면 시험할 때마다 대상을 붙여야 하고 안 붙이면 운영으로 간다.
실수했을 때 가는 방향이 위험한 쪽이면 그 실수는 언젠가 사고가 된다.
기본값을 안전한 쪽으로 바꿨다
기본값을 시험 서버로 바꿨다. 이러면 인자를 빠뜨렸을 때 시험 서버로 가고 되돌리기 쉽다.
기본값을 아예 안 두는 방법도 있다. 셸에는 ${1:?...} 가 있다. 인자가 없으면 그 문구를 내고 그 자리에서 죽는다.
TARGET=${1:?"사용법: deploy.sh <dev|prod>"}
$ ./deploy.sh
deploy.sh: line 2: 1: 사용법: deploy.sh <dev|prod>
매번 적어야 해서 조금 번거롭지만 헷갈릴 여지가 없다. 같은 이유로 맨 위에 set -u 도 넣었다. 오타로 만든 빈 변수가 조용히 지나가지 않는다.
지우고 나면 못 되살리는 것에만 확인을 붙였다
운영으로 갈 때는 read 로 한 번 물어보게 했다. 대답을 한 글자가 아니라 deploy prod 처럼 여러 글자로 받는다. 습관적으로 엔터를 치는 것을 막으려는 것이다.
스크립트 안의 동작을 원래대로 돌릴 수 있는지로 나눠 봤다.
| 동작 | 되돌리기 |
|---|---|
rsync 파일 복사 | 이전 파일이 있으면 가능 |
| Tomcat 재시작 | 가능 |
| MySQL 스키마 변경 | 어려움 |
rsync --delete 로 옛 파일 삭제 | 불가 |
뒤의 둘에만 확인을 붙였다. 전부에 붙이면 확인이 많아져서 읽지 않고 넘기게 된다.
rsync 에는 -n 이 있다. 붙이면 옮기지 않고 무엇을 옮길지만 낸다. 운영으로 갈 때는 -n 을 먼저 돌려 목록을 보고 나서 진짜를 돌린다.
crontab 에서 부를 때는 물어보는 자리에서 멈춘다. 입력이 없으니 read 가 영원히 기다린다. 확인을 건너뛰는 인자를 따로 두고 자동 실행에서만 붙이게 했다.
[ -t 0 ] 으로 가르는 방법도 있다. 표준 입력이 터미널이면 참이고 파이프나 crontab 이면 거짓이다. 이쪽이 인자를 안 붙여도 되지만, 붙이는 쪽이 어느 경로로 도는지 눈에 남는다.
실행 전 출력과 기록
실행하기 전에 무엇을 할지 먼저 출력하게 했다. 대상과 소스 경로와 SVN 리비전과 배포 경로를 찍는다. 리비전은 svnversion 으로 얻는다.
대상 : prod (10.0.0.31)
소스 : /home/dev/adsvc
리비전 : 1284
배포 경로: /var/www/adsvc
여기서 prod 라는 글자를 보고 멈출 수 있다. 확인 문구만 있고 무엇을 하는지 안 보이면 확인의 의미가 적다. 배포는 ssh 로 붙어 rsync 를 돌리고 Tomcat 을 다시 띄우는 순서다.
그래도 실수는 난다. 무엇을 했는지 기록을 남겼다.
2011-12-16 21:14:02 dev1 prod rev=1284
2011-12-17 22:03:41 dev1 dev rev=1285
문제가 생겼을 때 언제 무엇이 나갔는지 본다. 없으면 기억에 의존하게 된다. logger 로 syslog 에도 같이 남겼다. 스크립트가 지워져도 그쪽은 남는다.
정리
- 기본값이 위험한 쪽이면 실수 한 번이 사고가 된다
- 기본값을 안전한 쪽으로 두거나
${1:?}로 아예 안 둔다 set -u를 켜면 오타로 만든 빈 변수가 조용히 지나가지 않는다- 되돌릴 수 없는 동작에만 확인을 붙인다
- 전부에 붙이면 읽지 않고 넘기게 된다
- 확인 입력은 한 글자보다 여러 글자가 낫다. 습관적 입력을 막는다
- crontab 에서는
read가 영원히 기다린다. 건너뛰는 길을 따로 둔다 [ -t 0 ]으로 터미널인지 갈라도 된다- 실행 전에 무엇을 할지 출력한다. 확인 문구만 있으면 의미가 적다
- 무엇을 했는지 기록을 남긴다. 없으면 기억에 의존한다