@shipfox/api-runners 9.2.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 +53 -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 +12 -12
- 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
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
$ shipfox-swc && shipfox-temporal-bundle dist/temporal/workflows/index.js
|
|
2
|
-
Successfully compiled: 94 files with swc (
|
|
3
|
-
2026-07-
|
|
2
|
+
Successfully compiled: 94 files with swc (596.37ms)
|
|
3
|
+
2026-07-28T07:35:34.740Z [INFO] asset workflow-bundle-0c3da2487e29e352d64e.js 3.17 MiB [emitted] [immutable] (name: main)
|
|
4
4
|
orphan modules 33.5 KiB [orphan] 21 modules
|
|
5
5
|
runtime modules 1.13 KiB 5 modules
|
|
6
6
|
modules by path ../../../node_modules/.pnpm/ 970 KiB 196 modules
|
|
@@ -14,6 +14,6 @@ optional modules 30 bytes [optional]
|
|
|
14
14
|
__temporal_custom_payload_converter (ignored) 15 bytes [optional] [built] [code generated]
|
|
15
15
|
__temporal_custom_failure_converter (ignored) 15 bytes [optional] [built] [code generated]
|
|
16
16
|
../../shared/node/temporal/dist/workflow-error-interceptor.js 1.21 KiB [built] [code generated]
|
|
17
|
-
webpack 5.107.2 compiled successfully in
|
|
18
|
-
2026-07-
|
|
17
|
+
webpack 5.107.2 compiled successfully in 6590 ms
|
|
18
|
+
2026-07-28T07:35:34.755Z [INFO] Workflow bundle created { size: '3.17MB' }
|
|
19
19
|
/home/runner/work/shipfox/shipfox/libs/api/runners/dist/temporal/workflows/index.js: 3326598 bytes
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
# @shipfox/api-runners
|
|
2
2
|
|
|
3
|
+
## 10.0.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- e9280fc: Add an observer-authorized administrator workspace lookup with bounded safe summaries,
|
|
8
|
+
best-effort job counts, and a neutral unavailable-workspace member experience for
|
|
9
|
+
suspended or deleted workspaces.
|
|
10
|
+
- 837bf5d: Stores runner reservation intent and promotes it during enrollment for lower activation latency.
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- a48ad8c: Allows provisioner assignment retries after reservation cleanup.
|
|
15
|
+
- 2402bdb: Keep runner assignment polls open through transient activation-token races.
|
|
16
|
+
- Updated dependencies [6054364]
|
|
17
|
+
- Updated dependencies [74f9e31]
|
|
18
|
+
- Updated dependencies [22bf8a2]
|
|
19
|
+
- Updated dependencies [e9280fc]
|
|
20
|
+
- Updated dependencies [837bf5d]
|
|
21
|
+
- Updated dependencies [3f5610b]
|
|
22
|
+
- @shipfox/api-auth-dto@10.0.0
|
|
23
|
+
- @shipfox/node-fastify@0.4.0
|
|
24
|
+
- @shipfox/api-workflows-dto@10.0.0
|
|
25
|
+
- @shipfox/api-runners-dto@10.0.0
|
|
26
|
+
- @shipfox/api-auth-context@10.0.0
|
|
27
|
+
- @shipfox/node-module@1.0.4
|
|
28
|
+
- @shipfox/config@1.2.4
|
|
29
|
+
- @shipfox/inter-module@0.2.2
|
|
30
|
+
- @shipfox/runner-labels@0.1.3
|
|
31
|
+
- @shipfox/node-auth-root-key@0.2.3
|
|
32
|
+
- @shipfox/node-drizzle@0.3.4
|
|
33
|
+
- @shipfox/node-error-monitoring@0.3.0
|
|
34
|
+
- @shipfox/node-opentelemetry@0.6.3
|
|
35
|
+
- @shipfox/node-outbox@0.2.6
|
|
36
|
+
- @shipfox/node-postgres@0.4.4
|
|
37
|
+
- @shipfox/node-rate-limit@0.3.2
|
|
38
|
+
- @shipfox/node-temporal@0.4.4
|
|
39
|
+
- @shipfox/node-tokens@0.3.2
|
|
40
|
+
|
|
41
|
+
## 9.3.0
|
|
42
|
+
|
|
43
|
+
### Patch Changes
|
|
44
|
+
|
|
45
|
+
- Updated dependencies [10cf63c]
|
|
46
|
+
- Updated dependencies [4425c6d]
|
|
47
|
+
- Updated dependencies [6017e56]
|
|
48
|
+
- @shipfox/api-auth-dto@9.3.0
|
|
49
|
+
- @shipfox/node-opentelemetry@0.6.3
|
|
50
|
+
- @shipfox/api-workflows-dto@9.3.0
|
|
51
|
+
- @shipfox/api-auth-context@9.3.0
|
|
52
|
+
- @shipfox/node-fastify@0.3.4
|
|
53
|
+
- @shipfox/node-module@1.0.3
|
|
54
|
+
- @shipfox/node-temporal@0.4.4
|
|
55
|
+
|
|
3
56
|
## 9.2.0
|
|
4
57
|
|
|
5
58
|
### Patch Changes
|
package/dist/config.js
CHANGED
|
@@ -22,7 +22,7 @@ export const config = createConfig({
|
|
|
22
22
|
}),
|
|
23
23
|
RUNNER_ASSIGNMENT_POLL_INTERVAL_MS: num({
|
|
24
24
|
desc: 'Delay between durable assignment reads while a runner-control session waits for an assignment, in milliseconds.',
|
|
25
|
-
default:
|
|
25
|
+
default: 250
|
|
26
26
|
}),
|
|
27
27
|
EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS: num({
|
|
28
28
|
desc: `Lifetime of a provisioner-minted runner registration token, in seconds. The token can be exchanged once by a runner before this time passes. Set this between 1 and ${EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS}.`,
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts"],"sourcesContent":["import {bool, createConfig, num} from '@shipfox/config';\nimport {STUCK_JOB_THRESHOLD_SECONDS} from '#core/maintenance-policy.js';\n\nconst EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS = 3600;\nconst REGISTRATION_TOKEN_BATCH_HARD_MAX = 1000;\nconst RUNNER_CONTROL_PLANE_TOKEN_TTL_HARD_MAX_SECONDS = 3600;\n\nexport const config = createConfig({\n RUNNER_BOOTSTRAP_TOKEN_TTL_SECONDS: num({\n desc: 'Lifetime of a one-use runner bootstrap token in seconds. The token can only create one runner-control session before it expires.',\n default: 300,\n }),\n RUNNER_CONTROL_SESSION_TTL_SECONDS: num({\n desc: 'Lifetime of a pre-workspace runner-control session in seconds. This session can only enroll, attach its provider identity, and report its own liveness.',\n default: 3600,\n }),\n RUNNER_ACTIVATION_TOKEN_TTL_SECONDS: num({\n desc: 'Lifetime of a one-use activation token in seconds. The token is issued only to an assigned runner-control session and creates one workspace runner session.',\n default: 300,\n }),\n RUNNER_ASSIGNMENT_POLL_MAX_WAIT_SECONDS: num({\n desc: 'Maximum time the runner assignment poll waits before returning no assignment, in seconds.',\n default: 30,\n }),\n RUNNER_ASSIGNMENT_POLL_INTERVAL_MS: num({\n desc: 'Delay between durable assignment reads while a runner-control session waits for an assignment, in milliseconds.',\n default: 1000,\n }),\n EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS: num({\n desc: `Lifetime of a provisioner-minted runner registration token, in seconds. The token can be exchanged once by a runner before this time passes. Set this between 1 and ${EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS}.`,\n default: 300,\n }),\n REGISTRATION_TOKEN_BATCH_MAX: num({\n desc: `Maximum number of runner registration tokens a provisioner can mint in one batch request. Set this between 1 and ${REGISTRATION_TOKEN_BATCH_HARD_MAX}.`,\n default: 500,\n }),\n PROVISIONER_MINT_RATE_LIMIT_MAX_REQUESTS: num({\n desc: 'Maximum number of batch runner registration token mint requests one provisioner can make per rate-limit window.',\n default: 120,\n }),\n PROVISIONER_MINT_RATE_LIMIT_WINDOW_SECONDS: num({\n desc: 'Rate-limit window for provisioner batch runner registration token mint requests, in seconds.',\n default: 60,\n }),\n EPHEMERAL_REGISTER_RATE_LIMIT_MAX_REQUESTS: num({\n desc: 'Maximum number of runner registration attempts one ephemeral registration token can make per rate-limit window.',\n default: 5,\n }),\n EPHEMERAL_REGISTER_RATE_LIMIT_WINDOW_SECONDS: num({\n desc: 'Rate-limit window for runner registration attempts with one ephemeral registration token, in seconds.',\n default: 60,\n }),\n RUNNERS_RATE_LIMIT_TIMEOUT_MS: num({\n desc: 'Maximum time, in milliseconds, a runners rate-limit storage check may wait before the request fails closed.',\n default: 250,\n }),\n RESERVATION_TTL_SECONDS: num({\n desc: 'Lifetime of a count-based runner reservation, in seconds. Expired reservations stop counting against queued demand.',\n default: 60,\n }),\n RESERVATION_LONG_POLL_MAX_WAIT_SECONDS: num({\n desc: 'Maximum time the provisioner demand poll endpoint waits for reservable demand before returning, in seconds.',\n default: 30,\n }),\n RESERVATION_POLL_INTERVAL_MS: num({\n desc: 'Initial interval between demand re-checks while a provisioner request is waiting, in milliseconds.',\n default: 1000,\n }),\n RESERVATION_POLL_MAX_INTERVAL_MS: num({\n desc: 'Maximum backoff interval between demand re-checks while a provisioner request is waiting, in milliseconds.',\n default: 5000,\n }),\n RUNNER_ACTIVE_WINDOW_SECONDS: num({\n desc: 'Time window, in seconds, used to list active runners from recent heartbeats and provisioned runner reports.',\n default: 60,\n }),\n RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS: num({\n desc: 'Time window, in seconds, after which a runner tool capability report is treated as stale. Set this higher than the runner heartbeat interval so active runners keep their advertised tools fresh.',\n default: 60,\n }),\n RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS: num({\n desc: 'Grace window, in seconds, before maintenance expires a claimed job that has not sent its first heartbeat. Set this lower than the normal stuck-job threshold so startup crashes release work quickly.',\n default: 60,\n }),\n RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS: num({\n desc: 'Grace window, in seconds, before reconcile marks an absent provisioned runner as terminated. Set this higher than the provisioner report interval so a transient empty or partial observed set does not kill a live runner.',\n default: 120,\n }),\n RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS: num({\n desc: 'Time, in seconds, after which a provisioned runner with no recent report, no live provisioner, no live runner session, and no running job is marked failed by backend maintenance.',\n default: 300,\n }),\n RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT: num({\n desc: 'Maximum number of stale provisioned runners the maintenance worker marks failed in one run. Higher values clear backlogs faster but hold database locks longer.',\n default: 100,\n }),\n RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS: num({\n desc: 'Minimum time, in seconds, between runner session liveness writes from job request polls. Set this lower than RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS so active idle runners stay fresh.',\n default: 10,\n }),\n RUNNER_SESSION_MANUAL_RETENTION_DAYS: num({\n desc: 'How long manual runner sessions are retained before maintenance deletes them, in days. Set this longer than AUTH_RUNNER_SESSION_TOKEN_EXPIRES_IN so a valid session token never outlives its row.',\n default: 30,\n }),\n RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS: num({\n desc: 'How long ephemeral runner sessions are retained before maintenance deletes them, in days. Set this longer than AUTH_RUNNER_SESSION_TOKEN_EXPIRES_IN so a valid session token never outlives its row.',\n default: 7,\n }),\n RUNNER_SESSION_GC_BATCH_SIZE: num({\n desc: 'Maximum number of expired runner sessions maintenance deletes in one pass.',\n default: 1000,\n }),\n RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS: num({\n desc: 'How long consumed or expired ephemeral registration tokens are retained for audit and debugging before maintenance deletes them, in days. Active tokens that are neither consumed nor expired are never deleted. This window is independent of the runner-session retention windows.',\n default: 7,\n }),\n RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE: num({\n desc: 'Maximum number of consumed or expired ephemeral registration tokens maintenance deletes in one pass.',\n default: 1000,\n }),\n PROVISIONER_ACTIVE_WINDOW_SECONDS: num({\n desc: 'Time window, in seconds, used to list active provisioners from recent authenticated requests.',\n default: 120,\n }),\n PROVISIONER_LAST_SEEN_THROTTLE_SECONDS: num({\n desc: 'Minimum time, in seconds, between last-seen writes for one provisioner token.',\n default: 10,\n }),\n PROVISIONED_RUNNER_COUNT_DIVERGENCE_TEMPLATE_KEY_LABEL_ENABLED: bool({\n desc: 'Whether runners_provider_runner_count_divergence includes template_key as a metric label. Use true or false. Defaults to false because template keys can create high-cardinality metric series. Set true only when template keys are bounded and stable.',\n default: false,\n }),\n});\n\nif (\n !Number.isInteger(config.EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS) ||\n config.EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS < 1 ||\n config.EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS >\n EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS\n) {\n throw new Error(\n `EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS (${config.EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS}) must be a whole number of seconds between 1 and ${EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS}.`,\n );\n}\n\nfor (const [name, value] of [\n ['RUNNER_BOOTSTRAP_TOKEN_TTL_SECONDS', config.RUNNER_BOOTSTRAP_TOKEN_TTL_SECONDS],\n ['RUNNER_CONTROL_SESSION_TTL_SECONDS', config.RUNNER_CONTROL_SESSION_TTL_SECONDS],\n ['RUNNER_ACTIVATION_TOKEN_TTL_SECONDS', config.RUNNER_ACTIVATION_TOKEN_TTL_SECONDS],\n] as const) {\n if (\n !Number.isInteger(value) ||\n value < 1 ||\n value > RUNNER_CONTROL_PLANE_TOKEN_TTL_HARD_MAX_SECONDS\n ) {\n throw new Error(\n `${name} (${value}) must be a whole number of seconds between 1 and ${RUNNER_CONTROL_PLANE_TOKEN_TTL_HARD_MAX_SECONDS}.`,\n );\n }\n}\n\nfor (const [name, value] of [\n ['RUNNER_ASSIGNMENT_POLL_MAX_WAIT_SECONDS', config.RUNNER_ASSIGNMENT_POLL_MAX_WAIT_SECONDS],\n ['RUNNER_ASSIGNMENT_POLL_INTERVAL_MS', config.RUNNER_ASSIGNMENT_POLL_INTERVAL_MS],\n] as const) {\n if (!Number.isInteger(value) || value < 0)\n throw new Error(`${name} (${value}) must be a whole number >= 0.`);\n}\n\nif (\n !Number.isInteger(config.REGISTRATION_TOKEN_BATCH_MAX) ||\n config.REGISTRATION_TOKEN_BATCH_MAX < 1 ||\n config.REGISTRATION_TOKEN_BATCH_MAX > REGISTRATION_TOKEN_BATCH_HARD_MAX\n) {\n throw new Error(\n `REGISTRATION_TOKEN_BATCH_MAX (${config.REGISTRATION_TOKEN_BATCH_MAX}) must be a whole number between 1 and ${REGISTRATION_TOKEN_BATCH_HARD_MAX}.`,\n );\n}\n\nfor (const [name, value] of [\n ['PROVISIONER_MINT_RATE_LIMIT_MAX_REQUESTS', config.PROVISIONER_MINT_RATE_LIMIT_MAX_REQUESTS],\n ['PROVISIONER_MINT_RATE_LIMIT_WINDOW_SECONDS', config.PROVISIONER_MINT_RATE_LIMIT_WINDOW_SECONDS],\n ['EPHEMERAL_REGISTER_RATE_LIMIT_MAX_REQUESTS', config.EPHEMERAL_REGISTER_RATE_LIMIT_MAX_REQUESTS],\n [\n 'EPHEMERAL_REGISTER_RATE_LIMIT_WINDOW_SECONDS',\n config.EPHEMERAL_REGISTER_RATE_LIMIT_WINDOW_SECONDS,\n ],\n ['RUNNERS_RATE_LIMIT_TIMEOUT_MS', config.RUNNERS_RATE_LIMIT_TIMEOUT_MS],\n] as const) {\n if (!Number.isInteger(value) || value < 1) {\n throw new Error(`${name} (${value}) must be a whole number >= 1.`);\n }\n}\n\nif (!Number.isInteger(config.RESERVATION_TTL_SECONDS) || config.RESERVATION_TTL_SECONDS < 1) {\n throw new Error(\n `RESERVATION_TTL_SECONDS (${config.RESERVATION_TTL_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RESERVATION_LONG_POLL_MAX_WAIT_SECONDS) ||\n config.RESERVATION_LONG_POLL_MAX_WAIT_SECONDS < 0\n) {\n throw new Error(\n `RESERVATION_LONG_POLL_MAX_WAIT_SECONDS (${config.RESERVATION_LONG_POLL_MAX_WAIT_SECONDS}) must be a whole number of seconds >= 0.`,\n );\n}\n\nif (\n !Number.isInteger(config.RESERVATION_POLL_INTERVAL_MS) ||\n config.RESERVATION_POLL_INTERVAL_MS < 1\n) {\n throw new Error(\n `RESERVATION_POLL_INTERVAL_MS (${config.RESERVATION_POLL_INTERVAL_MS}) must be a whole number of milliseconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RESERVATION_POLL_MAX_INTERVAL_MS) ||\n config.RESERVATION_POLL_MAX_INTERVAL_MS < config.RESERVATION_POLL_INTERVAL_MS\n) {\n throw new Error(\n `RESERVATION_POLL_MAX_INTERVAL_MS (${config.RESERVATION_POLL_MAX_INTERVAL_MS}) must be a whole number of milliseconds >= RESERVATION_POLL_INTERVAL_MS (${config.RESERVATION_POLL_INTERVAL_MS}).`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_ACTIVE_WINDOW_SECONDS) ||\n config.RUNNER_ACTIVE_WINDOW_SECONDS < 1\n) {\n throw new Error(\n `RUNNER_ACTIVE_WINDOW_SECONDS (${config.RUNNER_ACTIVE_WINDOW_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS) ||\n config.RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS < 1\n) {\n throw new Error(\n `RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS (${config.RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS) ||\n config.RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS < 1 ||\n config.RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS >= STUCK_JOB_THRESHOLD_SECONDS\n) {\n throw new Error(\n `RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS (${config.RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS}) must be a whole number of seconds >= 1 and < ${STUCK_JOB_THRESHOLD_SECONDS}.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS) ||\n config.RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS < 1\n) {\n throw new Error(\n `RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS (${config.RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS) ||\n config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS < 1\n) {\n throw new Error(\n `RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS (${config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT) ||\n config.RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT < 1\n) {\n throw new Error(\n `RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT (${config.RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT}) must be a whole number >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS) ||\n config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS < 1\n) {\n throw new Error(\n `RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS (${config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_SESSION_MANUAL_RETENTION_DAYS) ||\n config.RUNNER_SESSION_MANUAL_RETENTION_DAYS < 1\n) {\n throw new Error(\n `RUNNER_SESSION_MANUAL_RETENTION_DAYS (${config.RUNNER_SESSION_MANUAL_RETENTION_DAYS}) must be a whole number of days >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS) ||\n config.RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS < 1\n) {\n throw new Error(\n `RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS (${config.RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS}) must be a whole number of days >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_SESSION_GC_BATCH_SIZE) ||\n config.RUNNER_SESSION_GC_BATCH_SIZE < 1\n) {\n throw new Error(\n `RUNNER_SESSION_GC_BATCH_SIZE (${config.RUNNER_SESSION_GC_BATCH_SIZE}) must be a whole number >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS) ||\n config.RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS < 1\n) {\n throw new Error(\n `RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS (${config.RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS}) must be a whole number of days >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE) ||\n config.RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE < 1\n) {\n throw new Error(\n `RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE (${config.RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE}) must be a whole number >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.PROVISIONER_ACTIVE_WINDOW_SECONDS) ||\n config.PROVISIONER_ACTIVE_WINDOW_SECONDS < 1\n) {\n throw new Error(\n `PROVISIONER_ACTIVE_WINDOW_SECONDS (${config.PROVISIONER_ACTIVE_WINDOW_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS) ||\n config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS < 1\n) {\n throw new Error(\n `PROVISIONER_LAST_SEEN_THROTTLE_SECONDS (${config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS <=\n config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS\n) {\n throw new Error(\n `RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS (${config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS}) must be greater than PROVISIONER_LAST_SEEN_THROTTLE_SECONDS (${config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS}).`,\n );\n}\n\nif (\n config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS <=\n config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS\n) {\n throw new Error(\n `RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS (${config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS}) must be greater than RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS (${config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS}).`,\n );\n}\n"],"names":["bool","createConfig","num","STUCK_JOB_THRESHOLD_SECONDS","EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS","REGISTRATION_TOKEN_BATCH_HARD_MAX","RUNNER_CONTROL_PLANE_TOKEN_TTL_HARD_MAX_SECONDS","config","RUNNER_BOOTSTRAP_TOKEN_TTL_SECONDS","desc","default","RUNNER_CONTROL_SESSION_TTL_SECONDS","RUNNER_ACTIVATION_TOKEN_TTL_SECONDS","RUNNER_ASSIGNMENT_POLL_MAX_WAIT_SECONDS","RUNNER_ASSIGNMENT_POLL_INTERVAL_MS","EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS","REGISTRATION_TOKEN_BATCH_MAX","PROVISIONER_MINT_RATE_LIMIT_MAX_REQUESTS","PROVISIONER_MINT_RATE_LIMIT_WINDOW_SECONDS","EPHEMERAL_REGISTER_RATE_LIMIT_MAX_REQUESTS","EPHEMERAL_REGISTER_RATE_LIMIT_WINDOW_SECONDS","RUNNERS_RATE_LIMIT_TIMEOUT_MS","RESERVATION_TTL_SECONDS","RESERVATION_LONG_POLL_MAX_WAIT_SECONDS","RESERVATION_POLL_INTERVAL_MS","RESERVATION_POLL_MAX_INTERVAL_MS","RUNNER_ACTIVE_WINDOW_SECONDS","RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS","RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS","RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS","RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS","RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT","RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS","RUNNER_SESSION_MANUAL_RETENTION_DAYS","RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS","RUNNER_SESSION_GC_BATCH_SIZE","RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS","RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE","PROVISIONER_ACTIVE_WINDOW_SECONDS","PROVISIONER_LAST_SEEN_THROTTLE_SECONDS","PROVISIONED_RUNNER_COUNT_DIVERGENCE_TEMPLATE_KEY_LABEL_ENABLED","Number","isInteger","Error","name","value"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/config.ts"],"sourcesContent":["import {bool, createConfig, num} from '@shipfox/config';\nimport {STUCK_JOB_THRESHOLD_SECONDS} from '#core/maintenance-policy.js';\n\nconst EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS = 3600;\nconst REGISTRATION_TOKEN_BATCH_HARD_MAX = 1000;\nconst RUNNER_CONTROL_PLANE_TOKEN_TTL_HARD_MAX_SECONDS = 3600;\n\nexport const config = createConfig({\n RUNNER_BOOTSTRAP_TOKEN_TTL_SECONDS: num({\n desc: 'Lifetime of a one-use runner bootstrap token in seconds. The token can only create one runner-control session before it expires.',\n default: 300,\n }),\n RUNNER_CONTROL_SESSION_TTL_SECONDS: num({\n desc: 'Lifetime of a pre-workspace runner-control session in seconds. This session can only enroll, attach its provider identity, and report its own liveness.',\n default: 3600,\n }),\n RUNNER_ACTIVATION_TOKEN_TTL_SECONDS: num({\n desc: 'Lifetime of a one-use activation token in seconds. The token is issued only to an assigned runner-control session and creates one workspace runner session.',\n default: 300,\n }),\n RUNNER_ASSIGNMENT_POLL_MAX_WAIT_SECONDS: num({\n desc: 'Maximum time the runner assignment poll waits before returning no assignment, in seconds.',\n default: 30,\n }),\n RUNNER_ASSIGNMENT_POLL_INTERVAL_MS: num({\n desc: 'Delay between durable assignment reads while a runner-control session waits for an assignment, in milliseconds.',\n default: 250,\n }),\n EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS: num({\n desc: `Lifetime of a provisioner-minted runner registration token, in seconds. The token can be exchanged once by a runner before this time passes. Set this between 1 and ${EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS}.`,\n default: 300,\n }),\n REGISTRATION_TOKEN_BATCH_MAX: num({\n desc: `Maximum number of runner registration tokens a provisioner can mint in one batch request. Set this between 1 and ${REGISTRATION_TOKEN_BATCH_HARD_MAX}.`,\n default: 500,\n }),\n PROVISIONER_MINT_RATE_LIMIT_MAX_REQUESTS: num({\n desc: 'Maximum number of batch runner registration token mint requests one provisioner can make per rate-limit window.',\n default: 120,\n }),\n PROVISIONER_MINT_RATE_LIMIT_WINDOW_SECONDS: num({\n desc: 'Rate-limit window for provisioner batch runner registration token mint requests, in seconds.',\n default: 60,\n }),\n EPHEMERAL_REGISTER_RATE_LIMIT_MAX_REQUESTS: num({\n desc: 'Maximum number of runner registration attempts one ephemeral registration token can make per rate-limit window.',\n default: 5,\n }),\n EPHEMERAL_REGISTER_RATE_LIMIT_WINDOW_SECONDS: num({\n desc: 'Rate-limit window for runner registration attempts with one ephemeral registration token, in seconds.',\n default: 60,\n }),\n RUNNERS_RATE_LIMIT_TIMEOUT_MS: num({\n desc: 'Maximum time, in milliseconds, a runners rate-limit storage check may wait before the request fails closed.',\n default: 250,\n }),\n RESERVATION_TTL_SECONDS: num({\n desc: 'Lifetime of a count-based runner reservation, in seconds. Expired reservations stop counting against queued demand.',\n default: 60,\n }),\n RESERVATION_LONG_POLL_MAX_WAIT_SECONDS: num({\n desc: 'Maximum time the provisioner demand poll endpoint waits for reservable demand before returning, in seconds.',\n default: 30,\n }),\n RESERVATION_POLL_INTERVAL_MS: num({\n desc: 'Initial interval between demand re-checks while a provisioner request is waiting, in milliseconds.',\n default: 1000,\n }),\n RESERVATION_POLL_MAX_INTERVAL_MS: num({\n desc: 'Maximum backoff interval between demand re-checks while a provisioner request is waiting, in milliseconds.',\n default: 5000,\n }),\n RUNNER_ACTIVE_WINDOW_SECONDS: num({\n desc: 'Time window, in seconds, used to list active runners from recent heartbeats and provisioned runner reports.',\n default: 60,\n }),\n RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS: num({\n desc: 'Time window, in seconds, after which a runner tool capability report is treated as stale. Set this higher than the runner heartbeat interval so active runners keep their advertised tools fresh.',\n default: 60,\n }),\n RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS: num({\n desc: 'Grace window, in seconds, before maintenance expires a claimed job that has not sent its first heartbeat. Set this lower than the normal stuck-job threshold so startup crashes release work quickly.',\n default: 60,\n }),\n RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS: num({\n desc: 'Grace window, in seconds, before reconcile marks an absent provisioned runner as terminated. Set this higher than the provisioner report interval so a transient empty or partial observed set does not kill a live runner.',\n default: 120,\n }),\n RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS: num({\n desc: 'Time, in seconds, after which a provisioned runner with no recent report, no live provisioner, no live runner session, and no running job is marked failed by backend maintenance.',\n default: 300,\n }),\n RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT: num({\n desc: 'Maximum number of stale provisioned runners the maintenance worker marks failed in one run. Higher values clear backlogs faster but hold database locks longer.',\n default: 100,\n }),\n RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS: num({\n desc: 'Minimum time, in seconds, between runner session liveness writes from job request polls. Set this lower than RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS so active idle runners stay fresh.',\n default: 10,\n }),\n RUNNER_SESSION_MANUAL_RETENTION_DAYS: num({\n desc: 'How long manual runner sessions are retained before maintenance deletes them, in days. Set this longer than AUTH_RUNNER_SESSION_TOKEN_EXPIRES_IN so a valid session token never outlives its row.',\n default: 30,\n }),\n RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS: num({\n desc: 'How long ephemeral runner sessions are retained before maintenance deletes them, in days. Set this longer than AUTH_RUNNER_SESSION_TOKEN_EXPIRES_IN so a valid session token never outlives its row.',\n default: 7,\n }),\n RUNNER_SESSION_GC_BATCH_SIZE: num({\n desc: 'Maximum number of expired runner sessions maintenance deletes in one pass.',\n default: 1000,\n }),\n RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS: num({\n desc: 'How long consumed or expired ephemeral registration tokens are retained for audit and debugging before maintenance deletes them, in days. Active tokens that are neither consumed nor expired are never deleted. This window is independent of the runner-session retention windows.',\n default: 7,\n }),\n RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE: num({\n desc: 'Maximum number of consumed or expired ephemeral registration tokens maintenance deletes in one pass.',\n default: 1000,\n }),\n PROVISIONER_ACTIVE_WINDOW_SECONDS: num({\n desc: 'Time window, in seconds, used to list active provisioners from recent authenticated requests.',\n default: 120,\n }),\n PROVISIONER_LAST_SEEN_THROTTLE_SECONDS: num({\n desc: 'Minimum time, in seconds, between last-seen writes for one provisioner token.',\n default: 10,\n }),\n PROVISIONED_RUNNER_COUNT_DIVERGENCE_TEMPLATE_KEY_LABEL_ENABLED: bool({\n desc: 'Whether runners_provider_runner_count_divergence includes template_key as a metric label. Use true or false. Defaults to false because template keys can create high-cardinality metric series. Set true only when template keys are bounded and stable.',\n default: false,\n }),\n});\n\nif (\n !Number.isInteger(config.EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS) ||\n config.EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS < 1 ||\n config.EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS >\n EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS\n) {\n throw new Error(\n `EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS (${config.EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS}) must be a whole number of seconds between 1 and ${EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS}.`,\n );\n}\n\nfor (const [name, value] of [\n ['RUNNER_BOOTSTRAP_TOKEN_TTL_SECONDS', config.RUNNER_BOOTSTRAP_TOKEN_TTL_SECONDS],\n ['RUNNER_CONTROL_SESSION_TTL_SECONDS', config.RUNNER_CONTROL_SESSION_TTL_SECONDS],\n ['RUNNER_ACTIVATION_TOKEN_TTL_SECONDS', config.RUNNER_ACTIVATION_TOKEN_TTL_SECONDS],\n] as const) {\n if (\n !Number.isInteger(value) ||\n value < 1 ||\n value > RUNNER_CONTROL_PLANE_TOKEN_TTL_HARD_MAX_SECONDS\n ) {\n throw new Error(\n `${name} (${value}) must be a whole number of seconds between 1 and ${RUNNER_CONTROL_PLANE_TOKEN_TTL_HARD_MAX_SECONDS}.`,\n );\n }\n}\n\nfor (const [name, value] of [\n ['RUNNER_ASSIGNMENT_POLL_MAX_WAIT_SECONDS', config.RUNNER_ASSIGNMENT_POLL_MAX_WAIT_SECONDS],\n ['RUNNER_ASSIGNMENT_POLL_INTERVAL_MS', config.RUNNER_ASSIGNMENT_POLL_INTERVAL_MS],\n] as const) {\n if (!Number.isInteger(value) || value < 0)\n throw new Error(`${name} (${value}) must be a whole number >= 0.`);\n}\n\nif (\n !Number.isInteger(config.REGISTRATION_TOKEN_BATCH_MAX) ||\n config.REGISTRATION_TOKEN_BATCH_MAX < 1 ||\n config.REGISTRATION_TOKEN_BATCH_MAX > REGISTRATION_TOKEN_BATCH_HARD_MAX\n) {\n throw new Error(\n `REGISTRATION_TOKEN_BATCH_MAX (${config.REGISTRATION_TOKEN_BATCH_MAX}) must be a whole number between 1 and ${REGISTRATION_TOKEN_BATCH_HARD_MAX}.`,\n );\n}\n\nfor (const [name, value] of [\n ['PROVISIONER_MINT_RATE_LIMIT_MAX_REQUESTS', config.PROVISIONER_MINT_RATE_LIMIT_MAX_REQUESTS],\n ['PROVISIONER_MINT_RATE_LIMIT_WINDOW_SECONDS', config.PROVISIONER_MINT_RATE_LIMIT_WINDOW_SECONDS],\n ['EPHEMERAL_REGISTER_RATE_LIMIT_MAX_REQUESTS', config.EPHEMERAL_REGISTER_RATE_LIMIT_MAX_REQUESTS],\n [\n 'EPHEMERAL_REGISTER_RATE_LIMIT_WINDOW_SECONDS',\n config.EPHEMERAL_REGISTER_RATE_LIMIT_WINDOW_SECONDS,\n ],\n ['RUNNERS_RATE_LIMIT_TIMEOUT_MS', config.RUNNERS_RATE_LIMIT_TIMEOUT_MS],\n] as const) {\n if (!Number.isInteger(value) || value < 1) {\n throw new Error(`${name} (${value}) must be a whole number >= 1.`);\n }\n}\n\nif (!Number.isInteger(config.RESERVATION_TTL_SECONDS) || config.RESERVATION_TTL_SECONDS < 1) {\n throw new Error(\n `RESERVATION_TTL_SECONDS (${config.RESERVATION_TTL_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RESERVATION_LONG_POLL_MAX_WAIT_SECONDS) ||\n config.RESERVATION_LONG_POLL_MAX_WAIT_SECONDS < 0\n) {\n throw new Error(\n `RESERVATION_LONG_POLL_MAX_WAIT_SECONDS (${config.RESERVATION_LONG_POLL_MAX_WAIT_SECONDS}) must be a whole number of seconds >= 0.`,\n );\n}\n\nif (\n !Number.isInteger(config.RESERVATION_POLL_INTERVAL_MS) ||\n config.RESERVATION_POLL_INTERVAL_MS < 1\n) {\n throw new Error(\n `RESERVATION_POLL_INTERVAL_MS (${config.RESERVATION_POLL_INTERVAL_MS}) must be a whole number of milliseconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RESERVATION_POLL_MAX_INTERVAL_MS) ||\n config.RESERVATION_POLL_MAX_INTERVAL_MS < config.RESERVATION_POLL_INTERVAL_MS\n) {\n throw new Error(\n `RESERVATION_POLL_MAX_INTERVAL_MS (${config.RESERVATION_POLL_MAX_INTERVAL_MS}) must be a whole number of milliseconds >= RESERVATION_POLL_INTERVAL_MS (${config.RESERVATION_POLL_INTERVAL_MS}).`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_ACTIVE_WINDOW_SECONDS) ||\n config.RUNNER_ACTIVE_WINDOW_SECONDS < 1\n) {\n throw new Error(\n `RUNNER_ACTIVE_WINDOW_SECONDS (${config.RUNNER_ACTIVE_WINDOW_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS) ||\n config.RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS < 1\n) {\n throw new Error(\n `RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS (${config.RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS) ||\n config.RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS < 1 ||\n config.RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS >= STUCK_JOB_THRESHOLD_SECONDS\n) {\n throw new Error(\n `RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS (${config.RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS}) must be a whole number of seconds >= 1 and < ${STUCK_JOB_THRESHOLD_SECONDS}.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS) ||\n config.RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS < 1\n) {\n throw new Error(\n `RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS (${config.RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS) ||\n config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS < 1\n) {\n throw new Error(\n `RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS (${config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT) ||\n config.RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT < 1\n) {\n throw new Error(\n `RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT (${config.RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT}) must be a whole number >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS) ||\n config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS < 1\n) {\n throw new Error(\n `RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS (${config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_SESSION_MANUAL_RETENTION_DAYS) ||\n config.RUNNER_SESSION_MANUAL_RETENTION_DAYS < 1\n) {\n throw new Error(\n `RUNNER_SESSION_MANUAL_RETENTION_DAYS (${config.RUNNER_SESSION_MANUAL_RETENTION_DAYS}) must be a whole number of days >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS) ||\n config.RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS < 1\n) {\n throw new Error(\n `RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS (${config.RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS}) must be a whole number of days >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_SESSION_GC_BATCH_SIZE) ||\n config.RUNNER_SESSION_GC_BATCH_SIZE < 1\n) {\n throw new Error(\n `RUNNER_SESSION_GC_BATCH_SIZE (${config.RUNNER_SESSION_GC_BATCH_SIZE}) must be a whole number >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS) ||\n config.RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS < 1\n) {\n throw new Error(\n `RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS (${config.RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS}) must be a whole number of days >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE) ||\n config.RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE < 1\n) {\n throw new Error(\n `RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE (${config.RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE}) must be a whole number >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.PROVISIONER_ACTIVE_WINDOW_SECONDS) ||\n config.PROVISIONER_ACTIVE_WINDOW_SECONDS < 1\n) {\n throw new Error(\n `PROVISIONER_ACTIVE_WINDOW_SECONDS (${config.PROVISIONER_ACTIVE_WINDOW_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n !Number.isInteger(config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS) ||\n config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS < 1\n) {\n throw new Error(\n `PROVISIONER_LAST_SEEN_THROTTLE_SECONDS (${config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS}) must be a whole number of seconds >= 1.`,\n );\n}\n\nif (\n config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS <=\n config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS\n) {\n throw new Error(\n `RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS (${config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS}) must be greater than PROVISIONER_LAST_SEEN_THROTTLE_SECONDS (${config.PROVISIONER_LAST_SEEN_THROTTLE_SECONDS}).`,\n );\n}\n\nif (\n config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS <=\n config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS\n) {\n throw new Error(\n `RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS (${config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS}) must be greater than RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS (${config.RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS}).`,\n );\n}\n"],"names":["bool","createConfig","num","STUCK_JOB_THRESHOLD_SECONDS","EPHEMERAL_REGISTRATION_TOKEN_TTL_HARD_MAX_SECONDS","REGISTRATION_TOKEN_BATCH_HARD_MAX","RUNNER_CONTROL_PLANE_TOKEN_TTL_HARD_MAX_SECONDS","config","RUNNER_BOOTSTRAP_TOKEN_TTL_SECONDS","desc","default","RUNNER_CONTROL_SESSION_TTL_SECONDS","RUNNER_ACTIVATION_TOKEN_TTL_SECONDS","RUNNER_ASSIGNMENT_POLL_MAX_WAIT_SECONDS","RUNNER_ASSIGNMENT_POLL_INTERVAL_MS","EPHEMERAL_REGISTRATION_TOKEN_TTL_SECONDS","REGISTRATION_TOKEN_BATCH_MAX","PROVISIONER_MINT_RATE_LIMIT_MAX_REQUESTS","PROVISIONER_MINT_RATE_LIMIT_WINDOW_SECONDS","EPHEMERAL_REGISTER_RATE_LIMIT_MAX_REQUESTS","EPHEMERAL_REGISTER_RATE_LIMIT_WINDOW_SECONDS","RUNNERS_RATE_LIMIT_TIMEOUT_MS","RESERVATION_TTL_SECONDS","RESERVATION_LONG_POLL_MAX_WAIT_SECONDS","RESERVATION_POLL_INTERVAL_MS","RESERVATION_POLL_MAX_INTERVAL_MS","RUNNER_ACTIVE_WINDOW_SECONDS","RUNNER_TOOL_CAPABILITIES_STALE_AFTER_SECONDS","RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS","RUNNER_RECONCILE_TERMINATE_GRACE_SECONDS","RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS","RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT","RUNNER_SESSION_LIVENESS_THROTTLE_SECONDS","RUNNER_SESSION_MANUAL_RETENTION_DAYS","RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS","RUNNER_SESSION_GC_BATCH_SIZE","RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS","RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE","PROVISIONER_ACTIVE_WINDOW_SECONDS","PROVISIONER_LAST_SEEN_THROTTLE_SECONDS","PROVISIONED_RUNNER_COUNT_DIVERGENCE_TEMPLATE_KEY_LABEL_ENABLED","Number","isInteger","Error","name","value"],"mappings":"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"}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
+
import type { Tx } from '#db/db.js';
|
|
1
2
|
export declare function issueRunnerActivationToken(params: {
|
|
2
3
|
runnerInstanceId: string;
|
|
3
4
|
provisionerId: string;
|
|
4
5
|
ttlSeconds: number;
|
|
5
6
|
}): Promise<string | null>;
|
|
7
|
+
export declare function issueRunnerActivationTokenTx(tx: Tx, params: {
|
|
8
|
+
runnerInstanceId: string;
|
|
9
|
+
provisionerId: string;
|
|
10
|
+
ttlSeconds: number;
|
|
11
|
+
}): Promise<string | null>;
|
|
6
12
|
export declare function getRunnerAssignment(params: {
|
|
7
13
|
runnerInstanceId: string;
|
|
8
14
|
provisionerId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner-activation.d.ts","sourceRoot":"","sources":["../../src/core/runner-activation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runner-activation.d.ts","sourceRoot":"","sources":["../../src/core/runner-activation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,WAAW,CAAC;AAKlC,wBAAsB,0BAA0B,CAAC,MAAM,EAAE;IACvD,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAEzB;AAED,wBAAsB,4BAA4B,CAChD,EAAE,EAAE,EAAE,EACN,MAAM,EAAE;IACN,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB,GACA,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAuCxB;AAED,wBAAsB,mBAAmB,CAAC,MAAM,EAAE;IAChD,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;CACvB;;;UAeA"}
|
|
@@ -4,26 +4,27 @@ import { db } from '#db/db.js';
|
|
|
4
4
|
import { runnerActivationTokens } from '#db/schema/runner-activation-tokens.js';
|
|
5
5
|
import { providerRunners } from '#db/schema/runner-instances.js';
|
|
6
6
|
export async function issueRunnerActivationToken(params) {
|
|
7
|
-
return await db().transaction(async (tx)=>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
7
|
+
return await db().transaction(async (tx)=>issueRunnerActivationTokenTx(tx, params));
|
|
8
|
+
}
|
|
9
|
+
export async function issueRunnerActivationTokenTx(tx, params) {
|
|
10
|
+
await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`runners_activation:${params.runnerInstanceId}`}))`);
|
|
11
|
+
const [runner] = await tx.select({
|
|
12
|
+
workspaceId: providerRunners.workspaceId,
|
|
13
|
+
runnerSessionId: providerRunners.runnerSessionId,
|
|
14
|
+
state: providerRunners.state
|
|
15
|
+
}).from(providerRunners).where(and(eq(providerRunners.id, params.runnerInstanceId), eq(providerRunners.provisionerId, params.provisionerId))).limit(1).for('update');
|
|
16
|
+
if (!runner?.workspaceId || runner.runnerSessionId || runner.state !== 'running') return null;
|
|
17
|
+
await tx.update(runnerActivationTokens).set({
|
|
18
|
+
revokedAt: sql`now()`
|
|
19
|
+
}).where(and(eq(runnerActivationTokens.runnerInstanceId, params.runnerInstanceId), isNull(runnerActivationTokens.consumedAt), isNull(runnerActivationTokens.revokedAt)));
|
|
20
|
+
const rawToken = generateOpaqueToken('runnerActivationToken');
|
|
21
|
+
await tx.insert(runnerActivationTokens).values({
|
|
22
|
+
runnerInstanceId: params.runnerInstanceId,
|
|
23
|
+
hashedToken: hashOpaqueToken(rawToken),
|
|
24
|
+
prefix: extractDisplayPrefix(rawToken),
|
|
25
|
+
expiresAt: new Date(Date.now() + params.ttlSeconds * 1000)
|
|
26
26
|
});
|
|
27
|
+
return rawToken;
|
|
27
28
|
}
|
|
28
29
|
export async function getRunnerAssignment(params) {
|
|
29
30
|
const [runner] = await db().select({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/runner-activation.ts"],"sourcesContent":["import {extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken} from '@shipfox/node-tokens';\nimport {and, eq, isNull, sql} from 'drizzle-orm';\nimport {db} from '#db/db.js';\nimport {runnerActivationTokens} from '#db/schema/runner-activation-tokens.js';\nimport {providerRunners} from '#db/schema/runner-instances.js';\n\nexport async function issueRunnerActivationToken(params: {\n runnerInstanceId: string;\n provisionerId: string;\n ttlSeconds: number;\n}): Promise<string | null> {\n return await db().transaction(async (tx) => {\n await tx.execute(\n
|
|
1
|
+
{"version":3,"sources":["../../src/core/runner-activation.ts"],"sourcesContent":["import {extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken} from '@shipfox/node-tokens';\nimport {and, eq, isNull, sql} from 'drizzle-orm';\nimport type {Tx} from '#db/db.js';\nimport {db} from '#db/db.js';\nimport {runnerActivationTokens} from '#db/schema/runner-activation-tokens.js';\nimport {providerRunners} from '#db/schema/runner-instances.js';\n\nexport async function issueRunnerActivationToken(params: {\n runnerInstanceId: string;\n provisionerId: string;\n ttlSeconds: number;\n}): Promise<string | null> {\n return await db().transaction(async (tx) => issueRunnerActivationTokenTx(tx, params));\n}\n\nexport async function issueRunnerActivationTokenTx(\n tx: Tx,\n params: {\n runnerInstanceId: string;\n provisionerId: string;\n ttlSeconds: number;\n },\n): Promise<string | null> {\n await tx.execute(\n sql`select pg_advisory_xact_lock(hashtext(${`runners_activation:${params.runnerInstanceId}`}))`,\n );\n const [runner] = await tx\n .select({\n workspaceId: providerRunners.workspaceId,\n runnerSessionId: providerRunners.runnerSessionId,\n state: providerRunners.state,\n })\n .from(providerRunners)\n .where(\n and(\n eq(providerRunners.id, params.runnerInstanceId),\n eq(providerRunners.provisionerId, params.provisionerId),\n ),\n )\n .limit(1)\n .for('update');\n if (!runner?.workspaceId || runner.runnerSessionId || runner.state !== 'running') return null;\n\n await tx\n .update(runnerActivationTokens)\n .set({revokedAt: sql`now()`})\n .where(\n and(\n eq(runnerActivationTokens.runnerInstanceId, params.runnerInstanceId),\n isNull(runnerActivationTokens.consumedAt),\n isNull(runnerActivationTokens.revokedAt),\n ),\n );\n const rawToken = generateOpaqueToken('runnerActivationToken');\n await tx.insert(runnerActivationTokens).values({\n runnerInstanceId: params.runnerInstanceId,\n hashedToken: hashOpaqueToken(rawToken),\n prefix: extractDisplayPrefix(rawToken),\n expiresAt: new Date(Date.now() + params.ttlSeconds * 1000),\n });\n return rawToken;\n}\n\nexport async function getRunnerAssignment(params: {\n runnerInstanceId: string;\n provisionerId: string;\n}) {\n const [runner] = await db()\n .select({\n workspaceId: providerRunners.workspaceId,\n runnerSessionId: providerRunners.runnerSessionId,\n })\n .from(providerRunners)\n .where(\n and(\n eq(providerRunners.id, params.runnerInstanceId),\n eq(providerRunners.provisionerId, params.provisionerId),\n ),\n )\n .limit(1);\n return runner?.workspaceId && !runner.runnerSessionId ? runner : null;\n}\n"],"names":["extractDisplayPrefix","generateOpaqueToken","hashOpaqueToken","and","eq","isNull","sql","db","runnerActivationTokens","providerRunners","issueRunnerActivationToken","params","transaction","tx","issueRunnerActivationTokenTx","execute","runnerInstanceId","runner","select","workspaceId","runnerSessionId","state","from","where","id","provisionerId","limit","for","update","set","revokedAt","consumedAt","rawToken","insert","values","hashedToken","prefix","expiresAt","Date","now","ttlSeconds","getRunnerAssignment"],"mappings":"AAAA,SAAQA,oBAAoB,EAAEC,mBAAmB,EAAEC,eAAe,QAAO,uBAAuB;AAChG,SAAQC,GAAG,EAAEC,EAAE,EAAEC,MAAM,EAAEC,GAAG,QAAO,cAAc;AAEjD,SAAQC,EAAE,QAAO,YAAY;AAC7B,SAAQC,sBAAsB,QAAO,yCAAyC;AAC9E,SAAQC,eAAe,QAAO,iCAAiC;AAE/D,OAAO,eAAeC,2BAA2BC,MAIhD;IACC,OAAO,MAAMJ,KAAKK,WAAW,CAAC,OAAOC,KAAOC,6BAA6BD,IAAIF;AAC/E;AAEA,OAAO,eAAeG,6BACpBD,EAAM,EACNF,MAIC;IAED,MAAME,GAAGE,OAAO,CACdT,GAAG,CAAC,sCAAsC,EAAE,CAAC,mBAAmB,EAAEK,OAAOK,gBAAgB,EAAE,CAAC,EAAE,CAAC;IAEjG,MAAM,CAACC,OAAO,GAAG,MAAMJ,GACpBK,MAAM,CAAC;QACNC,aAAaV,gBAAgBU,WAAW;QACxCC,iBAAiBX,gBAAgBW,eAAe;QAChDC,OAAOZ,gBAAgBY,KAAK;IAC9B,GACCC,IAAI,CAACb,iBACLc,KAAK,CACJpB,IACEC,GAAGK,gBAAgBe,EAAE,EAAEb,OAAOK,gBAAgB,GAC9CZ,GAAGK,gBAAgBgB,aAAa,EAAEd,OAAOc,aAAa,IAGzDC,KAAK,CAAC,GACNC,GAAG,CAAC;IACP,IAAI,CAACV,QAAQE,eAAeF,OAAOG,eAAe,IAAIH,OAAOI,KAAK,KAAK,WAAW,OAAO;IAEzF,MAAMR,GACHe,MAAM,CAACpB,wBACPqB,GAAG,CAAC;QAACC,WAAWxB,GAAG,CAAC,KAAK,CAAC;IAAA,GAC1BiB,KAAK,CACJpB,IACEC,GAAGI,uBAAuBQ,gBAAgB,EAAEL,OAAOK,gBAAgB,GACnEX,OAAOG,uBAAuBuB,UAAU,GACxC1B,OAAOG,uBAAuBsB,SAAS;IAG7C,MAAME,WAAW/B,oBAAoB;IACrC,MAAMY,GAAGoB,MAAM,CAACzB,wBAAwB0B,MAAM,CAAC;QAC7ClB,kBAAkBL,OAAOK,gBAAgB;QACzCmB,aAAajC,gBAAgB8B;QAC7BI,QAAQpC,qBAAqBgC;QAC7BK,WAAW,IAAIC,KAAKA,KAAKC,GAAG,KAAK5B,OAAO6B,UAAU,GAAG;IACvD;IACA,OAAOR;AACT;AAEA,OAAO,eAAeS,oBAAoB9B,MAGzC;IACC,MAAM,CAACM,OAAO,GAAG,MAAMV,KACpBW,MAAM,CAAC;QACNC,aAAaV,gBAAgBU,WAAW;QACxCC,iBAAiBX,gBAAgBW,eAAe;IAClD,GACCE,IAAI,CAACb,iBACLc,KAAK,CACJpB,IACEC,GAAGK,gBAAgBe,EAAE,EAAEb,OAAOK,gBAAgB,GAC9CZ,GAAGK,gBAAgBgB,aAAa,EAAEd,OAAOc,aAAa,IAGzDC,KAAK,CAAC;IACT,OAAOT,QAAQE,eAAe,CAACF,OAAOG,eAAe,GAAGH,SAAS;AACnE"}
|
|
@@ -10,6 +10,7 @@ export declare function createRunnerInstancesWithBootstrapTokens(params: {
|
|
|
10
10
|
providerKind?: string | null;
|
|
11
11
|
runnerInstances: Array<{
|
|
12
12
|
templateKey?: string | null;
|
|
13
|
+
reservationId?: string | null;
|
|
13
14
|
}>;
|
|
14
15
|
ttlSeconds: number;
|
|
15
16
|
}): Promise<Array<{
|
|
@@ -36,7 +37,7 @@ export declare function enrollRunnerControlSession(params: {
|
|
|
36
37
|
capabilities?: RunnerToolCapabilitiesDto | null;
|
|
37
38
|
providerKind: string;
|
|
38
39
|
protocolVersion: string;
|
|
39
|
-
}): Promise<
|
|
40
|
+
}): Promise<string | null>;
|
|
40
41
|
export declare function attachRunnerControlProviderId(params: {
|
|
41
42
|
runnerInstanceId: string;
|
|
42
43
|
provisionerId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner-control-sessions.d.ts","sourceRoot":"","sources":["../../src/core/runner-control-sessions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"runner-control-sessions.d.ts","sourceRoot":"","sources":["../../src/core/runner-control-sessions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,0BAA0B,CAAC;AAqBxE,qBAAa,gCAAiC,SAAQ,KAAK;;CAK1D;AAED,qBAAa,gCAAiC,SAAQ,KAAK;;CAK1D;AAED,wBAAsB,wCAAwC,CAAC,MAAM,EAAE;IACrE,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,EAAE,KAAK,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC/B,CAAC,CAAC;IACH,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,KAAK,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC,CAgCrE;AAED,wBAAsB,4BAA4B,CAAC,MAAM,EAAE;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,IAAI,CAAA;CAAC,CAAC,CA8BpF;AAED,wBAAsB,2BAA2B,CAAC,QAAQ,EAAE,MAAM;;;;eAmBjE;AAED,wBAAsB,0BAA0B,CAAC,MAAM,EAAE;IACvD,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,yBAAyB,GAAG,IAAI,CAAC;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiFzB;AAED,wBAAsB,6BAA6B,CAAC,MAAM,EAAE;IAC1D,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,GAAG,OAAO,CAAC,OAAO,CAAC,CAcnB;AAED,wBAAsB,yBAAyB,CAAC,gBAAgB,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,iBAW9F"}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
+
import { logger } from '@shipfox/node-opentelemetry';
|
|
1
2
|
import { extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken } from '@shipfox/node-tokens';
|
|
2
3
|
import { canonicalizeLabels } from '@shipfox/runner-labels';
|
|
3
4
|
import { and, eq, gt, isNull, notInArray, or, sql } from 'drizzle-orm';
|
|
5
|
+
import { config } from '#config.js';
|
|
6
|
+
import { ReservationExpiredError, ReservationNotFoundError, RunnerInstanceAlreadyAssignedError, RunnerInstanceNotAssignableError } from '#core/errors.js';
|
|
4
7
|
import { db } from '#db/db.js';
|
|
8
|
+
import { assignRunnerInstancesTx } from '#db/runner-assignments.js';
|
|
5
9
|
import { terminalStates } from '#db/runner-instances.js';
|
|
6
10
|
import { provisionerTokens } from '#db/schema/provisioner-tokens.js';
|
|
7
11
|
import { runnerBootstrapTokens, runnerControlSessions } from '#db/schema/runner-control-sessions.js';
|
|
8
12
|
import { providerRunners } from '#db/schema/runner-instances.js';
|
|
13
|
+
import { issueRunnerActivationTokenTx } from './runner-activation.js';
|
|
9
14
|
export class RunnerBootstrapTokenInvalidError extends Error {
|
|
10
15
|
constructor(){
|
|
11
16
|
super('Runner bootstrap token is invalid, expired, or has already been used');
|
|
@@ -25,6 +30,7 @@ export async function createRunnerInstancesWithBootstrapTokens(params) {
|
|
|
25
30
|
provisionerId: params.provisionerId,
|
|
26
31
|
providerKind: params.providerKind ?? null,
|
|
27
32
|
templateKey: runner.templateKey ?? null,
|
|
33
|
+
intendedReservationId: runner.reservationId ?? null,
|
|
28
34
|
state: 'starting',
|
|
29
35
|
labels: [],
|
|
30
36
|
reportedAt: new Date()
|
|
@@ -79,23 +85,60 @@ export async function resolveRunnerControlSession(rawToken) {
|
|
|
79
85
|
return session;
|
|
80
86
|
}
|
|
81
87
|
export async function enrollRunnerControlSession(params) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
88
|
+
return await db().transaction(async (tx)=>{
|
|
89
|
+
const [current] = await tx.select({
|
|
90
|
+
intendedReservationId: providerRunners.intendedReservationId
|
|
91
|
+
}).from(providerRunners).where(and(eq(providerRunners.id, params.runnerInstanceId), eq(providerRunners.provisionerId, params.provisionerId)));
|
|
92
|
+
if (!current) throw new RunnerControlSessionInvalidError();
|
|
93
|
+
if (current.intendedReservationId) await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`runners_assignment:${params.provisionerId}:${current.intendedReservationId}`}))`);
|
|
94
|
+
const [updated] = await tx.update(providerRunners).set({
|
|
95
|
+
labels: [
|
|
96
|
+
...canonicalizeLabels(params.labels)
|
|
97
|
+
],
|
|
98
|
+
providerKind: params.providerKind,
|
|
99
|
+
protocolVersion: params.protocolVersion,
|
|
100
|
+
capabilities: params.capabilities ?? null,
|
|
101
|
+
state: 'running',
|
|
102
|
+
reportedAt: sql`now()`,
|
|
103
|
+
updatedAt: sql`now()`
|
|
104
|
+
}).where(and(eq(providerRunners.id, params.runnerInstanceId), eq(providerRunners.provisionerId, params.provisionerId), notInArray(providerRunners.state, [
|
|
105
|
+
...terminalStates
|
|
106
|
+
]))).returning({
|
|
107
|
+
id: providerRunners.id,
|
|
108
|
+
intendedReservationId: providerRunners.intendedReservationId
|
|
109
|
+
});
|
|
110
|
+
if (!updated) throw new RunnerControlSessionInvalidError();
|
|
111
|
+
await updateRunnerControlSessionLastSeen(tx, params.runnerInstanceId, params.provisionerId);
|
|
112
|
+
const intendedReservationId = updated.intendedReservationId;
|
|
113
|
+
if (!intendedReservationId) return null;
|
|
114
|
+
try {
|
|
115
|
+
return await tx.transaction(async (promotionTx)=>{
|
|
116
|
+
await assignRunnerInstancesTx(promotionTx, {
|
|
117
|
+
provisionerId: params.provisionerId,
|
|
118
|
+
reservationId: intendedReservationId,
|
|
119
|
+
runnerInstanceIds: [
|
|
120
|
+
params.runnerInstanceId
|
|
121
|
+
]
|
|
122
|
+
});
|
|
123
|
+
return await issueRunnerActivationTokenTx(promotionTx, {
|
|
124
|
+
runnerInstanceId: params.runnerInstanceId,
|
|
125
|
+
provisionerId: params.provisionerId,
|
|
126
|
+
ttlSeconds: config.RUNNER_ACTIVATION_TOKEN_TTL_SECONDS
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
} catch (error) {
|
|
130
|
+
const expectedFailure = error instanceof ReservationExpiredError || error instanceof ReservationNotFoundError || error instanceof RunnerInstanceAlreadyAssignedError || error instanceof RunnerInstanceNotAssignableError;
|
|
131
|
+
const details = {
|
|
132
|
+
err: error,
|
|
133
|
+
runnerInstanceId: params.runnerInstanceId,
|
|
134
|
+
provisionerId: params.provisionerId,
|
|
135
|
+
reservationId: intendedReservationId
|
|
136
|
+
};
|
|
137
|
+
if (expectedFailure) logger().debug(details, 'Runner reservation could not be promoted during enrollment');
|
|
138
|
+
else logger().error(details, 'Unexpected failure promoting runner reservation during enrollment');
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
96
141
|
});
|
|
97
|
-
if (!updated[0]) throw new RunnerControlSessionInvalidError();
|
|
98
|
-
await touchRunnerControlSession(params.runnerInstanceId, params.provisionerId);
|
|
99
142
|
}
|
|
100
143
|
export async function attachRunnerControlProviderId(params) {
|
|
101
144
|
const rows = await db().update(providerRunners).set({
|
|
@@ -109,13 +152,16 @@ export async function attachRunnerControlProviderId(params) {
|
|
|
109
152
|
return rows.length === 1;
|
|
110
153
|
}
|
|
111
154
|
export async function touchRunnerControlSession(runnerInstanceId, provisionerId) {
|
|
112
|
-
await db()
|
|
113
|
-
lastSeenAt: sql`now()`
|
|
114
|
-
}).where(and(eq(runnerControlSessions.runnerInstanceId, runnerInstanceId), eq(runnerControlSessions.provisionerId, provisionerId), isNull(runnerControlSessions.closedAt)));
|
|
155
|
+
await updateRunnerControlSessionLastSeen(db(), runnerInstanceId, provisionerId);
|
|
115
156
|
await db().update(providerRunners).set({
|
|
116
157
|
reportedAt: sql`now()`,
|
|
117
158
|
updatedAt: sql`now()`
|
|
118
159
|
}).where(and(eq(providerRunners.id, runnerInstanceId), eq(providerRunners.provisionerId, provisionerId)));
|
|
119
160
|
}
|
|
161
|
+
async function updateRunnerControlSessionLastSeen(tx, runnerInstanceId, provisionerId) {
|
|
162
|
+
await tx.update(runnerControlSessions).set({
|
|
163
|
+
lastSeenAt: sql`now()`
|
|
164
|
+
}).where(and(eq(runnerControlSessions.runnerInstanceId, runnerInstanceId), eq(runnerControlSessions.provisionerId, provisionerId), isNull(runnerControlSessions.closedAt)));
|
|
165
|
+
}
|
|
120
166
|
|
|
121
167
|
//# sourceMappingURL=runner-control-sessions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/runner-control-sessions.ts"],"sourcesContent":["import type {RunnerToolCapabilitiesDto} from '@shipfox/api-runners-dto';\nimport {extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken} from '@shipfox/node-tokens';\nimport {canonicalizeLabels} from '@shipfox/runner-labels';\nimport {and, eq, gt, isNull, notInArray, or, sql} from 'drizzle-orm';\nimport {db} from '#db/db.js';\nimport {terminalStates} from '#db/runner-instances.js';\nimport {provisionerTokens} from '#db/schema/provisioner-tokens.js';\nimport {runnerBootstrapTokens, runnerControlSessions} from '#db/schema/runner-control-sessions.js';\nimport {providerRunners} from '#db/schema/runner-instances.js';\n\nexport class RunnerBootstrapTokenInvalidError extends Error {\n constructor() {\n super('Runner bootstrap token is invalid, expired, or has already been used');\n this.name = 'RunnerBootstrapTokenInvalidError';\n }\n}\n\nexport class RunnerControlSessionInvalidError extends Error {\n constructor() {\n super('Runner control session is invalid, expired, or closed');\n this.name = 'RunnerControlSessionInvalidError';\n }\n}\n\nexport async function createRunnerInstancesWithBootstrapTokens(params: {\n provisionerId: string;\n providerKind?: string | null;\n runnerInstances: Array<{templateKey?: string | null}>;\n ttlSeconds: number;\n}): Promise<Array<{runnerInstanceId: string; bootstrapToken: string}>> {\n const expiresAt = new Date(Date.now() + params.ttlSeconds * 1000);\n return await db().transaction(async (tx) => {\n const instances = await tx\n .insert(providerRunners)\n .values(\n params.runnerInstances.map((runner) => ({\n provisionerId: params.provisionerId,\n providerKind: params.providerKind ?? null,\n templateKey: runner.templateKey ?? null,\n state: 'starting' as const,\n labels: [],\n reportedAt: new Date(),\n })),\n )\n .returning({id: providerRunners.id});\n const results = instances.map((instance) => ({\n runnerInstanceId: instance.id,\n bootstrapToken: generateOpaqueToken('runnerBootstrapToken'),\n }));\n await tx.insert(runnerBootstrapTokens).values(\n results.map((result) => ({\n runnerInstanceId: result.runnerInstanceId,\n provisionerId: params.provisionerId,\n hashedToken: hashOpaqueToken(result.bootstrapToken),\n prefix: extractDisplayPrefix(result.bootstrapToken),\n expiresAt,\n })),\n );\n return results;\n });\n}\n\nexport async function exchangeRunnerBootstrapToken(params: {\n rawToken: string;\n ttlSeconds: number;\n}): Promise<{runnerInstanceId: string; controlSessionToken: string; expiresAt: Date}> {\n const controlSessionToken = generateOpaqueToken('runnerControlSession');\n const expiresAt = new Date(Date.now() + params.ttlSeconds * 1000);\n return await db().transaction(async (tx) => {\n const [bootstrap] = await tx\n .update(runnerBootstrapTokens)\n .set({consumedAt: sql`now()`})\n .where(\n and(\n eq(runnerBootstrapTokens.hashedToken, hashOpaqueToken(params.rawToken)),\n isNull(runnerBootstrapTokens.consumedAt),\n isNull(runnerBootstrapTokens.revokedAt),\n gt(runnerBootstrapTokens.expiresAt, sql`now()`),\n ),\n )\n .returning();\n if (!bootstrap) throw new RunnerBootstrapTokenInvalidError();\n const [session] = await tx\n .insert(runnerControlSessions)\n .values({\n runnerInstanceId: bootstrap.runnerInstanceId,\n provisionerId: bootstrap.provisionerId,\n hashedToken: hashOpaqueToken(controlSessionToken),\n prefix: extractDisplayPrefix(controlSessionToken),\n expiresAt,\n })\n .returning({id: runnerControlSessions.id});\n if (!session) throw new Error('Runner control session insert returned no row');\n return {runnerInstanceId: bootstrap.runnerInstanceId, controlSessionToken, expiresAt};\n });\n}\n\nexport async function resolveRunnerControlSession(rawToken: string) {\n const [session] = await db()\n .select({\n id: runnerControlSessions.id,\n runnerInstanceId: runnerControlSessions.runnerInstanceId,\n provisionerId: runnerControlSessions.provisionerId,\n })\n .from(runnerControlSessions)\n .leftJoin(provisionerTokens, eq(provisionerTokens.id, runnerControlSessions.provisionerId))\n .where(\n and(\n eq(runnerControlSessions.hashedToken, hashOpaqueToken(rawToken)),\n isNull(runnerControlSessions.closedAt),\n or(isNull(provisionerTokens.id), isNull(provisionerTokens.revokedAt)),\n gt(runnerControlSessions.expiresAt, sql`now()`),\n ),\n )\n .limit(1);\n return session;\n}\n\nexport async function enrollRunnerControlSession(params: {\n runnerInstanceId: string;\n provisionerId: string;\n labels: string[];\n capabilities?: RunnerToolCapabilitiesDto | null;\n providerKind: string;\n protocolVersion: string;\n}): Promise<void> {\n const updated = await db()\n .update(providerRunners)\n .set({\n labels: [...canonicalizeLabels(params.labels)],\n providerKind: params.providerKind,\n protocolVersion: params.protocolVersion,\n capabilities: params.capabilities ?? null,\n state: 'running',\n reportedAt: sql`now()`,\n updatedAt: sql`now()`,\n })\n .where(\n and(\n eq(providerRunners.id, params.runnerInstanceId),\n eq(providerRunners.provisionerId, params.provisionerId),\n notInArray(providerRunners.state, [...terminalStates]),\n ),\n )\n .returning({id: providerRunners.id});\n if (!updated[0]) throw new RunnerControlSessionInvalidError();\n await touchRunnerControlSession(params.runnerInstanceId, params.provisionerId);\n}\n\nexport async function attachRunnerControlProviderId(params: {\n runnerInstanceId: string;\n provisionerId: string;\n providerRunnerId: string;\n}): Promise<boolean> {\n const rows = await db()\n .update(providerRunners)\n .set({providerRunnerId: params.providerRunnerId, updatedAt: sql`now()`})\n .where(\n and(\n eq(providerRunners.id, params.runnerInstanceId),\n eq(providerRunners.provisionerId, params.provisionerId),\n isNull(providerRunners.providerRunnerId),\n notInArray(providerRunners.state, [...terminalStates]),\n ),\n )\n .returning({id: providerRunners.id});\n return rows.length === 1;\n}\n\nexport async function touchRunnerControlSession(runnerInstanceId: string, provisionerId: string) {\n await db()\n .update(runnerControlSessions)\n .set({lastSeenAt: sql`now()`})\n .where(\n and(\n eq(runnerControlSessions.runnerInstanceId, runnerInstanceId),\n eq(runnerControlSessions.provisionerId, provisionerId),\n isNull(runnerControlSessions.closedAt),\n ),\n );\n await db()\n .update(providerRunners)\n .set({reportedAt: sql`now()`, updatedAt: sql`now()`})\n .where(\n and(\n eq(providerRunners.id, runnerInstanceId),\n eq(providerRunners.provisionerId, provisionerId),\n ),\n );\n}\n"],"names":["extractDisplayPrefix","generateOpaqueToken","hashOpaqueToken","canonicalizeLabels","and","eq","gt","isNull","notInArray","or","sql","db","terminalStates","provisionerTokens","runnerBootstrapTokens","runnerControlSessions","providerRunners","RunnerBootstrapTokenInvalidError","Error","name","RunnerControlSessionInvalidError","createRunnerInstancesWithBootstrapTokens","params","expiresAt","Date","now","ttlSeconds","transaction","tx","instances","insert","values","runnerInstances","map","runner","provisionerId","providerKind","templateKey","state","labels","reportedAt","returning","id","results","instance","runnerInstanceId","bootstrapToken","result","hashedToken","prefix","exchangeRunnerBootstrapToken","controlSessionToken","bootstrap","update","set","consumedAt","where","rawToken","revokedAt","session","resolveRunnerControlSession","select","from","leftJoin","closedAt","limit","enrollRunnerControlSession","updated","protocolVersion","capabilities","updatedAt","touchRunnerControlSession","attachRunnerControlProviderId","rows","providerRunnerId","length","lastSeenAt"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/core/runner-control-sessions.ts"],"sourcesContent":["import type {RunnerToolCapabilitiesDto} from '@shipfox/api-runners-dto';\nimport type {NodePgDatabase} from '@shipfox/node-drizzle';\nimport {logger} from '@shipfox/node-opentelemetry';\nimport {extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken} from '@shipfox/node-tokens';\nimport {canonicalizeLabels} from '@shipfox/runner-labels';\nimport {and, eq, gt, isNull, notInArray, or, sql} from 'drizzle-orm';\nimport {config} from '#config.js';\nimport {\n ReservationExpiredError,\n ReservationNotFoundError,\n RunnerInstanceAlreadyAssignedError,\n RunnerInstanceNotAssignableError,\n} from '#core/errors.js';\nimport {db, type schema, type Tx} from '#db/db.js';\nimport {assignRunnerInstancesTx} from '#db/runner-assignments.js';\nimport {terminalStates} from '#db/runner-instances.js';\nimport {provisionerTokens} from '#db/schema/provisioner-tokens.js';\nimport {runnerBootstrapTokens, runnerControlSessions} from '#db/schema/runner-control-sessions.js';\nimport {providerRunners} from '#db/schema/runner-instances.js';\nimport {issueRunnerActivationTokenTx} from './runner-activation.js';\n\nexport class RunnerBootstrapTokenInvalidError extends Error {\n constructor() {\n super('Runner bootstrap token is invalid, expired, or has already been used');\n this.name = 'RunnerBootstrapTokenInvalidError';\n }\n}\n\nexport class RunnerControlSessionInvalidError extends Error {\n constructor() {\n super('Runner control session is invalid, expired, or closed');\n this.name = 'RunnerControlSessionInvalidError';\n }\n}\n\nexport async function createRunnerInstancesWithBootstrapTokens(params: {\n provisionerId: string;\n providerKind?: string | null;\n runnerInstances: Array<{\n templateKey?: string | null;\n reservationId?: string | null;\n }>;\n ttlSeconds: number;\n}): Promise<Array<{runnerInstanceId: string; bootstrapToken: string}>> {\n const expiresAt = new Date(Date.now() + params.ttlSeconds * 1000);\n return await db().transaction(async (tx) => {\n const instances = await tx\n .insert(providerRunners)\n .values(\n params.runnerInstances.map((runner) => ({\n provisionerId: params.provisionerId,\n providerKind: params.providerKind ?? null,\n templateKey: runner.templateKey ?? null,\n intendedReservationId: runner.reservationId ?? null,\n state: 'starting' as const,\n labels: [],\n reportedAt: new Date(),\n })),\n )\n .returning({id: providerRunners.id});\n const results = instances.map((instance) => ({\n runnerInstanceId: instance.id,\n bootstrapToken: generateOpaqueToken('runnerBootstrapToken'),\n }));\n await tx.insert(runnerBootstrapTokens).values(\n results.map((result) => ({\n runnerInstanceId: result.runnerInstanceId,\n provisionerId: params.provisionerId,\n hashedToken: hashOpaqueToken(result.bootstrapToken),\n prefix: extractDisplayPrefix(result.bootstrapToken),\n expiresAt,\n })),\n );\n return results;\n });\n}\n\nexport async function exchangeRunnerBootstrapToken(params: {\n rawToken: string;\n ttlSeconds: number;\n}): Promise<{runnerInstanceId: string; controlSessionToken: string; expiresAt: Date}> {\n const controlSessionToken = generateOpaqueToken('runnerControlSession');\n const expiresAt = new Date(Date.now() + params.ttlSeconds * 1000);\n return await db().transaction(async (tx) => {\n const [bootstrap] = await tx\n .update(runnerBootstrapTokens)\n .set({consumedAt: sql`now()`})\n .where(\n and(\n eq(runnerBootstrapTokens.hashedToken, hashOpaqueToken(params.rawToken)),\n isNull(runnerBootstrapTokens.consumedAt),\n isNull(runnerBootstrapTokens.revokedAt),\n gt(runnerBootstrapTokens.expiresAt, sql`now()`),\n ),\n )\n .returning();\n if (!bootstrap) throw new RunnerBootstrapTokenInvalidError();\n const [session] = await tx\n .insert(runnerControlSessions)\n .values({\n runnerInstanceId: bootstrap.runnerInstanceId,\n provisionerId: bootstrap.provisionerId,\n hashedToken: hashOpaqueToken(controlSessionToken),\n prefix: extractDisplayPrefix(controlSessionToken),\n expiresAt,\n })\n .returning({id: runnerControlSessions.id});\n if (!session) throw new Error('Runner control session insert returned no row');\n return {runnerInstanceId: bootstrap.runnerInstanceId, controlSessionToken, expiresAt};\n });\n}\n\nexport async function resolveRunnerControlSession(rawToken: string) {\n const [session] = await db()\n .select({\n id: runnerControlSessions.id,\n runnerInstanceId: runnerControlSessions.runnerInstanceId,\n provisionerId: runnerControlSessions.provisionerId,\n })\n .from(runnerControlSessions)\n .leftJoin(provisionerTokens, eq(provisionerTokens.id, runnerControlSessions.provisionerId))\n .where(\n and(\n eq(runnerControlSessions.hashedToken, hashOpaqueToken(rawToken)),\n isNull(runnerControlSessions.closedAt),\n or(isNull(provisionerTokens.id), isNull(provisionerTokens.revokedAt)),\n gt(runnerControlSessions.expiresAt, sql`now()`),\n ),\n )\n .limit(1);\n return session;\n}\n\nexport async function enrollRunnerControlSession(params: {\n runnerInstanceId: string;\n provisionerId: string;\n labels: string[];\n capabilities?: RunnerToolCapabilitiesDto | null;\n providerKind: string;\n protocolVersion: string;\n}): Promise<string | null> {\n return await db().transaction(async (tx) => {\n const [current] = await tx\n .select({intendedReservationId: providerRunners.intendedReservationId})\n .from(providerRunners)\n .where(\n and(\n eq(providerRunners.id, params.runnerInstanceId),\n eq(providerRunners.provisionerId, params.provisionerId),\n ),\n );\n if (!current) throw new RunnerControlSessionInvalidError();\n if (current.intendedReservationId)\n await tx.execute(\n sql`select pg_advisory_xact_lock(hashtext(${`runners_assignment:${params.provisionerId}:${current.intendedReservationId}`}))`,\n );\n\n const [updated] = await tx\n .update(providerRunners)\n .set({\n labels: [...canonicalizeLabels(params.labels)],\n providerKind: params.providerKind,\n protocolVersion: params.protocolVersion,\n capabilities: params.capabilities ?? null,\n state: 'running',\n reportedAt: sql`now()`,\n updatedAt: sql`now()`,\n })\n .where(\n and(\n eq(providerRunners.id, params.runnerInstanceId),\n eq(providerRunners.provisionerId, params.provisionerId),\n notInArray(providerRunners.state, [...terminalStates]),\n ),\n )\n .returning({\n id: providerRunners.id,\n intendedReservationId: providerRunners.intendedReservationId,\n });\n if (!updated) throw new RunnerControlSessionInvalidError();\n\n await updateRunnerControlSessionLastSeen(tx, params.runnerInstanceId, params.provisionerId);\n\n const intendedReservationId = updated.intendedReservationId;\n if (!intendedReservationId) return null;\n\n try {\n return await tx.transaction(async (promotionTx) => {\n await assignRunnerInstancesTx(promotionTx, {\n provisionerId: params.provisionerId,\n reservationId: intendedReservationId,\n runnerInstanceIds: [params.runnerInstanceId],\n });\n return await issueRunnerActivationTokenTx(promotionTx, {\n runnerInstanceId: params.runnerInstanceId,\n provisionerId: params.provisionerId,\n ttlSeconds: config.RUNNER_ACTIVATION_TOKEN_TTL_SECONDS,\n });\n });\n } catch (error) {\n const expectedFailure =\n error instanceof ReservationExpiredError ||\n error instanceof ReservationNotFoundError ||\n error instanceof RunnerInstanceAlreadyAssignedError ||\n error instanceof RunnerInstanceNotAssignableError;\n const details = {\n err: error,\n runnerInstanceId: params.runnerInstanceId,\n provisionerId: params.provisionerId,\n reservationId: intendedReservationId,\n };\n if (expectedFailure)\n logger().debug(details, 'Runner reservation could not be promoted during enrollment');\n else\n logger().error(\n details,\n 'Unexpected failure promoting runner reservation during enrollment',\n );\n return null;\n }\n });\n}\n\nexport async function attachRunnerControlProviderId(params: {\n runnerInstanceId: string;\n provisionerId: string;\n providerRunnerId: string;\n}): Promise<boolean> {\n const rows = await db()\n .update(providerRunners)\n .set({providerRunnerId: params.providerRunnerId, updatedAt: sql`now()`})\n .where(\n and(\n eq(providerRunners.id, params.runnerInstanceId),\n eq(providerRunners.provisionerId, params.provisionerId),\n isNull(providerRunners.providerRunnerId),\n notInArray(providerRunners.state, [...terminalStates]),\n ),\n )\n .returning({id: providerRunners.id});\n return rows.length === 1;\n}\n\nexport async function touchRunnerControlSession(runnerInstanceId: string, provisionerId: string) {\n await updateRunnerControlSessionLastSeen(db(), runnerInstanceId, provisionerId);\n await db()\n .update(providerRunners)\n .set({reportedAt: sql`now()`, updatedAt: sql`now()`})\n .where(\n and(\n eq(providerRunners.id, runnerInstanceId),\n eq(providerRunners.provisionerId, provisionerId),\n ),\n );\n}\n\nasync function updateRunnerControlSessionLastSeen(\n tx: Tx | NodePgDatabase<typeof schema>,\n runnerInstanceId: string,\n provisionerId: string,\n) {\n await tx\n .update(runnerControlSessions)\n .set({lastSeenAt: sql`now()`})\n .where(\n and(\n eq(runnerControlSessions.runnerInstanceId, runnerInstanceId),\n eq(runnerControlSessions.provisionerId, provisionerId),\n isNull(runnerControlSessions.closedAt),\n ),\n );\n}\n"],"names":["logger","extractDisplayPrefix","generateOpaqueToken","hashOpaqueToken","canonicalizeLabels","and","eq","gt","isNull","notInArray","or","sql","config","ReservationExpiredError","ReservationNotFoundError","RunnerInstanceAlreadyAssignedError","RunnerInstanceNotAssignableError","db","assignRunnerInstancesTx","terminalStates","provisionerTokens","runnerBootstrapTokens","runnerControlSessions","providerRunners","issueRunnerActivationTokenTx","RunnerBootstrapTokenInvalidError","Error","name","RunnerControlSessionInvalidError","createRunnerInstancesWithBootstrapTokens","params","expiresAt","Date","now","ttlSeconds","transaction","tx","instances","insert","values","runnerInstances","map","runner","provisionerId","providerKind","templateKey","intendedReservationId","reservationId","state","labels","reportedAt","returning","id","results","instance","runnerInstanceId","bootstrapToken","result","hashedToken","prefix","exchangeRunnerBootstrapToken","controlSessionToken","bootstrap","update","set","consumedAt","where","rawToken","revokedAt","session","resolveRunnerControlSession","select","from","leftJoin","closedAt","limit","enrollRunnerControlSession","current","execute","updated","protocolVersion","capabilities","updatedAt","updateRunnerControlSessionLastSeen","promotionTx","runnerInstanceIds","RUNNER_ACTIVATION_TOKEN_TTL_SECONDS","error","expectedFailure","details","err","debug","attachRunnerControlProviderId","rows","providerRunnerId","length","touchRunnerControlSession","lastSeenAt"],"mappings":"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"}
|
package/dist/db/db.d.ts
CHANGED
|
@@ -452,6 +452,23 @@ export declare const schema: {
|
|
|
452
452
|
identity: undefined;
|
|
453
453
|
generated: undefined;
|
|
454
454
|
}, {}, {}>;
|
|
455
|
+
intendedReservationId: import("drizzle-orm/pg-core").PgColumn<{
|
|
456
|
+
name: "intended_reservation_id";
|
|
457
|
+
tableName: "runner_instances";
|
|
458
|
+
dataType: "string";
|
|
459
|
+
columnType: "PgUUID";
|
|
460
|
+
data: string;
|
|
461
|
+
driverParam: string;
|
|
462
|
+
notNull: false;
|
|
463
|
+
hasDefault: false;
|
|
464
|
+
isPrimaryKey: false;
|
|
465
|
+
isAutoincrement: false;
|
|
466
|
+
hasRuntimeDefault: false;
|
|
467
|
+
enumValues: undefined;
|
|
468
|
+
baseColumn: never;
|
|
469
|
+
identity: undefined;
|
|
470
|
+
generated: undefined;
|
|
471
|
+
}, {}, {}>;
|
|
455
472
|
reservationId: import("drizzle-orm/pg-core").PgColumn<{
|
|
456
473
|
name: "reservation_id";
|
|
457
474
|
tableName: "runner_instances";
|
|
@@ -3511,6 +3528,23 @@ export declare function db(): NodePgDatabase<{
|
|
|
3511
3528
|
identity: undefined;
|
|
3512
3529
|
generated: undefined;
|
|
3513
3530
|
}, {}, {}>;
|
|
3531
|
+
intendedReservationId: import("drizzle-orm/pg-core").PgColumn<{
|
|
3532
|
+
name: "intended_reservation_id";
|
|
3533
|
+
tableName: "runner_instances";
|
|
3534
|
+
dataType: "string";
|
|
3535
|
+
columnType: "PgUUID";
|
|
3536
|
+
data: string;
|
|
3537
|
+
driverParam: string;
|
|
3538
|
+
notNull: false;
|
|
3539
|
+
hasDefault: false;
|
|
3540
|
+
isPrimaryKey: false;
|
|
3541
|
+
isAutoincrement: false;
|
|
3542
|
+
hasRuntimeDefault: false;
|
|
3543
|
+
enumValues: undefined;
|
|
3544
|
+
baseColumn: never;
|
|
3545
|
+
identity: undefined;
|
|
3546
|
+
generated: undefined;
|
|
3547
|
+
}, {}, {}>;
|
|
3514
3548
|
reservationId: import("drizzle-orm/pg-core").PgColumn<{
|
|
3515
3549
|
name: "reservation_id";
|
|
3516
3550
|
tableName: "runner_instances";
|