Files
os-build/scripts/build-rootfs.sh
Blake Ridgway 0ea8b713dd 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).
2026-08-21 20:24:09 -05:00

151 lines
6.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# ─────────────────────────────────────────────────────────────────────────────
# Arcline OS — rootfs builder
#
# scripts/build-rootfs.sh <edition>
#
# Pipeline:
# 1. debootstrap a minimal Debian base
# 2. configure apt sources (main + security)
# 3. install the edition package set
# 4. apply overlays (hardening, configs, service units)
# 5. run configure-system.sh inside the chroot
# 6. clean and tar the result → build/artifacts/arcline-<edition>-<version>.tar.xz
#
# Root is required (re-execs under sudo when needed).
# ─────────────────────────────────────────────────────────────────────────────
set -euo pipefail
source "$(dirname "${BASH_SOURCE[0]}")/common.sh"
EDITION="${1:?usage: build-rootfs.sh <edition>}"
validate_edition "$EDITION"
# Re-exec under sudo if we aren't root (debootstrap/chroot/mount need it).
require_root "$0" "$@"
# Fail fast on a bad toolchain policy before debootstrap does any work.
case "$ARCLINE_TOOLCHAIN" in
auto|skip|require) ;;
*) die "ARCLINE_TOOLCHAIN must be auto|skip|require (got '$ARCLINE_TOOLCHAIN')" ;;
esac
# Fail fast on a bad boot flavour. grub-pc and grub-efi-amd64 conflict, so we
# install exactly the one matching BOOT (never both).
case "$BOOT" in
bios) BOOT_PKGS="grub-pc" ;;
efi) BOOT_PKGS="grub-efi-amd64 shim-signed mokutil" ;;
*) die "BOOT must be bios|efi (got '$BOOT')" ;;
esac
EDIR="$(edition_dir "$EDITION")"
ROOTFS="$ROOTFS_DIR/$EDITION"
ARTIFACT="$ARTIFACT_DIR/arcline-$EDITION-$VERSION-$ARCH.tar.xz"
mkdir -p "$ROOTFS_DIR" "$LOG_DIR" "$ARTIFACT_DIR"
rm -rf "$ROOTFS" "$ARTIFACT"
log "═══ building Arcline $EDITION rootfs ($DISTRO_NAME $VERSION) ═══"
# ── 1. bootstrap ────────────────────────────────────────────────────────────
log "[1/6] debootstrap $DEBIAN_SUITE ($ARCH)"
debootstrap \
--arch="$ARCH" \
--variant=minbase \
--include=apt-transport-https,ca-certificates,gnupg,curl \
"$DEBIAN_SUITE" "$ROOTFS" "$DEBIAN_MIRROR" \
| tee "$LOG_DIR/bootstrap-$EDITION.log"
# ── 2. apt sources ──────────────────────────────────────────────────────────
log "[2/6] configuring apt sources"
cat > "$ROOTFS/etc/apt/sources.list" <<EOF
deb $DEBIAN_MIRROR $DEBIAN_SUITE main contrib non-free-firmware
deb $DEBIAN_MIRROR $DEBIAN_SUITE-updates main contrib non-free-firmware
deb $SECURITY_MIRROR $DEBIAN_SUITE-security main contrib non-free-firmware
EOF
# ── chroot helpers (bind-mount pseudo-fs, run in chroot, unmount on exit) ──
mount_pseudo() {
mount --bind /dev "$ROOTFS/dev"
mount --bind /proc "$ROOTFS/proc"
mount --bind /sys "$ROOTFS/sys"
mount --bind /dev/pts "$ROOTFS/dev/pts" 2>/dev/null || true
}
unmount_pseudo() {
umount -l "$ROOTFS/dev/pts" 2>/dev/null || true
umount -l "$ROOTFS/sys" 2>/dev/null || true
umount -l "$ROOTFS/proc" 2>/dev/null || true
umount -l "$ROOTFS/dev" 2>/dev/null || true
}
trap 'unmount_pseudo' EXIT
chroot_run() { chroot "$ROOTFS" /bin/bash -c "$*"; }
# ── 3. install edition packages ─────────────────────────────────────────────
log "[3/6] installing edition packages (${EDITION}, boot: $BOOT)"
PKGS="$(grep -vE '^\s*(#|$)' "$EDIR/packages.list" | tr '\n' ' ')$BOOT_PKGS"
mount_pseudo
chroot_run "export DEBIAN_FRONTEND=noninteractive; apt-get update -qq && apt-get install -y --no-install-recommends $PKGS" \
| tee "$LOG_DIR/packages-$EDITION.log"
unmount_pseudo
# ── 4. overlays ─────────────────────────────────────────────────────────────
log "[4/6] applying overlays"
"$ROOT/scripts/apply-overlays.sh" "$ROOTFS" "$EDITION"
# copy btrfs snapshot/rollback tooling into the image
install -Dm0755 "$ROOT/btrfs/snapshot.sh" "$ROOTFS/usr/local/sbin/arcline-snapshot"
install -Dm0755 "$ROOT/btrfs/rollback.sh" "$ROOTFS/usr/local/sbin/arcline-rollback"
# ── 5. configure system in chroot ───────────────────────────────────────────
log "[5/6] configuring system in chroot"
install -m0755 "$ROOT/scripts/configure-system.sh" "$ROOTFS/root/configure-system.sh"
# Stage the edition manifest INSIDE the chroot (the hook runs in there and
# cannot see host paths).
mkdir -p "$ROOTFS/root/arcline-edition"
cp "$EDIR/kernel.cmdline" "$EDIR/metadata.yaml" "$ROOTFS/root/arcline-edition/"
# Toolchain policy — the Arcline tools are optional in an image build. See
# ARCLINE_TOOLCHAIN in scripts/common.sh (auto | skip | require).
HAVE_DEBS=0
if [[ -d "$DEB_DIR" ]] && ls "$DEB_DIR"/*.deb >/dev/null 2>&1; then
HAVE_DEBS=1
fi
case "$ARCLINE_TOOLCHAIN" in
require)
[[ $HAVE_DEBS -eq 1 ]] || die "ARCLINE_TOOLCHAIN=require but no .deb files in $DEB_DIR (run: make toolchain)"
mkdir -p "$ROOTFS/arcline-debs"
cp "$DEB_DIR"/*.deb "$ROOTFS/arcline-debs/"
log "toolchain: staging $(ls "$DEB_DIR"/*.deb | wc -l) packages (required)"
;;
skip)
log "toolchain: skipped (ARCLINE_TOOLCHAIN=skip) — building without Arcline tools"
;;
auto)
if [[ $HAVE_DEBS -eq 1 ]]; then
mkdir -p "$ROOTFS/arcline-debs"
cp "$DEB_DIR"/*.deb "$ROOTFS/arcline-debs/"
log "toolchain: staging $(ls "$DEB_DIR"/*.deb | wc -l) packages"
else
warn "no toolchain .debs in $DEB_DIR — building WITHOUT Arcline tools (run: make toolchain)"
fi
;;
*)
die "ARCLINE_TOOLCHAIN must be auto|skip|require (got '$ARCLINE_TOOLCHAIN')"
;;
esac
mount_pseudo
chroot_run "ARCLINE_EDITION_DIR='/root/arcline-edition' ARCLINE_LOCK_ROOT='${ARCLINE_LOCK_ROOT:-0}' ARCLINE_EXTRA_REPOS='${ARCLINE_EXTRA_REPOS:-0}' /root/configure-system.sh '$EDITION'"
rm -f "$ROOTFS/root/configure-system.sh"
rm -rf "$ROOTFS/root/arcline-edition" "$ROOTFS/arcline-debs"
unmount_pseudo
# ── 6. clean + archive ──────────────────────────────────────────────────────
log "[6/6] cleaning and archiving"
chroot_run "apt-get clean 2>/dev/null; rm -rf /var/lib/apt/lists/* /var/cache/apt/* /tmp/* /root/.bash_history"
rm -f "$ROOTFS/etc/machine-id"
: > "$ROOTFS/etc/machine-id"
tar -C "$ROOTFS" -cJf "$ARTIFACT" .
log "rootfs artifact: $ARTIFACT"
sha256sum "$ARTIFACT" | tee "$ARTIFACT.sha256"