fix(installer): make the unattended module path non-interactive

An answerfile/PXE install runs the TUI modules with no operator present, so any
interactive prompt or confirmation hangs the deployment forever.

- tui-install.sh: run each module in the FOREGROUND with a background `tail -f`
  mirroring its log, instead of backgrounding the module. Backgrounding made
  interactive module reads (e.g. the EWW form-factor question) trigger SIGTTIN
  and stop; the file-based log still avoids the `| tee` pipe-inherit hang that
  paused installs after a module spawned a daemon. Export MARCHY_UNATTENDED=1
  in answerfile mode so modules can detect it.
- hyprlua.sh: skip the EWW form-factor `read` when MARCHY_UNATTENDED=1 or stdin
  is not a TTY, defaulting to the desktop/no-battery bar; add --noconfirm to the
  tablet-branch yay call.
- python.sh: add --noconfirm --needed to its `pacman -Syu` so it no longer waits
  on the "Proceed?" prompt during unattended installs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R5kHioUMK3mtf2eiLEozCM
main
Amir Alexander Abdelbaki 2026-06-27 01:15:43 +02:00
parent d445f965ce
commit 587b95cada
3 changed files with 34 additions and 18 deletions

View File

@ -214,8 +214,16 @@ log "Setting up EWW bar..."
rm -rf ~/.config/eww rm -rf ~/.config/eww
# Single-keystroke form-factor selection (no Enter required). # Single-keystroke form-factor selection (no Enter required).
read -n1 -p "Install eww bar for PC, Notebook or Tablet [P/N/T]: " doit # Skip the prompt in unattended installs (answerfile mode) or when stdin is not
echo # Newline after single-char read # a terminal — otherwise the read blocks forever during automated deployment.
# Default to the desktop/no-battery layout, the safe choice for VMs and PCs.
if [[ "${MARCHY_UNATTENDED:-0}" == "1" || ! -t 0 ]]; then
doit="P"
log "Unattended mode — installing desktop (no-battery) EWW bar."
else
read -n1 -p "Install eww bar for PC, Notebook or Tablet [P/N/T]: " doit
echo # Newline after single-char read
fi
case $doit in case $doit in
# Notebook: battery-aware layout # Notebook: battery-aware layout
@ -226,7 +234,7 @@ case $doit in
t|T) cp -rf ~/Dotfiles/desktopenvs/hyprlua/eww-touch/ ~/.config/eww t|T) cp -rf ~/Dotfiles/desktopenvs/hyprlua/eww-touch/ ~/.config/eww
# evdev-right-click-emulation enables long-press → right-click on touch # evdev-right-click-emulation enables long-press → right-click on touch
# screens; its systemd service must be started alongside the session. # screens; its systemd service must be started alongside the session.
yay -S evdev-right-click-emulation yay -S --noconfirm evdev-right-click-emulation
enable_service evdev-rce.service; start_service evdev-rce.service ;; enable_service evdev-rce.service; start_service evdev-rce.service ;;
# Unrecognised key: leave ~/.config/eww absent; user must copy manually. # Unrecognised key: leave ~/.config/eww absent; user must copy manually.
*) warn "No valid choice — skipping EWW copy. Run manually later." ;; *) warn "No valid choice — skipping EWW copy. Run manually later." ;;

View File

@ -10,7 +10,8 @@ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/logging.sh"
# pyright — Microsoft's Python LSP; used by nvim-lspconfig # pyright — Microsoft's Python LSP; used by nvim-lspconfig
# python-pynvim — Python client library that lets neovim plugins call Python RPCs # python-pynvim — Python client library that lets neovim plugins call Python RPCs
# python-pipx — tool to install Python apps in isolated venvs (replaces pipsi) # python-pipx — tool to install Python apps in isolated venvs (replaces pipsi)
# Note: --noconfirm and --needed are not passed here; add them to make this idempotent. # --noconfirm keeps the install non-interactive (required for unattended/answerfile
# deployment); --needed skips packages already present so re-runs are idempotent.
log "Installing Python tools..." log "Installing Python tools..."
sudo pacman -Syu python pyright python-pynvim python-pipx sudo pacman -Syu --noconfirm --needed python pyright python-pynvim python-pipx
log "Python tools installed." log "Python tools installed."

