Skip to content

feat(server): surface VM→host placement in the cross-layer graph#129

Merged
astrojerms merged 1 commit into
mainfrom
feat/graph-followups
Jul 12, 2026
Merged

feat(server): surface VM→host placement in the cross-layer graph#129
astrojerms merged 1 commit into
mainfrom
feat/graph-followups

Conversation

@astrojerms

Copy link
Copy Markdown
Owner

What

A k3s-managed VirtualMachine pins itself to a physical host via a plain spec.node string. GetChildrenGraph only turned $ref markers and Planner children into edges, so a workload-rooted graph reached the cluster's VMs but stopped there — the host they run on was invisible. This completes the workload → Cluster → K3sNode → VM → host spine of the unified cross-layer graph (the follow-on noted when Phase 6 / #128 shipped).

How

expandNode now synthesizes a VM → ProxmoxNode ref edge from spec.node.

Two deliberate design choices, both documented at the call site:

  1. Graph-only, not a $ref. Making spec.node a real $ref would couple VM Apply to the observed-only ProxmoxNode being fetchable — refs.Resolve errors on any unresolvable ref, so a transient node-Get failure would fail VM provisioning. The edge is synthesized purely for the graph; the apply path is untouched.
  2. The host is a terminal node — added but not enqueued for expansion. Otherwise ChildrenOf(ProxmoxNode) would pull every unrelated guest on the box into a focused workload graph. A ProxmoxNode-rooted query still lists all its guests, exactly as before.

Tests

  • TestGetChildrenGraphSurfacesVMHostPlacement — VM with spec.node yields the placement edge; host is present, unmanaged (observed/dimmed), and terminal (2 nodes, no sibling fan-out).
  • TestGetChildrenGraphVMWithoutNodeHasNoPlacementEdge — a VM with provider-default placement (no spec.node) draws no edge.

Backend-only; the UI DagView renders ref edges generically already.

A k3s-managed VirtualMachine pins itself to a physical host via a plain
spec.node string. GetChildrenGraph previously only turned $ref markers and
Planner children into edges, so a workload-rooted graph reached the cluster's
VMs but stopped there — the host they run on was invisible.

expandNode now synthesizes a VM→ProxmoxNode 'ref' edge from spec.node. The
host is deliberately NOT a $ref: making spec.node one would couple VM Apply to
the observed-only ProxmoxNode being fetchable (refs.Resolve errors on any
unresolvable ref), so the edge is graph-only. The host is a TERMINAL node —
added but not enqueued — so ChildrenOf(ProxmoxNode) doesn't drag every
unrelated guest on the box into a focused workload graph. A ProxmoxNode-rooted
query still lists all its guests as before.

Completes the workload→Cluster→K3sNode→VM→host spine of the cross-layer graph.
@astrojerms astrojerms merged commit c837fe5 into main Jul 12, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant