コンテキストマネージャー¶
コンテキストマネージャーは with とともに使用します。
注釈
Python 2.5の利用時、 with ステートメントを利用するためにはfabfileを from __future__ import with_statement から始める必要があります(Python 2.6以上では通常の非 non __future__ 機能です)。
注釈
ダイレクトにネストされている複数の with ステートメントを使用する場合、1つのwithステートメント内に複数のコンテキスト表現を用いたほうが便利なことがあります。次のように書く代わりに:
with cd('/path/to/app'):
with prefix('workon myvenv'):
run('./manage.py syncdb')
run('./manage.py loaddata myfixture')
次のように書くことができます:
with cd('/path/to/app'), prefix('workon myvenv'):
run('./manage.py syncdb')
run('./manage.py loaddata myfixture')
このようにするにはPython 2.7以上が必要です。Python 2.5もしくは2.6では次のようにします:
from contextlib import nested
with nested(cd('/path/to/app'), prefix('workon myvenv')):
...
最後に settings は nested 自身を実装していることに留意してください。詳しくはこのAPIドキュメントをご覧ください。
-
fabric.context_managers.cd(path)¶ コンテキストマネージャーはリモート操作を呼び出すときにはディレクトリの状態を維持します。
これでラップされたブロック内の
run、sudo、get、putへのどんな呼び出しも、実際に状態が維持されているという意味を持たせるために"cd <path> && "がプリフィックスされたのと似た文字列を暗に含みます。cdの利用はこうしたすべての実行に影響を与えるので、contribセクションの多くなど、うした操作を行うコードもまたcdの利用に影響を受けます。実際のシェルビルトインの
cdのように、cdは相対パスで呼び出すことができ(最初のディレクトリのデフォルトはリモートユーザーの$HOMEであることに気をつけてください)、ネストすることも可能です。下の例はシェルの
cdを使った "ノーマルな" 試みで、runもしくはsudoの実行と実行の間の状態が維持 されない というシェルなしSSH接続の実装のため動作しません。run('cd /var/www') run('ls')
上の例は
/var/wwwではなく、リモートユーザーの$HOMEのコンテンツの一覧を表示します。cdとともに使うと期待通りに動作します:with cd('/var/www'): run('ls') # Turns into "cd /var/www && ls"
最後に、ネストの例(インラインのコメントをご覧ください)をお見せします:
with cd('/var/www'): run('ls') # cd /var/www && ls with cd('website1'): run('ls') # cd /var/www/website1 && ls
注釈
このコンテキストマネージャーは環境変数のカレントの値、
env.cwdに追加することによって実装されています(そして、いつものようにその後もとの状態にもどします)。とは言え、この実装は将来的には変更されるかもしれませんので、手動でenv.cwdに変更することはおすすめしません。後方互換性を保証するのはcdの 挙動 のみです。注釈
空白文字を含むディレクトリ名を扱うため、空白文字は自動的にエスケープされます。
バージョン 1.0 で変更: コマンドでの操作に加え、
getとputにも適用されます。参考
-
fabric.context_managers.char_buffered(*args, **kwds)¶ ローカルターミナルの
パイプを行ごとではなく文字ごとに強制的にバッファします。ユニックスベースのシステムのみの適用されます。Windowsでは操作できません。
-
fabric.context_managers.hide(*args, **kwds)¶ 与えられた出力
groupsをFalseにセットするためにコンテキストマネージャー。groupsはoutputで定義された出力グループを命名している1つ以上の文字列でなければなりません。与えられたグループは、囲まれたブロックでの継続性のためFalseにセットされ、その後は前の状態に戻ります。例えば、 "[hostname] run:" のステータスラインを隠し、同じように標準出力と標準エラー出力を表示させないようにするには、次のように
hideを利用することができます:def my_task(): with hide('running', 'stdout', 'stderr'): run('ls /var/www')
-
fabric.context_managers.lcd(path)¶ ローカルのカレントワーキングディレクトリを更新するためのコンテキストマネージャー。
このコンテキストマネージャーは
cdと同じですが、別の環境変数(cwdではなくlcwd)を変更するので、localの実行とget/putへのローカルの引数のみに影響を与えます。相対パスの引数はローカルユーザーのカレントのワーキングディレクトリに対する相対になり、Fabric(もしくはFabricを使うコード)がどこで実行されるかによって違ってきます。これは os.getcwd で確認できます。fabfileが利用されている場所からの相対に固定すると便利かもしれません。それは env.real_fabfile で確認できます。
バージョン 1.0 で追加.
-
fabric.context_managers.path(path, behavior='append')¶ ラップされたコマンド実行するために使われるパスに与えられた
pathを追加します。これで囲まれたブロック内の
runもしくはsudoに対するどんな呼び出しも、与えられたコマンドの前に"PATH=$PATH:<path> "に似た文字列を暗黙のうちに追加されます。次のように、オプションの
behaviorキーワード引数を指定することによってpathの挙動をカスタマイズできます:'append': カレントの$PATHに与えられたパスを追加します。例えばPATH=$PATH:<path>です。これはデフォルトの挙動になります。'prepend': カレントの$PATHに与えられたパスを前に追加します。例えばPATH=<path>:$PATHです。'replace':$PATHの前の値を完全に無視します。例えばPATH=<path>となります。
注釈
このコンテキストマネージャーは、環境変数
env.pathとenv.path_behaviorのカレントの値を変更する(そしていつものようにその後に元に戻す)ように今は実装されています。しかし、この実装は将来的には変更されるかもしれないので直接手動で変更することはおすすめしません。バージョン 1.0 で追加.
-
fabric.context_managers.prefix(command)¶ 囲まれたすべての
run/sudoコマンドの前に、与えられたコマンドと&&を追加します。これは
cdとほとんど同一ですが、1つの文字列を変更する代わりにコマンド文字列のリストに、ネストされた呼び出しが追加されます。たいていの場合、シェル環境変数をエクスポートしたり変更するような、シェルの状態を変えるシェルスクリプトと一緒に使うといいでしょう。
例えば、このツールのもっとも一般的な利用方法の1つは virtualenvwrapper からの
workonコマンドと使うものです:with prefix('workon myvenv'): run('./manage.py syncdb')
上記の例では、実際のシェルコマンドの実行はこのようになります:
$ workon myvenv && ./manage.py syncdb
このコンテキストマネージャーは
cdと互換性があるので、もし自分の virtualenv がそのpostactivateスクリプトでcdできないときは次ようにもできます:with cd('/path/to/app'): with prefix('workon myvenv'): run('./manage.py syncdb') run('./manage.py loaddata myfixture')
これは、実行時には次のような結果になります:
$ cd /path/to/app && workon myvenv && ./manage.py syncdb $ cd /path/to/app && workon myvenv && ./manage.py loaddata myfixture
最後に、冒頭近くで示唆したように、
prefixはお好みのようにネストできます。例えば:with prefix('workon myenv'): run('ls') with prefix('source /some/script'): run('touch a_file')
結果:
$ workon myenv && ls $ workon myenv && source /some/script && touch a_file
不自然かもしれませんが、説明的だと思います。
-
fabric.context_managers.quiet()¶ settings(hide('everything'), warn_only=True)へのエイリアス。時折失敗が予期されるかつ/もしくは何も表示させたくない疑問形のリモートコマンドをラップするときに便利です。
例:
with quiet(): have_build_dir = run("test -e /tmp/build").succeeded
タスク内で使用されると、上記スニペットは
run: test -e /tmp/buildの行を生成せず、また、標準出力/標準エラー出力のまったく表示させず、コマンドの失敗は無視されます。参考
バージョン 1.5 で追加.
-
fabric.context_managers.remote_tunnel(*args, **kwds)¶ ローカルの開いているポートからリモートのターゲットにトンネルフォワーディングを作成します。
例えば、クライアントホストにインストールしてあるデータベースへリモートからアクセスさせます:
# Map localhost:6379 on the server to localhost:6379 on the client, # so that the remote 'redis-cli' program ends up speaking to the local # redis-server. with remote_tunnel(6379): run("redis-cli -i")
データベースは、クライアントホストからのみ接続可能なクライアント上にインストールされているとします(クライアント自身の 上に あるのとは対照的に):
# Map localhost:6379 on the server to redis.internal:6379 on the client with remote_tunnel(6379, local_host="redis.internal") run("redis-cli -i")
remote_tunnelは4個までの引き数を取ります:remote_port(必須)リッスンするリモートホストのポート。local_port(オプション) は接続するローカルのポートです。デフォルトはリモートのポートと同じポートです。local_host(オプション) は接続するローカルで到達可能なコンピュータ(DNS名かIPアドレス)です。デフォルトはlocalhostです(これはつまり、Fabricが動いているのと同じコンピュータのことです)。remote_bind_address(オプション) は、カレントターゲット上のリッスンするためにバインドするためのリモートのIPアドレスです。これはターゲット上のインターフェースに割り当てられたIPである必要があります(もしくはそうしたIPをリゾルブするDNS名)。すべてのインターフェースにバインドするには "0.0.0.0" を使います。
注釈
デフォルトでは、たいていのSSHサーバはリモートトンネルにローカルホストのインターフェース(127.0.0.1)をリッスンすることしか許可していません。こうしたケースでは
remote_bind_addressはサーバーによって無視され、トンネルは127.0.0.1だけをリッスンします。
-
fabric.context_managers.settings(*args, **kwargs)¶ コンテキストマネージャーをネストおよび/もしくは
env変数を上書きします。settingsには2つの目的があります:もっとも便利なのが、
envを与えられるどんなキーワード引き数、例えばwith settings(user='foo'):などで一時的に上書き更新できることです。元の値は、もしあればですが、withブロックが閉じられると戻されます。- キーワード引き数
clean_revertはsettings自身にとっては特別な意味を持ち(下記参照)、実行前に取り除かれます。
- キーワード引き数
加えて、 contextlib.nested を使うと、与えられたどんな非キーワード引き数でもネストできます。これは他のコンテキストマネージャーである必要がありますが、例えば
with settings(hide('stderr'), show('stdout')):などです。
これらの挙動は望めば同時に指定することも可能です。これがなぜ便利であるのかは例でわかりやすく説明します:
def my_task(): with settings( hide('warnings', 'running', 'stdout', 'stderr'), warn_only=True ): if run('ls /etc/lsb-release'): return 'Ubuntu' elif run('ls /etc/redhat-release'): return 'RedHat'
上のタスクは
run命令文を実行しますが、もしlsが失敗した場合に中断するのではなく警告を出し、その警告自身を含めたすべての出力はユーザーには表示されません。その結果としてこのシナリオでは、通常であれば発生するたくさんの出力を発生させずに、リモートホストがどのシステムのタイプなのかを呼び出しが判別することができる完全に静かなタスクとなります。したがって
settingsは、特定のレベルの出力を隠す(もしくは表示する)のとともに、もしくはコンテキストマネージャーとして実装された他のFabricの機能のひとつとともに、環境変数とのどんな組み合わせでもセットするために利用可能です。clean_revertがTrueにセットされると、settingsはネストされたブロック内で変更されたキーは 元には戻しません 。その代わり、与えられたときと同じ値を持つキーだけを元に戻します。さらに例をご覧になるとより理解できるでしょう。以下はsettingsの通常の動作です:# Before the block, env.parallel defaults to False, host_string to None with settings(parallel=True, host_string='myhost'): # env.parallel is True # env.host_string is 'myhost' env.host_string = 'otherhost' # env.host_string is now 'otherhost' # Outside the block: # * env.parallel is False again # * env.host_string is None again
env.host_stringの内部での変更は取り消されていますが、これが常に希望の状態であるとは限りません。ここでclean_revertの登場です:# Before the block, env.parallel defaults to False, host_string to None with settings(parallel=True, host_string='myhost', clean_revert=True): # env.parallel is True # env.host_string is 'myhost' env.host_string = 'otherhost' # env.host_string is now 'otherhost' # Outside the block: # * env.parallel is False again # * env.host_string remains 'otherhost'
clean_revert有効時にはsettingsの利用前にenvに存在しなかった新しいキーも保存されます。Falseの時はこうしたキーはブロック終了時に取り除かれます。バージョン 1.4.1 で追加:
clean_revertキーワード引数。
-
fabric.context_managers.shell_env(**kw)¶ ラップされたコマンドのためのシェル環境変数をセットします。
例えば、以下はPythonのZMQライブラリをインストールするときに関連する環境変数をどのようにセットするのかをお見せしています:
with shell_env(ZMQ_DIR='/home/user/local'): run('pip install pyzmq')
prefixと同様に、これは実質的にrunコマンドを以下に変更します:$ export ZMQ_DIR='/home/user/local' && pip install pyzmq
複数のキーバリューペアを同時に与えることができます。
注釈
Windowsのローカルホストから実行したときに
localの挙動に営業が出る場合、この機能の実装にはSETコマンドが使われます。
-
fabric.context_managers.show(*args, **kwds)¶ 与えられた出力
groupsをTrueにセットするためにコンテキストマネージャー。groupsはoutputで定義された出力グループを命名している1つ以上の文字列でなければなりません。与えられたグループは、囲まれたブロックでの継続性のためTrueにセットされ、その後は前の状態に戻ります。例えば、デバッグ出力を有効にします(デフォルトではたいていオフになっています):
def my_task(): with show('debug'): run('ls /var/www')
ほぼすべての出力グループがデフォルトでは表示されますが、通常は非表示になっている
debugグループをオンにしたり、ご自分のコードを呼び出すコードがhideで出力を隠そうとしていることを知っていたり疑っていたりする場合にshowはとても有用です。
-
fabric.context_managers.warn_only()¶ settings(warn_only=True)のエイリアスです。参考