save
This commit is contained in:
76
build-iso.sh
76
build-iso.sh
@@ -14,7 +14,7 @@
|
||||
#
|
||||
# USAGE:
|
||||
# ./build-iso.sh
|
||||
# ./build-iso.sh --ubuntu-iso ~/Downloads/ubuntu-24.04-live-server-amd64.iso
|
||||
# ./build-iso.sh --ubuntu-iso ~/Downloads/ubuntu-24.04.4-live-server-amd64.iso
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@@ -24,10 +24,14 @@ UBUNTU_ISO_URL="https://releases.ubuntu.com/${UBUNTU_VERSION}/ubuntu-${UBUNTU_VE
|
||||
WORK_DIR="$(mktemp -d /tmp/autoinstall-build.XXXXXX)"
|
||||
OUTPUT_ISO="autoinstall-$(date +%Y%m%d-%H%M).iso"
|
||||
SOPS_FILE="secrets.sops.yaml"
|
||||
TEMPLATE_FILE="user-data.tmpl"
|
||||
RENDERED_FILE="user-data.yaml"
|
||||
TEMPLATE_DIR="templates"
|
||||
# TEMPLATE_FILE="user-data.tmpl"
|
||||
# RENDERED_FILE="user-data.yaml"
|
||||
POST_INSTALL_SCRIPT="scripts/post-install.sh"
|
||||
|
||||
NOCLOUD_DIR="$WORK_DIR/iso/nocloud"
|
||||
mkdir -p "$NOCLOUD_DIR"
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
@@ -52,42 +56,28 @@ done
|
||||
cleanup() {
|
||||
info "Cleaning up..."
|
||||
rm -rf "$WORK_DIR"
|
||||
if [[ -f "$RENDERED_FILE" ]]; then
|
||||
rm -f "$RENDERED_FILE"
|
||||
info "Deleted plaintext $RENDERED_FILE"
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
for cmd in sops envsubst xorriso; do
|
||||
command -v "$cmd" &>/dev/null || error "'$cmd' not found. Install it first."
|
||||
done
|
||||
[[ -f "$SOPS_FILE" ]] || error "Secrets file '$SOPS_FILE' not found."
|
||||
[[ -f "$TEMPLATE_FILE" ]] || error "Template '$TEMPLATE_FILE' not found."
|
||||
[[ -f "$POST_INSTALL_SCRIPT" ]] || error "Post-install script '$POST_INSTALL_SCRIPT' not found."
|
||||
[[ -f ".sops.yaml" ]] || error ".sops.yaml not found in current directory."
|
||||
|
||||
export SOPS_AGE_KEY_FILE="${SOPS_AGE_KEY_FILE:-$HOME/.config/sops/age/keys.txt}"
|
||||
[[ -f "$SOPS_AGE_KEY_FILE" ]] || error "age key not found at $SOPS_AGE_KEY_FILE"
|
||||
|
||||
# ── Decrypt secrets → render template ─────────────────────────────────────────
|
||||
info "Decrypting secrets and rendering template..."
|
||||
sops exec-env "$SOPS_FILE" "envsubst < $TEMPLATE_FILE > $RENDERED_FILE"
|
||||
sops exec-env "$SOPS_FILE" "envsubst < $TEMPLATE_DIR/user-data.tmpl > $NOCLOUD_DIR/user-data"
|
||||
sops exec-env "$SOPS_FILE" "envsubst '\$WIFI_HOUSE_PASSWORD \$NOKIA_WIFI_KEY_PASSWORD' < $TEMPLATE_DIR/user-data-wifi.tmpl > $NOCLOUD_DIR/user-data-wifi.config"
|
||||
|
||||
if grep -qE '\$\{[A-Z_]+\}' "$RENDERED_FILE"; then
|
||||
warn "Some variables were NOT substituted:"
|
||||
grep -oE '\$\{[A-Z_]+\}' "$RENDERED_FILE" | sort -u | sed 's/^/ /'
|
||||
error "Add the missing keys to secrets.yaml and re-encrypt."
|
||||
fi
|
||||
info "Template rendered."
|
||||
|
||||
# ── Get Ubuntu ISO ─────────────────────────────────────────────────────────────
|
||||
if [[ -n "$UBUNTU_ISO" ]]; then
|
||||
# User provided a path — validate it exists
|
||||
[[ -f "$UBUNTU_ISO" ]] || error "ISO not found: $UBUNTU_ISO"
|
||||
info "Using provided ISO: $UBUNTU_ISO"
|
||||
else
|
||||
# Auto mode — use default name, download if missing
|
||||
# UBUNTU_ISO="ubuntu-${UBUNTU_VERSION}-desktop-amd64.iso"
|
||||
UBUNTU_ISO="ubuntu-${UBUNTU_VERSION}-live-server-amd64.iso"
|
||||
if [[ ! -f "$UBUNTU_ISO" ]]; then
|
||||
info "Downloading Ubuntu ${UBUNTU_VERSION} server ISO..."
|
||||
@@ -101,29 +91,63 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── Extract ISO + MBR template ────────────────────────────────────────────────
|
||||
# ── Extract ISO ────────────────────────────────────────────────────────────────
|
||||
info "Extracting ISO..."
|
||||
xorriso -osirrox on -indev "$UBUNTU_ISO" -extract / "$WORK_DIR/iso" 2>/dev/null
|
||||
chmod -R u+w "$WORK_DIR/iso"
|
||||
|
||||
# Extract MBR template directly from the original ISO (first 432 bytes)
|
||||
# boot_hybrid.img is NOT present in the extracted filesystem on 24.04
|
||||
dd if="$UBUNTU_ISO" bs=1 count=432 of="$WORK_DIR/mbr_template.bin" 2>/dev/null
|
||||
|
||||
# ── Inject autoinstall files ───────────────────────────────────────────────────
|
||||
info "Injecting autoinstall config and post-install script..."
|
||||
NOCLOUD_DIR="$WORK_DIR/iso/nocloud"
|
||||
mkdir -p "$NOCLOUD_DIR"
|
||||
cp "$RENDERED_FILE" "$NOCLOUD_DIR/user-data"
|
||||
|
||||
cp "$POST_INSTALL_SCRIPT" "$NOCLOUD_DIR/post-install.sh"
|
||||
cp "scripts/wifi.sh" "$NOCLOUD_DIR/wifi.sh"
|
||||
touch "$NOCLOUD_DIR/meta-data"
|
||||
|
||||
# ── Patch GRUB ────────────────────────────────────────────────────────────────
|
||||
GRUB_CFG="$WORK_DIR/iso/boot/grub/grub.cfg"
|
||||
if [[ -f "$GRUB_CFG" ]]; then
|
||||
info "Patching GRUB for unattended boot..."
|
||||
sed -i 's|linux\s*/casper/vmlinuz\(.*\)|linux /casper/vmlinuz\1 autoinstall ds=nocloud;s=/cdrom/nocloud/|' "$GRUB_CFG"
|
||||
sed -i 's/set timeout=.*/set timeout=0/' "$GRUB_CFG"
|
||||
cat >"$WORK_DIR/grub_prepend.cfg" <<'GRUBENTRY'
|
||||
set default=0
|
||||
set timeout=1
|
||||
|
||||
menuentry "Autoinstall Ubuntu" {
|
||||
set gfxpayload=keep
|
||||
linux /casper/vmlinuz quiet autoinstall ds=nocloud\;s=/cdrom/nocloud/ ---
|
||||
initrd /casper/initrd
|
||||
}
|
||||
|
||||
GRUBENTRY
|
||||
# Prepend our entry, then append the original (so manual install is still reachable)
|
||||
cat "$WORK_DIR/grub_prepend.cfg" "$GRUB_CFG" >"$WORK_DIR/grub_merged.cfg"
|
||||
mv "$WORK_DIR/grub_merged.cfg" "$GRUB_CFG"
|
||||
fi
|
||||
|
||||
# ── Repack ISO ─────────────────────────────────────────────────────────────────
|
||||
info "Repacking ISO → $OUTPUT_ISO ..."
|
||||
xorriso -as mkisofs \
|
||||
-r -V "Ubuntu-AutoInstall" -o "$OUTPUT_ISO" \
|
||||
-J -joliet-long \
|
||||
--grub2-mbr "$WORK_DIR/mbr_template.bin" \
|
||||
--protective-msdos-label \
|
||||
-partition_offset 16 \
|
||||
--mbr-force-bootable \
|
||||
-append_partition 2 28732ac11ff8d211ba4b00a0c93ec93b \
|
||||
--interval:local_fs:1s-300s::"$UBUNTU_ISO" \
|
||||
-appended_part_as_gpt \
|
||||
-iso_mbr_part_type a2a0d0ebe5b9334487c068b6b72699c7 \
|
||||
-c '/boot.catalog' \
|
||||
-b '/boot/grub/i386-pc/eltorito.img' \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||
--grub2-boot-info \
|
||||
-eltorito-alt-boot \
|
||||
-e '--interval:appended_partition_2:::' \
|
||||
-no-emul-boot \
|
||||
"$WORK_DIR/iso"
|
||||
|
||||
info "Done! ✓"
|
||||
echo ""
|
||||
|
||||
Reference in New Issue
Block a user