/.ssh/configで多段sshの設定と、use_ssh_configを組み合わせると処理が終わっても切断されない。
バグっぽい
/.ssh/config
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/null IdentityFile ~/.ssh/id_rsa
# -*- 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')
# localは大丈夫 fab multistage_ssh_test # 多段sshは処理が終了しない fab -u user01 -H target01.example.com multistage_ssh_test
fab -u user01 -H target01.example.com -g gateway-user01@gateway.example.com multistage_ssh_test
fabricからシェルスクリプト等を実行する時、起動しないものがある
run("nohup my_script.sh")
run("my_script.sh", pty=True)
sudo pip install fabtools
fabtools.rpm.install(['ntp'],options=['--quiet'])
env.always_use_pty=False
fab -f gateway_test.py gateway_test
# -*- 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
$ 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.
fab -R web deploy [web01.example.com] Executing task 'deploy' [web02.example.com] Executing task 'deploy' Done.
... @task @roles('web') def deploy(): pass
fab deploy [web01.example.com] Executing task 'deploy' [web02.example.com] Executing task 'deploy' Done.
fab -R db deploy [web01.example.com] Executing task 'deploy' [web02.example.com] Executing task 'deploy' Done.
@task def test_quiet(): with quiet(): print local("test -e /tmp/build").succeeded # False print local("test -e /tmp/build").failed # True
@task def test_return(): print local('test -d /tmp', quiet=True, warn_only=True).succeeded # True print local('test -d /tmp', quiet=True, warn_only=True).return_code # 0
@task def test_shell(): with shell_env(VAR1='hoge'): print local('echo $VAR1') # hoge print run('echo $VAR1') # hoge
@task def test_cd(): with cd('/tmp'): run('pwd') # /tmp
import distutils print distutils.util.strtobool("true") # 1: y, yes, t, true, on print distutils.util.strtobool("false") # 0: n, no, f, false, off var1 = distutils.util.strtobool(var1) if isinstance(var1, str) else var1
def test(): env.use_ssh_config = True # ~/.ssh/configを参照する場合 env.user = "hoge" env.key_filename = "/home/hoge/.ssh/id_rsa" run("hostname -s")
# -*- 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)
# -*- coding: utf8 -*- from fabric.api import * import logging # ~/.fabricrc に log_filename=/tmp/fab.log 等を追加 def set_logging(filename=env.log_filename, level=logging.INFO): 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%(message)s\t%(module)s\t%(funcName)s\t%(lineno)d\t%(pathname)s") console = logging.StreamHandler() console.setLevel(level) formatter = logging.Formatter("%(asctime)s\t%(levelname)s\t%(message)s") 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')
vim ~/.fabricrc ---- servers=host1,host2 ----
# -*- 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 test -H host1,host2
env.hosts = ["host1","host2"] #env.hosts = env.servers.split(",") # ERROR: No hosts found.
env.host_string="ssh.example.com"
@hosts(env.servers.split(",")) @task def test(): run("hostname -s")
def _test(arg1, arg2): run("hostname -s") @task def test(): host_list=env.servers.split(",") execute(_test, arg1="arg1", arg2="arg2", hosts=host_list)
vim ~/.fabricrc ---- user = hoge ---- fab show_env:user hoge
env.varname に対して、読み書き可能。省略時のデフォルトとして使われる。
env.newvar="value" のように新しい値も作成できる。
envは辞書型
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"] のように複数ホストを指定。コマンドの-H 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 '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.
pip list ... Exception: Traceback (most recent call last): File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.egg/pip/basecommand.py", line 134, in main status = self.run(options, args) File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.egg/pip/commands/list.py", line 80, in run self.run_listing(options) File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.egg/pip/commands/list.py", line 127, in run_listing self.output_package_listing(installed_packages) File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.egg/pip/commands/list.py", line 136, in output_package_listing if dist_is_editable(dist): File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.egg/pip/util.py", line 347, in dist_is_editable req = FrozenRequirement.from_dist(dist, []) File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.egg/pip/__init__.py", line 194, in from_dist assert len(specs) == 1 and specs[0][0] == '==' AssertionError
sudo pip install -U distribute
# -*- 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")
fab test_confirm hoge [y/N] y yes
# -*- 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
fab create_file_in_prompt -H localhost
Which file: hoge
# -*- 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
fab create_file_in_tmp:filename=hoge -H localhost
# -*- coding: utf-8 -*- from fabric.api import * @task def hello_world(message=""): localhost('echo "Hello, world! %s"' % message); # vim: ts=4 sw=4 expandtab
fab hello_world:message=hoge Hello, world! hoge
fab hello_world:"bar\,foo" Hello, world! bar,foo
sudo pip install git+git://github.com/rackerlabs/python-clouddns
sudo pip install boto
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
svn propedit svn:ignore . ---- *.pem *.pyc *.pyo ----
vim .gitignore ---- *.pem *.pyc *.pyo ----
sudo pip install fabric -U # 1.7.0 => 1.8.0の場合 sudo pip install fabric paramiko pycrypto -U
sudo pip install fabric -I
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
yum install python python-devel python-setuptools --enablerepo=epel 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.egg/pip/basecommand.py", line 134, in main status = self.run(options, args) File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.egg/pip/commands/list.py", line 80, in run self.run_listing(options) File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.egg/pip/commands/list.py", line 127, in run_listing self.output_package_listing(installed_packages) File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.egg/pip/commands/list.py", line 136, in output_package_listing if dist_is_editable(dist): File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.egg/pip/util.py", line 347, in dist_is_editable req = FrozenRequirement.from_dist(dist, []) File "/usr/lib/python2.6/site-packages/pip-1.4-py2.6.egg/pip/__init__.py", line 194, in from_dist assert len(specs) == 1 and specs[0][0] == '==' AssertionError # 解決するには sudo pip install -U distribute
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
sudo yum install python26-paramiko sudo pip2.6 install paramiko==1.10 sudo pip install fabric==1.8.1