#!/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. # # Source paths on GOLD use the legacy flat enrollment layout. Destination # paths on the new server use the reorganized layout (ppkgs/, scripts/, # config/, pre-install/, installers-post/, blancco/, etc). # # Usage: # sudo ./mirror-from-gold.sh [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 [--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 --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 with path translation (flat -> taxonomy) ---------- # Preinstall installers (adobe, opentext, drivers, display, vcredist, UDC, Oracle, etc.) mirror "Pre-install installers" \ "/srv/samba/enrollment/preinstall/installers/" \ "/srv/samba/enrollment/pre-install/installers/" \ --exclude='*.old' # CMM installers (PCDMIS) - flat dir on GOLD becomes installers-post/cmm/ mirror "CMM installers (PCDMIS)" \ "/srv/samba/enrollment/cmm-installers/" \ "/srv/samba/enrollment/installers-post/cmm/" # Blancco custom image - flat file on GOLD becomes blancco/ echo echo "==== Blancco custom image ====" mkdir -p /srv/samba/enrollment/blancco rsync -aHl --info=progress2 $DRY_RUN \ -e "$RSH" \ "pxe@$GOLD:/srv/samba/enrollment/BDE715_GEAE_INTERNET.img.gz" \ "/srv/samba/enrollment/blancco/" # Site-specific config file echo echo "==== Site config (site-config.json) ====" echo " Verifying GOLD's copy is more recent than playbook default..." rsync -avhl $DRY_RUN -e "$RSH" \ "pxe@$GOLD:/srv/samba/enrollment/site-config.json" \ "/srv/samba/enrollment/config/site-config.json" 2>/dev/null || \ echo " (no site-config.json at flat path on GOLD - skipping)" # 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 "============================================"