Как в ansible выбрать имена пакетов по маске?
Мне нужно получить список пакетов, имя которых начинается на dotnet.
Такая схема работает:
- debug:
msg: "{{ ansible_facts.packages['dotnet-runtime-3.1'] }}"
А такая уже нет:
- debug:
msg: "{{ ansible_facts.packages['dotnet*'] }}"
"{{ ansible_facts.packages | regex_findall('^dotnet.*') }}" тоже почему-то не отрабатывает.
Ответы (1 шт):
Выяснились интересные моменты. Проблема и решилась и не решилась одновременно.
package_facts
Итак, модуль package_facts показывает инфу только об установленных пакетах. Те, которые доступны - он игнорит. Это ставит крест на том, чтобы избежать использования aptitude search и aptitude versions. Тем не менее, инфу об установленных пакетах можно вытащить вот так (огромное спасибо коллеге, который умеет читать документацию в отличии от меня).
Буду показывать на firefox:
- package_facts:
- name: Get installed soft
vars:
my_json_query: keys(packages)[?contains(@, 'firefox')]
set_fact:
needing_package: "{{ ansible_facts | json_query(my_json_query) }}"
ok: [test-vm.local] => {
"ansible_facts": {
"needing_package": [
"firefox",
"firefox-locale-ru"
]
},
"changed": false
}
Вывалило 2 пакета. Хотя aptitude search firefox | wc -l возвращает аж 218
Решение конкретной задачи
Debian\Ubuntu
Кроме как дёргать apt-cache я других вариантов не нашёл, поэтому:
Спрашиваем у кэша какие пакеты с маской dotnet-runtime-* нам доступны, выдёргиваем строки, содержащие слова Package: и Version:, и магией sed+tr формируем...
apt-cache show dotnet-runtime-* | grep -E -i '(Package:|Version:)' | tr '\n' ' ' | sed 's| Package|\nPackage|g' | grep -v -i deps
... здоровенный лист, который на момент написания выглядит так:
Package: dotnet-runtime-2.1 Version: 2.1.20-1
Package: dotnet-runtime-2.1 Version: 2.1.19-1
Package: dotnet-runtime-2.1 Version: 2.1.18-1
Package: dotnet-runtime-2.1 Version: 2.1.17-1
Package: dotnet-runtime-2.1 Version: 2.1.16-1
Package: dotnet-runtime-2.1 Version: 2.1.15-1
Package: dotnet-runtime-2.1 Version: 2.1.14-1
Package: dotnet-runtime-2.1 Version: 2.1.13-1
Package: dotnet-runtime-2.1 Version: 2.1.12-1
Package: dotnet-runtime-2.1 Version: 2.1.11-1
Package: dotnet-runtime-2.1 Version: 2.1.10-1
Package: dotnet-runtime-2.1 Version: 2.1.9-1
Package: dotnet-runtime-2.1 Version: 2.1.8-1
Package: dotnet-runtime-2.1 Version: 2.1.7-1
Package: dotnet-runtime-2.1 Version: 2.1.6-1
Package: dotnet-runtime-2.1 Version: 2.1.5-1
Package: dotnet-runtime-2.1 Version: 2.1.4-1
Package: dotnet-runtime-2.1 Version: 2.1.3-1
Package: dotnet-runtime-2.1 Version: 2.1.2-1
Package: dotnet-runtime-2.1 Version: 2.1.1-1
Package: dotnet-runtime-2.1 Version: 2.1.0-1
Package: dotnet-runtime-2.1.0-preview2-26406-04 Version: 2.1.0-preview2-26406-04-1
Package: dotnet-runtime-2.1.0-rc1 Version: 2.1.0-rc1-1
Package: dotnet-runtime-2.2 Version: 2.2.8-1
Package: dotnet-runtime-2.2 Version: 2.2.7-1
Package: dotnet-runtime-2.2 Version: 2.2.6-1
Package: dotnet-runtime-2.2 Version: 2.2.5-1
Package: dotnet-runtime-2.2 Version: 2.2.4-1
Package: dotnet-runtime-2.2 Version: 2.2.3-1
Package: dotnet-runtime-2.2 Version: 2.2.2-1
Package: dotnet-runtime-2.2 Version: 2.2.1-1
Package: dotnet-runtime-2.2 Version: 2.2.0-1
Package: dotnet-runtime-3.0 Version: 3.0.3-1
Package: dotnet-runtime-3.0 Version: 3.0.2-1
Package: dotnet-runtime-3.0 Version: 3.0.1-1
Package: dotnet-runtime-3.0 Version: 3.0.0-1
Package: dotnet-runtime-3.1 Version: 3.1.6-1
Package: dotnet-runtime-3.1 Version: 3.1.5-1
Package: dotnet-runtime-3.1 Version: 3.1.4-1
Package: dotnet-runtime-3.1 Version: 3.1.3-1
Package: dotnet-runtime-3.1 Version: 3.1.2-1
Package: dotnet-runtime-3.1 Version: 3.1.1-1
Package: dotnet-runtime-3.1 Version: 3.1.0-1
Package: dotnet-runtime-2.0.7 Version: 2.0.7-1
Package: dotnet-runtime-2.0.9 Version: 2.0.9-1
Дальше - просто. Дёргаем regex_search и split уже из под ansible получая вот это (по условию, нам надо найти имя пакета, в котором есть версия 3.1.6):
vars:
dotnet_current_version: 3.1.6
- name: Find .NET versions on Debian\Ubuntu over shell
when:
- ansible_os_family == 'Debian'
- ansible_pkg_mgr == 'apt'
environment:
LANG: C
LC_ALL: C
shell: apt-cache show dotnet-{{ dotnet_default_component }}-* | grep -E -i '(Package:|Version:)' | tr '\n' ' ' | sed 's| Package|\nPackage|g' | grep -v -i deps
register: dotnet_current_version_list
changed_when: dotnet_current_version_list.rc != 0
- name: Get current .NET version 4 install over shell
when:
- ansible_os_family == 'Debian'
- ansible_pkg_mgr == 'apt'
block:
- set_fact:
# https://stackoverflow.com/a/55047177/5430535
dotnet_package_and_version_in_on_line_fact: "{{ dotnet_current_version_list.stdout | regex_search('.*' + dotnet_current_version + '.*') }}"
- set_fact:
dotnet_current_packagename_fact: "{{ dotnet_package_and_version_in_on_line_fact.split(' ')[1] }}"
- set_fact:
dotnet_current_version_fact: "{{ dotnet_package_and_version_in_on_line_fact.split(' ')[3] }}"
Выхлоп будет таким:
ok: [test-vm.local] => {
"ansible_facts": {
"dotnet_package_and_version_in_on_line_fact": "Package: dotnet-runtime-3.1 Version: 3.1.6-1"
},
"changed": false
}
ok: [test-vm.local] => {
"ansible_facts": {
"dotnet_current_packagename_fact": "dotnet-runtime-3.1"
},
"changed": false
}
ok: [test-vm.local] => {
"ansible_facts": {
"dotnet_current_version_fact": "3.1.6-1"
},
"changed": false
}
Т.е. установить dotnet теперь можно так:
- name: Install dotnet 4 Debian\Ubuntu
when:
- ansible_os_family == 'Debian'
- ansible_pkg_mgr == 'apt'
become: yes
apt:
name:
- '{{ dotnet_current_packagename_fact }}={{ dotnet_current_version_fact }}'
state: present
install_recommends: yes
force: yes
P.S. ansible 2.9.11, python version = 2.7.12 (default, Jul 21 2020, 15:19:50) [GCC 5.4.0 20160609], ubuntu 16.04.6