SVX日記

2004|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|06|07|08|09|10|11|

2024-02-10(Sat) コンテナ上のリモートデスクトップ環境の実用化に成功・改

  前回「最後、言語とタイムゾーンの設定の問題」をクリアしたかように書いたが、よく見れば、左上のメニューも、ターミナルのメニューも、「Applications」や「File」などの表記のままであり正しく日本語化できてはいない。別に実用上は問題ないのだけれど、ロケールを正しく設定しているにもかかわらず、なんでなの? という気持ちは残る。

  画像の説明

  で、調べ始めて、最後には解決に至ったのだけれど、これが複雑怪奇。結論だけ知りたい人は、さっさと当エントリの最後にどうぞ。

  まず、ロケールの設定が不十分である可能性。あまり詳しくないが、様々な切り口で見ても問題が見当たらない。そもそも、メニューの中身の一部は日本語化しているしなぁ。それも意味わからんけど。

# localectl
System Locale: LANG=ja_JP.UTF-8
    VC Keymap: us
   X11 Layout: us
    X11 Model: pc105
 
# locale
LANG=ja_JP.UTF-8
LC_TIME="ja_JP.UTF-8"
LC_MESSAGES="ja_JP.UTF-8"
LC_ALL=
 
# env | grep LANG
LANG=ja_JP.UTF-8

  気づけば、GUI環境でなく、CUI環境もヘンだ。lsの冒頭が「total」になっている。日本語環境なら「合計」になるはず。

# ls -l
total 12
-rw-r--r-- 1 root root 2162 11月 26 16:48 anaconda-post-nochroot.log
-rw-r--r-- 1 root root  150 11月 26 16:48 anaconda-post.log
-rw------- 1 root root 3533 11月 26 16:48 original-ks.cfg

  そこでフト、日本語化を含む、多言語化の方式について思い出した。多くのアプリケーションはgettextという共通の枠組みを使って、英語表記を望みの言語表記に置き換えている。その辞書に当たる「言語ファイル」が「.po」から作られる「.mo」ファイルだ。

