- playbook/startnet.cmd + startnet-template.cmd: after preinstall staging, xcopy Y:\pre-install\udc-backups to W:\PreInstall\udc-backups so UDC settings JSONs are available during image deployment. Harvested from live gold where this block existed but was never committed. - scripts/mirror-from-gold.sh: update source paths to current taxonomy layout (pre-install/, installers-post/, blancco/, config/) and add ppkgs/, scripts/, shopfloor-setup/ sections. Added --delete for exact mirror semantics. Used to seed the spare PXE server at 10.9.100.2 on 2026-04-16 from gold at 10.9.100.1. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
193 lines
6.5 KiB
Bash
Executable File
193 lines
6.5 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# mirror-from-gold.sh - Replicate content from an existing PXE server (GOLD)
|
|
# onto a freshly-installed PXE server.
|
|
#
|
|
# Run this ON THE NEW PXE SERVER, pointing at the GOLD server's IP.
|
|
# It pulls Operating Systems, drivers, packages, custom installers, and
|
|
# Blancco assets that are NOT bundled on the USB installer.
|
|
#
|
|
# GOLD is on the taxonomy layout (pre-install/, installers-post/, blancco/,
|
|
# config/, ppkgs/, scripts/, shopfloor-setup/). Source and destination paths
|
|
# are identical per section, so sections can be added trivially as GOLD grows.
|
|
#
|
|
# Usage:
|
|
# sudo ./mirror-from-gold.sh <GOLD_IP> [options]
|
|
#
|
|
# Options:
|
|
# --skip-drivers Do not mirror Dell driver tree (saves ~178G).
|
|
# --skip-dell10 Do not mirror Dell_10 drivers (saves ~179G).
|
|
# --skip-latitude Do not mirror Latitude drivers (saves ~48G).
|
|
# --skip-os Do not mirror Operating Systems (saves ~22G).
|
|
# --dry-run Show what would transfer without doing it.
|
|
#
|
|
# Prereqs:
|
|
# - GOLD's pxe user accepts the SSH key this script generates.
|
|
# - GOLD's filesystem is world-readable for the paths involved
|
|
# (it is, by default).
|
|
|
|
# Note: not using `set -e`. rsync legitimately exits non-zero (e.g. 23
|
|
# "some files/attrs were not transferred") when source dirs have files
|
|
# the rsync user cannot read (the OpenText W10shortcuts dir on GOLD is
|
|
# pxe-upload-group-only). We log and continue instead of aborting.
|
|
set -uo pipefail
|
|
|
|
GOLD="${1:-}"
|
|
shift || true
|
|
|
|
if [ -z "$GOLD" ]; then
|
|
echo "Usage: $0 <GOLD_IP> [--skip-drivers|--skip-dell10|--skip-latitude|--skip-os|--dry-run]"
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$(id -u)" -ne 0 ]; then
|
|
echo "ERROR: must run as root (sudo)."
|
|
exit 1
|
|
fi
|
|
|
|
SKIP_DRIVERS=0
|
|
SKIP_DELL10=0
|
|
SKIP_LATITUDE=0
|
|
SKIP_OS=0
|
|
DRY_RUN=""
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--skip-drivers) SKIP_DRIVERS=1 ;;
|
|
--skip-dell10) SKIP_DELL10=1 ;;
|
|
--skip-latitude) SKIP_LATITUDE=1 ;;
|
|
--skip-os) SKIP_OS=1 ;;
|
|
--dry-run) DRY_RUN="--dry-run" ;;
|
|
*) echo "Unknown option: $1"; exit 1 ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
KEY=/root/.ssh/pxe-mirror-key
|
|
if [ ! -f "$KEY" ]; then
|
|
echo "[setup] Generating mirror SSH key at $KEY"
|
|
mkdir -p /root/.ssh && chmod 700 /root/.ssh
|
|
ssh-keygen -t ed25519 -N '' -f "$KEY" -q
|
|
echo
|
|
echo "Copy the following public key into pxe@$GOLD's ~/.ssh/authorized_keys"
|
|
echo "(easiest: ssh pxe@$GOLD 'mkdir -p ~/.ssh && chmod 700 ~/.ssh' and then"
|
|
echo " scp '$KEY.pub' pxe@$GOLD:~/.ssh/authorized_keys, then chmod 600 there)"
|
|
echo
|
|
cat "$KEY.pub"
|
|
echo
|
|
read -rp "Press enter once the key is installed on GOLD..."
|
|
fi
|
|
|
|
RSH="ssh -i $KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
|
|
|
|
# Quick connectivity check
|
|
echo "[check] Testing key-based SSH to pxe@$GOLD..."
|
|
$RSH "pxe@$GOLD" "whoami" >/dev/null || {
|
|
echo "ERROR: SSH to pxe@$GOLD failed. Install $KEY.pub on GOLD first."
|
|
exit 1
|
|
}
|
|
echo " OK"
|
|
|
|
mirror() {
|
|
local label="$1"
|
|
local src="$2"
|
|
local dest="$3"
|
|
shift 3
|
|
echo
|
|
echo "==== $label ===="
|
|
echo " src: pxe@$GOLD:$src"
|
|
echo " dest: $dest"
|
|
mkdir -p "$dest"
|
|
rsync -aHl --delete --info=progress2 --no-inc-recursive $DRY_RUN "$@" \
|
|
-e "$RSH" \
|
|
"pxe@$GOLD:$src" "$dest" || \
|
|
echo " WARNING: rsync exited rc=$? (likely a permissions issue on source); continuing"
|
|
}
|
|
|
|
# ---------- Shared imaging content (winpeapps/_shared) ----------
|
|
DRIVER_EXCLUDES=()
|
|
[ "$SKIP_DELL10" = "1" ] && DRIVER_EXCLUDES+=(--exclude='Dell_10')
|
|
[ "$SKIP_LATITUDE" = "1" ] && DRIVER_EXCLUDES+=(--exclude='Latitude')
|
|
|
|
if [ "$SKIP_OS" = "0" ]; then
|
|
mirror "Operating Systems (gea-Operating Systems)" \
|
|
"/srv/samba/winpeapps/_shared/gea-Operating Systems/" \
|
|
"/srv/samba/winpeapps/_shared/gea-Operating Systems/"
|
|
fi
|
|
|
|
mirror "Packages (gea-Packages)" \
|
|
"/srv/samba/winpeapps/_shared/gea-Packages/" \
|
|
"/srv/samba/winpeapps/_shared/gea-Packages/"
|
|
|
|
mirror "Sources (gea-Sources)" \
|
|
"/srv/samba/winpeapps/_shared/gea-Sources/" \
|
|
"/srv/samba/winpeapps/_shared/gea-Sources/"
|
|
|
|
if [ "$SKIP_DRIVERS" = "0" ]; then
|
|
mirror "Out-of-box Drivers" \
|
|
"/srv/samba/winpeapps/_shared/Out-of-box Drivers/" \
|
|
"/srv/samba/winpeapps/_shared/Out-of-box Drivers/" \
|
|
"${DRIVER_EXCLUDES[@]}"
|
|
fi
|
|
|
|
# ---------- Per-image-type Deploy/ trees (mostly symlinks to _shared) ----------
|
|
for img in gea-standard gea-engineer gea-shopfloor; do
|
|
mirror "Image dir: $img" \
|
|
"/srv/samba/winpeapps/$img/" \
|
|
"/srv/samba/winpeapps/$img/" \
|
|
--exclude=backup --exclude=logs --exclude='New folder' --exclude=ProMax
|
|
done
|
|
|
|
# ---------- Enrollment-share content (GOLD is on taxonomy layout, src == dest) ----------
|
|
|
|
# Pre-install: installers + bios + preinstall.json + udc-backups
|
|
mirror "Pre-install tree" \
|
|
"/srv/samba/enrollment/pre-install/" \
|
|
"/srv/samba/enrollment/pre-install/" \
|
|
--exclude='*.old'
|
|
|
|
# Post-install installers (CMM PC-DMIS, etc.)
|
|
mirror "Post-install installers" \
|
|
"/srv/samba/enrollment/installers-post/" \
|
|
"/srv/samba/enrollment/installers-post/"
|
|
|
|
# Blancco custom image
|
|
mirror "Blancco images" \
|
|
"/srv/samba/enrollment/blancco/" \
|
|
"/srv/samba/enrollment/blancco/"
|
|
|
|
# Site config (site-config.json, etc.)
|
|
mirror "Enrollment config" \
|
|
"/srv/samba/enrollment/config/" \
|
|
"/srv/samba/enrollment/config/"
|
|
|
|
# Provisioning packages
|
|
mirror "PPKGs" \
|
|
"/srv/samba/enrollment/ppkgs/" \
|
|
"/srv/samba/enrollment/ppkgs/"
|
|
|
|
# Enrollment scripts (run-enrollment.ps1, startnet.cmd, etc.)
|
|
mirror "Enrollment scripts" \
|
|
"/srv/samba/enrollment/scripts/" \
|
|
"/srv/samba/enrollment/scripts/" \
|
|
--exclude='*.pre-*'
|
|
|
|
# Shopfloor-setup tree (per-PC-type scripts + site-config)
|
|
mirror "Shopfloor-setup tree" \
|
|
"/srv/samba/enrollment/shopfloor-setup/" \
|
|
"/srv/samba/enrollment/shopfloor-setup/"
|
|
|
|
# Permissions: anything we just created should be readable by the share
|
|
chown -R root:root /srv/samba/enrollment /srv/samba/winpeapps
|
|
find /srv/samba/enrollment /srv/samba/winpeapps -type d -exec chmod 0755 {} \; 2>/dev/null || true
|
|
find /srv/samba/enrollment /srv/samba/winpeapps -type f -exec chmod 0644 {} \; 2>/dev/null || true
|
|
find /srv/samba/enrollment/ppkgs -name '*.ppkg' -exec chmod 0755 {} \; 2>/dev/null || true
|
|
|
|
echo
|
|
echo "============================================"
|
|
echo "Mirror complete. Verify with:"
|
|
echo " du -sh /srv/samba/winpeapps/_shared/*"
|
|
echo " du -sh /srv/samba/enrollment/*"
|
|
echo " df -h /srv"
|
|
echo "============================================"
|