我正在 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
註冊的 var包含一個字典列表(或地圖/哈希 - 如果我錯了,請糾正我)以及與每個安裝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)