Everything West Jefferson specific moved out to a separate repo (pxe-site-wj): NTLARS/UDC/heat-treat backups keyed by WJ machine numbers, CMM and Wax/Trace bay lists, WJ OpenText profiles, site-config.json, the WJ preinstall list, and the WJ shopfloor PC types (Collections, NoCollections, Common, Keyence, CMM, Genspect, HeatTreat, Wax/Trace, Display, PartMarker) with GE-Enforce, machine numbers and the desktop layout. The part-marker bench tools moved to their own repo. Dead scripts removed: build-proxmox-iso, deploy-bios, sync_hardware_models, mirror-from-gold, pull-bios, startnet-template.cmd. Shopfloor is one generic type, gea-shopfloor-standard, with today's timing: - PPKG at first logon (unattend Order 10, unchanged). - Install-AppList.ps1 runs C:\PreInstall\preinstall.json during setup. - A new SYSTEM task, GE Shopfloor Post-PPKG, runs postppkg.json once after the post-PPKG reboot. It also clears AutoLogonCount after the ShopFloor handover (the Users-level monitor can be denied that HKLM write) and removes the Intune Sync task when done. - Both lists ship empty. A site adds entries and installers. - WinPE choice 3 goes straight to the PPKG menu. Staging, fetch and heal carry only the generic payload. The webapp's shopfloor sub-menu editor is gone, and the imaging tiles name the new stages. - The playbook deploys the empty lists only if missing. It now deploys the PowerShell 7 MSI the shopfloor unattend installs, which it never did before. Blancco site settings move into the webapp (Updates > Blancco releases): business location, licensing Wi-Fi SSID and password. They are rendered into the served preferences.xml and applied to every staged release, and are seeded from site-vars (site_name, blancco_wifi_ssid, blancco_wifi_password) only while none exist. The repo XML carries no site values; the plaintext Wi-Fi password is gone from it. New site_name and site_timezone settings: report and evidence-pack site name, server clock and webapp time zone. No more West Jefferson defaults in webapp/config.py or the dashboard title. Sync-BPRT.ps1 gets the server address filled in at download instead of WJ's GE address. USB on Windows: - scripts/Build-PxeUsb.ps1 runs the same checks as build-usb.sh. It writes one FAT32 CIDATA partition (ISO files plus patched grub.cfg plus payload) with diskpart and reads every file back by SHA-256. - Tested with Windows PowerShell 5.1 in the win11 VM, and the layout installs and first-boots in the pxetest VM. - scripts/stage-usb-share.sh stages the build folder on a share. - site-content/ is optional for both builders. KB docs/kb/How_To_Deploy_PXE_Server_New_Site.html: new-site deployment, Windows only, with a site-vars.yml guide. Checks: webapp tests pass (5 suites); the unattend lint and playbook syntax checks pass; every .ps1 parses; there are no WJ hosts, IPs, names or PC types in playbook/, webapp/, scripts/ or autoinstall/.
109 lines
4.3 KiB
Bash
Executable File
109 lines
4.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] [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).
|
|
#
|
|
# 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=""
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--iso) ISO="${2:?}"; shift 2 ;;
|
|
--payload-root) PAYLOAD_ROOT="$(cd "${2:?}" && pwd)"; shift 2 ;;
|
|
-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
|
|
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"
|
|
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)"
|