fix(supervisor): compat shim for COMPUTE checkpoint type (#3703)
Workloads bundled with CLI versions before v4.4.4 use a strict zod enum for `checkpoint.type` that only allows DOCKER and KUBERNETES. When a customer's runs are routed via the compute path, those old runners receive `type: "COMPUTE"` on `/snapshots/since/...` and `/dequeue` responses and fail validation - blocking silent migration of existing deployments. The workload never reads the field - only validates the shape. Rewriting COMPUTE -> KUBERNETES on the way out lets older runners keep parsing while the database and internal services keep the real value. Limited to the two workload-facing endpoints whose response includes a checkpoint; `/continue`, `/attempts/start`, `/attempts/complete` all return shapes without one. Followup to #3114.
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
area: supervisor
|
||||
type: fix
|
||||
---
|
||||
|
||||
Keep older workloads working when checkpoints are produced by the compute path
|
||||
@@ -43,6 +43,18 @@ const WorkloadActionParams = z.object({
|
||||
snapshotFriendlyId: z.string(),
|
||||
});
|
||||
|
||||
// Workloads bundled into customer task images before CLI v4.4.4 use a strict
|
||||
// zod enum for checkpoint type that only allows DOCKER and KUBERNETES. The
|
||||
// workload never reads this field - it only validates the response shape - so
|
||||
// rewriting it to a known value keeps older runners working without affecting
|
||||
// the value stored in the database or seen by internal services.
|
||||
function legacifyCheckpointType<T extends { checkpoint?: { type: string } | null }>(item: T): T {
|
||||
if (item.checkpoint?.type === "COMPUTE") {
|
||||
return { ...item, checkpoint: { ...item.checkpoint, type: "KUBERNETES" } } as T;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
type WorkloadServerEvents = {
|
||||
runConnected: [
|
||||
{
|
||||
@@ -384,7 +396,9 @@ export class WorkloadServer extends EventEmitter<WorkloadServerEvents> {
|
||||
return;
|
||||
}
|
||||
|
||||
reply.json(sinceSnapshotResponse.data satisfies WorkloadRunSnapshotsSinceResponseBody);
|
||||
reply.json({
|
||||
snapshots: sinceSnapshotResponse.data.snapshots.map(legacifyCheckpointType),
|
||||
} satisfies WorkloadRunSnapshotsSinceResponseBody);
|
||||
},
|
||||
}
|
||||
)
|
||||
@@ -409,7 +423,9 @@ export class WorkloadServer extends EventEmitter<WorkloadServerEvents> {
|
||||
return;
|
||||
}
|
||||
|
||||
reply.json(dequeueResponse.data satisfies WorkloadDequeueFromVersionResponseBody);
|
||||
reply.json(
|
||||
dequeueResponse.data.map(legacifyCheckpointType) satisfies WorkloadDequeueFromVersionResponseBody
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user