Commit Graph

424 Commits

Author SHA1 Message Date
goodolclint-claude[bot] a4ebcec753 fix: New-PveCluster -Wait blocks until the cluster is quorate
PVE's cluster-create task completes before corosync converges. Until the
node is quorate it rejects a join with "cluster not ready - no quorum?",
so New-PveCluster -Wait followed by Add-PveClusterMember failed for every
caller. Wait for quorum after the task, bounded by -Timeout (default 60 s,
following the -Wait timeout convention used by Stop-PveContainer and
Reset-PveVm). See DECISIONS.md D014.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 06:19:08 +00:00
goodolclint-claude[bot] db93af27b2 ci: capture cluster task logs in the diagnostics
"Cluster join aborted!" is PVE's generic wrapper; the reason lives only in
the task log on the joining node. Run 172's log said "An error occurred on
the cluster node: cluster not ready - no quorum?", which is what identified
the race. Capture it so the evidence survives cleanup.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 06:18:48 +00:00
goodolclint-claude[bot] 4294407d80 ci: run cluster diagnostics on test failure, add keep_vms dispatch input
The diagnostic step runs before cleanup so it reaches the nodes while
they still exist. keep_vms skips cleanup entirely for a dispatch run,
leaving the nested nodes up for hands-on inspection.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 05:38:56 +00:00
goodolclint-claude[bot] 44101e39c7 ci: dump corosync state from both nested nodes on cluster test failure
The API reports a joined-but-offline node as online=0 with no further
detail, and the cleanup job destroys the nodes minutes later, so the
reason corosync membership never forms has never reached a log. Read
corosync.conf, corosync-cfgtool, pvecm status and the corosync journal
off both nodes while they are still alive. Best-effort: never fails the
caller.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 05:38:08 +00:00
goodolclint-claude[bot] e0960d9c18 test: pin node B ring0 at join and dump cluster status on the online check
The "2 nodes online" check has never passed — run 159 shows the identical
failure while the job reported success (swallowed Pester exit code), and
run 170's 60 s poll expires with node B still online=0. Node B reaches
corosync.conf (Get-PveClusterConfigNode passes) but never becomes a
corosync member, and the suite captures nothing about why.

