feat(scheduling): node tags + service placement_tags affinity (#58)

Operator-set node labels (node_agents.tags) gate which nodes a service
may schedule onto: services.placement_tags requires every listed tag.
auto and spread filter eligible agents by tags; tags are re-evaluated
each reconcile so retagging a node re-spreads replicas. Pin + tags and
local + tags rejected; empty array clears the requirement.

Surfaces: --placement-tags on services create/update, nodes update
--tags, MCP args, OpenAPI, node-detail tag editor, service-detail
placement-tags input.

Generated with [Devin](https://devin.ai)

Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomáš DvořákandDevin authored and GitHub committed 2026-10-09 18:11:19 +02:00
1 parent 9de586f177
commit 4458de56b0
23 files changed
+475 -37

No files matched your search

@@ -0,0 +1,11 @@
-- +goose Up
-- Placement tags: operators label node_agents (tags jsonb array of strings),
-- services require a tag set (placement_tags). "auto" and spread placement
-- only consider online schedulable agents carrying every required tag.
-- Explicit node_id pins bypass tag filtering — the pin is an operator override.
ALTER TABLE services ADD COLUMN IF NOT EXISTS placement_tags jsonb NOT NULL DEFAULT '[]';
ALTER TABLE node_agents ADD COLUMN IF NOT EXISTS tags jsonb NOT NULL DEFAULT '[]';
-- +goose Down
ALTER TABLE services DROP COLUMN IF EXISTS placement_tags;
ALTER TABLE node_agents DROP COLUMN IF EXISTS tags;