Generic build for other GE sites: no WJ data, one shopfloor type, Windows USB builder
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/.
This commit is contained in:
108
scripts/stage-usb-share.sh
Executable file
108
scripts/stage-usb-share.sh
Executable file
@@ -0,0 +1,108 @@
|
||||
#!/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)"
|
||||
Reference in New Issue
Block a user