feat: graphical installer in the live ISO

The ISO now boots straight into a GTK installer instead of dropping to a
tty. Structure:

- installer/arcline-installer: small GTK3 (Python) frontend that drives
  scripts/deploy-disk.sh — pick a disk, choose boot mode, type the device
  path to confirm, watch the deploy log, reboot. Pure helper logic is
  tested against lsblk (lowercase keys, pseudo-devices filtered).
- scripts/build-live.sh: builds build/rootfs/<edition>-live by cloning the
  CLEAN rootfs and layering on live-boot, a minimal X session (Xorg +
  openbox), the installer, and the deploy tooling under /usr/lib/arcline
  (deploy-disk.sh + btrfs/init.sh + edition fstabs, laid out so the
  scripts' own path resolution works unchanged).
- overlays/live/: arcline-installer.service + session script that start
  Xorg on vt1 (with -allow-root) and run the installer as the X client.
- build-iso.sh: builds the live rootfs for the squashfs AND stages the
  clean rootfs archive into isofiles/install/ — the installer deploys the
  clean archive, so what's installed is the hardened system, never the
  live session with the installer in it.
- Refactor: ARCLINE_LIVE handling removed from build-rootfs.sh and
  configure-system.sh (now lives entirely in build-live.sh).
- validate.sh now checks overlays shell scripts + installer python.
- docs updated (building.md, architecture.md, installer/README.md).
This commit is contained in:
Blake Ridgway
2026-08-21 20:24:09 -05:00
parent 578c518553
commit 0ea8b713dd
11 changed files with 522 additions and 46 deletions

97
scripts/build-live.sh Executable file
View File

@@ -0,0 +1,97 @@
#!/usr/bin/env bash
# ─────────────────────────────────────────────────────────────────────────────
# Arcline OS — live-session rootfs builder
#
# scripts/build-live.sh <edition>
#
# Creates build/rootfs/<edition>-live: a bootable live-session rootfs used by
# the ISO. It starts from the CLEAN installed-system rootfs (so what you
# install is exactly what you booted), clones it, and layers on:
#
# - live-boot / live-config / live-tools (boot the squashfs)
# - a minimal X session (Xorg + openbox) for the graphical installer
# - the Arcline graphical installer (installer/arcline-installer)
# - the deploy tooling it needs (deploy-disk.sh + btrfs/init.sh + fstabs)
#
# The live rootfs itself is never what gets installed — the installer deploys
# the clean rootfs archive (staged into the ISO by build-iso.sh).
# ─────────────────────────────────────────────────────────────────────────────
set -euo pipefail
source "$(dirname "${BASH_SOURCE[0]}")/common.sh"
EDITION="${1:?usage: build-live.sh <edition>}"
validate_edition "$EDITION"
require_root "$0" "$@"
CLEAN="$ROOTFS_DIR/$EDITION"
LIVE_ROOT="$ROOTFS_DIR/$EDITION-live"
# ── 1. ensure the clean rootfs ──────────────────────────────────────────────
if [[ ! -d "$CLEAN" ]]; then
log "clean rootfs missing — building it first"
"$ROOT/scripts/build-rootfs.sh" "$EDITION"
fi
log "═══ building live session rootfs for $EDITION ═══"
rm -rf "$LIVE_ROOT"
cp -a "$CLEAN" "$LIVE_ROOT"
# ── chroot helpers ──────────────────────────────────────────────────────────
mount_pseudo() {
mount --bind /dev "$LIVE_ROOT/dev"
mount --bind /proc "$LIVE_ROOT/proc"
mount --bind /sys "$LIVE_ROOT/sys"
mount --bind /dev/pts "$LIVE_ROOT/dev/pts" 2>/dev/null || true
}
unmount_pseudo() {
umount -l "$LIVE_ROOT/dev/pts" 2>/dev/null || true
umount -l "$LIVE_ROOT/sys" 2>/dev/null || true
umount -l "$LIVE_ROOT/proc" 2>/dev/null || true
umount -l "$LIVE_ROOT/dev" 2>/dev/null || true
}
trap 'unmount_pseudo' EXIT
chroot_run() { chroot "$LIVE_ROOT" /bin/bash -c "$*"; }
# ── 2. install live session packages ────────────────────────────────────────
log "[1/4] installing live-boot + X + installer dependencies"
mount_pseudo
chroot_run "export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
apt-get install -y --no-install-recommends \
live-boot live-config-systemd live-tools \
xserver-xorg xinit x11-xserver-utils openbox \
python3-gi gir1.2-gtk-3.0 gdisk parted dosfstools \
| tee /tmp/live-packages.log"
# ── 3. ship the graphical installer + deploy tooling ────────────────────────
log "[2/4] installing installer + deploy tooling"
install -Dm0755 "$ROOT/installer/arcline-installer" "$LIVE_ROOT/usr/local/bin/arcline-installer"
# The installer drives deploy-disk.sh; mirror the repo layout under
# /usr/lib/arcline so common.sh's ROOT resolution works unchanged.
install -Dm0755 "$ROOT/scripts/common.sh" "$LIVE_ROOT/usr/lib/arcline/scripts/common.sh"
install -Dm0755 "$ROOT/scripts/deploy-disk.sh" "$LIVE_ROOT/usr/lib/arcline/scripts/deploy-disk.sh"
install -Dm0755 "$ROOT/scripts/apply-fstab.sh" "$LIVE_ROOT/usr/lib/arcline/scripts/apply-fstab.sh"
install -Dm0755 "$ROOT/btrfs/init.sh" "$LIVE_ROOT/usr/lib/arcline/btrfs/init.sh"
for e in "${EDITIONS[@]}"; do
install -Dm0644 "$ROOT/editions/$e/fstab" "$LIVE_ROOT/usr/lib/arcline/editions/$e/fstab"
done
# ── 4. live overlay (session autostart) + service wiring ────────────────────
log "[3/4] applying live overlay"
cp -a "$ROOT/overlays/live/." "$LIVE_ROOT/"
chroot_run "systemctl enable arcline-installer.service 2>/dev/null || true
systemctl mask sddm 2>/dev/null || true
systemctl set-default multi-user.target 2>/dev/null || true"
# the live session is disposable; give it a fresh identity
echo "arclines-live" > "$LIVE_ROOT/etc/hostname"
rm -f "$LIVE_ROOT/etc/machine-id"
: > "$LIVE_ROOT/etc/machine-id"
log "[4/4] cleaning live rootfs"
chroot_run "apt-get clean 2>/dev/null; rm -rf /var/lib/apt/lists/* /var/cache/apt/* /tmp/* /root/.bash_history"
unmount_pseudo
log "live rootfs ready: $LIVE_ROOT"