@taskhosts = [...]产生上下文,但-H产生连接?

问题描述

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...