# 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 and unzip is present to create test archive (yum) yum: name=zip,unzip state=latest when: ansible_pkg_mgr == 'yum' #- name: Ensure zip is present to create test archive (dnf) # dnf: name=zip state=latest # when: ansible_pkg_mgr == 'dnf' - name: Ensure zip & unzip is present to create test archive (apt) apt: name=zip,unzip state=latest when: ansible_pkg_mgr == 'apt' - name: Ensure zip & unzip is present to create test archive (pkg) pkgng: name=zip,unzip state=present when: ansible_pkg_mgr == 'pkgng' - name: prep our file copy: src=foo.txt dest={{output_dir}}/foo-unarchive.txt - name: prep a tar file shell: tar cvf test-unarchive.tar foo-unarchive.txt chdir={{output_dir}} - name: prep a tar.gz file shell: tar czvf test-unarchive.tar.gz foo-unarchive.txt chdir={{output_dir}} - name: prep a chmodded file for zip copy: src=foo.txt dest={{output_dir}}/foo-unarchive-777.txt mode=0777 - name: prep a windows permission file for our zip copy: src=foo.txt dest={{output_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" {{output_dir}}/foo-unarchive.txt {{output_dir}}/foo-unarchive-777.txt {{output_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={{output_dir}} - name: Prepare - Create test dirs file: path: "{{output_dir}}/{{item}}" state: directory with_items: - created/include - created/exclude - created/other - name: Prepare - Create test files file: path: "{{output_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 {{output_dir}}/unarchive-00.zip * chdir={{output_dir}}/created/ - name: Prepare - tar file shell: tar czvf {{output_dir}}/unarchive-00.tar * chdir={{output_dir}}/created/ - name: add a file with Windows permissions to zip file shell: zip -k test-unarchive.zip FOO-UNAR.TXT chdir={{output_dir}} - name: prep a subdirectory file: path={{output_dir}}/unarchive-dir state=directory - name: prep our file copy: src=foo.txt dest={{output_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={{output_dir}} - name: create our tar unarchive destination file: path={{output_dir}}/test-unarchive-tar state=directory - name: unarchive a tar file unarchive: src={{output_dir}}/test-unarchive.tar dest="{{output_dir | expanduser}}/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={{output_dir}}/test-unarchive-tar/foo-unarchive.txt state=file - name: remove our tar unarchive destination file: path={{output_dir}}/test-unarchive-tar state=absent - name: create our tar.gz unarchive destination file: path={{output_dir}}/test-unarchive-tar-gz state=directory - name: unarchive a tar.gz file unarchive: src={{output_dir}}/test-unarchive.tar.gz dest={{output_dir | expanduser}}/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={{output_dir}}/test-unarchive-tar-gz/foo-unarchive.txt state=file - name: remove our tar.gz unarchive destination file: path={{output_dir}}/test-unarchive-tar-gz state=absent - name: create our tar.gz unarchive destination for creates file: path={{output_dir}}/test-unarchive-tar-gz state=directory - name: unarchive a tar.gz file with creates set unarchive: src={{output_dir}}/test-unarchive.tar.gz dest={{output_dir | expanduser}}/test-unarchive-tar-gz remote_src=yes creates={{output_dir}}/test-unarchive-tar-gz/foo-unarchive.txt 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={{output_dir}}/test-unarchive-tar-gz/foo-unarchive.txt state=file - name: unarchive a tar.gz file with creates over an existing file unarchive: src={{output_dir}}/test-unarchive.tar.gz dest={{output_dir | expanduser}}/test-unarchive-tar-gz remote_src=yes creates={{output_dir}}/test-unarchive-tar-gz/foo-unarchive.txt 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: "{{output_dir}}/test-unarchive.tar.gz" dest: "{{output_dir | expanduser}}/test-unarchive-tar-gz" remote_src: yes creates: "{{output_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={{output_dir}}/test-unarchive-tar-gz state=absent - name: create our zip unarchive destination file: path={{output_dir}}/test-unarchive-zip state=directory - name: unarchive a zip file unarchive: src={{output_dir}}/test-unarchive.zip dest={{output_dir | expanduser}}/test-unarchive-zip remote_src=yes list_files=True 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={{output_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={{output_dir}}/test-unarchive.zip dest={{output_dir | expanduser}}/test-unarchive-zip remote_src=yes list_files=True register: unarchive03b - name: verify that the task was not marked as changed assert: that: - "unarchive03b.changed == false" - name: "Create {{ output_dir }}/exclude directory" file: state: directory path: "{{ output_dir }}/exclude-{{item}}" with_items: - zip - tar - name: Unpack archive file excluding regular and glob files. unarchive: src: "{{ output_dir }}/unarchive-00.{{item}}" dest: "{{ output_dir }}/exclude-{{item}}" exclude: - "exclude/exclude-*.txt" - "other/exclude-1.ext" with_items: - zip - tar - name: verify that the file was unarchived shell: find {{ output_dir }}/exclude-{{item}} chdir={{ output_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={{output_dir}}/test-unarchive-zip state=absent - name: remove our test files for the archive file: path={{output_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={{output_dir}}/test-unarchive.tar.gz dest=/tmp remote_src=yes 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={{output_dir}}/test-unarchive-tar-gz state=directory - name: unarchive and set mode to 0600, directories 0700 unarchive: src: "{{ output_dir }}/test-unarchive.tar.gz" dest: "{{ output_dir | expanduser }}/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: "{{ output_dir | expanduser }}/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={{ output_dir }}/test-unarchive-tar-gz state=absent - name: create our unarchive destination file: path={{output_dir}}/test-unarchive-tar-gz state=directory - name: unarchive over existing extraction and set mode to 0644 unarchive: src: "{{ output_dir }}/test-unarchive.tar.gz" dest: "{{ output_dir | expanduser }}/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: "{{ output_dir | expanduser }}/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: "{{ output_dir }}/test-unarchive.tar.gz" dest: "{{ output_dir | expanduser }}/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={{ output_dir }}/test-unarchive-tar-gz state=absent - name: create our unarchive destination file: path={{output_dir}}/test-unarchive-zip state=directory - name: unarchive and set mode to 0601, directories 0700 unarchive: src: "{{ output_dir }}/test-unarchive.zip" dest: "{{ output_dir | expanduser }}/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: "{{ output_dir | expanduser }}/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: "{{ output_dir }}/test-unarchive.zip" dest: "{{ output_dir | expanduser }}/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: "{{ output_dir | expanduser }}/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={{ output_dir }}/test-unarchive-zip state=absent - name: create our unarchive destination file: path={{output_dir}}/test-unarchive-tar-gz state=directory - name: create a directory with quotable chars file: path="{{ output_dir }}/test-quotes~root" state=directory - name: unarchive into directory with quotable chars unarchive: src: "{{ output_dir }}/test-unarchive.tar.gz" dest: "{{ output_dir | expanduser }}/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: "{{ output_dir }}/test-unarchive.tar.gz" dest: "{{ output_dir | expanduser }}/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="{{ output_dir }}/test-quotes~root" state=absent - name: create our unarchive destination file: path: "{{ output_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: "{{ output_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: "{{ output_dir | expanduser }}/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="{{ output_dir }}/test-unarchive-nonascii-くらとみ-tar-gz" state=absent # 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={{output_dir}}/test-unarchive-tar-gz state=directory - name: unarchive a tar that has directories unarchive: src: "{{ output_dir }}/test-unarchive-dir.tar.gz" dest: "{{ output_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: "{{ output_dir }}/test-unarchive-tar-gz/unarchive-dir" mode: 0701 - name: Remove a file from the extraction point file: path: "{{ output_dir }}/test-unarchive-tar-gz/unarchive-dir/foo-unarchive.txt" state: absent - name: unarchive a tar that has directories unarchive: src: "{{ output_dir }}/test-unarchive-dir.tar.gz" dest: "{{ output_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={{ output_dir }}/test-unarchive-tar-gz state=absent # # Symlink tests # - name: Create a destination dir file: path: "{{ output_dir }}/test-unarchive-tar-gz" state: directory - name: Create a symlink to the detination dir file: path: "{{ output_dir }}/link-to-unarchive-dir" src: "{{ output_dir }}/test-unarchive-tar-gz" state: "link" - name: test that unarchive works when dest is a symlink to a dir unarchive: src: "{{ output_dir }}/test-unarchive.tar.gz" dest: "{{ output_dir | expanduser }}/link-to-unarchive-dir" mode: "u+rwX,go+rX" remote_src: yes register: unarchive_11 - name: Check that file is really there stat: path: "{{ output_dir | expanduser }}/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={{ output_dir }}/test-unarchive-tar-gz state=absent - name: Create a file file: path: "{{ output_dir }}/test-unarchive-tar-gz" state: touch - name: Create a symlink to the file file: path: "{{ output_dir }}/link-to-unarchive-file" src: "{{ output_dir }}/test-unarchive-tar-gz" state: "link" - name: test that unarchive fails when dest is a link to a file unarchive: src: "{{ output_dir }}/test-unarchive.tar.gz" dest: "{{ output_dir | expanduser }}/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={{ output_dir }}/test-unarchive-tar-gz state=absent # Test downloading a file before unarchiving it - name: create our unarchive destination file: path={{output_dir}}/test-unarchive-tar-gz state=directory - name: unarchive a tar from an URL unarchive: src: "https://releases.ansible.com/ansible/ansible-latest.tar.gz" dest: "{{ output_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={{ output_dir }}/test-unarchive-tar-gz state=absent