Memo/Fabric
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
#contents
*Fabric [#cd1d4c02]
-[[Fabric:http://docs.fabfile.org/]]
--デプロイツール。sshの作業等を自動化できる。シェルスクリ...
--Python 2.5以上
--スクリプトはpython構文で書く
--[[Fabric Fabric 1.0 documentation:https://fabric_ja.re...
--[[Overview and Tutorial — Fabric 1.7 documentatio...
--[[Execution model — Fabric 1.7 documentation:http...
--[[Operations Fabric 1.7 documentation:http://docs.fabf...
-記事
--[[【30分で動かすシリーズ】Fabricでbash祭に対応してみる ...
--[[Tav's Blog Fabric Python with Cleaner API and Parall...
--[[fabfileの構造化 - logiqboard:http://d.hatena.ne.jp/fe...
--[[Python製デプロイツール Fabricを初めて使う際に役立つTi...
--[[Fabric デプロイツールのPythonicな書き方 - Ian Lewis:h...
--[[Python製デプロイツール Fabricを初めて使う際に役立つTi...
--[[Fabricを使ってリモートサーバーでコマンドを実行する - ...
--[[Chefに挫折したあなたへ。Fabricのすすめ:http://hozumi....
-参考ソース
--https://github.com/OpenMOOC/documentation/blob/master/s...
-類似ツール
--[[Puppet>Memo/Puppet]](ruby製) マニフェストを定義。状態...
--[[Chef:http://www.opscode.com/chef/]](ruby製)レシピを定...
----
**~/.ssh/configで多段sshの設定と、use_ssh_configを組み合...
~/.ssh/configで多段sshの設定と、use_ssh_configを組み合わ...
バグっぽい
-~/.ssh/config
#geshi(bash){{
Host gateway.example.com
ProxyCommand none
User gateway-user01
IdentityFile ~/.ssh/gateway.pem
Host target01.example.com
User user01
ProxyCommand ssh gateway.example.com nc %h %p 2> /dev/n...
IdentityFile ~/.ssh/id_rsa
}}
- fabric側 v1.8.0
#geshi(python){{
# -*- coding: utf-8 -*-
from fabric.api import *
from fabric.contrib.console import *
from pprint import pprint
@task
def multistage_ssh_test():
env.use_ssh_config = True
run('whoami')
}}
-実行
#geshi(bash){{
# localは大丈夫
fab multistage_ssh_test
# 多段sshは処理が終了しない
fab -u user01 -H target01.example.com multistage_ssh_test
}}
-対処
-- -gで明示的にgatewayを指定すると切断された
#geshi(bash){{
fab -u user01 -H target01.example.com -g gateway-user01@g...
}}
----
**fabricからスクリプトが起動しない場合 [#heb477aa]
fabricからシェルスクリプト等を実行する時、起動しないもの...
-nohupを付ける
#geshi(python){{
run("nohup my_script.sh")
}}
-仮想端末を割り当てる(pty=True)
#geshi(python){{
run("my_script.sh", pty=True)
}}
----
**fabtools [#idae6425]
-[[fabtools fabtools 0.18.0-dev documentation:http://fab...
-インストール
#geshi(bash){{
sudo pip install fabtools
}}
-yumパッケージのインストール
#geshi(bash){{
fabtools.rpm.install(['ntp'],options=['--quiet'])
}}
----
**実行時に処理が進まない場合 [#fb0ad61d]
-gateway側で操作ログをファイルに記録するために"script"コ...
--対処: ptyをデフォルトでは使わないようにする。(gateway側...
#geshi(bash){{
env.always_use_pty=False
}}
----
**gateway: 多段SSH [#e6304c99]
-[[fab options and arguments Fabric 1.8.2 documentation:...
-記事
--[[Fabricで多段ssh - チューリング不完全:http://aomoririn...
-env.gatewayを使うサンプル。
--localhost => gateway host => other host とssh接続して、...
--&attachref(gateway_test.py);
#geshi(bash){{
fab -f gateway_test.py gateway_test
}}
----
**env.roledefs/@roles : 環境別設定 [#v4edb69e]
-fabricのバージョンによって仕様が変わったのか、blog等の情...
- -R rolename オプションは、env.roledefs = {}を定義してい...
-記事
--[[Execution model Fabric 1.8.1 documentation:http://do...
-複数のサーバに特定の処理を実行(fabric 1.8.0)
--fabfile.py
#geshi(python){{
# -*- coding: utf-8 -*-
from fabric.api import *
env.roledefs = {
'web' : ['web01.example.com','web02.example.com'],
'db' : ['db01.example.com','db02.example.com'],
}
@task
def deploy():
pass
}}
-- webとdbにdeploy()を実行
#geshi(bash){{
$ fab -R web,db deploy
[web01.example.com] Executing task 'deploy'
[web02.example.com] Executing task 'deploy'
[db01.example.com] Executing task 'deploy'
[db02.example.com] Executing task 'deploy'
Done.
}}
-- webにだけdeploy()を実行
#geshi(bash){{
fab -R web deploy
[web01.example.com] Executing task 'deploy'
[web02.example.com] Executing task 'deploy'
Done.
}}
- 関数毎に環境を指定する(fabric 1.8.0)
--fabfile.py
#geshi(python){{
...
@task
@roles('web')
def deploy():
pass
}}
--roleを指定しないで実行するとwebホストにだけ実行される
#geshi(bash){{
fab deploy
[web01.example.com] Executing task 'deploy'
[web02.example.com] Executing task 'deploy'
Done.
}}
-- -R dbを指定しても、webホストに実行される
#geshi(bash){{
fab -R db deploy
[web01.example.com] Executing task 'deploy'
[web02.example.com] Executing task 'deploy'
Done.
}}
----
**@runs_onceデコレータ [#j24e0d4e]
-記事
--[[Decorators Fabric 1.8.1 documentation:http://docs.fa...
-スクリプト全体で1回実行される
----
**quiet() : エラーが発生した場合でも表示しない [#a37c01bb]
-通常、local(), run(), sudo()を実行するとコンソールに表示...
#geshi(python){{
@task
def test_quiet():
with quiet():
print local("test -e /tmp/build").succeeded # False
print local("test -e /tmp/build").failed # True
}}
----
**return_codeの取得 [#l1e570b3]
-local(), run(), sudo() で使える
#geshi(python){{
@task
def test_return():
print local('test -d /tmp', quiet=True, warn_only=Tru...
print local('test -d /tmp', quiet=True, warn_only=Tru...
}}
----
**環境変数の設定 [#wdcea51a]
-shell_env(name=value)で設定できる
#geshi(python){{
@task
def test_shell():
with shell_env(VAR1='hoge'):
print local('echo $VAR1') # hoge
print run('echo $VAR1') # hoge
}}
----
**with構文 [#oc4d44a3]
-python 2.5以上
-with構文に対応しているcd(), lcd(), shell_env()等は、環境...
#geshi(python){{
@task
def test_cd():
with cd('/tmp'):
run('pwd') # /tmp
}}
----
**文字列をbool型に変換 [#rb37fbbd]
-fabricのコマンドライン引数は文字列(str)になるため、ifの...
#geshi(python){{
import distutils
print distutils.util.strtobool("true") # 1: y, yes, t, t...
print distutils.util.strtobool("false") # 0: n, no, f, fa...
var1 = distutils.util.strtobool(var1) if isinstance(var1,...
}}
----
**公開鍵認証での接続 [#p50c14a9]
#geshi(python){{
def test():
env.use_ssh_config = True # ~/.ssh/configを参照する場合
env.user = "hoge"
env.key_filename = "/home/hoge/.ssh/id_rsa"
run("hostname -s")
}}
----
**Exception : エラーと例外 [#s233e5f8]
-[[8. エラーと例外 Python 2.7ja1 documentation:http://do...
#geshi(python){{
# -*- coding: utf8 -*-
from fabric.api import *
import logging
@task
def test():
try:
run("hostname -s")
raise Exception('foo bar')
except Exception, e:
logging.error("%s" % ( e.message ))
sys.exit(1)
}}
----
**logging : ログの出力 [#e0fee0da]
-[[ロギングクックブック Python 2.7ja1 documentation:http...
-コンソール(簡易)とファイル(詳細)に両方出力
#geshi(python){{
# -*- coding: utf8 -*-
from fabric.api import *
import logging
# ~/.fabricrc に log_filename=/tmp/fab.log 等を追加
def set_logging(filename=env.log_filename, level=logging....
try:
logger = logging.getLogger()
if logger.handlers:
for handler in logger.handlers:
logger.removeHandler(handler)
if filename != "":
logging.basicConfig(
filename=filename
, level=level
, format="%(asctime)s\t%(levelname)s\t%(m...
console = logging.StreamHandler()
console.setLevel(level)
formatter = logging.Formatter("%(asctime)s\t%(lev...
console.setFormatter(formatter)
logging.getLogger().addHandler(console)
except Exception, e:
sys.stderr.write(e.message)
@task
def test():
set_logging()
logging.debug('message') # level=logging.INFO なので...
logging.info('message')
logging.warning('message')
logging.error('message')
logging.critical('message')
}}
----
**env.hosts : ホストの指定 [#e1973101]
-例
--設定
#geshi(bash){{
vim ~/.fabricrc
----
servers=host1,host2
----
}}
--タスク
#geshi(python){{
# -*- coding: utf8 -*-
from fabric.api import *
@task
def test():
run("hostname -s")
@task
def test2():
""" パスワード指定 """
env.use_ssh_config = True
env.host_string="ssh.example.com"
env.user="foo"
env.password="bar"
run("hostname -s")
}}
- fab -H host1,host2 # env.hostsに値が入る
#geshi(bash){{
fab test -H host1,host2
}}
- env.hosts = ["host1","host2"] # 固定値のみで変数は使え...
#geshi(python){{
env.hosts = ["host1","host2"]
#env.hosts = env.servers.split(",") # ERROR: No hosts fou...
}}
- env.host_string # 1台だけ指定
#geshi(python){{
env.host_string="ssh.example.com"
}}
-@hosts : デコレータでは変数も使える
#geshi(python){{
@hosts(env.servers.split(","))
@task
def test():
run("hostname -s")
}}
-[[Using execute with dynamically-set host lists:http://d...
#geshi(python){{
def _test(arg1, arg2):
run("hostname -s")
@task
def test():
host_list=env.servers.split(",")
execute(_test, arg1="arg1", arg2="arg2", hosts=host_l...
}}
----
**fabricrc : 設定ファイル [#xc16003e]
-[[fab options and arguments Fabric 1.4 documentation:ht...
--ini書式。key=value。文字列のみ
-default: ~/.fabricrc, または -c fabricrc
#geshi(bash){{
vim ~/.fabricrc
----
user = hoge
----
fab show_env:user
hoge
}}
----
**env : 環境変数 [#a35ed6c4]
env.varname に対して、読み書き可能。省略時のデフォルトと...
env.newvar="value" のように新しい値も作成できる。~
envは辞書型
- '#'で注釈を入れた。環境:CentOS6.3 x86_64, fablic 1.8.0
#geshi(bash){{
vim fabfile.py
----
# -*- coding: utf8 -*-
from fabric.api import *
from pprint import pprint
@task
def show_env(key = ""):
if key == "":
pprint(env)
else:
print(env[key])
----
fab show_env
{'': True,
'abort_exception': None,
'abort_on_prompts': False,
'again_prompt': 'Sorry, try again.',
'all_hosts': [],
'always_use_pty': True,
'colorize_errors': False,
'combine_stderr': True,
'command': 'show_env',
'command_prefixes': [],
'command_timeout': None,
'connection_attempts': 1,
'cwd': '',
'dedupe_hosts': True,
'default_port': '22',
'disable_known_hosts': False,
'eagerly_disconnect': False,
'echo_stdin': True,
'exclude_hosts': [],
'fabfile': 'fabfile',
'forward_agent': False,
'gateway': None,
'hide': None,
'host': None, # hostname
'host_string': None, # 1台だけホストを指定
'hosts': [], # ["host1", "host2"] のように複数ホストを指...
'keepalive': 0,
'key_filename': None,
'lcwd': '',
'linewise': False,
'local_user': 'hoge',
'new_style_tasks': True,
'no_agent': False,
'no_keys': False,
'ok_ret_codes': [0],
'output_prefix': True,
'parallel': False,
'password': None,
'passwords': {},
'path': '',
'path_behavior': 'append',
'pool_size': 0,
'port': '22',
'rcfile': '/home/hoge/.fabricrc',
'real_fabfile': '/home/hoge/fabric/fabfile.py',
'reject_unknown_hosts': False,
'remote_interrupt': None,
'roledefs': {},
'roles': [],
'shell': '/bin/bash -l -c', # run(), local() で実行され...
'shell_env': {},
'show': None,
'skip_bad_hosts': False,
'ssh_config_path': '~/.ssh/config',
'sudo_prefix': "sudo -S -p '%(sudo_prompt)s' ",
'sudo_prompt': 'sudo password:',
'sudo_user': None,
'system_known_hosts': None,
'tasks': ['show_env'],
'timeout': 10,
'use_exceptions_for': {'network': False},
'use_shell': True,
'use_ssh_config': False, # True : ~/.ssh/config を使用する
'user': 'hoge', # ssh接続する時に使うユーザ名
'version': '1.8.0',
'warn_only': False} # タスク実行中に異常が起きた場合、中...
Done.
}}
----
**AssertionError [#ub25bf35]
-assert len(specs) == 1 and specs[0][0] == '=='
#geshi(bash){{
pip list
...
Exception:
Traceback (most recent call last):
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
status = self.run(options, args)
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
self.run_listing(options)
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
self.output_package_listing(installed_packages)
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
if dist_is_editable(dist):
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
req = FrozenRequirement.from_dist(dist, [])
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
assert len(specs) == 1 and specs[0][0] == '=='
AssertionError
}}
--解決方法 [[Assertion Error with pip list Issue #1093 ...
#geshi(bash){{
sudo pip install -U distribute
}}
----
**confirm: Yes/No確認 [#j0203aad]
-[[Console Output Utilities Fabric 1.8 documentation:htt...
-Yes/No確認を行う
#geshi(python){{
# -*- coding: utf-8 -*-
from fabric.api import *
from fabric.contrib.console import *
@task
def test_confirm():
if confirm("hoge", False):
print("yes")
else:
print("no")
}}
-実行
#geshi(bash){{
fab test_confirm
hoge [y/N] y
yes
}}
----
**prompt: ユーザ入力待ち [#u4488325]
-var1=prompt("message") でユーザ入力待ちになる
-source
#geshi(python){{
# -*- coding: utf-8 -*-
from fabric.api import *
@task
def create_file_in_prompt():
filename=prompt("Which file:");
run("touch /tmp/%s" % filename)
# vim: ts=4 sw=4 expandtab
}}
-run
#geshi(bash){{
fab create_file_in_prompt -H localhost
Which file: hoge
}}
----
**rootユーザで実行 [#m8a58925]
-事前に接続するユーザがsudoできるようにしておく必要がある
-sudo("command") : リモートでsudoしてcommandを実行
-from fabric.api import sudo が必要
-別ユーザ/グループで実行するには sudo("command", user='ap...
-source
#geshi(python){{
# -*- coding: utf-8 -*-
from fabric.api import *
@task
def create_file_in_tmp(filename):
sudo("touch /tmp/%s" % filename)
# vim: ts=4 sw=4 expandtab
}}
-run
#geshi(bash){{
fab create_file_in_tmp:filename=hoge -H localhost
}}
----
**関数と引数 [#pf82ea18]
-実行時に関数と引数を指定: fab command:arg1=val1,arg2=val...
-source
#geshi(python){{
# -*- coding: utf-8 -*-
from fabric.api import *
@task
def hello_world(message=""):
localhost('echo "Hello, world! %s"' % message);
# vim: ts=4 sw=4 expandtab
}}
-run
#geshi(bash){{
fab hello_world:message=hoge
Hello, world! hoge
}}
-パラメータに",","="を含む場合はエスケープが必要
#geshi(bash){{
fab hello_world:"bar\,foo"
Hello, world! bar,foo
}}
-python
-- print("message %s %s" % (arg1, arg2)) : メッセージを表示
-[[Core API > Operations:http://docs.fabfile.org/en/1.7/a...
-- local("command") : ローカルで実行
-- run("command") : リモートで実行
-- put("local path", "remote path") : ローカルファイルを...
-- get("remote path", "local paht") : リモートファイルを...
-- var1=prompt("message") : ユーザ入力待ち
-- sudo("command") : root または別ユーザで実行
-[[Core API > Utils:http://docs.fabfile.org/en/1.7/api/co...
-- abort(message)
-- error(message)
-- puts(message) : printのエイリアス
-- warn(message)
-[[Core API > Context Managers:http://docs.fabfile.org/en...
-- quiet() エラーが発生した場合でも表示しない
-- shell_env(**kw) :環境変数を設定する。shell_env(HOGE="h...
-- cd(path) :ローカルカレントディレクトリの変更。 with cd...
-- lcd(path) :リモートカレントディレクトリの変更。 with l...
-[[Contrib API > Console Output Utilities:http://docs.fab...
-- confirm(question, default=True) : [Yes/No] プロンプト...
-[[Contrib API > File and Directory Management:http://doc...
-- append(filename, text)
-- comment(filename, regex) : regexにマッチした行をコメン...
-- uncomment(filename, regex)
-- contains(filename, text) :ファイル中から文字列を探し、...
-- exists(path)
-[[Contrib API > Project Tools:http://docs.fabfile.org/en...
-- rsync_project(*args, **kwargs)
----
**clouddns:Python API binding to Rackspace Cloud DNS [#qd...
-https://github.com/rackerlabs/python-clouddns
-インストール
#geshi(bash){{
sudo pip install git+git://github.com/rackerlabs/python-c...
}}
----
**boto:A Python interface to Amazon Web Services [#sec38d...
-https://github.com/boto/boto
--[[boto: A Python interface to Amazon Web Services:http:...
-インストール
#geshi(){{
sudo pip install boto
}}
----
**@taskデコレータ [#f6a40766]
-関数の前に @task を付ける事でfab -lでタスク一覧として表...
-関数内の1行目のコメントがlistにも表示される
#geshi(bash){{
vim fabfile.py
----
# -*- coding: utf-8 -*-
from fabric.api import *
@task
def host_type() :
""" usage """
run('uname -s');
# vim: ts=4 sw=4 expandtab
----
fab -l
Available commands:
host_type usage
}}
-記事
--[[Fabricの階層化に使う @ task デコレータの挙動 - AtAsAt...
----
**git/svn無視ファイル [#ma230b36]
-svn
#geshi(bash){{
svn propedit svn:ignore .
----
*.pem
*.pyc
*.pyo
----
}}
-git
#geshi(bash){{
vim .gitignore
----
*.pem
*.pyc
*.pyo
----
}}
----
**再インストール/アップグレード [#mca0ffb8]
-アップグレード
#geshi(bash){{
sudo pip install fabric -U
# 1.7.0 => 1.8.0の場合
sudo pip install fabric paramiko pycrypto -U
}}
-再インストール
#geshi(bash){{
sudo pip install fabric -I
}}
----
**インストール [#l56b3c42]
----
***Raspbian 7.x [#s3a8bc64]
#geshi(bash){{
cat /etc/debian_version
7.1
python -V
Python 2.7.3
sudo aptitude update
sudo aptitude install python-pip python-dev gcc
sudo pip-2.7 install fabric fabtools fexpect
sudo pip-2.7 install -U distribute
}}
----
***CentOS 6.x [#d4c16bbb]
-CentOS 6.4 x86_64
#geshi(bash){{
yum install python python-devel python-setuptools --enabl...
easy_install pip
pip install fabric fabtools fexpect
pip list | grep -i fabric
Fabric (1.6.1)
# pip list で以下のエラーが出たが、fabricは動いている。
pip list
Traceback (most recent call last):
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
status = self.run(options, args)
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
self.run_listing(options)
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
self.output_package_listing(installed_packages)
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
if dist_is_editable(dist):
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
req = FrozenRequirement.from_dist(dist, [])
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
assert len(specs) == 1 and specs[0][0] == '=='
AssertionError
# 解決するには
sudo pip install -U distribute
}}
-テスト
-- localhostにsshでログインしてuname -sを実行
-- デフォルトファイルは fabfile.py
-- -f PATH: 別のpyファイルを指定する場合。
-- -H HOSTS : ホスト指定。カンマ区切りで複数ホストを指定...
-- -u USER : 接続ユーザ指定。指定しなければプロンプトが出る
-- -p PASSWORD : 接続パスワード
-- -i PATH : SSH private key file
#geshi(bash){{
vim fabfile.py
----
# -*- coding: utf-8 -*-
from fabric.api import *
@task
def host_type() :
""" usage """
run('uname -s');
# vim: ts=4 sw=4 expandtab
----
fab -H localhost host_type
out: Linux
fab list
Available commands:
host_type usage
}}
----
***CentOS 5.x [#f704a0b9]
- [[Memo/Python#a1abf210]] でpipを使えるようにする
-fabricのインストール
#geshi(bash){{
sudo yum install python26-paramiko
sudo pip2.6 install paramiko==1.10
sudo pip install fabric==1.8.1
}}
終了行:
#contents
*Fabric [#cd1d4c02]
-[[Fabric:http://docs.fabfile.org/]]
--デプロイツール。sshの作業等を自動化できる。シェルスクリ...
--Python 2.5以上
--スクリプトはpython構文で書く
--[[Fabric Fabric 1.0 documentation:https://fabric_ja.re...
--[[Overview and Tutorial — Fabric 1.7 documentatio...
--[[Execution model — Fabric 1.7 documentation:http...
--[[Operations Fabric 1.7 documentation:http://docs.fabf...
-記事
--[[【30分で動かすシリーズ】Fabricでbash祭に対応してみる ...
--[[Tav's Blog Fabric Python with Cleaner API and Parall...
--[[fabfileの構造化 - logiqboard:http://d.hatena.ne.jp/fe...
--[[Python製デプロイツール Fabricを初めて使う際に役立つTi...
--[[Fabric デプロイツールのPythonicな書き方 - Ian Lewis:h...
--[[Python製デプロイツール Fabricを初めて使う際に役立つTi...
--[[Fabricを使ってリモートサーバーでコマンドを実行する - ...
--[[Chefに挫折したあなたへ。Fabricのすすめ:http://hozumi....
-参考ソース
--https://github.com/OpenMOOC/documentation/blob/master/s...
-類似ツール
--[[Puppet>Memo/Puppet]](ruby製) マニフェストを定義。状態...
--[[Chef:http://www.opscode.com/chef/]](ruby製)レシピを定...
----
**~/.ssh/configで多段sshの設定と、use_ssh_configを組み合...
~/.ssh/configで多段sshの設定と、use_ssh_configを組み合わ...
バグっぽい
-~/.ssh/config
#geshi(bash){{
Host gateway.example.com
ProxyCommand none
User gateway-user01
IdentityFile ~/.ssh/gateway.pem
Host target01.example.com
User user01
ProxyCommand ssh gateway.example.com nc %h %p 2> /dev/n...
IdentityFile ~/.ssh/id_rsa
}}
- fabric側 v1.8.0
#geshi(python){{
# -*- coding: utf-8 -*-
from fabric.api import *
from fabric.contrib.console import *
from pprint import pprint
@task
def multistage_ssh_test():
env.use_ssh_config = True
run('whoami')
}}
-実行
#geshi(bash){{
# localは大丈夫
fab multistage_ssh_test
# 多段sshは処理が終了しない
fab -u user01 -H target01.example.com multistage_ssh_test
}}
-対処
-- -gで明示的にgatewayを指定すると切断された
#geshi(bash){{
fab -u user01 -H target01.example.com -g gateway-user01@g...
}}
----
**fabricからスクリプトが起動しない場合 [#heb477aa]
fabricからシェルスクリプト等を実行する時、起動しないもの...
-nohupを付ける
#geshi(python){{
run("nohup my_script.sh")
}}
-仮想端末を割り当てる(pty=True)
#geshi(python){{
run("my_script.sh", pty=True)
}}
----
**fabtools [#idae6425]
-[[fabtools fabtools 0.18.0-dev documentation:http://fab...
-インストール
#geshi(bash){{
sudo pip install fabtools
}}
-yumパッケージのインストール
#geshi(bash){{
fabtools.rpm.install(['ntp'],options=['--quiet'])
}}
----
**実行時に処理が進まない場合 [#fb0ad61d]
-gateway側で操作ログをファイルに記録するために"script"コ...
--対処: ptyをデフォルトでは使わないようにする。(gateway側...
#geshi(bash){{
env.always_use_pty=False
}}
----
**gateway: 多段SSH [#e6304c99]
-[[fab options and arguments Fabric 1.8.2 documentation:...
-記事
--[[Fabricで多段ssh - チューリング不完全:http://aomoririn...
-env.gatewayを使うサンプル。
--localhost => gateway host => other host とssh接続して、...
--&attachref(gateway_test.py);
#geshi(bash){{
fab -f gateway_test.py gateway_test
}}
----
**env.roledefs/@roles : 環境別設定 [#v4edb69e]
-fabricのバージョンによって仕様が変わったのか、blog等の情...
- -R rolename オプションは、env.roledefs = {}を定義してい...
-記事
--[[Execution model Fabric 1.8.1 documentation:http://do...
-複数のサーバに特定の処理を実行(fabric 1.8.0)
--fabfile.py
#geshi(python){{
# -*- coding: utf-8 -*-
from fabric.api import *
env.roledefs = {
'web' : ['web01.example.com','web02.example.com'],
'db' : ['db01.example.com','db02.example.com'],
}
@task
def deploy():
pass
}}
-- webとdbにdeploy()を実行
#geshi(bash){{
$ fab -R web,db deploy
[web01.example.com] Executing task 'deploy'
[web02.example.com] Executing task 'deploy'
[db01.example.com] Executing task 'deploy'
[db02.example.com] Executing task 'deploy'
Done.
}}
-- webにだけdeploy()を実行
#geshi(bash){{
fab -R web deploy
[web01.example.com] Executing task 'deploy'
[web02.example.com] Executing task 'deploy'
Done.
}}
- 関数毎に環境を指定する(fabric 1.8.0)
--fabfile.py
#geshi(python){{
...
@task
@roles('web')
def deploy():
pass
}}
--roleを指定しないで実行するとwebホストにだけ実行される
#geshi(bash){{
fab deploy
[web01.example.com] Executing task 'deploy'
[web02.example.com] Executing task 'deploy'
Done.
}}
-- -R dbを指定しても、webホストに実行される
#geshi(bash){{
fab -R db deploy
[web01.example.com] Executing task 'deploy'
[web02.example.com] Executing task 'deploy'
Done.
}}
----
**@runs_onceデコレータ [#j24e0d4e]
-記事
--[[Decorators Fabric 1.8.1 documentation:http://docs.fa...
-スクリプト全体で1回実行される
----
**quiet() : エラーが発生した場合でも表示しない [#a37c01bb]
-通常、local(), run(), sudo()を実行するとコンソールに表示...
#geshi(python){{
@task
def test_quiet():
with quiet():
print local("test -e /tmp/build").succeeded # False
print local("test -e /tmp/build").failed # True
}}
----
**return_codeの取得 [#l1e570b3]
-local(), run(), sudo() で使える
#geshi(python){{
@task
def test_return():
print local('test -d /tmp', quiet=True, warn_only=Tru...
print local('test -d /tmp', quiet=True, warn_only=Tru...
}}
----
**環境変数の設定 [#wdcea51a]
-shell_env(name=value)で設定できる
#geshi(python){{
@task
def test_shell():
with shell_env(VAR1='hoge'):
print local('echo $VAR1') # hoge
print run('echo $VAR1') # hoge
}}
----
**with構文 [#oc4d44a3]
-python 2.5以上
-with構文に対応しているcd(), lcd(), shell_env()等は、環境...
#geshi(python){{
@task
def test_cd():
with cd('/tmp'):
run('pwd') # /tmp
}}
----
**文字列をbool型に変換 [#rb37fbbd]
-fabricのコマンドライン引数は文字列(str)になるため、ifの...
#geshi(python){{
import distutils
print distutils.util.strtobool("true") # 1: y, yes, t, t...
print distutils.util.strtobool("false") # 0: n, no, f, fa...
var1 = distutils.util.strtobool(var1) if isinstance(var1,...
}}
----
**公開鍵認証での接続 [#p50c14a9]
#geshi(python){{
def test():
env.use_ssh_config = True # ~/.ssh/configを参照する場合
env.user = "hoge"
env.key_filename = "/home/hoge/.ssh/id_rsa"
run("hostname -s")
}}
----
**Exception : エラーと例外 [#s233e5f8]
-[[8. エラーと例外 Python 2.7ja1 documentation:http://do...
#geshi(python){{
# -*- coding: utf8 -*-
from fabric.api import *
import logging
@task
def test():
try:
run("hostname -s")
raise Exception('foo bar')
except Exception, e:
logging.error("%s" % ( e.message ))
sys.exit(1)
}}
----
**logging : ログの出力 [#e0fee0da]
-[[ロギングクックブック Python 2.7ja1 documentation:http...
-コンソール(簡易)とファイル(詳細)に両方出力
#geshi(python){{
# -*- coding: utf8 -*-
from fabric.api import *
import logging
# ~/.fabricrc に log_filename=/tmp/fab.log 等を追加
def set_logging(filename=env.log_filename, level=logging....
try:
logger = logging.getLogger()
if logger.handlers:
for handler in logger.handlers:
logger.removeHandler(handler)
if filename != "":
logging.basicConfig(
filename=filename
, level=level
, format="%(asctime)s\t%(levelname)s\t%(m...
console = logging.StreamHandler()
console.setLevel(level)
formatter = logging.Formatter("%(asctime)s\t%(lev...
console.setFormatter(formatter)
logging.getLogger().addHandler(console)
except Exception, e:
sys.stderr.write(e.message)
@task
def test():
set_logging()
logging.debug('message') # level=logging.INFO なので...
logging.info('message')
logging.warning('message')
logging.error('message')
logging.critical('message')
}}
----
**env.hosts : ホストの指定 [#e1973101]
-例
--設定
#geshi(bash){{
vim ~/.fabricrc
----
servers=host1,host2
----
}}
--タスク
#geshi(python){{
# -*- coding: utf8 -*-
from fabric.api import *
@task
def test():
run("hostname -s")
@task
def test2():
""" パスワード指定 """
env.use_ssh_config = True
env.host_string="ssh.example.com"
env.user="foo"
env.password="bar"
run("hostname -s")
}}
- fab -H host1,host2 # env.hostsに値が入る
#geshi(bash){{
fab test -H host1,host2
}}
- env.hosts = ["host1","host2"] # 固定値のみで変数は使え...
#geshi(python){{
env.hosts = ["host1","host2"]
#env.hosts = env.servers.split(",") # ERROR: No hosts fou...
}}
- env.host_string # 1台だけ指定
#geshi(python){{
env.host_string="ssh.example.com"
}}
-@hosts : デコレータでは変数も使える
#geshi(python){{
@hosts(env.servers.split(","))
@task
def test():
run("hostname -s")
}}
-[[Using execute with dynamically-set host lists:http://d...
#geshi(python){{
def _test(arg1, arg2):
run("hostname -s")
@task
def test():
host_list=env.servers.split(",")
execute(_test, arg1="arg1", arg2="arg2", hosts=host_l...
}}
----
**fabricrc : 設定ファイル [#xc16003e]
-[[fab options and arguments Fabric 1.4 documentation:ht...
--ini書式。key=value。文字列のみ
-default: ~/.fabricrc, または -c fabricrc
#geshi(bash){{
vim ~/.fabricrc
----
user = hoge
----
fab show_env:user
hoge
}}
----
**env : 環境変数 [#a35ed6c4]
env.varname に対して、読み書き可能。省略時のデフォルトと...
env.newvar="value" のように新しい値も作成できる。~
envは辞書型
- '#'で注釈を入れた。環境:CentOS6.3 x86_64, fablic 1.8.0
#geshi(bash){{
vim fabfile.py
----
# -*- coding: utf8 -*-
from fabric.api import *
from pprint import pprint
@task
def show_env(key = ""):
if key == "":
pprint(env)
else:
print(env[key])
----
fab show_env
{'': True,
'abort_exception': None,
'abort_on_prompts': False,
'again_prompt': 'Sorry, try again.',
'all_hosts': [],
'always_use_pty': True,
'colorize_errors': False,
'combine_stderr': True,
'command': 'show_env',
'command_prefixes': [],
'command_timeout': None,
'connection_attempts': 1,
'cwd': '',
'dedupe_hosts': True,
'default_port': '22',
'disable_known_hosts': False,
'eagerly_disconnect': False,
'echo_stdin': True,
'exclude_hosts': [],
'fabfile': 'fabfile',
'forward_agent': False,
'gateway': None,
'hide': None,
'host': None, # hostname
'host_string': None, # 1台だけホストを指定
'hosts': [], # ["host1", "host2"] のように複数ホストを指...
'keepalive': 0,
'key_filename': None,
'lcwd': '',
'linewise': False,
'local_user': 'hoge',
'new_style_tasks': True,
'no_agent': False,
'no_keys': False,
'ok_ret_codes': [0],
'output_prefix': True,
'parallel': False,
'password': None,
'passwords': {},
'path': '',
'path_behavior': 'append',
'pool_size': 0,
'port': '22',
'rcfile': '/home/hoge/.fabricrc',
'real_fabfile': '/home/hoge/fabric/fabfile.py',
'reject_unknown_hosts': False,
'remote_interrupt': None,
'roledefs': {},
'roles': [],
'shell': '/bin/bash -l -c', # run(), local() で実行され...
'shell_env': {},
'show': None,
'skip_bad_hosts': False,
'ssh_config_path': '~/.ssh/config',
'sudo_prefix': "sudo -S -p '%(sudo_prompt)s' ",
'sudo_prompt': 'sudo password:',
'sudo_user': None,
'system_known_hosts': None,
'tasks': ['show_env'],
'timeout': 10,
'use_exceptions_for': {'network': False},
'use_shell': True,
'use_ssh_config': False, # True : ~/.ssh/config を使用する
'user': 'hoge', # ssh接続する時に使うユーザ名
'version': '1.8.0',
'warn_only': False} # タスク実行中に異常が起きた場合、中...
Done.
}}
----
**AssertionError [#ub25bf35]
-assert len(specs) == 1 and specs[0][0] == '=='
#geshi(bash){{
pip list
...
Exception:
Traceback (most recent call last):
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
status = self.run(options, args)
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
self.run_listing(options)
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
self.output_package_listing(installed_packages)
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
if dist_is_editable(dist):
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
req = FrozenRequirement.from_dist(dist, [])
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
assert len(specs) == 1 and specs[0][0] == '=='
AssertionError
}}
--解決方法 [[Assertion Error with pip list Issue #1093 ...
#geshi(bash){{
sudo pip install -U distribute
}}
----
**confirm: Yes/No確認 [#j0203aad]
-[[Console Output Utilities Fabric 1.8 documentation:htt...
-Yes/No確認を行う
#geshi(python){{
# -*- coding: utf-8 -*-
from fabric.api import *
from fabric.contrib.console import *
@task
def test_confirm():
if confirm("hoge", False):
print("yes")
else:
print("no")
}}
-実行
#geshi(bash){{
fab test_confirm
hoge [y/N] y
yes
}}
----
**prompt: ユーザ入力待ち [#u4488325]
-var1=prompt("message") でユーザ入力待ちになる
-source
#geshi(python){{
# -*- coding: utf-8 -*-
from fabric.api import *
@task
def create_file_in_prompt():
filename=prompt("Which file:");
run("touch /tmp/%s" % filename)
# vim: ts=4 sw=4 expandtab
}}
-run
#geshi(bash){{
fab create_file_in_prompt -H localhost
Which file: hoge
}}
----
**rootユーザで実行 [#m8a58925]
-事前に接続するユーザがsudoできるようにしておく必要がある
-sudo("command") : リモートでsudoしてcommandを実行
-from fabric.api import sudo が必要
-別ユーザ/グループで実行するには sudo("command", user='ap...
-source
#geshi(python){{
# -*- coding: utf-8 -*-
from fabric.api import *
@task
def create_file_in_tmp(filename):
sudo("touch /tmp/%s" % filename)
# vim: ts=4 sw=4 expandtab
}}
-run
#geshi(bash){{
fab create_file_in_tmp:filename=hoge -H localhost
}}
----
**関数と引数 [#pf82ea18]
-実行時に関数と引数を指定: fab command:arg1=val1,arg2=val...
-source
#geshi(python){{
# -*- coding: utf-8 -*-
from fabric.api import *
@task
def hello_world(message=""):
localhost('echo "Hello, world! %s"' % message);
# vim: ts=4 sw=4 expandtab
}}
-run
#geshi(bash){{
fab hello_world:message=hoge
Hello, world! hoge
}}
-パラメータに",","="を含む場合はエスケープが必要
#geshi(bash){{
fab hello_world:"bar\,foo"
Hello, world! bar,foo
}}
-python
-- print("message %s %s" % (arg1, arg2)) : メッセージを表示
-[[Core API > Operations:http://docs.fabfile.org/en/1.7/a...
-- local("command") : ローカルで実行
-- run("command") : リモートで実行
-- put("local path", "remote path") : ローカルファイルを...
-- get("remote path", "local paht") : リモートファイルを...
-- var1=prompt("message") : ユーザ入力待ち
-- sudo("command") : root または別ユーザで実行
-[[Core API > Utils:http://docs.fabfile.org/en/1.7/api/co...
-- abort(message)
-- error(message)
-- puts(message) : printのエイリアス
-- warn(message)
-[[Core API > Context Managers:http://docs.fabfile.org/en...
-- quiet() エラーが発生した場合でも表示しない
-- shell_env(**kw) :環境変数を設定する。shell_env(HOGE="h...
-- cd(path) :ローカルカレントディレクトリの変更。 with cd...
-- lcd(path) :リモートカレントディレクトリの変更。 with l...
-[[Contrib API > Console Output Utilities:http://docs.fab...
-- confirm(question, default=True) : [Yes/No] プロンプト...
-[[Contrib API > File and Directory Management:http://doc...
-- append(filename, text)
-- comment(filename, regex) : regexにマッチした行をコメン...
-- uncomment(filename, regex)
-- contains(filename, text) :ファイル中から文字列を探し、...
-- exists(path)
-[[Contrib API > Project Tools:http://docs.fabfile.org/en...
-- rsync_project(*args, **kwargs)
----
**clouddns:Python API binding to Rackspace Cloud DNS [#qd...
-https://github.com/rackerlabs/python-clouddns
-インストール
#geshi(bash){{
sudo pip install git+git://github.com/rackerlabs/python-c...
}}
----
**boto:A Python interface to Amazon Web Services [#sec38d...
-https://github.com/boto/boto
--[[boto: A Python interface to Amazon Web Services:http:...
-インストール
#geshi(){{
sudo pip install boto
}}
----
**@taskデコレータ [#f6a40766]
-関数の前に @task を付ける事でfab -lでタスク一覧として表...
-関数内の1行目のコメントがlistにも表示される
#geshi(bash){{
vim fabfile.py
----
# -*- coding: utf-8 -*-
from fabric.api import *
@task
def host_type() :
""" usage """
run('uname -s');
# vim: ts=4 sw=4 expandtab
----
fab -l
Available commands:
host_type usage
}}
-記事
--[[Fabricの階層化に使う @ task デコレータの挙動 - AtAsAt...
----
**git/svn無視ファイル [#ma230b36]
-svn
#geshi(bash){{
svn propedit svn:ignore .
----
*.pem
*.pyc
*.pyo
----
}}
-git
#geshi(bash){{
vim .gitignore
----
*.pem
*.pyc
*.pyo
----
}}
----
**再インストール/アップグレード [#mca0ffb8]
-アップグレード
#geshi(bash){{
sudo pip install fabric -U
# 1.7.0 => 1.8.0の場合
sudo pip install fabric paramiko pycrypto -U
}}
-再インストール
#geshi(bash){{
sudo pip install fabric -I
}}
----
**インストール [#l56b3c42]
----
***Raspbian 7.x [#s3a8bc64]
#geshi(bash){{
cat /etc/debian_version
7.1
python -V
Python 2.7.3
sudo aptitude update
sudo aptitude install python-pip python-dev gcc
sudo pip-2.7 install fabric fabtools fexpect
sudo pip-2.7 install -U distribute
}}
----
***CentOS 6.x [#d4c16bbb]
-CentOS 6.4 x86_64
#geshi(bash){{
yum install python python-devel python-setuptools --enabl...
easy_install pip
pip install fabric fabtools fexpect
pip list | grep -i fabric
Fabric (1.6.1)
# pip list で以下のエラーが出たが、fabricは動いている。
pip list
Traceback (most recent call last):
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
status = self.run(options, args)
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
self.run_listing(options)
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
self.output_package_listing(installed_packages)
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
if dist_is_editable(dist):
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
req = FrozenRequirement.from_dist(dist, [])
File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.eg...
assert len(specs) == 1 and specs[0][0] == '=='
AssertionError
# 解決するには
sudo pip install -U distribute
}}
-テスト
-- localhostにsshでログインしてuname -sを実行
-- デフォルトファイルは fabfile.py
-- -f PATH: 別のpyファイルを指定する場合。
-- -H HOSTS : ホスト指定。カンマ区切りで複数ホストを指定...
-- -u USER : 接続ユーザ指定。指定しなければプロンプトが出る
-- -p PASSWORD : 接続パスワード
-- -i PATH : SSH private key file
#geshi(bash){{
vim fabfile.py
----
# -*- coding: utf-8 -*-
from fabric.api import *
@task
def host_type() :
""" usage """
run('uname -s');
# vim: ts=4 sw=4 expandtab
----
fab -H localhost host_type
out: Linux
fab list
Available commands:
host_type usage
}}
----
***CentOS 5.x [#f704a0b9]
- [[Memo/Python#a1abf210]] でpipを使えるようにする
-fabricのインストール
#geshi(bash){{
sudo yum install python26-paramiko
sudo pip2.6 install paramiko==1.10
sudo pip install fabric==1.8.1
}}
ページ名: