Ansible "until:" 和寄存器变量

Ansible "until:" and register variables

我接到了这个任务

---
- win_updates:
  ignore_errors: yes
    category_names: '*'
    reboot: yes
    state: installed
  register: win_updates
  until: win_updates.installed_update_count == 0

它会更新 Windows 服务器并重新启动,直到没有更新为止。

在剧本的最后我想打印出所有已安装的更新:

- debug:
    msg: '{{ win_updates.updates }}'

这在我安装没有“直到:”的更新时有效。现在它是空的。从 Ansible 文档中可以看出,当您使用循环注册变量时,结构不同:

When you use register with a loop, the data structure placed in the variable will contain a results attribute that is a list of all responses from the module. This differs from the data structure returned when using register without a loop

所以我试图打印出不存在的“{{ win_updates.results }}”:

FAILED! => {"msg": "'dict object' has no attribute 'results'"}

当我调试 win_updates 时,我确实找不到任何结果:

"msg": {
    "attempts": 2,
    "changed": false,
    "failed": false,
    "failed_update_count": 0,
    "filtered_updates": {},
    "found_update_count": 0,
    "installed_update_count": 0,
    "reboot_required": false,
    "updates": {}
}

对我来说,我的循环似乎覆盖了变量而不是添加每个 运行 .results。 until: 和 loop: 之间有什么我不知道的区别吗?

在此处创建一个名为 customfilter1 的自定义过滤器:

#!/usr/bin/python
import os
import json

class FilterModule(object):
    def filters(self):
        return {
            'customfilter1': self.customfilter1
        }

    def customfilter1(self, obj, file):
        if obj["attempts"] == 1:            
            result = [obj]
            json_file = json.dumps(result, sort_keys = False, indent= 4)
            with open(file, 'w') as f:
                f.write(json_file)
        else:         
            with open(file) as f:
                result = json.load(f)
            result.append(obj)
            json_file = json.dumps(result, sort_keys = False, indent= 4)
            with open(file, 'w') as f:
                f.write(json_file)           

        return False

插件 returns 始终为 false...

你使用它:

- win_updates:
  ignore_errors: yes
    category_names: '*'
    reboot: yes
    state: installed
  register: win_updates
  until: win_updates | customfilter1(file) or win_updates.installed_update_count == 0
  vars:
    file: /yourfolder/file.json

文件json包含所有历史记录,因此您可以修改插件以仅保留您想要的...

[
{
    "attempts": 1,
    "changed": false,
    "failed": false,
    "failed_update_count": 0,
    "filtered_updates": {},
    "found_update_count": 0,
    "installed_update_count": 2,
    "reboot_required": false,
    "updates": {something...}
},
{
    "attempts": 2,
    "changed": false,
    "failed": false,
    "failed_update_count": 0,
    "filtered_updates": {},
    "found_update_count": 0,
    "installed_update_count": 1,
    "reboot_required": false,
    "updates": {something...}
}, and so on

]

之后你可以做一个任务来捕获包的所有名称..(文件是 json 格式,字典列表)

所以我没有window所以我不知道你的输出..

随机数样本:

- name: simulate
  command: shuf -i 0-5 -n 1
  register: out 
  until: out | customfilter1(file) or out.stdout | int == 2
  retries: 100
  vars:
    file: /yourfolder/file.json

- name: group results
  set_fact:
    result: "{{ result | d([]) + [item.stdout] }}"
  loop: "{{ lookup('file',file) | from_json }}"
  vars:
    file: /yourfolder/file.json

- name: group results
  debug:
    var: result

显示结果(当随机数为2时停止)你有所有随机数的列表:

ok: [localhost] => {
    "result": [
        "5",
        "3",
        "3",
        "1",
        "3",
        "0",
        "4",
        "0",
        "5",
        "2"
    ]
}

有一个解决方法,希望能找到 Ansible 的方法:https://github.com/ansible/ansible/issues/58918#issuecomment-1057451791