用ansable部署ubuntu 18.04服务器时,我遇到了以下问题:
我要安装的某些软件包既不在官方存储库中,也不在PPA中。因此,我必须从github下载并安装它们。
我检查是否已经用dpkg-query -W
安装了一个软件包,并且仅在返回代码为1
时运行以下安装任务。像这样:
# ripgrep
- name: "Check if ripgrep is installed"
command: dpkg-query -W ripgrep
register: ripgrep_dpkg_check
failed_when: ripgrep_dpkg_check.rc > 1
changed_when: ripgrep_dpkg_check.rc == 1
- name: "Install ripgrep from github
apt:
deb: "https://github.com/BurntSushi/ripgrep/releases/download/11.0.2/ripgrep_11.0.2.deb"
when: ripgrep_dpkg_check.rc == 1
这对于单个程序包来说很好,但是对于多个程序包来说却很乏味。
所以我想到了循环遍历包含我的包裹信息的哈希:
extrapackages:
- { name: ripgrep , version: 2.0, url: awfawf }
- { name: fd, version: 1.4, url: awfdawf }
然后遍历它:
- name: "Check if package is installed"
command: "dpkg-query -W {{ item.name }}"
register: dpkg_check
loop: "{{ extrapackages }}"
这给了我
"dpkg_check": {
"changed": true,
"msg": "All items completed",
"results": [
{
"ansible_loop_var": "item",
"changed": true,
"cmd": [
"dpkg-query",
"-W",
"ripgrep"
],
"delta": "0:00:00.015585",
"end": "2019-11-27 17:18:42.951019",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "dpkg-query -W ripgrep",
"_uses_shell": false,
"argv": null,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"stdin_add_newline": true,
"strip_empty_ends": true,
"warn": true
}
},
"item": {
"name": "ripgrep",
"url": "awfawf",
"version": 2.0
},
"rc": 0,
"start": "2019-11-27 17:18:42.935434",
"stderr": "",
"stderr_lines": [],
"stdout": "ripgrep\t11.0.2",
"stdout_lines": [
"ripgrep\t11.0.2"
]
},
{
"ansible_loop_var": "item",
"changed": true,
"cmd": [
"dpkg-query",
"-W",
"fd"
],
"delta": "0:00:00.015857",
"end": "2019-11-27 17:18:43.137177",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "dpkg-query -W fd",
"_uses_shell": false,
"argv": null,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"stdin_add_newline": true,
"strip_empty_ends": true,
"warn": true
}
},
"item": {
"name": "fd",
"url": "awfdawf",
"version": 1.4
},
"rc": 0,
"start": "2019-11-27 17:18:43.121320",
"stderr": "",
"stderr_lines": [],
"stdout": "fd\t7.4.0",
"stdout_lines": [
"fd\t7.4.0"
]
}
]
}
现在,我想对所有具有rc = 1
的循环项运行apt。用伪代码,我想要类似的东西:
for package in dpkg_check.results:
if package.rc = 1:
apt install package.item.url
像这样的事情有可能在ansible吗?
答案 0 :(得分:1)
使用json_query。例如
- apt:
name: "{{ dpkg_check.results|
json_query('[?rc == `1`].item.url') }}"
首先使用调试对其进行测试。例如
- debug:
msg: "{{ dpkg_check.results|
json_query('[?rc == `1`].item.url') }}"
(未经测试)
答案 1 :(得分:1)
非常感谢@Vladimir Botka,这正是我想要的。
我的工作解决方案:
- name: "Check if extra packages are installed"
command: "dpkg-query -W {{ item.name }}"
register: dpkg_check
loop: "{{ extrapackages }}"
failed_when: dpkg_check.rc > 1
changed_when: dpkg_check.rc == 1
- name: "Install missing extra packages"
apt:
deb: "{{ item }}"
loop: "{{ dpkg_check.results|json_query('[?rc == `1`].item.url') }}"
when: dpkg_check.changed