NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.9k stars 13.95k forks source link

run0 doesn't fully handle UTF-8 locales #347697

Open acid-bong opened 1 week ago

acid-bong commented 1 week ago

Describe the bug

Only the interactive run0 session displays non-ASCII symbols properly, the non-interactive doesn't. Also it falls back to English/C locale, despite run0 printenv showing the same locale as usual.

Steps To Reproduce

Steps to reproduce the behavior:

  1. run ls in a directory with file names in, say, Cyrillic and a program that is Russified (like df -h)
  2. repeat 1 with prepending run0 to each command
  3. repeat 1 in an interactive run0 session

Expected behavior

run0 shouldn't change locale settings, just like sudo.

Pastes

~
❯ run0
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ====
Authentication is required to manage system services or other units.
Authenticating as: acid
Password:
==== AUTHENTICATION COMPLETE ====
root in /home/acid
❯ ls
 ardour                        nvim-cmp.cast   src     Документы      'Рабочий стол'
 Documents                     olbackup        Sync    Загрузки        Шаблоны
 iso                           olbackup2       www     Изображения
 kernel-report                 org             бекуп   Музыка
'Me 4 Me [Kbt_ltV-9H8].webm'   prog            Видео   Общедоступные
root in /home/acid
❯
~ took 7s
❯ run0 ls
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ====
Authentication is required to manage system services or other units.
Authenticating as: acid
Password:
==== AUTHENTICATION COMPLETE ====
 Documents
'Me 4 Me [Kbt_ltV-9H8].webm'
 Sync
 ardour
 iso
 kernel-report
 nvim-cmp.cast
 olbackup
 olbackup2
 org
 prog
 src
 www
''$'\320\222\320\270\320\264\320\265\320\276'
''$'\320\224\320\276\320\272\321\203\320\274\320\265\320\275\321\202\321\213'
''$'\320\227\320\260\320\263\321\200\321\203\320\267\320\272\320\270'
''$'\320\230\320\267\320\276\320\261\321\200\320\260\320\266\320\265\320\275\320\270\321\217'
''$'\320\234\321\203\320\267\321\213\320\272\320\260'
''$'\320\236\320\261\321\211\320\265\320\264\320\276\321\201\321\202\321\203\320\277\320\275\321\213\320\265'
#...

Additional context

First reported in https://github.com/systemd/systemd/issues/34682, turned out to be locale-/distro-specific (one of maintainers uses Fedora and doesn't have that issue). More pastes (long ones) there.

Notify maintainers

@flokli i guess

Metadata

Please run nix-shell -p nix-info --run "nix-info -m" and paste the result.

[user@system:~]$ nix-shell -p nix-info --run "nix-info -m"
 - system: `"x86_64-linux"`
 - host os: `Linux 6.6.53, NixOS, 24.11 (Vicuna), 24.11.20241004.bc947f5`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Lix, like Nix) 2.91.0
System type: x86_64-linux
Additional system types: i686-linux, x86_64-v1-linux, x86_64-v2-linux, x86_64-v3-linux
Features: gc, signed-caches
System configuration file: /etc/nix/nix.conf
User configuration files: /home/acid/.config/nix/nix.conf:/etc/xdg/nix/nix.conf:/home/acid/.nix-profile/etc/xdg/nix/nix.conf:/nix/profile/etc/xdg/nix/nix.conf:/home/acid/.local/state/nix/profile/etc/xdg/nix/nix.conf:/etc/profiles/per-user/acid/etc/xdg/nix/nix.conf:/nix/var/nix/profiles/default/etc/xdg/nix/nix.conf:/run/current-system/sw/etc/xdg/nix/nix.conf
Store directory: /nix/store
State directory: /nix/var/nix
Data directory: /nix/store/cfl6rqw64ndbh2m0qapg410jf4xmycia-lix-2.91.0/share`
 - channels(root): `""`
 - nixpkgs: `/nix/store/sdzpqjwx7pdx6lsq6llyfqqf7hspp83c-source`

Add a :+1: reaction to issues you find important.

flokli commented 1 week ago

cc @NixOS/systemd

ElvishJerricco commented 5 days ago

It's not clear to me from that systemd issue thread what NixOS specifically is doing wrong here. Can anyone explain?

acid-bong commented 4 days ago

@ElvishJerricco systemd as root doesn't handle locale properly:

❯ locale
LANG=ru_RU.UTF-8
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=

❯ run0 !!
run0 locale
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ====
Authentication is required to manage system services or other units.
Authenticating as: acid
Password:
==== AUTHENTICATION COMPLETE ====
/run/current-system/sw/bin/locale: Cannot set LC_CTYPE to default locale: No such file or directory
/run/current-system/sw/bin/locale: Cannot set LC_MESSAGES to default locale: No such file or directory
/run/current-system/sw/bin/locale: Cannot set LC_ALL to default locale: No such file or directory
LANG=ru_RU.UTF-8
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=
flokli commented 4 days ago

I'm not sure it matters, but at least LOCALE_ARCHIVE_2_27 is not set in there (LOCALE_ARCHIVE seems to be though).

acid-bong commented 4 days ago

Aha, a solution turns out to be to include LOCALE_ARCHIVE in the run0 env:

❯ run0 --setenv=LOCALE_ARCHIVE printenv
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ====
Authentication is required to manage system services or other units.
Authenticating as: acid
Password:
==== AUTHENTICATION COMPLETE ====
LANG=ru_RU.UTF-8
PATH=/nix/store/1lbc6v5p1a3rn4rjaqnz0694xfbq8dxq-systemd-256.4/bin/
USER=root
LOGNAME=root
HOME=/root
SHELL=/bin/sh
INVOCATION_ID=2539aed89f5742aa875730ea78bd70e6
TERM=st-256color
SYSTEMD_EXEC_PID=840737
MEMORY_PRESSURE_WATCH=/sys/fs/cgroup/user.slice/run-u365.service/memory.pressure
MEMORY_PRESSURE_WRITE=c29tZSAyMDAwMDAgMjAwMDAwMAA=
LOCALE_ARCHIVE=/run/current-system/sw/lib/locale/locale-archive
SUDO_USER=acid
SUDO_UID=1000
SUDO_GID=100

❯ run0 --setenv=LOCALE_ARCHIVE ls
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ====
Authentication is required to manage system services or other units.
Authenticating as: acid
Password:
==== AUTHENTICATION COMPLETE ====
 ardour      iso             olbackup    org    src    www     Видео       Загрузки      Музыка         'Рабочий стол'
 Documents   kernel-report   olbackup2   prog   Sync   бекуп   Документы   Изображения   Общедоступные   Шаблоны

And, of course, locale command not doesn't misbehave like there

❯ run0 --setenv=LOCALE_ARCHIVE locale
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ====
Authentication is required to manage system services or other units.
Authenticating as: acid
Password:
==== AUTHENTICATION COMPLETE ====
LANG=ru_RU.UTF-8
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=

Judging by the PATH value, this printenv output is the only env that PID1 is aware about. Would it be a good idea to add LOCALE_ARCHIVE=/run/current-system/sw/lib/locale/locale-archive to that env?

flokli commented 4 days ago

I didn't find the place yet where systemd keeps that list around, but I assume propagating that env variable too might be something upstreamable.

acid-bong commented 4 days ago

I noticed that run0 doesn't load envvars from PAM, just like doas. I'll address that in the original issue