Я устанавливаю список пакетов в ansible, регистрирую переменную и вывожу ее с помощью debug
:
community.general.homebrew:
name: "{{ package }}"
state: present
register: package_install
until: package_install is succeeded
loop:
- pam-reattach
- pinentry-mac
- jorgelbg/tap/pinentry-touchid
loop_control:
loop_var: package
- debug:
msg: "{{ package_install }}"
Вывод выглядит так:
msg:
changed: true
msg: All items completed
results:
- ansible_loop_var: package
attempts: 1
changed: false
changed_pkgs: []
failed: false
invocation:
module_args:
install_options: []
name:
- pam-reattach
path: /usr/local/bin:/opt/homebrew/bin:/home/linuxbrew/.linuxbrew/bin
state: present
update_homebrew: false
upgrade_all: false
upgrade_options: []
msg: 'Package already installed: pam-reattach'
package: pam-reattach
unchanged_pkgs:
- pam-reattach
- ansible_loop_var: package
attempts: 1
changed: true
changed_pkgs:
- pinentry-mac
failed: false
invocation:
module_args:
install_options: []
name:
- pinentry-mac
path: /usr/local/bin:/opt/homebrew/bin:/home/linuxbrew/.linuxbrew/bin
state: present
update_homebrew: false
upgrade_all: false
upgrade_options: []
msg: 'Package installed: pinentry-mac'
package: pinentry-mac
unchanged_pkgs: []
- ansible_loop_var: package
attempts: 1
changed: true
changed_pkgs:
- jorgelbg/tap/pinentry-touchid
failed: false
invocation:
module_args:
install_options: []
name:
- jorgelbg/tap/pinentry-touchid
path: /usr/local/bin:/opt/homebrew/bin:/home/linuxbrew/.linuxbrew/bin
state: present
update_homebrew: false
upgrade_all: false
upgrade_options: []
msg: 'Package installed: jorgelbg/tap/pinentry-touchid'
package: jorgelbg/tap/pinentry-touchid
unchanged_pkgs: []
skipped: false
Зарегистрированная переменная package_install.results
содержит список словарей (или карт/хэшей — поправьте меня, если я ошибаюсь) с данными, относящимися к каждой package
установке.
Мне нужно проверить, были ли установлены пакеты pinentry-mac
или pinentry-touchid
во время предыдущей задачи (равно ли значение changed
ключа в каждом элементе true
или false
), и если да, то выполнить указанную команду, например:
- command: <command>
when: >
`pinentry-mac` item's attribute `changed` is `True` within `package_install.results` \
OR \
`pinentry-touchid` item's attribute `changed` is `True` within `package_install.results`
Как бы я это сделал?
Сейчас я делаю следующее:
- command: <command>
when: "'pinentry' in item.package and item.changed"
loop: "{{ macterm_package_install.results }}"
Но в этом случае команда будет выполнена дважды, если оба пакета были установлены на предыдущем шаге, хотя команду необходимо выполнить только один раз.
Есть ли способ сделать это правильно? Любые мысли будут высоко оценены.
ОБНОВЛЯТЬ
«Лучший» способ, который мне удалось найти, это (в два этапа):
- name: Check if any of the pinentry packages were installed during previous tasks
set_fact:
pinentry_changed: True
when: "'pinentry-' in item.package and item.changed"
loop: "{{ macterm_package_install.results }}"
- command: <command>
when: pinentry_changed | default(false)
Но есть ли на самом деле более элегантный способ решить эту проблему?
решение1
Есть много вариантов. Выберите тот, который лучше всего подходит для вашего варианта использования.
- Создать словарь
package_changed: "{{ package_install.results|
items2dict(key_name='package', value_name='changed') }}"
дает
package_changed:
jorgelbg/tap/pinentry-touchid: true
pam-reattach: false
pinentry-mac: true
Тогда условия тривиальны
- command: <command>
when: package_changed['pinentry-mac'] or
package_changed['jorgelbg/tap/pinentry-touchid']
- Создать список измененных пакетов
changed_pkgs: "{{ package_install.results|
map(attribute='changed_pkgs')|flatten }}"
дает
changed_pkgs:
- pinentry-mac
- jorgelbg/tap/pinentry-touchid
Либо протестируйте каждую упаковку
- command: <command>
when: ('pinentry-mac' in changed_pkgs) or
('jorgelbg/tap/pinentry-touchid' in changed_pkgs)
, или пересечь списки, если вы можете поместить протестированные пакеты в список
- command: <command>
when: changed_pkgs|intersect(test_pkgs)|length > 0
vars:
test_pkgs: [pinentry-mac, jorgelbg/tap/pinentry-touchid]
- Создайте список и сопоставьте базовое имя
changed_pkgs: "{{ package_install.results|
map(attribute='changed_pkgs')|flatten|
map('basename')|list }}"
дает
changed_pkgs:
- pinentry-mac
- pinentry-touchid
Используйте только названия пакетов.
- command: <command>
when: ('pinentry-mac' in changed_pkgs) or
('pinentry-touchid' in changed_pkgs)