unarchive: make timezone aware timestamp (#85799)

* Consider the timezone offset while creating timestamp from `zipinfo -T`
  information. This information is required while comparing to mtime of the file
  on local filesystem (for idempotency purposes).

Fixes: #85779

Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
This commit is contained in:
Abhijeet Kasurde 2026-01-15 04:13:13 -08:00 committed by GitHub
parent bf349232e2
commit a3782f0e7d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 68 additions and 4 deletions

View file

@ -0,0 +1,3 @@
---
bugfixes:
- unarchive - make timezone aware timestamp for comparison (https://github.com/ansible/ansible/issues/85779).

View file

@ -428,17 +428,17 @@ class ZipArchive(object):
""" Return a valid time object from the given time string """
DT_RE = re.compile(r'^(\d{4})(\d{2})(\d{2})\.(\d{2})(\d{2})(\d{2})$')
match = DT_RE.match(timestamp_str)
epoch_date_time = (1980, 1, 1, 0, 0, 0, 0, 0, 0)
epoch_date_time = (1980, 1, 1, 0, 0, 0, 0, 0, -1)
if match:
try:
if int(match.groups()[0]) < 1980:
date_time = epoch_date_time
elif int(match.groups()[0]) >= 2038 and _y2038_impacted():
date_time = (2038, 1, 1, 0, 0, 0, 0, 0, 0)
date_time = (2038, 1, 1, 0, 0, 0, 0, 0, -1)
elif int(match.groups()[0]) > 2107:
date_time = (2107, 12, 31, 23, 59, 59, 0, 0, 0)
date_time = (2107, 12, 31, 23, 59, 59, 0, 0, -1)
else:
date_time = (int(m) for m in match.groups() + (0, 0, 0))
date_time = (int(m) for m in match.groups() + (0, 0, -1))
except ValueError:
date_time = epoch_date_time
else:

View file

@ -9,6 +9,7 @@
- import_tasks: test_tar_gz_content_differs.yml
- import_tasks: test_tar_zst.yml
- import_tasks: test_zip.yml
- import_tasks: test_zip_timezone_dst.yml
- import_tasks: test_exclude.yml
- import_tasks: test_include.yml
- import_tasks: test_parent_not_writeable.yml

View file

@ -0,0 +1,60 @@
# Ensure timestamp verification for zip unarchive is correctly done
# Setup
- name: Prepare - Create test dirs
file:
path: "{{remote_tmp_dir}}/datetime-dst"
state: directory
- name: Setup custom DST (date saving time) for zip test
# datetime must match a DST period for Europe/Paris
file:
path: "{{ remote_tmp_dir }}/datetime-dst/datetime-dst.txt"
state: touch
modification_time: 202507241203.34
- name: Prepare - zip file (timezone DST)
shell:
cmd: zip -r {{remote_tmp_dir}}/test-datetime-dst.zip *
chdir: "{{remote_tmp_dir}}/datetime-dst/"
# Test timezone DST
- environment:
TZ: Europe/Paris
block:
- name: Create zip unarchive destination
file:
path: '{{ remote_tmp_dir }}/test-unarchive-zip-timezone-dst'
state: directory
- name: Unarchive a zip file
unarchive:
src: '{{ remote_tmp_dir }}/test-datetime-dst.zip'
dest: '{{ remote_tmp_dir }}/test-unarchive-zip-timezone-dst'
list_files: True
remote_src: yes
register: unarchive_timezone
- name: Check if file is created
stat:
path: '{{ remote_tmp_dir }}/test-unarchive-zip-timezone-dst/datetime-dst.txt'
register: file_created
- name: Verify that the file was marked as changed
assert:
that:
- unarchive_timezone.changed
- file_created.stat.exists
- name: Unarchive a zip file again
unarchive:
src: '{{ remote_tmp_dir }}/test-datetime-dst.zip'
dest: '{{ remote_tmp_dir }}/test-unarchive-zip-timezone-dst'
list_files: True
remote_src: yes
register: unarchive_timezone
- name: Verify that the task was not marked as changed
assert:
that:
- not unarchive_timezone.changed