Pass link0 explicitly so ring0 is the address the harness verified node B
answers on, rather than whatever node B resolves its own DHCP-assigned
.test.local hostname to. Dump quorate and each node's ring0/online/local
unconditionally so the next run distinguishes a wrong ring0 address from
a working address with no corosync transport.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 05:02:53 +00:00
GoodOlClint f40324b948 Merge pull request #91 from GoodOlClint/test/cluster-status-poll 2026-08-31 19:21:00 -05:00
goodolclint-claude[bot] f758275668 test: poll cluster status for node B online instead of asserting instantly
The join task completing does not mean corosync membership has reached
the status endpoint; the instant assertion failed intermittently (runs
159 and 169) while every other cluster check passed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 23:00:49 +00:00
GoodOlClint 341f79e7ac Merge pull request #90 from GoodOlClint/ci/storage-vm-diagnostics
ci: storage VM on DHCP + FQDN addressing, self-diagnosing setup
2026-08-31 16:18:54 -05:00
goodolclint-claude[bot] 59a47e3fab ci: storage VM moves to DHCP and is addressed by FQDN (2/2)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 20:54:14 +00:00
goodolclint-claude[bot] 25746a94e3 ci: storage VM moves to DHCP and is addressed by FQDN (1/2)
The repo stops holding opinions about CI VLAN addressing: the VM boots
via DHCP with hostname pvetest-storage (deterministic MAC for an
optional reservation), registers in the operator's CI DNS zone, and
everything addresses it by STORAGE_VM_FQDN. Replaces the static-IP +
explicit-DNS variables.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 20:49:48 +00:00
goodolclint-claude[bot] 7872f08102 ci: storage VM uses public DNS — the CI VLAN gateway runs no resolver
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 20:42:07 +00:00
goodolclint-claude[bot] 5d0b384508 ci: storage VM setup diagnoses its own network and logs phases
Run 168 burned 13 minutes to report 'unable to locate package tgt' when
the real failure was dead egress from the CI VLAN (apt lists never
updated). The setup script now probes gateway/internet/DNS from inside
the VM and prints the verdicts, fails apt fast with the real error, and
marks each phase.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 20:39:02 +00:00
GoodOlClint e219766452 Merge pull request #88 from GoodOlClint/ci/retire-pve8-leg
ci: retire the PVE 8 integration leg
2026-08-31 15:18:59 -05:00
goodolclint-claude[bot] 77c6510788 ci: default PVE_VERSIONS to 9, count storage VM in headroom message
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 20:15:50 +00:00
goodolclint-claude[bot] 932cc0dcf5 ci: retire the PVE 8 integration leg
PVE 8 reached EOL 2026-08-31. The full matrix needs 42GiB free on one
parent node; no node has that after the fleet rebuild, so the headroom
guard blocks every run. Dropping the 8a/8b pair brings the requirement
to 26GiB. The module keeps PVE 8 runtime support and the script still
accepts PVE_VERSIONS='9 8' for local runs; the PVE-8-only Pester
contexts stay for SKIP_PROVISION runs against real PVE 8 hosts. Also
counts the storage VM in the headroom error message.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 20:13:33 +00:00
GoodOlClint 5564453177 Merge pull request #87 from GoodOlClint/ci/pester-exit-sandbox-storage
ci: storage and answer services move to a VM inside the CI sandbox
2026-08-31 15:03:54 -05:00
goodolclint-claude[bot] 4d3ea81bd4 ci: remove docker-compose storage definition (moved to storage VM) 2026-08-31 19:56:16 +00:00
goodolclint-claude[bot] 999bac6bdc ci: remove runner-side docker storage resources (moved to storage VM) 2026-08-31 19:56:10 +00:00
goodolclint-claude[bot] f4e5760080 ci: storage and answer services move to a VM inside the CI sandbox (2/2)
run-integration.sh: two-phase apply (storage VM configured before the
PVE guests boot), Pester PassThru with explicit failed/zero-test checks,
auto-ISO cache names embed the answer host, force-cleanup covers the
storage VM and imported cloud image, docker usage removed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 19:56:02 +00:00
goodolclint-claude[bot] f48f0ea9ae ci: storage and answer services move to a VM inside the CI sandbox (1/2)
The nested PVE guests live on an isolated VLAN with no route to the
runner network (ADR 0032, homelab repo), and the runner-hosted Docker
services died with each ephemeral ARC pod anyway. A small cloud-image VM
in the ci pool now serves NFS, iSCSI, and the auto-install answer files
from inside the sandbox. Includes fixes from Codex and in-house review:
bpg provider >= 0.79.0, serial console for the resized cloud image,
key-based SSH (cloud images refuse password auth), CIDR validation,
storage VM in the headroom check, docker socket mounts removed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 19:52:36 +00:00
GoodOlClint dc4d01c6fe Merge pull request #85 from GoodOlClint/ci/dynamic-node-selection
ci: provision picks the least-loaded node and guards host memory
2026-08-31 13:49:49 -05:00
goodolclint-claude[bot] 07b95aa4d0 Merge branch 'main' into ci/dynamic-node-selection 2026-08-31 18:44:58 +00:00
GoodOlClint 4e755fafb0 Merge pull request #86 from GoodOlClint/ci/claude-review-allowed-bots
ci: allow the goodolclint-claude and goodolclint-codex apps in Claude review
2026-08-31 13:44:20 -05:00
goodolclint-claude[bot] 71e12e68a1 ci: allow the goodolclint-claude and goodolclint-codex apps in Claude review
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 18:33:14 +00:00
goodolclint-claude[bot] 6bd1c37343 ci: PVE_TARGET_NODE is optional in the workflow docs
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 18:24:07 +00:00
goodolclint-claude[bot] d105f51246 ci: provision picks the least-loaded node and guards host memory
PVE_TARGET_NODE becomes optional: unset (or 'auto') queries
/cluster/resources for the online node with the most free memory and
refuses to provision when no node has vm_count x 8GiB + 8GiB headroom
free. The chosen node persists on the shared mount so cleanup and
force-cleanup aim at the node provision picked.

