【问题标题】:I need to sort env.hosts to run tasks in a specific order我需要对 env.hosts 进行排序以按特定顺序运行任务
【发布时间】:2016-02-13 04:21:59
【问题描述】:

我需要从角色定义中对主机进行排序,以便它们可以按特定顺序运行这些任务。

我正在实施 PostgreSQL BDR (http://2ndquadrant.com/en-us/resources/bdr/) 部署程序。为了成功,您需要在一个主机中创建一个 BDR 组,然后才能在所有其他主机中加入该 BDR 组。

用户需要从列表中选择第一个主机。

----已编辑----

我尝试动态设置 env.hosts 但它不起作用。

env.roledefs = {
  'array1':    [],
}

env.hostsdefs = {
  'array1': [
    {'host': 'data-03', 'server': 'root@data-03'},
    {'host': 'data-01', 'server': 'root@data-01'},
  ],
}

@serial
def sort_and_echo(default_host):
    sort_host(default_host)
    echoing()

@serial
def sort_host(default_host):
    hostnames = env.hostsdefs[env.roles[0]]
    new_hosts = []
    for host in (hostnames):
        if (host['host'] != default_host):
            new_hosts.append(host['server'])
        else:
            new_hosts = [host['server']] + new_hosts
    env.hosts = new_hosts


@serial
def echoing():
    print env.hosts
    print('current host: %s' % (env.host_string))

这样,如果我尝试:

fab -R array1 sort_and_echo:default_host=data-03
['root@data-03', 'root@data-01']
current host: None

Done.

它不会为列表中的每个服务器运行回显。

但是,如果我尝试一种排序,然后在同一命令中回显:

fab -R array1 sort_host:default_host=data-03 echoing

它将提供预期的输出:

[root@data-03] Executing task 'echoing'
['root@data-03', 'root@data-01']
current host: root@data-03
[root@data-01] Executing task 'echoing'
['root@data-03', 'root@data-01']
current host: root@data-01

Done.

如何在运行时更改主机列表?

【问题讨论】:

  • 我对 bdr 的了解不够,但如果您首先需要 node-02,为什么不直接更改 env.roledefs 中的顺序 - 也许我误解了您。你能提供你所拥有的“解决方案”,这样我就可以做出正面和反面。谢谢。
  • 哈维尔,谢谢。我目前的解决方案是为每项任务强制使用服务器。但没有按预期工作。现在我正在比较上面解释的两个测试的 env 输出,以便找到触发器
  • 好的。你能更好地解释你需要什么。忘记postgres,只解释你需要fabric做什么——或者更好的是,你想让它做什么(通常不同)。一些 sudo 代码有时会大有帮助。
  • @Javier,抱歉,虽然我之前编辑过。是不是更清楚了?

标签: python fabric postgresql-bdr


【解决方案1】:

过了一会儿,我解决了我的问题。这比预期的要容易。无需破解。

传递 hosts 参数将使主机在数组请求时添加。由于fabric的标准行为是丢弃重复数据删除(检查http://docs.fabfile.org/en/1.10/usage/execution.html#combining-host-lists中的主机列表重复数据删除),它解决了这个问题。

如果不传参数,会使用数组的第一个

env.roledefs = {
'array1': {'hosts': ['root@data-01', 'root@data-03'], }
}

所以当我尝试时:

fab -R array1 -H data-03 echoing

它将以正确的顺序运行:

[root@data-03] Executing task 'echoing'
['root@data-03']
current host: root@data-03
[root@data-01] Executing task 'echoing'
['root@data-03']
current host: root@data-01

Done.

【讨论】:

    【解决方案2】:

    如果我理解正确,你可以这样做:

    @task
    def environment(*args):
        env.hosts = args
    
    @task
    def dev(*args):
        hosts = list(args)
        hosts.append('dev.host1')
        hosts.append('dev.host2')
        environment(*hosts)
    
    @task
    @serial # <--- PS. you dont really need this
    def echoing():
        print env.hosts
        print('current host: %s' % (env.host_string))
    

    你现在可以这样称呼它:

    fab environment:node1.host.com,node2.host.com echoing
    

    或:

    # which is a "predetermined" list
    fab dev echoing
    # or add stuff to dev
    fab dev:qa.node.host.com echoing
    # ^^ this will just append the qa host to your existing list
    

    【讨论】:

    • 首先,感谢您的宝贵时间。正如我所写,如果我按顺序尝试任务,它会起作用:fab -R array1 sort_host:default_host=data-03 echoing。
    • 首先,感谢您的宝贵时间。正如我所写,如果我按顺序尝试任务,它会起作用:fab -R array1 sort_host:default_host=data-03 echoing。但我确实想封装在一项任务中。我想,当服务器无效时,我会尝试测试一种不同的方法来拒绝
    • @otaviofcs 如果您打算使用roledefshostsdefs,恐怕您将不得不按照现在的方式破解它。除非你想去破解织物内部。但这不是一个糟糕的解决方案,您忽略 hostsdefsroledefs 并将其移至任务级别。对主人做任何你想做的魔法;将其分配给env.hosts 并调用您拥有的任何次要任务。 -- 你的需求只有你自己知道,我只能尽力帮忙;)
    • 再次感谢您的光临。这不是一个微不足道的问题,因为它不是面料的工作方式。我明白了。
    猜你喜欢
    • 2021-04-13
    • 2016-11-01
    • 1970-01-01
    • 2012-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    相关资源
    最近更新 更多