2013-12-08 74 views
2

我在我的fabfile中有一些結構任務,我需要在它們執行前初始化env變量。我試圖使用裝飾器,它的作品,但織物總是說:「找不到主機請指定(單)」但是,如果我打印我的變量「env」的內容似乎都很好。 另外我從另一個python腳本調用我的任務。Python結構裝飾器

from fabric.api import * 
from instances import find_instances 

def init_env(func): 
    def wrapper(*args, **kwargs): 
     keysfolder = 'keys/' 
     env.user = 'admin' 
     env.key_filename = '%skey_%s_prod.pem'%(keysfolder, args[0]) 
     env.hosts = find_instances(args[1]) 
     return func(args[0], args[1]) 
    return wrapper 


@init_env 
def restart_apache2(region, groupe): 
    print(env.hosts) 
    run('/etc/init.d/apache2 restart') 
    return True 

我的腳本調用fabfile:

from fabfile import init_env, restart_apache2 

restart_apache2('eu-west-1', 'apache2') 

打印輸出在重啓的Apache2:

[u'10.10.0.1' ,u'10.10.0.2' ]

任何想法爲什麼我的任務restart_apache2不使用env變量?

感謝

編輯:

這是有趣的是,如果在我的腳本調用fabfile,我使用fabric.api設置,並設置主機IP,它的工作原理。這表明我的裝飾器很好地初始化了env變量,因爲密鑰和用戶被髮送到結構。這只是這不是由織物閱讀env.hosts ...

EDIT2:

我可以使用從fabric.api設置,這樣達到我的目標:

@init_env 
def restart_apache2(region, groupe): 
    for i in env.hosts: 
     with settings(host_string = '%[email protected]%s' % (env.user, i)): 
      run('/etc/init.d/apache2 restart') 
    return True 

獎金的問題,有沒有解決方案直接使用env.hosts沒有設置?

+0

看起來像'init_env'中有一個縮進錯誤。兩個返回語句看起來應該縮進一個級別。 – millerdev

+0

這是一個壞的複製粘貼,我原來的縮進是好的。我修改了我的帖子。 – Matt

+0

您提到您正在調用另一個python腳本的任務。你是用'fab'命令還是其他方式調用另一個腳本? – millerdev

回答

3

我在這裏猜測了一下,但我假設你遇到了麻煩,因爲你試圖一次解決兩個問題。

第一個問題涉及到多個主機的問題。結構包括roles的概念,它們只是您可以一次發出命令的機器組。 find_instances函數中的信息可用於填充此數據。

from fabric import * 
from something import find_instances 

env.roledefs = { 
    'eu-west-1' : find_instances('eu-west-1'), 
    'eu-west-2' : find_instances('eu-west-2'), 
} 

@task 
def restart_apache2(): 
    run('/etc/init.d/apache2 restart') 

第二個問題是您對不同的服務器組有不同的密鑰。解決此問題的一種方法是使用SSH配置文件,以防止您必須將密鑰/用戶帳戶的詳細信息與您的結構代碼混合。您可以添加每個實例的進入你的~/.ssh/config,或者您可以使用local SSH configenv.use_ssh_configenv.ssh_config_path

Host instance00 
    User admin 
    IdentityFile keys/key_instance00_prod.pem 

Host instance01 
    User admin 
    IdentityFile keys/key_instance01_prod.pem 

# ... 

在命令行上,則應能夠發出類似的命令:

fab restart_apache2 -R eu-west-1 

或者,你仍然可以做單主機:

fab restart_apache2 -H apache2 

在腳本中,這兩個是相當於execute函數:

from fabric.api import execute 
from fabfile import restart_apache2 

execute(restart_apache2, roles = ['eu-west-1']) 
execute(restart_apache2, hosts = ['apache2']) 
+0

尼斯!非常感謝解決方案和解釋:) – Matt