Как узнать текущую роль в Python Fabric
Это очень важный вопрос Fabric, но более опытные хакеры на питоне могут ответить на это, даже если они не знают Ткань.
Я пытаюсь указать другое поведение в команде в зависимости от того, для какой роли она выполняется, т.е.:
def restart():
if (SERVERTYPE == "APACHE"):
sudo("apache2ctl graceful",pty=True)
elif (SERVERTYPE == "APE"):
sudo("supervisorctl reload",pty=True)
Я взломал это с помощью таких функций, как этот:
def apache():
global SERVERTYPE
SERVERTYPE = "APACHE"
env.hosts = ['xxx.xxx.com']
Но это, очевидно, не очень элегантно, и я только что открыл роли, поэтому мой вопрос:
Как определить, к какой роли принадлежит текущий экземпляр?
env.roledefs = {
'apache': ['xxx.xxx.com'],
'APE': ['yyy.xxx.com'],
}
Спасибо!
Ответы
Ответ 1
Обновление: просто отметьте исходный код, и кажется, что это уже было доступно уже в 1.4.2!
update 2: Это не работает при использовании декоратора @roles
(в 1.5.3)! Он работает только при указании ролей с использованием флага командной строки -R
.
Для ткани 1.5.3 текущие роли доступны непосредственно в `fabric.api.env.roles '. Например:
import fabric.api as fab
fab.env.roledefs['staging'] = ['bbs-evolution.ipsw.dt.ept.lu']
fab.env.roledefs['prod'] = ['bbs-arbiter.ipsw.dt.ept.lu']
@fab.task
def testrole():
print fab.env.roles
Тестируемый выход на консоли:
› fab -R staging testrole
[bbs-evolution.ipsw.dt.ept.lu] Executing task 'testrole'
['staging']
Done.
Или:
› fab -R staging,prod testrole
[bbs-evolution.ipsw.dt.ept.lu] Executing task 'testrole'
['staging', 'prod']
[bbs-arbiter.ipsw.dt.ept.lu] Executing task 'testrole'
['staging', 'prod']
Done.
При этом мы можем сделать простой тест in
в задаче с тканью:
@fab.task
def testrole():
if 'prod' in fab.env.roles:
do_production_stuff()
elif 'staging' in fab.env.roles:
do_staging_stuff()
else:
raise ValueError('No valid role specified!')
Ответ 2
Для всех остальных с этим вопросом, вот мое решение:
Ключ был найден env.host_string.
Вот как я перезапускаю разные типы серверов с помощью одной команды:
env.roledefs = {
'apache': ['xxx.xxx.com'],
'APE': ['yyy.xxx.com']
}
def apache():
env.roles = ['apache']
...
def restart():
if env.host_string in env.roledefs['apache']:
sudo("apache2ctl graceful", pty=True)
elif env.host_string in env.roledefs['APE']:
sudo ("supervisorctl reload", pty=True)
наслаждайтесь!
Ответ 3
Я не тестировал его, но мог бы работать:
def _get_current_role():
for role in env.roledefs.keys():
if env.host_string in env.roledefs[role]:
return role
return None
Ответ 4
env.roles
предоставит вам роли, указанные флагом -R или жестко запрограммированные в самом script. Он не будет содержать роли, указанные для каждой задачи, с помощью командной строки или с помощью @roles
decorator. В настоящее время нет способа получить такую информацию.
Следующая версия ткани (вероятно, 1.9) предоставит атрибут env.effective_roles
точно, что вы хотите - роли, которые используются для выполняемой в настоящее время задачи. Код для этого уже был объединен с мастером.
Посмотрите эту проблему.