在Ansible中迭代哈希只会将最后的结果保存在寄存器中

时间:2019-02-07 12:28:18

标签: ansible

我有一个Ansible脚本,它在指定目录中获取磁盘映像,对其进行迭代,然后将其导入RHEV。除了它只导入最后一个磁盘映像之外,我都可以使用它。

图像信息存储在散列变量中,该散列变量是使用从磁盘提取的信息创建的。一切都按预期完成,并且假设我在保存称为“ disk_image_info”的哈希值时做错了什么。这在任务“收集要导入的信息”中。

我还看到Ansible的旧版本听起来与此非常相似,但是我使用的版本中应该包含此修复程序:

ansible 2.6.12
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Sep 12 2018, 05:31:16) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]

我的任务如下:

- name: Extract image
  unarchive:
    src: "{{item}}"
    dest: "{{rhev_image_tmp}}"
    list_files: true
  with_fileglob:
    - "{{rhev_image_tmp}}/*.tar.gz"
  register: extracted_image
  when: directory_created is succeeded

- name: Get the image size
  shell: qemu-img info "{{item}}" | grep 'virtual size' | awk '{print $3}'
  with_fileglob:
    - "{{rhev_image_tmp}}/*.qcow2"
  register: disk_size
  when: extracted_image is succeeded

- name: Gather file information for import
  set_fact:
    disk_image_info:
      name: "{{item.files[0]}}" # There is always only one file here for my situation
      size: 40G #"{{disk_size.results}}" # Will fix hard code later
      src: "{{item.dest}}/{{item.files[0]}}" # There is always only one file here for my situation
  with_items: "{{extracted_image.results}}"

- name: Load disk image into RHEV
  ovirt_disk:
    auth: "{{rhevm_auth}}"
    name: "{{item.name}}"
    interface: virtio
    size: "{{item.size}}iB"
    format: cow
    image_path: "{{item.src}}"
    storage_domain: "{{gluster_storage_name}}"
  with_items:
    - "{{disk_image_info}}"
  when: disk_size is succeeded

编辑: 我已经确认我的循环覆盖了任务“收集要导入的文件信息”中的先前条目。因此,进入该任务的项目列表按预期工作。

更新: 我在Clockworknet的帮助下对任务进行了更改,并提出了以下建议,但仍然导致值的覆盖:

- name: Gather file information for import
  include: set_image_info.yml
  with_items: "{{extracted_image.results}}"
  loop_control:
    loop_var: disk_image_info

set_image_info.yml:

- name: Set disk_image_info
  set_fact:
    disk_image_info:
        name: "{{disk_image_info.files[0]}}"
        size: 40G
        src: "{{disk_image_info.dest}}/{{disk_image_info.files[0]}}"
- name: Output disk info iteration
  debug:
    msg: "{{disk_image_info}}"

此外,作为参考,我从未归档的寄存器中获取以下信息:

changed: [dev1.dds.io] => (item=/var/images/Kali_Disk1.qcow2.tar.gz) => {
    "changed": true, 
    "dest": "/var/images", 
    "extract_results": {
        "cmd": [
            "/bin/gtar", 
            "--extract", 
            "-C", 
            "/var/images", 
            "-z", 
            "-f", 
            "/root/.ansible/tmp/ansible-tmp-1549567288.17-253158870541109/source"
        ], 
        "err": "/bin/gtar: Ignoring unknown extended header keyword `LIBARCHIVE.creationtime'\n/bin/gtar: Ignoring unknown extended header keyword `SCHILY.dev'\n/bin/gtar: Ignoring unknown extended header keyword `SCHILY.ino'\n/bin/gtar: Ignoring unknown extended header keyword `SCHILY.nlink'\n", 
        "out": "", 
        "rc": 0
    }, 
    "files": [
        "Kali_Disk1.qcow2"
    ], 
    "gid": 0, 
    "group": "root", 
    "handler": "TgzArchive", 
    "invocation": {
        "module_args": {
            "attributes": null, 
            "backup": null, 
            "content": null, 
            "creates": null, 
            "delimiter": null, 
            "dest": "/var/images", 
            "directory_mode": null, 
            "exclude": [], 
            "extra_opts": [], 
            "follow": false, 
            "force": null, 
            "group": null, 
            "keep_newer": false, 
            "list_files": true, 
            "mode": null, 
            "owner": null, 
            "regexp": null, 
            "remote_src": false, 
            "selevel": null, 
            "serole": null, 
            "setype": null, 
            "seuser": null, 
            "src": "/root/.ansible/tmp/ansible-tmp-1549567288.17-253158870541109/source", 
            "unsafe_writes": null, 
            "validate_certs": true
        }
    }, 
    "item": "/var/images/Kali_Disk1.qcow2.tar.gz", 
    "mode": "0755", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:var_t:s0", 
    "size": 64, 
    "src": "/root/.ansible/tmp/ansible-tmp-1549567288.17-253158870541109/source", 
    "state": "directory", 
    "uid": 0
}

1 个答案:

答案 0 :(得分:0)

这实际上不是答案,只是比注释部分更容易格式化。从顶部开始,您有:

- name: Extract image
  unarchive:
    src: "{{item}}"
    dest: "{{rhev_image_tmp}}"
    list_files: true
  with_fileglob:
    - "{{rhev_image_tmp}}/*.tar.gz"
  register: extracted_image
  when: directory_created is succeeded

因此,此任务将查找位于"{{rhev_image_tmp}}/*.tar.gz"的所有文件。然后,对于找到的每个文件,它将运行unarchive模块,并将该模块的输出存储在extracted_image中。这意味着当您移至后续任务时,extracted_image仅包含循环中最后次的输出。

当您到达- name: Gather file information for import时,您尝试循环浏览with_items: "{{extracted_image.results}}",但是您在extracted_image发布的输出中显示它不包含“结果”键-所以我不明白那里应该发生什么。

您对- name: Get the image size所做的操作也完全相同,因此您最终得到的'disk_size'再次仅包含循环中最后一次的输出。

下面是如何处理注册循环输出的示例:

---
- name: Loop through the tarballs
  include: extract_image.yml
  with_fileglob: "{{rhev_image_tmp}}/*.tar.gz"
- name: Show the registered data
  debug:
    var: extracted_images

extract_image.yml

---
- unarchive:
    src: "{{item}}"
    dest: "{{rhev_image_tmp}}"
    list_files: true
  register: image_data
- set_fact:
    extracted_images: "{{ extracted_images | default({}) | combine( {item | basename: image_data} ) ) }}"

因此,您将获得字典的字典,其中包含循环每次通过的输出。您还需要在其他循环中执行此操作。

您仍然需要弄清楚如何构建“ disk_image_info”字典。

我建议先处理两个循环,然后再使用调试模块查看两个变量的内容。一旦了解了结构,就可以弄清楚如何提取相关数据以创建“ disk_image_info”。