【问题标题】:python fabric erroneous duplicate executions of taskpython结构错误地重复执行任务
【发布时间】:2016-12-27 05:08:47
【问题描述】:

我从 Fabric 开始,遇到了一个任务被多次执行的问题。我只打算运行任务。

这是我的 fabfile(节点和集线器都是列表。节点有多个主机。集线器只有一个主机) 导入请求 导入json from fabric.api import cd, env, execute, roles, run, settings, task, runs_once

buildconfig_location = 'http://10.102.0.69'

def get_environment_configuration(environment_name):
    request = requests.get( "{}/api/v1/environments/{}".format(buildconfig_location, environment_name) )
    environment_configuration = json.loads(request.text)

    return environment_configuration

def get_hub_servers(server_list):
    hub = [
        server['ip_address']
        for server in server_list
        if server['active'] and server['unit_tests']]

    return hub

def get_node_servers(server_list):
    nodes = [
        server['ip_address']
        for server in server_list
        if server['active'] and server['unit_tests'] is False]

    return nodes

def set_hosts(environment_configuration):
    environment_configuration['servers']

    env.roledefs = {
        'hub': [
            server['ip_address']
            for server in environment_configuration['servers']
            if server['active'] and server['unit_tests']],
        'node': [
            server['ip_address']
            for server in environment_configuration['servers']
            if server['active'] and server['unit_tests'] is False],
    }

def start_node():
    with settings(user="automation1"):
        with cd('/home/automation1/inventory.robot/grid'):
            output = run('nohup ./start_node.sh > node_out 2>&1 &')

def start_hub():
    with settings(user="automation1"):
        with cd('/home/automation1/inventory.robot/grid'):
            run('nohup ./start_hub.sh > hub_out 2>&1 &')

def robot_test():
    with settings(user="automation1"):
        with cd('/home/automation1/inventory.robot/grid'):
            run('python grid.py')

def kill_node():
    with settings(user="automation1"):
        with cd('/home/automation1/inventory.robot/grid'):
            run('./kill_node.pl')

@task
@runs_once
def robot_test():
    environment_configuration = get_environment_configuration('Selenium')
    #set_hosts(environment_configuration)
    nodes = get_node_servers(environment_configuration['servers'])
    hubs = get_hub_servers(environment_configuration['servers'])

    execute(start_hub, hosts=hubs)
    execute(start_node, hosts=nodes)
    execute(robot_test, hosts=hubs)

    all = hubs + nodes
    execute(kill_node, hosts=(hubs + nodes))

这是输出:

[10.102.0.101] Executing task 'start_hub'
[10.102.0.101] run: nohup ./start_hub.sh > hub_out 2>&1 &
[10.102.0.102] Executing task 'start_node'
[10.102.0.102] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.103] Executing task 'start_node'
[10.102.0.103] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.104] Executing task 'start_node'
[10.102.0.104] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.105] Executing task 'start_node'
[10.102.0.105] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.106] Executing task 'start_node'
[10.102.0.106] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.107] Executing task 'start_node'
[10.102.0.107] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.108] Executing task 'start_node'
[10.102.0.108] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.109] Executing task 'start_node'
[10.102.0.109] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.110] Executing task 'start_node'
[10.102.0.110] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.101] Executing task 'robot_test'
[10.102.0.101] Executing task 'start_hub'
[10.102.0.101] run: nohup ./start_hub.sh > hub_out 2>&1 &
[10.102.0.102] Executing task 'start_node'
[10.102.0.102] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.103] Executing task 'start_node'
[10.102.0.103] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.104] Executing task 'start_node'
[10.102.0.104] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.105] Executing task 'start_node'
[10.102.0.105] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.106] Executing task 'start_node'
[10.102.0.106] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.107] Executing task 'start_node'
[10.102.0.107] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.108] Executing task 'start_node'
[10.102.0.108] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.109] Executing task 'start_node'
[10.102.0.109] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.110] Executing task 'start_node'
[10.102.0.110] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.101] Executing task 'robot_test'
[10.102.0.101] Executing task 'start_hub'
[10.102.0.101] run: nohup ./start_hub.sh > hub_out 2>&1 &
[10.102.0.102] Executing task 'start_node'
[10.102.0.102] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.103] Executing task 'start_node'
[10.102.0.103] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.104] Executing task 'start_node'
[10.102.0.104] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.105] Executing task 'start_node'
[10.102.0.105] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.106] Executing task 'start_node'
[10.102.0.106] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.107] Executing task 'start_node'
[10.102.0.107] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.108] Executing task 'start_node'
[10.102.0.108] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.109] Executing task 'start_node'
[10.102.0.109] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.110] Executing task 'start_node'
[10.102.0.110] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.101] Executing task 'robot_test'
[10.102.0.101] Executing task 'start_hub'
[10.102.0.101] run: nohup ./start_hub.sh > hub_out 2>&1 &
[10.102.0.102] Executing task 'start_node'
[10.102.0.102] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.103] Executing task 'start_node'
[10.102.0.103] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.104] Executing task 'start_node'
[10.102.0.104] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.105] Executing task 'start_node'
[10.102.0.105] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.106] Executing task 'start_node'
[10.102.0.106] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.107] Executing task 'start_node'
[10.102.0.107] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.108] Executing task 'start_node'
[10.102.0.108] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.109] Executing task 'start_node'
[10.102.0.109] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.110] Executing task 'start_node'
[10.102.0.110] run: nohup ./start_node.sh > node_out 2>&1 &
[10.102.0.101] Executing task 'robot_test'
^C
Stopped.
Disconnecting from automation1@10.102.0.106... done.
Disconnecting from automation1@10.102.0.109... done.
Disconnecting from automation1@10.102.0.107... done.
Disconnecting from automation1@10.102.0.105... done.
Disconnecting from automation1@10.102.0.108... done.
Disconnecting from automation1@10.102.0.103... done.
Disconnecting from automation1@10.102.0.101... done.
Disconnecting from automation1@10.102.0.110... done.
Disconnecting from automation1@10.102.0.102... done.
Disconnecting from automation1@10.102.0.104... done.

