feat: add disk-deploy core, disk image builder, and installer
- deploy-disk.sh: the shared "write a finished system to a disk" step — partition (GPT bios/efi) -> btrfs layout via btrfs/init.sh -> rsync rootfs -> chroot (real fstab, GRUB, hostname). Carries the optional ARCLINE_SIGN hook; the signing tooling itself lands in a later commit. - apply-fstab.sh: renders the edition fstab template with real root/efi UUIDs and drops the swap line. - build-image.sh: rootfs -> bootable qcow2/raw disk image (sparse file + loop device + deploy), the cloud edition's primary output. - install.sh: scripted installer for a real disk, confirmation-gated. - Makefile: image-<edition> targets (+ minimal variants); build-edition.sh learns the "image" stage; cloud metadata now ships a disk image. - check-host-deps.sh / GitLab CI: add gdisk, parted, rsync, dosfstools, qemu-utils, dpkg, sbsigntool to the build image.
This commit is contained in:
82
scripts/build-image.sh
Executable file
82
scripts/build-image.sh
Executable file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env bash
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Arcline OS — disk image builder (qcow2 / raw)
|
||||
#
|
||||
# scripts/build-image.sh <edition> [--format qcow2|raw] [--size 4G] [--boot bios|efi]
|
||||
#
|
||||
# Produces a bootable disk image (the cloud edition's real output — and useful
|
||||
# for testing server/workstation locally in a VM):
|
||||
#
|
||||
# 1. ensure the rootfs exists (build it if needed)
|
||||
# 2. create a sparse raw file, attach a loop device
|
||||
# 3. deploy-disk.sh writes the finished system (btrfs layout + GRUB + fstab)
|
||||
# 4. optionally qemu-img convert to qcow2
|
||||
# 5. artifact → build/artifacts/arcline-<edition>-<version>-<arch>.<ext> + sha256
|
||||
#
|
||||
# Requires root (for the loop device + deploy step).
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
set -euo pipefail
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/common.sh"
|
||||
|
||||
EDITION="${1:?usage: build-image.sh <edition> [--format qcow2|raw] [--size 4G] [--boot bios|efi]}"
|
||||
FORMAT="qcow2"
|
||||
SIZE="4G"
|
||||
BOOT="bios"
|
||||
|
||||
shift || true
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--format) FORMAT="${2:?}"; shift 2 ;;
|
||||
--size) SIZE="${2:?}"; shift 2 ;;
|
||||
--boot) BOOT="${2:?}"; shift 2 ;;
|
||||
*) die "unknown option '$1'" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
validate_edition "$EDITION"
|
||||
[[ "$FORMAT" == "qcow2" || "$FORMAT" == "raw" ]] || die "--format must be qcow2|raw"
|
||||
[[ "$BOOT" == "bios" || "$BOOT" == "efi" ]] || die "--boot must be bios|efi"
|
||||
require_root "$0" "$@"
|
||||
|
||||
command -v qemu-img >/dev/null || die "missing 'qemu-img' (package: qemu-utils)"
|
||||
command -v losetup >/dev/null || die "missing 'losetup' (package: util-linux)"
|
||||
|
||||
ROOTFS="$ROOTFS_DIR/$EDITION"
|
||||
RAW="$IMAGE_DIR/$EDITION/arcline-$EDITION-$VERSION-$ARCH.raw"
|
||||
EXT="$FORMAT"
|
||||
ARTIFACT="$ARTIFACT_DIR/arcline-$EDITION-$VERSION-$ARCH.$EXT"
|
||||
|
||||
mkdir -p "$IMAGE_DIR/$EDITION" "$ARTIFACT_DIR"
|
||||
rm -f "$RAW" "$ARTIFACT" "$ARTIFACT.sha256"
|
||||
|
||||
# ── 1. rootfs ───────────────────────────────────────────────────────────────
|
||||
if [[ ! -d "$ROOTFS" ]]; then
|
||||
log "rootfs missing — building it first"
|
||||
"$ROOT/scripts/build-rootfs.sh" "$EDITION"
|
||||
fi
|
||||
|
||||
# ── 2. sparse raw file + loop device ────────────────────────────────────────
|
||||
log "creating ${SIZE} sparse image (edition $EDITION, $BOOT boot)"
|
||||
truncate -s "$SIZE" "$RAW"
|
||||
LOOP="$(losetup --find --show --partscan "$RAW")"
|
||||
cleanup() { losetup -d "$LOOP" 2>/dev/null || true; }
|
||||
trap cleanup EXIT
|
||||
log "attached loop device: $LOOP"
|
||||
|
||||
# ── 3. deploy ───────────────────────────────────────────────────────────────
|
||||
"$ROOT/scripts/deploy-disk.sh" "$LOOP" "$ROOTFS" "$EDITION" --boot "$BOOT"
|
||||
|
||||
# ── 4. convert ──────────────────────────────────────────────────────────────
|
||||
losetup -d "$LOOP"
|
||||
trap - EXIT
|
||||
|
||||
if [[ "$FORMAT" == "qcow2" ]]; then
|
||||
log "converting to qcow2"
|
||||
qemu-img convert -f raw -O qcow2 "$RAW" "$ARTIFACT"
|
||||
rm -f "$RAW"
|
||||
else
|
||||
mv "$RAW" "$ARTIFACT"
|
||||
fi
|
||||
|
||||
log "image artifact: $ARTIFACT"
|
||||
sha256sum "$ARTIFACT" | tee "$ARTIFACT.sha256"
|
||||
Reference in New Issue
Block a user