RUNBOOK §1/§5 gain `ci template deploy-win` (UUP determinism, build pin, --win-iso, tooling + scratch-space notes). Add plans/deploy-win-windows-host.md describing the deferred cross-platform port (os.name dispatch to oscdimg / IMAPI2FS shim; deploy-linux seed ISO via oscdimg on Windows).
93 lines
4.8 KiB
Markdown
93 lines
4.8 KiB
Markdown
# 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 (UUP resolve/download, 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)
|
|
|
|
- `winimage/uup.py` — pure `urllib`/`subprocess`/`zipfile`. The **conversion
|
|
package** must run the Windows variant: invoke `uup_download_windows.cmd`
|
|
(present in the same zip) instead of `uup_download_linux.sh`. Add an
|
|
`os.name`-based branch in `build_iso` to pick the script; the Windows `.cmd`
|
|
needs `aria2c.exe` + the bundled converter (it self-fetches via `get_aria2.ps1`).
|
|
- `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<etfsboot.com>#pEF,e,b<efisys_noprompt.bin> <src> <out>`.
|
|
- 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. `uup.build_iso` — pick `uup_download_windows.cmd` on Windows.
|
|
5. Preflight: on Windows check for `oscdimg.exe` (ADK) / `aria2c.exe` instead of
|
|
the Linux tools; clear error if the ADK is missing.
|
|
6. 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.
|
|
- The Windows UUP `.cmd` converter pulls its own toolchain; ensure it runs
|
|
non-interactively (it can prompt — pass the right flags / answer file).
|