Eliminate USB requirement for WinPE PXE boot, add image upload script

- Add startnet.cmd: FlatSetupLoader.exe + Boot.tag/Media.tag eliminates
  physical USB requirement for WinPE PXE deployment
- Add Upload-Image.ps1: PowerShell script to robocopy MCL cached images
  to PXE server via SMB (Deploy, Tools, Sources)
- Add gea-shopfloor-mce image type across playbook, webapp, startnet
- Change webapp import to move (not copy) for upload sources to save disk
- Add Samba symlink following config for shared image directories
- Add Media.tag creation task in playbook for drive detection
- Update prepare-boot-tools.sh with Blancco config/initramfs patching
- Add grub-efi-amd64-bin to download-packages.sh

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-02-12 16:40:27 -05:00
parent f4c158a5ac
commit 1a5c4f7124
7 changed files with 696 additions and 38 deletions

View File

@@ -37,6 +37,7 @@
- gea-standard
- gea-engineer
- gea-shopfloor
- gea-shopfloor-mce
- ge-standard
- ge-engineer
- ge-shopfloor-lockdown
@@ -95,6 +96,33 @@
debug:
msg: "Using {{ pxe_iface }} for DHCP/TFTP"
- name: "Expand root partition and filesystem to use full disk"
args:
executable: /bin/bash
shell: |
# Find the root LV device
ROOT_DEV=$(findmnt -n -o SOURCE /)
ROOT_DISK=$(lsblk -n -o PKNAME $(readlink -f "$ROOT_DEV") | tail -1)
if [ -z "$ROOT_DISK" ]; then
echo "Could not determine root disk, skipping"
exit 0
fi
# Find the partition number for the LVM PV
PV_PART=$(pvs --noheadings -o pv_name | tr -d ' ' | head -1)
if [ -z "$PV_PART" ]; then
echo "No LVM PV found, skipping"
exit 0
fi
PART_NUM=$(echo "$PV_PART" | grep -o '[0-9]*$')
echo "Expanding /dev/${ROOT_DISK} partition ${PART_NUM} (${PV_PART})..."
growpart "/dev/${ROOT_DISK}" "${PART_NUM}" 2>&1 || true
pvresize "$PV_PART" 2>&1
lvextend -l +100%FREE "$ROOT_DEV" 2>&1 || true
resize2fs "$ROOT_DEV" 2>&1
echo "Disk: $(df -h / | tail -1)"
register: disk_expand
changed_when: "'CHANGED' in disk_expand.stdout or 'resized' in disk_expand.stdout"
- name: "Configure dnsmasq for DHCP and TFTP"
copy:
dest: /etc/dnsmasq.conf
@@ -158,9 +186,9 @@
menu GE Aerospace PXE Boot Menu
item --gap -- ---- Windows Deployment ----
item winpe Windows PE (Image Deployment)
item --gap -- ---- Utilities ----
item clonezilla Clonezilla Live (Disk Imaging)
item --gap -- ---- Utilities (Secure Boot must be DISABLED) ----
item blancco Blancco Drive Eraser
item clonezilla Clonezilla Live (Disk Imaging)
item memtest Memtest86+ (Memory Diagnostics)
item --gap -- ----
item reboot Reboot
@@ -168,6 +196,13 @@
choose --default winpe --timeout 30000 target && goto ${target}
:winpe
echo
echo Windows deployment requires Secure Boot to be ENABLED.
echo If you disabled it for Blancco/Clonezilla, re-enable it now.
echo
prompt --timeout 5000 Press any key to continue (auto-boot in 5s)... && goto winpe_boot || goto winpe_boot
:winpe_boot
kernel http://${server}/win11/wimboot gui
initrd http://${server}/win11/EFI/Microsoft/Boot/boot.stl EFI/Microsoft/Boot/Boot.stl
initrd http://${server}/win11/EFI/Microsoft/Boot/BCD EFI/Microsoft/Boot/BCD
@@ -178,20 +213,34 @@
:clonezilla
set base http://${server}/clonezilla
kernel ${base}/vmlinuz boot=live username=user union=overlay config components noswap edd=on nomodeset nodmraid locales= keyboard-layouts= ocs_live_run="ocs-live-general" ocs_live_extra_param="" ocs_live_batch=no net.ifnames=0 nosplash noprompt fetch=${base}/filesystem.squashfs
kernel ${base}/vmlinuz boot=live username=user union=overlay config components noswap edd=on nomodeset nodmraid locales= keyboard-layouts= ocs_live_run="ocs-live-general" ocs_live_extra_param="" ocs_live_batch=no net.ifnames=0 nosplash noprompt fetch=${base}/filesystem.squashfs || goto secureboot_warn
initrd ${base}/initrd.img
boot
:blancco
set bbase http://${server}/blancco
kernel ${bbase}/vmlinuz-bde-linux archisobasedir=arch archiso_http_srv=http://${server}/blancco/ copytoram=y cow_spacesize=50% memtest=00 vmalloc=400M ip=dhcp quiet nomodeset libata.allow_tpm=1
initrd ${bbase}/intel-ucode.img ${bbase}/amd-ucode.img ${bbase}/config.img ${bbase}/initramfs-bde-linux.img
boot
chain http://${server}/blancco/grubx64.efi || goto secureboot_warn
:memtest
kernel http://${server}/memtest/memtest.efi
kernel http://${server}/memtest/memtest.efi || goto secureboot_warn
boot
:secureboot_warn
echo
echo ======================================================
echo This option requires Secure Boot to be DISABLED.
echo
echo 1. Reboot this machine
echo 2. Press F2 / Del to enter BIOS Setup
echo 3. Disable Secure Boot
echo 4. Save and exit BIOS
echo 5. PXE boot again and select this option
echo
echo Re-enable Secure Boot after completing the task.
echo ======================================================
echo
prompt Press any key to return to menu...
goto menu
:reboot
reboot
@@ -248,6 +297,25 @@
state: directory
mode: '0777'
- name: "Create image upload staging directory"
file:
path: /home/pxe/image-upload
state: directory
mode: '0777'
owner: pxe
group: pxe
- name: "Enable Samba symlink following (shared image dirs)"
blockinfile:
path: /etc/samba/smb.conf
backup: yes
marker: "# {mark} MANAGED - GLOBAL SYMLINKS"
insertafter: '\[global\]'
block: |
follow symlinks = yes
wide links = yes
unix extensions = no
- name: "Configure Samba shares"
blockinfile:
path: /etc/samba/smb.conf
@@ -257,22 +325,48 @@
path = {{ samba_share }}
browseable = yes
read only = no
guest ok = yes
guest ok = no
valid users = pxe-upload
force user = root
[clonezilla]
path = /srv/samba/clonezilla
browseable = yes
read only = no
guest ok = yes
guest ok = no
valid users = pxe-upload
force user = root
comment = Clonezilla backup images
[blancco-reports]
path = /srv/samba/blancco-reports
browseable = yes
read only = no
guest ok = yes
guest ok = no
valid users = pxe-upload blancco
force user = root
comment = Blancco Drive Eraser reports
[image-upload]
path = /home/pxe/image-upload
browseable = yes
read only = no
guest ok = no
valid users = pxe-upload
force user = pxe
force group = pxe
comment = PXE image upload staging area
- name: "Create Samba users (pxe-upload and blancco)"
shell: |
id pxe-upload >/dev/null 2>&1 || useradd -M -s /usr/sbin/nologin pxe-upload
echo -e 'pxe\npxe' | smbpasswd -a pxe-upload -s
id blancco >/dev/null 2>&1 || useradd -M -s /usr/sbin/nologin blancco
echo -e 'blancco\nblancco' | smbpasswd -a blancco -s
args:
executable: /bin/bash
changed_when: false
- name: "Create image-type top-level directories"
file:
path: "{{ samba_share }}/{{ item }}"
@@ -289,6 +383,14 @@
- "{{ image_types }}"
- "{{ deploy_subdirs }}"
- name: "Create Media.tag for FlatSetupLoader.exe drive detection"
copy:
content: ""
dest: "{{ samba_share }}/{{ item }}/Deploy/Control/Media.tag"
mode: '0644'
force: no
loop: "{{ image_types }}"
- name: "Copy WinPE & boot files from USB (skipped if not present)"
copy:
src: "{{ usb_root }}/{{ item.src }}"
@@ -303,6 +405,20 @@
- { src: "boot.wim", dest: "sources/boot.wim" }
ignore_errors: yes
- name: "Inject startnet.cmd into boot.wim (virtual BOOT/MEDIA volumes)"
shell: |
WIM="{{ web_root }}/win11/sources/boot.wim"
STARTNET="{{ usb_mount }}/startnet.cmd"
if [ -f "$WIM" ] && [ -f "$STARTNET" ]; then
echo "add $STARTNET /Windows/System32/startnet.cmd" | wimupdate "$WIM" 1
echo "Updated startnet.cmd in boot.wim"
else
echo "Skipped: boot.wim or startnet.cmd not found"
fi
args:
executable: /bin/bash
ignore_errors: yes
- name: "Copy iPXE binaries from USB (skipped if not present)"
copy:
src: "{{ usb_root }}/{{ item }}"
@@ -320,6 +436,25 @@
- blancco
- memtest
- name: "Create TFTP blancco directory for GRUB boot"
file:
path: "{{ tftp_dir }}/blancco"
state: directory
mode: '0755'
- name: "Symlink Blancco boot files to TFTP (GRUB loads via TFTP)"
file:
src: "{{ web_root }}/blancco/{{ item }}"
dest: "{{ tftp_dir }}/blancco/{{ item }}"
state: link
force: yes
loop:
- vmlinuz-bde-linux
- intel-ucode.img
- amd-ucode.img
- config.img
- initramfs-bde-linux.img
- name: "Check for WinPE deployment content on USB"
stat:
path: "{{ usb_root }}/images"