From c757e7bec226864bf72f997a13da029c017082fe Mon Sep 17 00:00:00 2001 From: Simone Date: Mon, 8 Jun 2026 23:21:02 +0200 Subject: [PATCH] docs: document deploy-win + Windows-host port plan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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). --- docs/RUNBOOK-PhaseC.md | 27 ++++++++++ plans/deploy-win-windows-host.md | 92 ++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 plans/deploy-win-windows-host.md diff --git a/docs/RUNBOOK-PhaseC.md b/docs/RUNBOOK-PhaseC.md index 0472f29..2fdf547 100644 --- a/docs/RUNBOOK-PhaseC.md +++ b/docs/RUNBOOK-PhaseC.md @@ -77,6 +77,7 @@ sudo); `--uninstall` removes the block. The script defines two helpers: | `ci vmware --vmx ...` | Open a VMX in the VMware Workstation GUI | [§4](#4-manual-vm-lifecycle) | | `ci creds set --user ...` | Store guest credentials in the keyring | [§5](#5-credentials--template-provisioning) | | `ci template deploy-linux` | Build the Linux template VM | [§5](#5-credentials--template-provisioning) | +| `ci template deploy-win` | Build the Windows Server 2025 template VM (UUP→patch→deploy) | [§5](#5-credentials--template-provisioning) | | `ci template prepare-linux` | Provision the Linux template over SSH | [§5](#5-credentials--template-provisioning) | | `ci template prepare-win` | Provision a Windows template over WinRM | [§5](#5-credentials--template-provisioning) | | `ci template backup` | Timestamped copy of the template directories | [§5](#5-credentials--template-provisioning) | @@ -409,11 +410,37 @@ Run `ci template --help` for the (many) per-template options. ```bash ci template deploy-linux # build the Linux template VM from scratch (Ubuntu 24.04) +ci template deploy-win # build the Windows Server 2025 template VM (see below) ci template prepare-linux # provision an existing Linux template over SSH ci template prepare-win # provision a Windows template over WinRM (Linux-host driven) ci template backup # timestamped backup of the template directories ``` +### `deploy-win` — build the Windows Server 2025 template + +Downloads the newest WS2025 ISO from **UUP dump** (deterministic, build-pinned; +component files are MS-signed), patches it (injects `autounattend.xml` + +`post-install.ps1` and swaps the EFI boot image to the no-prompt variant), then +runs the unattended install, swaps the NIC e1000e → vmxnet3 and takes the cold +`PostInstall` snapshot. VMware Tools are mounted as a second CD. + +```bash +ci template deploy-win # newest build, headless +ci template deploy-win --gui # watch the install (needs X — §4.7) +ci template deploy-win --build 26100.32860 # pin a specific build (reproducible) +ci template deploy-win --win-iso /var/lib/ci/iso/my.iso # skip UUP, use a local ISO +``` + +Notes: +- First run downloads ~5 GB and builds the ISO locally (slow, tens of minutes); + the result is cached at `/var/lib/ci/iso/ws2025-.iso` and reused. +- Needs `aria2`, `wimtools`, `xorriso`, `genisoimage`, `cabextract`, `chntpw` + (installed by `setup-host-linux.sh`) and ~16 GiB scratch for the ISO repack. +- The final ISO hash is not canonical (assembled locally); the UUP component + files are MS-signed. Pin `--build` for reproducible inputs. +- After it finishes: `ci template prepare-win` then + `ci validate guest --winrm --guest-os windows`. + --- ## 6. Maintenance diff --git a/plans/deploy-win-windows-host.md b/plans/deploy-win-windows-host.md new file mode 100644 index 0000000..750b7d4 --- /dev/null +++ b/plans/deploy-win-windows-host.md @@ -0,0 +1,92 @@ +# 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#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. `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).