我正在更新一些我的 ansible 剧本,以便在最新版本的 Fedora 上运行,现在dnf
默认使用。
由于我的大多数剧本也应该在 CentOS 上运行,我希望我的脚本yum
在 CentOS 机器上运行时运行 ansible 命令,在dnf
Fedora 上运行时运行该命令(Ansible 1.9 中的新功能),但按原样使用其余角色。
换句话说,我想编写一个可以智能地选择正确命令的单一操作(类似于):
- name: Install zsh
sudo: yes
yum|dnf: name=zsh state=latest
...而不是两次复制粘贴相同的命令,yum
用dnf
其中一个替换,然后实现一些逻辑来说明要运行两个不同角色中的一个:
- name: Install zsh (yum version)
sudo: yes
yum: name=zsh state=latest
- name: Install zsh (dnf version)
sudo: yes
dnf: name=zsh state=latest
在有人冲过去之前:我知道yum
在最新的 Fedora 上有一个别名dnf
,我可以保留剧本原样...我的问题是不是关于编写与 CentOS/Fedora 兼容的剧本,我的问题是关于根据目标环境为相同参数选择不同的命令
答案1
Ansible 2 现在有一个通用的包管理器:
http://docs.ansible.com/ansible/package_module.html
对于旧版本,您可以通过事实关联包管理器
- name: Install packages
with_items: package_list
action: "{{ ansible_pkg_mgr }} state=installed name={{ item }}"
ansible_pkg_mgr
现在您所需要的只是一些设置为apt
或等的逻辑yum
,然后所有when
逻辑都会消失。
看起来像 Ansible也正在努力在未来的模块中做你想做的事情。
答案2
据我所知,这是 Ansible 中比较混乱的部分之一。我一直认为它应该有办法自己找出正在使用的包管理器,而不需要我指定它。
与此同时,我还有很多角色,任务如下:
- name: Update OpenSSH on CentOS
yum: name=openssh state=latest enablerepo=cr
when: ansible_distribution == 'CentOS' and ansible_distribution_major_version|int == 7
notify: restart sshd
- name: Update OpenSSH on RHEL
yum: name=openssh state=latest
when: ansible_distribution == 'RedHat' and ansible_distribution_major_version|int == 7
notify: restart sshd
- name: Update OpenSSH on Fedora
yum: name=openssh state=latest
when: ansible_distribution == 'Fedora' andansible_distribution_major_version|int <= 21
notify: restart sshd
- name: Update OpenSSH on Fedora
dnf: name=openssh state=latest
when: ansible_distribution == 'Fedora' andansible_distribution_major_version|int >= 22
notify: restart sshd
- name: Update OpenSSH on Debian/Ubuntu
apt: name=openssh-server state=latest
when: ansible_os_family == 'Debian'
notify: restart ssh
这有点不方便。但是,它确实有其优点。如果你仔细检查,你会发现 CentOS 版本有所不同;它在安装软件包时启用了存储库。
当然这样做是有原因的。在不同的系统上,你甚至可能有不同的包名称,所以你最终可能还是要为它们设置不同的任务。但你可以将其放入特定于操作系统的变量中,然后执行以下操作:
- include_vars: common_os_{{ansible_distribution}}_{{ansible_distribution_major_version}}.yml
- name: Install minimum system administration packages
yum: name={{item}} state=present
with_items: common_packages_admin
when: ansible_os_family == 'RedHat'
- name: Install minimum system administration packages
apt: name={{item}} state=present
with_items: common_packages_admin
when: ansible_os_family == 'Debian'
但要扩展它,dnf
需要大量额外的when:
逻辑,这需要做大量工作,而且没有任何好处,因为 dnf 的 yum 兼容性会处理好这个问题。这里就是那个假设的“自动找出要使用的包管理器”模块有用的地方。
但即使你有一个,你有时仍然需要使用单独的包管理器,因为其中一些有...特性。
- name: Install salt-minion
yum: name=salt-minion state=latest
when: ansible_os_family == 'RedHat'
- name: Install salt-minion
apt: name=salt-minion state=latest update_cache=yes
when: ansible_os_family == 'Debian'
所以,我能给你的最好建议是:等到 Ansible 有更好的方法来处理包管理器。或者写一个……