From 59d82f06f5726e8b75039446bc065a81812cdd77 Mon Sep 17 00:00:00 2001 From: alvinlollo Date: Wed, 7 Oct 2026 21:55:30 +1100 Subject: [PATCH] feat(installer): sshd opt-in, gsettings replay, live-medium motd stamp - alvin-install: new sshd screen (default on) + install step. openssh is guaranteed into the pacstrap list when requested, and the final banner reports whether the enable actually succeeded (SSHD_APPLIED) instead of what was selected. The prompt warns that password login uses the same password as LUKS, and only mentions the GitHub key import when a username was given. - alvin-install: replay the `gsettings set` commands end-4 logged during its setup run with a clean env and a throwaway session bus as the target user, then read each key back in a second session to confirm it persisted (gvariant_unescape normalizes both '...' and "..." GVariant output). The venv check now walks the uv bin/python symlink chain, re-rooting absolute hops under $TARGET, since that link dangles on the live medium. - build: append the build stamp to the live /etc/motd (keeps the installed system's motd untouched) and drop alvin-install's install_motd step. - docs: installer sections in README/AGENTS.md, sshd notes, corrected line counts. --- AGENTS.md | 43 +++++- README.md | 71 ++++++++- airootfs/root/customize_airootfs.sh | 6 +- airootfs/usr/local/bin/alvin-install | 216 ++++++++++++++++++++++++--- profiledef.sh | 5 +- 5 files changed, 312 insertions(+), 29 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 9497644..eb9b11c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -54,13 +54,50 @@ install them into the target without the network. | `bootstrap_packages` | Minimal build-time packages (`base`, `arch-install-scripts`) | | `airootfs/root/customize_airootfs.sh` | Runs inside chroot during build: keyrings, skel dotfiles (incl. end4-pC), qsConfig patch, end-4 `install-deps`, package harvest, uv/font pre-warm | | `airootfs/root/.live-pacman.conf` | `/etc/pacman.conf` of the built image (adds `[local-aur]` = `file:///opt/localrepo`) | -| `airootfs/usr/local/bin/alvin-install` | Installer: partitions, pacstrap, LUKS (systemd initramfs **or** experimental unl0kr + optional TPM2 unlock), user, git identity + GitHub SSH keys, login manager (none/greetd/sddm/gdm) + autologin, end-4 dotfiles (`--skip-alldeps`), build-stamp motd, boot | +| `airootfs/usr/local/bin/alvin-install` | Installer: partitions, pacstrap, LUKS (systemd initramfs **or** experimental unl0kr + optional TPM2 unlock), user, git identity + GitHub SSH keys, login manager (none/greetd/sddm/gdm) + autologin, optional sshd (default on), end-4 dotfiles (`--skip-alldeps`), boot | | `localrepo/build-end4-deps.sh` | Non-interactive AUR builds for end-4 dependencies | | `localrepo/update.sh` | Regenerates localrepo DB, syncs names to packages.x86_64, syncs `airootfs/opt/localrepo/` | +## alvin-install (installer inside the ISO) + +Source: `airootfs/usr/local/bin/alvin-install` (~1,880 lines, **no `.sh` extension**). +The airootfs overlay ships it as `/usr/local/bin/alvin-install` (mode `0755` forced in +`profiledef.sh` `file_permissions`), and `/etc/motd` advertises it on the live medium. + +- **Invoke**: as root from the live session. Hard requirements: `gum` and UEFI — + `check_prereqs` exits if `/sys/firmware/efi` is missing. Log: `/var/log/alvin-install.log` + (copied into the target at the end; `ERR` trap prints the failing line). +- **Structure**: `main()` runs 16 `screen_*` TUI functions (collect answers: welcome, keymap, + network, disk, luks, unl0kr, filesystem, username, password, hostname, git, timezone, + locale, login manager, sshd, summary) then a fixed order of `install_*` steps + (partition → LUKS → format/mount → pacstrap → fstab → repos → timezone → locale → + hostname → network → sshd → user → git/SSH → end-4 dots → mkinitcpio → bootloader → + TPM/unl0kr → login manager → autologin → cleanup). Screens and install steps are + independent — edit one without + touching the other. An `EXIT` trap unmounts `$TARGET` and closes `cryptroot` on any exit. +- **Package list**: `install_pacstrap` builds the *installed* system's list from the medium's + `/run/archiso/bootmnt/arch/pkglist.x86_64.txt` (i.e. `pacman -Q` of the live ISO), so + `packages.x86_64` changes flow into installed systems. It drops `PKGS_EXCLUDE` + (`archiso mkinitcpio-archiso mkinitcpio-nfs-utils syslinux memtest86+`) plus names not + resolvable in the live repos, then always appends hardcoded essentials + (`base linux linux-firmware linux-cachyos networkmanager grub efibootmgr sudo git …`). +- **CI never lints it**: the shellcheck step globs only `*.sh`. Check manually after edits: + `shellcheck -x -s bash airootfs/usr/local/bin/alvin-install` +- end-4 quirks (`--skip-alldeps`, `yes i`, end4-pC re-copy) are in [Gotchas](#gotchas) below. + +## Verify a single change locally (mirrors CI) + +```bash +shellcheck -x -s bash