问题描述
Python 3.8.2,Fabric 2.5.0,Paramiko 2.7.2,调用1.4.1
你好
我有一个fabfile,它需要处理在命令行(使用-H
)传递的主机,如果未传递-H
,则需要处理在fabfile中定义的主机。这是我面临的问题的一个示例:
target_group = None
@task
def prod(c):
_env_handler(c,"prod")
def _env_handler(c,env_name):
global target_group
if not hasattr(c,'host'):
target_group = Group("somehost1.tld","somehost2.tld")
@task(hosts=target_group)
def test(c):
print(c)
如果我运行fab prod test
:
<Context: <Config: {'run': {'asynch ...
如果我运行fab -H 1,2 test
:
<Connection host=1>
<Connection host=2>
因此,使用@task(hosts=[...]
装饰器传递主机会产生一个c Context
对象,而使用-H
会产生一个c Connection
对象。
我知道使用任务(prod(c)
)包装环境逻辑可能会令人怀疑...但是有一种方法可以确保任务(test(c)
)始终接收到Connection
对象...或者我从根本上误会了什么?
谢谢。
编辑:我也尝试过直接传递具有相同结果的主机列表(e.g. @task(hosts=["somehost1.tld","somehost2.tld"]))
。
编辑:这是当前的解决方法,但是如果您有很多任务,显然并不理想:
@task
def test(c):
if not hasattr(c,'host'):
for c in target_group:
test(c)
else:
logging.info(f"targeting {c.host}")
解决方法
使用自定义任务装饰器的解决方法:
def _task_handler(func):
@task
@functools.wraps(func)
def wrapper(c):
if not hasattr(c,'host'):
for c in target_group:
func(c)
else:
func(c)
return wrapper