From f75d4772090d3a9cfd798dd193cd324083a9b3a7 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 8 Nov 2020 13:45:12 +0100 Subject: [PATCH 1/9] Deprecate __locale and replace with __localedef --- cdist/conf/type/__locale/deprecated | 1 + cdist/conf/type/__localedef/gencode-remote | 60 +++++++++++++++++++ cdist/conf/type/__localedef/man.rst | 55 +++++++++++++++++ cdist/conf/type/__localedef/manifest | 41 +++++++++++++ .../type/__localedef/parameter/default/state | 1 + .../conf/type/__localedef/parameter/optional | 1 + 6 files changed, 159 insertions(+) create mode 100644 cdist/conf/type/__locale/deprecated create mode 100755 cdist/conf/type/__localedef/gencode-remote create mode 100644 cdist/conf/type/__localedef/man.rst create mode 100755 cdist/conf/type/__localedef/manifest create mode 100644 cdist/conf/type/__localedef/parameter/default/state create mode 100644 cdist/conf/type/__localedef/parameter/optional diff --git a/cdist/conf/type/__locale/deprecated b/cdist/conf/type/__locale/deprecated new file mode 100644 index 00000000..5a06b28e --- /dev/null +++ b/cdist/conf/type/__locale/deprecated @@ -0,0 +1 @@ +This type is deprecated. Please use __localedef instead. diff --git a/cdist/conf/type/__localedef/gencode-remote b/cdist/conf/type/__localedef/gencode-remote new file mode 100755 index 00000000..1feb9884 --- /dev/null +++ b/cdist/conf/type/__localedef/gencode-remote @@ -0,0 +1,60 @@ +#!/bin/sh -e +# +# 2013-2019 Nico Schottelius (nico-cdist at schottelius.org) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# +# +# Let localedef do the magic +# + +locale="$__object_id" + +# Hardcoded, create a pull request with +# branching on $os in case it is at another location +alias=/usr/share/locale/locale.alias + +input=$(echo "$locale" | cut -d . -f 1) +charmap=$(echo "$locale" | cut -d . -f 2) + +# Adding locale? The name is de_CH.UTF-8 +# Removing locale? The name is de_CH.utf8. +# W-T-F! +locale_remove=$(echo "$locale" | sed 's/UTF-8/utf8/') + +state=$(cat "$__object/parameter/state") + +os=$(cat "$__global/explorer/os") + +# Nothing to be done on alpine +case "$os" in + alpine) + exit 0 + ;; +esac + +case "$state" in + present) + echo localedef -A "$alias" -f "$charmap" -i "$input" "$locale" + ;; + absent) + echo localedef --delete-from-archive "$locale_remove" + ;; + *) + echo "Unsupported state: $state" >&2 + exit 1 + ;; +esac diff --git a/cdist/conf/type/__localedef/man.rst b/cdist/conf/type/__localedef/man.rst new file mode 100644 index 00000000..0ccf484a --- /dev/null +++ b/cdist/conf/type/__localedef/man.rst @@ -0,0 +1,55 @@ +cdist-type__localedef(7) +======================== + +NAME +---- +cdist-type__localedef - Define and remove system locales + + +DESCRIPTION +----------- +This cdist type allows you to define locales on the system using +:strong:`localedef`\ (1) or remove them. +On systems that don't support definition of new locales, the type will raise an +error. + + +OPTIONAL PARAMETERS +------------------- +state + ``present`` or ``absent``. Defaults to ``present``. + + +EXAMPLES +-------- + +.. code-block:: sh + + # Add locale de_CH.UTF-8 + __localedef de_CH.UTF-8 + + # Same as above, but more explicit + __localedef de_CH.UTF-8 --state present + + # Remove colourful British English + __localedef en_GB.UTF-8 --state absent + + +SEE ALSO +-------- +:strong:`locale`\ (1), +:strong:`localedef`\ (1), +:strong:`cdist-type__locale_system`\ (7) + + +AUTHORS +------- +| Dennis Camera +| Nico Schottelius + + +COPYING +------- +Copyright \(C) 2013-2019 Nico Schottelius, 2020 Dennis Camera. Free use of this +software is granted under the terms of the GNU General Public License version 3 +or later (GPLv3+). diff --git a/cdist/conf/type/__localedef/manifest b/cdist/conf/type/__localedef/manifest new file mode 100755 index 00000000..9f1e17ac --- /dev/null +++ b/cdist/conf/type/__localedef/manifest @@ -0,0 +1,41 @@ +#!/bin/sh -e +# +# 2013-2019 Nico Schottelius (nico-cdist at schottelius.org) +# 2015 David Hürlimann (david at ungleich.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# +# +# Install required packages +# + +os=$(cat "$__global/explorer/os") + + +case "$os" in + debian|devuan) + # Debian needs a seperate package + __package locales --state present + ;; + archlinux|suse|ubuntu|scientific|centos|alpine) + : + ;; + *) + echo "Sorry, do not know how to handle os: $os" >&2 + echo "Please edit the type ${__type##*/} to fix this." >&2 + exit 1 + ;; +esac diff --git a/cdist/conf/type/__localedef/parameter/default/state b/cdist/conf/type/__localedef/parameter/default/state new file mode 100644 index 00000000..e7f6134f --- /dev/null +++ b/cdist/conf/type/__localedef/parameter/default/state @@ -0,0 +1 @@ +present diff --git a/cdist/conf/type/__localedef/parameter/optional b/cdist/conf/type/__localedef/parameter/optional new file mode 100644 index 00000000..ff72b5c7 --- /dev/null +++ b/cdist/conf/type/__localedef/parameter/optional @@ -0,0 +1 @@ +state From 54e689f7c2b3bc25aedb2aaf9f5aece289ec5b66 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 8 Nov 2020 13:49:04 +0100 Subject: [PATCH 2/9] [type/__localedef] Add state explorer --- cdist/conf/type/__localedef/explorer/state | 71 ++++++++++++++++++++++ cdist/conf/type/__localedef/gencode-remote | 13 +++- 2 files changed, 82 insertions(+), 2 deletions(-) create mode 100755 cdist/conf/type/__localedef/explorer/state diff --git a/cdist/conf/type/__localedef/explorer/state b/cdist/conf/type/__localedef/explorer/state new file mode 100755 index 00000000..d8db29c5 --- /dev/null +++ b/cdist/conf/type/__localedef/explorer/state @@ -0,0 +1,71 @@ +#!/bin/sh -e +# +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# +# This explorer determines if the locale is defined on the target system. +# Will print nothing on error. +# +# Possible output: +# present: +# the main locale (and possibly aliases) is present +# absent: +# neither the main locale nor any aliases are present +# + +command -v locale >/dev/null 2>&1 || exit 0 + +locales=$(locale -a) + +parse_locale() { + # This function will split locales into their parts. Locale strings are + # usually of the form: [language[_territory][.codeset][@modifier]] + # For simplicity, language and territory are not separated by this function. + # Old Linux systems were also using "english" or "german" as locale strings. + # Usage: parse_locale locale_str lang_var codeset_var modifier_var + eval "${2:?}"="$(expr "$1" : '\([^.@]*\)')" + eval "${3:?}"="$(expr "$1" : '[^.]*\.\([^@]*\)')" + eval "${4:?}"="$(expr "$1" : '.*@\(.*\)$')" +} + +format_locale() { + # Usage: format_locale language codeset modifier + printf '%s' "$1" + test -z "$2" || printf '.%s' "$2" + test -z "$3" || printf '@%s' "$3" + printf '\n' +} + +gnu_normalize_codeset() { + # reimplementation of glibc/locale/programs/localedef.c normalize_codeset() + echo "$*" | tr '[:upper:]' '[:lower:]' | tr -cd '[:alnum:]' +} + +locale_available() ( + echo "${locales}" | grep -qxF "$1" || { + # glibc uses "normalized" locale names in archives. + # If a locale is stored in an archive, the normalized name will be + # printed by locale, so that needs to be checked, too. + localename=$( + parse_locale "$1" _lang _codeset _modifier \ + && format_locale "${_lang:?}" "$(gnu_normalize_codeset "${_codeset?}")" \ + "${_modifier?}") + echo "${locales}" | grep -qxF "${localename}" + } +) + +locale_available "${__object_id:?}" && echo present || echo absent diff --git a/cdist/conf/type/__localedef/gencode-remote b/cdist/conf/type/__localedef/gencode-remote index 1feb9884..9ea3f6f1 100755 --- a/cdist/conf/type/__localedef/gencode-remote +++ b/cdist/conf/type/__localedef/gencode-remote @@ -35,7 +35,8 @@ charmap=$(echo "$locale" | cut -d . -f 2) # W-T-F! locale_remove=$(echo "$locale" | sed 's/UTF-8/utf8/') -state=$(cat "$__object/parameter/state") +state_is=$(cat "${__object:?}/explorer/state") +state_should=$(cat "${__object:?}/parameter/state") os=$(cat "$__global/explorer/os") @@ -46,7 +47,15 @@ case "$os" in ;; esac -case "$state" in +# NOTE: If state explorer fails (e.g. locale(1) missing), the following check +# will always fail and let definition/removal run. +if test "${state_is}" = "${state_should}" +then + exit 0 +fi + +case ${state_should} +in present) echo localedef -A "$alias" -f "$charmap" -i "$input" "$locale" ;; From cc29e54b851212568c3f6eddf4bf0a64c1eabb0d Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Thu, 23 Jul 2020 23:20:39 +0200 Subject: [PATCH 3/9] [type/__localedef] Differentiate between OSes and better handling of normalized locale names --- cdist/conf/type/__localedef/gencode-remote | 117 +++++++++++++++------ 1 file changed, 82 insertions(+), 35 deletions(-) diff --git a/cdist/conf/type/__localedef/gencode-remote b/cdist/conf/type/__localedef/gencode-remote index 9ea3f6f1..b9cc68e8 100755 --- a/cdist/conf/type/__localedef/gencode-remote +++ b/cdist/conf/type/__localedef/gencode-remote @@ -1,6 +1,7 @@ #!/bin/sh -e # # 2013-2019 Nico Schottelius (nico-cdist at schottelius.org) +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # @@ -17,35 +18,16 @@ # You should have received a copy of the GNU General Public License # along with cdist. If not, see . # +# Manage system locales using localedef(1). # -# Let localedef do the magic -# - -locale="$__object_id" - -# Hardcoded, create a pull request with -# branching on $os in case it is at another location -alias=/usr/share/locale/locale.alias - -input=$(echo "$locale" | cut -d . -f 1) -charmap=$(echo "$locale" | cut -d . -f 2) - -# Adding locale? The name is de_CH.UTF-8 -# Removing locale? The name is de_CH.utf8. -# W-T-F! -locale_remove=$(echo "$locale" | sed 's/UTF-8/utf8/') state_is=$(cat "${__object:?}/explorer/state") state_should=$(cat "${__object:?}/parameter/state") -os=$(cat "$__global/explorer/os") - -# Nothing to be done on alpine -case "$os" in - alpine) - exit 0 - ;; -esac +test "${state_should}" = 'present' -o "${state_should}" = 'absent' || { + printf 'Invalid state: %s\n' "${state_should}" >&2 + exit 1 +} # NOTE: If state explorer fails (e.g. locale(1) missing), the following check # will always fail and let definition/removal run. @@ -54,16 +36,81 @@ then exit 0 fi -case ${state_should} +locale=${__object_id:?} +os=$(cat "${__global:?}/explorer/os") + +if expr "${locale}" : '.*/' >/dev/null +then + printf 'Paths as locales are not supported.\n' >&2 + printf '__object_id is: %s\n' "${locale}" >&2 + exit 1 +fi + +parse_locale() { + # This function will split locales into their parts. Locale strings are + # usually of the form: [language[_territory][.codeset][@modifier]] + # For simplicity, language and territory are not separated by this function. + # Old Linux systems were also using "english" or "german" as locale strings. + # Usage: parse_locale locale_str lang_var codeset_var modifier_var + eval "${2:?}"="$(expr "$1" : '\([^.@]*\)')" + eval "${3:?}"="$(expr "$1" : '[^.]*\.\([^@]*\)')" + eval "${4:?}"="$(expr "$1" : '.*@\(.*\)$')" +} + +format_locale() { + # Usage: format_locale language codeset modifier + printf '%s' "$1" + test -z "$2" || printf '.%s' "$2" + test -z "$3" || printf '@%s' "$3" + printf '\n' +} + +gnu_normalize_codeset() { + echo "$*" | tr -cd '[:alnum:]' | tr '[:upper:]' '[:lower:]' +} + + +: "${lang=}" "${codeset=}" "${modifier=}" # declare variables for shellcheck +parse_locale "${locale}" lang codeset modifier + + +case ${os} in - present) - echo localedef -A "$alias" -f "$charmap" -i "$input" "$locale" - ;; - absent) - echo localedef --delete-from-archive "$locale_remove" - ;; - *) - echo "Unsupported state: $state" >&2 - exit 1 - ;; + (alpine|openwrt) + printf '%s does not support locales.\n' "${os}" >&2 + exit 1 + ;; + (archlinux|debian|devuan|ubuntu|suse|centos|fedora|redhat|scientific) + # FIXME: The code below only works for glibc-based installations. + + # NOTE: Hardcoded, create a pull request in case it is at another + # location for some opther distro. + # NOTE: locale.alias can be symlinked (e.g. Debian) + aliasfile='/usr/share/locale/locale.alias' + + case ${state_should} + in + (present) + input=$(format_locale "${lang}" '' "${modifier}") + cat <<-EOF + set -- + if test -e '${aliasfile}' + then + set -- -A '${aliasfile}' + fi + + localedef -i '${input}' -f '${codeset}' "\$@" '${locale}' + EOF + ;; + (absent) + localename=$(format_locale "${lang}" "$(gnu_normalize_codeset "${codeset}")" "${modifier}") + printf "localedef --delete-from-archive '%s'\n" "${localename}" + ;; + esac + ;; + (*) + echo "Your operating system (${os}) is currently not supported by this type (${__type##*/})." >&2 + echo "Please contribute an implementation for it if you can." >&2 + exit 1 + ;; esac From f44888f192d78d8ce1e3583f70f94b0c2039c1e2 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 8 Nov 2020 14:02:08 +0100 Subject: [PATCH 4/9] [type/__localedef] Only install dependencies in manifest. OS checking moved to gencode-remote --- cdist/conf/type/__localedef/manifest | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/cdist/conf/type/__localedef/manifest b/cdist/conf/type/__localedef/manifest index 9f1e17ac..3ab3ad8c 100755 --- a/cdist/conf/type/__localedef/manifest +++ b/cdist/conf/type/__localedef/manifest @@ -2,6 +2,7 @@ # # 2013-2019 Nico Schottelius (nico-cdist at schottelius.org) # 2015 David Hürlimann (david at ungleich.ch) +# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # @@ -18,24 +19,12 @@ # You should have received a copy of the GNU General Public License # along with cdist. If not, see . # -# -# Install required packages +# Install required packages. # -os=$(cat "$__global/explorer/os") - - -case "$os" in - debian|devuan) - # Debian needs a seperate package - __package locales --state present - ;; - archlinux|suse|ubuntu|scientific|centos|alpine) - : - ;; - *) - echo "Sorry, do not know how to handle os: $os" >&2 - echo "Please edit the type ${__type##*/} to fix this." >&2 - exit 1 - ;; +case $(cat "${__global:?}/explorer/os") +in + (debian|devuan) + __package_apt locales --state present + ;; esac From dcef2c19f5b87e3a9594f01fefab66cc7488dce7 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 8 Nov 2020 14:07:42 +0100 Subject: [PATCH 5/9] [type/__localedef] Add support for FreeBSD --- cdist/conf/type/__localedef/gencode-remote | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/cdist/conf/type/__localedef/gencode-remote b/cdist/conf/type/__localedef/gencode-remote index b9cc68e8..80e7eb1c 100755 --- a/cdist/conf/type/__localedef/gencode-remote +++ b/cdist/conf/type/__localedef/gencode-remote @@ -108,6 +108,25 @@ in ;; esac ;; + (freebsd) + case ${state_should} + in + (present) + if expr "$(grep -oe '^[0-9]*' "${__global:?}/explorer/os_version")" '>=' 11 >/dev/null + then + # localedef(1) is available with FreeBSD >= 11 + printf "localedef -i '%s' -f '%s' '%s'\n" "${input}" "${codeset}" "${locale}" + else + printf 'localedef(1) was added to FreeBSD starting with version 11.\n' >&2 + printf 'Please upgrade your FreeBSD installation to use %s.\n' "${__type##*/}" >&2 + exit 1 + fi + ;; + (absent) + printf "rm -R '/usr/share/locale/%s'\n" "${locale}" + ;; + esac + ;; (*) echo "Your operating system (${os}) is currently not supported by this type (${__type##*/})." >&2 echo "Please contribute an implementation for it if you can." >&2 From c1c60e3374e0cb93ea182c4cbcb813150756c3e4 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sun, 8 Nov 2020 15:24:46 +0100 Subject: [PATCH 6/9] [type/__localedef] Blacklist OpenBSD and NetBSD --- cdist/conf/type/__localedef/gencode-remote | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cdist/conf/type/__localedef/gencode-remote b/cdist/conf/type/__localedef/gencode-remote index 80e7eb1c..af1a77f7 100755 --- a/cdist/conf/type/__localedef/gencode-remote +++ b/cdist/conf/type/__localedef/gencode-remote @@ -127,6 +127,12 @@ in ;; esac ;; + (netbsd|openbsd) + # NetBSD/OpenBSD are missing localedef(1). + # We also do not delete defined locales because they can't be recreated. + echo "${os} is lacking localedef(1). Locale management unavailable." >&2 + exit 1 + ;; (*) echo "Your operating system (${os}) is currently not supported by this type (${__type##*/})." >&2 echo "Please contribute an implementation for it if you can." >&2 From 575bb62dc507fb8c294319f8db20ba45595e6869 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Fri, 13 Nov 2020 18:42:04 +0100 Subject: [PATCH 7/9] [type/__localedef] Externalise functions to separate files --- .../conf/type/__localedef/files/lib/glibc.sh | 5 ++++ .../conf/type/__localedef/files/lib/locale.sh | 20 +++++++++++++ cdist/conf/type/__localedef/gencode-remote | 29 ++++--------------- 3 files changed, 30 insertions(+), 24 deletions(-) create mode 100644 cdist/conf/type/__localedef/files/lib/glibc.sh create mode 100644 cdist/conf/type/__localedef/files/lib/locale.sh diff --git a/cdist/conf/type/__localedef/files/lib/glibc.sh b/cdist/conf/type/__localedef/files/lib/glibc.sh new file mode 100644 index 00000000..6ace80d4 --- /dev/null +++ b/cdist/conf/type/__localedef/files/lib/glibc.sh @@ -0,0 +1,5 @@ +# -*- mode: sh; indent-tabs-mode: t -*- + +gnu_normalize_codeset() { + echo "$*" | tr -cd '[:alnum:]' | tr '[:upper:]' '[:lower:]' +} diff --git a/cdist/conf/type/__localedef/files/lib/locale.sh b/cdist/conf/type/__localedef/files/lib/locale.sh new file mode 100644 index 00000000..b5e61374 --- /dev/null +++ b/cdist/conf/type/__localedef/files/lib/locale.sh @@ -0,0 +1,20 @@ +# -*- mode: sh; indent-tabs-mode:t -*- + +parse_locale() { + # This function will split locales into their parts. Locale strings are + # usually of the form: [language[_territory][.codeset][@modifier]] + # For simplicity, language and territory are not separated by this function. + # Old Linux systems were also using "english" or "german" as locale strings. + # Usage: parse_locale locale_str lang_var codeset_var modifier_var + eval "${2:?}"="$(expr "$1" : '\([^.@]*\)')" + eval "${3:?}"="$(expr "$1" : '[^.]*\.\([^@]*\)')" + eval "${4:?}"="$(expr "$1" : '.*@\(.*\)$')" +} + +format_locale() { + # Usage: format_locale language codeset modifier + printf '%s' "$1" + test -z "$2" || printf '.%s' "$2" + test -z "$3" || printf '@%s' "$3" + printf '\n' +} diff --git a/cdist/conf/type/__localedef/gencode-remote b/cdist/conf/type/__localedef/gencode-remote index af1a77f7..17941c63 100755 --- a/cdist/conf/type/__localedef/gencode-remote +++ b/cdist/conf/type/__localedef/gencode-remote @@ -21,6 +21,11 @@ # Manage system locales using localedef(1). # +# shellcheck source=cdist/conf/type/__localedef/files/lib/locale.sh +. "${__type:?}/files/lib/locale.sh" +# shellcheck source=cdist/conf/type/__localedef/files/lib/glibc.sh +. "${__type:?}/files/lib/glibc.sh" + state_is=$(cat "${__object:?}/explorer/state") state_should=$(cat "${__object:?}/parameter/state") @@ -46,30 +51,6 @@ then exit 1 fi -parse_locale() { - # This function will split locales into their parts. Locale strings are - # usually of the form: [language[_territory][.codeset][@modifier]] - # For simplicity, language and territory are not separated by this function. - # Old Linux systems were also using "english" or "german" as locale strings. - # Usage: parse_locale locale_str lang_var codeset_var modifier_var - eval "${2:?}"="$(expr "$1" : '\([^.@]*\)')" - eval "${3:?}"="$(expr "$1" : '[^.]*\.\([^@]*\)')" - eval "${4:?}"="$(expr "$1" : '.*@\(.*\)$')" -} - -format_locale() { - # Usage: format_locale language codeset modifier - printf '%s' "$1" - test -z "$2" || printf '.%s' "$2" - test -z "$3" || printf '@%s' "$3" - printf '\n' -} - -gnu_normalize_codeset() { - echo "$*" | tr -cd '[:alnum:]' | tr '[:upper:]' '[:lower:]' -} - - : "${lang=}" "${codeset=}" "${modifier=}" # declare variables for shellcheck parse_locale "${locale}" lang codeset modifier From eeb98719197a09691af60fa26c0b64b3aaf8960e Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sat, 14 Nov 2020 09:54:01 +0100 Subject: [PATCH 8/9] [type/__localedef] glibc: Also delete aliases when removing a locale --- cdist/conf/type/__localedef/gencode-remote | 15 +++++++++++++-- cdist/conf/type/__localedef/man.rst | 5 +++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/cdist/conf/type/__localedef/gencode-remote b/cdist/conf/type/__localedef/gencode-remote index 17941c63..d7fd6942 100755 --- a/cdist/conf/type/__localedef/gencode-remote +++ b/cdist/conf/type/__localedef/gencode-remote @@ -84,8 +84,19 @@ in EOF ;; (absent) - localename=$(format_locale "${lang}" "$(gnu_normalize_codeset "${codeset}")" "${modifier}") - printf "localedef --delete-from-archive '%s'\n" "${localename}" + main_localename=$(format_locale "${lang}" "$(gnu_normalize_codeset "${codeset}")" "${modifier}") + + cat <<-EOF + while read -r _alias _localename + do + if test "\${_localename}" = '$(format_locale "${lang}" "${codeset}")' + then + localedef --delete-from-archive "\${_alias}" + fi + done <'${aliasfile}' + + localedef --delete-from-archive '${main_localename}' + EOF ;; esac ;; diff --git a/cdist/conf/type/__localedef/man.rst b/cdist/conf/type/__localedef/man.rst index 0ccf484a..454ce9d1 100644 --- a/cdist/conf/type/__localedef/man.rst +++ b/cdist/conf/type/__localedef/man.rst @@ -13,6 +13,11 @@ This cdist type allows you to define locales on the system using On systems that don't support definition of new locales, the type will raise an error. +**NB:** This type respects the glibc ``locale.alias`` file, +i.e. it defines alias locales or deletes aliases of a locale when it is removed. +It is not possible, however, to use alias names to define locales or only remove +certain aliases of a locale. + OPTIONAL PARAMETERS ------------------- From 87faffd8750cac94190707c2b37233229c3fbde2 Mon Sep 17 00:00:00 2001 From: Dennis Camera Date: Sat, 14 Nov 2020 10:41:50 +0100 Subject: [PATCH 9/9] [type/__localdef] Also check for aliases in state explorer --- cdist/conf/type/__localedef/explorer/state | 31 +++++++++++++++++++++- cdist/conf/type/__localedef/gencode-remote | 7 +++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/cdist/conf/type/__localedef/explorer/state b/cdist/conf/type/__localedef/explorer/state index d8db29c5..3ba57661 100755 --- a/cdist/conf/type/__localedef/explorer/state +++ b/cdist/conf/type/__localedef/explorer/state @@ -25,8 +25,14 @@ # the main locale (and possibly aliases) is present # absent: # neither the main locale nor any aliases are present +# alias-present: +# the main locale is absent, but at least one of its aliases is present # +# Hardcoded, create a pull request in case it is at another location for +# some other distro. (cf. gencode-remote) +aliasfile='/usr/share/locale/locale.alias' + command -v locale >/dev/null 2>&1 || exit 0 locales=$(locale -a) @@ -68,4 +74,27 @@ locale_available() ( } ) -locale_available "${__object_id:?}" && echo present || echo absent +if locale_available "${__object_id:?}" +then + echo present +else + # NOTE: locale.alias can be symlinked. + if test -e "${aliasfile}" + then + # Check if one of the aliases of the locale is defined + baselocale=$( + parse_locale "${__object_id:?}" _lang _codeset _modifiers \ + && format_locale "${_lang}" "${_codeset}") + while read -r _alias _localename + do + if test "${_localename}" = "${baselocale}" \ + && echo "${locales}" | grep -qxF "${_alias}" + then + echo alias-present + exit 0 + fi + done <"${aliasfile}" + fi + + echo absent +fi diff --git a/cdist/conf/type/__localedef/gencode-remote b/cdist/conf/type/__localedef/gencode-remote index d7fd6942..4538151f 100755 --- a/cdist/conf/type/__localedef/gencode-remote +++ b/cdist/conf/type/__localedef/gencode-remote @@ -94,9 +94,12 @@ in localedef --delete-from-archive "\${_alias}" fi done <'${aliasfile}' - - localedef --delete-from-archive '${main_localename}' EOF + + if test "${state_is}" = present + then + printf "localedef --delete-from-archive '%s'\n" "${main_localename}" + fi ;; esac ;;