【问题标题】:Ansible working with multiple loops in conditionsAnsible 在条件下使用多个循环
【发布时间】:2020-12-10 03:43:30
【问题描述】:

当任务本身也基于循环时,如何向基于循环的 ansible 任务添加条件?

例如,这是我的代码:

- hosts: all
  gather_facts: False
  vars:
    current_version: 826
    versions:
      - 805
      - 821
      - 824
      - 826
  tasks:
    - name: First Task
      find:
          paths: /Users/tomer/projects/personal/ansible/test
          patterns: snapshot* 
      register: files
      when:
        - current_version == item
      loop: "{{versions}}"

    - name: Second task
      set_fact:
        test_work:  "{{ true if item > 0 else false}}"
      loop:
        -  "{{ files | json_query('results[*].matched') }}"

到目前为止,这按预期工作。 如果current_version 与列表中的某个版本匹配,则第一项任务是查找名称为snapshot 的任何文件。

第二个任务迭代第一个任务的字典结果,并根据每个项目设置事实。 (在我的例子中,只有一项具有此属性)。

我想运行第二个任务,在第一个任务确实运行时,但是,changed 状态始终为false ,所以这个条件没有用。 我想添加current_version == item 的相同条件,但我不能在这里使用两次item

知道如何实现吗?

【问题讨论】:

    标签: ansible


    【解决方案1】:

    find 命令并不是真的去change anything,它只是查询文件系统而不做任何修改,所以它确实总是会给你一个false

    另一方面,您绝对可以使用itemskipped 字段。

    这就是说,我会简化你set_fact 上的循环,因为这里没有真正需要使用json_query

    这项任务可以很好地完成这项工作:

    - set_fact:
        test_work: "{{ item.matched > 0 }}"
      loop: "{{ files.results }}"
      when: item is not skipped
    

    另一个额外的提示是不要做类似的事情

    true if condition_that_evaluates_to_true else false
    

    而是马上做

    condition_that_evaluates_to_true
    

    这将是一个虚构的示例剧本

    - hosts: all
      gather_facts: no
          
      tasks:
        - find:
            path: /tmp
            pattern: dummy*
          when: item == current_version
          register: files
          loop: "{{ versions }}"
          vars:
            current_version: 826
            versions:
              - 805
              - 821
              - 824
              - 826
    
        - debug:
            msg:  "{{ item.matched > 0 }}"
          loop: "{{ files.results }}"
          when: item is not skipped
          loop_control:
            label: "{{ item.item }}"
    

    这会产生结果

    PLAY [all] *******************************************************************************************************
    
    TASK [find] ******************************************************************************************************
    skipping: [localhost] => (item=805) 
    skipping: [localhost] => (item=821) 
    skipping: [localhost] => (item=824) 
    ok: [localhost] => (item=826)
    
    TASK [debug] *****************************************************************************************************
    skipping: [localhost] => (item=805) 
    skipping: [localhost] => (item=821) 
    skipping: [localhost] => (item=824) 
    ok: [localhost] => (item=826) => {
        "msg": true
    }
    
    PLAY RECAP *******************************************************************************************************
    localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    

    【讨论】:

    • 感谢分析器。这是我所做的: - set_fact: test_work: "{{ item.matched > 0 }}" 循环: - "{{ files.results }}" 它导致了这个错误:The error was: 'list object' has no attribute 'matched
    • 请注意我是如何创建循环的:loop: "{{ files.results }}" 按您的方式进行操作,实际上是在创建一个列表列表,这会导致您出现此错误。
    猜你喜欢
    • 1970-01-01
    • 2017-11-12
    • 2016-03-29
    • 1970-01-01
    • 2022-11-15
    • 2021-11-06
    • 2015-01-02
    • 2016-08-20
    • 1970-01-01
    相关资源
    最近更新 更多