Task to enable dnf repos only if they are not enabled

Then you have two problems: (1) parsing the results from dnf repolist --disabled, and (2) parsing the registered result from the “repolist” task in the “config-manager” task.

You could just write the IDs of those repos to stdout, which you would register, and the 2nd task could use result.stdout_lines which, conveniently enough, is a list version of result.stdout. In fact, in this case, you probably should.

However, parsing “stuff” and generating JSON from bash not hard, and the technique may be useful especially if you have more complicated datums than single strings to return. So here’s the “create the list as JSON even though dnf repolist doesn’t support --json” version.

    - name: List disabled dnf repos
      args:
        executable: /bin/bash
      ansible.builtin.shell: |
        seen_header=no
        declare -a repos
        while read -r -a repo ; do
          if [ "${repo[0]} ${repo[1]}" = "repo id" ] ; then
            seen_header=yes
            continue
          fi
          [ "${seen_header}" = "yes" ] || continue
          repos+=( "\"${repo[0]}\"" ) # double-quoted!
        done < <( dnf repolist --disabled )
        # Print JSON to stdout
        IFS=',';
        printf "[%s]\n" "${repos[*]}"
      become: true
      changed_when: false
      register: repos_disabled

    - name: Enable only the repos of interest
      ansible.builtin.command:
        cmd: "dnf config-manager --enable {{ item }}"
      become: true
      register: result
      changed_when: result.rc == 0
      vars:
        to_enable:
          - codeready-builder-for-rhel-9-x86_64-rpms
          - ansible-automation-platform-2.4-for-rhel-9-x86_64-rpms
          - rhel-9-for-x86_64-supplementary-rpms
      loop: '{{ repos_disabled.stdout
                | from_json
                | intersect(to_enable) }}'

A couple of things worth pointing out.

First, because JSON likes double-quoted strings, go ahead and add the enclosing quotes at the time the strings are added to the array. That leaves only the problem of getting commas between the entries when we get around to producing the JSON.

Second, "${repos[*]}" will separate all the strings in the repos array with the first character of $IFS, so set that to a comma. (It’s right at the end of the script; otherwise we’d set it back to something sane, like $' \t\n'.)

Third, because our JSON is just a list of strings, we don’t have to use
| map(attribute="id")” in the second task.

There you go - a much fancier hammer than this little nail requires, but people seem to have this thing about “don’t use the shell” when they would be perfectly happy using the same logic if it were wrapped in Python and hidden away in a plugin or module. Go figure.

1 Like