0

我想用Ansible在OpenNebula中部署一些虚拟机。比如我用command / shell模块创建 vms (因为 Ansible 中没有opennebula模块,而且我没有足够的资格来编写它):

- name: Create VMs
  become_user: oneadmin
  command: onevm create --name "{{ item.1.name }}"
  with_items: "{{ vms }}"

但当然我需要检查是否已经创建了同名的 vm,我的解决方案如下所示:

- 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.

有没有更有效的方法来解决这个问题?

4

3 回答 3

0

这里有一些巧妙的技巧给你:

- 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执行。请注意,实际退出代码被屏蔽,模块退出代码为or 。这解决了您仅创建不存在的 VM 的问题。onevm creategrepgrepechoonevm create

另一件事是changed_when——这将确保 Ansible 以绿色打印现有 VM 并以黄色创建。created_vms在循环内使用时是当前迭代的结果,当您在当前任务之后使用它时会填充组合循环结果。

于 2017-06-28T13:15:55.153 回答
0

您正在使用ignore_errors: yes,因此 ansible 将忽略错误,但由于shell任务的失败状态是返回码,因此任何失败的 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 }}"
于 2017-06-28T10:06:08.770 回答
0

感谢康斯坦丁·苏沃洛夫的回答!得出了类似的解决方案:

- 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 }}"

希望它对某人有用

于 2017-06-30T05:26:11.337 回答