From 0c10e1ebe4d2be58b95af8663eab1815f30a9608 Mon Sep 17 00:00:00 2001 From: Will Thames Date: Fri, 20 Oct 2017 16:02:38 +1000 Subject: [PATCH] Handle timezone updates on Ubuntu 16.04+ on containers (#27546) * Handle timezone updates on Ubuntu 16.04+ on containers Although Ubuntu 16.04 will use timedatectl by default, containers without a working timedatectl need to use the old method. A bug in Ubuntu for the old method means having to write a nasty hack https://bugs.launchpad.net/ubuntu/+source/tzdata/+bug/1554806 * Add tests for timezones Ensure timezone changes work across various OSs --- lib/ansible/modules/system/timezone.py | 16 +++++++++------- test/integration/targets/timezone/aliases | 4 ++++ test/integration/targets/timezone/tasks/main.yml | 15 +++++++++++++++ 3 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 test/integration/targets/timezone/aliases create mode 100644 test/integration/targets/timezone/tasks/main.yml diff --git a/lib/ansible/modules/system/timezone.py b/lib/ansible/modules/system/timezone.py index 8abc1f5c58..0cce1d3020 100644 --- a/lib/ansible/modules/system/timezone.py +++ b/lib/ansible/modules/system/timezone.py @@ -334,15 +334,15 @@ class NosystemdTimezone(Timezone): # Validate given timezone if 'name' in self.value: tzfile = self._verify_timezone() - self.update_timezone = self.module.get_bin_path('cp', required=True) - self.update_timezone += ' %s /etc/localtime' % tzfile + self.update_timezone = ['%s %s /etc/localtime' % (self.module.get_bin_path('cp', required=True), tzfile)] self.update_hwclock = self.module.get_bin_path('hwclock', required=True) self.allow_no_file['hwclock'] = True # Since this is only used for get values, file absense does not metter # Distribution-specific configurations if self.module.get_bin_path('dpkg-reconfigure') is not None: # Debian/Ubuntu - self.update_timezone = self.module.get_bin_path('dpkg-reconfigure', required=True) - self.update_timezone += ' --frontend noninteractive tzdata' + # With additional hack for https://bugs.launchpad.net/ubuntu/+source/tzdata/+bug/1554806 + self.update_timezone = ['rm -f /etc/localtime', '%s --frontend noninteractive tzdata' % + self.module.get_bin_path('dpkg-reconfigure', required=True)] self.conf_files['name'] = '/etc/timezone' self.allow_no_file['name'] = True self.conf_files['hwclock'] = '/etc/default/rcS' @@ -351,7 +351,7 @@ class NosystemdTimezone(Timezone): else: # RHEL/CentOS if self.module.get_bin_path('tzdata-update') is not None: - self.update_timezone = self.module.get_bin_path('tzdata-update', required=True) + self.update_timezone = [self.module.get_bin_path('tzdata-update', required=True)] self.allow_no_file['name'] = True # else: # self.update_timezone = 'cp ...' <- configured above @@ -456,7 +456,8 @@ class NosystemdTimezone(Timezone): regexp=self.regexps['name'], value=self.tzline_format % value, key='name') - self.execute(self.update_timezone) + for cmd in self.update_timezone: + self.execute(cmd) def set_hwclock(self, value): if value == 'local': @@ -652,7 +653,8 @@ def main(): # Examine if the current state matches planned state (after, planned) = tz.diff('after', 'planned').values() if after != planned: - tz.abort('still not desired state, though changes have made') + tz.abort('still not desired state, though changes have made - ' + 'planned: %s, after: %s' % (str(planned), str(after))) diff = tz.diff('before', 'after') changed = (diff['before'] != diff['after']) diff --git a/test/integration/targets/timezone/aliases b/test/integration/targets/timezone/aliases new file mode 100644 index 0000000000..c34804aced --- /dev/null +++ b/test/integration/targets/timezone/aliases @@ -0,0 +1,4 @@ +destructive +posix/ci/group1 +skip/osx +systemd diff --git a/test/integration/targets/timezone/tasks/main.yml b/test/integration/targets/timezone/tasks/main.yml new file mode 100644 index 0000000000..63b5edf1e7 --- /dev/null +++ b/test/integration/targets/timezone/tasks/main.yml @@ -0,0 +1,15 @@ +- name: set timezone to Etc/UTC + timezone: + name: Etc/UTC + +- name: set timezone to Australia/Brisbane + timezone: + name: Australia/Brisbane + register: timezone_set + +- name: ensure timezone changed + assert: + that: + - timezone_set.changed + - timezone_set.diff.after.name == 'Australia/Brisbane' + - timezone_set.diff.before.name == 'Etc/UTC'