見出し画像

【NixOS GUI設定ツール(nixgen)】仕上げの26コミット(8月10日→8月11日の差分)

NixOS の設定項目 24,557 個とパッケージ 144,245 個を、検索とフォームで .nix ファイルにする道具 nixgen の更新報告、第2回です。

前回の記事では「作る」部分を報告しました。今回の 26コミットのテーマは仕上げです。作った設定をマシンに届ける前の作業に戻る、そして壊れ方を潰す。デスクトップは10種類になり、すべてのメッセージが日英併記になり、ロゴが付きました。

nix run github:hatake716/nixgen

1. System update ボタン — 最後の一歩を代行する

これまでの nixgen は、ファイルを作るところまでが仕事でした。展開して、コピーして、nixos-rebuild switch するのは手作業です。今回、ヘッダーの右端に System update ボタンを付けました。

押すと3段階、それぞれの前に確認が出ます。

  1. ブラウザ — これから何をするかの一覧を出し、承諾すると書庫をダウンロード

  2. ターミナル — 展開した3ファイルを表示し、/etc/nixos へコピーする前に [y/N]

  3. ターミナル — nixos-rebuild switch の前にもう一度 [y/N]

ここで設計の判断がひとつありました。nixgen のサーバーは実行しません。コマンドを渡します。

nixgen は認証のないローカルサーバーです。もし「/etc/nixos を上書きして再構築する」APIを開けたら、同じブラウザで開いている任意のWebページからその口を叩けます。管理者権限でシステムを書き換えるドライブバイの入口を、全利用者のマシンに配ることになる。だからボタンはコマンドを1つ組み立ててクリップボードに置くところまでで、sudo と最後の2つの確認はターミナルに残しました。

コマンド自体にも細工があります。

  • ダウンロードフォルダを決め打ちしない。 xdg-user-dir に尋ね、~/Downloads と ~/ダウンロード の両方を試します。日本語環境のフォルダ名問題はここで吸収します

  • bash・zsh・fish のどれに貼っても動く。 fish はヒアドキュメントが無く read の仕様も違うので、単引用符を内側に含まない bash -c '…' 1行にしました。3つのシェル全部で実際に走らせて確認しています

  • 上書きされたファイルは残る。 cp --backup=numbered なので、configuration.nix.~1~ が隣に残り、失敗しても戻れます。hardware-configuration.nix は書庫に入っておらず、コマンドも名前を出しません


2. 取り込みが2つになった — ファイルには持ち主がいる

地味ですが、今回いちばん考えた変更です。

nixgen は2種類のファイルを扱います。configuration.nix はあなたのマシンのファイルで、generated.nix は nixgen が管理するファイル。ところが取り込みボタンは1つで、どちらを読んでも中身は module(generated.nix 側)に入っていました。動きはするけれど、あなたのファイルの中身が、道具側のファイルに移ってしまうわけです。

今はボタンが2つあり、ファイルごとに行き先が違います。

Import configuration.nix — マシン自身の情報(ホスト名・ユーザー・ブートローダー・stateVersion など)は Setup タブの入力欄に入り、以後はそこから書き出されます。imports の行は統合。それ以外は「どこから来たか」のコメント付きで、そのまま configuration.nix に写ります。module には触れません。

Import generated.nix — 前回の作業を module に読み戻します。「タブを閉じると入力内容は消える」の答えがこれで完結しました。generated.nix をダウンロードしておけば、いつでも続きから再開できます。

検証は往復でやりました。UIで設定を組み立て→書庫を受け取り→その書庫の2ファイルを新しいセッションに読み戻し→内容が一致するか。Setup の欄も、module の18行も、元通りに戻ります。


3. デスクトップ10種類 — 同じ形にしないことが仕事だった

前回5種類だったデスクトップ環境に、LXQt・Hyprland・Sway・niri・i3 を足しました。面白いのは、これが「リストに5行足す」作業ではなかったことです。

Wayland のコンポジタ3つ(Hyprland・Sway・niri)は素のままだとパネルも通知もログイン画面もありません。そこで3点セットを組みました。

  • sddm を Wayland モードで。wayland.enable を忘れると、sddm の設定は DisplayServer=x11 になります。他に何もXを使わないマシンの前に、X11のログイン画面だけが立つ。これは両方の設定ファイルを実際にビルドして比べて確かめました

  • noctalia-shell をパッケージとして。パネル・ランチャー・通知を上に載せる部分です

  • XWayland。ここで発見がありました。Hyprland と Sway にはオプションがあるのに、niri には存在しません(XWayland を内蔵していない)。niri だけ xwayland-satellite というパッケージで対応し、「起動は niri の設定から行う必要がある」ことをステータス欄で案内します

10種類とも、構文解析ではなく実際の NixOS システムとして評価し、セッション(hyprland-0.55.4、none+i3-xsession など)が正しく登録されることまで見ています。ほかに Shell の行(bash・zsh・fish。users.defaultUserShell だけだと /etc/shells に載らず補完も入らないので、programs.*.enable と2点セット。bash は readline 無しビルドを避けて bashInteractive)と、Flatpak の行(portal を一緒に入れないとファイルダイアログが出ない。設定では代われない flatpak remote-add … flathub はステータス欄で案内)も足しました。


4. パッケージ一覧に、アイコンとグレーアウト

