108

Fabric を使用して、Web アプリ コードを開発、ステージング、および運用サーバーにデプロイしたいと考えています。私のfabfile:

def deploy_2_dev():
  deploy('dev')

def deploy_2_staging():
  deploy('staging')

def deploy_2_prod():
  deploy('prod')

def deploy(server):
  print 'env.hosts:', env.hosts
  env.hosts = [server]
  print 'env.hosts:', env.hosts

出力例:

host:folder user$ fab deploy_2_dev
env.hosts: []
env.hosts: ['dev']
No hosts found. Please specify (single) host string for connection:

Fabric docsset_hosts()に示されているようにタスクを作成すると、env.hosts が適切に設定されます。ただし、これは実行可能なオプションではなく、デコレーターでもありません。コマンド ラインでホストを渡すと、最終的に fabfile を呼び出すある種のシェル スクリプトが生成されます。私は、1 つのツールが適切に機能することを望んでいます。

Fabric のドキュメントには、「env.hosts は単なる Python リスト オブジェクトです」と書かれています。私の観察から、これは単に真実ではありません。

ここで何が起こっているのか誰でも説明できますか? デプロイ先のホストを設定するにはどうすればよいですか?

4

15 に答える 15

129

これを行うには、環境ごとに実際の関数を宣言します。例えば:

def test():
    env.user = 'testuser'
    env.hosts = ['test.server.com']

def prod():
    env.user = 'produser'
    env.hosts = ['prod.server.com']

def deploy():
    ...

上記の関数を使用して、次のように入力してテスト環境にデプロイします。

fab test deploy

...そして本番環境にデプロイするための以下:

fab prod deploy

この方法の良いところは、デプロイするだけでなく、fab関数の前にtestandprod関数を使用できることです。それは信じられないほど便利です。

于 2011-01-14T00:53:14.943 に答える
77

ロール定義を使用する

from fabric.api import env, run

env.roledefs = {
    'test': ['localhost'],
    'dev': ['user@dev.example.com'],
    'staging': ['user@staging.example.com'],
    'production': ['user@production.example.com']
} 

def deploy():
    run('echo test')

-R で役割を選択:

$ fab -R test deploy
[localhost] Executing task 'deploy'
...
于 2011-06-11T00:22:43.030 に答える
49

serverhorror の答えのより簡単なバージョンは次のとおりです。

from fabric.api import settings

def mystuff():
    with settings(host_string='192.0.2.78'):
        run("hostname -f")
于 2011-06-17T08:31:04.490 に答える
21

私自身これに行き詰まっていましたが、最終的にそれを理解しました。タスク内から env.hosts 構成を設定することはできません。各タスクは、指定されたホストごとに 1 回、N 回実行されるため、設定は基本的にタスクの範囲外です。

上記のコードを見ると、次のように簡単に実行できます。

@hosts('dev')
def deploy_dev():
    deploy()

@hosts('staging')
def deploy_staging():
    deploy()

def deploy():
    # do stuff...

それはあなたが意図していることをするようです。

または、引数を手動で解析し、タスク関数を定義する前に env.hosts を設定するグローバル スコープにカスタム コードを記述することもできます。いくつかの理由から、それが実際に私が設定した方法です。

于 2010-03-02T21:07:15.707 に答える
9

なぜそれが問題なのかを説明する。コマンドfabは、ファブリック ライブラリを利用して、ホスト リストでタスクを実行します。タスク内のホスト リストを変更しようとすると、本質的にリストを反復しながらリストを変更しようとしています。または、ホストが定義されていない場合は、リストをループするように設定したコードが実行されない空のリストをループします。

env.host_string の使用は、接続するホストを関数に直接指定するという点でのみ、この動作の回避策です。これにより、多数のホストで実行する必要がある場合に実行ループを再作成するという問題が発生します。

人々が実行時にホストを設定できるようにする最も簡単な方法は、すべてのホスト文字列、ユーザーなどを設定する個別のタスクとして env populatiing を維持することです。次に、デプロイ タスクを実行します。次のようになります。

fab production deploy

また

fab staging deploy

