对“进行嵌套调用”;执行;使用Python';s结构库

对“进行嵌套调用”;执行;使用Python';s结构库,python,fabric,Python,Fabric,Python的结构提供了使用execute函数在fab实用程序之外调用结构函数的能力。在使用execute调用的另一个函数中调用execute函数时,会出现上下文问题。当调用内部执行时,结构将丢失外部执行的上下文,并且永远不会恢复它。例如: env.roledefs = { 'webservers': ['web1','web2'], 'load_balancer': ['lb1'] } @roles('webserver') def deploy_code(): #s

Python的结构提供了使用
execute
函数在
fab
实用程序之外调用结构函数的能力。在使用execute调用的另一个函数中调用
execute
函数时,会出现上下文问题。当调用内部执行时,结构将丢失外部执行的上下文,并且永远不会恢复它。例如:

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完全失去其上下文,并使用
host\u string='lb1'
而不是
'web1'
执行
deploy\u code
函数中的所有进一步命令如何让它记住它?

我想出了这个黑客,但我觉得它可能会在未来的版本中崩溃:

 with settings(**env):
     execute(remove_webserver_from_load_balancer, sHost=env.host_string)
这有效地保存了所有状态,并在调用后将其恢复,但似乎是无意中使用了该函数。有没有更好的方法告诉Fabric它位于嵌套执行中,并使用设置堆栈或等效方法来记住状态


谢谢

您没有正确使用面料。正如您只需调用
fab deploy\u code
而不是像python一样运行fab文件。我建议阅读本教程,以便更好地了解如何构造文件

无论如何,您可以了解如何使用
execute()
,以及更多细节

您有一个输入错误,您从Web服务器角色中删除了“s”。这可能是您在第二个任务中需要主机字符串时没有好的主机字符串的原因


除此之外,您还可以在execute()命令本身中设置角色和主机。

为什么要在任务内部使用
execute()
而不是直接调用函数?@J.F.Sebastian我想答案是:
结构的设计避免了神奇的行为,因此,简单地调用任务函数并不考虑诸如角色之类的装饰器。正确,jcollado,我需要装饰器context@jcollado:您的前提是@Andrew Patrick Dowds的意图是始终使用
@roles('load\u balancer')
运行
remove\u webserver..()
。,您认为所讨论的代码是规范性的(这很可能是真的)。但是代码并没有按照他想要的那样运行,因此我的问题是看用简单的英语表达的意图。@J.F.Sebastian,意图是使用\@roles范例,这样我就可以使用Fabric的尼斯配置系统。对于我要将代码部署到的每个Web服务器,我希望引用它的每个负载平衡器(在“load_balancer”roledef中)在部署之前将其停止旋转,并在部署之后恢复。