2013-12-08 41 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