ステージングとプロダクションは、与えられたタスクに似ていますが、次のタスク自体を呼び出しません。このように動作する必要がある理由は、タスクが終了し、ループから抜け出す必要があるためです (ホストの、env の場合は None ですが、その時点では 1 つのループです)。ホスト (前のタスクで定義済み) を新たに作成します。

于 2011-03-28T21:50:36.813 に答える
9

host_string次のような例を設定する必要があります。

from fabric.context_managers import settings as _settings

def _get_hardware_node(virtualized):
    return "localhost"

def mystuff(virtualized):
    real_host = _get_hardware_node(virtualized)
    with _settings(
        host_string=real_host):
        run("echo I run on the host %s :: `hostname -f`" % (real_host, ))
于 2010-03-10T09:52:17.297 に答える
3

したがって、ホストを設定し、すべてのホストでコマンドを実行するには、以下から始める必要があります。

def PROD():
    env.hosts = ['10.0.0.1', '10.0.0.2']

def deploy(version='0.0'):
    sudo('deploy %s' % version)

これらを定義したら、コマンド ラインで次のコマンドを実行します。

fab PROD deploy:1.5

タスクを実行する前に env.hosts を設定するため、PROD 関数にリストされているすべてのサーバーでデプロイ タスクを実行するもの。

于 2014-04-04T22:00:05.590 に答える
3

タスク関数内ではなく、モジュール レベルで env.hosts を変更する必要があります。私も同じ間違いをしました。

from fabric.api import *

def _get_hosts():
    hosts = []
    ... populate 'hosts' list ...
    return hosts

env.hosts = _get_hosts()

def your_task():
    ... your task ...
于 2010-08-10T14:24:12.197 に答える
3

とても簡単です。env.host_string 変数を初期化するだけで、次のすべてのコマンドがこのホストで実行されます。

from fabric.api import env, run

env.host_string = 'user@exmaple.com'

def foo:
    run("hostname -f")
于 2011-11-27T20:53:33.560 に答える
3

私はファブリックにまったく慣れていませんが、複数のホストで同じコマンドを実行するようにファブリックを取得するには (たとえば、1 つのコマンドで複数のサーバーにデプロイするには)、次を実行できます。

fab -H staging-server,production-server deploy 

staging-serverproduction-serverは、デプロイ アクションを実行する 2 つのサーバーです。OS 名を表示する単純な fabfile.py を次に示します。fabfile.py は、fab コマンドを実行したディレクトリと同じディレクトリにある必要があることに注意してください。

from fabric.api import *

def deploy():
    run('uname -s')

これは、少なくともファブリック 1.8.1 で動作します。

于 2014-01-30T13:45:05.690 に答える
2

env.hoststringサブタスクを実行する前に割り当てることができます。複数のホストを反復処理する場合は、ループでこのグローバル変数に割り当てます。

残念ながら、fabric はこのユース ケース用に設計されていません。http://github.com/bitprophet/fabric/blob/master/fabric/main.pymainで関数をチェックして、その仕組みを確認してください。

于 2010-05-11T22:51:23.077 に答える
0

ロールを使用することは、現在、これを行うための「適切な」「正しい」方法であると考えられており、「すべき」ことです。

そうは言っても、あなたが「望む」または「望む」もののほとんどが好きなら、「ねじれたシステム」を実行するか、その場でターゲットシステムを切り替える能力です。

したがって、娯楽のみを目的として (!) 次の例は、多くの人が危険であると考える可能性があることを示しています。

env.remote_hosts       = env.hosts = ['10.0.1.6']
env.remote_user        = env.user = 'bob'
env.remote_password    = env.password = 'password1'
env.remote_host_string = env.host_string

env.local_hosts        = ['127.0.0.1']
env.local_user         = 'mark'
env.local_password     = 'password2'

def perform_sumersault():
    env_local_host_string = env.host_string = env.local_user + '@' + env.local_hosts[0]
    env.password = env.local_password
    run("hostname -f")
    env.host_string = env.remote_host_string
    env.remote_password = env.password
    run("hostname -f")

次に実行します:

fab perform_sumersault
于 2012-01-31T14:57:54.960 に答える