Estoy instalando una lista de paquetes en la variable de registro ansible y la estoy generando con 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 }}"
La salida se ve así:
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
La var registrada package_install.results
contiene una lista de diccionarios (o mapas/hashes; corríjame si me equivoco) con los datos relacionados con cada package
instalación.
Necesito verificar si alguno pinentry-mac
de pinentry-touchid
los paquetes se instaló durante la tarea anterior (el valor de changed
la clave dentro de cada elemento es igual true
a o false
) y, en caso afirmativo, ejecutar un comando específico, por ejemplo:
- 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`
¿Cómo haría esto?
Ahora mismo hago lo siguiente:
- command: <command>
when: "'pinentry' in item.package and item.changed"
loop: "{{ macterm_package_install.results }}"
Pero en este caso el comando se ejecutará dos veces si ambos paquetes se instalaron durante el paso anterior, aunque el comando debe ejecutarse sólo una vez.
¿Hay alguna manera de hacerlo correctamente? Cualquier idea es muy apreciada.
ACTUALIZAR
La "mejor" forma que pude encontrar es esta (en dos pasos):
- 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)
Pero realmente, ¿existe alguna forma más elegante de solucionar esto?
Respuesta1
Hay muchas opciones. Elija el que mejor se adapte a su caso de uso.
- Crear el diccionario
package_changed: "{{ package_install.results|
items2dict(key_name='package', value_name='changed') }}"
da
package_changed:
jorgelbg/tap/pinentry-touchid: true
pam-reattach: false
pinentry-mac: true
Entonces las condiciones son triviales.
- command: <command>
when: package_changed['pinentry-mac'] or
package_changed['jorgelbg/tap/pinentry-touchid']
- Crear la lista de paquetes modificados.
changed_pkgs: "{{ package_install.results|
map(attribute='changed_pkgs')|flatten }}"
da
changed_pkgs:
- pinentry-mac
- jorgelbg/tap/pinentry-touchid
Pruebe cada paquete
- command: <command>
when: ('pinentry-mac' in changed_pkgs) or
('jorgelbg/tap/pinentry-touchid' in changed_pkgs)
, o intersecar las listas si puede colocar los paquetes probados en una lista
- command: <command>
when: changed_pkgs|intersect(test_pkgs)|length > 0
vars:
test_pkgs: [pinentry-mac, jorgelbg/tap/pinentry-touchid]
- Crea la lista y asigna el nombre base.
changed_pkgs: "{{ package_install.results|
map(attribute='changed_pkgs')|flatten|
map('basename')|list }}"
da
changed_pkgs:
- pinentry-mac
- pinentry-touchid
Utilice únicamente los nombres de los paquetes.
- command: <command>
when: ('pinentry-mac' in changed_pkgs) or
('pinentry-touchid' in changed_pkgs)