feat: scaffold Arcline OS build system
Scaffold the Arcline OS build system ("the wires"): a transparent,
auditable pipeline that turns a Debian bookworm base into hardened OS
images for the server, workstation, and cloud editions.
- Makefile orchestrates everything (make iso-<edition>, check, test,
toolchain, clean); versions.mk is the single source of truth for
versions and paths.
- scripts/ is the plain-bash pipeline: debootstrap -> install packages
-> apply overlays -> in-chroot configure -> live ISO, plus a rootfs
archive along the way.
- ARCLINE_TOOLCHAIN=auto|skip|require controls whether the 11 Go tools
are bundled into an image (auto by default; minimal builds available
via make iso-<edition>-minimal).
- GPL-3.0 licensed, sponsored by Arcline IT LLC.
This commit is contained in:
18
.gitignore
vendored
Normal file
18
.gitignore
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Build artifacts
|
||||||
|
build/
|
||||||
|
*.iso
|
||||||
|
*.tar.xz
|
||||||
|
*.deb
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Toolchain output
|
||||||
|
toolchain/out/
|
||||||
|
|
||||||
|
# Local mirrors / caches
|
||||||
|
.cache/
|
||||||
|
mirror/
|
||||||
|
|
||||||
|
# Editor cruft
|
||||||
|
*.swp
|
||||||
|
*~
|
||||||
|
.DS_Store
|
||||||
20
LICENSE
Normal file
20
LICENSE
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2026 Arcline IT LLC
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The full text of the license is available at:
|
||||||
|
https://www.gnu.org/licenses/gpl-3.0.txt
|
||||||
104
Makefile
Normal file
104
Makefile
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
# Arcline OS — top-level build orchestration
|
||||||
|
#
|
||||||
|
# The Makefile is a thin, readable wrapper around the scripts/ pipeline. It
|
||||||
|
# exists so that "make iso-server" is the one command that takes a host with
|
||||||
|
# the right build deps to a bootable Arcline OS ISO.
|
||||||
|
#
|
||||||
|
# Everything that has real logic lives in scripts/ — this file only wires
|
||||||
|
# editions to targets and passes through environment.
|
||||||
|
#
|
||||||
|
# Quick reference:
|
||||||
|
# make help → this message
|
||||||
|
# make deps → install host build dependencies
|
||||||
|
# make check → validate manifests + shell syntax (fast, safe)
|
||||||
|
# make rootfs-<edition> → build just the rootfs for an edition
|
||||||
|
# make iso-<edition> → build a bootable ISO for an edition
|
||||||
|
# make iso → build all editions
|
||||||
|
# make toolchain → build the 11 Arcline Go tools into .deb
|
||||||
|
# make test → run the smoke tests against a built image
|
||||||
|
# make clean → wipe build/
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
SHELL := /bin/bash
|
||||||
|
.DEFAULT_GOAL := help
|
||||||
|
|
||||||
|
include versions.mk
|
||||||
|
|
||||||
|
# Pass edition + env through to the scripts.
|
||||||
|
export DISTRO_NAME DISTRO_ID VERSION RELEASE_NAME
|
||||||
|
export DEBIAN_SUITE DEBIAN_MIRROR SECURITY_MIRROR ARCH
|
||||||
|
export KERNEL_PACKAGE KERNEL_VERSION
|
||||||
|
export BUILD_DIR ROOTFS_DIR IMAGE_DIR DEB_DIR LOG_DIR ARTIFACT_DIR
|
||||||
|
export TOOLCHAIN_REPO
|
||||||
|
|
||||||
|
ROOT := $(CURDIR)
|
||||||
|
EDITION := $(filter-out $@,$(MAKECMDGOALS))
|
||||||
|
|
||||||
|
.PHONY: help deps check toolchain test clean
|
||||||
|
|
||||||
|
# ── help ────────────────────────────────────────────────────────────────────
|
||||||
|
help:
|
||||||
|
@echo "Arcline OS build targets"
|
||||||
|
@echo "───────────────────────"
|
||||||
|
@echo " make deps Install host build dependencies"
|
||||||
|
@echo " make check Validate manifests + shell syntax"
|
||||||
|
@echo " make rootfs-<edition> Build rootfs (server|workstation|cloud)"
|
||||||
|
@echo " make iso-<edition> Build ISO (server|workstation|cloud)"
|
||||||
|
@echo " make iso Build ISO for every edition"
|
||||||
|
@echo " make iso-<edition>-minimal Build ISO WITHOUT the Arcline toolchain"
|
||||||
|
@echo " make toolchain Build the 11 Go tools into .deb"
|
||||||
|
@echo " make test Run smoke tests against a built image"
|
||||||
|
@echo " make clean Remove build/ artifacts"
|
||||||
|
@echo
|
||||||
|
@echo "Configuration (see versions.mk):"
|
||||||
|
@echo " VERSION=$(VERSION) DEBIAN_SUITE=$(DEBIAN_SUITE) ARCH=$(ARCH)"
|
||||||
|
@echo " ARCLINE_TOOLCHAIN=auto|skip|require (toolchain in image builds)"
|
||||||
|
|
||||||
|
# ── host deps ────────────────────────────────────────────────────────────────
|
||||||
|
deps:
|
||||||
|
@./scripts/check-host-deps.sh
|
||||||
|
|
||||||
|
# ── validation (fast, no network, safe on any machine) ──────────────────────
|
||||||
|
check:
|
||||||
|
@./scripts/validate.sh
|
||||||
|
|
||||||
|
# ── edition builds ──────────────────────────────────────────────────────────
|
||||||
|
# ARCLINE_TOOLCHAIN controls whether the 11 Go tools are included:
|
||||||
|
# auto (default) install if build/debs/ has .deb files, else skip
|
||||||
|
# skip never install (minimal image)
|
||||||
|
# require fail if no .deb files are available
|
||||||
|
# The *-minimal targets are a shortcut for ARCLINE_TOOLCHAIN=skip.
|
||||||
|
define ISO_RULE
|
||||||
|
.PHONY: rootfs-$(1) iso-$(1) clean-$(1) rootfs-$(1)-minimal iso-$(1)-minimal
|
||||||
|
rootfs-$(1):
|
||||||
|
@./scripts/build-edition.sh $(1) rootfs
|
||||||
|
|
||||||
|
iso-$(1):
|
||||||
|
@./scripts/build-edition.sh $(1) iso
|
||||||
|
|
||||||
|
rootfs-$(1)-minimal:
|
||||||
|
@ARCLINE_TOOLCHAIN=skip ./scripts/build-edition.sh $(1) rootfs
|
||||||
|
|
||||||
|
iso-$(1)-minimal:
|
||||||
|
@ARCLINE_TOOLCHAIN=skip ./scripts/build-edition.sh $(1) iso
|
||||||
|
|
||||||
|
clean-$(1):
|
||||||
|
@rm -rf "$(ROOTFS_DIR)/$(1)" "$(IMAGE_DIR)/$(1)"
|
||||||
|
endef
|
||||||
|
$(foreach e,$(EDITIONS),$(eval $(call ISO_RULE,$(e))))
|
||||||
|
|
||||||
|
iso: $(foreach e,$(EDITIONS),iso-$(e))
|
||||||
|
|
||||||
|
# ── toolchain ───────────────────────────────────────────────────────────────
|
||||||
|
toolchain:
|
||||||
|
@./toolchain/build-tools.sh
|
||||||
|
|
||||||
|
# ── tests ───────────────────────────────────────────────────────────────────
|
||||||
|
test:
|
||||||
|
@./tests/run-tests.sh
|
||||||
|
|
||||||
|
# ── clean ───────────────────────────────────────────────────────────────────
|
||||||
|
clean:
|
||||||
|
@rm -rf "$(BUILD_DIR)"
|
||||||
|
@echo "removed $(BUILD_DIR)/"
|
||||||
36
scripts/apply-overlays.sh
Executable file
36
scripts/apply-overlays.sh
Executable file
@@ -0,0 +1,36 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
# Arcline OS — overlay application
|
||||||
|
#
|
||||||
|
# scripts/apply-overlays.sh <rootfs> <edition>
|
||||||
|
#
|
||||||
|
# overlays/ is organised as layered filesystem trees:
|
||||||
|
# overlays/base/<abs path> → every edition
|
||||||
|
# overlays/<edition>/<abs path> → that edition only
|
||||||
|
#
|
||||||
|
# Files are copied preserving structure and permissions. Later layers win.
|
||||||
|
# overlays/base is applied first, then the edition overlay.
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
set -euo pipefail
|
||||||
|
source "$(dirname "${BASH_SOURCE[0]}")/common.sh"
|
||||||
|
|
||||||
|
TARGET="${1:?usage: apply-overlays.sh <rootfs> <edition>}"
|
||||||
|
EDITION="${2:?usage: apply-overlays.sh <rootfs> <edition>}"
|
||||||
|
validate_edition "$EDITION"
|
||||||
|
|
||||||
|
[[ -d "$TARGET" ]] || die "rootfs '$TARGET' does not exist"
|
||||||
|
|
||||||
|
apply_layer() {
|
||||||
|
local layer="$1"
|
||||||
|
local src="$ROOT/overlays/$layer"
|
||||||
|
[[ -d "$src" ]] || { warn "overlay layer '$layer' not present, skipping"; return 0; }
|
||||||
|
log "applying overlay layer: $layer"
|
||||||
|
# Copy the *contents* of the layer dir into the rootfs, keeping dotfiles,
|
||||||
|
# symlinks, and permissions. Never clobber across layers silently — but
|
||||||
|
# cp -a with overwrite is the desired "later layer wins" behaviour here.
|
||||||
|
cp -a "$src/." "$TARGET/"
|
||||||
|
}
|
||||||
|
|
||||||
|
apply_layer base
|
||||||
|
apply_layer "$EDITION"
|
||||||
|
log "overlays applied ✓"
|
||||||
27
scripts/build-edition.sh
Executable file
27
scripts/build-edition.sh
Executable file
@@ -0,0 +1,27 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
# Arcline OS — edition build orchestrator
|
||||||
|
#
|
||||||
|
# scripts/build-edition.sh <edition> <stage>
|
||||||
|
# stage: rootfs | iso
|
||||||
|
#
|
||||||
|
# Thin dispatcher so the Makefile can stay dumb.
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
set -euo pipefail
|
||||||
|
source "$(dirname "${BASH_SOURCE[0]}")/common.sh"
|
||||||
|
|
||||||
|
EDITION="${1:?usage: build-edition.sh <edition> <rootfs|iso>}"
|
||||||
|
STAGE="${2:?usage: build-edition.sh <edition> <rootfs|iso>}"
|
||||||
|
validate_edition "$EDITION"
|
||||||
|
|
||||||
|
case "$STAGE" in
|
||||||
|
rootfs)
|
||||||
|
"$ROOT/scripts/build-rootfs.sh" "$EDITION"
|
||||||
|
;;
|
||||||
|
iso)
|
||||||
|
"$ROOT/scripts/build-iso.sh" "$EDITION"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
die "unknown stage '$STAGE' (expected: rootfs | iso)"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
81
scripts/build-iso.sh
Executable file
81
scripts/build-iso.sh
Executable file
@@ -0,0 +1,81 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
# Arcline OS — live ISO builder
|
||||||
|
#
|
||||||
|
# scripts/build-iso.sh <edition>
|
||||||
|
#
|
||||||
|
# Wraps a rootfs into a hybrid (BIOS+UEFI) live ISO:
|
||||||
|
# 1. ensure the rootfs exists (build it with live-boot support if needed)
|
||||||
|
# 2. stage kernel + initramfs + squashfs in isofiles/live
|
||||||
|
# 3. write the grub boot config (live-boot: boot=live)
|
||||||
|
# 4. grub-mkrescue → build/artifacts/arcline-<edition>-<version>-<arch>.iso
|
||||||
|
#
|
||||||
|
# Requires root for the rootfs stage; the ISO assembly itself runs unprivileged.
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
set -euo pipefail
|
||||||
|
source "$(dirname "${BASH_SOURCE[0]}")/common.sh"
|
||||||
|
|
||||||
|
EDITION="${1:?usage: build-iso.sh <edition>}"
|
||||||
|
validate_edition "$EDITION"
|
||||||
|
|
||||||
|
ROOTFS="$ROOTFS_DIR/$EDITION"
|
||||||
|
ISOFILES="$IMAGE_DIR/$EDITION/isofiles"
|
||||||
|
ARTIFACT="$ARTIFACT_DIR/arcline-$EDITION-$VERSION-$ARCH.iso"
|
||||||
|
|
||||||
|
# ── 1. rootfs ───────────────────────────────────────────────────────────────
|
||||||
|
if [[ ! -d "$ROOTFS" ]]; then
|
||||||
|
log "rootfs missing — building with live-boot support"
|
||||||
|
ARCLINE_LIVE=1 "$ROOT/scripts/build-rootfs.sh" "$EDITION"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# live-boot must be present in the rootfs for the ISO to boot
|
||||||
|
if [[ ! -d "$ROOTFS/lib/live" && ! -d "$ROOTFS/usr/lib/live" ]]; then
|
||||||
|
warn "rootfs has no live-boot support; rebuilding with ARCLINE_LIVE=1"
|
||||||
|
ARCLINE_LIVE=1 "$ROOT/scripts/build-rootfs.sh" "$EDITION"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 2. stage files ──────────────────────────────────────────────────────────
|
||||||
|
log "staging ISO files for edition '$EDITION'"
|
||||||
|
rm -rf "$ISOFILES"
|
||||||
|
mkdir -p "$ISOFILES/live" "$ISOFILES/boot/grub"
|
||||||
|
|
||||||
|
KERNEL="$(find "$ROOTFS/boot" -maxdepth 1 -name 'vmlinuz-*' | sort -V | tail -1)"
|
||||||
|
INITRD="$(find "$ROOTFS/boot" -maxdepth 1 -name 'initrd.img-*' | sort -V | tail -1)"
|
||||||
|
[[ -n "$KERNEL" && -n "$INITRD" ]] || die "kernel or initramfs not found in rootfs"
|
||||||
|
cp -L "$KERNEL" "$ISOFILES/live/vmlinuz"
|
||||||
|
cp -L "$INITRD" "$ISOFILES/live/initrd.img"
|
||||||
|
|
||||||
|
log "compressing rootfs → squashfs (this takes a while)"
|
||||||
|
# The squashfs is the live root. Keep it complete — offline man pages and
|
||||||
|
# docs are a product promise (see the landing page), so nothing is excluded.
|
||||||
|
mksquashfs "$ROOTFS" "$ISOFILES/live/arcline.squashfs" -noappend -comp zstd -Xcompression-level 15 2>/dev/null || \
|
||||||
|
mksquashfs "$ROOTFS" "$ISOFILES/live/arcline.squashfs" -noappend -comp xz
|
||||||
|
|
||||||
|
# ── 3. grub boot config ─────────────────────────────────────────────────────
|
||||||
|
log "writing grub config"
|
||||||
|
KCMD="$(tr '\n' ' ' < "$(edition_dir "$EDITION")/kernel.cmdline" | sed 's/ */ /g')"
|
||||||
|
cat > "$ISOFILES/boot/grub/grub.cfg" <<EOF
|
||||||
|
set timeout=5
|
||||||
|
set default=0
|
||||||
|
|
||||||
|
menuentry "Arcline $EDITION ($VERSION)" {
|
||||||
|
linux /live/vmlinuz boot=live config quiet $KCMD
|
||||||
|
initrd /live/initrd.img
|
||||||
|
}
|
||||||
|
|
||||||
|
menuentry "Arcline $EDITION ($VERSION) — safe mode (no mitigations)" {
|
||||||
|
linux /live/vmlinuz boot=live config quiet nomodeset
|
||||||
|
initrd /live/initrd.img
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# ── 4. assemble ─────────────────────────────────────────────────────────────
|
||||||
|
log "assembling ISO with grub-mkrescue"
|
||||||
|
command -v grub-mkrescue >/dev/null || die "grub-mkrescue not found (run scripts/check-host-deps.sh --install)"
|
||||||
|
mkdir -p "$ARTIFACT_DIR"
|
||||||
|
grub-mkrescue -o "$ARTIFACT" "$ISOFILES" -- \
|
||||||
|
-volume-label "ARCLINE_${EDITION^^}" 2>/dev/null || \
|
||||||
|
grub-mkrescue -o "$ARTIFACT" "$ISOFILES"
|
||||||
|
|
||||||
|
log "ISO artifact: $ARTIFACT"
|
||||||
|
sha256sum "$ARTIFACT" | tee "$ARTIFACT.sha256"
|
||||||
143
scripts/build-rootfs.sh
Executable file
143
scripts/build-rootfs.sh
Executable file
@@ -0,0 +1,143 @@
|
|||||||
|
#!/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
|
||||||
|
|
||||||
|
EDIR="$(edition_dir "$EDITION")"
|
||||||
|
ROOTFS="$ROOTFS_DIR/$EDITION"
|
||||||
|
ARTIFACT="$ARTIFACT_DIR/arcline-$EDITION-$VERSION-$ARCH.tar.xz"
|
||||||
|
LIVE="${ARCLINE_LIVE:-0}"
|
||||||
|
|
||||||
|
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})"
|
||||||
|
PKGS="$(grep -vE '^\s*(#|$)' "$EDIR/packages.list" | tr '\n' ' ')"
|
||||||
|
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_LIVE='$LIVE' 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"
|
||||||
53
scripts/check-host-deps.sh
Executable file
53
scripts/check-host-deps.sh
Executable file
@@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
# Arcline OS — host build-dependency check
|
||||||
|
#
|
||||||
|
# scripts/check-host-deps.sh → report what's missing
|
||||||
|
# scripts/check-host-deps.sh --install → apt-get install what's missing
|
||||||
|
#
|
||||||
|
# Builds run debootstrap (rootfs), copy overlays (standard tools), and produce
|
||||||
|
# a hybrid ISO via grub-mkrescue + mksquashfs.
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
set -euo pipefail
|
||||||
|
source "$(dirname "${BASH_SOURCE[0]}")/common.sh"
|
||||||
|
|
||||||
|
NEEDED=(
|
||||||
|
"debootstrap|debootstrap"
|
||||||
|
"grub-mkrescue|grub2-common"
|
||||||
|
"mksquashfs|squashfs-tools"
|
||||||
|
"xorriso|xorriso"
|
||||||
|
"cpio|cpio"
|
||||||
|
"bash|bash"
|
||||||
|
)
|
||||||
|
|
||||||
|
MISSING=()
|
||||||
|
for entry in "${NEEDED[@]}"; do
|
||||||
|
bin="${entry%%|*}"; pkg="${entry##*|}"
|
||||||
|
if ! command -v "$bin" >/dev/null 2>&1; then
|
||||||
|
MISSING+=("$pkg")
|
||||||
|
warn "missing: $bin (package: $pkg)"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ ${#MISSING[@]} -eq 0 ]]; then
|
||||||
|
log "all host build dependencies present ✓"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${1:-}" == "--install" ]]; then
|
||||||
|
log "installing: ${MISSING[*]}"
|
||||||
|
if [[ $EUID -ne 0 ]] && command -v sudo >/dev/null; then
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y "${MISSING[@]}"
|
||||||
|
else
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y "${MISSING[@]}"
|
||||||
|
fi
|
||||||
|
log "dependencies installed ✓"
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
echo "Run the following to install them:"
|
||||||
|
echo " sudo apt-get install -y ${MISSING[*]}"
|
||||||
|
echo "or: scripts/check-host-deps.sh --install"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
67
scripts/common.sh
Executable file
67
scripts/common.sh
Executable file
@@ -0,0 +1,67 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
# Arcline OS — shared build environment + helpers
|
||||||
|
#
|
||||||
|
# Every script under scripts/ sources this first. Values mirror versions.mk;
|
||||||
|
# when invoked through the Makefile the exported variables take precedence, so
|
||||||
|
# versions.mk stays the single source of truth.
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# ── identity ────────────────────────────────────────────────────────────────
|
||||||
|
: "${DISTRO_NAME:=Arcline OS}"
|
||||||
|
: "${DISTRO_ID:=arclineos}"
|
||||||
|
: "${VERSION:=0.1.0}"
|
||||||
|
: "${RELEASE_NAME:=arclines}"
|
||||||
|
: "${DEBIAN_SUITE:=bookworm}"
|
||||||
|
: "${DEBIAN_MIRROR:=http://deb.debian.org/debian}"
|
||||||
|
: "${SECURITY_MIRROR:=http://security.debian.org/debian-security}"
|
||||||
|
: "${ARCH:=amd64}"
|
||||||
|
: "${KERNEL_PACKAGE:=linux-image-amd64}"
|
||||||
|
: "${KERNEL_VERSION:=6.1}"
|
||||||
|
|
||||||
|
# Toolchain policy for image builds:
|
||||||
|
# auto (default) install the Arcline tools if build/debs/*.deb exist,
|
||||||
|
# otherwise build without them (with a warning)
|
||||||
|
# skip never install the tools, even if debs are present
|
||||||
|
# require fail the build if no toolchain debs are available
|
||||||
|
: "${ARCLINE_TOOLCHAIN:=auto}"
|
||||||
|
|
||||||
|
# ── paths (relative to the repo root) ───────────────────────────────────────
|
||||||
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
: "${BUILD_DIR:=$ROOT/build}"
|
||||||
|
: "${ROOTFS_DIR:=$BUILD_DIR/rootfs}"
|
||||||
|
: "${IMAGE_DIR:=$BUILD_DIR/iso}"
|
||||||
|
: "${DEB_DIR:=$BUILD_DIR/debs}"
|
||||||
|
: "${LOG_DIR:=$BUILD_DIR/logs}"
|
||||||
|
: "${ARTIFACT_DIR:=$BUILD_DIR/artifacts}"
|
||||||
|
|
||||||
|
# Valid edition names, mirroring versions.mk.
|
||||||
|
EDITIONS=(server workstation cloud)
|
||||||
|
|
||||||
|
# ── output helpers ──────────────────────────────────────────────────────────
|
||||||
|
log() { printf '\033[1;34m[arcline]\033[0m %s\n' "$*"; }
|
||||||
|
warn() { printf '\033[1;33m[arcline]\033[0m warning: %s\n' "$*" >&2; }
|
||||||
|
die() { printf '\033[1;31m[arcline]\033[0m error: %s\n' "$*" >&2; exit 1; }
|
||||||
|
|
||||||
|
# ── path helpers ────────────────────────────────────────────────────────────
|
||||||
|
edition_dir() { printf '%s/editions/%s' "$ROOT" "$1"; }
|
||||||
|
|
||||||
|
validate_edition() {
|
||||||
|
local e
|
||||||
|
for e in "${EDITIONS[@]}"; do [[ "$e" == "$1" ]] && return 0; done
|
||||||
|
die "unknown edition '$1' (expected: ${EDITIONS[*]})"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── privilege helper ────────────────────────────────────────────────────────
|
||||||
|
# Builds need root (debootstrap / chroot / mount). If we are not root and sudo
|
||||||
|
# is present, re-exec under sudo so the rest of the script can assume root.
|
||||||
|
require_root() {
|
||||||
|
if [[ $EUID -eq 0 ]]; then
|
||||||
|
return 0
|
||||||
|
elif command -v sudo >/dev/null; then
|
||||||
|
exec sudo -E "$0" "$@"
|
||||||
|
else
|
||||||
|
die "build requires root: run with sudo or as root (debootstrap + chroot need it)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
112
scripts/configure-system.sh
Executable file
112
scripts/configure-system.sh
Executable file
@@ -0,0 +1,112 @@
|
|||||||
|
#!/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}"
|
||||||
|
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 <<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)
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# ── 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'"
|
||||||
64
scripts/validate.sh
Executable file
64
scripts/validate.sh
Executable file
@@ -0,0 +1,64 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
# Arcline OS — fast, offline validation of the build tree.
|
||||||
|
#
|
||||||
|
# scripts/validate.sh
|
||||||
|
#
|
||||||
|
# Runs on any machine (no root, no network). Checks:
|
||||||
|
# * every shell script parses (bash -n)
|
||||||
|
# * every edition has a complete manifest (metadata, packages, cmdline, fstab)
|
||||||
|
# * package lists reference no obvious duplicate lines
|
||||||
|
# * the Makefile + versions.mk parse
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
set -euo pipefail
|
||||||
|
source "$(dirname "${BASH_SOURCE[0]}")/common.sh"
|
||||||
|
|
||||||
|
fail=0
|
||||||
|
note_fail() { warn "$1"; fail=1; }
|
||||||
|
|
||||||
|
log "validating shell scripts…"
|
||||||
|
while IFS= read -r -d '' s; do
|
||||||
|
if ! bash -n "$s"; then
|
||||||
|
note_fail "syntax error in $s"
|
||||||
|
fi
|
||||||
|
done < <(find "$ROOT/scripts" "$ROOT/btrfs" "$ROOT/toolchain" "$ROOT/tests" \
|
||||||
|
-name '*.sh' -type f -print0 2>/dev/null)
|
||||||
|
|
||||||
|
log "validating editions…"
|
||||||
|
for e in "${EDITIONS[@]}"; do
|
||||||
|
ed="$(edition_dir "$e")"
|
||||||
|
for f in metadata.yaml packages.list kernel.cmdline fstab; do
|
||||||
|
[[ -f "$ed/$f" ]] || note_fail "edition '$e' missing $f"
|
||||||
|
done
|
||||||
|
|
||||||
|
# package list sanity: no blank-or-comment duplicates
|
||||||
|
if [[ -f "$ed/packages.list" ]]; then
|
||||||
|
dup="$(grep -vE '^\s*(#|$)' "$ed/packages.list" | sort | uniq -d)"
|
||||||
|
[[ -z "$dup" ]] || note_fail "edition '$e' has duplicate package entries: $(echo "$dup" | tr '\n' ' ')"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
log "validating top-level Makefile / versions.mk…"
|
||||||
|
make -C "$ROOT" -n check >/dev/null 2>&1 || note_fail "Makefile dry-run failed (make -n check)"
|
||||||
|
|
||||||
|
log "validating YAML manifests (if python3 + pyyaml available)…"
|
||||||
|
if python3 -c 'import yaml' 2>/dev/null; then
|
||||||
|
python3 - "$ROOT" <<'PYEOF' || note_fail "YAML manifest parse failed"
|
||||||
|
import sys, glob, yaml
|
||||||
|
root = sys.argv[1]
|
||||||
|
for f in sorted(glob.glob(root + "/editions/*/metadata.yaml")):
|
||||||
|
d = yaml.safe_load(open(f))
|
||||||
|
assert d.get("edition") and d.get("codename"), f"{f}: missing edition/codename"
|
||||||
|
assert d.get("image", {}).get("type"), f"{f}: missing image.type"
|
||||||
|
assert "services" in d, f"{f}: missing services"
|
||||||
|
assert isinstance(d["services"].get("enabled", []), list)
|
||||||
|
PYEOF
|
||||||
|
else
|
||||||
|
warn "python3/pyyaml not available — skipping YAML parse (structural checks above still apply)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $fail -eq 0 ]]; then
|
||||||
|
log "validation passed ✓"
|
||||||
|
else
|
||||||
|
die "validation found problems"
|
||||||
|
fi
|
||||||
40
versions.mk
Normal file
40
versions.mk
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
# Arcline OS — version pins & build constants
|
||||||
|
#
|
||||||
|
# Single source of truth for what a build produces. Every script sources this
|
||||||
|
# (directly or via scripts/common.sh) so there is exactly one place to bump a
|
||||||
|
# version or switch the Debian base.
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
# Distro identity
|
||||||
|
DISTRO_NAME := Arcline OS
|
||||||
|
DISTRO_ID := arclineos
|
||||||
|
VERSION := 0.1.0
|
||||||
|
RELEASE_NAME := arclines
|
||||||
|
|
||||||
|
# Debian base we build on. Bookworm = Debian 12 stable.
|
||||||
|
DEBIAN_SUITE := bookworm
|
||||||
|
DEBIAN_MIRROR := http://deb.debian.org/debian
|
||||||
|
SECURITY_MIRROR := http://security.debian.org/debian-security
|
||||||
|
|
||||||
|
# Architecture we target first. amd64 is the primary; arm64 builds are a
|
||||||
|
# stretch goal. Kept in one place so adding arm64 is a one-line change.
|
||||||
|
ARCH := amd64
|
||||||
|
|
||||||
|
# Kernel flavour shipped by the base. Bookworm ships 6.1 LTS.
|
||||||
|
KERNEL_PACKAGE := linux-image-amd64
|
||||||
|
KERNEL_VERSION := 6.1
|
||||||
|
|
||||||
|
# Edition codenames (the "what do I install" flavours).
|
||||||
|
EDITIONS := server workstation cloud
|
||||||
|
|
||||||
|
# Output layout under build/
|
||||||
|
BUILD_DIR := build
|
||||||
|
ROOTFS_DIR := $(BUILD_DIR)/rootfs
|
||||||
|
IMAGE_DIR := $(BUILD_DIR)/iso
|
||||||
|
DEB_DIR := $(BUILD_DIR)/debs
|
||||||
|
LOG_DIR := $(BUILD_DIR)/logs
|
||||||
|
ARTIFACT_DIR := $(BUILD_DIR)/artifacts
|
||||||
|
|
||||||
|
# Toolchain: the 11 Go tools that ship with Arcline OS (see toolchain/).
|
||||||
|
TOOLCHAIN_REPO := https://git.arcline.it/arcline/tools.git
|
||||||
Reference in New Issue
Block a user