![如何强制 Ansible‘shell’任务使用‘changed_when’条件改变状态?](https://linux22.com/image/786757/%E5%A6%82%E4%BD%95%E5%BC%BA%E5%88%B6%20Ansible%E2%80%98shell%E2%80%99%E4%BB%BB%E5%8A%A1%E4%BD%BF%E7%94%A8%E2%80%98changed_when%E2%80%99%E6%9D%A1%E4%BB%B6%E6%94%B9%E5%8F%98%E7%8A%B6%E6%80%81%EF%BC%9F.png)
我正在使用 Ansible 任务运行脚本,该脚本安装了一些存储库,我的目标是在运行更改模式时显示更改的状态以通知,如果检查模式未激活,则该脚本将运行。
我的第一个任务是检查这个存储库是否存在:
- name: Check repository existence
become: yes
shell: yum repolist -v | grep some-repository
register: repo_exists
check_mode: false
failed_when: false
changed_when: false
此任务应在检查模式下运行,以便我可以使用repo_exists变量在下一个任务中。当我在检查模式下运行 Ansible 时,这可以正常工作,这是输出:
"msg": {
"changed": false,
"cmd": "yum repolist -v | grep some-repository",
"delta": "0:00:02.022965",
"end": "2023-06-12 13:06:54.611504",
"failed": false,
"failed_when_result": false,
"msg": "non-zero return code",
"rc": 1,
"start": "2023-06-12 13:06:52.588539",
"stderr": "",
"stderr_lines": [],
"stdout": "",
"stdout_lines": []
}
我的脚本应仅在存储库丢失时运行:
- name: Add repository
become: yes
shell: echo "install repository"
changed_when: "repo_exists.rc != 0"
when: "repo_exists.rc != 0"
when
条件应确保,任务仅在以下情况下运行:rc不是零,这意味着存储库不在 repolist 中。
changed_when
应该显示状态已改变即使在检查模式下rc不为零。
除了预期的结果,我可以看到状态跳过:
{
"changed": false,
"cmd": "echo \"install repository\"",
"delta": null,
"end": null,
"msg": "Command would have run if not in check mode",
"rc": 0,
"start": null,
"stderr": "",
"stderr_lines": [],
"stdout": "",
"stdout_lines": []
}
我不明白,为什么任务处于跳过状态以及我做错了什么?这是在运行检查模式时查看更改状态的 shell 任务的正确方法吗?
答案1
我不明白为什么任务处于跳过状态
正如前面提到的返回值
"msg": "Command would have run if not in check mode"
因为你是使用检查模式. 如果你真的想防止任务检查模式你需要使用
---
- hosts: localhost
become: false
gather_facts: false
tasks:
- name: Check repository existence
shell:
cmd: yum repolist -v | grep not-existing
register: repo_exists
# Since it is a reporting task
# which needs to deliver a result in any case
failed_when: repo_exists.rc != 0 and repo_exists.rc != 1
changed_when: false
check_mode: false
- name: Add repository
shell:
cmd: "echo {{ repo_exists.stdout_lines }}"
when: repo_exists.rc != 0
changed_when: repo_exists.rc != 0
check_mode: false
ansible-playbook main.yml --check -v
输出结果为
TASK [Check repository existence] ************
ok: [localhost] => changed=false
cmd: yum repolist -v | grep not-existing
delta: '0:00:05.598043'
end: '2023-06-13 18:00:31.862501'
failed_when_result: false
msg: non-zero return code
rc: 1
start: '2023-06-13 18:00:26.264458'
stderr: ''
stderr_lines: <omitted>
stdout: ''
stdout_lines: <omitted>
TASK [Add repository] ************************
changed: [localhost] => changed=true
cmd: echo []
delta: '0:00:00.014928'
end: '2023-06-13 18:00:32.318558'
msg: ''
rc: 0
start: '2023-06-13 18:00:32.303630'
stderr: ''
stderr_lines: <omitted>
stdout: '[]'
stdout_lines: <omitted>
PLAY RECAP ***********************************
localhost : ok=2 changed=1
但请记住,这不再是shell
模块的试运行。
每次都会运行它 - 不是必需的。我的目标是显示脚本是否会超出检查模式 - 因此将显示更改状态。
您所要求的是,shell
命令或脚本本身首先需要知道它是否在运行check_mode: true
,其次如果在运行,则其行为会有所不同。换句话说,您的脚本需要支持check_mode
。这是shell
模块正在做的事情部分,它不能代表或执行您的命令和脚本。
也许我理解错了,我定义的输出无法实现?
你至少需要实现类似
- name: Add repository
shell:
cmd: "{{ ansible_check_mode | lower }} || echo {{ repo_exists.stdout_lines }}"
changed_when: "repo_exists.rc != 0"
when: repo_exists.rc != 0
check_mode: false
使命令意识到check_mode
,让它运行或不运行,并导致输出
TASK [Add repository] ***************
changed: [localhost] => changed=true
cmd: true || echo []
delta: '0:00:00.023104'
end: '2023-06-15 11:00:00.550097'
msg: ''
rc: 0
start: '2023-06-15 11:00:00.526993'
stderr: ''
stderr_lines: <omitted>
stdout: ''
stdout_lines: <omitted>
TASK [Add repository] ***************
changed: [localhost] => changed=true
cmd: false || echo []
delta: '0:00:00.014626'
end: '2023-06-15 11:00:00.098413'
msg: ''
rc: 0
start: '2023-06-15 11:00:00.083787'
stderr: ''
stderr_lines: <omitted>
stdout: '[]'
stdout_lines: <omitted>
由于这似乎已经变得非常复杂,你可能需要仔细考虑你真正想要实现的目标。X/Y问题并且已经有模块正在工作,只需添加一个存储库yum_repository
模块 – 添加或删除 YUM 存储库与 f全部check_mode
支持或更新ini_file
模块 – 调整 INI 文件中的设置. 完全没有必要进行“检查添加如果仅当”或重新实现已经存在的功能。