先日、複数台のサーバに設定を投入しないといけない事案が発生した。 システムを運用していると頻繁にあるけど、そういう時は台数がすくなければ sshで入って…台数がおおければシェルスクリプトを書いてpscpでそれを撒いてpsshで実行していた。
しかし、シェルスクリプトで書いてしまうとその場限りのものになってしまって、 再利用性が低く構造化しづらかったのでfabricを使ってみた。 (こういうことはpuppetやChefなどの構成管理ツールを使えって話だけど、 使えたら使っている のでそこら辺はお察しください)
fabricを選んだのは、同僚でありpythonistaな @laughk先生 が 布教活動をしていて使い方をある程度知っていたのと、何かあればすぐ聞けるっていう理由なのであったw fabricの使い方とかはググってください。。
以下に、私がfabricを導入したときにこれどうするんだろ?ってなった時の解決策をメモっておく。
1. ssh_configを使う
デフォルトではssh_configは参照されない。
~/.fabricrc に以下の設定を書くとssh_configを参照するようになる。
use_ssh_config = True
ちなみに、スクリプトの中で env.use_ssh_config = True しても同じことができる。
2. 出力するテキストにprefixをつける
デバッグなどをする時にテキストを出力したい時がある。
そういうときは fabric.utils.puts 使えばよい。
from fabric.utils import puts def hoge: puts("hoge")
printの場合
$ fab -H test1,test2 hoge [test1] Executing task 'hoge' hoge [test2] Executing task 'hoge' hoge Done.
putsの場合
[test1] Executing task 'hoge' [test1] hoge [test2] Executing task 'hoge' [test2] hoge Done.
3. 出力に色を付ける
fabric.colors に色を付けるための関数が用意されている。
例えば、赤を出力するなら以下の様な感じ
from fabric.utils import puts from fabric.colors import * def hoge: puts(red("赤"))
赤以外にも、 blue, cyan, green, magenta, white, yellowがある
see. Color output functions — Fabric documentation
4. コマンドの出力や戻り値を取る
run や sudo の結果の戻り値にコマンドの出力や戻り値が含まれている。
res = run("uname -a") して print res するとコマンドの出力が表示される。
コマンドの出力結果は改行毎にsplitされてArrayに入っている。
また、コマンドの戻り値は res.return_code に入っていて、
コマンドが成功している場合 res.succeeded がTrueになり res.failed がFalseになる。
5. コマンドの出力を無視して実行する
基本的にコマンドの実行結果がエラーになるとfabricはその時点でタスクの実行をやめる。
例えば、差分が前提でdiffを実行した場合エラーになってしまう。
diff ~~ || true とかすればいいのだけど、それはちょっとダサいので以下のようにする。
from fabric.api import settings do hoge: with settings(warn_only=True): run("diff hoge hige")
warn_only=Trueしない場合
$ cat fabfile.py
from fabric.api import run
def hoge():
run("/bin/false")
$ fab -H test1 hoge
[test1] Executing task 'hoge'
[test1] run: /bin/false
Fatal error: run() received nonzero return code 1 while executing!
Requested: /bin/false
Executed: /bin/bash -l -c "/bin/false"
Aborting.
warn_only=Trueする場合
$ cat fabfile.py
from fabric.api import settings,run
def hoge():
with settings(warn_only=True):
run("/bin/false")
$ fab -H test1 hoge
[test1] Executing task 'hoge'
[test1] run: /bin/false
Warning: run() received nonzero return code 1 while executing '/bin/false'!
Done.
6. 5にあわせてwarningメッセージも無視する
warn_only=True だけだと、warningメッセージが出力される。
コマンドが失敗することがわかっているのであれば、以下のように書くと便利。
from fabric.api import quiet do hoge: with quiet(): run("diff hoge hige")
実行例
$ cat fabfile.py
from fabric.api import quiet,run
def hoge():
with quiet():
run("/bin/false")
$ fab -H test1 hoge
[test1] Executing task 'hoge'
Done.
別のやり方
戻り値がわかっているなら以下のように書くこともできる。
from fabric.api import settings do hoge: with settings(ok_ret_codes=[0,1]): run("diff hoge hige")
7. デフォルトタスクを定義する
通常、コマンドラインからタスク名を指定しないと実行できないが、 デフォルトのタスクを定義することができる。
from fabric.api import task @task(default=True) def hoge: pass
8. タスクに説明を書く
fab --list でタスク一覧を表示できる。
タスクにコメントを書いておくと、その時にコメントの内容を表示できる。
def hoge: ''' ほげほげ ''' # 1行コメントは表示されないよー pass
実行例
$ fab --list
Available commands:
hoge ほげほげ
だいたいこんな感じ。 また何かあったら追記しよう。