56

When extracting a tar.gz file in ansible I end up with a first directory

- name: Extract archive
  unarchive: src=file.tar.gz
             dest=/foo/bar

which results in /foo/bar/bar-version-someFirstLevelFolder/contentOfArchive How can I prevent creating this extra level of hierarchy?

Georg Heiler
  • 663
  • 1
  • 5
  • 6
  • May not be relevant but I know you sometimes need to be careful in adding a trailing slash to the destination directory. Does that help at all? – SauceCode Feb 20 '17 at 18:35

1 Answers1

75

In order to strip the bar-version-someFirstLevelFolder you need to use the --strip-components=1 option in tar. So your playbook should look like

- name: Extract archive
  unarchive:
    src: file.tar.gz
    dest: /foo/bar
    extra_opts: [--strip-components=1]
GMaster
  • 5,992
  • 3
  • 28
  • 32
  • 2
    This seems to be the correct answer, but currently it can cause a crash. See this bug report: http://github.com/ansible/ansible/issues/29657 an intermediate solution would be to untar in the parent directory and then have a `command: mv /foo/bar-version-someFirstLevelFolder/* foo/bar/` – TheAtomicOption Nov 28 '17 at 01:22
  • 1
    Tested in the last version, it works. But, unarchive is not idempotent. – Jérôme B Aug 13 '18 at 21:15
  • If you know content of your archive and you can risk a bit, you can use `creates: /some/file/that/unpacks` to get some very limited impotence (tried and `ansible-2.9.7-1.fc30.noarch` correctly skips the task if I rerun the playbook). – jhutar Jun 02 '20 at 21:01
  • 2
    If you want to extract only a subset of files (like `tar -xzf file.tar.gz dirname_in_tar/file.xyz` does), you can add the file(s) to `extra_opts` as well, but you need to add them **unstripped**. Example: `extra_opts: [ --strip-components=1, dirname_in_tar/file.xyz ]` will only extract `file.xyz` from the `dirname_in_tar` directory. – riha Jan 13 '21 at 15:40