安装软件包时是什么触发了 "changed: true"?
What triggers a "changed: true" when installing a package?
我有几个使用 ansible
的 Debian 服务器。其中一项任务是安装一些软件包。行为因机器而异,特别是在重新运行 剧本时,一些机器会重新安装包,而另一些则不会。
相关剧本部分:
- name: install logstash on debian
apt: deb=/tmp/logstash.deb
when: ansible_os_family == "Debian"
两台机器的详细输出是:
TASK: [install logstash on debian] ********************************************
changed: [eu5.example.com] => {"changed": true, "stderr": "", "stdout": "(Reading database ... 45337 files and directories currently installed.)\nPreparing to unpack /tmp/logstash.deb ...\nUnpacking logstash (1:2.0.0-beta3-1) over (1:2.0.0-beta3-1) ...\nSetting up logstash (1:2.0.0-beta3-1) ...\nProcessing triggers for systemd (215-17+deb8u2) ...\n"}
TASK: [install logstash on debian] ********************************************
ok: [eu2.example.com] => {"changed": false, "stderr": "", "stdout": ""}
触发changed
状态的机制是什么?由于在两台机器上都已经安装了 logstash
(在同一级别,来自同一包),因此有两种可能的情况:
- 无论包是否安装,
apt
命令每次都应该运行(在这种情况下,eu5
的行为没问题,eu2
的不是)
- 或检查软件包是否已安装并且跳过(在这种情况下,上面的 OK/not OK 行为被切换)
直接安装:
[root@eu2:~]# dpkg -i /tmp/logstash.deb
(Reading database ... 232343 files and directories currently installed.)
Preparing to unpack /tmp/logstash.deb ...
Unpacking logstash (1:2.0.0-beta3-1) over (1:2.0.0-beta3-1) ...
Setting up logstash (1:2.0.0-beta3-1) ...
Processing triggers for systemd (227-2) ...
这表明软件包每次都会重新安装(因此 ansible
在 eu2
上的行为有问题)。如果确实如此:是否有一种方法可以仅在尚未安装软件包时有条件地安装? (有些previous answers suggest认为dpkg
中没有内置这样的机制)
无论何时安装、升级或删除软件包,apt
模块都应该 return changed: True
。我怀疑这个错误是在 Ansible 中,因为这是最常用的模块之一,而且此时边缘情况可能都被某人击中了。尽管如此,您可能还是想绕过它并继续前进。你可以这样做:
- command: dpkg -s logstash
register: logstash_available
ignore_errors: True
- name: install logstash on debian
apt: deb=/tmp/logstash.deb
when: logstash_available.rc != 0
我有几个使用 ansible
的 Debian 服务器。其中一项任务是安装一些软件包。行为因机器而异,特别是在重新运行 剧本时,一些机器会重新安装包,而另一些则不会。
相关剧本部分:
- name: install logstash on debian
apt: deb=/tmp/logstash.deb
when: ansible_os_family == "Debian"
两台机器的详细输出是:
TASK: [install logstash on debian] ********************************************
changed: [eu5.example.com] => {"changed": true, "stderr": "", "stdout": "(Reading database ... 45337 files and directories currently installed.)\nPreparing to unpack /tmp/logstash.deb ...\nUnpacking logstash (1:2.0.0-beta3-1) over (1:2.0.0-beta3-1) ...\nSetting up logstash (1:2.0.0-beta3-1) ...\nProcessing triggers for systemd (215-17+deb8u2) ...\n"}
TASK: [install logstash on debian] ********************************************
ok: [eu2.example.com] => {"changed": false, "stderr": "", "stdout": ""}
触发changed
状态的机制是什么?由于在两台机器上都已经安装了 logstash
(在同一级别,来自同一包),因此有两种可能的情况:
- 无论包是否安装,
apt
命令每次都应该运行(在这种情况下,eu5
的行为没问题,eu2
的不是) - 或检查软件包是否已安装并且跳过(在这种情况下,上面的 OK/not OK 行为被切换)
直接安装:
[root@eu2:~]# dpkg -i /tmp/logstash.deb
(Reading database ... 232343 files and directories currently installed.)
Preparing to unpack /tmp/logstash.deb ...
Unpacking logstash (1:2.0.0-beta3-1) over (1:2.0.0-beta3-1) ...
Setting up logstash (1:2.0.0-beta3-1) ...
Processing triggers for systemd (227-2) ...
这表明软件包每次都会重新安装(因此 ansible
在 eu2
上的行为有问题)。如果确实如此:是否有一种方法可以仅在尚未安装软件包时有条件地安装? (有些previous answers suggest认为dpkg
中没有内置这样的机制)
无论何时安装、升级或删除软件包,apt
模块都应该 return changed: True
。我怀疑这个错误是在 Ansible 中,因为这是最常用的模块之一,而且此时边缘情况可能都被某人击中了。尽管如此,您可能还是想绕过它并继续前进。你可以这样做:
- command: dpkg -s logstash
register: logstash_available
ignore_errors: True
- name: install logstash on debian
apt: deb=/tmp/logstash.deb
when: logstash_available.rc != 0