【问题标题】:ansible looping through the result and finding filesansible 循环遍历结果并查找文件
【发布时间】:2019-10-13 04:11:04
【问题描述】:

我正在使用 ansible 来配置 10-20 个 linux 系统。我有一组工具,我在我的清单文件中定义了版本,如:

tools:
  - tool: ABC
    version: 7.8
  - tool: XYZ
    version: 8.32.1

现在,在我的播放 yml 文件中,我想遍历它们并拥有必要的安装逻辑。如:

调试工具循环

  - name: Find installer files
    copy:
      src=
    with_items:
    - "{{ tools }}"
    when:
      tools.tool == "ABC"

在我的例子中,{{tools.tool}}/{{tools.version}} 有一个 tgz 文件,我需要在远程位置解压缩它。你知道怎么做吗?我试过这些:

- name: Find installer files
    vars:
      files: {{ lookup("fileglob",'tools/{{item.tool}}/linux/{{item.version}}/*') }}
    unarchive:
      src: "{{ files }}"
      dest: "tools/{{item.tool}}/{{item.version}}/"
    with_items:
    - "{{ tools }}"
    when:
      item.tool == "ABC"

- name: Find installer files
   debug:
     msg: "{{ item}}"
   with_items:
   - "{{ tools }}"
   with_fileglob:
   - "tools/{{item.tool}}/linux/{{item.version}}/*"
   when:
     item.toolchain == "ABC"

但没有一个有效。感谢您的帮助。

【问题讨论】:

    标签: ansible file-globs


    【解决方案1】:

    我认为,如果目录中有多个文件,您自己的解决方案会中断,这并不简单。
    因此,如果您在目录中只有一个文件,我根本不会使用fileglob,而是为它定义一个固定名称,您可以生成知道的工具和版本。

    我也经常看到对此类事情的需求,但没有找到任何好的解决方案。只有这样丑陋的东西:

    - name: example book
      hosts: localhost
      become: false
      gather_facts: false
      vars:
        tools:
          - tool: ABC
            version: 7.8
          - tool: XYZ
            version: 8.32.1
        tools_files: []
      tasks:
        - name: prepare facts
          set_fact:
            tools_files: "{{ tools_files + [{'tool': item.tool | string, 'version': item.version | string, 'files': lookup('fileglob', 'tools/' ~ item.tool ~ '/linux/' ~ item.version ~ '/*', wantlist=True)}] }}"
          with_items:
            - "{{ tools }}"
        - name: action loop
          debug:
            msg: "{{ {'src': item[1], 'dest': 'tools/' ~ item[0].tool ~ '/' ~ item[0].version ~ '/'} }}"
          with_subelements:
            - "{{ tools_files }}"
            - files
          when:
            item[0].tool == "ABC"
    

    或

    - name: example book
      hosts: localhost
      become: false
      gather_facts: false
      vars:
        tools:
          - tool: ABC
            version: 7.8
          - tool: XYZ
            version: 8.32.1
        tools_files: []
      tasks:
        - name: prepare facts
          set_fact:
            tools_files: "{{ tools_files + [{'tool': item.tool | string, 'version': item.version | string, 'files': lookup('fileglob', 'tools/' ~ item.tool ~ '/linux/' ~ item.version ~ '/*', wantlist=True)}] }}"
          with_items:
            - "{{ tools }}"
        - name: action loop
          debug:
            msg: "{{ {'src': item[1], 'dest': 'tools/' ~ item[0].tool ~ '/' ~ item[0].version ~ '/'} }}"
          with_items:
            - "{{ tools_files | subelements('files') }}"
          when:
            item[0].tool == "ABC"
    

    也许我错过了一些东西,因为这些东西是一个非常基本的功能(循环通过一个数组生成一个结果数组beeing能够使用所有可用的功能,而不仅仅是map使用filters,其中一些重要的东西不可用或不能使用,因为 map 总是将输入端口作为过滤器的第一个参数)。

    【讨论】:

    • 谢谢。我发现在 ansible 中循环是一项极其困难的任务。我猜对某些人来说,编码比声明式风格要容易得多。
    • 确实如此。不仅是循环,还有其他使播放灵活并因此通用/可重用的东西通常需要多个声明块,而不是每个动作只有两个行代码。
    【解决方案2】:

    其实很简单。这对我有用:

    - name: Find installer files
      unarchive:
        src: 
        "lookup('fileglob','tools/item.tool/linux/item.version/*') }}"
        dest: "tools/{{item.tool}}/{{item.version}}/"
        with_items:
        - "{{ tools }}"
        when:
          item.tool == "ABC"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-09
      • 1970-01-01
      • 2013-09-14
      • 2019-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多