Skip to main content

max / alloy_tui

4.4 KB · 118 lines History Blame Raw
1 #!/usr/bin/env bash
2 #
3 # build-image.sh — build the Alloy bootc image and a bootable artifact
4 # (installer ISO by default) with bootc-image-builder.
5 #
6 # Alloy re-brands os-release (ID=alloy, VERSION_ID=0.0). Two consequences
7 # are handled in the Containerfile (pinned $releasever, disabled build-only
8 # repos) and one here: bootc-image-builder has no distro definition named
9 # "alloy-0.0", so build/alloy-0.0.yaml is bind-mounted into its defs dir.
10 #
11 # Everything runs rootful on purpose: the image build and bib share one
12 # container store, so bib finds the image at /var/lib/containers/storage
13 # without a rootless->rootful copy.
14 #
15 # Usage:
16 # build/build-image.sh # build image + installer ISO
17 # build/build-image.sh --type raw # build image + raw disk image
18 # build/build-image.sh --skip-build # reuse the current image, just run bib
19 # build/build-image.sh --write /dev/sdX # also dd the artifact to a device
20 #
21 # Writing requires an explicit device path and an interactive confirmation.
22
23 set -euo pipefail
24
25 REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
26 IMAGE="localhost/alloy:local"
27 BIB_IMAGE="quay.io/centos-bootc/bootc-image-builder:latest"
28 DEF="$REPO_ROOT/build/alloy-0.0.yaml"
29 OUTPUT="$REPO_ROOT/output"
30
31 TYPE="iso"
32 WRITE_DEV=""
33 SKIP_BUILD=0
34
35 die() { printf 'error: %s\n' "$*" >&2; exit 1; }
36
37 usage() {
38 sed -n '2,20p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'
39 exit "${1:-0}"
40 }
41
42 while [ $# -gt 0 ]; do
43 case "$1" in
44 --type) TYPE="${2:?--type needs a value}"; shift 2 ;;
45 --write) WRITE_DEV="${2:?--write needs a device path}"; shift 2 ;;
46 --skip-build) SKIP_BUILD=1; shift ;;
47 -h|--help) usage 0 ;;
48 *) die "unknown argument: $1 (see --help)" ;;
49 esac
50 done
51
52 command -v podman >/dev/null || die "podman not found"
53 [ -f "$DEF" ] || die "missing distro def: $DEF"
54 [ -f "$REPO_ROOT/Containerfile" ] || die "no Containerfile at $REPO_ROOT"
55
56 # 1. Build the bootc image (rootful, so bib sees it in the same store).
57 if [ "$SKIP_BUILD" -eq 0 ]; then
58 echo "==> Building $IMAGE (rootful)"
59 sudo podman build -t "$IMAGE" "$REPO_ROOT"
60 else
61 echo "==> Skipping image build; reusing $IMAGE"
62 sudo podman image exists "$IMAGE" || die "$IMAGE not in the root store; drop --skip-build"
63 fi
64
65 # 2. Make sure the image builder is present.
66 sudo podman image exists "$BIB_IMAGE" || {
67 echo "==> Pulling $BIB_IMAGE"
68 sudo podman pull "$BIB_IMAGE"
69 }
70
71 # 3. Build the artifact. The alloy-0.0 def is mounted read-only into bib's
72 # defs directory; librepo (the default) resolves repos from the image.
73 echo "==> Building --type $TYPE into $OUTPUT"
74 mkdir -p "$OUTPUT"
75 sudo rm -rf "${OUTPUT:?}/"* 2>/dev/null || true
76 sudo podman run --rm --privileged \
77 --security-opt label=type:unconfined_t \
78 -v /var/lib/containers/storage:/var/lib/containers/storage \
79 -v "$OUTPUT":/output \
80 -v "$DEF":/usr/share/bootc-image-builder/defs/alloy-0.0.yaml:ro \
81 "$BIB_IMAGE" \
82 --type "$TYPE" \
83 --log-level info \
84 "$IMAGE"
85
86 # 4. Locate the produced artifact.
87 case "$TYPE" in
88 iso) ARTIFACT="$OUTPUT/bootiso/install.iso" ;;
89 raw) ARTIFACT="$OUTPUT/image/disk.raw" ;;
90 qcow2) ARTIFACT="$OUTPUT/qcow2/disk.qcow2" ;;
91 *) ARTIFACT="$(sudo find "$OUTPUT" -type f ! -name '*.json' | head -1)" ;;
92 esac
93 [ -n "$ARTIFACT" ] && sudo test -f "$ARTIFACT" || die "expected artifact not found for type $TYPE"
94 echo "==> Built: $ARTIFACT ($(sudo du -h "$ARTIFACT" | cut -f1))"
95
96 # 5. Optionally write to a device.
97 if [ -n "$WRITE_DEV" ]; then
98 [ -b "$WRITE_DEV" ] || die "$WRITE_DEV is not a block device"
99 # Refuse to write to a disk that carries a mounted filesystem (root disk guard).
100 if lsblk -nro MOUNTPOINT "$WRITE_DEV" | grep -qE '^/$|^/boot'; then
101 die "$WRITE_DEV has a system mountpoint; refusing to write"
102 fi
103 echo
104 lsblk -o NAME,SIZE,TYPE,MOUNTPOINT,MODEL,SERIAL,TRAN "$WRITE_DEV"
105 echo
106 printf 'This ERASES all data on %s. Type the device path to confirm: ' "$WRITE_DEV"
107 read -r reply
108 [ "$reply" = "$WRITE_DEV" ] || die "confirmation did not match; not writing"
109 echo "==> Writing $ARTIFACT to $WRITE_DEV"
110 sudo dd if="$ARTIFACT" of="$WRITE_DEV" bs=4M oflag=direct conv=fsync status=progress
111 sync
112 echo "==> Done. $WRITE_DEV is now a bootable Alloy $TYPE."
113 else
114 echo "==> To write it to a USB stick:"
115 echo " sudo dd if=$ARTIFACT of=/dev/sdX bs=4M oflag=direct conv=fsync status=progress"
116 echo " (or re-run with --write /dev/sdX to rebuild and write in one step)"
117 fi
118