Fabric学習のまとめ

20527 ワード

Fabricノート


何ができる?

  • executing local or remote shell commands
  • uploading/downloading files
  • others auxiliary functionality

  • インストール

    pip install fabric
    fabfileを編集し、ファイル名をfabfileと名付けます.py
    from fabric.api import run
    
    def host_type():
        run('uname -s')

    コマンドラインツールfabの使用

    fab -H localhost, remotehost host_type fab -H host
    概説
    辞書user env.password env.warn_only env.hostsなど

    コンテキストマネージャ

    from fabric.api import settings, run
    
    def exists(path):
        with settings(warn_only=True):
            return run('test -e %s' % path)

    一時指定user

    from fabric.api import env, run
    
    env.user = 'implicit_user'
    env.hosts = ['host1', 'explicit_user@host2', 'host3']
    
    def print_user():
        with hide('running'):
            run('echo "%(user)s"' % env)

    fabricの実行ポリシー

  • タスクの列が作成され、パラメータとしてfabに渡され、タスクは所定の順序
  • を維持する.
  • 異なるタスクに対してhostsの割り当てを指定する方法を参照してください.
  • 各タスクは順番に実行され、hostごとに1回のみ実行されます.
  • Tasks with no hosts in their host list are considered local-only, and will always run once and only once. (やってみたらダメみたい、hostがないとrunが実行できない、ヒントNo hosts found. Please specify (single) host string for connection:)fab options and arguments

  • fabのオプションとパラメータ


    fab --help

    Usage: fab [options] [:arg1,arg2=val2,host=foo,hosts='h1;h2',...] ...
    
    Options:
      -h, --help            show this help message and exit
      -d NAME, --display=NAME
                            print detailed info about command NAME
      -F FORMAT, --list-format=FORMAT
                            formats --list, choices: short, normal, nested
      -I, --initial-password-prompt
                            Force password prompt up-front
      -l, --list            print list of possible commands and exit
      --set=KEY=VALUE,...   comma separated KEY=VALUE pairs to set Fab env vars
      --shortlist           alias for -F short --list
      -V, --version         show program's version number and exit
      -a, --no_agent        don't use the running SSH agent
      -A, --forward-agent   forward local agent to remote end
      --abort-on-prompts    abort instead of prompting (for password, host, etc)
      -c PATH, --config=PATH
                            specify location of config file to use
      --colorize-errors     Color error output
      -D, --disable-known-hosts
                            do not load user known_hosts file
      -e, --eagerly-disconnect
                            disconnect from hosts as soon as possible
      -f PATH, --fabfile=PATH
                            python module file to import, e.g. '../other.py'
      -g HOST, --gateway=HOST
                            gateway host to connect through
      --gss-auth            Use GSS-API authentication
      --gss-deleg           Delegate GSS-API client credentials or not
      --gss-kex             Perform GSS-API Key Exchange and user authentication
      --hide=LEVELS         comma-separated list of output levels to hide
      -H HOSTS, --hosts=HOSTS
                            comma-separated list of hosts to operate on
      -i PATH               path to SSH private key file. May be repeated.
      -k, --no-keys         don't load private key files from ~/.ssh/
      --keepalive=N         enables a keepalive every N seconds
      --linewise            print line-by-line instead of byte-by-byte
      -n M, --connection-attempts=M
                            make M attempts to connect before giving up
      --no-pty              do not use pseudo-terminal in run/sudo
      -p PASSWORD, --password=PASSWORD
                            password for use with authentication and/or sudo
      -P, --parallel        default to parallel execution method
      --port=PORT           SSH connection port
      -r, --reject-unknown-hosts
                            reject unknown hosts
      --system-known-hosts=SYSTEM_KNOWN_HOSTS
                            load system known_hosts file before reading user
                            known_hosts
      -R ROLES, --roles=ROLES
                            comma-separated list of roles to operate on
      -s SHELL, --shell=SHELL
                            specify a new shell, defaults to '/bin/bash -l -c'
      --show=LEVELS         comma-separated list of output levels to show
      --skip-bad-hosts      skip over hosts that can't be reached
      --skip-unknown-tasks  skip over unknown tasks
      --ssh-config-path=PATH
                            Path to SSH config file
      -t N, --timeout=N     set connection timeout to N seconds
      -T N, --command-timeout=N
                            set remote command timeout to N seconds
      -u USER, --user=USER  username to use when connecting to remote hosts
      -w, --warn-only       warn, instead of abort, when commands fail
      -x HOSTS, --exclude-hosts=HOSTS
                            comma-separated list of hosts to exclude
      -z INT, --pool-size=INT
                            number of concurrent processes to use in parallel mode

    並列実行


    次のようになります.
    from fabric.api import *
    
    def update():
        with cd("/srv/django/myapp"):
            run("git pull")
    
    def reload():
        sudo("service apache2 reload")
    fab -H web1,web2,web3 update reload並列実行でない場合
    1.update on web1
    2.update on web2
    3.update on web3
    4.reload on web1
    5.reload on web2
    6.reload on web3

    パラレル実行の場合
    1.update on web1, web2, and web3
    2.reload on web1, web2, and web3

    updateに5秒,reloadに2秒かかると仮定すると非並列の所要時間(5+2)*3=21秒,並列の所要時間であれば5+2=7秒,fabricではマルチプロセスを用いて同時化を実現し,グローバル解釈器ロックの制限をうまく回避できる.
    各タスクに対して同時実行を使用
    version 1:アクセサリーで
    from fabric.api import *
    
    
    @parallel
    def runs_in_parallel():
        pass
    
    def runs_serially():
        pass
    fab -H host1,host2,host3 runs_in_parallel runs_seriallyが実行されると、実行順序は
    1. runs_in_parallel on host1, host2, and host3
    2. runs_serially on host1
    3. runs_serially on host2
    4. runs_serially on host3

    version 2:コマンドラインで-Pを指定しますが、非並列タスクを指定する必要があります.
    from fabric.api import *
    
    def runs_in_parallel():
        pass
    
    @serial
    def runs_serially():
        pass
    fab -H host1,host2,host3 -P runs_in_parallel runs_serially
    大量のhostが操作を必要とする場合、io操作が非常に頻繁なタスクは、プロセスプールのサイズを規定し、同時量を制限するのが一般的です.
    二つの方法
  • は、デコレーション入力パラメータ
  • である.
    from fabric.api import *
    
    @parallel(pool_size=5)
    def heavy_task():
        # lots of heavy local lifting or lots of IO here

    Or skip the pool_size kwarg and instead:
  • コマンドラインパラメータ-zにより
    $ fab -P -z 5 heavy_task
  • を指定する.

    タスク@taskアクセラレータの定義


    このデコレーションがあればいい、タスクに別名をつける
    from fabric.api import task
    
    @task(alias='dwm')
    def deploy_with_migrations():
        pass

    に届く
    $ fab --list
    Available commands:
    
        deploy_with_migrations
        dwm

    タスクをオブジェクト向けに作成し、from fabric.tasks import Taskから継承
    class MyTask(Task):
        name = "deploy"
        def run(self, environment, domain="whatever.com"):
            run("git clone foo")
            sudo("service apache2 restart")
    
    instance = MyTask()

    これと同じように
    @task
    def deploy(environment, domain="whatever.com"):
        run("git clone foo")
        sudo("service apache2 restart")

    自分のTaskクラスを使う
    from fabric.api import task
    from fabric.tasks import Task
    
    class CustomTask(Task):
        def __init__(self, func, myarg, *args, **kwargs):
            super(CustomTask, self).__init__(*args, **kwargs)
            self.func = func
            self.myarg = myarg
    
        def run(self, *args, **kwargs):
            return self.func(*args, **kwargs)
    
    @task(task_class=CustomTask, myarg='value', alias='at')
    def actual_task():
        pass
    
    
    task_obj = CustomTask(actual_task, myarg='value')

    ネーミングスペース


    ディレクトリツリー
    fabfile
    ├── __init__.py

    init.pyのコード
    from fabric.api import task
    
    @task
    def deploy():
        pass
    
    @task
    def compress():
        pass

    結果
    $ fab --list
    Available commands:
    
        compress
        deploy

    lb.pyを追加するには:
    from fabric.api import task
    @task
    def add_backend():
        pass

    And we’ll add this to the top of init.py: import lb現在fab --list:
    deploy
    compress
    lb.add_backend

    ネーミングスペースはさらに深いネストを実現し、次の層を第1層と同じようにPythonのパッケージを作ればいい.次のようになります.
    .
    ├── __init__.py
    ├── db
    │   ├── __init__.py
    │   └── migrations.py
    └── lb.py

    すべての関数をfabricに露出したくない場合はlb.pyに追加できます
    先に加入する
    @task
    def hidden_task():
        pass
    fab --list願い通りに
    Available commands:
    
        compress
        deploy
        lb.add_backend
        lb.hidden_task

    hidden-taskを隠したい
    lb.pyの頭部に露出したいものを加えると__all__ = ['add_backend']です
    フォーマット出力fab --list-format=nested --list
    Available commands (remember to call as module.[...].task):
    
        compress
        deploy
        lb:
            add_backend

    終端テキストの色

    fabric.colors.blue(text, bold=False)
    fabric.colors.cyan(text, bold=False)
    fabric.colors.green(text, bold=False)
    fabric.colors.magenta(text, bold=False)
    fabric.colors.red(text, bold=False)
    fabric.colors.white(text, bold=False)
    fabric.colors.yellow(text, bold=False)

    黒がないことに気づきました.うん、ほとんどの実用的な端末は黒です.もしあなたが本当に白い端末が好きなら、これを試して黒を印刷してみてください.
    from fabric.colors import red, green, _wrap_with
    
    #         text
    print _wrap_with('30')("i am black")

    コンテキストマネージャ


    show、hide、lcd、cd、prefixなど

    デコレーション


    hosts、parallel、roles、runs_once、task、serial

    ネットワーク関連の部分


    一般的な操作

  • get()リモートサイトからファイル
  • をダウンロード
  • local()ローカルでコマンド
  • を実行
  • prompt()キーボード入力、raw_inputは、正規表現を用いて入力を検証することができる
  • .
    # Simplest form:
    environment = prompt('Please specify target environment: ')
    
    # With default, and storing as env.dish:
    prompt('Specify favorite dish: ', 'dish', default='spam & eggs')
    
    # With validation, i.e. requiring integer input:
    prompt('Please specify process nice level: ', key='nice', validate=int)
    
    # With validation against a regular expression:
    release = prompt('Please supply a release name',
            validate=r'^\w+-\d+(\.\d+)?$')
    
    # Prompt regardless of the global abort-on-prompts setting:
    with settings(abort_on_prompts=False):
        prompt('I seriously need an answer on this! ')
  • put()リモートホスト
  • にファイルをアップロード
  • run()リモートホスト上でコマンド
  • を実行
  • sudo()は、スーパーユーザの権限を使用して、リモートホスト上でコマンド
  • を実行する.
    文/konglx 90(簡書作者)
    テキストリンク:http://www.jianshu.com/p/0a90ae13f541
    著作権は作者の所有で、転載は作者に連絡して授権を得て、そして“簡書の作者”を表示してください.