diff options
author | Tim Smith <tsmith84@gmail.com> | 2020-08-18 11:19:33 -0700 |
---|---|---|
committer | Tim Smith <tsmith84@gmail.com> | 2020-08-18 12:22:55 -0700 |
commit | 5e1ce8ccb4805bcad69e2d9c7a5fed3f6ef15671 (patch) | |
tree | 29719963f7de8a957b6eebb346565a4ee402841f | |
parent | fc953cefe6119d659973b9c635543bc06f3f1285 (diff) | |
download | chef-5e1ce8ccb4805bcad69e2d9c7a5fed3f6ef15671.tar.gz |
Refactor the timezone resource to properly load the current timezone
This way we get a proper state change instead of just showing a converge. This also removes awk/grep in not_if statements and overall improves logging.
Signed-off-by: Tim Smith <tsmith@chef.io>
-rw-r--r-- | kitchen-tests/cookbooks/end_to_end/recipes/linux.rb | 2 | ||||
-rw-r--r-- | kitchen-tests/cookbooks/end_to_end/recipes/macos.rb | 2 | ||||
-rw-r--r-- | lib/chef/resource/timezone.rb | 163 |
3 files changed, 94 insertions, 73 deletions
diff --git a/kitchen-tests/cookbooks/end_to_end/recipes/linux.rb b/kitchen-tests/cookbooks/end_to_end/recipes/linux.rb index 051a7c9b52..012a9a7507 100644 --- a/kitchen-tests/cookbooks/end_to_end/recipes/linux.rb +++ b/kitchen-tests/cookbooks/end_to_end/recipes/linux.rb @@ -23,7 +23,7 @@ execute "sensitive sleep" do sensitive true end -timezone "UTC" +timezone "America/Los_Angeles" include_recipe "::_yum" if platform_family?("rhel") diff --git a/kitchen-tests/cookbooks/end_to_end/recipes/macos.rb b/kitchen-tests/cookbooks/end_to_end/recipes/macos.rb index 1fbc1f0aca..6ac2607caa 100644 --- a/kitchen-tests/cookbooks/end_to_end/recipes/macos.rb +++ b/kitchen-tests/cookbooks/end_to_end/recipes/macos.rb @@ -19,7 +19,7 @@ execute "sensitive sleep" do sensitive true end -timezone "GMT" +timezone "America/Los_Angeles" include_recipe "ntp" diff --git a/lib/chef/resource/timezone.rb b/lib/chef/resource/timezone.rb index fe03940e1d..9c9396c250 100644 --- a/lib/chef/resource/timezone.rb +++ b/lib/chef/resource/timezone.rb @@ -26,7 +26,7 @@ class Chef provides :timezone - description "Use the **timezone** resource to change the system timezone on Windows, Linux, and macOS hosts. Timezones are specified in tz database format, with a complete list of available TZ values for Linux and macOS here: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones and for Windows here: https://ss64.com/nt/timezones.html." + description "Use the **timezone** resource to change the system timezone on Windows, Linux, and macOS hosts. Timezones are specified in tz database format, with a complete list of available TZ values for Linux and macOS here: <https://en.wikipedia.org/wiki/List_of_tz_database_time_zones> and for Windows here: <https://ss64.com/nt/timezones.html>." introduced "14.6" examples <<~DOC **Set the timezone to UTC** @@ -35,11 +35,11 @@ class Chef timezone 'UTC' ``` - **Set the timezone to UTC with a friendly resource name** + **Set the timezone to UTC with a friendly resource name on Linux/macOS** ```ruby - timezone 'Set the host's timezone to UTC' do - timezone 'UTC' + timezone 'Set the host's timezone to America/Los_Angeles' do + timezone 'America/Los_Angeles' end ``` DOC @@ -48,90 +48,111 @@ class Chef description: "An optional property to set the timezone value if it differs from the resource block's name.", name_property: true - action :set do - description "Set the timezone." - - # some linux systems may be missing the timezone data - if linux? - package "tzdata" do - package_name suse? ? "timezone" : "tzdata" - end + # detect the current TZ on darwin hosts + # + # @since 14.7 + # @return [String] TZ database value + def current_darwin_tz + tz_shellout = shell_out!("systemsetup -gettimezone") + if /You need administrator access/.match?(tz_shellout.stdout) + raise "The timezone resource requires administrative privileges to run on macOS hosts!" + else + /Time Zone: (.*)/.match(tz_shellout.stdout)[1] end + end - # Modern SUSE, Amazon, Fedora, RHEL, Ubuntu & Debian - if systemd? - cmd_set_tz = "/usr/bin/timedatectl --no-ask-password set-timezone #{new_resource.timezone}" + # detect the current timezone on windows hosts + # + # @since 14.7 + # @return [String] timezone id + def current_windows_tz + tz_shellout = shell_out("tzutil /g") + raise "There was an error running the tzutil command" if tz_shellout.exitstatus == 1 - cmd_check_if_set = "/usr/bin/timedatectl status" - cmd_check_if_set += " | /usr/bin/awk '/Time.*zone/{print}'" - cmd_check_if_set += " | grep -q #{new_resource.timezone}" + tz_shellout.stdout.strip + end - execute cmd_set_tz do - action :run - not_if cmd_check_if_set - end + # detect the current timezone on systemd hosts + # + # @since 16.5 + # @return [String] timezone id + def current_systemd_tz + tz_shellout = shell_out!("/usr/bin/timedatectl status") + raise "There was an error running the timedatectl command" if tz_shellout.exitstatus == 1 + + # https://rubular.com/r/eV68MX9XXbyG4k + /Time zone: (.*) \(.*/.match(tz_shellout.stdout)[1] + end + + # detect the current timezone on non-systemd RHEL-ish hosts + # + # @since 16.5 + # @return [String] timezone id + def current_rhel_tz + return nil unless ::File.exist?("/etc/sysconfig/clock") + + # https://rubular.com/r/aoj01L3bKBM7wh + /ZONE="(.*)"/.match(::File.read("/etc/sysconfig/clock"))[1] + end + + load_current_value do + if systemd? + timezone current_systemd_tz else case node["platform_family"] # Old version of RHEL < 7 and Amazon 201X when "rhel", "amazon" - file "/etc/sysconfig/clock" do - owner "root" - group "root" - mode "0644" - action :create - content %{ZONE="#{new_resource.timezone}"\nUTC="true"\n} - end - - execute "tzdata-update" do - command "/usr/sbin/tzdata-update" - action :nothing - only_if { ::File.executable?("/usr/sbin/tzdata-update") } - subscribes :run, "file[/etc/sysconfig/clock]", :immediately - end - - link "/etc/localtime" do - to "/usr/share/zoneinfo/#{new_resource.timezone}" - not_if { ::File.executable?("/usr/sbin/tzdata-update") } - end + timezone current_rhel_tz when "mac_os_x" - unless current_darwin_tz == new_resource.timezone - converge_by("set timezone to #{new_resource.timezone}") do - shell_out!("sudo systemsetup -settimezone #{new_resource.timezone}") - end - end + timezone current_darwin_tz when "windows" - unless current_windows_tz.casecmp?(new_resource.timezone) - converge_by("setting timezone to \"#{new_resource.timezone}\"") do - shell_out!("tzutil /s \"#{new_resource.timezone}\"") - end - end + timezone current_windows_tz end end end - action_class do - # detect the current TZ on darwin hosts - # - # @since 14.7 - # @return [String] TZ database value - def current_darwin_tz - tz_shellout = shell_out!("systemsetup -gettimezone") - if /You need administrator access/.match?(tz_shellout.stdout) - raise "The timezone resource requires administrative privileges to run on macOS hosts!" + action :set do + description "Set the timezone." + + converge_if_changed(:timezone) do + # Modern SUSE, Amazon, Fedora, RHEL, Ubuntu & Debian + if systemd? + # make sure we have the tzdata files + package suse? ? "timezone" : "tzdata" + + shell_out!("/usr/bin/timedatectl --no-ask-password set-timezone #{new_resource.timezone}") else - /Time Zone: (.*)/.match(tz_shellout.stdout)[1] - end - end + case node["platform_family"] + # Old version of RHEL < 7 and Amazon 201X + when "rhel", "amazon" + # make sure we have the tzdata files + package "tzdata" + + file "/etc/sysconfig/clock" do + owner "root" + group "root" + mode "0644" + action :create + content %{ZONE="#{new_resource.timezone}"\nUTC="true"\n} + end - # detect the current timezone on windows hosts - # - # @since 14.7 - # @return [String] timezone id - def current_windows_tz - tz_shellout = shell_out("tzutil /g") - raise "There was an error running the tzutil command" if tz_shellout.exitstatus == 1 + execute "tzdata-update" do + command "/usr/sbin/tzdata-update" + action :nothing + only_if { ::File.executable?("/usr/sbin/tzdata-update") } + subscribes :run, "file[/etc/sysconfig/clock]", :immediately + end - tz_shellout.stdout.strip + link "/etc/localtime" do + to "/usr/share/zoneinfo/#{new_resource.timezone}" + not_if { ::File.executable?("/usr/sbin/tzdata-update") } + end + when "mac_os_x" + shell_out!("sudo systemsetup -settimezone #{new_resource.timezone}") + when "windows" + shell_out!("tzutil /s \"#{new_resource.timezone}\"") + end + end end end end |