Skip to content

feat: node labels and selective deployment#32

Merged
TerrifiedBug merged 8 commits intomainfrom
feat/node-labels
Mar 7, 2026
Merged

feat: node labels and selective deployment#32
TerrifiedBug merged 8 commits intomainfrom
feat/node-labels

Conversation

@TerrifiedBug
Copy link
Copy Markdown
Owner

Summary

  • Add labels (JSON) field to VectorNode and nodeSelector (JSON) field to Pipeline models with database migration
  • Fleet router: updateLabels mutation (EDITOR access) and listLabels query (VIEWER access) for managing node labels
  • Agent heartbeat: accept optional labels field; merge with existing labels (UI-set labels take precedence)
  • Agent config endpoint: filter deployed pipelines by nodeSelector matching node labels
  • Deploy router: accept nodeSelector on deploy, save to pipeline; include labels in environment info
  • Fleet table: display label badges (key=value) per node
  • Node detail page: editable labels section with key-value input pairs, add/remove controls
  • Deploy dialog: multi-select combobox for label-based node targeting with live "X of Y nodes match" counter
  • Documentation updates for fleet management and agent reference

Test plan

  • Run Prisma migration and verify labels column on VectorNode and nodeSelector on Pipeline
  • Add labels to a node via the detail page; verify they persist and display in the fleet table
  • Deploy a pipeline with no label selector; verify it deploys to all nodes
  • Deploy a pipeline with a label selector; verify only matching nodes receive it via /api/agent/config
  • Send a heartbeat with agent-reported labels; verify merge behavior (UI labels take precedence)
  • Verify the deploy dialog shows available labels and matching node count updates live
  • Verify backward compatibility: existing pipelines with no nodeSelector deploy to all nodes

…oy selector

- Fleet router: updateLabels mutation, listLabels query
- Heartbeat: accept and merge agent-reported labels (UI takes precedence)
- Config endpoint: filter pipelines by nodeSelector vs node labels
- Deploy router: accept nodeSelector, save to pipeline, include labels in env info
@github-actions github-actions bot added documentation Improvements or additions to documentation feature labels Mar 7, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 7, 2026

Greptile Summary

This PR successfully adds node label management and selector-based pipeline deployment to VectorFlow. Nodes can carry arbitrary key-value metadata set via the UI or reported by the agent, and pipeline deploys can be scoped to nodes matching a label selector — with no selector defaulting to deploy-to-all for full backward compatibility.

Key improvements over the previous review:

  • Database schema correctly adds a labels column (JSONB with empty-object default) to VectorNode and a nullable nodeSelector column to Pipeline
  • Heartbeat label merge now uses a single atomic SQL $executeRaw update, eliminating the TOCTOU race — UI-set labels correctly take precedence via JSONB merge semantics
  • Agent config endpoint properly applies in-memory label matching; empty or null selector passes all nodes
  • Deploy flow correctly persists nodeSelector only after the deploy service succeeds, preventing orphaned selectors on deploy failures
  • Deploy dialog properly seeds label selections from the pipeline's existing nodeSelector on open, so re-deploys preserve targeting
  • Combobox prevents duplicate label keys via a keyAlreadyUsed guard — selecting an alternate value for an already-selected key disables that option

One minor convention gap remains: the new fleet.updateLabels mutation skips the existence check that every other fleet mutation performs, causing a raw Prisma error (500) instead of a tRPC NOT_FOUND (404) when passed an invalid nodeId.

Confidence Score: 4/5

  • This PR is safe to merge; all previously reported critical issues have been correctly addressed and the new code is largely consistent with existing patterns.
  • All four previously reported critical issues (TOCTOU race, duplicate-key selector bug, re-deploy clearing nodeSelector, and nodeSelector persisted before deploy success) have been properly fixed. The remaining finding is a minor convention gap in error handling for an invalid nodeId in the new updateLabels mutation, which would produce a 500 rather than a 404 but does not affect correctness or security.
  • src/server/routers/fleet.ts — the new updateLabels mutation should add a findUnique existence check to match the error-handling pattern of every other fleet mutation.

Sequence Diagram

sequenceDiagram
    participant UI as Browser (Deploy Dialog)
    participant tRPC as tRPC Router
    participant DB as PostgreSQL
    participant Agent as Vector Agent

    UI->>tRPC: deploy.preview { pipelineId }
    tRPC-->>UI: { nodeSelector, configYaml, nodes[] }
    Note over UI: useEffect seeds selectedLabels<br/>from existing nodeSelector

    UI->>tRPC: deploy.agent { pipelineId, nodeSelector }
    tRPC->>tRPC: deployAgent() — create PipelineVersion
    tRPC->>DB: pipeline.update { nodeSelector } (only on success)
    tRPC-->>UI: { success, versionNumber }

    Agent->>tRPC: POST /api/agent/heartbeat { labels }
    tRPC->>DB: UPDATE VectorNode SET labels = agent_labels || labels
    Note over DB: Atomic merge — existing DB labels win

    Agent->>tRPC: GET /api/agent/config
    tRPC->>DB: SELECT node.labels, pipeline.nodeSelector
    Note over tRPC: Filter: selector entries must all match node labels
    tRPC-->>Agent: matching pipelines only
Loading

Last reviewed commit: 469e359

- Replace two-step read-then-write label merge with atomic PostgreSQL
  JSONB operation to prevent TOCTOU race with fleet.updateLabels
- Disable combobox label options whose key is already selected to
  prevent silent overwrites in nodeSelector
- Seed selectedLabels from existing pipeline nodeSelector on dialog
  open to prevent re-deploy from clearing the saved node selector
- Return nodeSelector from deploy.preview query so the dialog can
  hydrate existing selections
@TerrifiedBug TerrifiedBug merged commit 56296f4 into main Mar 7, 2026
10 of 12 checks passed
@TerrifiedBug TerrifiedBug deleted the feat/node-labels branch March 7, 2026 14:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant