# Unpacking a zip with variably named root folder

**URL:** <https://forum.ansible.com/t/unpacking-a-zip-with-variably-named-root-folder/2805>\
**Category:** Get Help\
**Tags:** playbook, ansible-core\
**Created:** [December 8, 2023, 11:59am UTC](https://forum.ansible.com/t/unpacking-a-zip-with-variably-named-root-folder/2805 "2023-12-08T11:59:58Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Zonoia](https://avatars.discourse-cdn.com/v4/letter/z/df705f/32.png) [@Zonoia](https://forum.ansible.com/u/Zonoia)\
**Post date:** [December 8, 2023, 11:59am UTC](https://forum.ansible.com/t/unpacking-a-zip-with-variably-named-root-folder/2805/1 "2023-12-08T11:59:58Z")

</div>

Hi there!

I’m trying to unzip a file ([https://download.axoniq.io/axonserver/AxonServer.zip](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:

```auto
- 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](https://github.com/Hoekstraa/axoniq-cluster-ansible)

---

<div class="post-metadata">

**Author:** ![kurokobo](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/kurokobo/32/182_2.png) [@kurokobo](https://forum.ansible.com/u/kurokobo)\
**Post date:** [December 8, 2023, 1:34pm UTC](https://forum.ansible.com/t/unpacking-a-zip-with-variably-named-root-folder/2805/2 "2023-12-08T13:34:28Z")

</div>

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:

```yaml
    - 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:

```bash
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:

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

```

Result:

```bash
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 😃

---

<div class="post-metadata">

**Author:** ![Zonoia](https://avatars.discourse-cdn.com/v4/letter/z/df705f/32.png) [@Zonoia](https://forum.ansible.com/u/Zonoia)\
**Post date:** [December 8, 2023, 1:46pm UTC](https://forum.ansible.com/t/unpacking-a-zip-with-variably-named-root-folder/2805/3 "2023-12-08T13:46:20Z")

</div>

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!):

```auto
- 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"

```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/ansible/original/1X/1882d9a01da5d8996a862359b0913cc568a39b84.svg) [@system](https://forum.ansible.com/u/system)\
**Post date:** [January 7, 2024, 1:47pm UTC](https://forum.ansible.com/t/unpacking-a-zip-with-variably-named-root-folder/2805/4 "2024-01-07T13:47:17Z")

</div>

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