View File

@ -29,6 +29,10 @@ ANSWERFILE="${ANSWERFILE:-/answerfile.json}"
ANSWERFILE_MODE=false ANSWERFILE_MODE=false
# Enable unattended mode only when the answerfile is actually present on disk. # Enable unattended mode only when the answerfile is actually present on disk.
[[ -f "$ANSWERFILE" ]] && ANSWERFILE_MODE=true [[ -f "$ANSWERFILE" ]] && ANSWERFILE_MODE=true
# Signal unattended mode to child module scripts so they skip interactive prompts
# (e.g. hyprlua's EWW form-factor question) and fall back to a sensible default.
# Exported so it reaches modules launched via `bash "$script"` in run_module().
$ANSWERFILE_MODE && export MARCHY_UNATTENDED=1
# ── Cyberqueer CLI palette ──────────────────────────────────────────────────── # ── Cyberqueer CLI palette ────────────────────────────────────────────────────
# Plain ANSI escape codes used by the prompt helpers below. These keep the # Plain ANSI escape codes used by the prompt helpers below. These keep the
@ -263,21 +267,24 @@ run_module() {
printf "\n\033[1;35m [$STEP/$TOTAL] %s\033[0m\n" "$label" printf "\n\033[1;35m [$STEP/$TOTAL] %s\033[0m\n" "$label"
printf "\033[35m ─────────────────────────────────────────────\033[0m\n\n" printf "\033[35m ─────────────────────────────────────────────\033[0m\n\n"
# Run the module, combining stderr into stdout. We append to the log FILE # Run the module in the FOREGROUND so its stdin stays connected to the
# (not through a 'tee' pipe) and tail it for live console output, waiting only # terminal: some modules prompt interactively (e.g. hyprlua's EWW form-factor
# on the module's own PID. A 'bash "$script" | tee' pipeline would block AFTER # selection). Backgrounding the module would make any such read trigger
# the module finished whenever a daemon it spawned (flatpak's system helper, # SIGTTIN and stop the job. Output (stdout+stderr) is appended to the log
# gpg-agent, dbus, …) inherited the pipe's write end and held it open — that is # FILE rather than piped through 'tee'. A 'bash "$script" | tee' pipeline
# the "module done but it pauses" symptom. Writing to a real file avoids the # blocks AFTER the module finishes whenever a daemon it spawned (flatpak's
# wait: lingering daemons hold a harmless file descriptor, not the pipe. # system helper, gpg-agent, dbus, …) inherits the pipe's write end and holds
# it open — the "module done but it pauses" symptom. A plain file write has no
# such write end to inherit, so lingering daemons can't stall us. A background
# 'tail -f' mirrors freshly appended lines to the console for live output.
local rc=0 local rc=0
bash "$script" >>"$LOG" 2>&1 & tail -n0 -f "$LOG" 2>/dev/null &
local _modpid=$!
# Mirror newly appended log lines to the console while the module runs.
# --pid makes tail exit once the module process is gone.
tail -n0 --pid="$_modpid" -f "$LOG" 2>/dev/null &
local _tailpid=$! local _tailpid=$!
wait "$_modpid"; rc=$? bash "$script" >>"$LOG" 2>&1
rc=$?
# Stop the mirror; give it a moment to flush the module's final lines.
sleep 0.2
kill "$_tailpid" 2>/dev/null || true
wait "$_tailpid" 2>/dev/null || true wait "$_tailpid" 2>/dev/null || true
if [[ $rc -ne 0 ]]; then if [[ $rc -ne 0 ]]; then