Files
os-build/scripts/build-image.sh
Blake Ridgway 0361c12c07 fix: resolve grub-pc / grub-efi-amd64 "held broken packages" conflict
The edition package lists installed BOTH grub-pc and grub-efi-amd64
(+ shim-signed). Those provide the same bootloader role and conflict in
apt, so every rootfs build failed with "unable to correct problems, you
have held broken packages".

A rootfs now carries exactly ONE bootloader, chosen by the BOOT variable
(mirroring the existing --boot bios|efi deploy option):

- versions.mk / common.sh: BOOT := bios (bios -> grub-pc,
  efi -> grub-efi-amd64 + shim-signed + mokutil), exported via the
  Makefile.
- build-rootfs.sh validates BOOT early and injects the matching boot
  packages into the apt install; the static package lists no longer
  contain any grub package.
- deploy-disk.sh / build-image.sh / install.sh default --boot from the
  same BOOT variable, so a rootfs and the artifact deployed from it can
  never disagree (BOOT=efi make image-cloud produces a UEFI image).
- mokutil is now installed explicitly in the efi flavour (it was not
  pulled in because we install with --no-install-recommends).
- docs updated (building.md knob + rationale, secureboot.md note).
2026-08-21 14:15:10 -05:00

83 lines
3.7 KiB
Bash
Executable File

#!/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="${BOOT:-bios}" # default from the BOOT build variable (see versions.mk)
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"