Ответ 1
Я тоже был смущен этим. Оказывается, что можно получить доступ к ним в Fabric 1.11: https://github.com/fabric/fabric/issues/1276
На веб-сайте веб-сайт приведен пример:
from fabric.api import env
env.roledefs = {
'web': {
'hosts': ['www1', 'www2', 'www3'],
'foo': 'bar'
},
'dns': {
'hosts': ['ns1', 'ns2'],
'foo': 'baz'
}
}
Насколько я могу судить по документации, эта настройка должна дать команде env dict "foo" значение "bar" при выполнении на хостах "www1", "www2", "www3". Я не могу получить это поведение, хотя ткань правильно определяет хосты. Пример fabfile:
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.
Неужели я не понимаю цели этого? Как я могу сделать это так, чтобы один сервер видел другое значение для ключа, а затем другое без особых проблем?
Я использую ткань 1.10.0
Я тоже был смущен этим. Оказывается, что можно получить доступ к ним в Fabric 1.11: https://github.com/fabric/fabric/issues/1276
Две проблемы: сначала версия используемой ткани старше, чем словарные определения, поэтому она интерпретирует ключи как имена хостов. Это можно исправить, обновив до >= ткань 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
Просто ответ на этот вопрос:
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']
Если вы хотите, чтобы дополнительные ключи roledef автоматически устанавливались в env
для данной задачи, вы можете использовать декоратор. Вот тот, который я использую:
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():
...