sftpserverモジュールをforkしていじった件
諸事情によりテスト用のsftpサーバーが必要になったのでsftpserverなるモジュールを見つけてきた。しかしこいつシングルスレッドなので、やりたいことのためにはmultiprocessingと併用する必要があったわけなんだけど、そうするとなんかエラーが出る。
raise AssertionError("PID check failed. RNG must be re-initialized after fork().
Hint: Try Random.atfork()")
で調べてみたところそのものズバリのエラーで困ってる人がいた。
python - multiprocess module with paramiko - Stack Overflow
どうやらparamikoのバグらしい。paramikoのforkで、pure python実装なsshモジュールだとこの問題は解決済みらしい。
ちなみにpyftpdlibはFTPSには対応しているけれど、SFTPには対応してないとのことだったので諦めた。issueに「SFTPにも対応しないの?」みたいなのもあったけど、「pyftpdlibがやるようなことじゃない」って蹴られてたので多分今後もそういう方向には行かないと思う。
あと、pyFileSystemというものがSFTPに対応していたので使ってみたけど、こいつもparamiko依存なので同じエラーが出る。
で、仕方がないのでforkしてちょこっと改良した。
kk6/sftpserver at spike · GitHub
変更点
今にして思えばデーモン化はちょっと余計だった気がしてpull-requestは飛ばしてない
テストで使う
unittestのsetupで、こんな感じでmultiprocessingと併用して立ち上げてやる
def setUp(self): from sftpserver import start_server from multiprocessing import Process args = (HOST, PORT, KEYFILE, 'DEBUG') self._process = Process(target=start_server, args=args) self._process.start() def tearDown(self): self._process.terminate()