Hi,

having run into this issue, I have figured out why locales behaves unexpectedly. Here's a snippet to show the issue:

--->8------>8------>8------>8------>8------>8------>8------>8------>8---
root@sid:/tmp/autopkgtest.3hIrFA/build.AZ6/real-tree# apt install locales
Installing:
  locales

Summary:
  Upgrading: 0, Installing: 1, Removing: 0, Not Upgrading: 1
  Download size: 0 B / 3902 kB
  Space needed: 16.1 MB / 3378 MB available

debconf: unable to initialize frontend: Dialog
debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 79, <STDIN> line 1.)
debconf: falling back to frontend: Readline
Preconfiguring packages ...
Selecting previously unselected package locales.
(Reading database ... 27044 files and directories currently installed.)
Preparing to unpack .../locales_2.39-6_all.deb ...
Unpacking locales (2.39-6) ...
Setting up locales (2.39-6) ...
debconf: unable to initialize frontend: Dialog
debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 79.)
debconf: falling back to frontend: Readline
Generating locales (this might take a while)...
Generation complete.
Processing triggers for man-db (2.12.1-2) ...
root@sid:/tmp/autopkgtest.3hIrFA/build.AZ6/real-tree# cat << EOF | debconf-set-selections
locales locales/default_environment_locale      select  en_US.UTF-8
locales locales/locales_to_be_generated multiselect     en_US.UTF-8 UTF-8
EOF
root@sid:/tmp/autopkgtest.3hIrFA/build.AZ6/real-tree# debconf-get-selections | grep -P ^locales
locales locales/default_environment_locale      select  en_US.UTF-8
locales locales/locales_to_be_generated multiselect     en_US.UTF-8 UTF-8
root@sid:/tmp/autopkgtest.3hIrFA/build.AZ6/real-tree# dpkg-reconfigure --frontend=noninteractive locales
Generating locales (this might take a while)...
Generation complete.
root@sid:/tmp/autopkgtest.3hIrFA/build.AZ6/real-tree# debconf-get-selections | grep -P ^locales
locales locales/default_environment_locale      select  None
locales locales/locales_to_be_generated multiselect     
root@sid:/tmp/autopkgtest.3hIrFA/build.AZ6/real-tree#
--->8------>8------>8------>8------>8------>8------>8------>8------>8---

As you can see above, I'm setting the debconf selections first, verifying that they're correctly set, then run dpkg-reconfigure to let the reconfigure mechanism run it's course. However, instead of correctly setting the /etc/locale.gen and /etc/locale.conf to the debconf selections, those values are reverted to the defaults. Interestingly, if the order of the "apt install locales" and the debconf-set-selections command are reversed, it correctly sets the locale.

The reason is how /var/lib/dpkg/info/locales.config is run. Here's the relevant code snippet from this file:

--->8------>8------>8------>8------>8------>8------>8------>8------>8---
# Get the list of selected locales from /etc/locale.gen
if [ -e /etc/locale.gen ]; then
    if [ -L $LG ] && [ "$(readlink $LG)" = "/usr/share/i18n/SUPPORTED" ]; then
        SELECTED_LOCALES="All locales"
    else
SELECTED_LOCALES="$(echo "$GEN_LOCALES" | sort -u | tr '\n' ',' | sed -e 's/, */, /g' -e 's/, *$//g')"
    fi
    db_set locales/locales_to_be_generated "$SELECTED_LOCALES"
fi

DEFAULT_ENVIRONMENT="$(cat $LEGACY_EE $EE 2>/dev/null | awk '/^LANG=/ {gsub("\"", ""); sub("LANG=", ""); lang=$0;} END {print lang}')"
DEFAULT_ENVIRONMENT="$(convert_locale "$DEFAULT_ENVIRONMENT")"
if [ -n "$SUPPORTED_LOCALES" ] && [ -n "$DEFAULT_ENVIRONMENT" ]; then
  if echo "$SUPPORTED_LOCALES" | grep -q -e "\b$DEFAULT_ENVIRONMENT\b" ; then
    db_set locales/default_environment_locale "$DEFAULT_ENVIRONMENT"
  fi
fi
--->8------>8------>8------>8------>8------>8------>8------>8------>8---

So when /etc/locale.gen exists, this file is read, and then the settings in the debconf database overwritten by those value. So once debconf is installed, there's no programmatic way via debconf to change the locale. A workaround is template the files /etc/locale.gen and /etc/locale.conf and then run dpkg-reconfigure locales.

This however seems counterintuitive to me, as practically all other packages using debconf have the debconf database as authoritative data from which the config is written (e.g. apt-cacher-ng, ca-certificates, console-setup, iproute2, grub-efi-amd64, grub-pc, postfix, tzdata, wireshark-common, to name a few).

Neither /etc/locale.gen, nor /etc/locale.conf are marked as conffiles, so they shouldn't edited by users, and neither be preserved, nor authoritative on the matter. As such, I'm raising the bug severity.

I propose to remove the shown code lines from locales.config. This would make any debconf selections authoritative again.

A compromise would be to add another debconf option that decides on which side is authoritative (either config file, or debconf), but IMHO that adds complexity without much benefit.

Regards,
Lee

Reply via email to