feat(installer): global flatpaks, drop redundant TUI hostname, upfront passwords
- Flatpaks now install globally again: ensure_flatpak adds the Flathub remote at --system and all 19 app modules use `sudo flatpak install --system`. Running via sudo (root) performs the system op directly, avoiding the SystemHelper/ polkit D-Bus path that caused "The name is not activatable" for non-root users. - tui-install.sh no longer prompts for or sets the hostname — the base installer already configures it. Removed the Hostname section, the MAC-suffix helper, the AF_HOSTNAME field and the summary line. - archbaseos-guided-install.sh now gathers ALL input up front, including passwords. New ask_password() prompts in clear text (by request) and requires a confirmation entry, looping until the two match — so each password is typed exactly twice and never again. The LUKS passphrase is captured once and fed to luksFormat/open/luksAddKey (--key-file=-) and cryptenroll ($PASSWORD), instead of cryptsetup prompting repeatedly. After all input, a single all-caps "type YES" gate replaces the old per-step confirmations (answerfile mode keeps its 5-second abort window). The run-TUI choice is also asked up front. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>main
parent
9107b9961a
commit
bc13de7508
|
|
@ -55,11 +55,27 @@ trap 'error_handler $LINENO' ERR
|
|||
# Helper Functions
|
||||
############################################
|
||||
|
||||
confirm() {
|
||||
# Require the exact string "YES" before erasing $1 — prevents accidental wipes.
|
||||
echo "WARNING: This will ERASE ALL DATA on $1"
|
||||
read -rp "Type YES to continue: " ans
|
||||
[[ $ans == "YES" ]]
|
||||
ask_password() {
|
||||
# Prompt for a password and confirm it — BOTH shown in clear text (by request).
|
||||
# Loops until the two entries are identical and non-empty, so a typo can't
|
||||
# silently lock the operator out. The password is therefore typed exactly
|
||||
# twice (once + confirmation) and never again. The result is printed to stdout
|
||||
# for capture via $(...); the prompts and error messages go to stderr so they
|
||||
# never pollute the captured value.
|
||||
local label=$1 _p1 _p2
|
||||
while true; do
|
||||
read -rp "$label: " _p1
|
||||
if [[ -z "$_p1" ]]; then
|
||||
echo " Password cannot be empty — try again." >&2
|
||||
continue
|
||||
fi
|
||||
read -rp "$label (confirm): " _p2
|
||||
if [[ "$_p1" == "$_p2" ]]; then
|
||||
printf '%s' "$_p1"
|
||||
return 0
|
||||
fi
|
||||
echo " Passwords do not match — try again." >&2
|
||||
done
|
||||
}
|
||||
|
||||
ask() {
|
||||
|
|
@ -157,8 +173,13 @@ KEYMAPS=(
|
|||
)
|
||||
|
||||
############################################
|
||||
# User input
|
||||
# User input — gather EVERYTHING up front
|
||||
############################################
|
||||
# All operator input (including passwords) is collected here, before any
|
||||
# destructive action runs. Passwords are shown in clear text by request and are
|
||||
# each entered twice (once + confirmation) so a typo can't silently lock you out.
|
||||
# After this block the only remaining interaction is the single final "type YES"
|
||||
# gate plus any physical FIDO2 key taps.
|
||||
if $AF_MODE; then
|
||||
KERNEL=$(af_get '.kernel' 'linux')
|
||||
RAW_HOSTNAME=$(af_get '.hostname' '')
|
||||
|
|
@ -209,24 +230,62 @@ else
|
|||
# Out-of-range input silently falls back to the first entry (us).
|
||||
KEYMAP="${KEYMAPS[0]%%|*}"
|
||||
fi
|
||||
|
||||
# Whether to run the dotfiles TUI inside the chroot — asked now so the whole
|
||||
# back half of the install can proceed without further interaction.
|
||||
read -rp "Run dotfiles TUI setup inside chroot after base install? [YES/no]: " _TUI_IN
|
||||
_TUI_IN="${_TUI_IN:-YES}"
|
||||
[[ "${_TUI_IN^^}" == "YES" ]] && RUN_TUI="YES" || RUN_TUI="NO"
|
||||
fi
|
||||
|
||||
# Password always prompted interactively — never stored in the answerfile.
|
||||
read -rp "Password for $USERNAME: " USERPASS
|
||||
[[ -z "$USERPASS" ]] && { echo "Error: password cannot be empty."; exit 1; }
|
||||
|
||||
# Print block device layout so the operator can visually confirm the target drive.
|
||||
# ── Target drive ──────────────────────────────────────────────────────────────
|
||||
# Print the block device layout so the operator can identify the correct disk.
|
||||
lsblk
|
||||
|
||||
if $AF_MODE && [[ -n "$(af_get '.drive')" ]]; then
|
||||
DRIVE=$(af_get '.drive')
|
||||
echo "Drive (from answerfile): $DRIVE"
|
||||
echo "WARNING: All data on $DRIVE will be erased. Proceeding in 5 seconds..."
|
||||
# Give the operator a 5-second window to abort with Ctrl-C before destructive ops.
|
||||
sleep 5
|
||||
else
|
||||
DRIVE=$(ask "Enter install drive (e.g., /dev/sda)")
|
||||
confirm "$DRIVE" || exit 1
|
||||
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")
|
||||
|
||||
# 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")
|
||||
fi
|
||||
|
||||
# ── Final confirmation ────────────────────────────────────────────────────────
|
||||
# A single gate before anything destructive happens. Summarise the choices so the
|
||||
# operator can sanity-check them, then require one explicit all-caps YES.
|
||||
echo ""
|
||||
echo "──────────────────────────────────────────────"
|
||||
echo " Review your selections:"
|
||||
echo " Kernel: $KERNEL"
|
||||
echo " Hostname: $HOSTNAME"
|
||||
echo " Username: $USERNAME"
|
||||
echo " Keymap: $KEYMAP"
|
||||
echo " Encrypt disk: $ENCRYPT_DISK"
|
||||
echo " FIDO2 root: $ENABLE_FIDO_ROOT"
|
||||
echo " FIDO2 user: $ENABLE_FIDO_USER"
|
||||
echo " Run TUI: $RUN_TUI"
|
||||
echo " Target drive: $DRIVE"
|
||||
echo "──────────────────────────────────────────────"
|
||||
echo " WARNING: ALL DATA on $DRIVE will be PERMANENTLY ERASED."
|
||||
echo ""
|
||||
if $AF_MODE; then
|
||||
# Unattended deployment: no human to type YES — give a short abort window.
|
||||
echo "Answerfile mode — proceeding in 5 seconds (Ctrl-C to abort)..."
|
||||
sleep 5
|
||||
else
|
||||
read -rp "Type YES (all caps) to begin installation: " _final_ans
|
||||
[[ "$_final_ans" == "YES" ]] || { echo "Aborted."; exit 1; }
|
||||
fi
|
||||
|
||||
# Required packages — installed into the live environment before partitioning.
|
||||
|
|
@ -285,9 +344,11 @@ LUKS_BACKUP_KEY=""
|
|||
if [[ "$ENCRYPT_DISK" == "YES" ]]; then
|
||||
echo "Formatting LUKS2 root..."
|
||||
# --type luks2 uses the newer LUKS2 format required by systemd-cryptenroll for FIDO2.
|
||||
cryptsetup luksFormat "$ROOT_PART" --type luks2
|
||||
# Feed the pre-gathered passphrase on stdin (--key-file=-) and --batch-mode to
|
||||
# skip cryptsetup's own interactive "type uppercase YES" + passphrase prompts.
|
||||
printf '%s' "$LUKS_PASS" | cryptsetup luksFormat "$ROOT_PART" --type luks2 --batch-mode --key-file=-
|
||||
# Open (decrypt) the container; exposes it as /dev/mapper/cryptroot for formatting.
|
||||
cryptsetup open "$ROOT_PART" cryptroot
|
||||
printf '%s' "$LUKS_PASS" | cryptsetup open "$ROOT_PART" cryptroot --key-file=-
|
||||
|
||||
# ── Auto-generate backup LUKS key ─────────────────────────────────────────
|
||||
# A random key enrolled in a second LUKS slot enables recovery without
|
||||
|
|
@ -297,8 +358,9 @@ if [[ "$ENCRYPT_DISK" == "YES" ]]; then
|
|||
# Read 64 bytes of entropy; base64-encode with -w0 to disable line wrapping.
|
||||
dd if=/dev/urandom bs=64 count=1 2>/dev/null | base64 -w0 > "$LUKS_BACKUP_KEY"
|
||||
echo "Enrolling auto-generated backup LUKS key..."
|
||||
# luksAddKey prompts for the existing passphrase to authorise adding the new key file.
|
||||
cryptsetup luksAddKey "$ROOT_PART" "$LUKS_BACKUP_KEY"
|
||||
# --key-file=- supplies the EXISTING passphrase (on stdin) to authorise the
|
||||
# operation; the positional file is the NEW backup key added to a second slot.
|
||||
printf '%s' "$LUKS_PASS" | cryptsetup luksAddKey "$ROOT_PART" "$LUKS_BACKUP_KEY" --key-file=-
|
||||
|
||||
if [[ "$ENABLE_FIDO_ROOT" == "YES" ]]; then
|
||||
echo "Enroll FIDO2 key for LUKS2"
|
||||
|
|
@ -306,7 +368,9 @@ if [[ "$ENCRYPT_DISK" == "YES" ]]; then
|
|||
pause
|
||||
# systemd-cryptenroll writes the FIDO2 credential into a LUKS2 token slot.
|
||||
# --fido2-with-client-pin=no: presence tap only, no PIN required at boot.
|
||||
systemd-cryptenroll "$ROOT_PART" --fido2-device=auto --fido2-with-client-pin=no
|
||||
# $PASSWORD supplies the existing passphrase to unlock a slot for enrollment,
|
||||
# so only the physical key tap remains interactive here.
|
||||
PASSWORD="$LUKS_PASS" systemd-cryptenroll "$ROOT_PART" --fido2-device=auto --fido2-with-client-pin=no
|
||||
fi
|
||||
|
||||
# Format btrfs on the decrypted mapper device, not the raw partition.
|
||||
|
|
@ -540,15 +604,9 @@ fi
|
|||
############################################
|
||||
# DOTFILES SETUP (in-chroot, optional)
|
||||
############################################
|
||||
if $AF_MODE; then
|
||||
# RUN_TUI was already populated from the answerfile earlier.
|
||||
# RUN_TUI was gathered up front (answerfile field or the initial prompt), so no
|
||||
# additional interaction is needed at this point.
|
||||
_DO_TUI="${RUN_TUI}"
|
||||
else
|
||||
read -rp "Run dotfiles TUI setup inside chroot now? [YES/no]: " _TUI_IN
|
||||
# Default to YES when the user presses Enter without typing anything.
|
||||
_TUI_IN="${_TUI_IN:-YES}"
|
||||
[[ "${_TUI_IN^^}" == "YES" ]] && _DO_TUI="YES" || _DO_TUI="NO"
|
||||
fi
|
||||
|
||||
if [[ "${_DO_TUI^^}" == "YES" ]]; then
|
||||
# Grant temporary passwordless sudo so the TUI installer can call pacman/yay
|
||||
|
|
|
|||
|
|
@ -58,15 +58,15 @@ ensure_flatpak() {
|
|||
log "Installing flatpak..."
|
||||
sudo pacman -S --noconfirm --needed flatpak
|
||||
fi
|
||||
# Add the Flathub remote at --user scope. A system-scope remote (and the
|
||||
# matching `flatpak install` below) needs the org.freedesktop.Flatpak
|
||||
# SystemHelper D-Bus service + polkit, which are not activatable in a chroot
|
||||
# or bare-TTY install — that is the "The name is not activatable" failure.
|
||||
# User scope needs neither, so it works during install and is the right place
|
||||
# for per-user app installs anyway (apply_flatpak_theme already uses --user).
|
||||
if ! flatpak remotes --user 2>/dev/null | grep -q flathub; then
|
||||
log "Adding Flathub remote (user)..."
|
||||
flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
# Add the Flathub remote at --system scope (global install for all users).
|
||||
# A non-root user requesting a system action triggers the
|
||||
# org.freedesktop.Flatpak SystemHelper over D-Bus + polkit, which is not
|
||||
# activatable in a chroot/bare-TTY install — the "The name is not activatable"
|
||||
# failure. Running via sudo (as root) performs the system operation directly,
|
||||
# so no helper/polkit is involved and global installs work during setup.
|
||||
if ! flatpak remotes --system 2>/dev/null | grep -q flathub; then
|
||||
log "Adding Flathub remote (system)..."
|
||||
sudo flatpak remote-add --system --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ ensure_flatpak
|
|||
|
||||
# Install Ardour from the Flathub repository.
|
||||
# -y skips the interactive confirmation prompt so the script is non-interactive.
|
||||
flatpak install --user -y flathub org.ardour.Ardour
|
||||
sudo flatpak install --system -y flathub org.ardour.Ardour
|
||||
|
||||
# apply_flatpak_theme: applies the cyberqueer GTK theme override so Ardour's
|
||||
# GTK widgets match the rest of the desktop, rather than using the Flatpak
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ log "Installing Audacity (Flatpak)..."
|
|||
ensure_flatpak
|
||||
|
||||
# Install from Flathub. -y suppresses the interactive confirmation.
|
||||
flatpak install --user -y flathub org.audacityteam.Audacity
|
||||
sudo flatpak install --system -y flathub org.audacityteam.Audacity
|
||||
|
||||
# apply_flatpak_theme: injects the cyberqueer GTK theme into Audacity's
|
||||
# Flatpak environment so it renders consistently with the rest of the desktop.
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ ensure_flatpak
|
|||
# Install Blender from Flathub. The Flatpak edition ships its own Python,
|
||||
# CUDA/HIP compute libraries, and codec support pre-bundled, avoiding
|
||||
# dependency conflicts with the system Python or GPU driver packages.
|
||||
flatpak install --user -y flathub org.blender.Blender
|
||||
sudo flatpak install --system -y flathub org.blender.Blender
|
||||
|
||||
# apply_flatpak_theme: sets the cyberqueer GTK theme for Blender's dialogs
|
||||
# (the main 3D viewport uses its own renderer, but file choosers and system
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ log "Installing Chromium (Flatpak)..."
|
|||
ensure_flatpak
|
||||
|
||||
# Install Chromium from Flathub. -y skips the confirmation prompt.
|
||||
flatpak install --user -y flathub org.chromium.Chromium
|
||||
sudo flatpak install --system -y flathub org.chromium.Chromium
|
||||
|
||||
# apply_flatpak_theme: applies the cyberqueer GTK theme so Chromium's file
|
||||
# dialogs and context menus match the rest of the desktop.
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ log "Installing Firefox (Flatpak)..."
|
|||
ensure_flatpak
|
||||
|
||||
# Install from Flathub. -y skips interactive confirmation.
|
||||
flatpak install --user -y flathub org.mozilla.firefox
|
||||
sudo flatpak install --system -y flathub org.mozilla.firefox
|
||||
|
||||
# apply_flatpak_theme: injects the cyberqueer GTK theme so Firefox's native
|
||||
# file-open dialogs and context menus match the rest of the desktop.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/logging.sh"
|
|||
|
||||
log "Installing Obsidian (Flatpak)..."
|
||||
ensure_flatpak
|
||||
flatpak install --user -y flathub md.obsidian.Obsidian
|
||||
sudo flatpak install --system -y flathub md.obsidian.Obsidian
|
||||
apply_flatpak_theme "md.obsidian.Obsidian"
|
||||
|
||||
log "Obsidian installed."
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@ log "Installing PrismLauncher (Flatpak)..."
|
|||
# PrismLauncher is a Minecraft launcher that manages multiple instances and Java versions.
|
||||
# The Flatpak edition bundles its own Java runtimes, avoiding system JDK conflicts.
|
||||
# -y: non-interactive, auto-approve all prompts.
|
||||
flatpak install --user -y flathub org.prismlauncher.PrismLauncher
|
||||
sudo flatpak install --system -y flathub org.prismlauncher.PrismLauncher
|
||||
apply_flatpak_theme "org.prismlauncher.PrismLauncher"
|
||||
log "PrismLauncher installed."
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/logging.sh"
|
|||
|
||||
log "Installing Remmina (Flatpak)..."
|
||||
ensure_flatpak
|
||||
flatpak install --user -y flathub org.remmina.Remmina
|
||||
sudo flatpak install --system -y flathub org.remmina.Remmina
|
||||
apply_flatpak_theme "org.remmina.Remmina"
|
||||
log "Remmina installed."
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/logging.sh"
|
|||
|
||||
log "Installing Rnote (Flatpak)..."
|
||||
ensure_flatpak
|
||||
flatpak install --user -y flathub com.github.flxzt.rnote
|
||||
sudo flatpak install --system -y flathub com.github.flxzt.rnote
|
||||
apply_flatpak_theme "com.github.flxzt.rnote"
|
||||
|
||||
log "Rnote installed."
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/logging.sh"
|
|||
|
||||
log "Installing Shotcut (Flatpak)..."
|
||||
ensure_flatpak
|
||||
flatpak install --user -y flathub org.shotcut.Shotcut
|
||||
sudo flatpak install --system -y flathub org.shotcut.Shotcut
|
||||
apply_flatpak_theme "org.shotcut.Shotcut"
|
||||
log "Shotcut installed."
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/logging.sh"
|
|||
|
||||
log "Installing Steam (Flatpak)..."
|
||||
ensure_flatpak
|
||||
flatpak install --user -y flathub com.valvesoftware.Steam
|
||||
sudo flatpak install --system -y flathub com.valvesoftware.Steam
|
||||
apply_flatpak_theme "com.valvesoftware.Steam"
|
||||
log "Steam installed."
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/logging.sh"
|
|||
|
||||
log "Installing Stunt Rally (Flatpak)..."
|
||||
ensure_flatpak
|
||||
flatpak install --user -y flathub io.github.stuntrally.StuntRally3
|
||||
sudo flatpak install --system -y flathub io.github.stuntrally.StuntRally3
|
||||
apply_flatpak_theme "io.github.stuntrally.StuntRally3"
|
||||
log "Stunt Rally installed."
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/logging.sh"
|
|||
|
||||
log "Installing Tangent Notes (Flatpak)..."
|
||||
ensure_flatpak
|
||||
flatpak install --user -y flathub io.github.suchnsuch.Tangent
|
||||
sudo flatpak install --system -y flathub io.github.suchnsuch.Tangent
|
||||
apply_flatpak_theme "io.github.suchnsuch.Tangent"
|
||||
|
||||
log "Tangent Notes installed."
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/logging.sh"
|
|||
|
||||
log "Installing Vesktop (Flatpak)..."
|
||||
ensure_flatpak
|
||||
flatpak install --user -y flathub dev.vencord.Vesktop
|
||||
sudo flatpak install --system -y flathub dev.vencord.Vesktop
|
||||
apply_flatpak_theme "dev.vencord.Vesktop"
|
||||
|
||||
log "Deploying Vencord config..."
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/logging.sh"
|
|||
|
||||
log "Installing VSCodium (Flatpak)..."
|
||||
ensure_flatpak
|
||||
flatpak install --user -y flathub com.vscodium.codium
|
||||
sudo flatpak install --system -y flathub com.vscodium.codium
|
||||
apply_flatpak_theme "com.vscodium.codium"
|
||||
log "VSCodium installed."
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/logging.sh"
|
|||
|
||||
log "Installing Wireshark (Flatpak)..."
|
||||
ensure_flatpak
|
||||
flatpak install --user -y flathub org.wireshark.Wireshark
|
||||
sudo flatpak install --system -y flathub org.wireshark.Wireshark
|
||||
apply_flatpak_theme "org.wireshark.Wireshark"
|
||||
log "Wireshark installed."
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/logging.sh"
|
|||
|
||||
log "Installing Xournal++ (Flatpak)..."
|
||||
ensure_flatpak
|
||||
flatpak install --user -y flathub com.github.xournalpp.xournalpp
|
||||
sudo flatpak install --system -y flathub com.github.xournalpp.xournalpp
|
||||
apply_flatpak_theme "com.github.xournalpp.xournalpp"
|
||||
log "Xournal++ installed."
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/logging.sh"
|
|||
|
||||
log "Installing Zed editor (Flatpak)..."
|
||||
ensure_flatpak
|
||||
flatpak install --user -y flathub dev.zed.Zed
|
||||
sudo flatpak install --system -y flathub dev.zed.Zed
|
||||
apply_flatpak_theme "dev.zed.Zed"
|
||||
log "Zed editor installed."
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/logging.sh"
|
|||
|
||||
log "Installing Zen Browser (Flatpak)..."
|
||||
ensure_flatpak
|
||||
flatpak install --user -y flathub io.github.zen_browser.zen
|
||||
sudo flatpak install --system -y flathub io.github.zen_browser.zen
|
||||
apply_flatpak_theme "io.github.zen_browser.zen"
|
||||
log "Zen Browser installed."
|
||||
|
|
|
|||
|
|
@ -390,7 +390,6 @@ count_steps() {
|
|||
# AF_* variables hold values parsed from the JSON answerfile.
|
||||
# They are initialised to safe defaults so the rest of the script can reference
|
||||
# them unconditionally whether or not answerfile mode is active.
|
||||
AF_HOSTNAME=""
|
||||
AF_COMPONENTS=""
|
||||
AF_DE="none"
|
||||
AF_APPS=""
|
||||
|
|
@ -406,7 +405,6 @@ load_answerfile() {
|
|||
# -r outputs raw strings without JSON quoting.
|
||||
# '// ""' / '// "none"' are jq's null-coalescing operator: if the key is
|
||||
# absent from the file the expression yields the fallback instead.
|
||||
AF_HOSTNAME=$(jq -r '.hostname // ""' "$ANSWERFILE")
|
||||
# JSON arrays are flattened to a space-separated string to match the format
|
||||
# that COMPONENTS and SELECTED_APPS expect throughout the rest of the script.
|
||||
AF_COMPONENTS=$(jq -r '(.components // []) | join(" ")' "$ANSWERFILE")
|
||||
|
|
@ -421,20 +419,6 @@ load_answerfile() {
|
|||
AF_COLOR_RED=$(jq -r '.colors.COLOR_RED // ""' "$ANSWERFILE")
|
||||
}
|
||||
|
||||
# ── MAC address helper ────────────────────────────────────────────────────────
|
||||
get_mac_suffix() {
|
||||
# Returns the MAC address of the first non-loopback interface, colons stripped.
|
||||
# Used to make answerfile-derived hostnames unique per machine (e.g. "myhost-aabbccddee").
|
||||
local mac
|
||||
# awk state machine: sets iface=1 when it sees an interface line whose name
|
||||
# does NOT start with "lo" ([^l][^o] skips "lo"), then captures the
|
||||
# 'link/ether XX:XX:XX:XX:XX:XX' line and exits immediately after the first hit.
|
||||
mac=$(ip link show 2>/dev/null \
|
||||
| awk '/^[0-9]+: [^l][^o]/{iface=1} iface && /link\/ether/{print $2; iface=0; exit}')
|
||||
# Strip colons from the MAC so it is safe to embed in a hostname (only [a-z0-9-] allowed).
|
||||
printf '%s' "${mac//:/}"
|
||||
}
|
||||
|
||||
# ── Preflight ─────────────────────────────────────────────────────────────────
|
||||
if [[ $EUID -eq 0 ]]; then
|
||||
# Root context (e.g. archiso chroot): shim sudo as a passthrough
|
||||
|
|
@ -493,32 +477,8 @@ if ! $ANSWERFILE_MODE; then
|
|||
Log: $LOG"
|
||||
fi
|
||||
|
||||
# ── Hostname ──────────────────────────────────────────────────────────────────
|
||||
HOSTNAME_SET=""
|
||||
if $ANSWERFILE_MODE; then
|
||||
if [[ -n "$AF_HOSTNAME" ]]; then
|
||||
# Append the stripped MAC address to the base name from the answerfile.
|
||||
# This makes each cloned machine's hostname unique without needing per-host
|
||||
# answerfiles (useful for mass-provisioning identical images).
|
||||
MAC=$(get_mac_suffix)
|
||||
HOSTNAME_SET="${AF_HOSTNAME}-${MAC}"
|
||||
printf "Hostname (from answerfile + MAC): %s\n" "$HOSTNAME_SET" | tee -a "$LOG"
|
||||
fi
|
||||
else
|
||||
# ui_input prints its prompt to stderr and the typed value to stdout, so the
|
||||
# $() capture receives only the hostname. A blank line keeps the default.
|
||||
HOSTNAME_INPUT=$(ui_input " Hostname " \
|
||||
" Hostname for this machine (leave blank to keep default).") || HOSTNAME_INPUT=""
|
||||
HOSTNAME_SET="$HOSTNAME_INPUT"
|
||||
fi
|
||||
|
||||
if [[ -n "$HOSTNAME_SET" ]]; then
|
||||
# hostnamectl is the preferred method on systemd systems; fall back to writing
|
||||
# /etc/hostname directly for minimal chroot environments that lack systemd.
|
||||
sudo hostnamectl set-hostname "$HOSTNAME_SET" 2>/dev/null \
|
||||
|| echo "$HOSTNAME_SET" | sudo tee /etc/hostname > /dev/null
|
||||
printf "Hostname set: %s\n" "$HOSTNAME_SET" >> "$LOG"
|
||||
fi
|
||||
# Note: the hostname is set by the base installer (archbaseos-guided-install.sh),
|
||||
# so this script intentionally does not prompt for or change it.
|
||||
|
||||
# ── Component selection ───────────────────────────────────────────────────────
|
||||
if $ANSWERFILE_MODE; then
|
||||
|
|
@ -660,7 +620,6 @@ if ! $ANSWERFILE_MODE; then
|
|||
# Build a human-readable summary of everything that will be installed so the
|
||||
# user can review the full list before any changes are made to the system.
|
||||
SUMMARY=""
|
||||
[[ -n "$HOSTNAME_SET" ]] && SUMMARY+=" ✦ Hostname: $HOSTNAME_SET\n"
|
||||
[[ "$COMPONENTS" == *"pkg"* ]] && SUMMARY+=" ✦ Package managers (yay, nvm, rust)\n"
|
||||
[[ "$COMPONENTS" == *"core"* ]] && SUMMARY+=" ✦ Core packages\n"
|
||||
[[ "$COMPONENTS" == *"svc"* ]] && SUMMARY+=" ✦ Core services\n"
|
||||
|
|
|
|||
Loading…
Reference in New Issue