Unpacking a zip with variably named root folder

Hi there!

I’m trying to unzip a file (https://download.axoniq.io/axonserver/AxonServer.zip), to copy the contents to a server host. The zip however contains a root folder which contains the release version (i.e. AxonServer-2023.2.1).

I’ve been trying to find a way to extract the contents of that root folder generically.
I wasn’t able to find an option in the unarchive API however, so I tried doing it in the following manner:

- name: AxonServer.zip should be unzipped
  hosts: localhost
  tasks:
    - name: Make folder
      file:
        path: ../../files/server
        state: directory
    - name: Extract ./files/AxonServer.zip into ./files/server/
      unarchive:
        src: ../../files/AxonServer.zip
        dest: ../../files/server
        extra_opts:
          - "--add-file"
          - "*/."

- name: Get latest unzipped files in the folder
  hosts: localhost
  tasks:
    - name: Register all unzipped folders in the server folder
      find:
        paths: ../../files/server
        file_type: directory
      register: found_files
    - name: Creating a variable of the newest folder
      set_fact:
        newest_folder: "{{(found_files.files | sort(attribute='mtime',reverse=true) | first).path}}"
    - name: Debug folder name
      debug:
        var: newest_folder
    - name: Copy over the files to the Axon host
      copy:
        src: "{{newest_folder}}/"
        dest: "~/axon"

However this method seems quite verbose, imperative. And doesn´t even work due to the task Get latest unzipped files in the folder needing to be ran on localhost first but the subtask Copy over the files to the Axon host needing to be axon, not localhost. As right now files get copied to localhost’s home folder, which of course isn’t that helpful.

So, I’m either looking for a better way to unarchive zip files with variably named root folders, a better way to store and use variables (so I can split the tasks up and use multiple hosts configurations), or a combination of the both. Feel free to completely flip the problem/solution on it’s head if it helps solve the problem.

Thanks in advance!

P.S. Repo with everything available here: GitHub - Hoekstraa/axoniq-cluster-ansible: Axoniq cluster with Ansible demo

If I understand your situation correctly, list_files parameter for unarchive module may helps you.

unarchive can return list of extacted files if list_files is true, and the first value of the list should always be root directory (of course only if the zip has root directory).

So you can:

  • Specify list_files: true for unarchive and register returned value by register
  • Extract the name of the root directory by <REGISTARED_VARIABLE>.files[0] | regex_replace('\\/$', '')

Snippet of tasks:

    - name: Extract ./files/AxonServer.zip into ./files/server/
      unarchive:
        src: ../../files/AxonServer.zip
        dest: ../../files/server
        list_files: true
      register: extracted_files
    - name: Debug extracted files
      debug:
        var: extracted_files
    - name: Save root directory
      set_fact:
        root_dir: "{{ extracted_files.files[0] | regex_replace('\\/$', '') }}"
    - name: Debug root directory
      debug:
        var: root_dir

Results:

TASK [Debug extracted files] **************************************************************************************************************************
ok: [localhost] => {
    "extracted_files": {
        "changed": false,
        "dest": "../../files/server",
        "failed": false,
        "files": [
            "AxonServer-2023.2.1/",
            "AxonServer-2023.2.1/axonserver.properties",
            "AxonServer-2023.2.1/README.txt",
            "AxonServer-2023.2.1/axonserver-cli.jar",
            "AxonServer-2023.2.1/axonserver.jar",
            "AxonServer-2023.2.1/axoniq-cli.jar",
            "AxonServer-2023.2.1/axonserver-migration.jar",
            "AxonServer-2023.2.1/extensions/",
            "AxonServer-2023.2.1/extensions/axon-server-extension-oauth-4.6.1.zip",
            "AxonServer-2023.2.1/extensions/axon-server-extension-ldap-4.6.3.zip"
        ],
        ...
    }
}

TASK [Save root directory] ****************************************************************************************************************************
ok: [localhost]

TASK [Debug root directory] ***************************************************************************************************************************
ok: [localhost] => {
    "root_dir": "AxonServer-2023.2.1"
}

Note the variable root_dir is stored as only for localhost. But you can refer this variable by hostvars.localhost.root_dir in the plays for another host, if this plays in the same playbook:

- name: Copy over the files to the Axon host
  hosts: axon_target
  tasks:
    - name: Debug folder name
      debug:
        var: hostvars.localhost.root_dir

Result:

PLAY [Copy over the files to the Axon host] ***********************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************
ok: [axon_target]

TASK [Debug folder name] ******************************************************************************************************************************
ok: [axon_target] => {
    "hostvars.localhost.root_dir": "AxonServer-2023.2.1"
}

Hope this helps :smiley:

2 Likes

Thank you! You gave exactly what I needed to work out a solution. This is what I have now, which has solved my problem (not cleaned up yet!):

- name: AxonServer.zip should be unzipped
  hosts: localhost
  tasks:
    - name: Make folder
      file:
        path: ../../files/server
        state: directory
    - name: Extract ./files/AxonServer.zip into ./files/server/
      unarchive:
        src: ../../files/AxonServer.zip
        dest: ../../files/server
        list_files: true
      register: extracted_files
    - name: Debug extracted files
      debug:
        var: extracted_files

- name: Get latest unzipped files in the folder
  hosts: axon
  tasks:
    - name: Copy over the files to the Axon host
      copy:
        src: "../../files/server/{{hostvars.localhost.extracted_files.files[0]}}"
        dest: "~/axon"
1 Like

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