unarchive - Check 'fut_gid' against 'run_gid' in addition to supplemental groups (#65666)

Add integration tests for unarchiving as unprivileged user
Break tasks into separate files for easier reading and maintenance

Create a user by specifying a default group of 'staff' for macOS.

The user module does not actually remove the user directory on macOS,
so explicitly remove it.

Put the removal tasks in an always block to ensure they always run

Co-authored-by: Philip Douglass <philip.douglass@amadeus.com>
Co-authored-by: Sam Doran <sdoran@redhat.com>
pull/71004/head
Philip Douglass 4 years ago committed by GitHub
parent e139739ab3
commit ac5f3f8bef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,2 @@
bugfixes:
- unarchive - check ``fut_gid`` against ``run_gid`` in addition to supplemental groups (https://github.com/ansible/ansible/issues/49284)

@ -564,7 +564,7 @@ class ZipArchive(object):
except (KeyError, ValueError, OverflowError): except (KeyError, ValueError, OverflowError):
gid = st.st_gid gid = st.st_gid
if run_uid != 0 and fut_gid not in groups: if run_uid != 0 and (fut_group != run_group or fut_gid != run_gid) and fut_gid not in groups:
raise UnarchiveError('Cannot change group ownership of %s to %s, as user %s' % (path, fut_group, run_owner)) raise UnarchiveError('Cannot change group ownership of %s to %s, as user %s' % (path, fut_group, run_owner))
if group and group != fut_group: if group and group != fut_group:

@ -1,864 +1,16 @@
# Test code for the unarchive module. - import_tasks: prepare_tests.yml
# (c) 2014, Richard Isaacson <richard.c.isaacson@gmail.com> - import_tasks: test_tar.yml
- import_tasks: test_tar_gz.yml
# This file is part of Ansible - import_tasks: test_tar_gz_creates.yml
# - import_tasks: test_tar_gz_owner_group.yml
# Ansible is free software: you can redistribute it and/or modify - import_tasks: test_tar_gz_keep_newer.yml
# it under the terms of the GNU General Public License as published by - import_tasks: test_zip.yml
# the Free Software Foundation, either version 3 of the License, or - import_tasks: test_exclude.yml
# (at your option) any later version. - import_tasks: test_parent_not_writeable.yml
# - import_tasks: test_mode.yml
# Ansible is distributed in the hope that it will be useful, - import_tasks: test_quotable_characters.yml
# but WITHOUT ANY WARRANTY; without even the implied warranty of - import_tasks: test_non_ascii_filename.yml
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - import_tasks: test_missing_files.yml
# GNU General Public License for more details. - import_tasks: test_symlink.yml
# - import_tasks: test_download.yml
# You should have received a copy of the GNU General Public License - import_tasks: test_unprivileged_user.yml
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# Make sure we start fresh
# Need unzip for unarchive module, and zip for archive creation.
- name: Ensure zip & unzip are present
package:
name:
- zip
- unzip
when: ansible_pkg_mgr in ('yum', 'dnf', 'apt', 'pkgng')
- name: prep our file
copy:
src: foo.txt
dest: "{{remote_tmp_dir}}/foo-unarchive.txt"
- name: prep a tar file
shell: tar cvf test-unarchive.tar foo-unarchive.txt chdir={{remote_tmp_dir}}
- name: prep a tar.gz file
shell: tar czvf test-unarchive.tar.gz foo-unarchive.txt chdir={{remote_tmp_dir}}
- name: prep a chmodded file for zip
copy:
src: foo.txt
dest: '{{remote_tmp_dir}}/foo-unarchive-777.txt'
mode: '0777'
- name: prep a windows permission file for our zip
copy:
src: foo.txt
dest: '{{remote_tmp_dir}}/FOO-UNAR.TXT'
# This gets around an unzip timestamp bug in some distributions
# Recent unzip on Ubuntu and BSD will randomly round some timestamps up.
# But that doesn't seem to happen when the timestamp has an even second.
- name: Bug work around
command: touch -t "201705111530.00" {{remote_tmp_dir}}/foo-unarchive.txt {{remote_tmp_dir}}/foo-unarchive-777.txt {{remote_tmp_dir}}/FOO-UNAR.TXT
# See Ubuntu bug 1691636: https://bugs.launchpad.net/ubuntu/+source/unzip/+bug/1691636
# When these are fixed, this code should be removed.
- name: prep a zip file
shell: zip test-unarchive.zip foo-unarchive.txt foo-unarchive-777.txt chdir={{remote_tmp_dir}}
- name: Prepare - Create test dirs
file:
path: "{{remote_tmp_dir}}/{{item}}"
state: directory
with_items:
- created/include
- created/exclude
- created/other
- name: Prepare - Create test files
file:
path: "{{remote_tmp_dir}}/created/{{item}}"
state: touch
with_items:
- include/include-1.txt
- include/include-2.txt
- include/include-3.txt
- exclude/exclude-1.txt
- exclude/exclude-2.txt
- exclude/exclude-3.txt
- other/include-1.ext
- other/include-2.ext
- other/exclude-1.ext
- other/exclude-2.ext
- other/other-1.ext
- other/other-2.ext
- name: Prepare - zip file
shell: zip -r {{remote_tmp_dir}}/unarchive-00.zip * chdir={{remote_tmp_dir}}/created/
- name: Prepare - tar file
shell: tar czvf {{remote_tmp_dir}}/unarchive-00.tar * chdir={{remote_tmp_dir}}/created/
- name: add a file with Windows permissions to zip file
shell: zip -k test-unarchive.zip FOO-UNAR.TXT chdir={{remote_tmp_dir}}
- name: prep a subdirectory
file:
path: '{{remote_tmp_dir}}/unarchive-dir'
state: directory
- name: prep our file
copy:
src: foo.txt
dest: '{{remote_tmp_dir}}/unarchive-dir/foo-unarchive.txt'
- name: prep a tar.gz file with directory
shell: tar czvf test-unarchive-dir.tar.gz unarchive-dir chdir={{remote_tmp_dir}}
- name: create our tar unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar'
state: directory
- name: unarchive a tar file
unarchive:
src: '{{remote_tmp_dir}}/test-unarchive.tar'
dest: '{{remote_tmp_dir}}/test-unarchive-tar'
remote_src: yes
register: unarchive01
- name: verify that the file was marked as changed
assert:
that:
- "unarchive01.changed == true"
- name: verify that the file was unarchived
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar/foo-unarchive.txt'
state: file
- name: remove our tar unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar'
state: absent
- name: create our tar.gz unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
state: directory
- name: unarchive a tar.gz file
unarchive:
src: '{{remote_tmp_dir}}/test-unarchive.tar.gz'
dest: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
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-gz/foo-unarchive.txt'
state: file
- name: remove our tar.gz unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
state: absent
- name: create our tar.gz unarchive destination for creates
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
state: directory
- name: unarchive a tar.gz file with creates set
unarchive:
src: '{{remote_tmp_dir}}/test-unarchive.tar.gz'
dest: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
creates: '{{remote_tmp_dir}}/test-unarchive-tar-gz/foo-unarchive.txt'
remote_src: yes
register: unarchive02b
- name: verify that the file was marked as changed
assert:
that:
- "unarchive02b.changed == true"
- name: verify that the file was unarchived
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz/foo-unarchive.txt'
state: file
- name: unarchive a tar.gz file with creates over an existing file
unarchive:
src: '{{remote_tmp_dir}}/test-unarchive.tar.gz'
dest: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
creates: '{{remote_tmp_dir}}/test-unarchive-tar-gz/foo-unarchive.txt'
remote_src: yes
register: unarchive02c
- name: verify that the file was not marked as changed
assert:
that:
- "unarchive02c.changed == false"
- name: unarchive a tar.gz file with creates over an existing file using complex_args
unarchive:
src: "{{remote_tmp_dir}}/test-unarchive.tar.gz"
dest: "{{remote_tmp_dir}}/test-unarchive-tar-gz"
remote_src: yes
creates: "{{remote_tmp_dir}}/test-unarchive-tar-gz/foo-unarchive.txt"
register: unarchive02d
- name: verify that the file was not marked as changed
assert:
that:
- "unarchive02d.changed == false"
- name: remove our tar.gz unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
state: absent
- block:
- name: Create a group to chown to
group:
name: testgroup
- name: Create a user to chown to
user:
name: testuser
groups:
- testgroup
- name: create our tar.gz unarchive destination for chown
file:
path: "{{remote_tmp_dir}}/test-unarchive-tar-gz"
state: directory
- name: unarchive a tar.gz file with owner and group set to the above user
unarchive:
src: "{{remote_tmp_dir}}/test-unarchive.tar.gz"
dest: "{{remote_tmp_dir}}/test-unarchive-tar-gz"
remote_src: yes
owner: testuser
group: testgroup
register: unarchive02e
- name: Stat a file in the directory we unarchived to
stat:
path: "{{remote_tmp_dir}}/test-unarchive-tar-gz/foo-unarchive.txt"
register: unarchive02e_file_stat
- name: verify results
assert:
that:
- unarchive02e is changed
- unarchive02e_file_stat.stat.exists
- unarchive02e_file_stat.stat.pw_name == 'testuser'
- unarchive02e_file_stat.stat.gr_name == 'testgroup'
always:
- name: Remove testuser
user:
name: testuser
state: absent
- name: Remove testgroup
group:
name: testgroup
state: absent
# tgz: --keep-newer
- name: create our tar.gz unarchive destination for keep-newer
file:
path: "{{remote_tmp_dir}}/test-unarchive-tar-gz"
state: directory
- name: Create a newer file that we would replace
copy:
dest: "{{remote_tmp_dir}}/test-unarchive-tar-gz/foo-unarchive.txt"
content: boo
- name: unarchive a tar.gz file but avoid overwriting newer files (keep_newer=true)
unarchive:
src: "{{remote_tmp_dir}}/test-unarchive.tar.gz"
dest: "{{remote_tmp_dir}}/test-unarchive-tar-gz"
remote_src: yes
keep_newer: true
register: unarchive02f
- name: Make sure the file still contains 'boo'
shell: cat {{remote_tmp_dir}}/test-unarchive-tar-gz/foo-unarchive.txt
register: unarchive02f_cat
- name: remove our tar.gz unarchive destination
file:
path: "{{remote_tmp_dir}}/test-unarchive-tar-gz"
state: absent
- name: create our tar.gz unarchive destination for keep-newer (take 2)
file:
path: "{{remote_tmp_dir}}/test-unarchive-tar-gz"
state: directory
- name: unarchive a tar.gz file and overwrite newer files (keep_newer=false)
unarchive:
src: "{{remote_tmp_dir}}/test-unarchive.tar.gz"
dest: "{{remote_tmp_dir}}/test-unarchive-tar-gz"
remote_src: yes
keep_newer: false
register: unarchive02g
- name: Make sure the file still contains 'boo'
shell: cat {{remote_tmp_dir}}/test-unarchive-tar-gz/foo-unarchive.txt
register: unarchive02g_cat
- name: remove our tar.gz unarchive destination
file:
path: "{{remote_tmp_dir}}/test-unarchive-tar-gz"
state: absent
- name: verify results
assert:
that:
- unarchive02f is changed
- unarchive02f_cat.stdout == 'boo'
- unarchive02g is changed
- unarchive02g_cat.stdout != 'boo'
# Zip
- name: create our zip unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-zip'
state: directory
- name: unarchive a zip file
unarchive:
src: '{{remote_tmp_dir}}/test-unarchive.zip'
dest: '{{remote_tmp_dir}}/test-unarchive-zip'
list_files: True
remote_src: yes
register: unarchive03
- name: verify that the file was marked as changed
assert:
that:
- "unarchive03.changed == true"
# Verify that file list is generated
- "'files' in unarchive03"
- "{{unarchive03['files']| length}} == 3"
- "'foo-unarchive.txt' in unarchive03['files']"
- "'foo-unarchive-777.txt' in unarchive03['files']"
- "'FOO-UNAR.TXT' in unarchive03['files']"
- name: verify that the file was unarchived
file:
path: '{{remote_tmp_dir}}/test-unarchive-zip/{{item}}'
state: file
with_items:
- foo-unarchive.txt
- foo-unarchive-777.txt
- FOO-UNAR.TXT
- name: repeat the last request to verify no changes
unarchive:
src: '{{remote_tmp_dir}}/test-unarchive.zip'
dest: '{{remote_tmp_dir}}/test-unarchive-zip'
list_files: true
remote_src: true
register: unarchive03b
- name: verify that the task was not marked as changed
assert:
that:
- "unarchive03b.changed == false"
- name: "Create {{ remote_tmp_dir }}/exclude directory"
file:
state: directory
path: "{{ remote_tmp_dir }}/exclude-{{item}}"
with_items:
- zip
- tar
- name: Unpack archive file excluding regular and glob files.
unarchive:
src: "{{ remote_tmp_dir }}/unarchive-00.{{item}}"
dest: "{{ remote_tmp_dir }}/exclude-{{item}}"
remote_src: yes
exclude:
- "exclude/exclude-*.txt"
- "other/exclude-1.ext"
with_items:
- zip
- tar
- name: verify that the file was unarchived
shell: find {{ remote_tmp_dir }}/exclude-{{item}} chdir={{ remote_tmp_dir }}
register: unarchive00
with_items:
- zip
- tar
- name: verify that archive extraction excluded the files
assert:
that:
- "'exclude/exclude-1.txt' not in item.stdout"
- "'other/exclude-1.ext' not in item.stdout"
with_items:
- "{{ unarchive00.results }}"
- name: remove our zip unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-zip'
state: absent
- name: remove our test files for the archive
file:
path: '{{remote_tmp_dir}}/{{item}}'
state: absent
with_items:
- foo-unarchive.txt
- foo-unarchive-777.txt
- FOO-UNAR.TXT
- name: check if /tmp/foo-unarchive.text exists
stat:
path: /tmp/foo-unarchive.txt
ignore_errors: True
register: unarchive04
- name: fail if the proposed destination file exists for safey
fail:
msg: /tmp/foo-unarchive.txt already exists, aborting
when: unarchive04.stat.exists
- name: try unarchiving to /tmp
unarchive:
src: '{{remote_tmp_dir}}/test-unarchive.tar.gz'
dest: /tmp
remote_src: true
register: unarchive05
- name: verify that the file was marked as changed
assert:
that:
- "unarchive05.changed == true"
- name: verify that the file was unarchived
file:
path: /tmp/foo-unarchive.txt
state: file
- name: remove our unarchive destination
file:
path: /tmp/foo-unarchive.txt
state: absent
- name: create our unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
state: directory
- name: unarchive and set mode to 0600, directories 0700
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive.tar.gz"
dest: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
remote_src: yes
mode: "u+rwX,g-rwx,o-rwx"
list_files: True
register: unarchive06
- name: Test that the file modes were changed
stat:
path: "{{ remote_tmp_dir }}/test-unarchive-tar-gz/foo-unarchive.txt"
register: unarchive06_stat
- name: Test that the file modes were changed
assert:
that:
- "unarchive06.changed == true"
- "unarchive06_stat.stat.mode == '0600'"
# Verify that file list is generated
- "'files' in unarchive06"
- "{{unarchive06['files']| length}} == 1"
- "'foo-unarchive.txt' in unarchive06['files']"
- name: remove our tar.gz unarchive destination
file:
path: '{{ remote_tmp_dir }}/test-unarchive-tar-gz'
state: absent
- name: create our unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
state: directory
- name: unarchive over existing extraction and set mode to 0644
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive.tar.gz"
dest: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
remote_src: yes
mode: "u+rwX,g-wx,o-wx,g+r,o+r"
register: unarchive06_2
- name: Test that the file modes were changed
stat:
path: "{{ remote_tmp_dir }}/test-unarchive-tar-gz/foo-unarchive.txt"
register: unarchive06_2_stat
- debug:
var: unarchive06_2_stat.stat.mode
- name: Test that the files were changed
assert:
that:
- "unarchive06_2.changed == true"
- "unarchive06_2_stat.stat.mode == '0644'"
- name: Repeat the last request to verify no changes
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive.tar.gz"
dest: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
remote_src: yes
mode: "u+rwX-x,g-wx,o-wx,g+r,o+r"
list_files: True
register: unarchive07
- name: Test that the files were not changed
assert:
that:
- "unarchive07.changed == false"
# Verify that file list is generated
- "'files' in unarchive07"
- "{{unarchive07['files']| length}} == 1"
- "'foo-unarchive.txt' in unarchive07['files']"
- name: remove our tar.gz unarchive destination
file:
path: '{{ remote_tmp_dir }}/test-unarchive-tar-gz'
state: absent
- name: create our unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-zip'
state: directory
- name: unarchive and set mode to 0601, directories 0700
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive.zip"
dest: "{{ remote_tmp_dir }}/test-unarchive-zip"
remote_src: yes
mode: "u+rwX-x,g-rwx,o=x"
list_files: True
register: unarchive08
- name: Test that the file modes were changed
stat:
path: "{{ remote_tmp_dir }}/test-unarchive-zip/foo-unarchive.txt"
register: unarchive08_stat
- name: Test that the file modes were changed
assert:
that:
- "unarchive08.changed == true"
- "unarchive08_stat.stat.mode == '0601'"
# Verify that file list is generated
- "'files' in unarchive08"
- "{{unarchive08['files']| length}} == 3"
- "'foo-unarchive.txt' in unarchive08['files']"
- "'foo-unarchive-777.txt' in unarchive08['files']"
- "'FOO-UNAR.TXT' in unarchive08['files']"
- name: unarchive zipfile a second time and set mode to 0601, directories 0700
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive.zip"
dest: "{{ remote_tmp_dir }}/test-unarchive-zip"
remote_src: yes
mode: "u+rwX-x,g-rwx,o=x"
list_files: True
register: unarchive08
- name: Test that the file modes were not changed
stat:
path: "{{ remote_tmp_dir }}/test-unarchive-zip/foo-unarchive.txt"
register: unarchive08_stat
- debug:
var: unarchive08
- debug:
var: unarchive08_stat
- name: Test that the files did not change
assert:
that:
- "unarchive08.changed == false"
- "unarchive08_stat.stat.mode == '0601'"
# Verify that file list is generated
- "'files' in unarchive08"
- "{{unarchive08['files']| length}} == 3"
- "'foo-unarchive.txt' in unarchive08['files']"
- "'foo-unarchive-777.txt' in unarchive08['files']"
- "'FOO-UNAR.TXT' in unarchive08['files']"
- name: remove our zip unarchive destination
file:
path: '{{ remote_tmp_dir }}/test-unarchive-zip'
state: absent
- name: create our unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
state: directory
- name: create a directory with quotable chars
file:
path: '{{ remote_tmp_dir }}/test-quotes~root'
state: directory
- name: unarchive into directory with quotable chars
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive.tar.gz"
dest: "{{ remote_tmp_dir }}/test-quotes~root"
remote_src: yes
register: unarchive08
- name: Test that unarchive succeeded
assert:
that:
- "unarchive08.changed == true"
- name: unarchive into directory with quotable chars a second time
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive.tar.gz"
dest: "{{ remote_tmp_dir }}/test-quotes~root"
remote_src: yes
register: unarchive09
- name: Test that unarchive did nothing
assert:
that:
- "unarchive09.changed == false"
- name: remove quotable chars test
file:
path: '{{ remote_tmp_dir }}/test-quotes~root'
state: absent
- name: create our unarchive destination
file:
path: "{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz"
state: directory
- name: test that unarchive works with an archive that contains non-ascii filenames
unarchive:
# Both the filename of the tarball and the filename inside the tarball have
# nonascii chars
src: "test-unarchive-nonascii-くらとみ.tar.gz"
dest: "{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz"
mode: "u+rwX,go+rX"
remote_src: no
register: nonascii_result0
- name: Check that file is really there
stat:
path: "{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz/storage/àâæçéèïîôœ(copy)!@#$%^&-().jpg"
register: nonascii_stat0
- name: Assert that nonascii tests succeeded
assert:
that:
- "nonascii_result0.changed == true"
- "nonascii_stat0.stat.exists == true"
- name: remove nonascii test
file:
path: "{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz"
state: absent
- name: test non-ascii with different LC_ALL
block:
- name: create our unarchive destination
file:
path: "{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz"
state: directory
- name: test that unarchive works with an archive that contains non-ascii filenames
unarchive:
# Both the filename of the tarball and the filename inside the tarball have
# nonascii chars
src: "test-unarchive-nonascii-くらとみ.tar.gz"
dest: "{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz"
mode: "u+rwX,go+rX"
remote_src: no
register: nonascii_result0
- name: Check that file is really there
stat:
path: "{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz/storage/àâæçéèïîôœ(copy)!@#$%^&-().jpg"
register: nonascii_stat0
- name: Assert that nonascii tests succeeded
assert:
that:
- "nonascii_result0.changed == true"
- "nonascii_stat0.stat.exists == true"
- name: remove nonascii test
file:
path: "{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz"
state: absent
environment:
LC_ALL: C
# Test that unarchiving is performed if files are missing
# https://github.com/ansible/ansible-modules-core/issues/1064
- name: create our unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
state: directory
- name: unarchive a tar that has directories
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive-dir.tar.gz"
dest: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
mode: "0700"
remote_src: yes
register: unarchive10
- name: Test that unarchive succeeded
assert:
that:
- "unarchive10.changed == true"
- name: Change the mode of the toplevel dir
file:
path: "{{ remote_tmp_dir }}/test-unarchive-tar-gz/unarchive-dir"
mode: "0701"
- name: Remove a file from the extraction point
file:
path: "{{ remote_tmp_dir }}/test-unarchive-tar-gz/unarchive-dir/foo-unarchive.txt"
state: absent
- name: unarchive a tar that has directories
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive-dir.tar.gz"
dest: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
mode: "0700"
remote_src: yes
register: unarchive10_1
- name: Test that unarchive succeeded
assert:
that:
- "unarchive10_1.changed == true"
- name: remove our tar.gz unarchive destination
file:
path: '{{ remote_tmp_dir }}/test-unarchive-tar-gz'
state: absent
#
# Symlink tests
#
- name: Create a destination dir
file:
path: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
state: directory
- name: Create a symlink to the detination dir
file:
path: "{{ remote_tmp_dir }}/link-to-unarchive-dir"
src: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
state: "link"
- name: test that unarchive works when dest is a symlink to a dir
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive.tar.gz"
dest: "{{ remote_tmp_dir }}/link-to-unarchive-dir"
mode: "u+rwX,go+rX"
remote_src: yes
register: unarchive_11
- name: Check that file is really there
stat:
path: "{{ remote_tmp_dir }}/test-unarchive-tar-gz/foo-unarchive.txt"
register: unarchive11_stat0
- name: Assert that unarchive when dest is a symlink to a dir worked
assert:
that:
- "unarchive_11.changed == true"
- "unarchive11_stat0.stat.exists == true"
- name: remove our tar.gz unarchive destination
file:
path: '{{ remote_tmp_dir }}/test-unarchive-tar-gz'
state: absent
- name: Create a file
file:
path: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
state: touch
- name: Create a symlink to the file
file:
src: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
path: "{{ remote_tmp_dir }}/link-to-unarchive-file"
state: "link"
- name: test that unarchive fails when dest is a link to a file
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive.tar.gz"
dest: "{{ remote_tmp_dir }}/link-to-unarchive-file"
mode: "u+rwX,go+rX"
remote_src: yes
ignore_errors: True
register: unarchive_12
- name: Assert that unarchive when dest is a file failed
assert:
that:
- "unarchive_12.failed == true"
- name: remove our tar.gz unarchive destination
file:
path: '{{ remote_tmp_dir }}/test-unarchive-tar-gz'
state: absent
# Test downloading a file before unarchiving it
- name: create our unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
state: directory
- name: Install packages to make TLS connections work on CentOS 6
pip:
name:
- urllib3==1.10.2
- ndg_httpsclient==0.4.4
- pyOpenSSL==16.2.0
state: present
when:
- ansible_facts.distribution == 'CentOS'
- not ansible_facts.python.has_sslcontext
- name: unarchive a tar from an URL
unarchive:
src: "https://releases.ansible.com/ansible/ansible-latest.tar.gz"
dest: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
mode: "0700"
remote_src: yes
register: unarchive13
- name: Test that unarchive succeeded
assert:
that:
- "unarchive13.changed == true"
- name: remove our tar.gz unarchive destination
file:
path: '{{ remote_tmp_dir }}/test-unarchive-tar-gz'
state: absent

@ -0,0 +1,89 @@
# Need unzip for unarchive module, and zip for archive creation.
- name: Ensure zip & unzip are present
package:
name:
- zip
- unzip
when: ansible_pkg_mgr in ('yum', 'dnf', 'apt', 'pkgng')
- name: prep our file
copy:
src: foo.txt
dest: "{{remote_tmp_dir}}/foo-unarchive.txt"
- name: prep a tar file
shell: tar cvf test-unarchive.tar foo-unarchive.txt chdir={{remote_tmp_dir}}
- name: prep a tar.gz file
shell: tar czvf test-unarchive.tar.gz foo-unarchive.txt chdir={{remote_tmp_dir}}
- name: prep a chmodded file for zip
copy:
src: foo.txt
dest: '{{remote_tmp_dir}}/foo-unarchive-777.txt'
mode: '0777'
- name: prep a windows permission file for our zip
copy:
src: foo.txt
dest: '{{remote_tmp_dir}}/FOO-UNAR.TXT'
# This gets around an unzip timestamp bug in some distributions
# Recent unzip on Ubuntu and BSD will randomly round some timestamps up.
# But that doesn't seem to happen when the timestamp has an even second.
- name: Bug work around
command: touch -t "201705111530.00" {{remote_tmp_dir}}/foo-unarchive.txt {{remote_tmp_dir}}/foo-unarchive-777.txt {{remote_tmp_dir}}/FOO-UNAR.TXT
# See Ubuntu bug 1691636: https://bugs.launchpad.net/ubuntu/+source/unzip/+bug/1691636
# When these are fixed, this code should be removed.
- name: prep a zip file
shell: zip test-unarchive.zip foo-unarchive.txt foo-unarchive-777.txt chdir={{remote_tmp_dir}}
- name: Prepare - Create test dirs
file:
path: "{{remote_tmp_dir}}/{{item}}"
state: directory
with_items:
- created/include
- created/exclude
- created/other
- name: Prepare - Create test files
file:
path: "{{remote_tmp_dir}}/created/{{item}}"
state: touch
with_items:
- include/include-1.txt
- include/include-2.txt
- include/include-3.txt
- exclude/exclude-1.txt
- exclude/exclude-2.txt
- exclude/exclude-3.txt
- other/include-1.ext
- other/include-2.ext
- other/exclude-1.ext
- other/exclude-2.ext
- other/other-1.ext
- other/other-2.ext
- name: Prepare - zip file
shell: zip -r {{remote_tmp_dir}}/unarchive-00.zip * chdir={{remote_tmp_dir}}/created/
- name: Prepare - tar file
shell: tar czvf {{remote_tmp_dir}}/unarchive-00.tar * chdir={{remote_tmp_dir}}/created/
- name: add a file with Windows permissions to zip file
shell: zip -k test-unarchive.zip FOO-UNAR.TXT chdir={{remote_tmp_dir}}
- name: prep a subdirectory
file:
path: '{{remote_tmp_dir}}/unarchive-dir'
state: directory
- name: prep our file
copy:
src: foo.txt
dest: '{{remote_tmp_dir}}/unarchive-dir/foo-unarchive.txt'
- name: prep a tar.gz file with directory
shell: tar czvf test-unarchive-dir.tar.gz unarchive-dir chdir={{remote_tmp_dir}}

@ -0,0 +1,34 @@
# Test downloading a file before unarchiving it
- name: create our unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
state: directory
- name: Install packages to make TLS connections work on CentOS 6
pip:
name:
- urllib3==1.10.2
- ndg_httpsclient==0.4.4
- pyOpenSSL==16.2.0
state: present
when:
- ansible_facts.distribution == 'CentOS'
- not ansible_facts.python.has_sslcontext
- name: unarchive a tar from an URL
unarchive:
src: "https://releases.ansible.com/ansible/ansible-latest.tar.gz"
dest: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
mode: "0700"
remote_src: yes
register: unarchive13
- name: Test that unarchive succeeded
assert:
that:
- "unarchive13.changed == true"
- name: remove our tar.gz unarchive destination
file:
path: '{{ remote_tmp_dir }}/test-unarchive-tar-gz'
state: absent

@ -0,0 +1,48 @@
- name: "Create {{ remote_tmp_dir }}/exclude directory"
file:
state: directory
path: "{{ remote_tmp_dir }}/exclude-{{item}}"
with_items:
- zip
- tar
- name: Unpack archive file excluding regular and glob files.
unarchive:
src: "{{ remote_tmp_dir }}/unarchive-00.{{item}}"
dest: "{{ remote_tmp_dir }}/exclude-{{item}}"
remote_src: yes
exclude:
- "exclude/exclude-*.txt"
- "other/exclude-1.ext"
with_items:
- zip
- tar
- name: verify that the file was unarchived
shell: find {{ remote_tmp_dir }}/exclude-{{item}} chdir={{ remote_tmp_dir }}
register: unarchive00
with_items:
- zip
- tar
- name: verify that archive extraction excluded the files
assert:
that:
- "'exclude/exclude-1.txt' not in item.stdout"
- "'other/exclude-1.ext' not in item.stdout"
with_items:
- "{{ unarchive00.results }}"
- name: remove our zip unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-zip'
state: absent
- name: remove our test files for the archive
file:
path: '{{remote_tmp_dir}}/{{item}}'
state: absent
with_items:
- foo-unarchive.txt
- foo-unarchive-777.txt
- FOO-UNAR.TXT

@ -0,0 +1,47 @@
# Test that unarchiving is performed if files are missing
# https://github.com/ansible/ansible-modules-core/issues/1064
- name: create our unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
state: directory
- name: unarchive a tar that has directories
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive-dir.tar.gz"
dest: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
mode: "0700"
remote_src: yes
register: unarchive10
- name: Test that unarchive succeeded
assert:
that:
- "unarchive10.changed == true"
- name: Change the mode of the toplevel dir
file:
path: "{{ remote_tmp_dir }}/test-unarchive-tar-gz/unarchive-dir"
mode: "0701"
- name: Remove a file from the extraction point
file:
path: "{{ remote_tmp_dir }}/test-unarchive-tar-gz/unarchive-dir/foo-unarchive.txt"
state: absent
- name: unarchive a tar that has directories
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive-dir.tar.gz"
dest: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
mode: "0700"
remote_src: yes
register: unarchive10_1
- name: Test that unarchive succeeded
assert:
that:
- "unarchive10_1.changed == true"
- name: remove our tar.gz unarchive destination
file:
path: '{{ remote_tmp_dir }}/test-unarchive-tar-gz'
state: absent

@ -0,0 +1,151 @@
- name: create our unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
state: directory
- name: unarchive and set mode to 0600, directories 0700
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive.tar.gz"
dest: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
remote_src: yes
mode: "u+rwX,g-rwx,o-rwx"
list_files: True
register: unarchive06
- name: Test that the file modes were changed
stat:
path: "{{ remote_tmp_dir }}/test-unarchive-tar-gz/foo-unarchive.txt"
register: unarchive06_stat
- name: Test that the file modes were changed
assert:
that:
- "unarchive06.changed == true"
- "unarchive06_stat.stat.mode == '0600'"
# Verify that file list is generated
- "'files' in unarchive06"
- "{{unarchive06['files']| length}} == 1"
- "'foo-unarchive.txt' in unarchive06['files']"
- name: remove our tar.gz unarchive destination
file:
path: '{{ remote_tmp_dir }}/test-unarchive-tar-gz'
state: absent
- name: create our unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
state: directory
- name: unarchive over existing extraction and set mode to 0644
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive.tar.gz"
dest: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
remote_src: yes
mode: "u+rwX,g-wx,o-wx,g+r,o+r"
register: unarchive06_2
- name: Test that the file modes were changed
stat:
path: "{{ remote_tmp_dir }}/test-unarchive-tar-gz/foo-unarchive.txt"
register: unarchive06_2_stat
- debug:
var: unarchive06_2_stat.stat.mode
- name: Test that the files were changed
assert:
that:
- "unarchive06_2.changed == true"
- "unarchive06_2_stat.stat.mode == '0644'"
- name: Repeat the last request to verify no changes
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive.tar.gz"
dest: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
remote_src: yes
mode: "u+rwX-x,g-wx,o-wx,g+r,o+r"
list_files: True
register: unarchive07
- name: Test that the files were not changed
assert:
that:
- "unarchive07.changed == false"
# Verify that file list is generated
- "'files' in unarchive07"
- "{{unarchive07['files']| length}} == 1"
- "'foo-unarchive.txt' in unarchive07['files']"
- name: remove our tar.gz unarchive destination
file:
path: '{{ remote_tmp_dir }}/test-unarchive-tar-gz'
state: absent
- name: create our unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-zip'
state: directory
- name: unarchive and set mode to 0601, directories 0700
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive.zip"
dest: "{{ remote_tmp_dir }}/test-unarchive-zip"
remote_src: yes
mode: "u+rwX-x,g-rwx,o=x"
list_files: True
register: unarchive08
- name: Test that the file modes were changed
stat:
path: "{{ remote_tmp_dir }}/test-unarchive-zip/foo-unarchive.txt"
register: unarchive08_stat
- name: Test that the file modes were changed
assert:
that:
- "unarchive08.changed == true"
- "unarchive08_stat.stat.mode == '0601'"
# Verify that file list is generated
- "'files' in unarchive08"
- "{{unarchive08['files']| length}} == 3"
- "'foo-unarchive.txt' in unarchive08['files']"
- "'foo-unarchive-777.txt' in unarchive08['files']"
- "'FOO-UNAR.TXT' in unarchive08['files']"
- name: unarchive zipfile a second time and set mode to 0601, directories 0700
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive.zip"
dest: "{{ remote_tmp_dir }}/test-unarchive-zip"
remote_src: yes
mode: "u+rwX-x,g-rwx,o=x"
list_files: True
register: unarchive08
- name: Test that the file modes were not changed
stat:
path: "{{ remote_tmp_dir }}/test-unarchive-zip/foo-unarchive.txt"
register: unarchive08_stat
- debug:
var: unarchive08
- debug:
var: unarchive08_stat
- name: Test that the files did not change
assert:
that:
- "unarchive08.changed == false"
- "unarchive08_stat.stat.mode == '0601'"
# Verify that file list is generated
- "'files' in unarchive08"
- "{{unarchive08['files']| length}} == 3"
- "'foo-unarchive.txt' in unarchive08['files']"
- "'foo-unarchive-777.txt' in unarchive08['files']"
- "'FOO-UNAR.TXT' in unarchive08['files']"
- name: remove our zip unarchive destination
file:
path: '{{ remote_tmp_dir }}/test-unarchive-zip'
state: absent

@ -0,0 +1,66 @@
- name: create our unarchive destination
file:
path: "{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz"
state: directory
- name: test that unarchive works with an archive that contains non-ascii filenames
unarchive:
# Both the filename of the tarball and the filename inside the tarball have
# nonascii chars
src: "test-unarchive-nonascii-くらとみ.tar.gz"
dest: "{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz"
mode: "u+rwX,go+rX"
remote_src: no
register: nonascii_result0
- name: Check that file is really there
stat:
path: "{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz/storage/àâæçéèïîôœ(copy)!@#$%^&-().jpg"
register: nonascii_stat0
- name: Assert that nonascii tests succeeded
assert:
that:
- "nonascii_result0.changed == true"
- "nonascii_stat0.stat.exists == true"
- name: remove nonascii test
file:
path: "{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz"
state: absent
- name: test non-ascii with different LC_ALL
block:
- name: create our unarchive destination
file:
path: "{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz"
state: directory
- name: test that unarchive works with an archive that contains non-ascii filenames
unarchive:
# Both the filename of the tarball and the filename inside the tarball have
# nonascii chars
src: "test-unarchive-nonascii-くらとみ.tar.gz"
dest: "{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz"
mode: "u+rwX,go+rX"
remote_src: no
register: nonascii_result0
- name: Check that file is really there
stat:
path: "{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz/storage/àâæçéèïîôœ(copy)!@#$%^&-().jpg"
register: nonascii_stat0
- name: Assert that nonascii tests succeeded
assert:
that:
- "nonascii_result0.changed == true"
- "nonascii_stat0.stat.exists == true"
- name: remove nonascii test
file:
path: "{{ remote_tmp_dir }}/test-unarchive-nonascii-くらとみ-tar-gz"
state: absent
environment:
LC_ALL: C

@ -0,0 +1,32 @@
- name: check if /tmp/foo-unarchive.text exists
stat:
path: /tmp/foo-unarchive.txt
ignore_errors: True
register: unarchive04
- name: fail if the proposed destination file exists for safey
fail:
msg: /tmp/foo-unarchive.txt already exists, aborting
when: unarchive04.stat.exists
- name: try unarchiving to /tmp
unarchive:
src: '{{remote_tmp_dir}}/test-unarchive.tar.gz'
dest: /tmp
remote_src: true
register: unarchive05
- name: verify that the file was marked as changed
assert:
that:
- "unarchive05.changed == true"
- name: verify that the file was unarchived
file:
path: /tmp/foo-unarchive.txt
state: file
- name: remove our unarchive destination
file:
path: /tmp/foo-unarchive.txt
state: absent

@ -0,0 +1,38 @@
- name: create our unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
state: directory
- name: create a directory with quotable chars
file:
path: '{{ remote_tmp_dir }}/test-quotes~root'
state: directory
- name: unarchive into directory with quotable chars
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive.tar.gz"
dest: "{{ remote_tmp_dir }}/test-quotes~root"
remote_src: yes
register: unarchive08
- name: Test that unarchive succeeded
assert:
that:
- "unarchive08.changed == true"
- name: unarchive into directory with quotable chars a second time
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive.tar.gz"
dest: "{{ remote_tmp_dir }}/test-quotes~root"
remote_src: yes
register: unarchive09
- name: Test that unarchive did nothing
assert:
that:
- "unarchive09.changed == false"
- name: remove quotable chars test
file:
path: '{{ remote_tmp_dir }}/test-quotes~root'
state: absent

@ -0,0 +1,64 @@
- name: Create a destination dir
file:
path: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
state: directory
- name: Create a symlink to the detination dir
file:
path: "{{ remote_tmp_dir }}/link-to-unarchive-dir"
src: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
state: "link"
- name: test that unarchive works when dest is a symlink to a dir
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive.tar.gz"
dest: "{{ remote_tmp_dir }}/link-to-unarchive-dir"
mode: "u+rwX,go+rX"
remote_src: yes
register: unarchive_11
- name: Check that file is really there
stat:
path: "{{ remote_tmp_dir }}/test-unarchive-tar-gz/foo-unarchive.txt"
register: unarchive11_stat0
- name: Assert that unarchive when dest is a symlink to a dir worked
assert:
that:
- "unarchive_11.changed == true"
- "unarchive11_stat0.stat.exists == true"
- name: remove our tar.gz unarchive destination
file:
path: '{{ remote_tmp_dir }}/test-unarchive-tar-gz'
state: absent
- name: Create a file
file:
path: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
state: touch
- name: Create a symlink to the file
file:
src: "{{ remote_tmp_dir }}/test-unarchive-tar-gz"
path: "{{ remote_tmp_dir }}/link-to-unarchive-file"
state: "link"
- name: test that unarchive fails when dest is a link to a file
unarchive:
src: "{{ remote_tmp_dir }}/test-unarchive.tar.gz"
dest: "{{ remote_tmp_dir }}/link-to-unarchive-file"
mode: "u+rwX,go+rX"
remote_src: yes
ignore_errors: True
register: unarchive_12
- name: Assert that unarchive when dest is a file failed
assert:
that:
- "unarchive_12.failed == true"
- name: remove our tar.gz unarchive destination
file:
path: '{{ remote_tmp_dir }}/test-unarchive-tar-gz'
state: absent

@ -0,0 +1,26 @@
- name: create our tar unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar'
state: directory
- name: unarchive a tar file
unarchive:
src: '{{remote_tmp_dir}}/test-unarchive.tar'
dest: '{{remote_tmp_dir}}/test-unarchive-tar'
remote_src: yes
register: unarchive01
- name: verify that the file was marked as changed
assert:
that:
- "unarchive01.changed == true"
- name: verify that the file was unarchived
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar/foo-unarchive.txt'
state: file
- name: remove our tar unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar'
state: absent

@ -0,0 +1,28 @@
- name: create our tar.gz unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
state: directory
- name: unarchive a tar.gz file
unarchive:
src: '{{remote_tmp_dir}}/test-unarchive.tar.gz'
dest: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
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-gz/foo-unarchive.txt'
state: file
- name: remove our tar.gz unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
state: absent

@ -0,0 +1,53 @@
- name: create our tar.gz unarchive destination for creates
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
state: directory
- name: unarchive a tar.gz file with creates set
unarchive:
src: '{{remote_tmp_dir}}/test-unarchive.tar.gz'
dest: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
creates: '{{remote_tmp_dir}}/test-unarchive-tar-gz/foo-unarchive.txt'
remote_src: yes
register: unarchive02b
- name: verify that the file was marked as changed
assert:
that:
- "unarchive02b.changed == true"
- name: verify that the file was unarchived
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz/foo-unarchive.txt'
state: file
- name: unarchive a tar.gz file with creates over an existing file
unarchive:
src: '{{remote_tmp_dir}}/test-unarchive.tar.gz'
dest: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
creates: '{{remote_tmp_dir}}/test-unarchive-tar-gz/foo-unarchive.txt'
remote_src: yes
register: unarchive02c
- name: verify that the file was not marked as changed
assert:
that:
- "unarchive02c.changed == false"
- name: unarchive a tar.gz file with creates over an existing file using complex_args
unarchive:
src: "{{remote_tmp_dir}}/test-unarchive.tar.gz"
dest: "{{remote_tmp_dir}}/test-unarchive-tar-gz"
remote_src: yes
creates: "{{remote_tmp_dir}}/test-unarchive-tar-gz/foo-unarchive.txt"
register: unarchive02d
- name: verify that the file was not marked as changed
assert:
that:
- "unarchive02d.changed == false"
- name: remove our tar.gz unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-tar-gz'
state: absent

@ -0,0 +1,56 @@
- name: create our tar.gz unarchive destination for keep-newer
file:
path: "{{remote_tmp_dir}}/test-unarchive-tar-gz"
state: directory
- name: Create a newer file that we would replace
copy:
dest: "{{remote_tmp_dir}}/test-unarchive-tar-gz/foo-unarchive.txt"
content: boo
- name: unarchive a tar.gz file but avoid overwriting newer files (keep_newer=true)
unarchive:
src: "{{remote_tmp_dir}}/test-unarchive.tar.gz"
dest: "{{remote_tmp_dir}}/test-unarchive-tar-gz"
remote_src: yes
keep_newer: true
register: unarchive02f
- name: Make sure the file still contains 'boo'
shell: cat {{remote_tmp_dir}}/test-unarchive-tar-gz/foo-unarchive.txt
register: unarchive02f_cat
- name: remove our tar.gz unarchive destination
file:
path: "{{remote_tmp_dir}}/test-unarchive-tar-gz"
state: absent
- name: create our tar.gz unarchive destination for keep-newer (take 2)
file:
path: "{{remote_tmp_dir}}/test-unarchive-tar-gz"
state: directory
- name: unarchive a tar.gz file and overwrite newer files (keep_newer=false)
unarchive:
src: "{{remote_tmp_dir}}/test-unarchive.tar.gz"
dest: "{{remote_tmp_dir}}/test-unarchive-tar-gz"
remote_src: yes
keep_newer: false
register: unarchive02g
- name: Make sure the file still contains 'boo'
shell: cat {{remote_tmp_dir}}/test-unarchive-tar-gz/foo-unarchive.txt
register: unarchive02g_cat
- name: remove our tar.gz unarchive destination
file:
path: "{{remote_tmp_dir}}/test-unarchive-tar-gz"
state: absent
- name: verify results
assert:
that:
- unarchive02f is changed
- unarchive02f_cat.stdout == 'boo'
- unarchive02g is changed
- unarchive02g_cat.stdout != 'boo'

@ -0,0 +1,48 @@
- block:
- name: Create a group to chown to
group:
name: testgroup
- name: Create a user to chown to
user:
name: testuser
groups:
- testgroup
- name: create our tar.gz unarchive destination for chown
file:
path: "{{remote_tmp_dir}}/test-unarchive-tar-gz"
state: directory
- name: unarchive a tar.gz file with owner and group set to the above user
unarchive:
src: "{{remote_tmp_dir}}/test-unarchive.tar.gz"
dest: "{{remote_tmp_dir}}/test-unarchive-tar-gz"
remote_src: yes
owner: testuser
group: testgroup
register: unarchive02e
- name: Stat a file in the directory we unarchived to
stat:
path: "{{remote_tmp_dir}}/test-unarchive-tar-gz/foo-unarchive.txt"
register: unarchive02e_file_stat
- name: verify results
assert:
that:
- unarchive02e is changed
- unarchive02e_file_stat.stat.exists
- unarchive02e_file_stat.stat.pw_name == 'testuser'
- unarchive02e_file_stat.stat.gr_name == 'testgroup'
always:
- name: Remove testuser
user:
name: testuser
state: absent
- name: Remove testgroup
group:
name: testgroup
state: absent

@ -0,0 +1,81 @@
- name: Create unarchivetest1 user
user:
name: unarchivetest1
uid: 1002610001
group: "{{ group_table[ansible_facts['distribution']] | default(omit) }}"
register: user
vars:
group_table:
MacOSX: staff
- name: Test unarchiving twice as unprivileged user
become: yes
become_user: unarchivetest1
block:
- name: prep our file
copy:
src: foo.txt
dest: "{{ user.home }}/foo-unarchive.txt"
- name: Prep a zip file as unarchivetest1 user
shell: zip unarchivetest1-unarchive.zip foo-unarchive.txt
args:
chdir: "{{ user.home }}"
creates: "{{ user.home }}/unarchivetest1-unarchive.zip"
- name: create our zip unarchive destination as unarchivetest1 user
file:
path: "{{ user.home }}/unarchivetest1-unarchive-zip"
state: directory
- name: unarchive a zip file as unarchivetest1 user
unarchive:
src: "{{ user.home }}/unarchivetest1-unarchive.zip"
dest: "{{ user.home }}/unarchivetest1-unarchive-zip"
remote_src: yes
list_files: True
register: unarchive10
- name: verify that the file was marked as changed
assert:
that:
- "unarchive10.changed == true"
# Verify that file list is generated
- "'files' in unarchive10"
- "{{unarchive10['files']| length}} == 1"
- "'foo-unarchive.txt' in unarchive10['files']"
- name: verify that the file was unarchived
file:
path: "{{ user.home }}/unarchivetest1-unarchive-zip/{{ item }}"
state: file
loop:
- foo-unarchive.txt
- name: repeat the last request to verify no changes
unarchive:
src: "{{ user.home }}/unarchivetest1-unarchive.zip"
dest: "{{ user.home }}/unarchivetest1-unarchive-zip"
remote_src: yes
list_files: True
register: unarchive10b
- name: verify that the task was not marked as changed
assert:
that:
- "unarchive10b.changed == false"
always:
- name: remove our unarchivetest1 user and files
user:
name: unarchivetest1
state: absent
remove: yes
become: no
- name: Remove user home directory on macOS
file:
path: /Users/unarchivetest1
state: absent
become: no
when: ansible_facts.distribution == 'MacOSX'

@ -0,0 +1,45 @@
- name: create our zip unarchive destination
file:
path: '{{remote_tmp_dir}}/test-unarchive-zip'
state: directory
- name: unarchive a zip file
unarchive:
src: '{{remote_tmp_dir}}/test-unarchive.zip'
dest: '{{remote_tmp_dir}}/test-unarchive-zip'
list_files: True
remote_src: yes
register: unarchive03
- name: verify that the file was marked as changed
assert:
that:
- "unarchive03.changed == true"
# Verify that file list is generated
- "'files' in unarchive03"
- "{{unarchive03['files']| length}} == 3"
- "'foo-unarchive.txt' in unarchive03['files']"
- "'foo-unarchive-777.txt' in unarchive03['files']"
- "'FOO-UNAR.TXT' in unarchive03['files']"
- name: verify that the file was unarchived
file:
path: '{{remote_tmp_dir}}/test-unarchive-zip/{{item}}'
state: file
with_items:
- foo-unarchive.txt
- foo-unarchive-777.txt
- FOO-UNAR.TXT
- name: repeat the last request to verify no changes
unarchive:
src: '{{remote_tmp_dir}}/test-unarchive.zip'
dest: '{{remote_tmp_dir}}/test-unarchive-zip'
list_files: true
remote_src: true
register: unarchive03b
- name: verify that the task was not marked as changed
assert:
that:
- "unarchive03b.changed == false"
Loading…
Cancel
Save