Compare commits
3
Commits
3b1e7d1982
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6f00018d4
|
||
|
|
e377f9313a
|
||
|
|
00c89f23f0
|
@@ -74,7 +74,7 @@ The airootfs overlay ships it as `/usr/local/bin/alvin-install` (mode `0755` for
|
|||||||
locale, login manager, sshd, summary) then a fixed order of `install_*` steps
|
locale, login manager, sshd, summary) then a fixed order of `install_*` steps
|
||||||
(partition → LUKS → format/mount → pacstrap → fstab → repos → timezone → locale →
|
(partition → LUKS → format/mount → pacstrap → fstab → repos → timezone → locale →
|
||||||
hostname → network → sshd → user → git/SSH → end-4 dots → mkinitcpio → bootloader →
|
hostname → network → sshd → user → git/SSH → end-4 dots → mkinitcpio → bootloader →
|
||||||
TPM/unl0kr → login manager → autologin → update (reflector + keyrings + `pacman -Syu`, warn-only) → cleanup). Screens and install steps are
|
TPM/unl0kr → login manager (none if unl0kr succeeded; with unl0kr selected the login screen only asks for a fallback) → autologin → update (reflector + keyrings + `pacman -Syu`, warn-only) → cleanup, which offers an optional `arch-chroot` shell into the target before unmounting; the `EXIT` trap offers the same shell when a step after pacstrap fails or the install is interrupted (INT/TERM re-exit with 128+N so signals count as failure). Screens and install steps are
|
||||||
independent — edit one without
|
independent — edit one without
|
||||||
touching the other. An `EXIT` trap unmounts `$TARGET` and closes `cryptroot` on any exit.
|
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
|
- **Package list**: `install_pacstrap` builds the *installed* system's list from the medium's
|
||||||
@@ -116,7 +116,7 @@ commit; CI remains the enforcer. Bypass it with `git commit --no-verify`.
|
|||||||
- The **image** ships its own `[local-aur]` at `file:///opt/localrepo` (see `.live-pacman.conf`). It holds `localrepo/` (copied by CI/`update.sh`) plus everything `install-deps` built. pacstrap runs without `-P`, so the target keeps the stock `/etc/pacman.conf`; `alvin-install` strips `[local-aur]` from it anyway as a safety net, because `/opt/localrepo` exists only on the medium.
|
- The **image** ships its own `[local-aur]` at `file:///opt/localrepo` (see `.live-pacman.conf`). It holds `localrepo/` (copied by CI/`update.sh`) plus everything `install-deps` built. pacstrap runs without `-P`, so the target keeps the stock `/etc/pacman.conf`; `alvin-install` strips `[local-aur]` from it anyway as a safety net, because `/opt/localrepo` exists only on the medium.
|
||||||
- `alvin-install` runs end-4 with `--skip-alldeps` — dependencies must come from the ISO. It feeds `yes i` to end-4's failure prompt: inside the installer chroot the medium's `/run` is bind-mounted in, so end-4's `systemctl --machine=…@.host --user enable … --now` lines can never work (and `--now` would start services on the live medium). `install_end4_dots` re-applies the enable-only part (bluetooth, ydotool, i2c module) outside the chroot and reports every step end-4 had to skip. If the end-4 step reports "incomplete", check that `hyprctl`/`quickshell`/the venv were resolvable (harvest) before re-running anything.
|
- `alvin-install` runs end-4 with `--skip-alldeps` — dependencies must come from the ISO. It feeds `yes i` to end-4's failure prompt: inside the installer chroot the medium's `/run` is bind-mounted in, so end-4's `systemctl --machine=…@.host --user enable … --now` lines can never work (and `--now` would start services on the live medium). `install_end4_dots` re-applies the enable-only part (bluetooth, ydotool, i2c module) outside the chroot and reports every step end-4 had to skip. If the end-4 step reports "incomplete", check that `hyprctl`/`quickshell`/the venv were resolvable (harvest) before re-running anything.
|
||||||
- `/etc/skel/.cache/uv` + `/etc/skel/.local/share/uv/python` are pre-warmed by the build (~460 MB: CPython 3.12 and the pinned wheel cache) so end-4's `uv venv`/`uv pip install` at install time needs no network.
|
- `/etc/skel/.cache/uv` + `/etc/skel/.local/share/uv/python` are pre-warmed by the build (~460 MB: CPython 3.12 and the pinned wheel cache) so end-4's `uv venv`/`uv pip install` at install time needs no network.
|
||||||
- **end4-pC** (`pctrade/end4-pC`) is the default quickshell config: cloned into `/etc/skel/.config/quickshell/end4-pC` at build time, selected by patching `hl.env("qsConfig", "ii")` → `"end4-pC"` in the **staged** `/opt/dots-hyprland/dots/.config/hypr/hyprland/variables.lua` (there is no `hypr/hyprland/` in this repo — `./setup install` copies it to the installed system). `alvin-install` re-copies end4-pC into the user's home *after* `./setup install`, because end-4's installer `rsync --delete`s all of `~/.config/quickshell`.
|
- **end4-pC** (`pctrade/end4-pC`) is the default quickshell config: cloned into `/etc/skel/.config/quickshell/end4-pC` at build time, selected by patching `hl.env("qsConfig", "ii")` → `"end4-pC"` in the **staged** `/opt/dots-hyprland/dots/.config/hypr/hyprland/variables.lua` (there is no `hypr/hyprland/` in this repo — `./setup install` copies it to the installed system). `alvin-install` re-copies end4-pC into the user's home *after* `./setup install`, because end-4's installer `rsync --delete`s all of `~/.config/quickshell`. The build also rewrites the fork's hard-coded `QUICKSHELL_CONFIG_NAME="ii"` in its colour/wallpaper/kvantum scripts to `end4-pC` (otherwise they act on `~/.config/quickshell/ii`), and overwrites its `assets/images/default_wallpaper.png` (applied by `FirstRunExperience.qml` on first login) with `airootfs/etc/skel/Pictures/Wallpapers/Dynamic-Wallpapers/Dark/japan-street-Dark.png`.
|
||||||
- `airootfs/etc/skel/.config/illogical-impulse/presets/` carries the user's presets (`Laptop.json`, `Personal-Performance.json`, `Personal-Performance.zip`). They embed `/home/alvin/...` paths, so wallpapers/screenshots need fixing up after install.
|
- `airootfs/etc/skel/.config/illogical-impulse/presets/` carries the user's presets (`Laptop.json`, `Personal-Performance.json`, `Personal-Performance.zip`). They embed `/home/alvin/...` paths, so wallpapers/screenshots need fixing up after install.
|
||||||
- End-4 metapackages are built from `localrepo/end4-pkgbuilds/` (quickshell-git, bibata-modern-classic-bin, microtex-git).
|
- End-4 metapackages are built from `localrepo/end4-pkgbuilds/` (quickshell-git, bibata-modern-classic-bin, microtex-git).
|
||||||
- **quickshell pin / Qt 6.12**: end-4 pins quickshell to `41651d7` (Sep 25), which predates upstream fix `5d5d498` (Oct 3, *"use MOC includes instead of opaque pointer definitions — … Qt 6.12 compatibility"*). Arch shipped qt6 6.12.0 on Oct 8 and the old pin died with `Meta Types must be fully defined` in the moc build of quickshell-hyprland-ipc (failed CI run 137). `customize_airootfs.sh` therefore rewrites end-4's `_commit` to `11ca60be` after cloning — but **only** while it still matches `^_commit='41651d7`, so once end-4 bumps their own pin the guard goes inert and theirs wins. `localrepo/check-quickshell-pin.sh` (weekly `pin-check.yaml` job) fails CI if either pin goes stale or loses the fix; it warns instead of failing when end-4's known-stale pin is covered by the override.
|
- **quickshell pin / Qt 6.12**: end-4 pins quickshell to `41651d7` (Sep 25), which predates upstream fix `5d5d498` (Oct 3, *"use MOC includes instead of opaque pointer definitions — … Qt 6.12 compatibility"*). Arch shipped qt6 6.12.0 on Oct 8 and the old pin died with `Meta Types must be fully defined` in the moc build of quickshell-hyprland-ipc (failed CI run 137). `customize_airootfs.sh` therefore rewrites end-4's `_commit` to `11ca60be` after cloning — but **only** while it still matches `^_commit='41651d7`, so once end-4 bumps their own pin the guard goes inert and theirs wins. `localrepo/check-quickshell-pin.sh` (weekly `pin-check.yaml` job) fails CI if either pin goes stale or loses the fix; it warns instead of failing when end-4's known-stale pin is covered by the override.
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 9.4 MiB |
@@ -134,6 +134,29 @@ if [[ ! -d "${SKEL}/.config/quickshell/end4-pC" ]]; then
|
|||||||
git clone --depth=1 https://github.com/pctrade/end4-pC.git \
|
git clone --depth=1 https://github.com/pctrade/end4-pC.git \
|
||||||
"${SKEL}/.config/quickshell/end4-pC"
|
"${SKEL}/.config/quickshell/end4-pC"
|
||||||
fi
|
fi
|
||||||
|
# The fork's colour/wallpaper/kvantum scripts still hard-code
|
||||||
|
# QUICKSHELL_CONFIG_NAME="ii", so they'd read and write ~/.config/quickshell/ii
|
||||||
|
# instead of end4-pC. Point them at the fork. Re-running is a no-op.
|
||||||
|
mapfile -t PC_II_SCRIPTS < <(grep -rl --exclude-dir=.git \
|
||||||
|
'^QUICKSHELL_CONFIG_NAME="ii"$' "${SKEL}/.config/quickshell/end4-pC" || true)
|
||||||
|
if (( ${#PC_II_SCRIPTS[@]} )); then
|
||||||
|
echo "[customize] Pointing ${#PC_II_SCRIPTS[@]} end4-pC scripts at end4-pC..."
|
||||||
|
sed -i 's/^QUICKSHELL_CONFIG_NAME="ii"$/QUICKSHELL_CONFIG_NAME="end4-pC"/' \
|
||||||
|
"${PC_II_SCRIPTS[@]}"
|
||||||
|
fi
|
||||||
|
# Default wallpaper: end4-pC's first run (services/FirstRunExperience.qml)
|
||||||
|
# feeds assets/images/default_wallpaper.png to switchwall.sh, so replace that
|
||||||
|
# image with the one shipped in skel's ~/Pictures/Wallpapers.
|
||||||
|
DEFAULT_WALL="${SKEL}/Pictures/Wallpapers/Dynamic-Wallpapers/Dark/japan-street-Dark.png"
|
||||||
|
PC_DEFAULT_WALL="${SKEL}/.config/quickshell/end4-pC/assets/images/default_wallpaper.png"
|
||||||
|
if [[ ! -f "${DEFAULT_WALL}" ]]; then
|
||||||
|
echo "[customize] Default wallpaper ${DEFAULT_WALL} is missing" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! cmp -s "${DEFAULT_WALL}" "${PC_DEFAULT_WALL}"; then
|
||||||
|
echo "[customize] Setting end4-pC default wallpaper to ${DEFAULT_WALL##*/}..."
|
||||||
|
install -Dm644 "${DEFAULT_WALL}" "${PC_DEFAULT_WALL}"
|
||||||
|
fi
|
||||||
|
|
||||||
# ── Default quickshell config: ii -> end4-pC ─────────────────────────────────
|
# ── Default quickshell config: ii -> end4-pC ─────────────────────────────────
|
||||||
# alvin-install copies this staged repo onto the target and runs `./setup
|
# alvin-install copies this staged repo onto the target and runs `./setup
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ GH_USERNAME=""
|
|||||||
UNL0KR="false"
|
UNL0KR="false"
|
||||||
TPM_STATUS=""
|
TPM_STATUS=""
|
||||||
LOGIN_MANAGER="none"
|
LOGIN_MANAGER="none"
|
||||||
|
# true when unl0kr was picked: no login manager is installed if unl0kr
|
||||||
|
# succeeds, and LOGIN_MANAGER only holds the fallback for when it doesn't.
|
||||||
|
LOGIN_MANAGER_SKIP="false"
|
||||||
AUTOLOGIN=""
|
AUTOLOGIN=""
|
||||||
# SSHD is the choice made on the sshd screen; SSHD_APPLIED is only flipped once
|
# SSHD is the choice made on the sshd screen; SSHD_APPLIED is only flipped once
|
||||||
# the target's sshd.service has actually been enabled, so the final banner can
|
# the target's sshd.service has actually been enabled, so the final banner can
|
||||||
@@ -40,20 +43,74 @@ SSHD_APPLIED="false"
|
|||||||
TPM_DISCLAIMER=""
|
TPM_DISCLAIMER=""
|
||||||
TARGET_DB_SYNCED="false"
|
TARGET_DB_SYNCED="false"
|
||||||
UPDATE_STATUS="not run"
|
UPDATE_STATUS="not run"
|
||||||
|
# Flipped once pacstrap succeeds: from then on a failed step still leaves a
|
||||||
|
# chroot-able system, so the EXIT trap offers a repair shell into it.
|
||||||
|
TARGET_INSTALLED="false"
|
||||||
|
# Teardown state: a signal arriving while cleanup() runs must not skip the
|
||||||
|
# unmount - the first one only aborts what is on screen, a second forces exit.
|
||||||
|
CLEANUP_RUNNING="false"
|
||||||
|
SIGNALS_SEEN="0"
|
||||||
|
|
||||||
log() { echo "[$(date '+%H:%M:%S')] $*" >>"$LOG"; }
|
log() { echo "[$(date '+%H:%M:%S')] $*" >>"$LOG"; }
|
||||||
|
|
||||||
cleanup() {
|
# Temporary NOPASSWD drop-ins some install steps create; never leave them
|
||||||
set +e
|
# behind (EXIT) or expose them to the user's post-install chroot shell.
|
||||||
|
remove_temp_sudoers() {
|
||||||
rm -f "${TARGET}/etc/sudoers.d/99-end4-install" \
|
rm -f "${TARGET}/etc/sudoers.d/99-end4-install" \
|
||||||
"${TARGET}/etc/sudoers.d/99-ssh-import-id" \
|
"${TARGET}/etc/sudoers.d/99-ssh-import-id" \
|
||||||
"${TARGET}/etc/sudoers.d/99-unl0kr-install" 2>/dev/null
|
"${TARGET}/etc/sudoers.d/99-unl0kr-install" 2>/dev/null || true
|
||||||
umount -R "$TARGET" 2>/dev/null
|
}
|
||||||
cryptsetup close cryptroot 2>/dev/null
|
|
||||||
|
cleanup() {
|
||||||
|
local rc=$?
|
||||||
|
CLEANUP_RUNNING="true"
|
||||||
|
set +e
|
||||||
|
trap - ERR
|
||||||
|
# A later step failed but the base system is on disk: let the user fix
|
||||||
|
# it from inside before everything is unmounted.
|
||||||
|
if ((rc != 0)) && [[ "$TARGET_INSTALLED" == "true" && -t 0 ]]; then
|
||||||
|
echo ""
|
||||||
|
warn "Installation failed after the base system was installed."
|
||||||
|
offer_chroot "The installed system is still mounted. Chroot into it to fix things?"
|
||||||
|
fi
|
||||||
|
remove_temp_sudoers
|
||||||
|
# A repair shell can leave mounts behind, and the LUKS mapping may still
|
||||||
|
# be open - report a failure instead of hiding it, so the user knows the
|
||||||
|
# target was not cleanly torn down before rebooting.
|
||||||
|
if mountpoint -q "$TARGET" 2>/dev/null; then
|
||||||
|
if ! umount -R "$TARGET"; then
|
||||||
|
log "Cleanup: umount -R $TARGET failed"
|
||||||
|
warn "Some mounts under ${TARGET} are busy - unmounting failed (released at reboot)."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ -e /dev/mapper/cryptroot ]] && ! cryptsetup close cryptroot 2>/dev/null; then
|
||||||
|
log "Cleanup: cryptsetup close cryptroot failed"
|
||||||
|
warn "cryptroot is still open - it is released at reboot."
|
||||||
|
fi
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
trap cleanup EXIT
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
# Signal handler. Without one, bash runs the EXIT trap with $? = 0 when the
|
||||||
|
# shell itself is killed (SIGINT between commands, SIGTERM from a shutdown),
|
||||||
|
# and cleanup()'s rc != 0 test would read that as success and skip the repair
|
||||||
|
# shell. Re-exit with the conventional 128+N status so an interrupted install
|
||||||
|
# takes the same path as a failed step. Note: a SIGINT delivered while a
|
||||||
|
# foreground command is running is consumed together with that command (bash
|
||||||
|
# then suppresses both errexit and this handler) - that case is unchanged.
|
||||||
|
on_signal() {
|
||||||
|
local status="$1"
|
||||||
|
if [[ "$CLEANUP_RUNNING" == "true" && "$SIGNALS_SEEN" == "0" ]]; then
|
||||||
|
SIGNALS_SEEN="1"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
echo "" >&2
|
||||||
|
echo "Interrupted." >&2
|
||||||
|
exit "$status"
|
||||||
|
}
|
||||||
|
trap 'on_signal 130' INT
|
||||||
|
trap 'on_signal 143' TERM
|
||||||
|
|
||||||
# ── error surfacing ───────────────────────────────────────────────────────────
|
# ── error surfacing ───────────────────────────────────────────────────────────
|
||||||
# Step output normally ends up in $LOG only. These helpers make sure a failure
|
# Step output normally ends up in $LOG only. These helpers make sure a failure
|
||||||
# is ALSO shown on screen, paged through `gum pager` so long outputs stay
|
# is ALSO shown on screen, paged through `gum pager` so long outputs stay
|
||||||
@@ -527,6 +584,11 @@ screen_locale() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
screen_login_manager() {
|
screen_login_manager() {
|
||||||
|
if [[ "$LUKS" == "true" && "$UNL0KR" == "true" ]]; then
|
||||||
|
screen_unl0kr_login
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
LOGIN_MANAGER_SKIP="false"
|
||||||
clear
|
clear
|
||||||
header "Login Manager"
|
header "Login Manager"
|
||||||
echo ""
|
echo ""
|
||||||
@@ -543,6 +605,33 @@ screen_login_manager() {
|
|||||||
log "Login manager: $LOGIN_MANAGER"
|
log "Login manager: $LOGIN_MANAGER"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# unl0kr already asks for the passphrase on screen at boot, so a login
|
||||||
|
# manager on top would be a second prompt. Skip it, but collect a fallback
|
||||||
|
# now: install_unl0kr can still fall back to the systemd initramfs, and the
|
||||||
|
# installer must not stop to ask mid-install.
|
||||||
|
screen_unl0kr_login() {
|
||||||
|
LOGIN_MANAGER_SKIP="true"
|
||||||
|
clear
|
||||||
|
header "Login Manager (unl0kr)"
|
||||||
|
echo ""
|
||||||
|
gum style --foreground 15 \
|
||||||
|
"unl0kr is selected, so no login manager will be installed:" \
|
||||||
|
"after the LUKS passphrase is entered with unl0kr, the system logs in on" \
|
||||||
|
"tty1 and Hyprland starts automatically (autologin is asked during install)." \
|
||||||
|
"" \
|
||||||
|
"If unl0kr fails to install, the installer falls back to the standard" \
|
||||||
|
"passphrase prompt. Pick the login manager to use in that case:" \
|
||||||
|
"" \
|
||||||
|
" none - plain tty login, Hyprland starts automatically" \
|
||||||
|
" greetd - lightweight TUI greeter (tuigreet)" \
|
||||||
|
" sddm - Qt display manager (already installed)" \
|
||||||
|
" gdm - GNOME display manager (large download)"
|
||||||
|
echo ""
|
||||||
|
LOGIN_MANAGER=$(gum choose --header "+ Fallback login manager (Enter = none)" \
|
||||||
|
"none" "greetd" "sddm" "gdm") || die "No fallback login manager selected."
|
||||||
|
log "Login manager: skipped for unl0kr (fallback: $LOGIN_MANAGER)"
|
||||||
|
}
|
||||||
|
|
||||||
screen_sshd() {
|
screen_sshd() {
|
||||||
clear
|
clear
|
||||||
header "SSH Server"
|
header "SSH Server"
|
||||||
@@ -592,6 +681,11 @@ screen_summary() {
|
|||||||
ssh_line="gh:${GH_USERNAME}"
|
ssh_line="gh:${GH_USERNAME}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
local login_line="${LOGIN_MANAGER}"
|
||||||
|
if [[ "$LOGIN_MANAGER_SKIP" == "true" ]]; then
|
||||||
|
login_line="none - unl0kr (fallback: ${LOGIN_MANAGER})"
|
||||||
|
fi
|
||||||
|
|
||||||
gum style --foreground 15 --border normal --border-foreground 8 \
|
gum style --foreground 15 --border normal --border-foreground 8 \
|
||||||
--padding "0 2" --width 60 \
|
--padding "0 2" --width 60 \
|
||||||
"Disk: ${DISK}" \
|
"Disk: ${DISK}" \
|
||||||
@@ -603,7 +697,7 @@ screen_summary() {
|
|||||||
"Keymap: ${KEYMAP}" \
|
"Keymap: ${KEYMAP}" \
|
||||||
"Locale: ${LOCALE}" \
|
"Locale: ${LOCALE}" \
|
||||||
"Timezone: ${TIMEZONE}" \
|
"Timezone: ${TIMEZONE}" \
|
||||||
"Login mgr: ${LOGIN_MANAGER}" \
|
"Login mgr: ${login_line}" \
|
||||||
"SSH server: $([[ "$SSHD" == "true" ]] && echo enabled || echo skipped)" \
|
"SSH server: $([[ "$SSHD" == "true" ]] && echo enabled || echo skipped)" \
|
||||||
"SSH keys: ${ssh_line}" \
|
"SSH keys: ${ssh_line}" \
|
||||||
"Git: ${git_line}"
|
"Git: ${git_line}"
|
||||||
@@ -771,6 +865,7 @@ install_pacstrap() {
|
|||||||
>>"$LOG" 2>&1 || warn "cert-sync failed - mono apps may reject TLS certificates."
|
>>"$LOG" 2>&1 || warn "cert-sync failed - mono apps may reject TLS certificates."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
TARGET_INSTALLED="true"
|
||||||
ok "Packages installed."
|
ok "Packages installed."
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1715,6 +1810,34 @@ install_unl0kr() {
|
|||||||
page_log_tail "unl0kr hook file output (q to quit)" 40 || true
|
page_log_tail "unl0kr hook file output (q to quit)" 40 || true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# unl0kr parses /usr/share/unl0kr/unl0kr.conf first; the package doesn't
|
||||||
|
# ship it, so inih fails to open it and unl0kr prints "Ignoring invalid
|
||||||
|
# config file" on every boot. An empty file parses cleanly - FILES+= puts
|
||||||
|
# it in the image (the hook only adds /etc/unl0kr.conf). Our own
|
||||||
|
# /etc/unl0kr.conf pins the dark theme instead of trusting the PKGBUILD's
|
||||||
|
# sed on the upstream (light) default.
|
||||||
|
mkdir -p "${TARGET}/usr/share/unl0kr"
|
||||||
|
: >"${TARGET}/usr/share/unl0kr/unl0kr.conf"
|
||||||
|
cat >"${TARGET}/etc/unl0kr.conf" <<'UNL0KR'
|
||||||
|
[general]
|
||||||
|
animations=true
|
||||||
|
|
||||||
|
[keyboard]
|
||||||
|
autohide=false
|
||||||
|
layout=us
|
||||||
|
popovers=true
|
||||||
|
|
||||||
|
[textarea]
|
||||||
|
obscured=true
|
||||||
|
|
||||||
|
[theme]
|
||||||
|
default=breezy-dark
|
||||||
|
alternate=breezy-light
|
||||||
|
UNL0KR
|
||||||
|
echo 'FILES+=(/usr/share/unl0kr/unl0kr.conf)' \
|
||||||
|
>>"${TARGET}/etc/mkinitcpio.conf.d/alvin.conf"
|
||||||
|
log "unl0kr: wrote /etc/unl0kr.conf (breezy-dark) + empty /usr/share/unl0kr/unl0kr.conf"
|
||||||
|
|
||||||
# Touchscreen/input stack for the initramfs: mkinitcpio fails the build
|
# Touchscreen/input stack for the initramfs: mkinitcpio fails the build
|
||||||
# on a MODULES entry it cannot resolve, and -P applies the list to every
|
# on a MODULES entry it cannot resolve, and -P applies the list to every
|
||||||
# preset - so a module may enter MODULES only if EVERY installed kernel
|
# preset - so a module may enter MODULES only if EVERY installed kernel
|
||||||
@@ -1904,6 +2027,21 @@ FISH
|
|||||||
log "tty profile: ${profile} (exec Hyprland on VT1)"
|
log "tty profile: ${profile} (exec Hyprland on VT1)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Runs after install_unl0kr, which resets UNL0KR to false when it falls
|
||||||
|
# back to the systemd initramfs - so UNL0KR still being true here means
|
||||||
|
# unl0kr really is in the image and no login manager is wanted.
|
||||||
|
resolve_login_manager() {
|
||||||
|
[[ "$LOGIN_MANAGER_SKIP" == "true" ]] || return 0
|
||||||
|
if [[ "$UNL0KR" == "true" ]]; then
|
||||||
|
LOGIN_MANAGER="none"
|
||||||
|
info "unl0kr is installed - skipping the login manager (tty1 + Hyprland)."
|
||||||
|
log "Login manager: none (unl0kr installed)"
|
||||||
|
else
|
||||||
|
warn "unl0kr fell back - using the fallback login manager: ${LOGIN_MANAGER}."
|
||||||
|
log "Login manager: fallback ${LOGIN_MANAGER} (unl0kr not installed)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
install_login_manager() {
|
install_login_manager() {
|
||||||
info "Configuring login manager: ${LOGIN_MANAGER}..."
|
info "Configuring login manager: ${LOGIN_MANAGER}..."
|
||||||
|
|
||||||
@@ -2009,6 +2147,19 @@ TOML
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
ensure_hyprland_session
|
ensure_hyprland_session
|
||||||
|
# gdm (autologin included) starts the session stored in the user's
|
||||||
|
# AccountsService record; without one it picks gnome.desktop, which
|
||||||
|
# the gdm install drags in. Pin Hyprland.
|
||||||
|
local as_dir="${TARGET}/var/lib/AccountsService/users"
|
||||||
|
mkdir -p "$as_dir"
|
||||||
|
cat >"${as_dir}/${USERNAME}" <<'ACCOUNT'
|
||||||
|
[User]
|
||||||
|
Session=hyprland
|
||||||
|
SessionType=wayland
|
||||||
|
SystemAccount=false
|
||||||
|
ACCOUNT
|
||||||
|
chmod 600 "${as_dir}/${USERNAME}"
|
||||||
|
log "gdm: AccountsService session pinned to hyprland"
|
||||||
if run_logged "Could not enable gdm.service" \
|
if run_logged "Could not enable gdm.service" \
|
||||||
arch-chroot "$TARGET" systemctl enable gdm.service; then
|
arch-chroot "$TARGET" systemctl enable gdm.service; then
|
||||||
run_logged "Could not disable getty@tty1.service" \
|
run_logged "Could not disable getty@tty1.service" \
|
||||||
@@ -2241,11 +2392,33 @@ install_cleanup() {
|
|||||||
gum pager <"$LOG" || true
|
gum pager <"$LOG" || true
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
offer_chroot
|
||||||
# Last line on screen after the optional log view - the instruction to
|
# Last line on screen after the optional log view - the instruction to
|
||||||
# reboot must be the final thing the user reads.
|
# reboot must be the final thing the user reads.
|
||||||
echo "Run 'reboot' to boot into your new system."
|
echo "Run 'reboot' to boot into your new system."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Optional shell inside the installed system. $TARGET (and cryptroot) are
|
||||||
|
# still mounted here - cleanup() only tears them down afterwards.
|
||||||
|
# Also called from the EXIT trap when a step after pacstrap failed ($1 then
|
||||||
|
# carries the failure prompt).
|
||||||
|
offer_chroot() {
|
||||||
|
gum confirm --affirmative "Open chroot" --negative "No thanks" \
|
||||||
|
"${1:-Chroot into the installed system to make changes before rebooting?}" ||
|
||||||
|
return 0
|
||||||
|
remove_temp_sudoers
|
||||||
|
# Copy first so the log is readable from inside (/var/log/alvin-install.log).
|
||||||
|
cp "$LOG" "${TARGET}/var/log/alvin-install.log" 2>/dev/null || true
|
||||||
|
info "Entering ${TARGET} - type 'exit' to leave and finish."
|
||||||
|
log "Chroot: interactive shell opened"
|
||||||
|
# The user's last command may fail; that must not trip errexit/ERR.
|
||||||
|
arch-chroot "$TARGET" /bin/bash || true
|
||||||
|
log "Chroot: shell closed"
|
||||||
|
# Keep the copy in the target current with the lines logged above.
|
||||||
|
cp "$LOG" "${TARGET}/var/log/alvin-install.log" 2>/dev/null || true
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
# ── Main ──────────────────────────────────────────────────────────────────────
|
# ── Main ──────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
@@ -2286,6 +2459,7 @@ main() {
|
|||||||
install_bootloader
|
install_bootloader
|
||||||
install_tpm
|
install_tpm
|
||||||
install_unl0kr
|
install_unl0kr
|
||||||
|
resolve_login_manager
|
||||||
install_login_manager
|
install_login_manager
|
||||||
install_autologin
|
install_autologin
|
||||||
install_update
|
install_update
|
||||||
|
|||||||
Reference in New Issue
Block a user