diff --git a/changelogs/fragments/5393-archive.yml b/changelogs/fragments/5393-archive.yml new file mode 100644 index 0000000000..a589c935ec --- /dev/null +++ b/changelogs/fragments/5393-archive.yml @@ -0,0 +1,2 @@ +bugfixes: + - "archive - avoid crash when ``lzma`` is not present and ``format`` is not ``xz`` (https://github.com/ansible-collections/community.general/pull/5393)." diff --git a/plugins/modules/files/archive.py b/plugins/modules/files/archive.py index 91dc6e5112..b7a05a0b2a 100644 --- a/plugins/modules/files/archive.py +++ b/plugins/modules/files/archive.py @@ -581,6 +581,11 @@ class TarArchive(Archive): self.file.add(path, archive_name, recursive=False, exclude=py26_filter) def _get_checksums(self, path): + if HAS_LZMA: + LZMAError = lzma.LZMAError + else: + # Just picking another exception that's also listed below + LZMAError = tarfile.ReadError try: if self.format == 'xz': with lzma.open(_to_native_ascii(path), 'r') as f: @@ -591,7 +596,7 @@ class TarArchive(Archive): archive = tarfile.open(_to_native_ascii(path), 'r|' + self.format) checksums = set((info.name, info.chksum) for info in archive.getmembers()) archive.close() - except (lzma.LZMAError, tarfile.ReadError, tarfile.CompressionError): + except (LZMAError, tarfile.ReadError, tarfile.CompressionError): try: # The python implementations of gzip, bz2, and lzma do not support restoring compressed files # to their original names so only file checksum is returned diff --git a/tests/integration/targets/archive/tasks/main.yml b/tests/integration/targets/archive/tasks/main.yml index e7b6c44175..88f2878afa 100644 --- a/tests/integration/targets/archive/tasks/main.yml +++ b/tests/integration/targets/archive/tasks/main.yml @@ -23,6 +23,37 @@ # Make sure we start fresh # Test setup +- name: prep our files + copy: src={{ item }} dest={{remote_tmp_dir}}/{{ item }} + with_items: + - foo.txt + - bar.txt + - empty.txt + - sub + - sub/subfile.txt + +# Run twice without lzma backport installed, to make sure it does not crash +- name: Archive - pre-test - first run + archive: + path: "{{ remote_tmp_dir }}/*.txt" + dest: "{{ remote_tmp_dir }}/archive_pretest_1.tar" + format: "tar" + register: pretest_1 + +- name: Archive - pre-test - second run + archive: + path: "{{ remote_tmp_dir }}/*.txt" + dest: "{{ remote_tmp_dir }}/archive_pretest_1.tar" + format: "tar" + register: pretest_2 + +- name: Archive - validate pre-test + assert: + that: + - pretest_1 is changed + - pretest_2 is not changed + +# Install dependencies - name: Ensure zip is present to create test archive (yum) yum: name=zip state=latest when: ansible_facts.pkg_mgr == 'yum' @@ -74,15 +105,6 @@ when: ansible_python_version.split('.')[0] == '2' register: backports_lzma_pip -- name: prep our files - copy: src={{ item }} dest={{remote_tmp_dir}}/{{ item }} - with_items: - - foo.txt - - bar.txt - - empty.txt - - sub - - sub/subfile.txt - - name: Define formats to test set_fact: formats: