Now allow every type of locales + archlinux fix
The previous version of this code was supporting only locales using the format "<language>_<territory>.<charset>". But all the locales that doesn't have this format were not installable (such as "fr_FR" or "fr_FR@euro"). Also, if an invalid locales was provided, the module kept sending a "changed" status. Now : * if the user provides an invalid locales, the module failed. Locales are verified using /etc/locale.gen or /usr/share/i18n/SUPPORTED if Ubuntu * Every types of valid locales are now supported. * The locale module was not working on Archlinux, as there's no space between the "#" and the locale. This is now supported. Credits goes to danderson189, this is his code. This module was tested on debian jessie, ubuntu 14 LTS and last Archlinux.
This commit is contained in:
parent
1b10058475
commit
a674cb06e7
1 changed files with 47 additions and 15 deletions
|
@ -41,6 +41,26 @@ LOCALE_NORMALIZATION = {
|
|||
# location module specific support methods.
|
||||
#
|
||||
|
||||
def is_available(name, ubuntuMode):
|
||||
"""Check if the given locale is available on the system. This is done by
|
||||
checking either :
|
||||
* if the locale is present in /etc/locales.gen
|
||||
* or if the locale is present in /usr/share/i18n/SUPPORTED"""
|
||||
if ubuntuMode:
|
||||
__regexp = '^(?P<locale>\S+_\S+) (?P<charset>\S+)\s*$'
|
||||
__locales_available = '/usr/share/i18n/SUPPORTED'
|
||||
else:
|
||||
__regexp = '^#{0,1}\s*(?P<locale>\S+_\S+) (?P<charset>\S+)\s*$'
|
||||
__locales_available = '/etc/locale.gen'
|
||||
|
||||
re_compiled = re.compile(__regexp)
|
||||
with open(__locales_available, 'r') as fd:
|
||||
for line in fd:
|
||||
result = re_compiled.match(line)
|
||||
if result and result.group('locale') == name:
|
||||
return True
|
||||
return False
|
||||
|
||||
def is_present(name):
|
||||
"""Checks if the given locale is currently installed."""
|
||||
output = Popen(["locale", "-a"], stdout=PIPE).communicate()[0]
|
||||
|
@ -60,32 +80,42 @@ def replace_line(existing_line, new_line):
|
|||
with open("/etc/locale.gen", "w") as f:
|
||||
f.write("".join(lines))
|
||||
|
||||
def apply_change(targetState, name, encoding):
|
||||
def set_locale(name, enabled=True):
|
||||
""" Sets the state of the locale. Defaults to enabled. """
|
||||
search_string = '#{0,1}\s*%s (?P<charset>.+)' % name
|
||||
if enabled:
|
||||
new_string = '%s \g<charset>' % (name)
|
||||
else:
|
||||
new_string = '# %s \g<charset>' % (name)
|
||||
with open("/etc/locale.gen", "r") as f:
|
||||
lines = [re.sub(search_string, new_string, line) for line in f]
|
||||
with open("/etc/locale.gen", "w") as f:
|
||||
f.write("".join(lines))
|
||||
|
||||
def apply_change(targetState, name):
|
||||
"""Create or remove locale.
|
||||
|
||||
|
||||
Keyword arguments:
|
||||
targetState -- Desired state, either present or absent.
|
||||
name -- Name including encoding such as de_CH.UTF-8.
|
||||
encoding -- Encoding such as UTF-8.
|
||||
"""
|
||||
if targetState=="present":
|
||||
# Create locale.
|
||||
replace_line("# "+name+" "+encoding, name+" "+encoding)
|
||||
set_locale(name, enabled=True)
|
||||
else:
|
||||
# Delete locale.
|
||||
replace_line(name+" "+encoding, "# "+name+" "+encoding)
|
||||
set_locale(name, enabled=False)
|
||||
|
||||
localeGenExitValue = call("locale-gen")
|
||||
if localeGenExitValue!=0:
|
||||
raise EnvironmentError(localeGenExitValue, "locale.gen failed to execute, it returned "+str(localeGenExitValue))
|
||||
|
||||
def apply_change_ubuntu(targetState, name, encoding):
|
||||
def apply_change_ubuntu(targetState, name):
|
||||
"""Create or remove locale.
|
||||
|
||||
Keyword arguments:
|
||||
targetState -- Desired state, either present or absent.
|
||||
name -- Name including encoding such as de_CH.UTF-8.
|
||||
encoding -- Encoding such as UTF-8.
|
||||
"""
|
||||
if targetState=="present":
|
||||
# Create locale.
|
||||
|
@ -97,7 +127,8 @@ def apply_change_ubuntu(targetState, name, encoding):
|
|||
content = f.readlines()
|
||||
with open("/var/lib/locales/supported.d/local", "w") as f:
|
||||
for line in content:
|
||||
if line!=(name+" "+encoding+"\n"):
|
||||
locale, charset = line.split(' ')
|
||||
if locale != name:
|
||||
f.write(line)
|
||||
# Purge locales and regenerate.
|
||||
# Please provide a patch if you know how to avoid regenerating the locales to keep!
|
||||
|
@ -120,8 +151,6 @@ def main():
|
|||
)
|
||||
|
||||
name = module.params['name']
|
||||
if not "." in name:
|
||||
module.fail_json(msg="Locale does not match pattern. Did you specify the encoding?")
|
||||
state = module.params['state']
|
||||
|
||||
if not os.path.exists("/etc/locale.gen"):
|
||||
|
@ -133,23 +162,26 @@ def main():
|
|||
else:
|
||||
# We found the common way to manage locales.
|
||||
ubuntuMode = False
|
||||
|
||||
|
||||
if not is_available(name, ubuntuMode):
|
||||
module.fail_json(msg="The locales you've entered is not available "
|
||||
"on your system.")
|
||||
|
||||
prev_state = "present" if is_present(name) else "absent"
|
||||
changed = (prev_state!=state)
|
||||
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=changed)
|
||||
else:
|
||||
encoding = name.split(".")[1]
|
||||
if changed:
|
||||
try:
|
||||
if ubuntuMode==False:
|
||||
apply_change(state, name, encoding)
|
||||
apply_change(state, name)
|
||||
else:
|
||||
apply_change_ubuntu(state, name, encoding)
|
||||
apply_change_ubuntu(state, name)
|
||||
except EnvironmentError as e:
|
||||
module.fail_json(msg=e.strerror, exitValue=e.errno)
|
||||
|
||||
|
||||
module.exit_json(name=name, changed=changed, msg="OK")
|
||||
|
||||
# import module snippets
|
||||
|
|
Loading…
Reference in a new issue