← Back to team overview

cloud-init-dev team mailing list archive

[Merge] ~vorlon/cloud-init:lp.1134036 into cloud-init:master

 

Steve Langasek has proposed merging ~vorlon/cloud-init:lp.1134036 into cloud-init:master.

Requested reviews:
  cloud-init commiters (cloud-init-dev)
Related bugs:
  Bug #1134036 in maas (Ubuntu): "Failure when using ssh with a locale that is not configured on the server"
  https://bugs.launchpad.net/ubuntu/+source/maas/+bug/1134036

For more details, see:
https://code.launchpad.net/~vorlon/cloud-init/+git/cloud-init/+merge/348101
-- 
Your team cloud-init commiters is requested to review the proposed merge of ~vorlon/cloud-init:lp.1134036 into cloud-init:master.
diff --git a/tools/Z99-cloud-locale-test.sh b/tools/Z99-cloud-locale-test.sh
index 4978d87..38cfd05 100644
--- a/tools/Z99-cloud-locale-test.sh
+++ b/tools/Z99-cloud-locale-test.sh
@@ -3,16 +3,19 @@
 #
 # Author: Ben Howard <ben.howard@xxxxxxxxxxxxx>
 # Author: Scott Moser <scott.moser@xxxxxxxxxx>
-# (c) 2012, Canonical Group, Ltd.
+# Author: Steve Langasek <steve.langasek@xxxxxxxxxx>
+# (c) 2012, 2018, Canonical Group, Ltd.
 #
 # This file is part of cloud-init. See LICENSE file for license information.
  
-# Purpose: Detect invalid locale settings and inform the user
-#  of how to fix them.
+# Purpose: Ensure the user has a valid locale upon remote login.
 
-locale_warn() {
+locale_fixup() {
     local bad_names="" bad_lcs="" key="" val="" var="" vars="" bad_kv=""
     local w1 w2 w3 w4 remain
+    # if we are given an invalid locale, try to set to a
+    # least-common-denominator UTF-8 locale for maximal compatibility.
+    local default_locale=C.UTF-8
 
     # if shell is zsh, act like sh only for this function (-L).
     # The behavior change will not permenently affect user's shell.
@@ -22,79 +25,42 @@ locale_warn() {
     # VARIABLE=
     # VARIABLE="value"
     # locale: Cannot set LC_SOMETHING to default locale
+    # glibc's 'locale' command outputs VARIABLE=foo for variables set in
+    # the environment, and VARIABLE="foo" for locale settings that are
+    # derived.  Use this to minimize the set of variables we are overriding
+    # to those that are specifically detected to be broken.
     while read -r w1 w2 w3 w4 remain; do
         case "$w1" in
             locale:) bad_names="${bad_names} ${w4}";;
             *)
                 key=${w1%%=*}
                 val=${w1#*=}
-                val=${val#\"}
-                val=${val%\"}
-                vars="${vars} $key=$val";;
+                case $val in
+                    \"*\"|"")
+                         # quoted means inferred; don't override it,
+                         # nor an empty value
+                         ;;
+                     *)
+                         set_vars="$key $set_vars"
+                         ;;
+                esac
         esac
     done
     for bad in $bad_names; do
-        for var in ${vars}; do
-            [ "${bad}" = "${var%=*}" ] || continue
-            val=${var#*=}
-            [ "${bad_lcs#* ${val}}" = "${bad_lcs}" ] &&
-                bad_lcs="${bad_lcs} ${val}"
-            bad_kv="${bad_kv} $bad=$val"
-            break
-        done
-    done
-    bad_lcs=${bad_lcs# }
-    bad_kv=${bad_kv# }
-    [ -n "$bad_lcs" ] || return 0
-
-    printf "_____________________________________________________________________\n"
-    printf "WARNING! Your environment specifies an invalid locale.\n"
-    printf " The unknown environment variables are:\n   %s\n" "$bad_kv"
-    printf " This can affect your user experience significantly, including the\n"
-    printf " ability to manage packages. You may install the locales by running:\n\n"
-
-    local bad invalid="" to_gen="" sfile="/usr/share/i18n/SUPPORTED"
-    local pkgs=""
-    if [ -e "$sfile" ]; then
-        for bad in ${bad_lcs}; do
-            grep -q -i "${bad}" "$sfile" &&
-                to_gen="${to_gen} ${bad}" ||
-                invalid="${invalid} ${bad}"
-        done
-    else
-        printf "  sudo apt-get install locales\n"
-        to_gen=$bad_lcs
-    fi
-    to_gen=${to_gen# }
-
-    local pkgs=""
-    for bad in ${to_gen}; do
-        pkgs="${pkgs} language-pack-${bad%%_*}"
-    done
-    pkgs=${pkgs# }
-
-    if [ -n "${pkgs}" ]; then
-        printf "   sudo apt-get install ${pkgs# }\n"
-        printf "     or\n"
-        printf "   sudo locale-gen ${to_gen# }\n"
-        printf "\n"
-    fi
-    for bad in ${invalid}; do
-        printf "WARNING: '${bad}' is an invalid locale\n"
+        case $set_vars in
+            *$bad*)
+                echo "$bad=$default_locale"
+                echo export $bad
+                ;;
+            *LANG\ *)
+                echo "LANG=$default_locale"
+                echo export LANG
+                ;;
+        esac
     done
-
-    printf "To see all available language packs, run:\n"
-    printf "   apt-cache search \"^language-pack-[a-z][a-z]$\"\n"
-    printf "To disable this message for all users, run:\n"
-    printf "   sudo touch /var/lib/cloud/instance/locale-check.skip\n"
-    printf "_____________________________________________________________________\n\n"
-
-    # only show the message once
-    : > ~/.cloud-locale-test.skip 2>/dev/null || :
 }
 
-[ -f ~/.cloud-locale-test.skip -o -f /var/lib/cloud/instance/locale-check.skip ] ||
-    locale 2>&1 | locale_warn
+eval $(locale 2>&1 | locale_fixup)
 
-unset locale_warn
+unset locale_fixup
 # vi: ts=4 expandtab

Follow ups