如果我注释掉 'execute(robot_test, hosts=hubs)' 我得到的输出更接近我的预期。我知道这与execute 以及该页面上的警告有关,但我不明白这里的问题是什么。

【问题讨论】:

    标签: python-2.7 fabric


    【解决方案1】:

    robot_test() 是递归的,它在无限循环中调用自己,这就是它一直执行直到你取消的原因。

    删除对robot_test() 内部robot_test() 的调用。你想通过这个电话得到什么?因为我猜它是有目的的,所以不是错字。

    @task
    @runs_once
    def robot_test():
      environment_configuration = get_environment_configuration('Selenium')
      #set_hosts(environment_configuration)
      nodes = get_node_servers(environment_configuration['servers'])
      hubs = get_hub_servers(environment_configuration['servers'])
    
      execute(start_hub, hosts=hubs)
      execute(start_node, hosts=nodes)
    
      all = hubs + nodes
      execute(kill_node, hosts=(hubs + nodes))
    

    如果你真的想递归执行它,你需要一个参数来知道递归应该何时停止。

    【讨论】:

    • 你成功了。我正忙于其他事情,不小心将名称 robots_test 用于两种不同的方法。
    【解决方案2】:

    您应该将runs_once 装饰器添加到每个应该只运行一次的函数中。例如:

    @runs_once
    def start_node():
        with settings(user="automation1"):
            with cd('/home/automation1/inventory.robot/grid'):
                output = run('nohup ./start_node.sh > node_out 2>&1 &')
    
    @runs_once
    def start_hub():
        with settings(user="automation1"):
            with cd('/home/automation1/inventory.robot/grid'):
                run('nohup ./start_hub.sh > hub_out 2>&1 &')
    
    @runs_once
    def robot_test():
        with settings(user="automation1"):
            with cd('/home/automation1/inventory.robot/grid'):
                run('python grid.py')
    

    如果没有 runs_once 装饰器,每个函数将每个主机运行一次,而不是每个主机集运行一次。


    对于每个主机一次,您可以执行以下操作:

    from fabric.context_managers import env
    
    env.hosts = hubs
    execute(start_hub)
    env.hosts = nodes
    execute(start_node)
    env.hosts = hubs
    execute(robot_test)
    

    【讨论】:

    • start_node、start_hub、robot_test 和 kill_node 应该在每个主机上运行一次。我的问题是每个主机运行多次而不是每个主机一次。
    猜你喜欢
    • 2016-01-27
    • 1970-01-01
    • 2021-10-09
    • 2015-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-11
    • 1970-01-01
    相关资源
    最近更新 更多