ライブラリ: Fabric

Python のパッケージである Fabric をご紹介したいと思います。

import fabric

Fabric とは

Fabric はいわゆる「デプロイツール」と言われるもののひとつで、 ssh での一連の処理を自動化するためのライブラリです。 Python らしいかんたんなインタフェースとなっており、比較的スムーズに使いはじめることができるのが特徴です。 同種のツールとしては Ruby の Capistrano があります。

公式ページには次のように紹介されています。

Fabric is a Python (2.5-2.7) library and command-line tool for streamlining the use of SSH for application deployment or systems administration tasks.

It provides a basic suite of operations for executing local or remote shell commands (normally or via sudo) and uploading/downloading files, as well as auxiliary functionality such as prompting the running user for input, or aborting execution.

意訳すると次のような感じになるでしょうか。

Fabric は Python (2.5-2.7) のライブラリで SSH を使いやすくするしてくれるコマンドラインツールです。アプリケーションのデプロイやシステム管理のために使うものです。

ローカル・リモートでのシェルコマンドの実行(通常のものと sudo 付きのもの)やファイルのアップロード・ダウンロードのための基本的な処理のセットを提供します。ユーザからの入力受付のためのプロンプトや処理の中断などの補助的な機能もあわせて提供します。

私が思う Fabric を使うことのメリットは次のとおりです。

  • 基本的なシェルコマンドを知っていれば全体の流れは Python 上で書ける
  • 分岐やループ処理がかんたん
  • 例外・エラーの処理がかんたん
  • 準備がかんたん: ローカルで fabric をインストールすればすぐに使い始められる

では基本的な使い方をかんたんにご紹介していきます。

インストール

まずはパッケージをインストールする必要があります。記事執筆時点の私の Mac 環境では pip だけでかんたんにインストールできました。

$ pip install fabric

Fabric で Hello World

では最初の Hello World をしてみましょう。 基本的な流れとしては、まずは fabfile.py をカレントディレクトリに作成して、その中の処理を fab コマンド呼び出す、という形になります。

まずは以下のコードを fabfile.py に保存しましょう。

# coding: utf-8
from fabric.api import local, run

# ホスト名を指定
# 複数個渡せばそのそれぞれに対して同じ処理が実行される
env.hosts = ['your_host_name']

def hello_world():
    # ローカル環境で echo を実行
    local('echo "Hello, world"')
    # リモート環境で echo を実行
    run('echo "Hello, world"')

つづいて fab コマンドでこちらを実行します。

$ fab hello_world

fab コマンドはこの fabric が提供するコマンドで、カレントディレクトリの fabfile.py の中の関数をコマンドラインから呼び出す機能を提供します。

上記のコマンドを実行するとまず最初にローカル環境で Hello, world がエコーされ、つづいてリモートホスト your_host_name 上で Hello, world がエコーされます。リモートに接続する際には通常の SSH が開始されるときの処理が自動的に走ります。パスワードで入る設定の場合にはパスワード入力のプロンプトが現れ 公開鍵で入る設定の場合にはそのまま SSH 接続が確立されます。

fabfile.py 内の関数は引数を受け取ることもできます。

def hello(name):
    # ローカル環境で echo を実行
    local('echo "Hello, {}"'.format(name))
    # リモート環境で echo を実行
    run('echo "Hello, {}"'.format(name))

引数に渡す値(文字列)を指定するには fab コマンドで関数名の後に「 : 」を付けてその後に渡します。

$ fab hello:japan

Fabric の基本的な関数

基本的な関数を覚えておけば、大体の処理は行うことができるかと思います。

  • local
  • run
  • lcd
  • cd
  • get
  • put
from fabric.api import local, run, lcd, cd, get, put

# ローカルでコマンドを実行
local('コマンド')

# リモートでコマンドを実行
result = run('コマンド')

# ローカルの特定のディレクトリでコマンドを実行
with lcd('ディレクトリ'):
    local('コマンド')

# リモートの特定のディレクトリでコマンドを実行
with cd('ディレクトリ'):
    result = run('コマンド')

# SFTP でリモートからローカルにファイルをコピー
get('リモートのパス', 'ローカルのパス')

# SFTP でローカルからリモートにファイルをコピー
put('リモートのパス', 'ローカルのパス')

## 処理を終了
abort('これ以上何もできません')

ファイルの存在チェックなども行えます。

from fabric.contrib import files
from fabric.api import abort

# filename ファイルがすでに存在すれば処理を中断して終了する
if files.exists(filename):
    abort('File {} already exists'.format(filename))

以上です。

参考