在不编写新模块的情况下处理 Ansible 中的测试任务
Processing of test-tasks in Ansible without writing a new module
我想用 Ansible 在 OpenNebula 中部署一些虚拟机。
比如我用command/shell模块创建vms(因为没有opennebula Ansible中的模块,我没有足够的资格来编写它):
- name: Create VMs
become_user: oneadmin
command: onevm create --name "{{ item.1.name }}"
with_items: "{{ vms }}"
但是我当然需要检查是否已经创建了同名的虚拟机,我的解决方案如下:
- name: Check what VMs already created
become_user: oneadmin
ignore_errors: yes
shell: onevm list --csv | grep -q "{{ item.name }}"
register: created_vms
with_items: "{{ vms }}"
loop_control:
label: "Check if VM {{ item.name }} created"
- name: Create VMs
become_user: oneadmin
command: onevm create --name "{{ item.1.name }}"
when: item.0|failed
with_together:
- "{{ created_vms.results }}"
- "{{ vms }}"
loop_control:
label: "Create VM {{ item.1.name }}"
它本身很麻烦,而且在失败时,我在 Ansible 中看到了一个麻烦的输出:
TASK [create-vms : Check what VMs already created]
************************************************
failed: [10.1.48.190] (item=Check if VM audit created) => {"changed": true, "cmd": "onevm list --csv | grep -q \"audit\"", "delta": "0:00:00.806504", "end": "2017-06-28 12:49:00.808454", "failed": true, "item": lalalalala etc.
有没有更有效的方法解决这个问题?
您正在使用 ignore_errors: yes
,因此 ansible 将忽略错误,但由于 shell
任务的失败状态是 return 代码,任何失败的 grep 都会将项目转换为失败并显示它。
更好的解决方案是简单地获取 运行 VM 的列表,如果它们在第一个任务的输出中,则在第二个任务中跳过它们:
- name: Get running VMs
become_user: oneadmin
shell: onevm list --csv
register: created_vms
- name: Create VMs
become_user: oneadmin
command: onevm create --name "{{ item.name }}"
when: item not in created_vms.stdout
with_items:
- "{{ vms }}"
loop_control:
label: "Create VM {{ item.1.name }}"
这里有一些巧妙的技巧供您使用:
- name: Create VM if required
become_user: oneadmin
shell: onevm list --csv | grep -q "{{ item.name }}" && echo "Exists" || onevm create --name "{{ item.name }}"
changed_when: created_vms.stdout != 'Exists'
register: created_vms
with_items: "{{ vms }}"
这里我们使用shell&&
和||
运算符打印"Exists"如果grep
成功或者执行onevm create
如果grep
失败。请注意,实际 grep
退出代码被屏蔽,模块退出代码为 echo
或 onevm create
。这解决了您仅创建不存在的 VM 的问题。
另一件事是 changed_when
– 这将确保 Ansible 以绿色打印现有 VM,以黄色创建。 created_vms
在循环内使用时是当前迭代的结果,在当前任务后使用它时填充组合循环结果。
感谢 Konstantin Suvorov 的回答!得出了类似的解决方案:
- name: Create VMs
become_user: oneadmin
shell: onevm list --csv | grep "{{ item.name }}" || onevm create --name "{{ item.name }}"
register: created_vms
changed_when: created_vms.stdout.find(item.name) == -1
with_items: "{{ vms }}"
loop_control:
label: "Create VM {{ item.name }}"
希望对某人有用
我想用 Ansible 在 OpenNebula 中部署一些虚拟机。 比如我用command/shell模块创建vms(因为没有opennebula Ansible中的模块,我没有足够的资格来编写它):
- name: Create VMs
become_user: oneadmin
command: onevm create --name "{{ item.1.name }}"
with_items: "{{ vms }}"
但是我当然需要检查是否已经创建了同名的虚拟机,我的解决方案如下:
- name: Check what VMs already created
become_user: oneadmin
ignore_errors: yes
shell: onevm list --csv | grep -q "{{ item.name }}"
register: created_vms
with_items: "{{ vms }}"
loop_control:
label: "Check if VM {{ item.name }} created"
- name: Create VMs
become_user: oneadmin
command: onevm create --name "{{ item.1.name }}"
when: item.0|failed
with_together:
- "{{ created_vms.results }}"
- "{{ vms }}"
loop_control:
label: "Create VM {{ item.1.name }}"
它本身很麻烦,而且在失败时,我在 Ansible 中看到了一个麻烦的输出:
TASK [create-vms : Check what VMs already created]
************************************************
failed: [10.1.48.190] (item=Check if VM audit created) => {"changed": true, "cmd": "onevm list --csv | grep -q \"audit\"", "delta": "0:00:00.806504", "end": "2017-06-28 12:49:00.808454", "failed": true, "item": lalalalala etc.
有没有更有效的方法解决这个问题?
您正在使用 ignore_errors: yes
,因此 ansible 将忽略错误,但由于 shell
任务的失败状态是 return 代码,任何失败的 grep 都会将项目转换为失败并显示它。
更好的解决方案是简单地获取 运行 VM 的列表,如果它们在第一个任务的输出中,则在第二个任务中跳过它们:
- name: Get running VMs
become_user: oneadmin
shell: onevm list --csv
register: created_vms
- name: Create VMs
become_user: oneadmin
command: onevm create --name "{{ item.name }}"
when: item not in created_vms.stdout
with_items:
- "{{ vms }}"
loop_control:
label: "Create VM {{ item.1.name }}"
这里有一些巧妙的技巧供您使用:
- name: Create VM if required
become_user: oneadmin
shell: onevm list --csv | grep -q "{{ item.name }}" && echo "Exists" || onevm create --name "{{ item.name }}"
changed_when: created_vms.stdout != 'Exists'
register: created_vms
with_items: "{{ vms }}"
这里我们使用shell&&
和||
运算符打印"Exists"如果grep
成功或者执行onevm create
如果grep
失败。请注意,实际 grep
退出代码被屏蔽,模块退出代码为 echo
或 onevm create
。这解决了您仅创建不存在的 VM 的问题。
另一件事是 changed_when
– 这将确保 Ansible 以绿色打印现有 VM,以黄色创建。 created_vms
在循环内使用时是当前迭代的结果,在当前任务后使用它时填充组合循环结果。
感谢 Konstantin Suvorov 的回答!得出了类似的解决方案:
- name: Create VMs
become_user: oneadmin
shell: onevm list --csv | grep "{{ item.name }}" || onevm create --name "{{ item.name }}"
register: created_vms
changed_when: created_vms.stdout.find(item.name) == -1
with_items: "{{ vms }}"
loop_control:
label: "Create VM {{ item.name }}"
希望对某人有用