From bcd6b5c6f8caebdb557e853b397f748c36a9b5d8 Mon Sep 17 00:00:00 2001 From: Shinichi TAMURA Date: Mon, 11 Jun 2018 23:27:50 +0900 Subject: [PATCH] BSDTimezone: distinguish UTC and Etc/UTC (#41234) * Fixed BSDTimezone to distinguish UTC and Etc/UTC * Added test for timezone to disinguish UTC vs Etc/UTC --- lib/ansible/modules/system/timezone.py | 32 +++---------- .../targets/timezone/tasks/test.yml | 48 +++++++++++++++++++ 2 files changed, 55 insertions(+), 25 deletions(-) diff --git a/lib/ansible/modules/system/timezone.py b/lib/ansible/modules/system/timezone.py index d4be8bdb937..d9fc8cfbe7b 100644 --- a/lib/ansible/modules/system/timezone.py +++ b/lib/ansible/modules/system/timezone.py @@ -705,25 +705,6 @@ class BSDTimezone(Timezone): return 'UTC' # Strategy 2: - # Return planned timezone as current timezone if their content matches. - # This is bad design to see `self.value` here, - # but it's intended to avoid useless diff. - planned = self.value['name']['planned'] - try: - planned_zonefile = os.path.join(zoneinfo_dir, planned) - already_planned_state = filecmp.cmp(planned_zonefile, localtime_file) - - except OSError: - # Even if reading planned zoneinfo file gives an OSError, don't abort here, - # because a bit more detailed check will be done in `set`. - already_planned_state = False - # Handle the case where the file comp previously would claim UTC and Etc/UTC - # are the same because they are the same file, but not the same path. This - # breaks idempotent task runs. - if already_planned_state and (planned_zonefile == os.path.realpath(planned_zonefile)): - return planned - - # Strategy 3: # Follow symlink of /etc/localtime zoneinfo_file = localtime_file while not zoneinfo_file.startswith(zoneinfo_dir): @@ -735,15 +716,16 @@ class BSDTimezone(Timezone): else: return zoneinfo_file.replace(zoneinfo_dir, '') - # Strategy 4: - # Check all files in /usr/share/zoneinfo and return first match. - for dname, _, fnames in os.walk(zoneinfo_dir): - for fname in fnames: + # Strategy 3: + # (If /etc/localtime is not symlinked) + # Check all files in /usr/share/zoneinfo and return first non-link match. + for dname, _, fnames in sorted(os.walk(zoneinfo_dir)): + for fname in sorted(fnames): zoneinfo_file = os.path.join(dname, fname) - if filecmp.cmp(zoneinfo_file, localtime_file): + if not os.path.islink(zoneinfo_file) and filecmp.cmp(zoneinfo_file, localtime_file): return zoneinfo_file.replace(zoneinfo_dir, '') - # Strategy 5: + # Strategy 4: # As a fall-back, return 'UTC' as default assumption. self.module.warn('Could not identify timezone name from /etc/localtime. Assuming UTC.') return 'UTC' diff --git a/test/integration/targets/timezone/tasks/test.yml b/test/integration/targets/timezone/tasks/test.yml index a44ec95e5fe..ec0d854df0c 100644 --- a/test/integration/targets/timezone/tasks/test.yml +++ b/test/integration/targets/timezone/tasks/test.yml @@ -81,6 +81,54 @@ that: - not timezone_again_checkmode.changed +## +## tests for same timezones with different names +## + +- name: check dpkg-reconfigure + shell: type dpkg-reconfigure + register: check_dpkg_reconfigure + ignore_errors: yes + changed_when: no + +- name: check timedatectl + shell: type timedatectl && timedatectl + register: check_timedatectl + ignore_errors: yes + changed_when: no + +- block: + - name: set timezone to Etc/UTC + timezone: + name: Etc/UTC + + - name: change timezone from Etc/UTC to UTC + timezone: + name: UTC + register: timezone_etcutc_to_utc + + - name: check timezone changed from Etc/UTC to UTC + assert: + that: + - timezone_etcutc_to_utc.changed + - timezone_etcutc_to_utc.diff.before.name == 'Etc/UTC' + - timezone_etcutc_to_utc.diff.after.name == 'UTC' + + - name: change timezone from UTC to Etc/UTC + timezone: + name: Etc/UTC + register: timezone_utc_to_etcutc + + - name: check timezone changed from UTC to Etc/UTC + assert: + that: + - timezone_utc_to_etcutc.changed + - timezone_utc_to_etcutc.diff.before.name == 'UTC' + - timezone_utc_to_etcutc.diff.after.name == 'Etc/UTC' + + when: + # FIXME: Due to the bug of the dpkg-reconfigure, those tests failed on non-systemd debian + - check_dpkg_reconfigure.rc != 0 or check_timedatectl.rc == 0 ## ## no systemd tests for timezone