Files
pxe-server/scripts/stage-usb-share.sh
cproudlock 5f7954ac88 Share folder for other sites: no WJ Blancco release or Wi-Fi password
stage-usb-share.sh --no-blancco-release leaves out boot-tools/blancco's
vendor release (config.img carries this site's licensing Wi-Fi password and
location) and the unused blancco-uki.efi. The KB's Part 4 now has the site
load its own Blancco 7.20 ISO on Updates > Blancco releases. The Wi-Fi
password is gone from SITE-CUSTOMIZATION.md.
2026-10-17 11:51:46 -04:00

125 lines
5.3 KiB
Bash
Executable File

#!/bin/bash
#
# stage-usb-share.sh - Put everything Build-PxeUsb.ps1 needs into a folder
# on a share, so a Windows PC can build the installer USB from it.
#
# Usage:
# scripts/stage-usb-share.sh [--iso FILE] [--payload-root DIR] [--no-blancco-release] [DEST]
#
# DEST defaults to ~/pxe-images/pxe-usb (the [pxe-images] Samba share; on
# the work PC: \\<this PC>\pxe-images\pxe-usb, usually Z:\pxe-usb). It gets:
# - the repo as committed (git archive HEAD: uncommitted edits are NOT
# staged, so the stick matches a commit);
# - the payload folders (offline-packages, pip-wheels, boot-files,
# boot-tools, enrollment, bios-staging, drivers-staging, site-content)
# as hard links, so they cost no extra disk space;
# - the Ubuntu ISO offline-packages/ was built for (hard link);
# - STAGED.txt: commit, date, sizes.
# Then on the work PC: copy the folder to a local disk (C:\pxe-usb) and
# double-click Build-PxeUsb.cmd (KB: docs/kb/How_To_Deploy_PXE_Server_New_Site.html).
#
# --no-blancco-release leaves out the Blancco release (the vendor files from
# boot-tools/blancco: kernel, initramfs, microcode, rootfs, and config.img
# with this site's preferences and licence files) and the unused
# blancco-uki.efi. Use it for a folder going to another site: that site
# uploads its own Blancco ISO on Updates > Blancco releases.
#
# The new copy is built beside the old one and swapped in when complete.
# Run capture-site-content.sh --apply first so site-content/ is current.
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "$0")"/.. && pwd)"
PAYLOAD_ROOT="$REPO_ROOT"
ISO=""
DEST=""
NO_BLANCCO_RELEASE=0
while [ $# -gt 0 ]; do
case "$1" in
--iso) ISO="${2:?}"; shift 2 ;;
--payload-root) PAYLOAD_ROOT="$(cd "${2:?}" && pwd)"; shift 2 ;;
--no-blancco-release) NO_BLANCCO_RELEASE=1; shift ;;
-h|--help) sed -n '2,/^$/p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
-*) echo "unknown option $1" >&2; exit 2 ;;
*) DEST="$1"; shift ;;
esac
done
DEST="${DEST:-$HOME/pxe-images/pxe-usb}"
mkdir -p "$(dirname "$DEST")"
DEST="$(cd "$(dirname "$DEST")" && pwd)/$(basename "$DEST")"
# Only ever replace a folder this script made (it is swapped and deleted).
if [ -e "$DEST" ] && [ ! -f "$DEST/STAGED.txt" ]; then
echo "ERROR: $DEST exists and was not made by this script (no STAGED.txt); refusing to replace it" >&2
exit 1
fi
# The ISO the offline set was resolved for (BUILD-INFO names it).
if [ -z "$ISO" ]; then
name=$(sed -n 's/.*--iso \([^ ]*\.iso\).*/\1/p' "$PAYLOAD_ROOT/offline-packages/BUILD-INFO.txt" 2>/dev/null | head -1)
name=$(basename "${name:-}")
for d in "$PAYLOAD_ROOT" "$PAYLOAD_ROOT/iso" "${PXETEST_CACHE:-$HOME/.cache/pxetest}"; do
[ -n "$name" ] && [ -f "$d/$name" ] && { ISO="$d/$name"; break; }
done
[ -n "$ISO" ] || { echo "ERROR: give --iso FILE (the offline set was built for ${name:-an unknown ISO})" >&2; exit 1; }
fi
[ -f "$ISO" ] || { echo "ERROR: ISO not found: $ISO" >&2; exit 1; }
same_fs() { [ "$(stat -c %d "$1")" = "$(stat -c %d "$2")" ]; }
NEW="$DEST.new.$$"
OLD="$DEST.old.$$"
cleanup() { [ -d "$NEW" ] && rm -rf -- "$NEW"; return 0; }
trap cleanup EXIT
mkdir -p "$NEW"
cd "$REPO_ROOT"
COMMIT=$(git rev-parse --short HEAD)
if ! git diff --quiet HEAD -- autoinstall playbook scripts webapp; then
echo "NOTE: uncommitted changes in autoinstall/playbook/scripts/webapp are NOT staged (HEAD $COMMIT is)."
fi
echo "Repo $COMMIT -> $NEW"
git archive HEAD | tar -x -C "$NEW"
link_or_copy() { # SRC DST
if same_fs "$1" "$(dirname "$2")"; then cp -al "$1" "$2"; else cp -a "$1" "$2"; fi
}
for d in offline-packages pip-wheels boot-files boot-tools enrollment bios-staging drivers-staging site-content; do
src="$PAYLOAD_ROOT/$d"
[ -d "$src" ] || { echo " $d: not in $PAYLOAD_ROOT (skipped)"; continue; }
# git archive brings the tracked bits of boot-files/ and boot-tools/; the
# payload folder replaces them whole.
rm -rf -- "${NEW:?}/$d"
link_or_copy "$src" "$NEW/$d"
printf ' %-17s %s\n' "$d" "$(du -sh "$NEW/$d" | cut -f1)"
done
if [ "$NO_BLANCCO_RELEASE" = 1 ]; then
# Hard links: removing them here leaves the payload copies alone.
B="$NEW/boot-tools/blancco"
rm -rf -- "$B/arch" "$B/vmlinuz-bde-linux" "$B/initramfs-bde-linux.img" \
"$B/intel-ucode.img" "$B/amd-ucode.img" "$B/config.img" "$B/blancco-uki.efi"
echo " Blancco release left out (--no-blancco-release)"
fi
link_or_copy "$ISO" "$NEW/$(basename "$ISO")"
echo " ISO $(basename "$ISO")"
{
echo "Staged by scripts/stage-usb-share.sh $(date -Is)"
echo "Commit: $(git log -1 --format='%h %s')"
echo "ISO: $(basename "$ISO")"
echo "Payload root: $PAYLOAD_ROOT"
[ "$NO_BLANCCO_RELEASE" = 1 ] && echo "Blancco release: not included (upload one on Updates > Blancco releases)"
echo
echo "On the Windows PC:"
echo " 1. Copy this whole folder to a local disk, e.g. C:\\pxe-usb"
echo " 2. Double-click C:\\pxe-usb\\Build-PxeUsb.cmd (asks for admin, lists USB disks)"
echo " Instructions: docs\\kb\\How_To_Deploy_PXE_Server_New_Site.html"
} >"$NEW/STAGED.txt"
if [ -e "$DEST" ]; then mv -- "$DEST" "$OLD"; fi
mv -- "$NEW" "$DEST"
[ -e "$OLD" ] && rm -rf -- "$OLD"
trap - EXIT
echo "Staged: $DEST ($(du -sh "$DEST" | cut -f1) apparent, hard-linked payload)"