fix(canvas): canonicalise Job.DependsOn entries with install- prefix — fix invisible edges (#1500)
PR #1499 plumbed spec.dependsOn end-to-end and verified deps populate on first event (no /refresh-watch needed). But the openova-flow snapshot composer (flow_snapshot_local.go) emits finish-to-start relationships where fromId = jobs.JobID(deploymentID, dep). Without the "install-" prefix on each dep entry, fromId came out as: <dep>:hel1-2:seaweedfs (secondary, missing "install-") <dep>:gitea (primary, missing "install-") But the FlowNode ids in the snapshot are: <dep>:install-hel1-2:seaweedfs <dep>:install-gitea The FE canvas adapter matches by exact id → every finish-to-start rel points at a non-existent node → 224 rels emitted, 0 edges rendered. Caught on prov t103.omani.works (005080699326a7ac, 2026-05-15): curl /v1/flows/.../snapshot → 376 rels total: 152 contains, 224 finish-to-start every finish-to-start fromId malformed canvas: sibling edges invisible across all 135 install Jobs Fix in two places: internal/handler/phase1_watch.go (spawnSecondaryRegionWatchers emit): Region-prefix each dep AND inject the "install-" prefix so ev.DependsOn = ["install-<region>:<chart>"] before the bridge receives the event. Symmetric with how ev.Component is constructed. internal/jobs/helmwatch_bridge.go (OnHelmReleaseEvent): Canonicalise every dep entry: if it doesn't already start with JobNamePrefix ("install-"), prepend it. Idempotent on entries that already are canonical (set by the phase1_watch.go path). Covers the primary-region path (bare chart names like "gitea") too — Job.DependsOn now stores "install-gitea", which matches the composer's emitted FromId exactly. Tests: go build ./... + go test on internal/jobs + helmwatch + provisioner all green. (Pre-existing TestHandleWhoami_* flake in handler is unrelated.) Co-authored-by: hatiyildiz <hatice.yildiz@openova.io>
This commit is contained in:
parent
5b2c8b79a8
commit
80fdbcd8e1
@ -477,12 +477,27 @@ func (h *Handler) spawnSecondaryRegionWatchers(dep *Deployment) func() {
|
||||
// pointing at the PRIMARY region's bare-named jobs,
|
||||
// and the canvas fan-out collapses cross-region edges
|
||||
// that aren't real. helmwatch.processEvent populated
|
||||
// ev.DependsOn from the live spec.dependsOn; we just
|
||||
// rescope here.
|
||||
// ev.DependsOn from the live spec.dependsOn (bare chart
|
||||
// names like "gitea"); we both region-prefix AND inject
|
||||
// the canonical "install-" prefix so the stored Job
|
||||
// row's DependsOn matches the JobName scheme exactly.
|
||||
//
|
||||
// Why "install-<region>:<chart>" not "<region>:<chart>":
|
||||
// the FE canvas adapter looks up node ids by exact match;
|
||||
// node ids are `<dep>:install-<region>:<chart>` for
|
||||
// install Jobs. Storing "<region>:<chart>" as a dep
|
||||
// produces a `<dep>:<region>:<chart>` fromId in the
|
||||
// finish-to-start relationship, which matches no node →
|
||||
// edge invisible. Caught on prov t103.omani.works
|
||||
// (005080699326a7ac, 2026-05-15): openova-flow snapshot
|
||||
// had 224 finish-to-start rels emitted but their fromIds
|
||||
// were `<dep>:hel1-2:seaweedfs` etc., missing "install-"
|
||||
// → canvas rendered every secondary HR with no sibling
|
||||
// edges despite the rel count being non-zero.
|
||||
if len(ev.DependsOn) > 0 {
|
||||
rescoped := make([]string, 0, len(ev.DependsOn))
|
||||
for _, d := range ev.DependsOn {
|
||||
rescoped = append(rescoped, region+":"+d)
|
||||
rescoped = append(rescoped, "install-"+region+":"+d)
|
||||
}
|
||||
ev.DependsOn = rescoped
|
||||
}
|
||||
|
||||
@ -489,6 +489,33 @@ func (b *Bridge) OnHelmReleaseEvent(componentID, state, level, message string, t
|
||||
dependsOn = []string{}
|
||||
}
|
||||
|
||||
// Prepend the canonical JobNamePrefix ("install-") to every dep so
|
||||
// the stored Job.DependsOn matches the format other Jobs use as
|
||||
// their JobName. Without this, the openova-flow snapshot composer
|
||||
// emits finish-to-start relationships with fromIds like
|
||||
// "<dep>:hel1-2:seaweedfs" (missing "install-"), which match no
|
||||
// FlowNode and the canvas renders every sibling-edge invisible.
|
||||
// Caught on prov t103.omani.works (005080699326a7ac, 2026-05-15):
|
||||
// 224 finish-to-start rels emitted, every fromId malformed.
|
||||
//
|
||||
// Three input shapes the watcher may emit:
|
||||
// "cilium" (primary, bare chart) → "install-cilium"
|
||||
// "hel1-2:cilium" (secondary, region-prefixed) → "install-hel1-2:cilium"
|
||||
// "install-hel1-2:cilium"(already canonical, idempotent) → same
|
||||
if len(dependsOn) > 0 {
|
||||
canon := make([]string, 0, len(dependsOn))
|
||||
for _, d := range dependsOn {
|
||||
if d == "" {
|
||||
continue
|
||||
}
|
||||
if !strings.HasPrefix(d, JobNamePrefix) {
|
||||
d = JobNamePrefix + d
|
||||
}
|
||||
canon = append(canon, d)
|
||||
}
|
||||
dependsOn = canon
|
||||
}
|
||||
|
||||
// Ensure the bootstrap-kit parent group exists before any leaf is
|
||||
// written underneath it (idempotent — UpsertJob's merge preserves
|
||||
// any prior row).
|
||||
|
||||
Loading…
Reference in New Issue
Block a user