概要
fabric は Python 製のデプロイツールです
簡単に言うとパラレルでシェルを実行することができるツールです
Ruby でいうところの Capistrano です
今回はインストールから簡単なサンプルを実行するところまでやってみました
環境
- macOS 10.13.5
- Python 3.6.5
- fabric 2.1.3
インストール
- pip3 install fabric
サンプル集
いろいろと実行してみます
サーバへのアクセスは ID/PW 認証を想定しています
とりあえず SSH してコマンド実行
- vim first.py
from fabric import Connection
conn = Connection("root@172.28.128.3", connect_kwargs = { "password": "xxxxxxxx" })
result = conn.run('uname -s')
print(result)
いきなりポイントですが認証情報を fabric のコード上に記載する場合は connect_kwargs
オプションを使います
fabric1 では env
を使うらしいのですが、fabric2 では使えません
代わりに Connection
のインスタンスを生成する際に引数で指定します
ここで渡した connect_kwargs の dict はそのまま paramiko.client.SSHClient.connect
のオプションとして扱われます
また、ホスト情報とユーザ情報だけは connect_kwargs には含めず、Connection の第一引数で指定します
connect_kwargs 側で指定すると
ValueError: Refusing to be ambiguous: connect() kwarg 'hostname' was given both via regular arg and via connect_kwargs!
というエラーになります
ファイルをアップロードする
- vim upload.py
from fabric import Connection
conn = Connection("root@172.28.128.3", connect_kwargs = { "password": "xxxxxxxx" })
result = conn.put("./first.py", remote="/tmp/first.py")
print(result)
これまたポイントですが remote 側はディレクトリを指定するだけではアウトです
IOError が発生します
ちゃんと remote 側で配置するファイル名まで指定しましょう
シェルスクリプトを実行する
- vim shell.py
- chmod 755 test.sh
from fabric import Connection
conn = Connection("root@172.28.128.3", connect_kwargs = { "password": "xxxxxxxx" })
result = conn.put("./test.sh", remote="/tmp/test.sh", preserve_mode = True)
result = conn.run("/tmp/test.sh")
print(result)
事前に権限を変更しておきます
そして preserve_mode = True
を指定することでローカルの権限情報を引き継いでリモートにコピーします
False にすると実行権限がなくなり実行できません
また、fabric2 では内部的に SFTP を使っているようです
preserve_mode = True
でアップロード後に False にして再度実行しても権限はなくならないので、ターゲットサーバ上のファイルを一度削除してから再度アップロードしてください
テンプレートファイルアップロード
どうやら upload_template
は fabric2 では使えないようです
エラーハンドリング
- vim error.py
from fabric import Connection
from invoke import UnexpectedExit
conn = Connection("root@172.28.128.3", connect_kwargs = { "password": "xxxxxxxx" })
try:
ret = conn.run("hoge")
print(ret)
except UnexpectedExit as e:
print(e)
UnexpectedExit を except する必要があります
fabric2 はステータスが 0 以外の場合エラーを発生させます
それを回避するためには上記のような対応をする必要があるようです
単純にコマンドでエラーになった場合は特に不要な処理だと思います
最後に
fabric2 に入門してみました
Web 上にはまだまだ fabric 1 系の情報が多いようです
機能的にも fabric1 のほうが豊富な印象です
API が全く互換していないので 1 系のドキュメントは役に立ちません
Python3 で動かしたい場合は fabric2 を使うしかないですが、そうでない場合にはまだ移行は微妙かもしれないです
2 系へのアップグレードに関してはこちらが参考になると思います
0 件のコメント:
コメントを投稿