unl0kr already prompts for the LUKS passphrase on screen, so a login
manager on top of it would be a second prompt. The login screen now only
collects a fallback (none/greetd/sddm/gdm) when unl0kr is selected;
resolve_login_manager applies it only when install_unl0kr falls back to
the systemd initramfs, and the summary shows both states.
Also ships /etc/unl0kr.conf (breezy-dark) plus the empty
/usr/share/unl0kr/unl0kr.conf the package omits so unl0kr stops warning
about an unparseable config, and pins Hyprland in the user's
AccountsService record so gdm autologin does not fall back to
gnome.desktop.
Adds a Troubleshooting entry (symptom, cause, drop-or-keep fixes). The
keep path removes grml-zsh-config instead of setting
skip_global_compinit=1: grml's /etc/zsh/zshrc runs compinit
unconditionally and ignores that Debian/Ubuntu variable.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- screen_hostname: reject names that break /etc/hostname and /etc/hosts.
- screen_disk: parse lsblk -P by regex so multi-word/empty MODELs show
correctly, and never offer /dev/zram* (TYPE=disk) as a target.
- packages: add python-distro, the undeclared runtime dep of the shipped
ssh-import-id (it always crashed and fell back to curl).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
linux.preset targeted the 'linux' package, which is not on the ISO, so
linux-cachyos generated its own default+fallback preset and the squashfs
carried an unused fallback initramfs. No package owns the preset file
(mkinitcpio's hook only creates one if missing), so this cannot conflict.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Replace the 644/755 chmod sweep (which also undid its own chmod 700)
with go-w,a+rX so non-.sh executables keep +x.
- Install an oh-my-zsh .zshrc into /etc/skel after pacstrap. It is staged
as /root/.zshrc-skel because grml-zsh-config owns /etc/skel/.zshrc and
an airootfs copy would abort pacstrap.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- install_pacstrap: fall back to the live system's pacman -Q when the
medium's pkglist is gone (copytoram unmounts bootmnt), and die on an
empty list instead of pacstrapping only the essentials.
- screen_disk: find the live medium via archisosearchuuid when bootmnt
is unmounted, and hide whole-disk sources (empty PKNAME).
- install_cachyos_repo: put [cachyos] ahead of [core] like the ISO build
and add [chaotic-aur], so chaotic packages keep updating.
- install_user: create the user with fish; the 'none' login manager now
autostarts Hyprland via ~/.config/fish/conf.d/alvin-hyprland.fish.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 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.
The chroot's /dev only gains fd/stdin/stdout/stderr symlinks at boot, and
container executors often lack them, which breaks mkinitcpio's preset step
(pipes through /dev/stdin) and bash process substitution
("/dev/fd/63: No such file or directory").
- build-iso workflow: create the links in the executor's /dev, then mount a
fresh devtmpfs and create them there too so the chroot tree is covered
whether the executor's /dev is devtmpfs or a plain tmpfs
- customize_airootfs.sh: self-heal the same links inside the chroot
screen_git now prompts GitHub username before git name/email, and the
screen description plus installation summary list SSH before git to
match the new prompt order. Behavior unchanged - prompts are
independent and all assignment sites are read after the screen returns.
- profiledef.sh stages airootfs/root/.iso-build-stamp (git/CI gated, falls
back to 'commit unknown'); customize_airootfs.sh installs it as
/etc/alvin-build-stamp; install_motd appends it to the target /etc/motd
- alvin-install: skippable git/GitHub screens with ssh-import-id import
(yay build + python-distro, curl .keys fallback), LUKS Mode A (systemd
sd-encrypt + rd.luks.name) vs Mode B (unl0kr + cryptdevice), TPM2
enrollment via $PASSWORD with rd.luks.options activation, unl0kr
build/verify with Mode-A fallback, login manager none/greetd/sddm/gdm
(enable DM before disabling getty@tty1), autologin per DM (forced off
when TPM enrolled), build-stamp motd; includes the existing
GRUB_DISABLE_BOOTNEXT grub tweak
- review fixes: greetd autologin TOML quoting, .ssh chowned before
ssh-import-id, builtin-aware initramfs module verification across all
installed kernels, curl exit-code split (fetch failure vs no keys),
plain Hyprland on every login path
- add curl to packages.x86_64; document stamp flow and installer in
AGENTS.md/README.md
Two low-severity review findings on 8501a60:
- owner="$(id -u):$(id -g)" as two substitutions only propagates the
last status, so a lone id -u failure would build ':1000' and abort at
the chown with "invalid owner" under the wrong line. Run both ids in
a single arch-chroot sh -c chained with && and join with paste -sd:;
pipefail makes any failure abort at the owner= line. Verified both
paths: existing user yields 1000:1000, missing user trips the ERR
trap before owner is used.
- the ydotool symlink mkdir/ln wrote stderr to the terminal while the
failure warn pointed at $LOG, which never recorded it; redirect both
into the log, matching the bluetooth block.
The end-4 step's chowns ran on the live medium, whose /etc/passwd has
no $USERNAME (the user exists only inside /mnt), so 'chown -R
alvin:alvin' failed with "invalid user" and the ERR trap aborted the
install at line 543. Resolve uid/gid once via arch-chroot id and chown
by number; the three remaining name-based chowns (fork/fish/hypr
restores) would have hit the same wall later.
Replace those three mid-function chowns with one catch-all over the
target home after the last root-side write: sed -i on the presets
rewrites through a temp file, which leaves them root-owned with no
chown after it.
systemctl --user enable ydotool.service could never work inside the
chroot (no /run/user/UID/bus exists before boot; it only ever warned
with "Failed to connect to user scope bus", so ydotool never
autostarted). Write the symlink enable would write:
~/.config/systemd/user/default.target.wants/ydotool.service ->
/usr/lib/systemd/user/ydotool.service.
end-4's ./setup sudo keepalive orphans a `sleep 60` child as ii-builder;
userdel then exits 8 and aborts the ISO build (CI exit 8).
Sweep uid-matching processes inside the build chroot before userdel,
mirroring shadow's user_busy_processes() checks (real/effective/saved
uid + root device/inode). Because arch-chroot mounts proc before
`unshare --fork --pid`, /proc entry numbers are outer-namespace pids:
signal the last NSpid field instead, require matching NSpid depth, and
surface kill errors instead of swallowing them. userdel keeps its stderr
and, on final failure, dumps the leftover process list before aborting.
- customize_airootfs.sh stages dots-hyprland at /opt, runs ./setup
install-deps as a throwaway builder, harvests the built packages into
/opt/localrepo so pacstrap resolves them offline
- image ships its own [local-aur] (file:///opt/localrepo); CI and
localrepo/update.sh keep that copy in sync; .gitignore covers work/,
out/ and airootfs/opt/localrepo/
- alvin-install runs ./setup install --skip-alldeps on the target
- clone pctrade/end4-pC into /etc/skel/.config/quickshell, patch qsConfig
ii -> end4-pC in the staged variables.lua (guarded + idempotent), and
restore the fork after setup rsync --delete's ~/.config/quickshell
- ship user presets in skel, point fish `q` alias at end4-pC
- AGENTS.md: document the fourth package source and new gotchas
pacstrap failed at line 382 because pkglist lines from pacman -Q are
'name version' and were passed whole as pacman targets (~400 'target
not found'). Parse only the first field, pre-filter against pacman -Slq
so packages missing from the live repos (local-aur) are skipped with a
warning, and fall back to an unfiltered list if pacman -Syy fails.
Keymap screen now offers a US-layout confirm before the gum filter.
- New gum-based installer script (alvin-install) with LUKS encryption,
nmtui networking, disk selector, user/git config, and CachyOS repo setup
- Replace NetworkManager full unit file with symlink for consistency
- Add alvin-install reference to MOTD
- Add file_permissions entry in profiledef.sh
- Fix localrepo path case in pacman.conf
These files exist in the airootfs overlay but are owned by packages
in packages.x86_64, causing 'exists in filesystem' errors during
mkarchiso pacman install:
- usr/lib/os-release (filesystem)
- usr/share/pacman/keyrings/cachyos-* (cachyos-keyring)
- etc/clamav/certs/clamav.crt (clamav)
- etc/skel/.zshrc (grml-zsh-config)