# Plan — cross-platform `deploy-win` / `deploy-linux` on a Windows host (deferred) ## Context `ci template deploy-win` (and the existing `deploy-linux`) are implemented for a **Linux** VMware Workstation host: they shell out to Linux-only tools (`xorriso`, `genisoimage`, `aria2c`, `wimlib-imagex`) and use POSIX paths. The Windows host port was deferred when the Linux slice was built — this document captures how to make both commands run on a **Windows** Workstation host without duplicating the orchestration logic. The Python orchestrator stays the single entry point. Where a step needs a Windows-only tool, Python detects `os.name == "nt"` and routes that one step to a thin PowerShell shim (or reuses functions already in `template/Deploy-WinBuild2025.ps1`). Everything else (ISO download/cache, VMX build, vmrun lifecycle, flag wait, NIC swap, snapshot) is already platform-neutral Python and is reused unchanged. ## What already works cross-platform (reuse as-is) - ISO acquisition: `deploy-win --iso-url` (urllib download + cache) / `--win-iso` is pure stdlib and portable as-is. (UUP dump was removed — on Linux it only produced the RTM `install.wim`; supply an updated ISO directly instead.) - `winimage/autounattend.py` — `importlib.resources`, fully portable. - `commands/template.py` deploy-win orchestration: `_winbuild_vmx_lines`, `_remove_vmx_lines`, `_patch_vmx_key`, `_wait_install_flag`, `_vmrun_soft_stop`, `_poll_guest_ip_deploy`, snapshot via `vmrun` — all platform-neutral (`vmrun.exe` exists on both hosts). `config.py` already resolves `F:\CI\...` paths on Windows. ## The one platform-specific step: ISO patch `winimage/iso_patch.py` uses `xorriso`, absent on Windows. Introduce an ISO-tool abstraction: | Host | No-prompt + inject implementation | |------|-----------------------------------| | Linux | current `xorriso -as mkisofs` path | | Windows | `oscdimg.exe` (Windows ADK) **or** reuse the IMAPI2FS / `New-WinIsoNoPrompt` + `New-IsoFromFolder` functions already in `template/Deploy-WinBuild2025.ps1` via a small `.ps1` shim | Design: - `winimage/iso_patch.py` exposes `patch_iso(...)` unchanged; inside, dispatch on `os.name`. Linux → existing xorriso. Windows → `_patch_iso_windows(...)` that writes `autounattend.xml` + `post-install.ps1` to a staging dir and calls a shim `template/shims/patch-win-iso.ps1` (new, thin) which uses `oscdimg.exe`: `oscdimg -m -o -u2 -udfver102 -bootdata:2#p0,e,b#pEF,e,b `. - Prefer `oscdimg` over IMAPI2FS (single command, scriptable, deterministic boot args) but keep the legacy IMAPI2FS path documented as a fallback for hosts without the ADK. - Note: with `oscdimg` we can inject `autounattend.xml` into the ISO root (one CD), matching the Linux design; VMware Tools stay a 2nd CD. ## `deploy-linux` on Windows (parallel work) `deploy-linux` Step 3 builds the cloud-init seed ISO with `genisoimage` (`_build_seed_iso`). On Windows, route that to `oscdimg.exe` (data ISO, volume label `cidata`, no boot) behind the same `os.name` dispatch. The rest of `deploy-linux` (paramiko SSH, cloud image download, VMX, vmrun) is already portable. ## Steps 1. `winimage/isotool.py` (new) — `make_data_iso(staging, out, label)` and `patch_windows_iso(src, out, files, efi_boot)` with Linux (xorriso/genisoimage) and Windows (oscdimg / shim) implementations selected by `os.name`. 2. Refactor `iso_patch.patch_iso` and `template._build_seed_iso` to call `isotool`. Keep current Linux behaviour byte-for-byte. 3. `template/shims/patch-win-iso.ps1` (new, lint-clean PS 5.1) — oscdimg wrapper; optional IMAPI2FS fallback reusing `Deploy-WinBuild2025.ps1` functions. 4. Preflight: on Windows check for `oscdimg.exe` (ADK) / `7z` instead of the Linux tools; clear error if the ADK is missing. (ISO download is stdlib — no extra tool.) 5. Tests: parametrize the new `isotool` dispatch (mock `os.name`); mock the shim call. Keep coverage ≥90%. 7. Docs: note Windows-host prerequisites (Windows ADK for `oscdimg`) in `docs/RUNBOOK-PhaseC.md` / a Windows runbook. ## Verification - Linux regression: existing `deploy-win` / `deploy-linux` tests stay green (the abstraction must not change Linux argv). - Windows live: on a Windows Workstation host with the ADK installed, run `ci template deploy-win` end-to-end → unattended install → snapshot. ## Risks - `oscdimg` boot-args syntax differs from xorriso; validate the no-prompt UEFI boot on a real VM.