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).
127 lines
6.0 KiB
Bash
Executable File
127 lines
6.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Arcline OS — in-chroot system configuration
|
|
#
|
|
# scripts/configure-system.sh <edition>
|
|
#
|
|
# This script is executed INSIDE the chroot (build-rootfs.sh copies it in and
|
|
# runs it via chroot). It turns a raw debootstrap tree into an Arcline system:
|
|
# hostname, locale, kernel cmdline, enabled/masked services, optional live-boot,
|
|
# optional Arcline toolchain install, optional upstream repos (grafana/loki).
|
|
#
|
|
# It is idempotent and safe to re-run.
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
set -euo pipefail
|
|
|
|
EDITION="${1:?usage: configure-system.sh <edition>}"
|
|
DISTRO_NAME="${DISTRO_NAME:-Arcline OS}"
|
|
VERSION="${VERSION:-0.1.0}"
|
|
RELEASE_NAME="${RELEASE_NAME:-arclines}"
|
|
LOCK_ROOT="${ARCLINE_LOCK_ROOT:-0}"
|
|
EXTRA_REPOS="${ARCLINE_EXTRA_REPOS:-0}"
|
|
|
|
# Absolute path of the edition dir on the host is injected by build-rootfs.sh.
|
|
EDIR="${ARCLINE_EDITION_DIR:?ARCLINE_EDITION_DIR must be set}"
|
|
|
|
log() { printf '\033[1;34m[arcline:chroot]\033[0m %s\n' "$*"; }
|
|
warn() { printf '\033[1;33m[arcline:chroot]\033[0m %s\n' "$*" >&2; }
|
|
|
|
# Read a flat YAML list (key: then indented "- item" lines). Keys may be
|
|
# nested under a section (e.g. services: → enabled:).
|
|
yaml_list() {
|
|
awk -v key="$2" '
|
|
$0 ~ "^[[:space:]]*" key ":" { insec=1; next }
|
|
insec && /^[[:space:]]*-/ { sub(/^[[:space:]]*-[[:space:]]*/, ""); print; next }
|
|
insec && !/^[[:space:]]*-/ && !/^[[:space:]]*$/ { exit }
|
|
' "$1"
|
|
}
|
|
|
|
# ── identity ────────────────────────────────────────────────────────────────
|
|
echo "$RELEASE_NAME" > /etc/hostname
|
|
cat > /etc/arcline-release <<EOF
|
|
$DISTRO_NAME $VERSION ($RELEASE_NAME)
|
|
Edition: $EDITION
|
|
Debian base: $(. /etc/os-release && echo "$PRETTY_NAME")
|
|
EOF
|
|
ln -sf /etc/arcline-release /etc/os-release-arcline
|
|
|
|
# ── locale / timezone ───────────────────────────────────────────────────────
|
|
sed -i 's/^# *en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen
|
|
locale-gen >/dev/null 2>&1 || true
|
|
echo "LANG=en_US.UTF-8" > /etc/default/locale
|
|
ln -sf /usr/share/zoneinfo/UTC /etc/localtime
|
|
|
|
# ── kernel cmdline (used when this rootfs is installed to disk) ─────────────
|
|
KCMD="$(tr '\n' ' ' < "$EDIR/kernel.cmdline" | sed 's/ */ /g; s/^ *//; s/ *$//')"
|
|
cat > /etc/default/grub <<EOF
|
|
GRUB_DEFAULT=0
|
|
GRUB_TIMEOUT=5
|
|
GRUB_DISTRIBUTOR="$DISTRO_NAME"
|
|
GRUB_CMDLINE_LINUX_DEFAULT="$KCMD"
|
|
GRUB_CMDLINE_LINUX=""
|
|
GRUB_DISABLE_OS_PROBER=false
|
|
EOF
|
|
|
|
# ── systemd services ────────────────────────────────────────────────────────
|
|
META="$EDIR/metadata.yaml"
|
|
while IFS= read -r svc; do
|
|
[[ -n "$svc" ]] && systemctl enable "$svc" 2>/dev/null || true
|
|
done < <(yaml_list "$META" "enabled" || true)
|
|
|
|
while IFS= read -r svc; do
|
|
[[ -n "$svc" ]] && systemctl mask "$svc" 2>/dev/null || true
|
|
done < <(yaml_list "$META" "masked" || true)
|
|
|
|
# Graphical boot: when a display manager (sddm) is enabled, boot straight to
|
|
# the graphical login instead of a tty. Without this the desktop is installed
|
|
# but the system still boots to multi-user.
|
|
if yaml_list "$META" "enabled" | grep -qx "sddm"; then
|
|
systemctl set-default graphical.target
|
|
log "graphical boot: default target set to graphical.target (sddm)"
|
|
fi
|
|
|
|
# Zero-telemetry: apt's automatic update calls are masked in metadata; also
|
|
# ensure no package telemetry survives.
|
|
rm -f /var/log/apt/*.log /var/cache/apt/archives/*.deb
|
|
|
|
# ── Arcline toolchain (host-built .debs) ────────────────────────────────────
|
|
if [[ -d /arcline-debs ]] && ls /arcline-debs/*.deb >/dev/null 2>&1; then
|
|
log "installing Arcline toolchain packages"
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
apt-get install -y /arcline-debs/*.deb 2>/dev/null \
|
|
|| dpkg -i /arcline-debs/*.deb 2>/dev/null \
|
|
|| warn "toolchain install incomplete (fix with: apt-get -f install)"
|
|
fi
|
|
|
|
# ── observability services (vendor debs from toolchain/build-vendor.sh) ─────
|
|
# Only enabled when their binaries actually landed in the image.
|
|
for svc_bin_unit in \
|
|
"/usr/sbin/grafana-server:grafana-server" \
|
|
"/usr/bin/loki:loki" \
|
|
"/usr/bin/promtail:promtail"; do
|
|
bin="${svc_bin_unit%%:*}"
|
|
unit="${svc_bin_unit##*:}"
|
|
if [[ -x "$bin" ]]; then
|
|
systemctl enable "$unit" 2>/dev/null || true
|
|
log "observability: enabled $unit ($bin present)"
|
|
fi
|
|
done
|
|
|
|
# ── optional upstream repos (grafana, loki) ─────────────────────────────────
|
|
if [[ "$EXTRA_REPOS" == "1" ]]; then
|
|
log "adding upstream observability repos (grafana, loki)"
|
|
install -d /usr/share/keyrings
|
|
curl -fsSL https://apt.grafana.com/gpg.key -o /usr/share/keyrings/grafana.asc 2>/dev/null || warn "grafana key fetch failed"
|
|
echo "deb [signed-by=/usr/share/keyrings/grafana.asc] https://apt.grafana.com stable main" > /etc/apt/sources.list.d/grafana.list
|
|
# Loki ships as a static binary tarball; the packaging lives in toolchain/.
|
|
# (No-op here; documented in docs/observability.md.)
|
|
fi
|
|
|
|
# ── root account policy ─────────────────────────────────────────────────────
|
|
if [[ "$LOCK_ROOT" == "1" ]]; then
|
|
passwd -l root
|
|
log "root account locked (sudo/ssh-key access only)"
|
|
fi
|
|
|
|
log "configure-system.sh complete for edition '$EDITION'"
|