Fabric は Python で書かれたデプロイやオペレーションを自動化するためのツール。 Fabric では、タスクと呼ばれるオペレーション内容も Python で書く。
今回は、普段ならコマンドラインツールから使うことが多い Fabric を Python のスクリプトに組み込んで使う方法について書く。 尚、Fabric はリモートのホストに接続して使うことが多いため、そのホストとして Vagrant を使って Ubuntu 16.04 LTS のマシンを用意した。
使った環境は次の通り。
$ sw_vers ProductName: Mac OS X ProductVersion: 10.11.6 BuildVersion: 15G1004 $ python --version Python 2.7.10
インストール
まずは pip を使って Fabric をインストールしておく。
$ pip install fabric
Vagrant で仮想マシンを用意する
ここでは Vagrant がすでにインストール済みであることを想定する。 もし、入っていないときは公式サイトのバイナリか Homebrew Cask などを使ってインストールしてほしい。
まずは Vagrant の設定ファイル (Vagrantfile) を用意する。 イメージは Chef 社の提供する bento リポジトリにあるものを使った。
$ cat << 'EOF' > Vagrantfile # -*- mode: ruby -*- Vagrant.configure("2") do |config| config.vm.box = "bento/ubuntu-16.04" config.vm.provider "virtualbox" do |vb| vb.cpus = "2" vb.memory = "1024" end end EOF
仮想マシンを起動する。
$ vagrant up
起動できたら vagrant ssh-config コマンドを実行しよう。 ここで Port の項目を確認しておく。 おそらく通常は 2222 が割り振られているはず。 ただ、異なる場合には後述する手順で指定するポート番号を変更する必要がある。
$ vagrant ssh-config Host default HostName 127.0.0.1 User vagrant Port 2222 UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile /Users/amedama/Documents/vagrant/ubuntu1604/.vagrant/machines/default/virtualbox/private_key IdentitiesOnly yes LogLevel FATAL
これは OpenSSH の設定ファイルと同じフォーマットになっている。 上記の設定から、先ほど Vagrant で作った仮想マシンには 127.0.0.1:2222 に SSH することでログインできることがわかる。
さて、これで Fabric を使う対象となる仮想マシンの準備ができた。
Fabric の設定ファイルを用意する
Fabric はデフォルトで fabfile という名前のモジュール (またはパッケージ) を、タスクが記述された処理対象として扱う。 なので fabfile.py という名前でファイルを用意しよう。 Python ではスクリプトファイル (*.py) とモジュールが 1:1 で対応している。 例えば fabfile.py であれば Python インタプリタはそれを fabfile というモジュールとして扱うということ。
それでは、今回の主役となる fabfile.py を用意する。 これには task() 関数として Fabric のタスクが定義されている。 この task() 関数はリモートのホスト上で、通常ユーザ権限を使って uptime コマンドを実行することを示している。 また、main() 関数では task 関数を引数にして execute() 関数を実行することもわかる。
$ cat << 'EOF' > fabfile.py #!/usr/bin/env python # -*- coding: utf-8 -*- from fabric.api import run from fabric.api import execute def task(): run('uptime') def main(): execute(task, hosts=['vagrant@127.0.0.1:2222']) if __name__ == '__main__': main() EOF
普段の使い方
Fabric がインストールされていると fab コマンドが使えるようになる。 この fab コマンド経由でタスクを実行するのが Fabric の普段の使い方だ。
先ほど用意した fabfile.py も fab コマンド経由で実行してみよう。 -H オプションでホスト名、--port オプションでポート名、-u オプションでユーザ名を指定する。 最後の引数は実行するタスク名だ。 仮想マシンのログインパスワードを聞かれるので「vagrant」答えよう。
$ fab -H localhost --port 2222 -u vagrant task [localhost] Executing task 'task' [localhost] run: uptime [localhost] Login password for 'vagrant': [localhost] out: 10:46:20 up 6 min, 1 user, load average: 0.00, 0.05, 0.02 [localhost] out: Done. Disconnecting from localhost:2222... done.
上手く実行できた。
Python スクリプトとして実行する
先ほどは fab コマンドからタスクを実行した。 今度は Python スクリプトからタスクを実行してみよう。
これは、ただ単に python コマンドで fabfile.py ファイルを実行するだけだ。 先ほどと同じようにログインパスワードを聞かれるので「vagrant」と答える。
$ python fabfile.py [vagrant@127.0.0.1:2222] Executing task 'task' [vagrant@127.0.0.1:2222] run: uptime [vagrant@127.0.0.1:2222] Login password for 'vagrant': [vagrant@127.0.0.1:2222] out: 10:48:08 up 8 min, 1 user, load average: 0.00, 0.03, 0.01 [vagrant@127.0.0.1:2222] out:
ちゃんと実行できたことがわかる。
実行した fabfile.py の内容をもう一度掲載しておく。 Python スクリプトとして実行したときは、この中の main() 関数が実行される。 そして、その中では execute() 関数にタスクとログイン名、ホスト名、ポート番号を指定していた。 つまり、組み込みで実行したいときはこの execute() 関数を使えば良いということが分かる。
#!/usr/bin/env python # -*- coding: utf-8 -*- from fabric.api import run from fabric.api import execute def task(): run('uptime') def main(): execute(task, hosts=['vagrant@127.0.0.1:2222']) if __name__ == '__main__': main()
環境を設定する
先ほどの例ではパスワードを手動で入力しなければいけなかった。 今度は、そこも自動化してみよう。
次の fabfile.py ではパスワードの手動入力が不要になっている。 ホスト名やユーザ名、パスワードといった Fabric の環境設定は fabric.api.env を指定すれば良い。
$ cat << 'EOF' > fabfile.py #!/usr/bin/env python # -*- coding: utf-8 -*- from fabric.api import run from fabric.api import execute from fabric.api import env def task(): run('uptime') def main(): env.hosts = ['127.0.0.1:2222'] env.user = 'vagrant' env.password = 'vagrant' execute(task) if __name__ == '__main__': main() EOF
実行してみよう。
$ python fabfile.py [127.0.0.1:2222] Executing task 'task' [127.0.0.1:2222] run: uptime [127.0.0.1:2222] out: 10:48:44 up 8 min, 1 user, load average: 0.00, 0.03, 0.00 [127.0.0.1:2222] out:
ちゃんと実行できて、今度はパスワードを聞かれることもない。
まとめ
Fabric を Python スクリプトに組み込んで使うときは fabric.api.execute() 関数を使おう。
追記
このやり方にはちょっとした注意点があるため、次の記事で補足している。
スマートPythonプログラミング: Pythonのより良い書き方を学ぶ
- 作者: もみじあめ
- 発売日: 2016/03/12
- メディア: Kindle版
- この商品を含むブログを見る