2026-08-31: a provision onto the pinned node OOM-killed a 16GiB
services-plane VM on the parent hypervisor; the pin predated a memory
bump that consumed the headroom it silently relied on. Needs PVEAuditor
on /nodes for the token's user (a non-privsep token ignores token ACLs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 18:23:23 +00:00
goodolclint-claude[bot] 6747878b19 Merge pull request #83 from GoodOlClint/dependabot/nuget/tests/PSProxmoxVE.Core.Tests/main/xunit.runner.visualstudio-4.0.0
Bump xunit.runner.visualstudio from 3.1.5 to 4.0.0
2026-08-31 17:22:31 +00:00
goodolclint-claude[bot] 3c97f0237a Merge branch 'main' into dependabot/nuget/tests/PSProxmoxVE.Core.Tests/main/xunit.runner.visualstudio-4.0.0 2026-08-31 17:19:58 +00:00
goodolclint-claude[bot] 105b2199d3 Merge pull request #82 from GoodOlClint/dependabot/nuget/tests/PSProxmoxVE.Core.Tests/main/Microsoft.NET.Test.Sdk-18.9.0
Bump Microsoft.NET.Test.Sdk from 18.5.1 to 18.9.0
2026-08-31 17:19:50 +00:00
goodolclint-claude[bot] 780efc8fbf Merge branch 'main' into dependabot/nuget/tests/PSProxmoxVE.Core.Tests/main/Microsoft.NET.Test.Sdk-18.9.0 2026-08-31 17:18:22 +00:00
goodolclint-claude[bot] e09ab64248 Merge pull request #81 from GoodOlClint/dependabot/nuget/src/PSProxmoxVE.Core/main/SharpCompress-0.50.4
Bump SharpCompress from 0.48.1 to 0.50.4
2026-08-31 17:18:17 +00:00
goodolclint-claude[bot] b16ea4164c Merge branch 'main' into dependabot/nuget/src/PSProxmoxVE.Core/main/SharpCompress-0.50.4 2026-08-31 17:17:36 +00:00
goodolclint-claude[bot] 1c6eb6919c Merge pull request #77 from GoodOlClint/dependabot/github_actions/main/actions/setup-dotnet-6
chore(deps): bump actions/setup-dotnet from 5 to 6
2026-08-31 17:17:28 +00:00
goodolclint-claude[bot] 60e84712f3 Merge branch 'main' into dependabot/github_actions/main/actions/setup-dotnet-6 2026-08-31 17:15:49 +00:00
goodolclint-claude[bot] 02595ca8e6 Merge pull request #73 from GoodOlClint/dependabot/github_actions/main/actions/checkout-7
chore(deps): bump actions/checkout from 6 to 7
2026-08-31 17:15:32 +00:00
dependabot[bot] aae3764227 Bump xunit.runner.visualstudio from 3.1.5 to 4.0.0
---
updated-dependencies:
- dependency-name: xunit.runner.visualstudio
  dependency-version: 4.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-31 17:10:23 +00:00
