如何使用Fabric并行运行?

时间:2016-10-19 03:01:33

标签: python parallel-processing fabric

我之前问了一个相关的问题:

How to issue commands on remote hosts in parallel using Fabric without using a fabfile?

我在各种测试主机上并行执行测试时遇到问题。

我的代码如下所示:

@parallel  
def run_test(arg_list):
    # arg_list is a list of dictionary.  Each entry in
    # arg_list has a 'ip_address' and a 'test_config_file'

    for x in arg_list:
        ip_address = x['ip_address']
        test_config_file = x['test_config_file']
        env['host_string'] = ip_address
        # The test program "test_localhost.py" is already on all the Test hosts
        cmd = "/root/test_localhost.py --ip_addr=" + ip_address + " --config=" + test_config_file
        run(cmd)


if __name__ == '__main__':

    env.parallel = True

    # Each test host will have unique test_config_files
    arg_list = list()
    arg_list.append({'ip_address':'10.10.10.10', 'test_config_file': "config_01.json"})
    arg_list.append({'ip_address':'10.10.10.11', 'test_config_file': "config_02.json"})

    execute(run_test, arg_list)

我已经针对2个以上的测试主机运行此代码。我有一个脚本,检查测试是否在测试主机上运行。测试不是并行运行的。

相反,测试按顺序运行 - " test_localhost.py"首先在10.10.10.10上运行,然后在完成后运行在10.10.10.11。

我还需要做些什么才能让测试并行运行?

注意:我不能使用fabfile,因为我正在为每个测试主机发送不同的测试配置文件。

1 个答案:

答案 0 :(得分:2)

这就是我要做的。针对不同主机的不同参数的技巧是向env context_manager添加信息,以便为任务抓取特定于主机的参数。只需确保主机与您用于字典的密钥匹配,并且并行命令可以正常工作。最后,结构中的任务通常通过fab命令运行。我从未尝试使用本机python脚本,并且不确定其后果或是否需要进行任何特殊处理。结构项目的典型格式是在名为fabfile.py的文件中定义任务,并且可以使用fab运行这些任务。

在名为fabfile.py的文件中:

from fabric.decorators import task, parallel
from fabric.operations import run
from fabric.context_managers import env

@task
def run_test(arg_list):
    # arg_list is a list of dictionary.  Each entry in
    # arg_list has a 'ip_address' and a 'test_config_file'
    env.hosts = [ x['ip_address'] for x in arg_list ]
    env.host_data = dict()
    for x in arg_list:
        env.host_data[x['ip_address']] = x
    execute(run_command)

@parallel
def run_command():
    context = env.host_data[env.host]
    cmd = '/root/test_localhost.py --ip_addr=%(ip_address)s --config=%(test_config_file)s' % context
    run(cmd)

@task 
def run_my_test():
    arg_list.append({'ip_address':'10.10.10.10', 'test_config_file': "config_01.json"})
    arg_list.append({'ip_address':'10.10.10.11', 'test_config_file': "config_02.json"})
    run_test(arg_list)

从命令行运行:

fab run_my_test