Ich installiere eine Liste von Paketen in der Ansible-Registrierungsvariable und gebe sie mit folgendem aus 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 }}"
Die Ausgabe sieht folgendermaßen aus:
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
Die registrierte Variable package_install.results
enthält eine Liste von Wörterbüchern (oder Maps/Hashes – bitte korrigieren Sie mich, wenn ich falsch liege) mit den Daten, die sich auf jede package
Installation beziehen.
Ich muss prüfen, ob während der vorherigen Aufgabe entweder pinentry-mac
oder pinentry-touchid
-Pakete installiert wurden (ist der Schlüsselwert changed
innerhalb jedes Elements gleich true
oder false
) und wenn ja, dann einen angegebenen Befehl ausführen, z. B.:
- 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`
Wie würde ich das machen?
Im Moment mache ich Folgendes:
- command: <command>
when: "'pinentry' in item.package and item.changed"
loop: "{{ macterm_package_install.results }}"
In diesem Fall wird der Befehl jedoch zweimal ausgeführt, wenn beide Pakete im vorherigen Schritt installiert wurden, obwohl der Befehl nur einmal ausgeführt werden muss.
Gibt es eine Möglichkeit, es richtig zu machen? Ich bin für jeden Gedanken dankbar.
AKTUALISIEREN
Der „beste“ Weg, den ich finden konnte, ist dieser (in zwei Schritten):
- 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)
Aber gibt es wirklich eine elegantere Möglichkeit, dieses Problem zu lösen?
Antwort1
Es gibt viele Optionen. Wählen Sie diejenige aus, die am besten zu Ihrem Anwendungsfall passt.
- Erstellen Sie das Wörterbuch
package_changed: "{{ package_install.results|
items2dict(key_name='package', value_name='changed') }}"
gibt
package_changed:
jorgelbg/tap/pinentry-touchid: true
pam-reattach: false
pinentry-mac: true
Dann sind die Bedingungen trivial
- command: <command>
when: package_changed['pinentry-mac'] or
package_changed['jorgelbg/tap/pinentry-touchid']
- Erstellen Sie die Liste der geänderten Pakete
changed_pkgs: "{{ package_install.results|
map(attribute='changed_pkgs')|flatten }}"
gibt
changed_pkgs:
- pinentry-mac
- jorgelbg/tap/pinentry-touchid
Testen Sie entweder jedes Paket
- command: <command>
when: ('pinentry-mac' in changed_pkgs) or
('jorgelbg/tap/pinentry-touchid' in changed_pkgs)
, oder schneiden Sie die Listen, wenn Sie die getesteten Pakete in eine Liste einfügen können
- command: <command>
when: changed_pkgs|intersect(test_pkgs)|length > 0
vars:
test_pkgs: [pinentry-mac, jorgelbg/tap/pinentry-touchid]
- Erstellen Sie die Liste und ordnen Sie den Basisnamen zu
changed_pkgs: "{{ package_install.results|
map(attribute='changed_pkgs')|flatten|
map('basename')|list }}"
gibt
changed_pkgs:
- pinentry-mac
- pinentry-touchid
Verwenden Sie nur die Namen der Pakete
- command: <command>
when: ('pinentry-mac' in changed_pkgs) or
('pinentry-touchid' in changed_pkgs)