Unarchive - using wildcards in 'src' option

I have these 2 tasks wich should download the latest a tar archive and then unpack it

    - name: get nexus 
      ansible.builtin.get_url: 
        url: https://download.sonatype.com/nexus/3/latest-unix.tar.gz
        dest: /tmp/
        owner: "{{ app_name }}"
        group: "{{ app_name }}"

    - name: unpack nexus.tar
      ansible.builtin.unarchive:
        src: /tmp/nexus-3.67.0-03-unix.tar.gz
        dest: "/opt/"
        owner: "{{ app_name }}"
        group: "{{ app_name }}"
        remote_src: true
        mode: 0700

I go via a link https://download.sonatype.com/nexus/3/latest-unix.tar.gz whitch results into downloading the specific nexus-3.67.0-03-unix.tar.gz

I do not know the exact version upfront so I am want to mimic unarchiving similar to
tar -xvf /opt/nexus-3*.tar.gz but can not figure out a way to apply any sort of * logic in the src option of the unarchive TASK though.

Is that doable?

I tried to make this work via stat, but that neither would allow * in its path option.

1 Like

I’m unable to test since download.sonatype.com is blocked by my company firewall, but I think you can just register the get_url: task to discover what the resulting filename was. Then unarchive the variable name.

Something like:

- name: get nexus 
      ansible.builtin.get_url: 
        url: https://download.sonatype.com/nexus/3/latest-unix.tar.gz
        dest: /tmp/
        owner: "{{ app_name }}"
        group: "{{ app_name }}"
      register: nexus

    - name: unpack nexus.tar
      ansible.builtin.unarchive:
        src: "{{ nexus.dest }}"
        dest: "/opt/"
        owner: "{{ app_name }}"
        group: "{{ app_name }}"
        remote_src: true
        mode: 0700
4 Likes

Another option is to specify a destination filename instead of a directory:

    - name: get nexus 
      ansible.builtin.get_url: 
        url: https://download.sonatype.com/nexus/3/latest-unix.tar.gz
        dest: /tmp/nexus-latest-unix.tar.gz
        owner: "{{ app_name }}"
        group: "{{ app_name }}"

There’s no particular reason to respect the server-provided filename in this case.

4 Likes

Another approach would be to use the URI module to do a HEAD request to get the Location of the file and then get the filename from that, for example (untested):

- name: Check the latest version of Nexus 3
  ansible.builtin.uri:
    url: https://download.sonatype.com/nexus/3/latest-unix.tar.gz
    method: HEAD
    status_code: 302 
    follow_redirects: none
  check_mode: false
  changed_when: false
  register: nexus_headers

- name: Debug Nexus 3 latest headers
  ansible.builtin.debug:
    msg:
      - "Location: {{ nexus_headers.location }}"
      - "Path: {{ nexus_headers.location | ansible.builtin.urlsplit('path') }}"
      - "File: {{ nexus_headers.location | ansible.builtin.urlsplit('path') | ansible.builtin.basename }}"
      - "Version: {{ nexus_headers.location | ansible.builtin.urlsplit('path') | ansible.builtin.basename | ansible.builtin.regex_replace('^nexus-') | ansible.builtin.regex_replace('[.]tar[.]gz$') }}"

This approach might make sense if you want to only download an update if the specific version isn’t already installed. :person_shrugging:

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.