From 72f0f46528054a5118c34d0303d5617eb091b392 Mon Sep 17 00:00:00 2001 From: dtoro Date: Wed, 29 Jul 2026 13:44:14 +0200 Subject: [PATCH] fix(scheduler): resolve guest routing when check_defs.target_type is blank MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Older writeCheck inserts omitted target_type, so every seed-created check_def had a NULL/empty target_type. checkSSHScript's IsGuest check then never matched, and guest checks silently fell back to their baked (often mesh-only) address — keeping them 'down' even after the pct-exec routing and deployed scripts were in place. rclone stayed down for exactly this reason after the host-hop fix. writeCheck now writes target_type, and checkSSHScript resolves the type from the target_id when the column is blank (a runtime safety net for existing rows; the seed rows were also backfilled in the live DB). --- internal/checkdefaults/defaults.go | 9 +++++---- internal/scheduler/scheduler.go | 9 +++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/internal/checkdefaults/defaults.go b/internal/checkdefaults/defaults.go index a8abf77..ec8bde6 100644 --- a/internal/checkdefaults/defaults.go +++ b/internal/checkdefaults/defaults.go @@ -299,14 +299,15 @@ func writeCheck(ctx context.Context, tx pgx.Tx, t Target, idx int, def checkDef) // absent from the DO UPDATE below — a re-seed must not reset the schedule // and re-herd everything. tag, err := tx.Exec(ctx, - `INSERT INTO check_defs (entity_id, target_id, kind, config, interval_s, timeout_s, enabled, last_run_at) - VALUES ($1, $2, $3, $4, $5, 30, true, + `INSERT INTO check_defs (entity_id, target_id, target_type, kind, config, interval_s, timeout_s, enabled, last_run_at) + VALUES ($1, $2, $6, $3, $4, $5, 30, true, now() - make_interval(secs => random() * $5::int)) ON CONFLICT (entity_id) DO UPDATE - SET target_id = EXCLUDED.target_id, kind = EXCLUDED.kind, + SET target_id = EXCLUDED.target_id, target_type = EXCLUDED.target_type, + kind = EXCLUDED.kind, config = EXCLUDED.config, interval_s = EXCLUDED.interval_s, updated_at = now()`, - checkID, t.ID, def.kind, configJSON, def.interval) + checkID, t.ID, def.kind, configJSON, def.interval, t.Type) if err != nil { return false, fmt.Errorf("upsert check_def %s: %w", checkSlug, err) } diff --git a/internal/scheduler/scheduler.go b/internal/scheduler/scheduler.go index caf8e7f..89273bb 100644 --- a/internal/scheduler/scheduler.go +++ b/internal/scheduler/scheduler.go @@ -767,6 +767,15 @@ func checkSSHScript(ctx context.Context, pool *db.Pool, cd sqlcgen.ListEnabledCh if cd.TargetType != nil { targetType = *cd.TargetType } + // target_type was omitted by older writeCheck inserts, so resolve it from + // the target entity when the column is blank — otherwise the guest routing + // below (IsGuest) never triggers and a guest check falls back to its baked + // (often mesh-only) address. + if targetType == "" && cd.TargetID != nil { + if err := pool.QueryRow(ctx, "SELECT type FROM entities WHERE id = $1", *cd.TargetID).Scan(&targetType); err != nil { + targetType = "" + } + } if cd.TargetID != nil { switch { case remote.IsGuest(targetType):