All checks were successful
Run Check Script / check (pull_request) Successful in 2m23s
DeploymentSpec.target_devices (flat string list) is gone. In its
place, DeploymentSpec.target_selector is a minimal
LabelSelector-shaped struct (matchLabels only for now, matchExpressions
deferred until there's a real need). Devices publish a labels map
in every AgentStatus heartbeat; operator resolves the selector
against the current fleet snapshot on each reconcile + aggregator
tick.
No legacy shim — the CRD is v1alpha1 and not yet deployed in the wild.
Aggregator consequences:
- controller and aggregator now share a StatusSnapshots map so
selector resolution sees the same data on both sides.
- unreported is dropped: a device that has never heartbeated is
invisible to the selector machinery, so the field no longer
has clean semantics. "device went dark" can come back as a
staleness metric later if needed.
- controller's MissingTargets error is gone: zero matches is a
legitimate state (devices may not have joined yet). The
controller logs and fast-requeues (15s/30s) so a just-joining
device picks the deployment up without needing a
cross-task subscription.
Agent + setup Score:
- Agent config grows a [labels] section (BTreeMap); the flat
[agent].group field is gone. group becomes just one label.
- IotDeviceSetupConfig takes a BTreeMap<String, String> instead
of a String group. TOML render iterates the BTreeMap (ordered)
so idempotent change detection still works cleanly.
CLI-facing:
- example_iot_apply_deployment: --target-device -> --to, accepts
comma-separated key=value pairs.
- example_iot_vm_setup: --group -> --labels, same grammar.
- smoke-a4.sh: VM publishes group=$GROUP,device=$DEVICE_ID;
deploys target --to device=$DEVICE_ID so single-device smoke
behavior is preserved while exercising the selector path.
CRD regenerated via chart/regen-crd.sh. 7 contract tests + 6
operator tests pass.