fix(scheduler): resolve guest routing when check_defs.target_type is blank
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).
This commit is contained in:
@@ -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
|
// absent from the DO UPDATE below — a re-seed must not reset the schedule
|
||||||
// and re-herd everything.
|
// and re-herd everything.
|
||||||
tag, err := tx.Exec(ctx,
|
tag, err := tx.Exec(ctx,
|
||||||
`INSERT INTO check_defs (entity_id, target_id, kind, config, interval_s, timeout_s, enabled, last_run_at)
|
`INSERT INTO check_defs (entity_id, target_id, target_type, kind, config, interval_s, timeout_s, enabled, last_run_at)
|
||||||
VALUES ($1, $2, $3, $4, $5, 30, true,
|
VALUES ($1, $2, $6, $3, $4, $5, 30, true,
|
||||||
now() - make_interval(secs => random() * $5::int))
|
now() - make_interval(secs => random() * $5::int))
|
||||||
ON CONFLICT (entity_id) DO UPDATE
|
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,
|
config = EXCLUDED.config, interval_s = EXCLUDED.interval_s,
|
||||||
updated_at = now()`,
|
updated_at = now()`,
|
||||||
checkID, t.ID, def.kind, configJSON, def.interval)
|
checkID, t.ID, def.kind, configJSON, def.interval, t.Type)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("upsert check_def %s: %w", checkSlug, err)
|
return false, fmt.Errorf("upsert check_def %s: %w", checkSlug, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -767,6 +767,15 @@ func checkSSHScript(ctx context.Context, pool *db.Pool, cd sqlcgen.ListEnabledCh
|
|||||||
if cd.TargetType != nil {
|
if cd.TargetType != nil {
|
||||||
targetType = *cd.TargetType
|
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 {
|
if cd.TargetID != nil {
|
||||||
switch {
|
switch {
|
||||||
case remote.IsGuest(targetType):
|
case remote.IsGuest(targetType):
|
||||||
|
|||||||
Reference in New Issue
Block a user