在ansible中循环json并使用json数据并行运行任务

ykejflvf  于 2023-02-01  发布在  其他
关注(0)|答案(1)|浏览(153)

我有以下要求。

  • 在json数据上循环
  • 使用以上数据并行运行任务

示例:我的json数据如下

{
 "xyx": 
    {
    "hostname": "xyz",
    "username": "root",
    "password": "welcome1",
    "password2": "welcome2",
    "version": "19.17",
    "toversion" : "19.18",
    "netconf": "bond",
    "baseversion": "18.8"
    },
"abc": {
    "hostname": "abc",
    "username": "root",
    "password": "welcome1",
    "password2": "welcome2",
    "version": "19.17",
    "toversion" : "19.18",
    "netconf": "bond",
    "baseversion": "18.8"
  }
}

我需要在主机名abcxyz中并行运行以下任务

- name: Image a system
  command: python3 image.pyc "{{ hostname }}" {{ version }}

有人能帮我实现这个目标吗?
我试着在JSON上循环,但不确定如何在任务中使用它来并行运行。

dy1byipe

dy1byipe1#

给定变量 * images * 中的字典。使用过滤器 * dict2items *

- name: Image a system
  command: "python3 image.pyc {{ item.value.hostname }} {{ item.value.version }}"
  loop: "{{ images|dict2items }}"

(not测试)
,或从字典中获取值

- name: Image a system
  command: "python3 image.pyc {{ item.hostname }} {{ item.version }}"
  loop: "{{ images.values()|list }}"

(not测试)
也可以为此创建字典。根据需要在 * vars * 中声明以下变量

hostname_version: "{{ images.values()|list|
                        items2dict(key_name='hostname',
                                   value_name='version') }}"

给予

hostname_version:
    abc: '19.17'
    xyz: '19.17'

然后,下面的任务应给出相同的结果

- name: Image a system
  command: "python3 image.pyc {{ item.key }} {{ item.value }}"
  loop: "{{ hostname_version|dict2items }}"

(not测试)
完整的测试行动手册示例

shell> cat pb.yml
- hosts: localhost

  vars:

    images:
      abc:
        baseversion: '18.8'
        hostname: abc
        netconf: bond
        password: welcome1
        password2: welcome2
        toversion: '19.18'
        username: root
        version: '19.17'
      xyx:
        baseversion: '18.8'
        hostname: xyz
        netconf: bond
        password: welcome1
        password2: welcome2
        toversion: '19.18'
        username: root
        version: '19.17'

    hostname_version: "{{ images.values()|list|
                          items2dict(key_name='hostname',
                                     value_name='version') }}"

  tasks:

    - debug:
        msg: "python3 image.pyc {{ item.value.hostname }} {{ item.value.version }}"
      loop: "{{ images|dict2items }}"
      loop_control:
        label: "{{ item.key }}"

    - debug:
        msg: "python3 image.pyc {{ item.hostname }} {{ item.version }}"
      loop: "{{ images.values()|list }}"
      loop_control:
        label: "{{ item.hostname }}"

    - debug:
        var: hostname_version

    - debug:
        msg: "python3 image.pyc {{ item.key }} {{ item.value }}"
      loop: "{{ hostname_version|dict2items }}"

给予

shell> ansible-playbook pb.yml 

PLAY [localhost] **********************************************************************************

TASK [debug] **************************************************************************************
ok: [localhost] => (item=abc) => 
  msg: python3 image.pyc abc 19.17
ok: [localhost] => (item=xyx) => 
  msg: python3 image.pyc xyz 19.17

TASK [debug] **************************************************************************************
ok: [localhost] => (item=abc) => 
  msg: python3 image.pyc abc 19.17
ok: [localhost] => (item=xyz) => 
  msg: python3 image.pyc xyz 19.17

TASK [debug] **************************************************************************************
ok: [localhost] => 
  hostname_version:
    abc: '19.17'
    xyz: '19.17'

TASK [debug] **************************************************************************************
ok: [localhost] => (item={'key': 'abc', 'value': '19.17'}) => 
  msg: python3 image.pyc abc 19.17
ok: [localhost] => (item={'key': 'xyz', 'value': '19.17'}) => 
  msg: python3 image.pyc xyz 19.17

PLAY RECAP ****************************************************************************************
localhost: ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

问:***"如何并行运行任务?"***
答:异步运行循环中的任务。请参阅异步操作和轮询。例如,要测试计时,下面的行动手册将运行命令 * sleep 3 *

shell> cat pb.yml
- hosts: localhost

  vars:

    images:
      abc:
        baseversion: '18.8'
        hostname: abc
        netconf: bond
        password: welcome1
        password2: welcome2
        toversion: '19.18'
        username: root
        version: '19.17'
      xyx:
        baseversion: '18.8'
        hostname: xyz
        netconf: bond
        password: welcome1
        password2: welcome2
        toversion: '19.18'
        username: root
        version: '19.17'

    hostname_version: "{{ images.values()|list|
                          items2dict(key_name='hostname',
                                     value_name='version') }}"

  tasks:

    - command:
        cmd: "sleep 3"
        #cmd: "echo python3 image.pyc {{ item.key }} {{ item.value }}"
      loop: "{{ hostname_version|dict2items }}"
      register: async_out
      async: 5
      poll: 0
    - debug:
        var: async_out
      when: debug|d(false)|bool

    - async_status:
        jid: "{{ item.ansible_job_id }}"
      loop: "{{ async_out.results }}"
      loop_control:
        label: "{{ item.item.key }}"
      register: async_poll
      until: async_poll.finished
      retries: 5
    - debug:
        var: async_poll
      when: debug|d(false)|bool

    - debug:
        msg: |
          {% for result in async_poll.results %}
          {{ result.item.item.key }} {{ result.start }} {{ result.end }}
          {% endfor %}

给予

shell> ansible-playbook pb.yml

PLAY [localhost] **********************************************************************************

TASK [command] ************************************************************************************
changed: [localhost] => (item={'key': 'abc', 'value': '19.17'})
changed: [localhost] => (item={'key': 'xyz', 'value': '19.17'})

TASK [debug] **************************************************************************************
skipping: [localhost]

TASK [async_status] *******************************************************************************
FAILED - RETRYING: [localhost]: async_status (5 retries left).
changed: [localhost] => (item=abc)
changed: [localhost] => (item=xyz)

TASK [debug] **************************************************************************************
skipping: [localhost]

TASK [debug] **************************************************************************************
ok: [localhost] => 
  msg: |-
    abc 2023-01-24 13:17:48.526694 2023-01-24 13:17:51.530734
    xyz 2023-01-24 13:17:48.831822 2023-01-24 13:17:51.836860

PLAY RECAP ****************************************************************************************
localhost: ok=3    changed=2    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0

从上一次调试中,您可以看到:

  • 第二个命令比第一个命令晚 * 0.3s * 启动
  • 第一个命令在第二个命令启动后 * 2.7s * 完成

这是您在Ansible中可以获得的"最佳"并行性。

相关问题