skip to Main Content

I created a dictionary of ansible packages filtered from ansible.package_facts, to only contain packages of a specific version. (example shown below)

"filtered_ansible_packages": {
    "cool_package1": [
       {
         "arch": "noarch",
         "epoch": "null",
         "name": "cool_package1",
         "release": "el7",
         "version": "1.2.6"
       }
    ],
    "cool_package2": [
       {
         "arch": "noarch",
         "epoch": "null",
         "name": "cool_package2",
         "release": "el7",
         "version": "1.4.7"
       }
    ]
 }

What I want is to loop through each package and grab the name, release, version and arch.

Then I want to concatenate them into a single string variable we can call "full_package_name", where in the case of cool package 1 would be: "cool_package1.1.2.6.el7.noarch" then store those full package names into a list called "full_package_name_list".

What would be the best way to retrieve the data in the way that I need? should I transform it to a list with "dict2items"? I am new to Ansible so any help would be really appreciated.

2

Answers


  1. Q: "Loop through each package and grab the name, release, version, and arch."

    A: Convert the dictionary to a list and iterate subelements

        - debug:
            msg: |
              arch: {{ item.1.arch }}
              name: {{ item.1.name }}
              release: {{ item.1.release }}
              version: {{ item.1.version }}
          loop: "{{ filtered_ansible_packages | dict2items | subelements('value') }}"
          loop_control:
            label: "{{ item.0.key }} {{ item.1.name }}"
    

    gives

    ok: [localhost] => (item=cool_package1 cool_package1) =>
      msg: |-
        arch: noarch
        name: cool_package1
        release: el7
        version: 1.2.6
    ok: [localhost] => (item=cool_package2 cool_package2) => 
      msg: |-
        arch: noarch
        name: cool_package2
        release: el7
        version: 1.4.7
    

    Q: "Store full package names into a list full_package_name_list"

    A: Use json_query to select the attributes and join them

      full_package_name_list: "{{ filtered_ansible_packages |
                                  json_query('*[].[name, version, release, arch]') |
                                  map('join', '.') }}"
    

    gives

      full_package_name_list:
      - cool_package1.1.2.6.el7.noarch
      - cool_package2.1.4.7.el7.noarch
    

    Example of a complete playbook for testing

    - hosts: localhost
    
      vars:
    
        filtered_ansible_packages:
          cool_package1:
            - {arch: noarch, epoch: 'null', name: cool_package1, release: el7, version: 1.2.6}
          cool_package2:
            - {arch: noarch, epoch: 'null', name: cool_package2, release: el7, version: 1.4.7}
    
        full_package_name_list: "{{ filtered_ansible_packages |
                                    json_query('*[].[name, version, release, arch]') |
                                    map('join', '.') }}"
    
      tasks:
    
        - debug:
            msg: |
              arch: {{ item.1.arch }}
              name: {{ item.1.name }}
              release: {{ item.1.release }}
              version: {{ item.1.version }}
          loop: "{{ filtered_ansible_packages | dict2items | subelements('value') }}"
          loop_control:
            label: "{{ item.0.key }} {{ item.1.name }}"
    
        - debug:
            var: full_package_name_list
    

    Login or Signup to reply.
  2. Q: "What I want is to loop through each package and grab the name, release, version and arch. Then I want to concatenate them into a single string variable we can call full_package_name"

    A minimal example playbook

    ---
    - hosts: localhost
      become: false
      gather_facts: false
    
      tasks:
    
      - package_facts:
    
      - name: full_package_name_list
        debug:
          msg: "{{ full_package.name ~ '.' ~ full_package.version ~ '.' ~ full_package.release ~ '.' ~ full_package.arch }}"
        vars:
          full_package: "{{ item.value | first }}"
        with_dict: "{{ ansible_facts.packages }}"
        loop_control:
          label: "{{ item.key }}"
    

    will provide such behavior.

    One could even filter the package dictionary for certain properties like the release before.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search