mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-10 02:25:56 +00:00
72599bd1ec
A host running both PVE and PBS is a deployment the docs call officially supported, and the agent's RunAll registers each product in turn from the one install token. The bootstrap grant recorded consumption per TOKEN, so the PVE leg spent it, the PBS leg came back canRegister=false, the agent wrote a proxmox-pbs-registration-blocked marker, and install.sh printed an ERROR banner over a PVE source that had registered perfectly well. - server: consumption is now recorded per canonical type. One PVE create and one PBS create per token, each still one-shot — a second create of the same type takes the same 403. The bounds that are not per type stay singular: the 24h mint-age clock and the first-use bound_hostname are shared, so whichever type registers first pins the hostname for both and the second type cannot be aimed at another machine. The per-type ledger lives in proxmox_registration_consumed_types; a record carrying only proxmox_registration_completed=true predates it and still reads as every type consumed, so upgrading cannot revive a token already spent in the field. The unsuffixed completion block keeps tracking the most recent completion, which also leaves an older binary reading the same store failing closed. - rollback: the consume-before-persist undo is scoped to the keys one consumption wrote, so a failed PBS source save restores the PBS grant without resurrecting the PVE grant that already produced a source. - agent: RunAll no longer lets one product's failure speak for the host. It attempts and returns the remaining products, errors only when every detected product failed, and publishes the detected products in a proxmox-detected-types state marker. - installer: report_proxmox_registration_outcome reads that marker, waits for an outcome from each detected product, and prints a success or denial line per product instead of one verdict. Agents predating the marker keep the old first-outcome-wins timing so a single-product host does not wait out the window. The blocked-marker path now only fires on genuine refusals. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>