@shipfox/api-runners 9.3.0 → 10.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +4 -4
- package/CHANGELOG.md +38 -0
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/core/runner-activation.d.ts +6 -0
- package/dist/core/runner-activation.d.ts.map +1 -1
- package/dist/core/runner-activation.js +20 -19
- package/dist/core/runner-activation.js.map +1 -1
- package/dist/core/runner-control-sessions.d.ts +2 -1
- package/dist/core/runner-control-sessions.d.ts.map +1 -1
- package/dist/core/runner-control-sessions.js +65 -19
- package/dist/core/runner-control-sessions.js.map +1 -1
- package/dist/db/db.d.ts +34 -0
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +1 -1
- package/dist/db/index.js.map +1 -1
- package/dist/db/job-executions.d.ts +7 -0
- package/dist/db/job-executions.d.ts.map +1 -1
- package/dist/db/job-executions.js +25 -0
- package/dist/db/job-executions.js.map +1 -1
- package/dist/db/runner-assignments.d.ts +6 -0
- package/dist/db/runner-assignments.d.ts.map +1 -1
- package/dist/db/runner-assignments.js +57 -42
- package/dist/db/runner-assignments.js.map +1 -1
- package/dist/db/runner-instances.d.ts.map +1 -1
- package/dist/db/runner-instances.js +64 -19
- package/dist/db/runner-instances.js.map +1 -1
- package/dist/db/schema/runner-instances.d.ts +17 -0
- package/dist/db/schema/runner-instances.d.ts.map +1 -1
- package/dist/db/schema/runner-instances.js +3 -0
- package/dist/db/schema/runner-instances.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/presentation/inter-module.d.ts.map +1 -1
- package/dist/presentation/inter-module.js +7 -2
- package/dist/presentation/inter-module.js.map +1 -1
- package/dist/presentation/routes/runner-enrollment.d.ts +9 -0
- package/dist/presentation/routes/runner-enrollment.d.ts.map +1 -1
- package/dist/presentation/routes/runner-enrollment.js +36 -23
- package/dist/presentation/routes/runner-enrollment.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/drizzle/0001_intended_reservation.sql +3 -0
- package/drizzle/meta/0001_snapshot.json +2093 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +10 -10
- package/src/config.test.ts +11 -0
- package/src/config.ts +1 -1
- package/src/core/runner-activation.ts +48 -38
- package/src/core/runner-control-sessions.ts +115 -33
- package/src/db/index.ts +1 -0
- package/src/db/job-executions.ts +28 -0
- package/src/db/runner-assignments.test.ts +81 -0
- package/src/db/runner-assignments.ts +134 -86
- package/src/db/runner-instances.test.ts +182 -0
- package/src/db/runner-instances.ts +123 -28
- package/src/db/schema/runner-instances.ts +9 -0
- package/src/index.ts +1 -0
- package/src/presentation/inter-module.ts +4 -0
- package/src/presentation/routes/poll-demand.test.ts +2 -2
- package/src/presentation/routes/runner-enrollment.test.ts +144 -1
- package/src/presentation/routes/runner-enrollment.ts +40 -20
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/presentation/inter-module.ts"],"sourcesContent":["import {runnersInterModuleContract} from '@shipfox/api-runners-dto/inter-module';\nimport {\n createInterModuleKnownError,\n defineInterModulePresentation,\n type InterModulePresentation,\n} from '@shipfox/inter-module';\nimport {EmptyRequiredLabelsError} from '#core/errors.js';\nimport {getEffectiveRunnerToolCapabilities} from '#core/runner-tool-capabilities.js';\nimport {\n cancelRunnerJobs,\n enqueueJobExecution,\n isJobLeaseActive,\n releaseJobExecution,\n} from '#db/job-executions.js';\n\nexport function createRunnersInterModulePresentation(): InterModulePresentation<\n typeof runnersInterModuleContract\n> {\n return defineInterModulePresentation(runnersInterModuleContract, {\n enqueueJobExecution: async (input) => {\n try {\n await enqueueJobExecution(input);\n return {};\n } catch (error) {\n throw toEnqueueJobExecutionKnownError(error);\n }\n },\n releaseJobExecution: async (input) => {\n await releaseJobExecution(input);\n return {};\n },\n cancelJobs: async (input) => {\n await cancelRunnerJobs(input);\n return {};\n },\n getLeaseState: async (input) => ({active: await isJobLeaseActive(input)}),\n getEffectiveRunnerToolCapabilities: async (input) => {\n const result = await getEffectiveRunnerToolCapabilities(input);\n return {capabilities: result.capabilities, reportFresh: result.reportFresh};\n },\n });\n}\n\nexport function toEnqueueJobExecutionKnownError(error: unknown): unknown {\n if (error instanceof EmptyRequiredLabelsError) {\n return createInterModuleKnownError(\n runnersInterModuleContract.methods.enqueueJobExecution,\n 'empty-required-labels',\n {},\n );\n }\n return error;\n}\n"],"names":["runnersInterModuleContract","createInterModuleKnownError","defineInterModulePresentation","EmptyRequiredLabelsError","getEffectiveRunnerToolCapabilities","cancelRunnerJobs","enqueueJobExecution","isJobLeaseActive","releaseJobExecution","createRunnersInterModulePresentation","input","error","toEnqueueJobExecutionKnownError","cancelJobs","getLeaseState","active","result","capabilities","reportFresh","methods"],"mappings":"AAAA,SAAQA,0BAA0B,QAAO,wCAAwC;AACjF,SACEC,2BAA2B,EAC3BC,6BAA6B,QAExB,wBAAwB;AAC/B,SAAQC,wBAAwB,QAAO,kBAAkB;AACzD,SAAQC,kCAAkC,QAAO,oCAAoC;AACrF,SACEC,gBAAgB,EAChBC,mBAAmB,EACnBC,gBAAgB,EAChBC,mBAAmB,QACd,wBAAwB;AAE/B,OAAO,SAASC;IAGd,
|
|
1
|
+
{"version":3,"sources":["../../src/presentation/inter-module.ts"],"sourcesContent":["import {runnersInterModuleContract} from '@shipfox/api-runners-dto/inter-module';\nimport {\n createInterModuleKnownError,\n defineInterModulePresentation,\n type InterModulePresentation,\n} from '@shipfox/inter-module';\nimport {EmptyRequiredLabelsError} from '#core/errors.js';\nimport {getEffectiveRunnerToolCapabilities} from '#core/runner-tool-capabilities.js';\nimport {\n cancelRunnerJobs,\n enqueueJobExecution,\n getWorkspaceJobCounts,\n isJobLeaseActive,\n releaseJobExecution,\n} from '#db/job-executions.js';\n\nexport function createRunnersInterModulePresentation(): InterModulePresentation<\n typeof runnersInterModuleContract\n> {\n return defineInterModulePresentation(runnersInterModuleContract, {\n enqueueJobExecution: async (input) => {\n try {\n await enqueueJobExecution(input);\n return {};\n } catch (error) {\n throw toEnqueueJobExecutionKnownError(error);\n }\n },\n releaseJobExecution: async (input) => {\n await releaseJobExecution(input);\n return {};\n },\n cancelJobs: async (input) => {\n await cancelRunnerJobs(input);\n return {};\n },\n getLeaseState: async (input) => ({active: await isJobLeaseActive(input)}),\n getEffectiveRunnerToolCapabilities: async (input) => {\n const result = await getEffectiveRunnerToolCapabilities(input);\n return {capabilities: result.capabilities, reportFresh: result.reportFresh};\n },\n getWorkspaceJobCounts: async ({workspaceIds}) => ({\n counts: await getWorkspaceJobCounts({workspaceIds}),\n }),\n });\n}\n\nexport function toEnqueueJobExecutionKnownError(error: unknown): unknown {\n if (error instanceof EmptyRequiredLabelsError) {\n return createInterModuleKnownError(\n runnersInterModuleContract.methods.enqueueJobExecution,\n 'empty-required-labels',\n {},\n );\n }\n return error;\n}\n"],"names":["runnersInterModuleContract","createInterModuleKnownError","defineInterModulePresentation","EmptyRequiredLabelsError","getEffectiveRunnerToolCapabilities","cancelRunnerJobs","enqueueJobExecution","getWorkspaceJobCounts","isJobLeaseActive","releaseJobExecution","createRunnersInterModulePresentation","input","error","toEnqueueJobExecutionKnownError","cancelJobs","getLeaseState","active","result","capabilities","reportFresh","workspaceIds","counts","methods"],"mappings":"AAAA,SAAQA,0BAA0B,QAAO,wCAAwC;AACjF,SACEC,2BAA2B,EAC3BC,6BAA6B,QAExB,wBAAwB;AAC/B,SAAQC,wBAAwB,QAAO,kBAAkB;AACzD,SAAQC,kCAAkC,QAAO,oCAAoC;AACrF,SACEC,gBAAgB,EAChBC,mBAAmB,EACnBC,qBAAqB,EACrBC,gBAAgB,EAChBC,mBAAmB,QACd,wBAAwB;AAE/B,OAAO,SAASC;IAGd,OAAOR,8BAA8BF,4BAA4B;QAC/DM,qBAAqB,OAAOK;YAC1B,IAAI;gBACF,MAAML,oBAAoBK;gBAC1B,OAAO,CAAC;YACV,EAAE,OAAOC,OAAO;gBACd,MAAMC,gCAAgCD;YACxC;QACF;QACAH,qBAAqB,OAAOE;YAC1B,MAAMF,oBAAoBE;YAC1B,OAAO,CAAC;QACV;QACAG,YAAY,OAAOH;YACjB,MAAMN,iBAAiBM;YACvB,OAAO,CAAC;QACV;QACAI,eAAe,OAAOJ,QAAW,CAAA;gBAACK,QAAQ,MAAMR,iBAAiBG;YAAM,CAAA;QACvEP,oCAAoC,OAAOO;YACzC,MAAMM,SAAS,MAAMb,mCAAmCO;YACxD,OAAO;gBAACO,cAAcD,OAAOC,YAAY;gBAAEC,aAAaF,OAAOE,WAAW;YAAA;QAC5E;QACAZ,uBAAuB,OAAO,EAACa,YAAY,EAAC,GAAM,CAAA;gBAChDC,QAAQ,MAAMd,sBAAsB;oBAACa;gBAAY;YACnD,CAAA;IACF;AACF;AAEA,OAAO,SAASP,gCAAgCD,KAAc;IAC5D,IAAIA,iBAAiBT,0BAA0B;QAC7C,OAAOF,4BACLD,2BAA2BsB,OAAO,CAAChB,mBAAmB,EACtD,yBACA,CAAC;IAEL;IACA,OAAOM;AACT"}
|
|
@@ -4,5 +4,14 @@ export declare const exchangeRunnerBootstrapRoute: import("@shipfox/node-fastify
|
|
|
4
4
|
export declare const enrollRunnerRoute: import("@shipfox/node-fastify").RouteDefinition;
|
|
5
5
|
export declare const attachRunnerControlProviderIdRoute: import("@shipfox/node-fastify").RouteDefinition;
|
|
6
6
|
export declare const runnerControlHeartbeatRoute: import("@shipfox/node-fastify").RouteDefinition;
|
|
7
|
+
type RunnerAssignmentPollParams = {
|
|
8
|
+
deadline: number;
|
|
9
|
+
intervalMs: number;
|
|
10
|
+
signal: AbortSignal;
|
|
11
|
+
getAssignment: () => Promise<unknown | null>;
|
|
12
|
+
issueActivationToken: () => Promise<string | null>;
|
|
13
|
+
};
|
|
14
|
+
export declare function pollForRunnerActivationToken(params: RunnerAssignmentPollParams): Promise<string | null>;
|
|
7
15
|
export declare const runnerAssignmentPollRoute: import("@shipfox/node-fastify").RouteDefinition;
|
|
16
|
+
export {};
|
|
8
17
|
//# sourceMappingURL=runner-enrollment.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner-enrollment.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/runner-enrollment.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runner-enrollment.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/runner-enrollment.ts"],"names":[],"mappings":"AAgCA,eAAO,MAAM,0BAA0B,iDA2BrC,CAAC;AAEH,eAAO,MAAM,mCAAmC,iDAmB9C,CAAC;AAEH,eAAO,MAAM,4BAA4B,iDA2BvC,CAAC;AAEH,eAAO,MAAM,iBAAiB,iDAuB5B,CAAC;AAEH,eAAO,MAAM,kCAAkC,iDAkB7C,CAAC;AAEH,eAAO,MAAM,2BAA2B,iDAYtC,CAAC;AAEH,KAAK,0BAA0B,GAAG;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;IACpB,aAAa,EAAE,MAAM,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAC7C,oBAAoB,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACpD,CAAC;AACF,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,0BAA0B,GACjC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWxB;AACD,eAAO,MAAM,yBAAyB,iDAwBpC,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { requireProvisionerContext, requireRunnerControlSessionContext } from '@shipfox/api-auth-context';
|
|
2
|
-
import { attachRunnerControlProviderIdBodySchema, createRunnerInstancesBodySchema, createRunnerInstancesResponseSchema, runnerAssignmentPollResponseSchema, runnerBootstrapExchangeBodySchema, runnerBootstrapExchangeResponseSchema, runnerControlHeartbeatResponseSchema, runnerEnrollmentBodySchema } from '@shipfox/api-runners-dto';
|
|
2
|
+
import { attachRunnerControlProviderIdBodySchema, createRunnerInstancesBodySchema, createRunnerInstancesResponseSchema, runnerAssignmentPollResponseSchema, runnerBootstrapExchangeBodySchema, runnerBootstrapExchangeResponseSchema, runnerControlHeartbeatResponseSchema, runnerEnrollmentBodySchema, runnerEnrollmentResponseSchema } from '@shipfox/api-runners-dto';
|
|
3
3
|
import { ClientError, defineRoute } from '@shipfox/node-fastify';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { config } from '#config.js';
|
|
@@ -25,9 +25,14 @@ export const createRunnerInstancesRoute = defineRoute({
|
|
|
25
25
|
...request.body.provider_kind ? {
|
|
26
26
|
providerKind: request.body.provider_kind
|
|
27
27
|
} : {},
|
|
28
|
-
runnerInstances: request.body.runner_instances.map((runner)=>
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
runnerInstances: request.body.runner_instances.map((runner)=>({
|
|
29
|
+
...runner.template_key ? {
|
|
30
|
+
templateKey: runner.template_key
|
|
31
|
+
} : {},
|
|
32
|
+
...runner.reservation_id ? {
|
|
33
|
+
reservationId: runner.reservation_id
|
|
34
|
+
} : {}
|
|
35
|
+
})),
|
|
31
36
|
ttlSeconds: config.RUNNER_BOOTSTRAP_TOKEN_TTL_SECONDS
|
|
32
37
|
});
|
|
33
38
|
return {
|
|
@@ -105,7 +110,7 @@ export const enrollRunnerRoute = defineRoute({
|
|
|
105
110
|
schema: {
|
|
106
111
|
body: runnerEnrollmentBodySchema,
|
|
107
112
|
response: {
|
|
108
|
-
|
|
113
|
+
200: runnerEnrollmentResponseSchema
|
|
109
114
|
}
|
|
110
115
|
},
|
|
111
116
|
preHandler: authenticateRunnerControlSession,
|
|
@@ -115,9 +120,9 @@ export const enrollRunnerRoute = defineRoute({
|
|
|
115
120
|
});
|
|
116
121
|
throw error;
|
|
117
122
|
},
|
|
118
|
-
handler: async (request
|
|
123
|
+
handler: async (request)=>{
|
|
119
124
|
const session = requireRunnerControlSessionContext(request);
|
|
120
|
-
await enrollRunnerControlSession({
|
|
125
|
+
const activationToken = await enrollRunnerControlSession({
|
|
121
126
|
runnerInstanceId: session.runnerInstanceId,
|
|
122
127
|
provisionerId: session.provisionerId,
|
|
123
128
|
labels: request.body.labels,
|
|
@@ -127,7 +132,9 @@ export const enrollRunnerRoute = defineRoute({
|
|
|
127
132
|
providerKind: request.body.provider_kind,
|
|
128
133
|
protocolVersion: request.body.protocol_version
|
|
129
134
|
});
|
|
130
|
-
return
|
|
135
|
+
return {
|
|
136
|
+
activation_token: activationToken
|
|
137
|
+
};
|
|
131
138
|
}
|
|
132
139
|
});
|
|
133
140
|
export const attachRunnerControlProviderIdRoute = defineRoute({
|
|
@@ -172,6 +179,18 @@ export const runnerControlHeartbeatRoute = defineRoute({
|
|
|
172
179
|
};
|
|
173
180
|
}
|
|
174
181
|
});
|
|
182
|
+
export async function pollForRunnerActivationToken(params) {
|
|
183
|
+
while(Date.now() <= params.deadline){
|
|
184
|
+
if (params.signal.aborted) return null;
|
|
185
|
+
const assignment = await params.getAssignment();
|
|
186
|
+
if (assignment) {
|
|
187
|
+
const activationToken = await params.issueActivationToken();
|
|
188
|
+
if (activationToken) return activationToken;
|
|
189
|
+
}
|
|
190
|
+
await new Promise((resolve)=>setTimeout(resolve, params.intervalMs));
|
|
191
|
+
}
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
175
194
|
export const runnerAssignmentPollRoute = defineRoute({
|
|
176
195
|
method: 'GET',
|
|
177
196
|
path: '/assignment',
|
|
@@ -187,24 +206,18 @@ export const runnerAssignmentPollRoute = defineRoute({
|
|
|
187
206
|
const deadline = Date.now() + config.RUNNER_ASSIGNMENT_POLL_MAX_WAIT_SECONDS * 1000;
|
|
188
207
|
const abortController = new AbortController();
|
|
189
208
|
reply.raw.on('close', ()=>abortController.abort());
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
const activationToken = await issueRunnerActivationToken({
|
|
209
|
+
const activationToken = await pollForRunnerActivationToken({
|
|
210
|
+
deadline,
|
|
211
|
+
intervalMs: config.RUNNER_ASSIGNMENT_POLL_INTERVAL_MS,
|
|
212
|
+
signal: abortController.signal,
|
|
213
|
+
getAssignment: ()=>getRunnerAssignment(session),
|
|
214
|
+
issueActivationToken: ()=>issueRunnerActivationToken({
|
|
197
215
|
...session,
|
|
198
216
|
ttlSeconds: config.RUNNER_ACTIVATION_TOKEN_TTL_SECONDS
|
|
199
|
-
})
|
|
200
|
-
|
|
201
|
-
activation_token: activationToken
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
await new Promise((resolve)=>setTimeout(resolve, config.RUNNER_ASSIGNMENT_POLL_INTERVAL_MS));
|
|
205
|
-
}
|
|
217
|
+
})
|
|
218
|
+
});
|
|
206
219
|
return {
|
|
207
|
-
activation_token:
|
|
220
|
+
activation_token: activationToken
|
|
208
221
|
};
|
|
209
222
|
}
|
|
210
223
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/presentation/routes/runner-enrollment.ts"],"sourcesContent":["import {\n requireProvisionerContext,\n requireRunnerControlSessionContext,\n} from '@shipfox/api-auth-context';\nimport {\n attachRunnerControlProviderIdBodySchema,\n createRunnerInstancesBodySchema,\n createRunnerInstancesResponseSchema,\n runnerAssignmentPollResponseSchema,\n runnerBootstrapExchangeBodySchema,\n runnerBootstrapExchangeResponseSchema,\n runnerControlHeartbeatResponseSchema,\n runnerEnrollmentBodySchema,\n} from '@shipfox/api-runners-dto';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {z} from 'zod';\nimport {config} from '#config.js';\nimport {getRunnerAssignment, issueRunnerActivationToken} from '#core/runner-activation.js';\nimport {\n attachRunnerControlProviderId,\n createRunnerInstancesWithBootstrapTokens,\n enrollRunnerControlSession,\n exchangeRunnerBootstrapToken,\n RunnerBootstrapTokenInvalidError,\n RunnerControlSessionInvalidError,\n touchRunnerControlSession,\n} from '#core/runner-control-sessions.js';\nimport {attachRunnerInstanceProviderId} from '#core/runner-instances.js';\nimport {runnerBootstrapExchangeCount, runnerControlHeartbeatCount} from '#metrics/instance.js';\nimport {authenticateRunnerControlSession} from '#presentation/auth/index.js';\n\nexport const createRunnerInstancesRoute = defineRoute({\n method: 'POST',\n path: '/runner-instances/batch',\n description:\n 'Create provisioner-owned runner instances and one-use bootstrap tokens before launch',\n schema: {\n body: createRunnerInstancesBodySchema,\n response: {200: createRunnerInstancesResponseSchema},\n },\n handler: async (request) => {\n const {provisionerTokenId} = requireProvisionerContext(request);\n const results = await createRunnerInstancesWithBootstrapTokens({\n provisionerId: provisionerTokenId,\n ...(request.body.provider_kind ? {providerKind: request.body.provider_kind} : {}),\n runnerInstances: request.body.runner_instances.map((runner) =>\n runner.template_key ? {templateKey: runner.template_key} : {},\n ),\n ttlSeconds: config.RUNNER_BOOTSTRAP_TOKEN_TTL_SECONDS,\n });\n return {\n runner_instances: results.map((result) => ({\n runner_instance_id: result.runnerInstanceId,\n bootstrap_token: result.bootstrapToken,\n })),\n };\n },\n});\n\nexport const attachRunnerInstanceProviderIdRoute = defineRoute({\n method: 'POST',\n path: '/runner-instances/:runnerInstanceId/provider-runner',\n description: 'Attach the provider identity after the provisioner launches a runner instance',\n schema: {\n params: z.object({runnerInstanceId: z.string().uuid()}),\n body: attachRunnerControlProviderIdBodySchema,\n response: {200: z.object({attached: z.boolean()})},\n },\n handler: async (request) => {\n const {provisionerTokenId} = requireProvisionerContext(request);\n return {\n attached: await attachRunnerInstanceProviderId({\n runnerInstanceId: request.params.runnerInstanceId,\n provisionerId: provisionerTokenId,\n providerRunnerId: request.body.provider_runner_id,\n }),\n };\n },\n});\n\nexport const exchangeRunnerBootstrapRoute = defineRoute({\n method: 'POST',\n path: '/exchange',\n description: 'Exchange a one-use runner bootstrap token for a workspace-neutral control session',\n schema: {\n body: runnerBootstrapExchangeBodySchema,\n response: {200: runnerBootstrapExchangeResponseSchema},\n },\n errorHandler: (error) => {\n if (error instanceof RunnerBootstrapTokenInvalidError)\n runnerBootstrapExchangeCount.add(1, {outcome: 'rejected'});\n if (error instanceof RunnerBootstrapTokenInvalidError)\n throw new ClientError(error.message, 'runner-bootstrap-token-invalid', {status: 401});\n throw error;\n },\n handler: async (request) => {\n const result = await exchangeRunnerBootstrapToken({\n rawToken: request.body.bootstrap_token,\n ttlSeconds: config.RUNNER_CONTROL_SESSION_TTL_SECONDS,\n });\n runnerBootstrapExchangeCount.add(1, {outcome: 'accepted'});\n return {\n runner_instance_id: result.runnerInstanceId,\n control_session_token: result.controlSessionToken,\n expires_at: result.expiresAt.toISOString(),\n };\n },\n});\n\nexport const enrollRunnerRoute = defineRoute({\n method: 'POST',\n path: '/enrollment',\n description: 'Declare the authenticated runner instance labels and protocol capabilities',\n schema: {body: runnerEnrollmentBodySchema, response: {204: z.null()}},\n preHandler: authenticateRunnerControlSession,\n errorHandler: (error) => {\n if (error instanceof RunnerControlSessionInvalidError)\n throw new ClientError(error.message, 'runner-control-session-invalid', {status: 409});\n throw error;\n },\n handler: async (request, reply) => {\n const session = requireRunnerControlSessionContext(request);\n await enrollRunnerControlSession({\n runnerInstanceId: session.runnerInstanceId,\n provisionerId: session.provisionerId,\n labels: request.body.labels,\n ...(request.body.capabilities ? {capabilities: request.body.capabilities} : {}),\n providerKind: request.body.provider_kind,\n protocolVersion: request.body.protocol_version,\n });\n return await reply.code(204).send();\n },\n});\n\nexport const attachRunnerControlProviderIdRoute = defineRoute({\n method: 'POST',\n path: '/provider-runner',\n description: 'Attach the authenticated runner instance provider identity once',\n schema: {\n body: attachRunnerControlProviderIdBodySchema,\n response: {200: z.object({attached: z.boolean()})},\n },\n preHandler: authenticateRunnerControlSession,\n handler: async (request) => {\n const session = requireRunnerControlSessionContext(request);\n return {\n attached: await attachRunnerControlProviderId({\n ...session,\n providerRunnerId: request.body.provider_runner_id,\n }),\n };\n },\n});\n\nexport const runnerControlHeartbeatRoute = defineRoute({\n method: 'POST',\n path: '/heartbeat',\n description: 'Record liveness for only the authenticated runner instance',\n schema: {response: {200: runnerControlHeartbeatResponseSchema}},\n preHandler: authenticateRunnerControlSession,\n handler: async (request) => {\n const session = requireRunnerControlSessionContext(request);\n await touchRunnerControlSession(session.runnerInstanceId, session.provisionerId);\n runnerControlHeartbeatCount.add(1);\n return {ok: true};\n },\n});\n\nexport const runnerAssignmentPollRoute = defineRoute({\n method: 'GET',\n path: '/assignment',\n description: 'Wait for only the authenticated runner instance assignment',\n schema: {response: {200: runnerAssignmentPollResponseSchema}},\n preHandler: authenticateRunnerControlSession,\n handler: async (request, reply) => {\n const session = requireRunnerControlSessionContext(request);\n const deadline = Date.now() + config.RUNNER_ASSIGNMENT_POLL_MAX_WAIT_SECONDS * 1000;\n const abortController = new AbortController();\n reply.raw.on('close', () => abortController.abort());\n while (Date.now() <= deadline) {\n if (abortController.signal.aborted) return {activation_token: null};\n const assignment = await getRunnerAssignment(session);\n if (assignment) {\n const activationToken = await issueRunnerActivationToken({\n ...session,\n ttlSeconds: config.RUNNER_ACTIVATION_TOKEN_TTL_SECONDS,\n });\n return {activation_token: activationToken};\n }\n await new Promise((resolve) =>\n setTimeout(resolve, config.RUNNER_ASSIGNMENT_POLL_INTERVAL_MS),\n );\n }\n return {activation_token: null};\n },\n});\n"],"names":["requireProvisionerContext","requireRunnerControlSessionContext","attachRunnerControlProviderIdBodySchema","createRunnerInstancesBodySchema","createRunnerInstancesResponseSchema","runnerAssignmentPollResponseSchema","runnerBootstrapExchangeBodySchema","runnerBootstrapExchangeResponseSchema","runnerControlHeartbeatResponseSchema","runnerEnrollmentBodySchema","ClientError","defineRoute","z","config","getRunnerAssignment","issueRunnerActivationToken","attachRunnerControlProviderId","createRunnerInstancesWithBootstrapTokens","enrollRunnerControlSession","exchangeRunnerBootstrapToken","RunnerBootstrapTokenInvalidError","RunnerControlSessionInvalidError","touchRunnerControlSession","attachRunnerInstanceProviderId","runnerBootstrapExchangeCount","runnerControlHeartbeatCount","authenticateRunnerControlSession","createRunnerInstancesRoute","method","path","description","schema","body","response","handler","request","provisionerTokenId","results","provisionerId","provider_kind","providerKind","runnerInstances","runner_instances","map","runner","template_key","templateKey","ttlSeconds","RUNNER_BOOTSTRAP_TOKEN_TTL_SECONDS","result","runner_instance_id","runnerInstanceId","bootstrap_token","bootstrapToken","attachRunnerInstanceProviderIdRoute","params","object","string","uuid","attached","boolean","providerRunnerId","provider_runner_id","exchangeRunnerBootstrapRoute","errorHandler","error","add","outcome","message","status","rawToken","RUNNER_CONTROL_SESSION_TTL_SECONDS","control_session_token","controlSessionToken","expires_at","expiresAt","toISOString","enrollRunnerRoute","null","preHandler","reply","session","labels","capabilities","protocolVersion","protocol_version","code","send","attachRunnerControlProviderIdRoute","runnerControlHeartbeatRoute","ok","runnerAssignmentPollRoute","deadline","Date","now","RUNNER_ASSIGNMENT_POLL_MAX_WAIT_SECONDS","abortController","AbortController","raw","on","abort","signal","aborted","activation_token","assignment","activationToken","RUNNER_ACTIVATION_TOKEN_TTL_SECONDS","Promise","resolve","setTimeout","RUNNER_ASSIGNMENT_POLL_INTERVAL_MS"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/routes/runner-enrollment.ts"],"sourcesContent":["import {\n requireProvisionerContext,\n requireRunnerControlSessionContext,\n} from '@shipfox/api-auth-context';\nimport {\n attachRunnerControlProviderIdBodySchema,\n createRunnerInstancesBodySchema,\n createRunnerInstancesResponseSchema,\n runnerAssignmentPollResponseSchema,\n runnerBootstrapExchangeBodySchema,\n runnerBootstrapExchangeResponseSchema,\n runnerControlHeartbeatResponseSchema,\n runnerEnrollmentBodySchema,\n runnerEnrollmentResponseSchema,\n} from '@shipfox/api-runners-dto';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {z} from 'zod';\nimport {config} from '#config.js';\nimport {getRunnerAssignment, issueRunnerActivationToken} from '#core/runner-activation.js';\nimport {\n attachRunnerControlProviderId,\n createRunnerInstancesWithBootstrapTokens,\n enrollRunnerControlSession,\n exchangeRunnerBootstrapToken,\n RunnerBootstrapTokenInvalidError,\n RunnerControlSessionInvalidError,\n touchRunnerControlSession,\n} from '#core/runner-control-sessions.js';\nimport {attachRunnerInstanceProviderId} from '#core/runner-instances.js';\nimport {runnerBootstrapExchangeCount, runnerControlHeartbeatCount} from '#metrics/instance.js';\nimport {authenticateRunnerControlSession} from '#presentation/auth/index.js';\n\nexport const createRunnerInstancesRoute = defineRoute({\n method: 'POST',\n path: '/runner-instances/batch',\n description:\n 'Create provisioner-owned runner instances and one-use bootstrap tokens before launch',\n schema: {\n body: createRunnerInstancesBodySchema,\n response: {200: createRunnerInstancesResponseSchema},\n },\n handler: async (request) => {\n const {provisionerTokenId} = requireProvisionerContext(request);\n const results = await createRunnerInstancesWithBootstrapTokens({\n provisionerId: provisionerTokenId,\n ...(request.body.provider_kind ? {providerKind: request.body.provider_kind} : {}),\n runnerInstances: request.body.runner_instances.map((runner) => ({\n ...(runner.template_key ? {templateKey: runner.template_key} : {}),\n ...(runner.reservation_id ? {reservationId: runner.reservation_id} : {}),\n })),\n ttlSeconds: config.RUNNER_BOOTSTRAP_TOKEN_TTL_SECONDS,\n });\n return {\n runner_instances: results.map((result) => ({\n runner_instance_id: result.runnerInstanceId,\n bootstrap_token: result.bootstrapToken,\n })),\n };\n },\n});\n\nexport const attachRunnerInstanceProviderIdRoute = defineRoute({\n method: 'POST',\n path: '/runner-instances/:runnerInstanceId/provider-runner',\n description: 'Attach the provider identity after the provisioner launches a runner instance',\n schema: {\n params: z.object({runnerInstanceId: z.string().uuid()}),\n body: attachRunnerControlProviderIdBodySchema,\n response: {200: z.object({attached: z.boolean()})},\n },\n handler: async (request) => {\n const {provisionerTokenId} = requireProvisionerContext(request);\n return {\n attached: await attachRunnerInstanceProviderId({\n runnerInstanceId: request.params.runnerInstanceId,\n provisionerId: provisionerTokenId,\n providerRunnerId: request.body.provider_runner_id,\n }),\n };\n },\n});\n\nexport const exchangeRunnerBootstrapRoute = defineRoute({\n method: 'POST',\n path: '/exchange',\n description: 'Exchange a one-use runner bootstrap token for a workspace-neutral control session',\n schema: {\n body: runnerBootstrapExchangeBodySchema,\n response: {200: runnerBootstrapExchangeResponseSchema},\n },\n errorHandler: (error) => {\n if (error instanceof RunnerBootstrapTokenInvalidError)\n runnerBootstrapExchangeCount.add(1, {outcome: 'rejected'});\n if (error instanceof RunnerBootstrapTokenInvalidError)\n throw new ClientError(error.message, 'runner-bootstrap-token-invalid', {status: 401});\n throw error;\n },\n handler: async (request) => {\n const result = await exchangeRunnerBootstrapToken({\n rawToken: request.body.bootstrap_token,\n ttlSeconds: config.RUNNER_CONTROL_SESSION_TTL_SECONDS,\n });\n runnerBootstrapExchangeCount.add(1, {outcome: 'accepted'});\n return {\n runner_instance_id: result.runnerInstanceId,\n control_session_token: result.controlSessionToken,\n expires_at: result.expiresAt.toISOString(),\n };\n },\n});\n\nexport const enrollRunnerRoute = defineRoute({\n method: 'POST',\n path: '/enrollment',\n description: 'Declare the authenticated runner instance labels and protocol capabilities',\n schema: {body: runnerEnrollmentBodySchema, response: {200: runnerEnrollmentResponseSchema}},\n preHandler: authenticateRunnerControlSession,\n errorHandler: (error) => {\n if (error instanceof RunnerControlSessionInvalidError)\n throw new ClientError(error.message, 'runner-control-session-invalid', {status: 409});\n throw error;\n },\n handler: async (request) => {\n const session = requireRunnerControlSessionContext(request);\n const activationToken = await enrollRunnerControlSession({\n runnerInstanceId: session.runnerInstanceId,\n provisionerId: session.provisionerId,\n labels: request.body.labels,\n ...(request.body.capabilities ? {capabilities: request.body.capabilities} : {}),\n providerKind: request.body.provider_kind,\n protocolVersion: request.body.protocol_version,\n });\n return {activation_token: activationToken};\n },\n});\n\nexport const attachRunnerControlProviderIdRoute = defineRoute({\n method: 'POST',\n path: '/provider-runner',\n description: 'Attach the authenticated runner instance provider identity once',\n schema: {\n body: attachRunnerControlProviderIdBodySchema,\n response: {200: z.object({attached: z.boolean()})},\n },\n preHandler: authenticateRunnerControlSession,\n handler: async (request) => {\n const session = requireRunnerControlSessionContext(request);\n return {\n attached: await attachRunnerControlProviderId({\n ...session,\n providerRunnerId: request.body.provider_runner_id,\n }),\n };\n },\n});\n\nexport const runnerControlHeartbeatRoute = defineRoute({\n method: 'POST',\n path: '/heartbeat',\n description: 'Record liveness for only the authenticated runner instance',\n schema: {response: {200: runnerControlHeartbeatResponseSchema}},\n preHandler: authenticateRunnerControlSession,\n handler: async (request) => {\n const session = requireRunnerControlSessionContext(request);\n await touchRunnerControlSession(session.runnerInstanceId, session.provisionerId);\n runnerControlHeartbeatCount.add(1);\n return {ok: true};\n },\n});\n\ntype RunnerAssignmentPollParams = {\n deadline: number;\n intervalMs: number;\n signal: AbortSignal;\n getAssignment: () => Promise<unknown | null>;\n issueActivationToken: () => Promise<string | null>;\n};\nexport async function pollForRunnerActivationToken(\n params: RunnerAssignmentPollParams,\n): Promise<string | null> {\n while (Date.now() <= params.deadline) {\n if (params.signal.aborted) return null;\n const assignment = await params.getAssignment();\n if (assignment) {\n const activationToken = await params.issueActivationToken();\n if (activationToken) return activationToken;\n }\n await new Promise((resolve) => setTimeout(resolve, params.intervalMs));\n }\n return null;\n}\nexport const runnerAssignmentPollRoute = defineRoute({\n method: 'GET',\n path: '/assignment',\n description: 'Wait for only the authenticated runner instance assignment',\n schema: {response: {200: runnerAssignmentPollResponseSchema}},\n preHandler: authenticateRunnerControlSession,\n handler: async (request, reply) => {\n const session = requireRunnerControlSessionContext(request);\n const deadline = Date.now() + config.RUNNER_ASSIGNMENT_POLL_MAX_WAIT_SECONDS * 1000;\n const abortController = new AbortController();\n reply.raw.on('close', () => abortController.abort());\n const activationToken = await pollForRunnerActivationToken({\n deadline,\n intervalMs: config.RUNNER_ASSIGNMENT_POLL_INTERVAL_MS,\n signal: abortController.signal,\n getAssignment: () => getRunnerAssignment(session),\n issueActivationToken: () =>\n issueRunnerActivationToken({\n ...session,\n ttlSeconds: config.RUNNER_ACTIVATION_TOKEN_TTL_SECONDS,\n }),\n });\n return {activation_token: activationToken};\n },\n});\n"],"names":["requireProvisionerContext","requireRunnerControlSessionContext","attachRunnerControlProviderIdBodySchema","createRunnerInstancesBodySchema","createRunnerInstancesResponseSchema","runnerAssignmentPollResponseSchema","runnerBootstrapExchangeBodySchema","runnerBootstrapExchangeResponseSchema","runnerControlHeartbeatResponseSchema","runnerEnrollmentBodySchema","runnerEnrollmentResponseSchema","ClientError","defineRoute","z","config","getRunnerAssignment","issueRunnerActivationToken","attachRunnerControlProviderId","createRunnerInstancesWithBootstrapTokens","enrollRunnerControlSession","exchangeRunnerBootstrapToken","RunnerBootstrapTokenInvalidError","RunnerControlSessionInvalidError","touchRunnerControlSession","attachRunnerInstanceProviderId","runnerBootstrapExchangeCount","runnerControlHeartbeatCount","authenticateRunnerControlSession","createRunnerInstancesRoute","method","path","description","schema","body","response","handler","request","provisionerTokenId","results","provisionerId","provider_kind","providerKind","runnerInstances","runner_instances","map","runner","template_key","templateKey","reservation_id","reservationId","ttlSeconds","RUNNER_BOOTSTRAP_TOKEN_TTL_SECONDS","result","runner_instance_id","runnerInstanceId","bootstrap_token","bootstrapToken","attachRunnerInstanceProviderIdRoute","params","object","string","uuid","attached","boolean","providerRunnerId","provider_runner_id","exchangeRunnerBootstrapRoute","errorHandler","error","add","outcome","message","status","rawToken","RUNNER_CONTROL_SESSION_TTL_SECONDS","control_session_token","controlSessionToken","expires_at","expiresAt","toISOString","enrollRunnerRoute","preHandler","session","activationToken","labels","capabilities","protocolVersion","protocol_version","activation_token","attachRunnerControlProviderIdRoute","runnerControlHeartbeatRoute","ok","pollForRunnerActivationToken","Date","now","deadline","signal","aborted","assignment","getAssignment","issueActivationToken","Promise","resolve","setTimeout","intervalMs","runnerAssignmentPollRoute","reply","RUNNER_ASSIGNMENT_POLL_MAX_WAIT_SECONDS","abortController","AbortController","raw","on","abort","RUNNER_ASSIGNMENT_POLL_INTERVAL_MS","RUNNER_ACTIVATION_TOKEN_TTL_SECONDS"],"mappings":"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"}
|