読者です 読者をやめる 読者になる 読者になる

ほわいとぼーど

ぷろぐらまのメモ帳

fabricでProxyを解決したりメモ

fabric

fabricのroleで試行錯誤した話もそうですが最近Fabricを少し触ってるのでその辺りのメモ。


①proxy経由でfabricする

"bundle installしたらプロキシに阻まれて失敗したので会社辞めます。"が話題になりましたが、、
ご多分にもれず私の現在の職場環境もProxyがかまされていて、
「Vagrantとか使う上ではまるProxyの話」とか、
Elasticsearchのplugin入れるのにjohtaniさんのブログ参考にしたりとか、
日々格闘しているわけですが、fabricももちろん例外ではありません。

fabricの場合、sshを使うのでssh_configを利用します。
ssh_configをfabricから使うには環境変数env.use_ssh_config=Trueにします。
、、、が!、env.use_ssh_configが使えるのversion 1.4からでした。
手元で試していたUbuntu12.04preciseではapt-get install fabricするとversion 1.3.2が入ります。
いきなり挫折してしまいました。

@shiumachiさんの記事@ymotongpooさんの記事を読んだにも関わらず、
virtualenvやらpipやらを入れる辺りで挫折してしまい(うぅ、、、) 追記:解決しました。
最終的にkuchitamaさんの記事を見て

wget https://raw.github.com/pypa/pip/master/contrib/get-pip.py
python get-pip.py

で何とかpipが入り、fabricも最新version?の1.8を入れることが出来ました。
ちなみにpipはapt-getとパスが異なる(/usr/bin/pip⇔/usr/local/bin/pip)みたいなのでパスを通す必要があります。
fabricも/usr/local/bin/fabに入りますね。

あとはssh_configにproxycommand使ってproxy指定すればいいのですが、
今度はコレにはまりました。
要はproxycommandを適用する部分のソースをtypoしているみたいです。
現時点ではプルリクがまだ取り込まれていないようなので、 (1.8.2でなおったみたいです
Issueを見ながら/usr/local/lib/python2.7/dist-packages/fabric/netowrk.pyの中を修正、

-        sock = ssh.proxycommand(proxy_command)
+        sock = ssh.ProxyCommand(proxy_command)

これでproxy経由でfabricできるようになりました。
ちなみにproxycommand使えるのはfabric 1.5からみたいです。


ssh_config使用時のdisconnectバグ?
何故かたまに実行自体は終わってるのに制御が戻ってこない時があります。
どこかでIssueを見た気がするのですが今は忘れてしまいました。
ssh_config使用時のdisconnectの部分に問題があるようなのですが、
これは@parallelの時は起きない事に気づいたので、
最終コマンドにechoみたいな何でもないコマンドを入れて@parallel実行するという方法でしのぎ中。
完全なるバッドノウハウですね・・・


③パスワード入力

sshする時にenv.passwordを設定しないと実行時にプロンプトで聞かれることになりますが
(pty=Falseだと聞かれないかも??)
@parallelしていると順番保障できない旨のメッセージが出ます。

Fatal error: Needed to prompt for a connection or sudo password (host: host.example.com), but input would be ambiguous in parallel mode

そこで、自分でパスワード入力を受けて内部で設定することにします。
というかしないとsudoの度にパス入力必要ですね。
promptを使えば入力を受け付けれますが、これだとパスワードが画面上で丸見えなので、
pythongetpassを使いました。

import getpass

def _login():
    prompt('Enter the user: ', 'login_user')
    env.user = env.login_user
    env.password = getpass('Enter the password: ')

上記のメソッドをenv設定するメソッドの中で呼んでます。
が、結局、今のところ自分しか使わないプログラムだったのでenv.passwordしました。。。
開発時ということで後で戻すはず、多分。



他にも細々色々あった気がするがとりあえず。
・色つけるメソッドがあることに気づいたり
・fabric分割するならfabfileってディレクトリ作って、、、みたいなのよく見るけど、
 普通にファイル分割して単純にimportするだけでも使えた
とか。


逆に課題という意味では、
順番を制御したい時には前回の記事の最後の@parallelのようなことができず、
各ノード向けのメソッドを作らなきゃならないのが冗長で悩んでいる。

あと、UbuntuにPPAというレポジトリがあることを今日知ったので、
これを試したらapt-getでもいけたのかもしれないとか。まだ試してませんが。

まだまだ使いこなすには程遠いですね。