dependabot[bot] eacd570922 Bump Microsoft.NET.Test.Sdk from 18.5.1 to 18.9.0
---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-version: 18.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-31 17:10:15 +00:00
dependabot[bot] fea29874b2 Bump SharpCompress from 0.48.1 to 0.50.4
---
updated-dependencies:
- dependency-name: SharpCompress
  dependency-version: 0.50.4
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-31 17:09:36 +00:00
dependabot[bot] 9fdd89fd95 chore(deps): bump actions/setup-dotnet from 5 to 6
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 5 to 6.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-31 17:08:15 +00:00
dependabot[bot] 93c23d21a4 chore(deps): bump actions/checkout from 6 to 7
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-31 17:07:37 +00:00
GoodOlClint cb49507168 Merge pull request #84 from GoodOlClint/ci/pool-ci
ci: nested PVE guests land in the ci pool with VMIDs 5081-5092
2026-08-23 10:01:56 -05:00
Clint Branham 2897feb43e ci: cleanup honours PVE_TARGET_NODE and the ISO storage var
A pool-scoped token cannot list /nodes, so node discovery fell back to 'pve'
and force-cleanup silently found no VMs to destroy.
2026-08-23 09:27:27 -05:00
Clint Branham 5b896b4681 ci: integration jobs run on the psproxmoxve ARC scale set
ARC scale sets match runs-on by scale-set name, not by label list.
2026-08-23 09:08:54 -05:00
Clint Branham d3f05187dd ci: nested PVE guests land in the ci pool with VMIDs 5081-5092
The runner token is pool-scoped (PVEVMAdmin on /pool/ci only), so VM.Allocate
succeeds only with pool_id set; VMIDs move into the 5000-5999 CI range.
2026-08-23 09:06:11 -05:00
Clint Branham c7eff18899 ci: feed disk/iso storage and bridge from repo vars for rebuilt homelab 2026-08-23 02:29:49 -05:00
GoodOlClint 3a50dd2fb7 Merge pull request #70 from GoodOlClint/chore/release-0.2.0
chore: release 0.2.0
v0.2.0
2026-05-22 15:50:49 -05:00
Clint Branham ee69c699b1 chore: release 0.2.0
Minor bump: this release adds features (New-PveVm disk controller/IO
options and Get-PveVmConfig key surfacing, #65) alongside two bug fixes
(#64 semicolon form-encoding, #68 guest-exec argv).

Updates the three release artifacts in lockstep: psd1 ModuleVersion,
psd1 ReleaseNotes, and CHANGELOG ([0.2.0] cut from [Unreleased]).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 15:47:36 -05:00
GoodOlClint 5cb5c90db8 Merge pull request #69 from GoodOlClint/fix/guest-exec-args
fix: deliver Invoke-PveVmGuestExec -Args as argv (#68)
2026-05-22 14:41:45 -05:00
Clint Branham 56dcf22cea fix: address PR #69 review feedback
- VmService.ExecuteGuestCommand: guard against null elements in -Args.
  The old JSON-serialization tolerated nulls (as "null"); the repeated-key
  path would NRE in EncodeFormValue. Throw a clear ArgumentException instead.
- findings.json: refresh the stale counters block (untouched since F085) to
  the actual ledger state — next_id 92, resolved 83 — and bump last_updated
  to 2026-05-22. last_scan_date stays 2026-03-26 (F086–F091 came from issue
  triage, not a formal review scan).
- VmServiceTests: add empty-array (single command entry) and null-element
  (throws) cases.

Note: F091 is the correct next ID — F086–F090 already exist from prior
merged PRs (#60/#61/#66/#67); only the counters were lagging.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 14:38:54 -05:00
Clint Branham bc71ed4a12 fix: deliver Invoke-PveVmGuestExec -Args to the guest as argv
ExecuteGuestCommand JSON-serialized the args array into the agent/exec
'input-data' field — which is the process's STDIN, not its arguments. So
guest commands ran with no argv: cmd.exe started interactively and the
JSON blob ['/c','echo',...] arrived at its prompt.

PVE's agent/exec 'command' parameter is itself an array (element 0 = the
executable, the rest = argv) sent as repeated form keys. The low-level
client couldn't express repeated keys (Dictionary<string,string> only),
so:

- Add PostAsync(string, IEnumerable<KeyValuePair<string,string>>) to
  IPveHttpClient/PveHttpClient; BuildFormContent now emits one key=value
  field per pair, so a key may repeat.
- ExecuteGuestCommand builds command = [exe] + args as repeated 'command'
  fields and no longer touches input-data.

Tests: form-encoder repeated-key + per-value encoding cases; VmService
tests asserting the command array, order, and absence of input-data; an
integration regression guard that echoes an arg and checks it round-trips
as stdout.

Tracked as F091. Closes #68.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 14:32:04 -05:00