dput (sftp) + inotify = FAIL
내부적으로 사용하는 apt 저장소에서는 dput이 incoming으로 올린 데이터를 crontab 을 이용해서 실제 배포용 디렉터리에 복사하고 / .db 업데이트하고 / … 등을 처리하게 했다.
crontab을 써서 사실 상 polling하는 구조가 맘에 안들어서, linux의 inotify를 이용해서 이걸 우회하려고 지난 주 후반부에 뭔가 진행해봤다. 대략 chroot jail에 sftp만 허용한 계정을 만들고 여기에 대해서 upload를 감지하자는거였는데 대략 다음과 같이 진행했다.
- scp로 업로드한 파일을 inotify가 인지하고 이에 대해서 처리하는 코드 테스트 (정상 작동)
- sftp 로 업로드한 파일에 대해선 inotify가 인지못하고 crontab이 처리
- ?!?!?!
3의 대혼란.
intoify를 래핑한 inoticoming 를 사용했는데, 코드를 까보니 주석처리된 디버깅 코드가 있더라; 이걸 주석해제하고 돌려보니 아뿔사 -_-
scp와 sftp를 순차적으로 썼을 때 inoticoming이 호출한 inotify에 걸린 이벤트는 아래와 같다. 1
rein@rein:~/inoticoming-0.2.2/build$ ./inoticoming --foreground /tmp/test --suffix .changes echo {} \;
File ready: python-stdeb_0.6.0+git-1_all.deb
File ready: stdeb_0.6.0+git-1_amd64.changes
Will call action echo for: stdeb_0.6.0+git-1_amd64.changes
stdeb_0.6.0+git-1_amd64.changes
File ready: python-stdeb_0.6.0+git-1_all.deb.tmp.1338036938.225992918.7760.688775960
File ready: stdeb_0.6.0+git-1_amd64.changes.tmp.1338036944.455483913.7760.1022155507
dput이 sftp를 통해 업로드할 때 대략 다음과 같은 일을 한다: 2
- 위에서 나온 임시 파일 형식으로 파일 업로드; bzrlib/transport/sftp.py:SFTPTransport._put
- 업로드가 끝나면 임시 파일을 실제 이름으로 link + 임시 파일 unlink; bzrlib/osutils.py:fancy_rename
그래서 inotify는 이걸 인지할 방법이 없다.
대략 chroot jail에서 scp만 허용하는 쪽으로 바꿔야 할 것 같다. 아니면 dput 말고 딴 걸 쓰거나; 근데 내가 왜 sftp만 허용하는 걸 생각했는지 기억이 나질 않는다 Orz.