fabric2いいかも
最近になって「fabricで作業の自動化を増やしたい」と思うことがありました。 調べてみたらPython3対応されたfabricはfabric2として独立していました。そしてfabric2を待ちきれずにフォークされたfabric3はメンテされている様子はありません。 正解はfabric2です。
fabric2はfabricと違いinvokeのssh拡張がついたラッパーなようです。 使うにあたりConfig, Connection, Groupの違いを確認したりしました。 また気楽なタスクランナーとして使うためにヘルパーやパターンが出てきたのでメモします。
実験した残骸はここに残してます。
pkg | version |
---|---|
fabric2 | 2.6.0 |
Python | 3.8.5 |
基本的なこと
したのように今まで通り @task デコレーターでタスクを登録します。引数は invoke.config.Config です。
|
|
タスク名は関数名の_
を-
に置き換えたものみたいです。
|
|
invoke.config.Config は invoke.runners.Runner を実装しているため c.run(“hostname”) のように外部コマンドを呼び出せます。 この Config は関数なのでさっきの例のように他のタスクから呼び出せます。引数は invoke.config.Config です。 fabric2で実行ホストは次の2つの場所で指定できます。 1つはPythonスクリプトの中です。もう1つはコマンド呼び出し時の -H フラグです。
fabric.Connection.Connection は Config であり Runner です。 そのためさっきの例のように他のタスクを呼び出すときに渡したり、 run メソッドで特定ホストでコマンド実行できます。
フラグについてです。 fab2 コマンドの -H オプションでホスト名が渡されない場合は invoke.config.Config です。 そのためローカルホストで直接実行されます。 -H でホスト名を , 区切りで与えると全てのタスクに各ホスト名に対応した fabric.connection.Connection が渡されます。
ちなみに -H を使って複数ホストを指定した fab2 -H host1,host2 other_task_1 other_task_2
の動きは下のようなタスクの動きと一致します。
|
|
この Connection は invoke.runners.Runner なので run() が使えますが他にも forward_local や forward_remote という便利メソッドを提供しています。
fabric を使う動機として複数ホストでのコマンド実行があります。そのために fabric.group.Group という Runner があります。 これには SerialGroup, Threading.Group が準備されています。つぎのように使います。
|
|
fabric.group.Group を使うことで柔軟な作業フローを設計できます。
注意するところとしては fabric.group.Group は faric.connection.Connection のコレクションであって invoke.config.Config を継承していないところです。そのためタスクに渡すことはできません。
invoke.runners.Runner ではあるのでさっきの例の tg.run("ip r")
のように使うことはできます。
どうすると管理しやすいか悩んでいます。とりあえず Runner を渡す関数と呼び出すタスクを分離することにしました。
ほかにはfabric.transfer.Transferというファイル転送に使えるクラスがいます。
タスクランナーで補足的なこと
- 作業記録を取る
- teeパッケージを使う teeパッケージのPython3対応
- 複数のコンテキストマネージャをまとめるヘルパーを準備する
- Serverspecの出力を色付きにする
- 手動確認を入れる
作業記録を取る
with 使って標準出力をログに残しておく。Python3ではバッファリング0はできないので buff=1
を与えておく。
|
|
StdoutTee, StderrTee と2つのコンテキストマネージャを同時に使うのでヘルパークラスを書くと楽です。
|
|
Serverspecの出力を色付きにする
Serverspecなどのコマンドツールはptyを有効にしないとカラー出力してくれません。
pty=True
フラグを使うことで解決できます。しかし tee.Tee を使っているとランタイムエラーになります。
なので、その場合は with の外側で実行する。
|
|
手動確認を入れる
次のようなヘルパー関数を準備すると楽できそうです。
|
|
おしまい
Goユーザーだしmageどうかなと少し調べました。 mageはRakeのような開発を支援するローカルで使われることを意図していてFabricの代わりには向かなそうでした。 また外部コマンドをたくさん呼ぶタスクランナーはシングルバイナリにして安定するということも少ないので無理して選ぶ必要は感じませんでした。
最近、会社の人たちにここが補足され公式読めよくらいのメモだったりを書くの迷ったりしましたがサブタイトル通り書いて覚える整理するが目的なので気にしないことにしました。