Commit Graph

44 Commits

Author SHA1 Message Date
cproudlock
7a27f1a0a1 sync_intune.bat: longer poll interval, in-place status, no sync flood
Two related fixes for the desktop helper:

1. Stop hammering the Intune sync trigger every 15 seconds. The old
   loop called :do_sync (Start-ScheduledTask on Schedule #3) on every
   failed check, which started a fresh CSP pull before the previous
   one had time to complete - the Intune engine treats a re-trigger
   as "start over" and kills in-flight policy application work, so
   nothing ever finished. New cadence: trigger sync once at the start
   of each step, then poll every 30 s, only re-trigger every 6 polls
   (~3 min). POLL_SECS and RETRIGGER_POLLS are top-of-script knobs.

2. Stop pushing the QR code off the top of the window. The old loop
   echoed "Checking again in 15s..." on a new line every iteration,
   so after a few minutes the QR code (which contains the device ID
   the operator scans) had scrolled out of view. Replaced the per-
   iteration echo with a single self-redrawing status line using a
   captured CR character (copy /Z trick) and <nul set /p, padded to
   clear leftover characters. Important transitions ("Re-triggering
   sync...", "[DONE] ...") still print echo. lines so they survive in
   the scrollback as permanent history.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 10:10:51 -04:00
cproudlock
a363fa31c0 OpenText: migrate from Intune Win32 LOB to PXE PreInstall + DSC
OpenText HostExplorer ShopFloor was previously delivered as an Intune
Win32 LOB app that ran the inner OpenTextHostExplorer15x64.msi directly,
which (a) skipped the [Files] section of the WJDT-built Inno Setup
wrapper that deploys profile/keymap/menu/macro files, and (b) deployed
desktop shortcuts pointing at C:\\GE Aerospace\\Hummingbird\\ - a path
HostExplorer doesn't search, so the profile would open from the desktop
shortcut but the keymaps and macros never got picked up.

This commit moves the install to the PXE PreInstall pipeline so it
gets baked into every Standard PC during imaging instead of being
pulled per-device by Intune. The DSC side ships separately as
Setup-OpenText.ps1 + Install-OpenText.ps1 wrapper in the
pxe-images/main/ tree (uploaded to Azure Blob).

preinstall.json: new entry for OpenText pointing at
opentext\\Setup-OpenText.cmd, a tiny launcher in the bundled subtree
that hands off to Setup-OpenText.ps1 (the runner only handles MSI/EXE
types). No DetectionMethod fields - Setup-OpenText.ps1 reads version
from version.txt next to itself and short-circuits via its own
HKLM\\SOFTWARE\\GE\\OpenText\\Installed marker check, so the version
constant lives in exactly one place (version.txt). Trade-off: ~1s
PowerShell launch on every up-to-date runner pass instead of a
zero-cost registry compare, in exchange for never having to bump
the version in multiple places.

sync-preinstall.sh: added dependencies/opentext to TREE_SUBDIRS so
the whole bundle (base MSI + cab + SP1 patch + ShopFloor transform +
profile/accessories/keymap/menu/W10shortcuts content + Setup-OpenText
script and cmd wrapper + version.txt) rides through the existing tar
pipe. Also added OpenText.exe to the legacy-cleanup rm list since the
old flat machineapps/OpenText.exe path is now obsolete.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 10:10:35 -04:00
cproudlock
b4dd8a4197 VC++ extracted MSIs: bypass LaunchCondition CA via NOVSUI=1
The extracted VC++ 2008/2010/2012/2013/2022 MSIs have a hardcoded
CustomAction CA_LaunchCondition (type 19 = msidbCustomActionTypeError)
whose Target is "To install this product, please run Setup.exe.  For
other installation options, see the Installation section of ReadMe.htm."
The CA's Condition row in InstallExecuteSequence is:

  NOT( (ADDEPLOY = 1 OR NOVSUI = 1 OR VSEXTUI = 1 OR
        ADVERTISED = 1 OR ProductState >= 1) )

So it fires (= aborts the install with that error) unless one of those
sentinel properties is set on the command line. The 2008 MSI uses a
slightly different name (CA_LaunchCondition_5122) and a different set:

  NOT( (USING_EXUIH = 1 OR USING_EXUIH_SILENT = 1 OR ProductState >= 1) )

The bootstrappers normally set NOVSUI=1 / USING_EXUIH_SILENT=1 to
identify themselves as non-interactive installers. When we run the
extracted MSI directly via msiexec, the property isn't set, the CA
fires, msiexec returns 1603 with MSI Note 1: 1708, and the install
rolls back.

Fix: pass both properties unconditionally on every VC++ install. MSIs
ignore unknown properties, so one args string works for all of them.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 10:10:11 -04:00
cproudlock
564f14ffcf PreInstall runner: capture real exit codes, surface MSI errors
Three observability fixes that made the VC++ MSI failures actually
debuggable instead of showing "Exit code  - FAILED" with an empty
value for every install:

1. Switch from Start-Process -PassThru (without -Wait) to
   [System.Diagnostics.Process]::Start() with a ProcessStartInfo.
   PowerShell 5.1 has a known bug where Start-Process disposes the
   Process object's OS handle when control returns to the script,
   so $proc.ExitCode reads as $null even after WaitForExit() - which
   was causing every MSI install to be reported as failed regardless
   of the actual result.

2. Pass /L*v <log> to msiexec on every MSI install so we get a full
   verbose log per app at C:\Logs\PreInstall\msi-<safename>.log.

3. On install failure, scan the verbose log for *meaningful* lines
   (Note: 1: <code>, "return value 3", custom action errors, "Failed
   to", "Installation failed", common 2xxx error codes) instead of
   tailing the last 25 lines, which is rollback/cleanup noise. This
   surfaces the actual root-cause line directly in the runner log so
   you don't have to dig through C:\Logs to diagnose.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 10:08:42 -04:00
cproudlock
61e0f3a033 Preinstall: extract MSIs for all VC++ redists to suppress reboot
The Microsoft VC++ bootstrappers (vcredist*_x86.exe) ignore /norestart
and trigger immediate Windows reboots when CRT DLLs are in use, which
in practice is always. We saw this break a live Standard PC imaging
run (installlog showed the manual shutdown -a sequence between runs).

Fix follows the existing 2008 pattern: extract the inner MSIs from
each Burn bundle, run them via msiexec with REBOOT=ReallySuppress
(a hard Windows Installer property the bootstrapper can't override),
and treat exit 3010 as success. Files are now staged per-version
under dependencies/vcredist/<version>/ because each MSI's Media table
hardcodes its CAB filename, so the pairs would otherwise collide.

preinstall.json: 4 EXE entries replaced with 8 MSI entries (Min+Add
for 2012/2013/2022 because each version's Burn bundle ships them
as separate MSIs). 2008 also moved into the same vcredist/2008/
subdir for consistency. ProductCodes verified against the existing
detection paths (the previous "bootstrapper" GUIDs were actually
the Min runtime GUIDs inherited up the chain).

sync-preinstall.sh: now tarballs the dependencies/vcredist/ subtree
to preserve directory structure across the scp+sudo-cp boundary,
flat installers (UDC, Oracle) still copied individually, and the
remote install script now removes the legacy flat vc_red.msi/cab
plus the obsolete vcredist*_x86.exe bootstrappers on every sync.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 15:01:23 -04:00
cproudlock
ded0a7184b Shopfloor scripts: em-dash to hyphen, add positional Level param
Replace em-dash characters with plain hyphens across the 5 shopfloor
setup scripts (avoids cp1252 mojibake in .bat files and keeps the
PowerShell sources consistent). Also adds [Parameter(Position=1)] to
Write-PreInstallLog so the Level argument can be passed positionally.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 14:24:37 -04:00
cproudlock
a1a78e2ba3 PXE preinstall pipeline + Set-MachineNumber helper for Standard PCs
Adds a local-install pipeline so Standard shopfloor PCs get Oracle, the
VC++ redists (2008-2022), and UDC installed during PXE imaging via Samba
instead of pulling ~215 MB per device from Azure blob over the corporate
WAN. Intune DSC then verifies (already-installed apps are skipped) and
the only Azure traffic on the happy path is ~11 KB of CustomScripts
wrapper polling.

New files:
- playbook/preinstall/preinstall.json — curated app list with PCTypes
  filter and per-app detection rules. Install order puts VC++ 2008
  LAST so its (formerly) reboot-triggering bootstrapper doesn't kill
  the runner mid-loop. (2008 itself now uses extracted vc_red.msi with
  REBOOT=ReallySuppress; the reorder is defense in depth.)
- playbook/shopfloor-setup/Shopfloor/00-PreInstall-MachineApps.ps1 —
  the runner. Numbered 00- so it runs first in the baseline sequence.
  Reads preinstall.json, filters by PCTYPE, polls for completion via
  detection check (handles UDC's hung WPF process by killing it once
  detection passes), uses synchronous WriteThrough logging that
  survives hard reboots, preserves log history across runs.
- playbook/shopfloor-setup/Standard/Set-MachineNumber.{ps1,bat} — desktop
  helper for SupportUser. Reads current UDC + eDNC machine numbers,
  prompts via VB InputBox, validates digits-only, kills running UDC,
  edits both C:\ProgramData\UDC\udc_settings.json and HKLM\…\GE Aircraft
  Engines\DNC\General\MachineNo, relaunches UDC. Lets a tech assign a
  real machine number to a mass-produced PC without admin/LAPS.
- playbook/sync-preinstall.sh — workstation helper to push installer
  binaries from /home/camp/pxe-images/main/ to the live PXE Samba.

Changes:
- playbook/startnet.cmd + startnet-template.cmd — add xcopy to stage
  preinstall bundle from Y:\preinstall\ to W:\PreInstall\ during the
  WinPE imaging phase, gated on PCTYPE being set.
- playbook/pxe_server_setup.yml — create /srv/samba/enrollment/preinstall
  + installers/ directories and deploy preinstall.json there.
- playbook/shopfloor-setup/Run-ShopfloorSetup.ps1 — bump AutoLogonCount
  to 99 at start (defense against any installer triggering an immediate
  reboot mid-dispatcher; final line still resets to 2 on successful
  completion). Copy Set-MachineNumber.{ps1,bat} to SupportUser desktop
  on Standard PCs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 14:06:26 -04:00
cproudlock
9c54307b1b Shopfloor cleanups: drop OpenText CSF + MarkZebra, gitignore eMxInfo
- Delete 02-OpenTextCSF.ps1 (CSF profile delivery moved to Intune YAML's
  CopyFiles section in main/device-config.yaml — no longer needed at the
  PXE/baseline layer)
- Strip MarkZebra install + post-config from 01-eDNC.ps1 (no longer
  needed; only eDNC core install + Dnc x86→x64 mirror + Site reg + eMxInfo
  deployment remain). Section numbering tightened.
- Add SITESELECTED="West Jefferson" to eDNC msiexec args so the MSI's
  site-specific Components (NtLarsWjfRegComp — FTP/FMS/PPDCS hosts +
  credentials) actually install. Without it, only the bare Site value was
  being set and all the connection details were unconfigured.
- gitignore: blanket-block any **/eMxInfo*.txt from being committed —
  the file contains obfuscated eDNC site credentials and must never go
  in git. Canonical source lives at /home/camp/pxe-images/main/eMxInfo.txt
  outside the repo.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 14:05:52 -04:00
cproudlock
05fa74574a Intune sync: 3-step lockdown monitor, fix batch detection, remove backup_lockdown
sync_intune.bat now monitors three stages sequentially:
1. SFLD registry key (device configuration received)
2. DSCInstall.log success string (DSC installation complete)
3. SFLD - Consume Credentials scheduled task (lockdown complete)
Triggers Intune sync before each poll. Prompts reboot on completion.

Fixed batch delayed expansion bugs, removed nested if/goto blocks.
Removed backup_lockdown.bat and its desktop copy.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 10:52:31 -04:00
cproudlock
e3f2bbc6a5 Add QR code display of Intune device ID to sync tool
Bundles QRCoder.dll (184KB, .NET 4.0) to render the Azure AD device
GUID as a scannable QR code in the console when sync_intune.bat runs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 10:15:20 -04:00
cproudlock
1ba4cce80f Remove shopfloor power and display settings script
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 09:46:38 -04:00
cproudlock
a570efda71 Remove shopfloor Start Menu shortcuts script
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 09:45:21 -04:00
cproudlock
9912b044a3 Shopfloor: single autologon, clear Start pins, Intune sync tool, update docs
- AutoLogonCount reduced from 2 to 1 in Run-ShopfloorSetup.ps1
- Remove default pinned Start Menu tiles and set blank layout for future users
- Add sync_intune.bat: triggers MDM sync and polls for SFLD group policies
- Update README.md and SETUP.md with current project state (boot chain, new
  scripts, samba shares, webapp pages, commit history)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 09:43:00 -04:00
cproudlock
163e58ab0b Fix dnsmasq reboot cron: use /etc/cron.d/ instead of crontab
Ansible cron module writes to root's crontab which requires cron
daemon running. Drop file in /etc/cron.d/ instead for reliability.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 15:03:09 -04:00
cproudlock
b7cd0974f1 Blancco 7.15.1 upgrade: native kernel boot, BMC cloud licensing
- Switch to Blancco native kernel (vmlinuz-bde-linux) for hardware compat
- Config.img preferences with BMC connection (classic.eu-west-1.blancco.cloud)
- Disable wired LAN in preferences so WiFi takes default route to BMC
- WiFi SSID INTERNETACCESS configured in plaintext in config.img
- Slim GRUB EFI (1.3MB standalone with minimal modules)
- Fix Windows line endings in blancco-init.sh
- Add extra NIC drivers to switch_root initramfs
- SSH enabled in modified airootfs.sfs (root:blancco)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 13:54:25 -04:00
cproudlock
76165495ff Shopfloor PC type system, webapp enhancements, slim Blancco GRUB
- Shopfloor PC type menu (CMM, WaxAndTrace, Keyence, Genspect, Display, Standard)
- Baseline scripts: OpenText CSF, Start Menu shortcuts, network/WinRM, power/display
- Standard type: eDNC + MarkZebra with 64-bit path mirroring
- CMM type: Hexagon CLM Tools, PC-DMIS 2016/2019 R2
- Display sub-type: Lobby vs Dashboard
- Webapp: enrollment management, image config editor, UI refresh
- Upload-Image.ps1: robocopy MCL cache to PXE server
- Download-Drivers.ps1: Dell driver download pipeline
- Slim Blancco GRUB EFI (10MB -> 660KB) for old hardware compat
- Shopfloor display imaging guide docs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:25:07 -04:00
cproudlock
6d0e6ee284 BIOS check fix, parallel downloads, shopfloor hardening
- Fix check-bios.cmd: replace parenthesized if blocks with goto labels
  (cmd.exe fails silently with if/else on network-mapped drives)
- Move BIOS check files to winpeapps/_shared/BIOS for reliable SMB access
- Add network wait loop before BIOS check in startnet.cmd
- Show firmware status in WinPE menu header (BIOS_STATUS variable)
- Add BypassNRO registry key to skip OOBE network requirement
- Refactor download-drivers.py with --parallel N flag (ThreadPoolExecutor)
- Set SupportUser AutoLogonCount to 3 in shopfloor unattend
- Add shutdown -a at start + shutdown /r /t 10 at end of Run-ShopfloorSetup.ps1
- Switch download-drivers.py from wget to curl for reliable stall detection

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 11:02:36 -04:00
cproudlock
86660a0939 Remove UEFI HTTP Boot config from dnsmasq
Not needed since iPXE chains to grubx64.efi for Blancco boot.
Simplifies DHCP config and avoids interfering with other UEFI clients.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 11:58:33 -05:00
cproudlock
dd2fec5a41 Blancco PXE boot via Ubuntu kernel switch_root
Blancco's own kernel freezes on Dell Precision towers during PXE boot.
Workaround: boot Ubuntu kernel via GRUB chainload, download Blancco's
666MB squashfs rootfs + 132MB kernel modules over HTTP, mount overlay
filesystem, and switch_root into Blancco's userspace.

- Add blancco-init.sh: custom initramfs init script for switch_root approach
- Add blancco-preferences.xml: pre-configured with network share for reports
- Update playbook: build initramfs, deploy Ubuntu kernel/modules, config
- Update prepare-boot-tools.sh: add HTTP modules to GRUB EFI build
- Add UEFI HTTP Boot support to dnsmasq config
- iPXE menu chains to grubx64.efi (replaces sanboot of ISO)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 11:20:00 -05:00
cproudlock
15983854ed Add git-crypt encrypted MOK signing keys
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 12:47:44 -05:00
cproudlock
5d5f5ce267 Add git-crypt encryption for MOK signing keys
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 12:47:09 -05:00
cproudlock
5de807143b Fix WinPE SMB auth and timeout commands, restore autoinstall disk match
- Add /user:pxe-upload pxe credentials to all net use commands (share requires auth)
- Replace timeout with ping delays (timeout.exe not available in WinPE)
- Restore size: largest disk match in autoinstall (root cause was BIOS RST mode)
- Simplify autoinstall late-commands structure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 15:32:39 -05:00
cproudlock
a4abd238de Harden cloud-init disable and rebuild ISO properly in build-usb
Autoinstall user-data now disables cloud-init in multiple stages
(late-commands + runcmd + systemd masks) to prevent post-install
hangs. Also disables networkd-wait-online for air-gapped networks.
build-usb.sh switched from in-place ISO patching to full extract
and rebuild with xorriso mkisofs for reliable UEFI boot.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 10:53:26 -05:00
cproudlock
d3a8e63b36 Fully unattended USB install: patch GRUB and remove cloud-init
- build-usb.sh now patches the ISO's grub.cfg with xorriso to add
  'autoinstall' kernel param (skips confirmation prompt) and reduces
  GRUB timeout from 30s to 5s
- Disable and remove cloud-init on the installed system to prevent
  boot delays on air-gapped network
- Fix ISO size calculation to use patched ISO for CIDATA partition offset

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 21:05:11 -05:00
cproudlock
d482cf4d0c Skip autoinstall confirmation prompt and disable cloud-init post-install
Adds interactive-sections: [] to avoid the "Continue with autoinstall?" prompt,
and disables cloud-init on the installed system to prevent boot delays.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 20:53:28 -05:00
cproudlock
57a53381f2 Ensure Media.tag exists for all images after import and via cron
Webapp now creates Deploy/Control/Media.tag after every image import.
Cron updated to create (not just touch) Media.tag for any image
directory that has Deploy/Control/.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 16:58:39 -05:00
cproudlock
0da52cb083 Auto-reboot after imaging, auto-download pip-wheels in build scripts
startnet.cmd now polls for PESetup.exe completion and reboots with a
15-second countdown. Build scripts (USB + Proxmox) auto-download pip
wheels if the pip-wheels/ directory is missing. Added mok-keys/ to
gitignore.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 16:56:14 -05:00
cproudlock
093a4d713b Add @reboot to Media.tag refresh cron
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 16:41:24 -05:00
cproudlock
a7636887b1 Add daily cron to refresh Media.tag (30-day expiry workaround)
PESetup.exe checks Media.tag last modified date and rejects it after
30 days. Cron job touches all Media.tag files daily at midnight.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 16:41:07 -05:00
cproudlock
1a5c4f7124 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>
2026-02-12 16:40:27 -05:00
cproudlock
f4c158a5ac Fix PXE interface detection, add br-pxe bridge to test VM, network upload import
- Playbook: detect interface already configured with 10.9.100.1 before
  falling back to non-default-gateway heuristic (fixes dnsmasq binding
  to wrong NIC when multiple interfaces exist)
- test-vm.sh: auto-attach br-pxe bridge NIC if available on host
- Webapp: add network upload import via SMB share with shared driver
  deduplication and symlinks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 15:15:14 -05:00
cproudlock
7486b9ed66 Apache reverse proxy for webapp, UI improvements
- Move Flask to localhost:9010, Apache serves port 9009 with static file
  handling and reverse proxy to fix intermittent asset loading on remote clients
- Add "PXE Manager" branding beneath logo in sidebar
- Increase code editor size (startnet.cmd and unattend XML) to 70vh
- Add test-lab.sh for full lab VM testing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 17:45:10 -05:00
cproudlock
f3a384fa1a Add Proxmox ISO builder, CSRF protection, boot-files integration
- Add build-proxmox-iso.sh: remaster Ubuntu ISO with autoinstall config,
  offline packages, playbook, webapp, and boot files for zero-touch
  Proxmox VM deployment
- Add boot-files/ directory for WinPE boot files (wimboot, boot.wim,
  BCD, ipxe.efi, etc.) sourced from WestJeff playbook
- Update build-usb.sh and test-vm.sh to bundle boot-files automatically
- Add usb_root variable to playbook, fix all file copy paths to use it
- Unify Apache VirtualHost config (merge default site + webapp proxy)
- Add CSRF token protection to all webapp POST forms and API endpoints
- Update README with Proxmox deployment instructions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 20:01:19 -05:00
cproudlock
cb442f971b Fix air-gapped deployment: pip wheel install, UFW ports, installer crash
- Fix pip/distutils incompatibility: install Python wheels directly via
  zipfile extraction instead of broken pip3 from Ubuntu 22.04 .debs
  (pip3 crashes on Python 3.12 with ModuleNotFoundError: distutils)
- Fix UFW port types: quote loop items so string comparison works
  correctly, giving ports 67/69 UDP rules instead of TCP
- Fix autoinstall crash: set refresh-installer to no (can't reach
  internet on air-gapped network, was crashing subiquity)
- Remove python3-pip and python3-venv from download-packages.sh
  (no longer needed with direct wheel extraction)
- Add ignore_errors to WinPE/iPXE copy tasks (files only present
  on real USB media, not test VM)
- Use system python3 instead of venv for webapp service

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 16:16:55 -05:00
cproudlock
851225d062 Add README, update docs, fix CRLF, SSH, and playbook network detection
- Add comprehensive README.md with full project documentation
- Update SETUP.md to reflect current state (7 image types, webapp, boot tools, Samba shares)
- Enable SSH in autoinstall user-data for remote access
- Fix ansible_default_ipv4.interface error when no default gateway exists
- Fix Windows CRLF line endings on all shell scripts and YAML files
- Fix test-vm.sh: use --install kernel extraction instead of --location, don't delete source ISO on --destroy

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 17:38:55 -05:00
cproudlock
725c8f43de Change webapp to port 9009, add test VM script
- Webapp now listens on port 9009 (UFW rule added)
- Apache reverse proxy updated to proxy to 9009
- test-vm.sh creates a KVM test environment with:
  - CIDATA ISO built from project files
  - Isolated libvirt network (10.9.100.0/24)
  - Ubuntu 24.04 VM with autoinstall

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 16:53:23 -05:00
cproudlock
92c9b0f762 Fix review findings: offline assets, security, audit logging
- Bundle Bootstrap CSS/JS/icons locally for air-gapped operation
- Add path traversal validation on image import source
- Disable Flask debug mode in production
- Fix file handle leaks, remove unused import
- Add python3-pip, python3-venv, p7zip-full to offline packages
- Add pip wheel download/bundling for offline Flask install
- Change UFW default policy from allow to deny
- Fix wrong path displayed in unattend editor template
- Dynamic sidebar image lists from all_image_types
- Add audit logging for all write operations
- Audit log viewer page with activity history

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 16:50:20 -05:00
cproudlock
ef7583920b Auto-patch Blancco config.img for network report storage
After extracting Blancco from ISO, automatically patches preferences.xml
to save erasure reports to \\10.9.100.1\blancco-reports via SMB.
Sets auto_backup=true so reports save without user intervention.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 16:40:09 -05:00
cproudlock
05dbb7ed5d Add Blancco erasure reports Samba share and webapp viewer
- Samba share at \\server\blancco-reports for automatic report collection
- Webapp reports page with list, download, and delete
- Compliance warning on delete confirmation
- Sidebar link under Tools section

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 16:27:27 -05:00
cproudlock
89b58347d9 Add wimtools and startnet.cmd editor for boot.wim modification
- Added wimtools to offline packages and playbook verification
- Webapp startnet.cmd editor: extract, view, edit, save back to boot.wim
- Uses wimextract/wimupdate for in-place WIM modification
- Dark-themed code editor with tab support and common command reference

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 16:23:22 -05:00
cproudlock
e7313c2ca3 Add multi-boot PXE menu, Clonezilla backup management, and GE Aerospace branding
- iPXE boot menu with WinPE, Clonezilla, Blancco Drive Eraser, Memtest86+
- prepare-boot-tools.sh to download/extract boot tool binaries
- Clonezilla backup management in webapp (upload, download, delete)
- Clonezilla Samba share for network backup/restore
- GE Aerospace logo and favicon in webapp
- Updated playbook with boot tool directories and webapp env vars

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 16:20:50 -05:00
cproudlock
f614596cdc Fix unattend.xml path to match actual image structure
Changed from Deploy/Control/unattend.xml to Deploy/FlatUnattendW10.xml
to match the real GE Aerospace image layout.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 16:02:01 -05:00
cproudlock
cee4ecd18d Add web management UI, offline packages, WinPE consolidation, and docs
- webapp/: Flask web management app with:
  - Dashboard showing image types and service status
  - USB import page for WinPE deployment content
  - Unattend.xml visual editor (driver paths, specialize commands,
    OOBE settings, first logon commands, raw XML view)
  - API endpoints for services and image management
- SETUP.md: Complete setup documentation for streamlined process
- build-usb.sh: Now copies webapp and optional WinPE images to USB
- playbook: Added webapp deployment (systemd service, Apache reverse
  proxy), offline package verification, WinPE auto-import from USB

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 15:57:34 -05:00
cproudlock
5791bd1b49 Initial project setup: automated PXE server provisioning
Reorganized from OneDrive export into a clean project structure:
- autoinstall/: cloud-init user-data and meta-data for Ubuntu 24.04 autoinstall
- playbook/: Ansible playbook for PXE server config (dnsmasq, Apache, Samba, iPXE)
- unattend/: Windows unattend.xml sample for image deployment
- build-usb.sh: builds a bootable USB with Ubuntu installer + CIDATA partition
- download-packages.sh: downloads all offline .deb dependencies via Docker

Key improvements over original:
- Fully air-gapped: all packages bundled offline, no WiFi needed
- Hardware-agnostic network config (wildcard NIC matching)
- Removed plaintext WiFi credentials
- Single USB build process (was 15+ manual steps)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 15:47:36 -05:00