Fix idempotency for Unix permissions in zip files. (#24580)

* Fix idempotency for Unix permissions in zip files.

This fix prevents the unarchive module from reporting 'changed' when a zipfile contains items with Unix permissions that differ from the system default.

* Update zip unarchive tests.

Additional tests for the unarchive module with zip files:
- Test file in zip archive with non-default permissions
- Test file added to zip archive with Windows permissions

* Additional fix for mixed win/unix archives.

  Turns out my original fix fails under some mixed archives, as setting the umask to zero can be applied to those files.  This creates a per-file umask variable, so a mix of permission types don't cause problems.

* CI Checks

CI checks for archives with:
* non default Unix permissions
* Windows permissions


* Workaround for BSD differences.

Using Zipinfo due to lack of support in BSD unzip.
Permissions handling is also different in BSD -- always applies UMASK to file permissions.

* Added checks for creating directories and SSH keys for existing users.
This commit is contained in:
chriskarel 2017-08-11 14:36:46 -05:00 committed by Toshio Kuratomi
commit 991918e9d2
2 changed files with 71 additions and 14 deletions

View file

@ -17,18 +17,23 @@
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# Make sure we start fresh
- name: Ensure zip is present to create test archive (yum)
yum: name=zip state=latest
# Need unzup 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 is present to create test archive (apt)
apt: name=zip state=latest
- name: Ensure zip & unzup is present to create test archive (apt)
apt: name=zip,unzip state=latest
when: ansible_pkg_mgr == 'apt'
- name: Ensure zip & unzup 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
@ -38,9 +43,27 @@
- name: prep a tar.gz file
shell: tar czvf test-unarchive.tar.gz foo-unarchive.txt chdir={{output_dir}}
- name: prep a zip file
shell: zip test-unarchive.zip 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 Fedora, 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 Fedora bug 1451953: https://bugzilla.redhat.com/show_bug.cgi?id=1451953
# 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: 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
@ -141,17 +164,36 @@
- "unarchive03.changed == true"
# Verify that file list is generated
- "'files' in unarchive03"
- "{{unarchive03['files']| length}} == 1"
- "{{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/foo-unarchive.txt state=file
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: remove our zip unarchive destination
file: path={{output_dir}}/test-unarchive-zip state=absent
- name: remove our test file for the archive
file: path={{output_dir}}/foo-unarchive.txt 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