fix(mibook): boot-menu terminal choice via specialisation
The previous startOnBoot approach booted mibook headless by default and locked the machine out: it is WiFi-only with credentials in KWallet, so with no desktop session NetworkManager never joins the network (no SSH), and boot stalled on NetworkManager-wait-online with the tty1 prompt buried under service logs. Replace it with a NixOS specialisation that adds a separate 'terminal' GRUB entry: - default entry boots KDE as before (identical to baseline); - 'terminal' entry boots multi-user.target with autologin for finn and a 'desktop' command to start SDDM on demand. Also disable NetworkManager-wait-online so boot never stalls on the network. Revert the kde-desktop startOnBoot option. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CfozKLQdUh5TzqyjSigLUx
This commit is contained in:
@@ -2,60 +2,104 @@
|
||||
|
||||
## Goal
|
||||
|
||||
Let mibook boot to a text console by default, with KDE fully installed and
|
||||
launchable on demand. The user decides after boot whether they need the
|
||||
graphical desktop, without rebuilding the system.
|
||||
Let mibook offer a choice, each time it boots, between the normal KDE desktop
|
||||
and a terminal-only ("server") mode with no graphical session — decided at
|
||||
boot, without rebuilding the system.
|
||||
|
||||
## Background: why the first attempt failed
|
||||
|
||||
The first implementation booted mibook to a text console by default
|
||||
(`systemd.defaultUnit = "multi-user.target"`, display manager not started) and
|
||||
provided a `desktop` command to start KDE on demand. On real hardware this
|
||||
locked the machine out:
|
||||
|
||||
- **No SSH.** mibook is WiFi-only and its WiFi credentials are stored per-user
|
||||
in KWallet ("agent-owned"). NetworkManager only receives the password once a
|
||||
desktop session is running, so a headless boot never joins the network and
|
||||
the machine has no IP — nothing to SSH into.
|
||||
- **No usable console.** The boot appeared to "hang" with no login prompt:
|
||||
`NetworkManager-wait-online` stalled waiting for a network that never came
|
||||
up, and the `getty` login prompt on tty1 was buried under later service
|
||||
messages.
|
||||
|
||||
Conclusion: a headless WiFi laptop cannot be reached remotely, and the plain
|
||||
console was hard to use. The design must (a) keep the desktop as the reliable
|
||||
default, (b) make the terminal path a deliberate, self-sufficient choice, and
|
||||
(c) not depend on the network being up.
|
||||
|
||||
## Behavior
|
||||
|
||||
- mibook boots to a text console (`multi-user.target`). SDDM and Plasma do
|
||||
**not** start automatically.
|
||||
- KDE (SDDM + Plasma 6) remains fully installed.
|
||||
- Running `desktop` in the terminal starts the SDDM display manager, which
|
||||
presents the graphical login screen; logging in there enters a Plasma 6
|
||||
session.
|
||||
- No reverse command. To return to a text console, stop the display manager
|
||||
(`sudo systemctl stop display-manager`) or reboot.
|
||||
- Other machines that enable the `kde-desktop` profile are unaffected; their
|
||||
desktop still starts on boot.
|
||||
- The **default GRUB entry** boots straight into KDE — unchanged from the
|
||||
known-working baseline.
|
||||
- A **separate GRUB entry, `mibook (terminal)`** (a NixOS *specialisation*),
|
||||
boots to a text console with **autologin** for `finn`. From there the user
|
||||
can work in the shell or run `desktop` to bring KDE up (via SDDM).
|
||||
- The choice is made in the GRUB menu at boot — matching the original request
|
||||
to "decide each time I boot."
|
||||
- Booting never stalls on the network.
|
||||
|
||||
### Known limitation (documented, not fixed in config)
|
||||
|
||||
In terminal mode WiFi will not connect on its own, because the password is
|
||||
stored per-user in KWallet. To reach mibook over SSH from terminal mode, the
|
||||
user must first save the WiFi as a **system** connection in KDE:
|
||||
network settings → the WiFi network → "All users may connect to this network".
|
||||
Until then, terminal mode is local-console-only. This is a one-time manual
|
||||
step outside the scope of the Nix config.
|
||||
|
||||
## Implementation
|
||||
|
||||
### `modules/environments/kde-desktop/default.nix`
|
||||
### `machines/mibook/configuration.nix`
|
||||
|
||||
Add an opt-out option to the existing profile:
|
||||
- Add a NixOS specialisation `specialisation.terminal.configuration`:
|
||||
- `system.nixos.tags = [ "terminal" ];` — labels the generated boot entry.
|
||||
- `systemd.defaultUnit = lib.mkForce "multi-user.target";` — boots to the
|
||||
text console. `graphical.target` is what pulls in the display manager (via
|
||||
its embedded `Wants=display-manager.service`), so defaulting to
|
||||
`multi-user.target` leaves SDDM installed but not started at boot.
|
||||
- `services.getty.autologinUser = "finn";` — guarantees a usable shell on
|
||||
the console instead of a login prompt that can scroll off screen.
|
||||
- A `desktop` command via
|
||||
`pkgs.writeShellScriptBin "desktop" "exec sudo systemctl start display-manager.service"`
|
||||
in `environment.systemPackages`, to start KDE on demand.
|
||||
- Add `systemd.services.NetworkManager-wait-online.enable = false;` (applies to
|
||||
both the default and terminal boots) so boot never stalls waiting for the
|
||||
network.
|
||||
|
||||
- New option `my.profiles.kde-desktop.startOnBoot`, a boolean defaulting to
|
||||
`true`. The default preserves the current behavior for every consumer.
|
||||
- The existing `config` block (SDDM, Plasma 6, user packages) stays enabled
|
||||
whenever the profile is enabled, regardless of `startOnBoot`.
|
||||
- When `startOnBoot = false`, additionally apply:
|
||||
- `systemd.services.display-manager.wantedBy = lib.mkForce [ ];` so SDDM is
|
||||
defined but not pulled in by any boot target.
|
||||
- `systemd.defaultUnit = "multi-user.target";` so the boot target is the
|
||||
text console.
|
||||
- A `desktop` command provided via
|
||||
`pkgs.writeShellScriptBin "desktop" "exec sudo systemctl start display-manager.service"`,
|
||||
added to `environment.systemPackages`.
|
||||
### Reverted from the first attempt
|
||||
|
||||
### `machines/mibook/environments.nix`
|
||||
- `modules/environments/kde-desktop/default.nix` — remove the `startOnBoot`
|
||||
option and its `mkMerge`/`mkIf` machinery; back to the original profile that
|
||||
simply enables SDDM + Plasma 6.
|
||||
- `machines/mibook/environments.nix` — remove `kde-desktop.startOnBoot = false;`
|
||||
(back to just `kde-desktop.enable = true;`).
|
||||
|
||||
Set `kde-desktop.startOnBoot = false;` alongside the existing
|
||||
`kde-desktop.enable = true;`.
|
||||
## Why a specialisation
|
||||
|
||||
A specialisation generates a second boot-menu entry automatically from a
|
||||
modified copy of the configuration. It is the idiomatic NixOS mechanism for a
|
||||
boot-time choice and avoids fragile hand-written GRUB `extraEntries` that would
|
||||
need to track kernel/initrd paths across generations. The default entry remains
|
||||
byte-for-byte the working desktop configuration.
|
||||
|
||||
## Testing / verification
|
||||
|
||||
- `nix build '.#nixosConfigurations.mibook.config.system.build.toplevel'`
|
||||
builds without error.
|
||||
- After `nixos-rebuild switch` on mibook: system boots to a TTY, no SDDM;
|
||||
running `desktop` brings up the SDDM login and a working Plasma session.
|
||||
- Confirm jupiter (or any non-mibook consumer) is unchanged: its evaluated
|
||||
`systemd.defaultUnit` / display-manager wantedBy are not altered.
|
||||
builds both `nixos-system-mibook` and `nixos-system-mibook-terminal`.
|
||||
- Verified on the built closures:
|
||||
- Parent `default.target` → `graphical.target`; no console autologin
|
||||
(identical to the pre-change baseline).
|
||||
- Specialisation `default.target` → `multi-user.target`; tty1 getty wrapper
|
||||
contains `--autologin finn`; `desktop` present in the system profile.
|
||||
- `NetworkManager-wait-online` disabled in both.
|
||||
- Post-`switch` manual check on mibook: default GRUB entry boots to KDE; the
|
||||
`terminal` entry boots to an autologged-in console; running `desktop` there
|
||||
starts SDDM and a working Plasma session.
|
||||
|
||||
## Trade-offs
|
||||
|
||||
- `desktop` relies on `sudo`; the user has sudo access, so no extra
|
||||
configuration is required.
|
||||
- Chose "boot to terminal, launch on demand" over a GRUB boot-menu entry
|
||||
because it is more robust across NixOS generations and needs no fragile
|
||||
static kernel entries.
|
||||
- Autologin on the terminal console means physical access grants a shell
|
||||
without a password. Acceptable for a personal laptop the user controls; the
|
||||
desktop (default) boot is unaffected.
|
||||
- `desktop` relies on `sudo`; the user has sudo access, so no extra config is
|
||||
required.
|
||||
|
||||
Reference in New Issue
Block a user