# strace ls -l 2>&1 | grep '\.mo'
openat(AT_FDCWD, "/usr/share/locale/ja/LC_TIME/coreutils.mo", O_RDONLY) = -1 ENOENT (そのようなファイルやディレクトリはありません)
openat(AT_FDCWD, "/usr/share/locale/ja/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (そのようなファイルやディレクトリはありません)

  ビンゴ。「ls」の実行時、探しに行っているものの見つかっていない。「言語ファイル」が入っていないことが原因だ。じゃ、その「言語ファイル」はどこに入っているのかというと「coreutils-common」パッケージだ。というか「言語ファイル」は、それを参照する「ls」コマンドと同じパッケージに入っている。つまり、各パッケージを横断して英語表記のままという症状が出ているということは、各パッケージの問題ではなくインストール機構の問題だということだ。

# rpm -qf /usr/share/locale/ja/LC_MESSAGES/coreutils.mo
coreutils-common-9.3-4.fc39.x86_64
 
# rpm -ql coreutils-common | grep ja
/usr/share/locale/ja/LC_MESSAGES/coreutils.mo
/usr/share/locale/ja/LC_TIME
/usr/share/locale/ja/LC_TIME/coreutils.mo

  しかし、この状況はヘンだ。「coreutils-common」パッケージは入っているのに「言語ファイル」だけ入っていない。パッケージの導入状態を検証する。

# rpm -qV coreutils-common

  何も出ない。ノーエラー。そんなアホな。冗長モードにする。

# rpm -qVv coreutils-common | grep ja
.........    /usr/share/locale/ja/LC_MESSAGES/coreutils.mo (not installed)
.........    /usr/share/locale/ja/LC_TIME (not installed)
.........    /usr/share/locale/ja/LC_TIME/coreutils.mo (not installed)

  「(not installed)」と出た。え。入ってないのにノーエラーってどんな状況よ。

  そこでフト、コンテナ環境の特性について思い当たる。コンテナはイメージ化して持ち運んだりするので、余計なファイルは極力含まれないほうが望ましく、特にサーバ用途に利用する場合に必要度の低い言語ファイル等を含めないような機構があるのではないかと。

  調べると、dnfには「tsflags」というパラメータがあり、これを指定するとドキュメント系のファイルのインストールがスキップされる仕組みがあるようだ。コンテナ内の「/etc/dnf/dnf.conf」を見ると、確かに「tsflags=nodocs」という記述がある。

  じゃ、コンテナビルドの序盤でこの記述をコメントアウトしてやればいい……試しに現状の環境でやってみる。

# rpm -qVv coreutils-common
.........    /usr/share/locale/ja/LC_MESSAGES/coreutils.mo (not installed)
.........    /usr/share/locale/ja/LC_TIME (not installed)
.........    /usr/share/locale/ja/LC_TIME/coreutils.mo (not installed)
 :
.........  d /usr/share/man/man1/ls.1.gz (not installed)
 
# diff /etc/dnf/dnf.conf.org /etc/dnf/dnf.conf
< tsflags=nodocs
> #tsflags=nodocs
 
# dnf reinstall coreutils-common
 
# rpm -qVv coreutils-common
.........    /usr/share/locale/ja/LC_MESSAGES/coreutils.mo (not installed)
.........    /usr/share/locale/ja/LC_TIME (not installed)
.........    /usr/share/locale/ja/LC_TIME/coreutils.mo (not installed)
 :
.........  d /usr/share/man/man1/ls.1.gz

  しかし効果なし。いや、ドキュメント系のファイルはインストールされたので、その効果はあったのだが「言語ファイル」は入らない。なんだよもぅ。

  挙げ句の果てには、coreutilsパッケージのソースをバラしてspecファイルの中身まで確認してみる……

# dnf download --source coreutils
# rpm2cpio coreutils-9.3-5.fc39.src.rpm | cpio -div
# view coreutils.spec 
 :
%find_lang %name
# Add the %%lang(xyz) ownership for the LC_TIME dirs as well...
grep LC_TIME %name.lang | cut -d'/' -f1-6 | sed -e 's/) /) %%dir /g' >>%name.lang
 : 
%files common -f %{name}.lang

  ……が収穫なし。いや、%filesって記述で言語ファイルを扱っているらしいけど、これは主にパッケージングに関係する記述で、インストーリングに関係する記述じゃないっぽいング。

  さすがにdnfのソースコードまでは追いたくない……ええいクソ、こうなったらstraceでdnfの挙動を絨毯爆撃じゃ。

# strace -o dnf.str dnf reinstall coreutils-common
# cat dnf.str | grep open | grep -v NOENT | less

  ……と、半ばヤケクソで見ていくと、妙なファイルを読み込んでいる様子に気づいた。中を見ると、ちょっとニオう内容。

openat(AT_FDCWD, "/etc/rpm/macros.image-language-conf", O_RDONLY) = 3
 
# cat /etc/rpm/macros.image-language-conf
%_install_langs en_US

  通常の環境にはこのファイルは存在していない。削除してreinstallしてみると……

# rm /etc/rpm/macros.image-language-conf
# dnf reinstall coreutils-common
# rpm -qVv coreutils-common
.........    /usr/share/locale/ja/LC_MESSAGES/coreutils.mo
.........    /usr/share/locale/ja/LC_TIME
.........    /usr/share/locale/ja/LC_TIME/coreutils.mo
 :
.........  d /usr/share/man/man1/ls.1.gz

  入ったーッ! ……つーか、そんなんわかるかーッ!

  画像の説明

  つうか、上記のファイルについてググってみても、どうも後付けっぽい理由で追加され、未だ完全に意図した挙動にはなっていないような雰囲気だ。ということは、この対処もテンポラリなものと考えておいたほうがいいことになるな。

  とはいえ、<かきかけ>