unarchive: add support for .tar.zst (zstd compression) (#73265)
This commit is contained in:
parent
ae241b407a
commit
6fd0a74601
5 changed files with 89 additions and 3 deletions
2
changelogs/fragments/unarchive-support-zst.yml
Normal file
2
changelogs/fragments/unarchive-support-zst.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
minor_changes:
|
||||||
|
- unarchive - Add support for .tar.zst (zstd compression) (https://github.com/ansible/ansible/pull/73265).
|
|
@ -110,8 +110,9 @@ todo:
|
||||||
- Re-implement zip support using native zipfile module.
|
- Re-implement zip support using native zipfile module.
|
||||||
notes:
|
notes:
|
||||||
- Requires C(zipinfo) and C(gtar)/C(unzip) command on target host.
|
- Requires C(zipinfo) and C(gtar)/C(unzip) command on target host.
|
||||||
- Can handle I(.zip) files using C(unzip) as well as I(.tar), I(.tar.gz), I(.tar.bz2) and I(.tar.xz) files using C(gtar).
|
- Requires C(zstd) command on target host to expand I(.tar.zst) files.
|
||||||
- Does not handle I(.gz) files, I(.bz2) files or I(.xz) files that do not contain a I(.tar) archive.
|
- Can handle I(.zip) files using C(unzip) as well as I(.tar), I(.tar.gz), I(.tar.bz2), I(.tar.xz), and I(.tar.zst) files using C(gtar).
|
||||||
|
- Does not handle I(.gz) files, I(.bz2) files, I(.xz), or I(.zst) files that do not contain a I(.tar) archive.
|
||||||
- Uses gtar's C(--diff) arg to calculate if changed or not. If this C(arg) is not
|
- Uses gtar's C(--diff) arg to calculate if changed or not. If this C(arg) is not
|
||||||
supported, it will always unpack the archive.
|
supported, it will always unpack the archive.
|
||||||
- Existing files/directories in the destination which are not in the archive
|
- Existing files/directories in the destination which are not in the archive
|
||||||
|
@ -891,9 +892,22 @@ class TarXzArchive(TgzArchive):
|
||||||
self.zipflag = '-J'
|
self.zipflag = '-J'
|
||||||
|
|
||||||
|
|
||||||
|
# Class to handle zstd compressed tar files
|
||||||
|
class TarZstdArchive(TgzArchive):
|
||||||
|
def __init__(self, src, b_dest, file_args, module):
|
||||||
|
super(TarZstdArchive, self).__init__(src, b_dest, file_args, module)
|
||||||
|
# GNU Tar supports the --use-compress-program option to
|
||||||
|
# specify which executable to use for
|
||||||
|
# compression/decompression.
|
||||||
|
#
|
||||||
|
# Note: some flavors of BSD tar support --zstd (e.g., FreeBSD
|
||||||
|
# 12.2), but the TgzArchive class only supports GNU Tar.
|
||||||
|
self.zipflag = '--use-compress-program=zstd'
|
||||||
|
|
||||||
|
|
||||||
# try handlers in order and return the one that works or bail if none work
|
# try handlers in order and return the one that works or bail if none work
|
||||||
def pick_handler(src, dest, file_args, module):
|
def pick_handler(src, dest, file_args, module):
|
||||||
handlers = [ZipArchive, TgzArchive, TarArchive, TarBzipArchive, TarXzArchive]
|
handlers = [ZipArchive, TgzArchive, TarArchive, TarBzipArchive, TarXzArchive, TarZstdArchive]
|
||||||
reasons = set()
|
reasons = set()
|
||||||
for handler in handlers:
|
for handler in handlers:
|
||||||
obj = handler(src, dest, file_args, module)
|
obj = handler(src, dest, file_args, module)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
- import_tasks: test_tar_gz_creates.yml
|
- import_tasks: test_tar_gz_creates.yml
|
||||||
- import_tasks: test_tar_gz_owner_group.yml
|
- import_tasks: test_tar_gz_owner_group.yml
|
||||||
- import_tasks: test_tar_gz_keep_newer.yml
|
- import_tasks: test_tar_gz_keep_newer.yml
|
||||||
|
- import_tasks: test_tar_zst.yml
|
||||||
- import_tasks: test_zip.yml
|
- import_tasks: test_zip.yml
|
||||||
- import_tasks: test_exclude.yml
|
- import_tasks: test_exclude.yml
|
||||||
- import_tasks: test_include.yml
|
- import_tasks: test_include.yml
|
||||||
|
|
|
@ -6,6 +6,13 @@
|
||||||
- unzip
|
- unzip
|
||||||
when: ansible_pkg_mgr in ('yum', 'dnf', 'apt', 'pkgng')
|
when: ansible_pkg_mgr in ('yum', 'dnf', 'apt', 'pkgng')
|
||||||
|
|
||||||
|
- name: Ensure zstd is present, if available
|
||||||
|
ignore_errors: true
|
||||||
|
package:
|
||||||
|
name:
|
||||||
|
- zstd
|
||||||
|
when: ansible_pkg_mgr in ('yum', 'dnf', 'apt', 'pkgng')
|
||||||
|
|
||||||
- name: prep our file
|
- name: prep our file
|
||||||
copy:
|
copy:
|
||||||
src: foo.txt
|
src: foo.txt
|
||||||
|
@ -18,6 +25,28 @@
|
||||||
- name: prep a tar.gz file
|
- name: prep a tar.gz file
|
||||||
shell: tar czvf test-unarchive.tar.gz foo-unarchive.txt chdir={{remote_tmp_dir}}
|
shell: tar czvf test-unarchive.tar.gz foo-unarchive.txt chdir={{remote_tmp_dir}}
|
||||||
|
|
||||||
|
- name: see if we have the zstd executable
|
||||||
|
ignore_errors: true
|
||||||
|
shell: zstd --version
|
||||||
|
register: zstd_available
|
||||||
|
|
||||||
|
- when: zstd_available.rc == 0
|
||||||
|
block:
|
||||||
|
- name: find gnu tar
|
||||||
|
shell: |
|
||||||
|
#!/bin/sh
|
||||||
|
which gtar 2>/dev/null
|
||||||
|
if test $? -ne 0; then
|
||||||
|
if test -z "`tar --version | grep bsdtar`"; then
|
||||||
|
which tar
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
register: gnu_tar
|
||||||
|
|
||||||
|
- name: prep a tar.zst file
|
||||||
|
shell: "{{ gnu_tar.stdout }} --use-compress-program=zstd -cvf test-unarchive.tar.zst foo-unarchive.txt chdir={{remote_tmp_dir}}"
|
||||||
|
when: gnu_tar.stdout != ""
|
||||||
|
|
||||||
- name: prep a chmodded file for zip
|
- name: prep a chmodded file for zip
|
||||||
copy:
|
copy:
|
||||||
src: foo.txt
|
src: foo.txt
|
||||||
|
|
40
test/integration/targets/unarchive/tasks/test_tar_zst.yml
Normal file
40
test/integration/targets/unarchive/tasks/test_tar_zst.yml
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
# Only do this whole file when the "zstd" executable is present
|
||||||
|
- when:
|
||||||
|
- zstd_available.rc == 0
|
||||||
|
- gnu_tar.stdout != ""
|
||||||
|
block:
|
||||||
|
- name: create our tar.zst unarchive destination
|
||||||
|
file:
|
||||||
|
path: '{{remote_tmp_dir}}/test-unarchive-tar-zst'
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: unarchive a tar.zst file
|
||||||
|
unarchive:
|
||||||
|
src: '{{remote_tmp_dir}}/test-unarchive.tar.zst'
|
||||||
|
dest: '{{remote_tmp_dir}}/test-unarchive-tar-zst'
|
||||||
|
remote_src: yes
|
||||||
|
register: unarchive02
|
||||||
|
|
||||||
|
- name: verify that the file was marked as changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "unarchive02.changed == true"
|
||||||
|
# Verify that no file list is generated
|
||||||
|
- "'files' not in unarchive02"
|
||||||
|
|
||||||
|
- name: verify that the file was unarchived
|
||||||
|
file:
|
||||||
|
path: '{{remote_tmp_dir}}/test-unarchive-tar-zst/foo-unarchive.txt'
|
||||||
|
state: file
|
||||||
|
|
||||||
|
- name: remove our tar.zst unarchive destination
|
||||||
|
file:
|
||||||
|
path: '{{remote_tmp_dir}}/test-unarchive-tar-zst'
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: test owner/group perms
|
||||||
|
include_tasks: test_owner_group.yml
|
||||||
|
vars:
|
||||||
|
ext: tar.zst
|
||||||
|
archive: test-unarchive.tar.zst
|
||||||
|
testfile: foo-unarchive.txt
|
Loading…
Reference in a new issue