Python
fabric

Fabricの利用時のまとめ

現在見ているシステムでのFabric導入にあたっての調査まとめ。公式ドキュメントを参考にして記載。色々できることはあるようですがシンプルにしないと引き継ぎ出来ないので以下くらいで。
試したバージョンは以下の通り。

  • Python 3.6.1
  • Fabric3 1.13.1.post1
  • Paramiko 2.2.1

シンプルな実行は以下の形式で実行

fab -f ファイル名 -H ホスト名 -u ユーザ名 実行メソッド

例:fab -f fab_test.py -H 192.168.1.10 -u ubuntu task_name

基本の記載内容

fab_test.py
from fabric.api import *

def task_name():
  run("whoami")
  sudo("whoami")
  with cd("/tmp"):
    run("pwd")

コマンドの内容

get

ファイルを対象のサーバからローカルにコピーする。成功かどうかは戻り値の.succeededで確認。.failedは失敗した場合のファイルパスのリストが格納される模様。

get("リモートサーバのパス","ローカルのパス")
r = get('/home/foo/hoge', './')
print(r.succeeded) # => Trueなら成功。Falseなら失敗
print(r.failed)

put

ファイルをローカルから対象サーバにコピーする。

put('ローカルサーバのパス','リモートサーバのパス')
r = put('./hoge',"/home/foo")
print(r.succeeded) # => Trueなら成功。Falseなら失敗

local

ローカルサーバでコマンドを実行する。

local("pwd")

run

リモートサーバでコマンドを実行する。実行するユーザはアクセスしたユーザ。

run("whoami")

sudo

sudoしてコマンドを実行する。アクセスしたユーザにsudo権限がない場合は失敗する。

sudo("whoami")

下記の通り記載することで実行ユーザを指定することも可能。

with settings(sudo_user='mysql'):
    sudo("whoami") # prints 'mysql'

open_shell

リモートサーバのシェルに移行してコマンドを実行する。そのまま対話型に移動。

open_shell("ls")

prompt

ユーザからのプロンプトからの入力を受け付ける。バリデーションもできる模様。int型は文字列を入力したところ、Exceptionが発生したので、正規表現でバリデーションをしたほうが良さそう。

r = prompt("run command ?")
run(r)

# With validation, i.e. requiring integer input:
prompt('Please specify process nice level: ', key='nice', validate=int)

# With validation against a regular expression:
release = prompt('Please supply a release name',
        validate=r'^\w+-\d+(\.\d+)?$')

with cd("XX"): または with prefix("YY"):

cd XX && または YY &&を全コマンドの前につける。prefixの前にsu - をつけるのはだめだったため、前述のsettingsを使うこと。

with cd("/etc"):
  run("cat hosts")

with prefix("cd /etc"):
  run("cat hosts")

色付け

以下のように記載することで色を付けることができる。成功とか失敗とかを色付けすればわかりやすそう。Teratermで色がつくかは要検証。

from fabric.colors import *

print(red("This sentence is red, except for " +   
        green("these words, which are green") + "."))

色は以下の通り。

  • fabric.colors.blue(text, bold=False)
  • fabric.colors.cyan(text, bold=False)
  • fabric.colors.green(text, bold=False)
  • fabric.colors.magenta(text, bold=False)
  • fabric.colors.red(text, bold=False)
  • fabric.colors.white(text, bold=False)
  • fabric.colors.yellow(text, bold=False)

ロール

対象のロールのサーバにだけメソッドを実行する。

from fabric.api import env

env.roledefs = {
    'web': ['192.168.1.10', '192.168.1.11', '192.168.1.12']
}

@roles('web')
def restart_nginx():
  sudo("service nginx restart ")

実行は以下の通り。上記ではメソッドの前に@roles('web')を記載しているため、実行時に-R webが省略できる。

fab -f 実行ファイル [-R ロール ] task
fab -f fab_test.py -u ubuntu restart_nginx

結果がエラーになることを確認する

手順中に"ファイルがなくなっていること"という手順があり、手作業でやったときと同じようにスクリプトを作ったらそこで停止してしまった。
下記のようにwarn_only=Trueをいれることで回避できる。

with settings(warn_only=True):
  result = sudo("ls -l /not/found/path")

[他の参考になりそうなサイト]
https://blog.masu-mi.me/2015/04/11/fabric_tips.html

http://perezvon.hatenablog.com/entry/20091026/1256552181