Fabric Python предоставляет возможность вызывать функции матрицы вне утилиты fab
, используя функцию execute
.Контекстуальная проблема возникает, когда функция execute
вызывается внутри другой функции, которая была вызвана с использованием execute.Fabric теряет контекст внешнего выполнения, когда внутренний выполняется, и никогда не восстанавливает его.Например:
env.roledefs = {
'webservers': ['web1','web2'],
'load_balancer': ['lb1']
}
@roles('webserver')
def deploy_code():
#ship over tar.gz of code to unpack.
...
execute(remove_webserver_from_load_balancer, sHost=env.host_string)
...
#shutdown webserver, unpack files, and restart web server
...
execute(add_webserver_to_load_balancer, sHost=env.host_string)
@roles('load_balancer')
def remove_webserver_from_load_balancer(sHost=None):
ssh("remove_host %s" % sHost)
execute(deploy_code)
После первого вызова execute
Fabric полностью теряет свой контекст и выполняет все дальнейшие команды в функции deploy_code
с host_string='lb1'
вместо 'web1'
. Как я могу заставить его запомнить это?
Я придумал этот хак, но чувствую, что он может сломаться в будущих выпусках:
with settings(**env):
execute(remove_webserver_from_load_balancer, sHost=env.host_string)
Это эффективносохраняет все состояние и восстанавливает его после вызова, но выглядит как непреднамеренное использование функции.Есть ли лучший способ сообщить Fabric, что он находится во вложенном выполнении, и использовать стек настроек или эквивалентный метод для запоминания состояния?
Спасибо!