Python 织物环境的作用不符合预期

Python 织物环境的作用不符合预期,python,fabric,Python,Fabric,在上,给出了以下示例: from fabric.api import env env.roledefs = { 'web': { 'hosts': ['www1', 'www2', 'www3'], 'foo': 'bar' }, 'dns': { 'hosts': ['ns1', 'ns2'], 'foo': 'baz' } } 从文档中可以看出,当在主机“www1”、“www2”、“www3”

在上,给出了以下示例:

from fabric.api import env

env.roledefs = {
    'web': {
        'hosts': ['www1', 'www2', 'www3'],
        'foo': 'bar'
    },
    'dns': {
        'hosts': ['ns1', 'ns2'],
        'foo': 'baz'
    }
}
从文档中可以看出,当在主机“www1”、“www2”、“www3”上执行时,此设置应为env dict键“foo”提供值“bar”。我无法获得此行为,尽管fabric确实可以正确确定主机。一个示例文件:

env.foo = 'WRONG'
@task()
def set_role():
    env.roles.append('web')

@task()
def print_foo():
    print env.foo
示例命令:

fab set_role print_foo
意外输出:

[www1] Executing task 'print_foo'
WRONG
[www2] Executing task 'print_foo'
WRONG
[www3] Executing task 'print_foo'
WRONG

Done.
我是不是误解了这个目的?我怎样才能使一台服务器看到一个密钥的不同值,而另一台服务器却没有太多麻烦


我使用fabric 1.10.0有两个问题,第一个问题是使用的fabric版本比基于词典的定义旧,因此它将密钥解释为主机名。这可以通过升级到>=fabric 1.10.0来解决。其次,此处定义的设置不会自动填充env,但如果您使用任务来设置角色,则可以这样设置:

@task
def set_role(role_name):
    env.roles.append(role_name)
    for k, v in env.roledefs[role_name].iteritems():
        if k == 'hosts':
            continue
        env[k] = v
使用以下命令调用:

fab set_role:dns do_my_task

我也被这弄糊涂了。事实证明,可以在Fabric 1.11中访问这些:

这只是一个答案:

env.roledefs = {
    'prod': {
        'hosts':['server1','server2'],
        'path':'/opt/prod'
        },
    'stag': {
        'hosts':['server3','server4'],
        'path':'/opt/stag'
        }
}

@roles('prod')
def runa():
    role = env.effective_roles[0]
    print env.roledefs[role]['path']

如果要在
env
中为给定任务自动设置额外的roledef键,可以使用装饰器。这是我正在使用的一个:

from functools import wraps

def apply_role(f):
    "Decorator to apply keys in effective roledef to current env."
    @wraps(f)
    def wrapper(*args, **kwargs):
        if env.effective_roles:
            for k, v in env.roledefs[env.effective_roles[0]].items():
                if k in env and isinstance(env[k], list) and isinstance(v, list):
                    env[k].extend(v)
                elif k in env and isinstance(env[k], list):
                    env[k].append(v)
                else:
                    env[k] = v
        return f(*args, **kwargs)
    return wrapper
然后装饰要应用roledef键的任何任务:

@apply_role
def mytask():
    ...

你有没有找到答案?我使用的是最新的面料(1.10.1),并且有相同的问题。“foo”:“bar”键似乎不可访问,fabric文档也没有给出如何使用这些键的任何示例。因此,如果roledefs定义的设置不能自动填充,那么这些键的作用是什么?似乎这个功能存在是有原因的,即使没有文档记录?因此,程序员可以使用它们,而不需要外部配置系统。但是,仅定义自己的dict和保留键似乎比这里建议的自定义函数和循环更简单,代码更少。我无法想象他们创建了这个更麻烦的系统来处理这种时尚的附加设置。我的问题与fabric的最新版本有关,从版本1.10.1起仍然有效。您无法升级。请阅读、研究并修改你的答案。嗨,亚伦,很抱歉你误解了。我说的是“升级到>=fabric 1.10.0”,1.10.1符合这一条件。没有什么可更改的,因为我的答案适用于最新版本的fabric。嗨,欢迎使用SO。虽然这个代码片段可能会解决这个问题,但包含代码外的解释确实有助于提高文章的质量。请记住,您将在将来回答读者的问题,而这些人可能不知道您的代码建议的原因。事实并非如此:Fabric 1.11已过时,行为尚未更改,问题已解决