veilor-os/overlay/usr/local/bin/veilor-update
obsidian-ai 606806f82f overlay: atomic CLI tools for v0.7+ (bootc upgrade, postinstall, doctor)
A3 inline (agent failed on API). Three CLIs ported / written for the
v0.7+ atomic system:

veilor-update — rewritten on bootc upgrade (was dnf upgrade --refresh).
  Pre-checks bootc status, pauses auditd while staging, prints summary
  and offers reboot. Returns 0/1/2/3 per legacy contract.

veilor-postinstall (NEW) — first-login TUI run via
  veilor-postinstall.service oneshot. Asks once for keyboard, locale,
  hostname, GPU drivers, package presets (dev/media/homelab),
  bluetooth, USBGuard snapshot, then invokes veilor-doctor. Writes
  /var/lib/veilor/postinstall-complete and self-disables on success.

veilor-doctor — Updates section rewritten to parse `bootc status
  --json` (with jq) when available, falls back to dnf history /
  check-update for legacy v0.5.x kickstart-installed systems.

Plus systemd units:
  - veilor-postinstall.service (oneshot on graphical.target, gated on
    absence of done-marker, runs on tty1)
  - veilor-doctor.service + .timer (weekly drift check)
2026-05-06 16:46:59 +01:00

94 lines
3.4 KiB
Bash
Executable file

#!/usr/bin/bash
# veilor-update — atomic update wrapper for v0.7+ (bootc + rpm-ostree).
#
# Wraps `bootc upgrade` + flatpak update behind a single command.
# Pre-checks rollback availability, pauses auditd while staging the
# new image, prints a clear post-state summary, and offers reboot.
#
# Exit codes:
# 0 success (with or without pending reboot)
# 1 bootc upgrade failed
# 2 flatpak failed (bootc still ran successfully)
# 3 no network
set -uo pipefail
have() { command -v "$1" >/dev/null 2>&1; }
GUM=$(have gum && echo gum || echo "")
say() {
if [[ -n $GUM ]]; then
gum style --foreground 212 --bold "$1"
else
printf '\n=== %s ===\n' "$1"
fi
}
confirm() {
local prompt=$1
if [[ -n $GUM ]]; then
gum confirm "$prompt"
else
read -r -p "$prompt [y/N] " yn
[[ ${yn,,} == y* ]]
fi
}
# ── Pre-flight: network ─────────────────────────────────────────────
say "veilor-update: checking network"
if ! ping -c 1 -W 2 1.1.1.1 >/dev/null 2>&1; then
echo " No network. Connect and re-run \`veilor-update\`."
exit 3
fi
# ── Pre-flight: rollback target available ───────────────────────────
# bootc has two deployments by design (booted + rollback). If
# something's wrong we want the user to see it before staging more.
if have bootc; then
say "veilor-update: bootc status"
bootc status || true
else
echo " bootc not present — this CLI targets v0.7+ atomic systems."
exit 1
fi
# ── Pause auditd while staging ──────────────────────────────────────
# Reduces audit log noise during the heavy fs writes; resume after.
AUDIT_PAUSED=0
if systemctl is-active auditd >/dev/null 2>&1; then
if sudo systemctl stop auditd 2>/dev/null; then
AUDIT_PAUSED=1
fi
fi
trap '[[ $AUDIT_PAUSED == 1 ]] && sudo systemctl start auditd 2>/dev/null || true' EXIT
# ── bootc upgrade ───────────────────────────────────────────────────
say "veilor-update: bootc upgrade"
if ! sudo bootc upgrade; then
echo " bootc upgrade failed. See output above."
exit 1
fi
# ── Flatpak (best-effort) ───────────────────────────────────────────
FLATPAK_RC=0
if have flatpak; then
say "veilor-update: updating flatpaks"
if ! flatpak update -y; then
FLATPAK_RC=2
echo " flatpak update failed; continuing."
fi
fi
# ── Post-update summary ─────────────────────────────────────────────
say "veilor-update: complete"
bootc status 2>/dev/null | head -20 || true
# ── Reboot prompt ───────────────────────────────────────────────────
# bootc always writes the new image into the staged deployment; reboot
# is required for it to become the running root.
if confirm " Reboot now to activate the new image?"; then
say "veilor-update: rebooting"
sudo systemctl reboot
fi
exit $FLATPAK_RC