VM write path: create/setConfig/start/stop/delete + reconciler#14
Merged
Conversation
Extends ProxmoxSharp from read-only into a layered VM write path (dry-run by default), so callers never hand-write Proxmox's comma-option config strings. - Codegen now emits write verbs: ProxmoxSharp.Api.csproj drives Kiota with --methods GET,POST,PUT,DELETE (new ApiMethods property; scope unchanged). - L1 QemuWriter: create/setConfig/delete via a form-urlencoded body over the shared adapter (Proxmox indexed params hostpci0/scsi0/netN can't be expressed by the generated typed query surface); start/stop/shutdown/pci/config-read/ task-poll via the generated builders. ProxmoxApi.CreateAdapter shares the exact auth/TLS wiring with the read client. - L2 QemuVmSpec + QemuParamEncoder (pure option-string serialization) + VmReconciler with adoption-safe subset diffing (Proxmox-added options like size=120G don't register as drift). - L3 CLI: vm plan | apply | start | stop | delete | pci | show (--confirm to mutate; dry-run by default). - 19 new unit tests for the encoder + reconciler (full suite 25, green). Verified live: `vm plan` vs a real VM yields only the genuine diff; full create -> start -> stop -> delete lifecycle exercised on a throwaway VM. Part of Homelab #115 (gaming VM as IaC). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A VM created from a fresh-allocation spec (storage:N disk, unpinned NIC) re-planned as false drift, because Proxmox realizes those as storage:<volid>+size=NG and an auto-assigned MAC. The reconciler now matches: - a bare NIC model (virtio) against the live virtio=<mac>, and - a size-allocation (storage:N) against the realized storage:<volid> + size=NG. Resize, model-change and wrong-storage are still flagged as real drift. Found by creating a persistent dummy VM (9999) and re-planning it. Adds the samples/dev-vm.json fixture used to exercise the write path, and 6 reconciler tests (suite 31, green). Live: VM 9999 now re-plans as Skip. Part of Homelab #115. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…lake) CI build broke on SchemaGen with "CreateAppHost task failed / could not find apphost" (SetUnixFileMode) after the runner's SDK moved to 10.0.301 — unrelated to any source change. SchemaGen runs via `dotnet run` and the CLI ships as a `dotnet tool`; neither uses a native apphost. Set UseAppHost=false repo-wide (no-op for libraries) to skip the buggy task. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ChrisonSimtian
added a commit
to Chrison-Homelab/Homelab
that referenced
this pull request
Jun 12, 2026
Scopes & starts the IaC-managed **Bazzite (SteamOS-style) gaming VM** on desktop-01 with GPU passthrough. Resolves the schema + stack portions of #115. Plan: [`docs/plans/115-gaming-vm-steamos.md`](docs/plans/115-gaming-vm-steamos.md). ## In this PR (hub-side, Phase A) - **Schema** — `kind: VM` tightened from permissive into a strict `vmSpec` (requires `vmid`), with the novel **`hostPci[]`** passthrough def plus `vmDisk`/`vmEfiDisk`/`vmTpmState`/`vmCdrom`/`vmBoot`, and the `kind: VM` `allOf` branch. - **Model + tests** — mirrored `VmSpec` C# model; drift tripwire extended (`vmSpec`/`hostPci`/`vmDisk`); positive/negative validator tests. **29 engine tests green.** - **Stack** — `stacks/Gaming/` (VMID block 1000–1099): `stack.yaml` + `bazzite.vm.yaml` (adopts the existing VM 1003, adds `hostpci0: 0000:09:00`) + `README.md`. Scaffolded locally; promoted to a submodule later. Also includes a one-line drive-by: the `/doctor` permission-rule fix (`mcp__claude-flow__:*` → `mcp__claude-flow__*`) as its own commit. ## Depends on (separate repo) The **ProxmoxSharp VM write path** that actually provisions these shapes — Chrison-dev/ProxmoxSharp#14 (built, 25 tests green, live-verified). The hub consumes ProxmoxSharp as a published package, so this PR is independent; the `vendor/ProxmoxSharp` submodule pointer should be bumped once #14 merges and a preview package publishes. ## Not in this PR - `kind: VM` provisioning wiring into the hub converge engine (uses ProxmoxSharp#14) — a follow-up. - Applying `+ hostpci0` to the live 1003 (Phase C) — deliberately deferred, mutating. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ChrisonSimtian
added a commit
that referenced
this pull request
Jun 20, 2026
#17) Adds PctWriter, the container counterpart to QemuWriter (#14), giving an IaC write path to tear a CT down instead of root SSH + pct. Motivated by Chrison-Homelab/Homelab#149 (decommissioning Teleport CT 9904 had no sanctioned write path). - PctWriter: StartAsync / StopAsync (hard kill) / ShutdownAsync (graceful + hard-stop fallback) / DeleteAsync (force + purge). Mirrors QemuWriter — raw form requests over the shared Kiota adapter (lifecycle ops carry forceStop/timeout/force/purge query flags), same token-auth/TLS + error-body surfacing, returns a task UPID; WaitForTaskAsync. - CLI: `proxmoxsharp lxc <start|stop|shutdown|delete> <node> <vmid>`; delete is gated on --confirm with --force/--no-purge, same discipline as `vm delete`. - Pure query-builder helpers (DeleteQuery/ShutdownQuery) unit-tested (5 new; suite green). Relates to Chrison-Homelab/Homelab#149 and the converge destroy lifecycle (#101). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Extends ProxmoxSharp from a read-only client into a layered, dry-run-by-default VM write path — the foundation for managing Proxmox VMs as IaC (Homelab #115, gaming VM).
Layers
ProxmoxSharp.Api.csprojnow drives Kiota with--methods GET,POST,PUT,DELETE(newApiMethodsproperty; path scope unchanged). The read surface is unaffected.QemuWriter—create/setConfig/deletesend a form-urlencoded body over the shared Kiota adapter (Proxmox's indexed paramshostpci0/scsi0/netNcan't be expressed by the generated typed query surface, which collapses them tohostpci[n]);start/stop/shutdown/pci/config-read/task-poll use the generated builders.ProxmoxApi.CreateAdaptershares the exact token-auth + TLS wiring with the read client.QemuVmSpec(native desired-state record) +QemuParamEncoder(pure option-string serialization) +VmReconcilerwith adoption-safe subset diffing: a key is satisfied when every desired comma-token is present in the live value, so Proxmox-added options (size=120G, reordering) don't register as drift.proxmoxsharp vm plan | apply | start | stop | delete | pci | show(--confirmto mutate; dry-run by default).Tests
19 new unit tests for the encoder + reconciler (full suite 25, green), including the headline case: reconciling a spec against an adopted VM yields exactly the genuine change.
Verified live
vm planagainst a real VM → only the true diff (+ hostpci0, a rename), all Proxmox-managed keys left untouched.OK, cleaned up).Notes
🤖 Generated with Claude Code