diff --git a/changelogs/fragments/unarchive-check-future-gid-against-run-gid.yml b/changelogs/fragments/unarchive-check-future-gid-against-run-gid.yml new file mode 100644 index 00000000000..2b0ed71892c --- /dev/null +++ b/changelogs/fragments/unarchive-check-future-gid-against-run-gid.yml @@ -0,0 +1,2 @@ +bugfixes: + - unarchive - check ``fut_gid`` against ``run_gid`` in addition to supplemental groups (https://github.com/ansible/ansible/issues/49284) diff --git a/lib/ansible/modules/unarchive.py b/lib/ansible/modules/unarchive.py index f69ab1c6cb1..f39bd8725bd 100644 --- a/lib/ansible/modules/unarchive.py +++ b/lib/ansible/modules/unarchive.py @@ -564,7 +564,7 @@ class ZipArchive(object): except (KeyError, ValueError, OverflowError): 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)) if group and group != fut_group: diff --git a/test/integration/targets/unarchive/tasks/main.yml b/test/integration/targets/unarchive/tasks/main.yml index 5c35b183835..7051539c63e 100644 --- a/test/integration/targets/unarchive/tasks/main.yml +++ b/test/integration/targets/unarchive/tasks/main.yml @@ -1,864 +1,16 @@ -# Test code for the unarchive module. -# (c) 2014, Richard Isaacson - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . -# 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 +- import_tasks: prepare_tests.yml +- import_tasks: test_tar.yml +- import_tasks: test_tar_gz.yml +- import_tasks: test_tar_gz_creates.yml +- import_tasks: test_tar_gz_owner_group.yml +- import_tasks: test_tar_gz_keep_newer.yml +- import_tasks: test_zip.yml +- import_tasks: test_exclude.yml +- import_tasks: test_parent_not_writeable.yml +- import_tasks: test_mode.yml +- import_tasks: test_quotable_characters.yml +- import_tasks: test_non_ascii_filename.yml +- import_tasks: test_missing_files.yml +- import_tasks: test_symlink.yml +- import_tasks: test_download.yml +- import_tasks: test_unprivileged_user.yml diff --git a/test/integration/targets/unarchive/tasks/prepare_tests.yml b/test/integration/targets/unarchive/tasks/prepare_tests.yml new file mode 100644 index 00000000000..e3e724a2316 --- /dev/null +++ b/test/integration/targets/unarchive/tasks/prepare_tests.yml @@ -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}} diff --git a/test/integration/targets/unarchive/tasks/test_download.yml b/test/integration/targets/unarchive/tasks/test_download.yml new file mode 100644 index 00000000000..6b17449bf9f --- /dev/null +++ b/test/integration/targets/unarchive/tasks/test_download.yml @@ -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 diff --git a/test/integration/targets/unarchive/tasks/test_exclude.yml b/test/integration/targets/unarchive/tasks/test_exclude.yml new file mode 100644 index 00000000000..be24756c0ae --- /dev/null +++ b/test/integration/targets/unarchive/tasks/test_exclude.yml @@ -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 diff --git a/test/integration/targets/unarchive/tasks/test_missing_files.yml b/test/integration/targets/unarchive/tasks/test_missing_files.yml new file mode 100644 index 00000000000..4f57e184869 --- /dev/null +++ b/test/integration/targets/unarchive/tasks/test_missing_files.yml @@ -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 diff --git a/test/integration/targets/unarchive/tasks/test_mode.yml b/test/integration/targets/unarchive/tasks/test_mode.yml new file mode 100644 index 00000000000..c69e3bd2b23 --- /dev/null +++ b/test/integration/targets/unarchive/tasks/test_mode.yml @@ -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 diff --git a/test/integration/targets/unarchive/tasks/test_non_ascii_filename.yml b/test/integration/targets/unarchive/tasks/test_non_ascii_filename.yml new file mode 100644 index 00000000000..c884f49a219 --- /dev/null +++ b/test/integration/targets/unarchive/tasks/test_non_ascii_filename.yml @@ -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 diff --git a/test/integration/targets/unarchive/tasks/test_parent_not_writeable.yml b/test/integration/targets/unarchive/tasks/test_parent_not_writeable.yml new file mode 100644 index 00000000000..bfb082c6aa7 --- /dev/null +++ b/test/integration/targets/unarchive/tasks/test_parent_not_writeable.yml @@ -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 diff --git a/test/integration/targets/unarchive/tasks/test_quotable_characters.yml b/test/integration/targets/unarchive/tasks/test_quotable_characters.yml new file mode 100644 index 00000000000..0a3c2cc3403 --- /dev/null +++ b/test/integration/targets/unarchive/tasks/test_quotable_characters.yml @@ -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 diff --git a/test/integration/targets/unarchive/tasks/test_symlink.yml b/test/integration/targets/unarchive/tasks/test_symlink.yml new file mode 100644 index 00000000000..fcb728282bf --- /dev/null +++ b/test/integration/targets/unarchive/tasks/test_symlink.yml @@ -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 diff --git a/test/integration/targets/unarchive/tasks/test_tar.yml b/test/integration/targets/unarchive/tasks/test_tar.yml new file mode 100644 index 00000000000..09105c600e8 --- /dev/null +++ b/test/integration/targets/unarchive/tasks/test_tar.yml @@ -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 diff --git a/test/integration/targets/unarchive/tasks/test_tar_gz.yml b/test/integration/targets/unarchive/tasks/test_tar_gz.yml new file mode 100644 index 00000000000..ac9e9a15499 --- /dev/null +++ b/test/integration/targets/unarchive/tasks/test_tar_gz.yml @@ -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 diff --git a/test/integration/targets/unarchive/tasks/test_tar_gz_creates.yml b/test/integration/targets/unarchive/tasks/test_tar_gz_creates.yml new file mode 100644 index 00000000000..fa3a23f8b86 --- /dev/null +++ b/test/integration/targets/unarchive/tasks/test_tar_gz_creates.yml @@ -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 diff --git a/test/integration/targets/unarchive/tasks/test_tar_gz_keep_newer.yml b/test/integration/targets/unarchive/tasks/test_tar_gz_keep_newer.yml new file mode 100644 index 00000000000..1d5ffb9d716 --- /dev/null +++ b/test/integration/targets/unarchive/tasks/test_tar_gz_keep_newer.yml @@ -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' diff --git a/test/integration/targets/unarchive/tasks/test_tar_gz_owner_group.yml b/test/integration/targets/unarchive/tasks/test_tar_gz_owner_group.yml new file mode 100644 index 00000000000..257692e1b13 --- /dev/null +++ b/test/integration/targets/unarchive/tasks/test_tar_gz_owner_group.yml @@ -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 diff --git a/test/integration/targets/unarchive/tasks/test_unprivileged_user.yml b/test/integration/targets/unarchive/tasks/test_unprivileged_user.yml new file mode 100644 index 00000000000..826e875ef4e --- /dev/null +++ b/test/integration/targets/unarchive/tasks/test_unprivileged_user.yml @@ -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' diff --git a/test/integration/targets/unarchive/tasks/test_zip.yml b/test/integration/targets/unarchive/tasks/test_zip.yml new file mode 100644 index 00000000000..aae57d8ec90 --- /dev/null +++ b/test/integration/targets/unarchive/tasks/test_zip.yml @@ -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"