Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

locale_gen: works with C.UTF-8 #6774

Merged
merged 8 commits into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelogs/fragments/6774-locale-gen-fix.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bugfixes:
- locale_gen - now works for locales without the underscore character such as ``C.UTF-8`` (https://github.com/ansible-collections/community.general/pull/6774, https://github.com/ansible-collections/community.general/issues/5142, https://github.com/ansible-collections/community.general/issues/4305).
24 changes: 6 additions & 18 deletions plugins/modules/locale_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
- Whether the locale shall be present.
choices: [ absent, present ]
default: present
notes:
- This module does not support RHEL-based systems.
'''

EXAMPLES = '''
Expand Down Expand Up @@ -74,11 +76,10 @@ def is_available(name, ubuntuMode):
checking either :
* if the locale is present in /etc/locales.gen
* or if the locale is present in /usr/share/i18n/SUPPORTED"""
__regexp = r'^#?\s*(?P<locale>\S+[\._\S]*) (?P<charset>\S+)\s*$'
if ubuntuMode:
__regexp = r'^(?P<locale>\S+_\S+) (?P<charset>\S+)\s*$'
__locales_available = '/usr/share/i18n/SUPPORTED'
else:
__regexp = r'^#{0,1}\s*(?P<locale>\S+_\S+) (?P<charset>\S+)\s*$'
__locales_available = '/etc/locale.gen'

re_compiled = re.compile(__regexp)
Expand All @@ -88,7 +89,8 @@ def is_available(name, ubuntuMode):
if result and result.group('locale') == name:
return True
fd.close()
return False
# locale may be installed but not listed in the file, for example C.UTF-8 in some systems
return is_present(name)


def is_present(name):
Expand All @@ -106,20 +108,6 @@ def fix_case(name):
return name


def replace_line(existing_line, new_line):
"""Replaces lines in /etc/locale.gen"""
try:
f = open("/etc/locale.gen", "r")
lines = [line.replace(existing_line, new_line) for line in f]
finally:
f.close()
try:
f = open("/etc/locale.gen", "w")
f.write("".join(lines))
finally:
f.close()


def set_locale(name, enabled=True):
""" Sets the state of the locale. Defaults to enabled. """
search_string = r'#{0,1}\s*%s (?P<charset>.+)' % name
Expand Down Expand Up @@ -209,7 +197,7 @@ def main():
# We found the common way to manage locales.
ubuntuMode = False
else:
module.fail_json(msg="/etc/locale.gen and /var/lib/locales/supported.d/local are missing. Is the package \"locales\" installed?")
module.fail_json(msg="/etc/locale.gen and /var/lib/locales/supported.d/local are missing. Is the package 'locales' installed?")
else:
# Ubuntu created its own system to manage locales.
ubuntuMode = True
Expand Down
2 changes: 2 additions & 0 deletions tests/integration/targets/locale_gen/aliases
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ azp/posix/3
destructive
needs/root
skip/aix
skip/freebsd
skip/macos
102 changes: 102 additions & 0 deletions tests/integration/targets/locale_gen/tasks/basic.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

- name: Is the locale we're going to test against installed? {{ locale_basic.localegen }}
command: locale -a
register: initial_state
ignore_errors: true

- name: Make sure the locale is not installed {{ locale_basic.localegen }}
locale_gen:
name: "{{ locale_basic.localegen }}"
state: absent

- name: Is the locale present? {{ locale_basic.localegen }}
command: locale -a
register: cleaned
ignore_errors: true

- name: Make sure the locale is not present {{ locale_basic.localegen }}
assert:
that:
- locale_basic.skip_removal or locale_basic.locales | intersect(cleaned.stdout_lines) == []

- name: Install the locale {{ locale_basic.localegen }}
locale_gen:
name: "{{ locale_basic.localegen }}"
state: present
register: output_present

- name: Is the locale present? {{ locale_basic.localegen }}
command: locale -a
register: post_check_output_present
ignore_errors: true

- name: Make sure the locale is present and we say we installed it {{ locale_basic.localegen }}
assert:
that:
- locale_basic.locales | intersect(post_check_output_present.stdout_lines) != []
- locale_basic.skip_removal or output_present is changed

- name: Install the locale a second time {{ locale_basic.localegen }}
locale_gen:
name: "{{ locale_basic.localegen }}"
state: present
register: output_present_idempotent

- name: Is the locale present? {{ locale_basic.localegen }}
command: locale -a
register: post_check_output_present_idempotent
ignore_errors: true

- name: Make sure the locale is present and we reported no change {{ locale_basic.localegen }}
assert:
that:
- locale_basic.locales | intersect(post_check_output_present_idempotent.stdout_lines) != []
- output_present_idempotent is not changed

- name: Removals
when: locale_basic.skip_removal is false
block:
- name: Remove the locale {{ locale_basic.localegen }}
locale_gen:
name: "{{ locale_basic.localegen }}"
state: absent
register: output_absent

- name: Is the locale present? {{ locale_basic.localegen }}
command: locale -a
register: post_check_output_absent
ignore_errors: true

- name: Make sure the locale is absent and we reported a change {{ locale_basic.localegen }}
assert:
that:
- locale_basic.locales | intersect(post_check_output_absent.stdout_lines) == []
- output_absent is changed

- name: Remove the locale a second time {{ locale_basic.localegen }}
locale_gen:
name: "{{ locale_basic.localegen }}"
state: absent
register: output_absent_idempotent

- name: Is the locale present? {{ locale_basic.localegen }}
command: locale -a
register: post_check_output_absent_idempotent
ignore_errors: true

- name: Make sure the locale is absent and we reported no change {{ locale_basic.localegen }}
assert:
that:
- locale_basic.locales | intersect(post_check_output_absent_idempotent.stdout_lines) == []
- output_absent_idempotent is not changed

# Cleanup
- name: Reinstall the locale we tested against if it was initially installed {{ locale_basic.localegen }}
locale_gen:
name: "{{ locale_basic.localegen }}"
state: present
when: locale_basic.locales | intersect(initial_state.stdout_lines) != []
99 changes: 0 additions & 99 deletions tests/integration/targets/locale_gen/tasks/locale_gen.yml

This file was deleted.

10 changes: 8 additions & 2 deletions tests/integration/targets/locale_gen/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,11 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

- include_tasks: 'locale_gen.yml'
when: ansible_distribution in ('Ubuntu', 'Debian')
- name: Bail out if not supported
ansible.builtin.meta: end_play
when: ansible_distribution not in ('Ubuntu', 'Debian')

- include_tasks: basic.yml
loop: "{{ locale_list_basic }}"
loop_control:
loop_var: locale_basic
17 changes: 17 additions & 0 deletions tests/integration/targets/locale_gen/vars/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

# locale_basic: pt_BR

locale_list_basic:
- localegen: pt_BR
locales: [pt_BR]
skip_removal: false
- localegen: C.UTF-8
locales: [C.utf8, C.UTF-8]
skip_removal: true
- localegen: eo
locales: [eo]
skip_removal: false