diff --git a/setup/arch-autoinstall.sh b/setup/arch-autoinstall.sh index 6f4a164..bd40c47 100755 --- a/setup/arch-autoinstall.sh +++ b/setup/arch-autoinstall.sh @@ -207,6 +207,26 @@ fi ############################################ # REQUIRED PACKAGES FOR INSTALL ENVIRONMENT ############################################ +# Wait for the live ISO's keyring initialization before any install. archiso +# initializes the pacman keyring asynchronously at boot via pacman-init.service +# (master-key generation can take a minute+ in VMs with little entropy), and +# this installer autostarts at login — racing that service leaves keys +# unpopulated/untrusted, so every package fails with "signature is unknown +# trust" / "invalid or corrupted package (PGP signature)". Do NOT run +# pacman-key --init ourselves here: doing so concurrently with +# pacman-init.service corrupts the half-built keyring. Wait, then refresh +# archlinux-keyring so an ISO built weeks ago still trusts current packager keys. +if systemctl cat pacman-init.service &>/dev/null; then + echo "Waiting for pacman keyring initialization (pacman-init.service)..." + while [[ "$(systemctl is-active pacman-init.service 2>/dev/null)" == "activating" ]]; do + sleep 2 + done +else + # Not on archiso (e.g. re-run from an installed system) — ensure a keyring exists. + [[ -d /etc/pacman.d/gnupg ]] || { pacman-key --init; pacman-key --populate archlinux; } +fi +pacman -Sy --noconfirm archlinux-keyring + # Install tools needed by this script into the live environment before partitioning: # parted — disk partitioning; cryptsetup — LUKS; libfido2/pam-u2f — FIDO2 enrollment. pacman -Sy --noconfirm parted cryptsetup libfido2 pam-u2f @@ -589,6 +609,14 @@ sed -i "s|^GRUB_CMDLINE_LINUX=.*|GRUB_CMDLINE_LINUX=\"$KERNEL_CMD\"|" /etc/defau # Install GRUB to the EFI partition; --bootloader-id sets the NVRAM entry name. grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=M-Archy-GRUB +# Also install to the UEFI removable-media fallback path (/EFI/BOOT/BOOTX64.EFI). +# The --bootloader-id install above only creates an NVRAM boot variable; a machine +# whose NVRAM is empty or gets cleared (fresh board, CMOS reset, firmware that +# drops stale entries, or — critically for this imaging/netboot installer — a disk +# cloned or redeployed to different hardware) then has "No bootable device". The +# removable fallback is what firmware boots when no NVRAM entry matches, so it makes +# the installed disk portable and self-booting regardless of NVRAM state. +grub-install --target=x86_64-efi --efi-directory=/boot --removable # Generate grub.cfg from /etc/default/grub and detected kernels. grub-mkconfig -o /boot/grub/grub.cfg diff --git a/setup/archbaseos-guided-install.sh b/setup/archbaseos-guided-install.sh index 2ba2f6f..241e151 100755 --- a/setup/archbaseos-guided-install.sh +++ b/setup/archbaseos-guided-install.sh @@ -255,17 +255,27 @@ else DRIVE=$(ask "Enter install drive (e.g., /dev/sda)") fi -# ── Passwords (always interactive; shown in clear text, each entered twice) ──── -# Never read from the answerfile. Captured once here and reused everywhere so the -# operator is never prompted for them again mid-install. -USERPASS=$(ask_password "Password for $USERNAME") +# ── Passwords ─────────────────────────────────────────────────────────────── +# In answerfile mode, honor a password embedded by the operator (needed for +# truly unattended netboot/WDS deployments where no one is at the console); +# otherwise fall back to the interactive prompt. Captured once here and reused +# everywhere so the operator is never prompted for them again mid-install. +if $AF_MODE && [[ -n "$(af_get '.password')" ]]; then + USERPASS=$(af_get '.password') +else + USERPASS=$(ask_password "Password for $USERNAME") +fi # LUKS passphrase — only needed when encrypting. Reused below for luksFormat / # open / luksAddKey / cryptenroll so it is typed exactly once (plus confirmation), # never again during the destructive phase. LUKS_PASS="" if [[ "$ENCRYPT_DISK" == "YES" ]]; then - LUKS_PASS=$(ask_password "Disk encryption (LUKS) passphrase") + if $AF_MODE && [[ -n "$(af_get '.luks_password')" ]]; then + LUKS_PASS=$(af_get '.luks_password') + else + LUKS_PASS=$(ask_password "Disk encryption (LUKS) passphrase") + fi fi # ── Final confirmation ──────────────────────────────────────────────────────── @@ -295,6 +305,26 @@ else [[ "$_final_ans" == "YES" ]] || { echo "Aborted."; exit 1; } fi +# Wait for the live ISO's keyring initialization before any install. archiso +# initializes the pacman keyring asynchronously at boot via pacman-init.service +# (master-key generation can take a minute+ in VMs with little entropy), and +# this installer autostarts at login — racing that service leaves keys +# unpopulated/untrusted, so every package fails with "signature is unknown +# trust" / "invalid or corrupted package (PGP signature)". Do NOT run +# pacman-key --init ourselves here: doing so concurrently with +# pacman-init.service corrupts the half-built keyring. Wait, then refresh +# archlinux-keyring so an ISO built weeks ago still trusts current packager keys. +if systemctl cat pacman-init.service &>/dev/null; then + echo "Waiting for pacman keyring initialization (pacman-init.service)..." + while [[ "$(systemctl is-active pacman-init.service 2>/dev/null)" == "activating" ]]; do + sleep 2 + done +else + # Not on archiso (e.g. re-run from an installed system) — ensure a keyring exists. + [[ -d /etc/pacman.d/gnupg ]] || { pacman-key --init; pacman-key --populate archlinux; } +fi +pacman -Sy --noconfirm archlinux-keyring + # Required packages — installed into the live environment before partitioning. # -d skips full dependency resolution for speed (these are standalone tools). # systemd-ukify included for Unified Kernel Image support if needed post-install. @@ -579,6 +609,13 @@ sed -i "s|^GRUB_CMDLINE_LINUX=.*|GRUB_CMDLINE_LINUX=\"$GRUB_CMDLINE\"|" /etc/def # Install GRUB to the EFI partition; --bootloader-id names the NVRAM/EFI menu entry. grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB +# Also install to the UEFI removable-media fallback path (/EFI/BOOT/BOOTX64.EFI). +# The --bootloader-id install above only creates an NVRAM boot variable; a machine +# whose NVRAM is empty or gets cleared (fresh board, CMOS reset, firmware that drops +# stale entries, or a disk cloned/redeployed to different hardware) then has "No +# bootable device". The removable fallback is what firmware boots when no NVRAM entry +# matches, making the installed disk portable and self-booting regardless of NVRAM. +grub-install --target=x86_64-efi --efi-directory=/boot --removable # Generate grub.cfg from /etc/default/grub and discovered kernels/initramfs images. grub-mkconfig -o /boot/grub/grub.cfg diff --git a/setup/archiso/build.sh b/setup/archiso/build.sh index 4b93d0e..fcdbdde 100755 --- a/setup/archiso/build.sh +++ b/setup/archiso/build.sh @@ -132,7 +132,11 @@ fi # ── Clean and create working directories ───────────────────────────────────── # Remove any previous build artifacts to ensure a clean, reproducible build. # mkarchiso can behave unexpectedly if the profile or work directory has stale state. -rm -rf "$WORK_DIR" +# Use sudo: mkarchiso runs as root below and leaves root-owned files in WORK_DIR +# if a prior build was interrupted before its own end-of-script chown; a plain +# `rm -rf` would then fail on those files and (under set -e) abort the script +# before mkarchiso ever runs. +sudo rm -rf "$WORK_DIR" mkdir -p "$WORK_DIR" "$OUT_DIR" # ── Assemble the profile from releng + M-Archy overlay ───────────────────────