アイコンは出どころが問題でした。ネットから取ると閲覧内容が外に漏れ、Papirus テーマに依存するとインデックス37MBの道具に252MBのクロージャが付き、リポジトリに同梱するとGPLの画像がMITのリポジトリに入る。採ったのは4つめの道で、そのマシンに既に入っているアイコンテーマから拾う。ダウンロードなし、依存増なし。代わりに表示される数はマシン次第です(作者の環境で189個中146個、77%)。無いものは名前から決まる色に頭文字を出します。tmux や gcc にはそもそもアイコンが存在しないので、これは欠落ではなく正解の表示です。

グレーアウトは「environment.systemPackages に既に入っているパッケージは一覧で薄くなる」機能です。判定はクリック履歴ではなく毎回 module を読み直す方式にしました。カードから手で消しても、テキストで直接編集しても、一覧が追従します。クリックの記録を持つ方式は、カードを直接編集された瞬間に嘘をつくからです。

開発カテゴリには vscode(unfree の表示付き)、lmstudio、ollama を、他のカテゴリに localsend・virtualbox・tradingview を足して12分野189個になりました。virtualbox はパッケージだけでは仮想マシンを起動できないので、virtualisation.virtualbox.host.enable への案内が毎回出ます。


5. すべてのメッセージが日英併記に

プルダウンの併記は前回やりました。今回はアプリが発するすべての文です。ステータス欄29箇所、取り込みサマリの通知、ダイアログ、dismiss — 閉じる まで。文章はラベルと違って1行に収まらないので、英語の下の行に日本語を置く形にしています。

例外を1つ、意図して残しました。Nix パーサーのエラーは訳しません。 「Nix がこのファイルを解析できませんでした:」と両言語で前置きした上で、パーサーの出力をそのまま引用します。エラーメッセージで検索する人に必要なのは、実際に表示された文字列だからです。


6. バグ狩り3ラウンド — 合計10件

「安定版にする」ためにアプリ全体を3回、コードを読むのではなく動かして点検しました。見つけて直したのは10件。印象的だったものを挙げます。

ダウンロードが1回分の編集より古い。 レンダリングは120ms遅延でサーバー実行なので、キー入力直後の一瞬だけ手元のファイルが古い。ホスト名を打って即 Download all three で、画面と違う書庫が落ちてきました。ファイルを渡す4つのボタン全部が、保留中のレンダリングを待ってから動くようにしました。

同じファイルを2回読み込むと、NixOS が拒否するファイルができる。 取り込みが既存のカードに合流していたため、1つの属性にカードが2枚でき、error: attribute 'services.openssh.enable' already defined。ごく普通の操作で再現します。読み込んだ内容が既存を置き換えるようにし、置き換えた項目はサマリに列挙します。

Setup タブを開いたまま読み込むと例外。 画面更新の処理が kind=setup の検索結果(=オプション)をパッケージ用の描画関数に渡していました。長らく「見えない場所に描くだけ」で無害でしたが、アイコン導入で attr を読むようになった途端に例外へ変わり、取り込み処理を巻き込みました。無害なバグは、無害なうちに直すべきという教訓です。

コンソールが404で埋まる。 アイコンの無いパッケージごとに404、検索1回で128件。デスクトップのプリセットも候補パスを1つずつ試して404を出していました。どちらも「存在するものだけ返す」一括問い合わせに変え、いまは通常操作で404を返す箇所がゼロです。赤い行が日常的に出るコンソールは、本当に壊れた時に誰も読みません。

最終ラウンドでは、引用符付き属性・負数・lib.mkIf・非ASCIIユーザー名・ドット付きパッケージを詰め込んだ意地悪なファイルの取り込み、プリセット連打、チャンネル切替、変なホスト名での System update まで通して、実バグは2件(let 束縛への事前警告の欠落と、エラーが常に generated.nix という名前で出る件)。正直に書くと、この過程で自作テスト側の誤検出も3件あり、都度実データと突き合わせて「アプリは正しい、テストが間違い」を確定させました。検証する側も検証されるという話です。


7. ロゴが付いた

原画(雪の結晶が右へ溶けて幾何学形になる線画)を支給してもらい、余白を切り落として白を透過に変換、508KB→9.6KB まで圧縮して、ホームページ・README・アプリ内に入れました。

ただし全部には使っていません。原画を48pxに縮めると灰色に潰れることが実測で分かったので、22pxのヘッダーと16pxのfaviconには、同じ意匠をコードで描き起こした「結晶だけ」のSVGを使っています。作図はスクリプト(tools/mark.py)にしました。手で描いた6本の腕は6本とも微妙に違うものになるからです。配色も、青いアクセントをやめてロゴに合わせた黒一色に寄せました。


8. ドキュメントを初心者の一本道に

最後に、README・アプリ内の説明・ホームページを書き直しました。きっかけは、READMEのインストール手順の Step 4 が Download all three ができる前の古い手順(ファイルを1つ受け取って imports を手で書き足す)のまま残っていたことです。機能が3日で26コミットぶん進むと、ドキュメントはこうやって取り残されます。

今は「flakes を有効にする → 起動 → ブラウザで組み立てる(入力欄の名前まで書いた具体例)→ マシンに載せる(実コマンド4行)→ 常用するなら」の5ステップで、インストールから switch まで途切れません。アプリ内の5手順も「1手順=1動作」に揃え、ファイル配置図はファイルが手元に来る手順5へ移しました。


まとめ

ベータ版です。適用の前には必ず sudo nixos-rebuild dry-build を。次は検証機での実機確認に進みます。

nix run github:hatake716/nixgen

続きはこちら

関連記事はこちら


いいなと思ったら応援しよう!

はたけっち|テック&ガジェット雑学 よろしければ応援お願いします! いただいたチップはクリエイターとしての活動費に使わせていただきます!