Ansible의 사전 목록 내에서 지정된 사전 키의 액세스 값

Ansible의 사전 목록 내에서 지정된 사전 키의 액세스 값

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값이 또는 과 같음 ), 그렇다면 지정된 명령을 실행합니다. 예:changedtruefalse

- 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

많은 옵션이 있습니다. 귀하의 사용 사례에 가장 적합한 것을 선택하십시오.

  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']
  1. 변경된 패키지 목록 생성
  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]
  1. 목록을 만들고 기본 이름을 매핑합니다.
  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)

관련 정보