summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNimesh-Msys <nimesh.patni@msystechnologies.com>2019-03-26 22:49:39 +0530
committerNimesh-Msys <nimesh.patni@msystechnologies.com>2019-04-04 22:11:16 +0530
commit9b19748867fcb05fab550262449a1bd825db15cf (patch)
treeb192ca1f69f754929a5409c856e8d3e82348d14b /lib
parent3c264946e8dd051e56418751f093eb3afa3c1387 (diff)
downloadchef-9b19748867fcb05fab550262449a1bd825db15cf.tar.gz
locale resource: Add support to set all LC ENV variables
- Deprecated `lc_all` - Provided other features like generate locale if it is not available - Removed system dependancy - Added unit and functional test cases - Added YARD format comments - Ensured Chefstyle - Fixes: MSYS-988 Signed-off-by: Nimesh-Msys <nimesh.patni@msystechnologies.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/chef/deprecated.rb5
-rw-r--r--lib/chef/resource/locale.rb140
2 files changed, 100 insertions, 45 deletions
diff --git a/lib/chef/deprecated.rb b/lib/chef/deprecated.rb
index 1e33fdde0a..6516366d49 100644
--- a/lib/chef/deprecated.rb
+++ b/lib/chef/deprecated.rb
@@ -226,6 +226,10 @@ class Chef
target 26
end
+ class LocaleLcAll < Base
+ target 27
+ end
+
class Generic < Base
def url
"https://docs.chef.io/chef_deprecations_client.html"
@@ -235,6 +239,5 @@ class Chef
"Deprecation from #{location}\n\n #{message}\n\n#{link}"
end
end
-
end
end
diff --git a/lib/chef/resource/locale.rb b/lib/chef/resource/locale.rb
index ca6ea510c0..b16cfe7e3c 100644
--- a/lib/chef/resource/locale.rb
+++ b/lib/chef/resource/locale.rb
@@ -25,67 +25,119 @@ class Chef
description "Use the locale resource to set the system's locale."
introduced "14.5"
+ LC_VARIABLES = %w{LC_ADDRESS LC_COLLATE LC_CTYPE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME}.freeze
+ LOCALE_CONF = "/etc/locale.conf".freeze
+ LOCALE_REGEX = /\A\S+/.freeze
+
property :lang, String,
- default: "en_US.utf8",
- description: "Sets the default system language."
+ description: "Sets the default system language.",
+ regex: [LOCALE_REGEX],
+ validation_message: "The provided lang is not valid. It should be a non-empty string without any leading whitespaces."
+
+ property :lc_env, Hash,
+ description: "A Hash of LC_* env variables in the form of ({ 'LC_ENV_VARIABLE' => 'VALUE' }).",
+ default: lazy { {} },
+ coerce: proc { |h|
+ if h.respond_to?(:keys)
+ invalid_keys = h.keys - LC_VARIABLES
+ unless invalid_keys.empty?
+ error_msg = "Key of option lc_env must be equal to one of: \"#{LC_VARIABLES.join('", "')}\"! You passed \"#{invalid_keys.join(', ')}\"."
+ raise Chef::Exceptions::ValidationFailed, error_msg
+ end
+ end
+ unless h.values.all? { |x| x =~ LOCALE_REGEX }
+ error_msg = "Values of option lc_env should be non-empty string without any leading whitespaces."
+ raise Chef::Exceptions::ValidationFailed, error_msg
+ end
+ h
+ }
- property :lc_all, String,
- default: "en_US.utf8",
- description: "Sets the fallback system language."
+ # @deprecated Use {#lc_env} instead of this property.
+ # {#lc_env} uses Hash with specific LC var as key.
+ # @raise [Chef::Deprecated]
+ #
+ def lc_all(arg = nil)
+ unless arg.nil?
+ Chef.deprecated(:locale_lc_all, "Changing LC_ALL can break Chef's parsing of command output in unexpected ways.\n Use one of the more specific LC_ properties as needed.")
+ end
+ end
action :update do
description "Update the system's locale."
-
- if node["init_package"] == "systemd"
- # on systemd settings LC_ALL is (correctly) reserved only for testing and cannot be set globally
- execute "localectl set-locale LANG=#{new_resource.lang}" do
- # RHEL uses /etc/locale.conf
- not_if { up_to_date?("/etc/locale.conf", new_resource.lang) } if ::File.exist?("/etc/locale.conf")
- # Ubuntu 16.04 still uses /etc/default/locale
- not_if { up_to_date?("/etc/default/locale", new_resource.lang) } if ::File.exist?("/etc/default/locale")
+ begin
+ unless up_to_date?
+ converge_by "Updating System Locale" do
+ generate_locales unless unavailable_locales.empty?
+ update_locale
+ end
end
- elsif ::File.exist?("/etc/sysconfig/i18n")
- locale_file_path = "/etc/sysconfig/i18n"
+ rescue
+ # It might affect debugging
+ raise "#{node['platform']} platform is not supported by the chef locale resource. " +
+ "If you believe this is in error please file an issue at https://github.com/chef/chef/issues"
+ end
+ end
- updated = up_to_date?(locale_file_path, new_resource.lang, new_resource.lc_all)
+ action_class do
- file locale_file_path do
- content lazy {
- locale = IO.read(locale_file_path)
- variables = Hash[locale.lines.map { |line| line.strip.split("=") }]
- variables["LANG"] = new_resource.lang
- variables["LC_ALL"] =
- variables.map { |pairs| pairs.join("=") }.join("\n") + "\n"
- }
- not_if { updated }
+ # Generates the localisation files from templates using locale-gen.
+ # @see http://manpages.ubuntu.com/manpages/cosmic/man8/locale-gen.8.html
+ # @raise [Mixlib::ShellOut::ShellCommandFailed] not a supported language or locale
+ #
+ def generate_locales
+ bash "Generating locales: #{unavailable_locales.join(' ')}" do
+ code <<~CODE
+ if type locale-gen >/dev/null 2>&1
+ then
+ locale-gen #{unavailable_locales.join(' ')}
+ fi
+ CODE
end
+ end
- execute "reload root's lang profile script" do
- command "source /etc/sysconfig/i18n; source /etc/profile.d/lang.sh"
- not_if { updated }
+ # Updates system locale by appropriately writing them in /etc/locale.conf
+ # @note This locale change won't affect the current run. At this time it is an exercise
+ # left to the user to restart or reboot if the locale change is required at
+ # later part of the client run.
+ # @see https://wiki.archlinux.org/index.php/locale#Setting_the_system_locale
+ #
+ def update_locale
+ file "Updating system locale" do
+ path LOCALE_CONF
+ content new_content
end
- elsif ::File.exist?("/usr/sbin/update-locale")
- execute "Generate locales" do
- command "locale-gen"
- not_if { up_to_date?("/etc/default/locale", new_resource.lang, new_resource.lc_all) }
+ end
+
+ # @return [Array<String>] Locales that user wants to set but are not available on
+ # the system. They are required to be generated.
+ #
+ def unavailable_locales
+ @unavailable_locales ||= begin
+ available = shell_out!("locale -a").stdout.split("\n")
+ required = [new_resource.lang, new_resource.lc_env.values].flatten.compact.uniq
+ required - available
end
+ end
- execute "Update locale" do
- command "update-locale LANG=#{new_resource.lang} LC_ALL=#{new_resource.lc_all}"
- not_if { up_to_date?("/etc/default/locale", new_resource.lang, new_resource.lc_all) }
+ # @return [String] Contents that are required to be
+ # updated in /etc/locale.conf
+ #
+ def new_content
+ @new_content ||= begin
+ content = {}
+ content = new_resource.lc_env.dup if new_resource.lc_env
+ content["LANG"] = new_resource.lang if new_resource.lang
+ content.sort.map { |t| t.join("=") }.join("\n") + "\n"
end
- else
- raise "#{node["platform"]} platform not supported by the chef locale resource."
end
- end
- action_class do
- def up_to_date?(file_path, lang, lc_all = nil)
- locale = IO.read(file_path)
- locale.include?("LANG=#{lang}") &&
- (node["init_package"] == "systemd" || lc_all.nil? || locale.include?("LC_ALL=#{lc_all}"))
+ # @return [Boolean] Whether any modification is required in /etc/locale.conf
+ #
+ def up_to_date?
+ old_content = ::File.read(LOCALE_CONF)
+ new_content == old_content
rescue
- false
+ false # We need to create the file if it is not present
end
end
end