#!/usr/bin/env bash # ───────────────────────────────────────────────────────────────────────────── # Arcline OS — in-chroot system configuration # # scripts/configure-system.sh # # 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 }" DISTRO_NAME="${DISTRO_NAME:-Arcline OS}" VERSION="${VERSION:-0.1.0}" RELEASE_NAME="${RELEASE_NAME:-arclines}" LIVE="${ARCLINE_LIVE:-0}" 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 </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 </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 # ── live-boot (ISO builds) ────────────────────────────────────────────────── if [[ "$LIVE" == "1" ]]; then log "installing live-boot support" export DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends live-boot live-config-systemd live-tools || warn "live-boot install failed" fi # ── 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'"