@shipfox/api-runners 5.0.0 → 6.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 +6 -6
- package/CHANGELOG.md +61 -0
- package/dist/config.d.ts +5 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +53 -6
- package/dist/config.js.map +1 -1
- package/dist/core/capacity-assignments.d.ts +7 -0
- package/dist/core/capacity-assignments.d.ts.map +1 -0
- package/dist/core/capacity-assignments.js +6 -0
- package/dist/core/capacity-assignments.js.map +1 -0
- package/dist/core/demand.d.ts +6 -6
- package/dist/core/demand.d.ts.map +1 -1
- package/dist/core/demand.js +10 -10
- package/dist/core/demand.js.map +1 -1
- package/dist/core/entities/capacity-assignment.d.ts +9 -0
- package/dist/core/entities/capacity-assignment.d.ts.map +1 -0
- package/dist/core/entities/capacity-assignment.js +3 -0
- package/dist/core/entities/capacity-assignment.js.map +1 -0
- package/dist/core/entities/ephemeral-registration-token.d.ts +1 -1
- package/dist/core/entities/ephemeral-registration-token.d.ts.map +1 -1
- package/dist/core/entities/ephemeral-registration-token.js.map +1 -1
- package/dist/core/entities/provisioner-capability-snapshot.d.ts +13 -0
- package/dist/core/entities/provisioner-capability-snapshot.d.ts.map +1 -0
- package/dist/core/entities/provisioner-capability-snapshot.js +3 -0
- package/dist/core/entities/provisioner-capability-snapshot.js.map +1 -0
- package/dist/core/entities/provisioner-token.d.ts +10 -2
- package/dist/core/entities/provisioner-token.d.ts.map +1 -1
- package/dist/core/entities/provisioner-token.js.map +1 -1
- package/dist/core/entities/{provisioned-runner.d.ts → runner-instance.d.ts} +6 -6
- package/dist/core/entities/runner-instance.d.ts.map +1 -0
- package/dist/core/entities/runner-instance.js +3 -0
- package/dist/core/entities/runner-instance.js.map +1 -0
- package/dist/core/entities/runner-session.d.ts +4 -2
- package/dist/core/entities/runner-session.d.ts.map +1 -1
- package/dist/core/entities/runner-session.js.map +1 -1
- package/dist/core/ephemeral-registration-tokens.d.ts +5 -5
- package/dist/core/ephemeral-registration-tokens.d.ts.map +1 -1
- package/dist/core/ephemeral-registration-tokens.js +12 -12
- package/dist/core/ephemeral-registration-tokens.js.map +1 -1
- package/dist/core/errors.d.ts +16 -4
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +22 -4
- package/dist/core/errors.js.map +1 -1
- package/dist/core/index.d.ts +10 -4
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +6 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/job-executions.d.ts +2 -0
- package/dist/core/job-executions.d.ts.map +1 -1
- package/dist/core/job-executions.js +1 -2
- package/dist/core/job-executions.js.map +1 -1
- package/dist/core/maintenance.d.ts +1 -1
- package/dist/core/maintenance.d.ts.map +1 -1
- package/dist/core/maintenance.js +5 -5
- package/dist/core/maintenance.js.map +1 -1
- package/dist/core/provisioner-capability-snapshots.d.ts +5 -0
- package/dist/core/provisioner-capability-snapshots.d.ts.map +1 -0
- package/dist/core/provisioner-capability-snapshots.js +10 -0
- package/dist/core/provisioner-capability-snapshots.js.map +1 -0
- package/dist/core/provisioner-tokens.d.ts +10 -0
- package/dist/core/provisioner-tokens.d.ts.map +1 -1
- package/dist/core/provisioner-tokens.js +23 -1
- package/dist/core/provisioner-tokens.js.map +1 -1
- package/dist/core/rate-limit.d.ts.map +1 -1
- package/dist/core/rate-limit.js +2 -7
- package/dist/core/rate-limit.js.map +1 -1
- package/dist/core/runner-activation.d.ts +13 -0
- package/dist/core/runner-activation.d.ts.map +1 -0
- package/dist/core/runner-activation.js +36 -0
- package/dist/core/runner-activation.js.map +1 -0
- package/dist/core/runner-control-sessions.d.ts +46 -0
- package/dist/core/runner-control-sessions.d.ts.map +1 -0
- package/dist/core/runner-control-sessions.js +121 -0
- package/dist/core/runner-control-sessions.js.map +1 -0
- package/dist/core/runner-instances.d.ts +79 -0
- package/dist/core/runner-instances.d.ts.map +1 -0
- package/dist/core/runner-instances.js +168 -0
- package/dist/core/runner-instances.js.map +1 -0
- package/dist/core/runner-sessions.d.ts +8 -2
- package/dist/core/runner-sessions.d.ts.map +1 -1
- package/dist/core/runner-sessions.js +8 -5
- package/dist/core/runner-sessions.js.map +1 -1
- package/dist/db/capacity-assignments.d.ts +7 -0
- package/dist/db/capacity-assignments.d.ts.map +1 -0
- package/dist/db/capacity-assignments.js +72 -0
- package/dist/db/capacity-assignments.js.map +1 -0
- package/dist/db/db.d.ts +2837 -1009
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/db.js +11 -2
- package/dist/db/db.js.map +1 -1
- package/dist/db/ephemeral-registration-tokens.d.ts +2 -2
- package/dist/db/ephemeral-registration-tokens.d.ts.map +1 -1
- package/dist/db/ephemeral-registration-tokens.js +21 -21
- package/dist/db/ephemeral-registration-tokens.js.map +1 -1
- package/dist/db/index.d.ts +7 -4
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +5 -2
- package/dist/db/index.js.map +1 -1
- package/dist/db/job-executions.d.ts +6 -6
- package/dist/db/job-executions.d.ts.map +1 -1
- package/dist/db/job-executions.js +20 -19
- package/dist/db/job-executions.js.map +1 -1
- package/dist/db/provisioner-capability-snapshots.d.ts +21 -0
- package/dist/db/provisioner-capability-snapshots.d.ts.map +1 -0
- package/dist/db/provisioner-capability-snapshots.js +57 -0
- package/dist/db/provisioner-capability-snapshots.js.map +1 -0
- package/dist/db/provisioner-tokens.d.ts +7 -2
- package/dist/db/provisioner-tokens.d.ts.map +1 -1
- package/dist/db/provisioner-tokens.js +59 -10
- package/dist/db/provisioner-tokens.js.map +1 -1
- package/dist/db/reservations.d.ts +18 -0
- package/dist/db/reservations.d.ts.map +1 -1
- package/dist/db/reservations.js +88 -1
- package/dist/db/reservations.js.map +1 -1
- package/dist/db/runner-instances.d.ts +91 -0
- package/dist/db/runner-instances.d.ts.map +1 -0
- package/dist/db/runner-instances.js +511 -0
- package/dist/db/runner-instances.js.map +1 -0
- package/dist/db/runner-sessions.d.ts +5 -0
- package/dist/db/runner-sessions.d.ts.map +1 -1
- package/dist/db/runner-sessions.js +48 -2
- package/dist/db/runner-sessions.js.map +1 -1
- package/dist/db/schema/capacity-assignments.d.ts +113 -0
- package/dist/db/schema/capacity-assignments.d.ts.map +1 -0
- package/dist/db/schema/capacity-assignments.js +29 -0
- package/dist/db/schema/capacity-assignments.js.map +1 -0
- package/dist/db/schema/ephemeral-registration-tokens.d.ts +2 -2
- package/dist/db/schema/ephemeral-registration-tokens.js +3 -3
- package/dist/db/schema/ephemeral-registration-tokens.js.map +1 -1
- package/dist/db/schema/provisioner-capability-snapshots.d.ts +207 -0
- package/dist/db/schema/provisioner-capability-snapshots.d.ts.map +1 -0
- package/dist/db/schema/provisioner-capability-snapshots.js +38 -0
- package/dist/db/schema/provisioner-capability-snapshots.js.map +1 -0
- package/dist/db/schema/provisioner-tokens.d.ts +19 -1
- package/dist/db/schema/provisioner-tokens.d.ts.map +1 -1
- package/dist/db/schema/provisioner-tokens.js +29 -3
- package/dist/db/schema/provisioner-tokens.js.map +1 -1
- package/dist/db/schema/runner-activation-tokens.d.ts +161 -0
- package/dist/db/schema/runner-activation-tokens.d.ts.map +1 -0
- package/dist/db/schema/runner-activation-tokens.js +27 -0
- package/dist/db/schema/runner-activation-tokens.js.map +1 -0
- package/dist/db/schema/runner-control-sessions.d.ts +338 -0
- package/dist/db/schema/runner-control-sessions.d.ts.map +1 -0
- package/dist/db/schema/runner-control-sessions.js +52 -0
- package/dist/db/schema/runner-control-sessions.js.map +1 -0
- package/dist/db/schema/{provisioned-runners.d.ts → runner-instances.d.ts} +88 -34
- package/dist/db/schema/runner-instances.d.ts.map +1 -0
- package/dist/db/schema/{provisioned-runners.js → runner-instances.js} +19 -14
- package/dist/db/schema/runner-instances.js.map +1 -0
- package/dist/db/schema/runner-sessions.d.ts +39 -5
- package/dist/db/schema/runner-sessions.d.ts.map +1 -1
- package/dist/db/schema/runner-sessions.js +13 -6
- package/dist/db/schema/runner-sessions.js.map +1 -1
- package/dist/db/schema/running-job-executions.d.ts +2 -2
- package/dist/db/schema/running-job-executions.js +4 -4
- package/dist/db/schema/running-job-executions.js.map +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +45 -38
- package/dist/index.js.map +1 -1
- package/dist/installation-provisioning.d.ts +14 -0
- package/dist/installation-provisioning.d.ts.map +1 -0
- package/dist/installation-provisioning.js +7 -0
- package/dist/installation-provisioning.js.map +1 -0
- package/dist/metrics/index.d.ts +1 -1
- package/dist/metrics/index.d.ts.map +1 -1
- package/dist/metrics/index.js +1 -1
- package/dist/metrics/index.js.map +1 -1
- package/dist/metrics/instance.d.ts +11 -7
- package/dist/metrics/instance.d.ts.map +1 -1
- package/dist/metrics/instance.js +13 -7
- package/dist/metrics/instance.js.map +1 -1
- package/dist/presentation/auth/index.d.ts +1 -0
- package/dist/presentation/auth/index.d.ts.map +1 -1
- package/dist/presentation/auth/index.js +1 -0
- package/dist/presentation/auth/index.js.map +1 -1
- package/dist/presentation/auth/provisioner-token-auth.d.ts.map +1 -1
- package/dist/presentation/auth/provisioner-token-auth.js +5 -1
- package/dist/presentation/auth/provisioner-token-auth.js.map +1 -1
- package/dist/presentation/auth/runner-control-session-auth.d.ts +4 -0
- package/dist/presentation/auth/runner-control-session-auth.d.ts.map +1 -0
- package/dist/presentation/auth/runner-control-session-auth.js +29 -0
- package/dist/presentation/auth/runner-control-session-auth.js.map +1 -0
- package/dist/presentation/auth/runner-registration-token-auth.d.ts +5 -1
- package/dist/presentation/auth/runner-registration-token-auth.d.ts.map +1 -1
- package/dist/presentation/auth/runner-registration-token-auth.js +21 -1
- package/dist/presentation/auth/runner-registration-token-auth.js.map +1 -1
- package/dist/presentation/dto/index.d.ts +2 -2
- package/dist/presentation/dto/index.d.ts.map +1 -1
- package/dist/presentation/dto/index.js +2 -2
- package/dist/presentation/dto/index.js.map +1 -1
- package/dist/presentation/dto/mint-registration-tokens.d.ts +5 -3
- package/dist/presentation/dto/mint-registration-tokens.d.ts.map +1 -1
- package/dist/presentation/dto/mint-registration-tokens.js +4 -4
- package/dist/presentation/dto/mint-registration-tokens.js.map +1 -1
- package/dist/presentation/dto/poll-demand.d.ts.map +1 -1
- package/dist/presentation/dto/poll-demand.js +7 -1
- package/dist/presentation/dto/poll-demand.js.map +1 -1
- package/dist/presentation/dto/provisioner-token.d.ts +1 -0
- package/dist/presentation/dto/provisioner-token.d.ts.map +1 -1
- package/dist/presentation/dto/provisioner-token.js +5 -1
- package/dist/presentation/dto/provisioner-token.js.map +1 -1
- package/dist/presentation/dto/{provisioned-runners.d.ts → runner-instances.d.ts} +9 -9
- package/dist/presentation/dto/runner-instances.d.ts.map +1 -0
- package/dist/presentation/dto/{provisioned-runners.js → runner-instances.js} +6 -6
- package/dist/presentation/dto/runner-instances.js.map +1 -0
- package/dist/presentation/index.d.ts +2 -2
- package/dist/presentation/index.d.ts.map +1 -1
- package/dist/presentation/index.js +2 -2
- package/dist/presentation/index.js.map +1 -1
- package/dist/presentation/inter-module.d.ts +5 -0
- package/dist/presentation/inter-module.d.ts.map +1 -0
- package/dist/presentation/inter-module.js +43 -0
- package/dist/presentation/inter-module.js.map +1 -0
- package/dist/presentation/routes/assign-capacity.d.ts +2 -0
- package/dist/presentation/routes/assign-capacity.d.ts.map +1 -0
- package/dist/presentation/routes/assign-capacity.js +44 -0
- package/dist/presentation/routes/assign-capacity.js.map +1 -0
- package/dist/presentation/routes/get-provisioner-me.d.ts.map +1 -1
- package/dist/presentation/routes/get-provisioner-me.js +5 -1
- package/dist/presentation/routes/get-provisioner-me.js.map +1 -1
- package/dist/presentation/routes/heartbeat.d.ts +2 -1
- package/dist/presentation/routes/heartbeat.d.ts.map +1 -1
- package/dist/presentation/routes/heartbeat.js +60 -50
- package/dist/presentation/routes/heartbeat.js.map +1 -1
- package/dist/presentation/routes/index.d.ts +3 -1
- package/dist/presentation/routes/index.d.ts.map +1 -1
- package/dist/presentation/routes/index.js +83 -50
- package/dist/presentation/routes/index.js.map +1 -1
- package/dist/presentation/routes/mint-registration-tokens.d.ts.map +1 -1
- package/dist/presentation/routes/mint-registration-tokens.js +5 -5
- package/dist/presentation/routes/mint-registration-tokens.js.map +1 -1
- package/dist/presentation/routes/planned-capacity.d.ts +3 -0
- package/dist/presentation/routes/planned-capacity.d.ts.map +1 -0
- package/dist/presentation/routes/planned-capacity.js +54 -0
- package/dist/presentation/routes/planned-capacity.js.map +1 -0
- package/dist/presentation/routes/poll-demand.d.ts +2 -0
- package/dist/presentation/routes/poll-demand.d.ts.map +1 -1
- package/dist/presentation/routes/poll-demand.js +86 -45
- package/dist/presentation/routes/poll-demand.js.map +1 -1
- package/dist/presentation/routes/reconcile-runner-instances.d.ts +2 -0
- package/dist/presentation/routes/reconcile-runner-instances.d.ts.map +1 -0
- package/dist/presentation/routes/reconcile-runner-instances.js +27 -0
- package/dist/presentation/routes/reconcile-runner-instances.js.map +1 -0
- package/dist/presentation/routes/register.d.ts +2 -1
- package/dist/presentation/routes/register.d.ts.map +1 -1
- package/dist/presentation/routes/register.js +55 -52
- package/dist/presentation/routes/register.js.map +1 -1
- package/dist/presentation/routes/report-runner-instances.d.ts +2 -0
- package/dist/presentation/routes/report-runner-instances.d.ts.map +1 -0
- package/dist/presentation/routes/report-runner-instances.js +37 -0
- package/dist/presentation/routes/report-runner-instances.js.map +1 -0
- package/dist/presentation/routes/request-job.d.ts +2 -1
- package/dist/presentation/routes/request-job.d.ts.map +1 -1
- package/dist/presentation/routes/request-job.js +39 -36
- package/dist/presentation/routes/request-job.js.map +1 -1
- package/dist/presentation/routes/runner-enrollment.d.ts +7 -0
- package/dist/presentation/routes/runner-enrollment.d.ts.map +1 -0
- package/dist/presentation/routes/runner-enrollment.js +185 -0
- package/dist/presentation/routes/runner-enrollment.js.map +1 -0
- package/dist/temporal/activities/index.d.ts +2 -2
- package/dist/temporal/activities/index.d.ts.map +1 -1
- package/dist/temporal/activities/index.js +2 -2
- package/dist/temporal/activities/index.js.map +1 -1
- package/dist/temporal/activities/maintenance-activities.d.ts +1 -1
- package/dist/temporal/activities/maintenance-activities.d.ts.map +1 -1
- package/dist/temporal/activities/maintenance-activities.js +3 -3
- package/dist/temporal/activities/maintenance-activities.js.map +1 -1
- package/dist/temporal/workflows/index.bundle.js +3 -3
- package/dist/temporal/workflows/stuck-job-detector.js +2 -2
- package/dist/temporal/workflows/stuck-job-detector.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/drizzle/0000_initial.sql +102 -24
- package/drizzle/meta/0000_snapshot.json +483 -63
- package/package.json +21 -16
- package/src/config.test.ts +0 -26
- package/src/config.ts +47 -6
- package/src/core/capacity-assignments.ts +10 -0
- package/src/core/demand.test.ts +29 -29
- package/src/core/demand.ts +22 -22
- package/src/core/entities/capacity-assignment.ts +8 -0
- package/src/core/entities/ephemeral-registration-token.ts +1 -1
- package/src/core/entities/provisioner-capability-snapshot.ts +12 -0
- package/src/core/entities/provisioner-token.ts +8 -2
- package/src/core/entities/{provisioned-runner.ts → runner-instance.ts} +5 -5
- package/src/core/entities/runner-session.ts +4 -2
- package/src/core/ephemeral-registration-tokens.test.ts +11 -11
- package/src/core/ephemeral-registration-tokens.ts +18 -20
- package/src/core/errors.ts +23 -4
- package/src/core/index.ts +39 -17
- package/src/core/job-executions.ts +3 -2
- package/src/core/maintenance.test.ts +13 -17
- package/src/core/maintenance.ts +5 -5
- package/src/core/provisioner-capability-snapshots.test.ts +35 -0
- package/src/core/provisioner-capability-snapshots.ts +12 -0
- package/src/core/provisioner-tokens.test.ts +20 -0
- package/src/core/provisioner-tokens.ts +33 -0
- package/src/core/rate-limit.test.ts +11 -27
- package/src/core/rate-limit.ts +3 -11
- package/src/core/runner-activation.ts +72 -0
- package/src/core/runner-control-sessions.ts +190 -0
- package/src/core/{provisioned-runners.test.ts → runner-instances.test.ts} +24 -24
- package/src/core/runner-instances.ts +310 -0
- package/src/core/runner-sessions.test.ts +112 -22
- package/src/core/runner-sessions.ts +25 -14
- package/src/db/capacity-assignments.test.ts +159 -0
- package/src/db/capacity-assignments.ts +116 -0
- package/src/db/db.ts +11 -2
- package/src/db/ephemeral-registration-tokens.test.ts +9 -9
- package/src/db/ephemeral-registration-tokens.ts +26 -26
- package/src/db/index.ts +31 -21
- package/src/db/job-executions.test.ts +13 -11
- package/src/db/job-executions.ts +33 -27
- package/src/db/provisioner-capability-snapshots.test.ts +175 -0
- package/src/db/provisioner-capability-snapshots.ts +130 -0
- package/src/db/provisioner-tokens.test.ts +139 -2
- package/src/db/provisioner-tokens.ts +123 -15
- package/src/db/reservations.test.ts +49 -0
- package/src/db/reservations.ts +146 -1
- package/src/db/{provisioned-runners.test.ts → runner-instances.test.ts} +429 -353
- package/src/db/runner-instances.ts +942 -0
- package/src/db/runner-sessions.test.ts +19 -6
- package/src/db/runner-sessions.ts +78 -2
- package/src/db/schema/capacity-assignments.ts +34 -0
- package/src/db/schema/ephemeral-registration-tokens.ts +4 -4
- package/src/db/schema/provisioner-capability-snapshots.ts +46 -0
- package/src/db/schema/provisioner-tokens.ts +33 -2
- package/src/db/schema/runner-activation-tokens.ts +22 -0
- package/src/db/schema/runner-control-sessions.ts +46 -0
- package/src/db/schema/{provisioned-runners.ts → runner-instances.ts} +26 -27
- package/src/db/schema/runner-sessions.ts +11 -7
- package/src/db/schema/running-job-executions.ts +5 -5
- package/src/index.test.ts +26 -0
- package/src/index.ts +39 -19
- package/src/installation-provisioning.ts +14 -0
- package/src/metrics/index.ts +5 -5
- package/src/metrics/instance.ts +25 -14
- package/src/presentation/auth/index.ts +4 -0
- package/src/presentation/auth/provisioner-token-auth.ts +8 -4
- package/src/presentation/auth/runner-control-session-auth.ts +31 -0
- package/src/presentation/auth/runner-registration-token-auth.ts +39 -3
- package/src/presentation/dto/index.ts +5 -5
- package/src/presentation/dto/mint-registration-tokens.ts +8 -15
- package/src/presentation/dto/poll-demand.ts +3 -1
- package/src/presentation/dto/provisioner-token.ts +5 -0
- package/src/presentation/dto/{provisioned-runners.ts → runner-instances.ts} +13 -15
- package/src/presentation/index.ts +2 -1
- package/src/presentation/inter-module.test.ts +15 -0
- package/src/presentation/inter-module.ts +53 -0
- package/src/presentation/routes/assign-capacity.ts +48 -0
- package/src/presentation/routes/get-provisioner-me.ts +3 -4
- package/src/presentation/routes/heartbeat.test.ts +4 -3
- package/src/presentation/routes/heartbeat.ts +67 -64
- package/src/presentation/routes/index.ts +93 -43
- package/src/presentation/routes/list-active-runners.test.ts +23 -23
- package/src/presentation/routes/manual-registration-tokens.test.ts +4 -3
- package/src/presentation/routes/mint-registration-tokens.test.ts +12 -12
- package/src/presentation/routes/mint-registration-tokens.ts +5 -7
- package/src/presentation/routes/planned-capacity.ts +49 -0
- package/src/presentation/routes/poll-demand-release.test.ts +4 -4
- package/src/presentation/routes/poll-demand.test.ts +161 -22
- package/src/presentation/routes/poll-demand.ts +105 -45
- package/src/presentation/routes/provisioner-me.test.ts +37 -3
- package/src/presentation/routes/{reconcile-provisioned-runners.test.ts → reconcile-runner-instances.test.ts} +66 -61
- package/src/presentation/routes/reconcile-runner-instances.ts +30 -0
- package/src/presentation/routes/register.test.ts +9 -5
- package/src/presentation/routes/register.ts +61 -57
- package/src/presentation/routes/{report-provisioned-runners.test.ts → report-runner-instances.test.ts} +28 -28
- package/src/presentation/routes/{report-provisioned-runners.ts → report-runner-instances.ts} +14 -14
- package/src/presentation/routes/request-job.test.ts +5 -3
- package/src/presentation/routes/request-job.ts +41 -37
- package/src/presentation/routes/runner-enrollment.test.ts +259 -0
- package/src/presentation/routes/runner-enrollment.ts +174 -0
- package/src/temporal/activities/index.ts +2 -2
- package/src/temporal/activities/maintenance-activities.test.ts +7 -7
- package/src/temporal/activities/maintenance-activities.ts +3 -3
- package/src/temporal/workflows/stuck-job-detector.test.ts +3 -3
- package/src/temporal/workflows/stuck-job-detector.ts +2 -2
- package/test/env.ts +1 -3
- package/test/factories/ephemeral-registration-token.ts +2 -2
- package/test/factories/provisioner-token.ts +3 -1
- package/test/factories/runner-instance.ts +57 -0
- package/test/factories/runner-session.ts +3 -1
- package/test/fixtures/auth-inter-module.ts +30 -0
- package/test/globalSetup.ts +5 -1
- package/test/index.ts +2 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/dist/core/entities/provisioned-runner.d.ts.map +0 -1
- package/dist/core/entities/provisioned-runner.js +0 -3
- package/dist/core/entities/provisioned-runner.js.map +0 -1
- package/dist/core/provisioned-runners.d.ts +0 -67
- package/dist/core/provisioned-runners.d.ts.map +0 -1
- package/dist/core/provisioned-runners.js +0 -162
- package/dist/core/provisioned-runners.js.map +0 -1
- package/dist/db/provisioned-runners.d.ts +0 -79
- package/dist/db/provisioned-runners.d.ts.map +0 -1
- package/dist/db/provisioned-runners.js +0 -466
- package/dist/db/provisioned-runners.js.map +0 -1
- package/dist/db/schema/provisioned-runners.d.ts.map +0 -1
- package/dist/db/schema/provisioned-runners.js.map +0 -1
- package/dist/presentation/dto/provisioned-runners.d.ts.map +0 -1
- package/dist/presentation/dto/provisioned-runners.js.map +0 -1
- package/dist/presentation/routes/reconcile-provisioned-runners.d.ts +0 -2
- package/dist/presentation/routes/reconcile-provisioned-runners.d.ts.map +0 -1
- package/dist/presentation/routes/reconcile-provisioned-runners.js +0 -27
- package/dist/presentation/routes/reconcile-provisioned-runners.js.map +0 -1
- package/dist/presentation/routes/report-provisioned-runners.d.ts +0 -2
- package/dist/presentation/routes/report-provisioned-runners.d.ts.map +0 -1
- package/dist/presentation/routes/report-provisioned-runners.js +0 -37
- package/dist/presentation/routes/report-provisioned-runners.js.map +0 -1
- package/src/core/provisioned-runners.ts +0 -301
- package/src/db/provisioned-runners.ts +0 -886
- package/src/presentation/routes/reconcile-provisioned-runners.ts +0 -30
- package/test/factories/provisioned-runner.ts +0 -78
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/maintenance.ts"],"sourcesContent":["import {config} from '#config.js';\nimport {deleteExpiredEphemeralRegistrationTokens as deleteExpiredEphemeralRegistrationTokensDb} from '#db/ephemeral-registration-tokens.js';\nimport {expireStuckJobExecutions} from '#db/job-executions.js';\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/core/maintenance.ts"],"sourcesContent":["import {config} from '#config.js';\nimport {deleteExpiredEphemeralRegistrationTokens as deleteExpiredEphemeralRegistrationTokensDb} from '#db/ephemeral-registration-tokens.js';\nimport {expireStuckJobExecutions} from '#db/job-executions.js';\nimport {deleteExpiredReservations} from '#db/reservations.js';\nimport {reapStaleRunnerInstances as reapStaleRunnerInstancesDb} from '#db/runner-instances.js';\nimport {deleteExpiredRunnerSessions as deleteExpiredRunnerSessionsDb} from '#db/runner-sessions.js';\nimport {providerRunnerReapedCount, reservationReleasedCount} from '#metrics/instance.js';\nimport {STUCK_JOB_THRESHOLD_SECONDS} from './maintenance-policy.js';\n\nexport interface DetectAndExpireStuckJobsParams {\n noFirstHeartbeatGraceSeconds?: number;\n thresholdSeconds?: number;\n}\n\nexport async function detectAndExpireStuckJobs(\n params: DetectAndExpireStuckJobsParams = {},\n): Promise<{expired: number}> {\n const reaped = await expireStuckJobExecutions({\n noFirstHeartbeatGraceSeconds:\n params.noFirstHeartbeatGraceSeconds ?? config.RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS,\n thresholdSeconds: params.thresholdSeconds ?? STUCK_JOB_THRESHOLD_SECONDS,\n });\n return {expired: reaped.length};\n}\n\nexport async function deleteExpiredRunnerReservations(params?: {\n limit?: number;\n}): Promise<{deleted: number}> {\n const deleted = await deleteExpiredReservations(params);\n return {deleted};\n}\n\nexport async function reapStaleRunnerInstances(params?: {\n thresholdSeconds?: number;\n limit?: number;\n}): Promise<{reaped: number; reservationsReleased: number}> {\n const result = await reapStaleRunnerInstancesDb({\n thresholdSeconds:\n params?.thresholdSeconds ?? config.RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS,\n limit: params?.limit ?? config.RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT,\n });\n\n if (result.reaped > 0) providerRunnerReapedCount.add(result.reaped);\n if (result.reservationsReleased > 0) {\n reservationReleasedCount.add(result.reservationsReleased);\n }\n\n return result;\n}\n\nexport async function deleteExpiredRunnerSessions(params?: {\n manualRetentionDays?: number;\n ephemeralRetentionDays?: number;\n limit?: number;\n}): Promise<{deleted: number}> {\n const deleted = await deleteExpiredRunnerSessionsDb({\n manualRetentionDays: params?.manualRetentionDays ?? config.RUNNER_SESSION_MANUAL_RETENTION_DAYS,\n ephemeralRetentionDays:\n params?.ephemeralRetentionDays ?? config.RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS,\n limit: params?.limit ?? config.RUNNER_SESSION_GC_BATCH_SIZE,\n });\n return {deleted};\n}\n\nexport async function deleteExpiredEphemeralRegistrationTokens(params?: {\n retentionDays?: number;\n limit?: number;\n}): Promise<{deleted: number}> {\n const deleted = await deleteExpiredEphemeralRegistrationTokensDb({\n retentionDays: params?.retentionDays ?? config.RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS,\n limit: params?.limit ?? config.RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE,\n });\n return {deleted};\n}\n"],"names":["config","deleteExpiredEphemeralRegistrationTokens","deleteExpiredEphemeralRegistrationTokensDb","expireStuckJobExecutions","deleteExpiredReservations","reapStaleRunnerInstances","reapStaleRunnerInstancesDb","deleteExpiredRunnerSessions","deleteExpiredRunnerSessionsDb","providerRunnerReapedCount","reservationReleasedCount","STUCK_JOB_THRESHOLD_SECONDS","detectAndExpireStuckJobs","params","reaped","noFirstHeartbeatGraceSeconds","RUNNER_NO_FIRST_HEARTBEAT_GRACE_SECONDS","thresholdSeconds","expired","length","deleteExpiredRunnerReservations","deleted","result","RUNNER_STALE_PROVISIONED_RUNNER_THRESHOLD_SECONDS","limit","RUNNER_STALE_PROVISIONED_RUNNER_REAPER_LIMIT","add","reservationsReleased","manualRetentionDays","RUNNER_SESSION_MANUAL_RETENTION_DAYS","ephemeralRetentionDays","RUNNER_SESSION_EPHEMERAL_RETENTION_DAYS","RUNNER_SESSION_GC_BATCH_SIZE","retentionDays","RUNNER_EPHEMERAL_TOKEN_RETENTION_DAYS","RUNNER_EPHEMERAL_TOKEN_GC_BATCH_SIZE"],"mappings":"AAAA,SAAQA,MAAM,QAAO,aAAa;AAClC,SAAQC,4CAA4CC,0CAA0C,QAAO,uCAAuC;AAC5I,SAAQC,wBAAwB,QAAO,wBAAwB;AAC/D,SAAQC,yBAAyB,QAAO,sBAAsB;AAC9D,SAAQC,4BAA4BC,0BAA0B,QAAO,0BAA0B;AAC/F,SAAQC,+BAA+BC,6BAA6B,QAAO,yBAAyB;AACpG,SAAQC,yBAAyB,EAAEC,wBAAwB,QAAO,uBAAuB;AACzF,SAAQC,2BAA2B,QAAO,0BAA0B;AAOpE,OAAO,eAAeC,yBACpBC,SAAyC,CAAC,CAAC;IAE3C,MAAMC,SAAS,MAAMX,yBAAyB;QAC5CY,8BACEF,OAAOE,4BAA4B,IAAIf,OAAOgB,uCAAuC;QACvFC,kBAAkBJ,OAAOI,gBAAgB,IAAIN;IAC/C;IACA,OAAO;QAACO,SAASJ,OAAOK,MAAM;IAAA;AAChC;AAEA,OAAO,eAAeC,gCAAgCP,MAErD;IACC,MAAMQ,UAAU,MAAMjB,0BAA0BS;IAChD,OAAO;QAACQ;IAAO;AACjB;AAEA,OAAO,eAAehB,yBAAyBQ,MAG9C;IACC,MAAMS,SAAS,MAAMhB,2BAA2B;QAC9CW,kBACEJ,QAAQI,oBAAoBjB,OAAOuB,iDAAiD;QACtFC,OAAOX,QAAQW,SAASxB,OAAOyB,4CAA4C;IAC7E;IAEA,IAAIH,OAAOR,MAAM,GAAG,GAAGL,0BAA0BiB,GAAG,CAACJ,OAAOR,MAAM;IAClE,IAAIQ,OAAOK,oBAAoB,GAAG,GAAG;QACnCjB,yBAAyBgB,GAAG,CAACJ,OAAOK,oBAAoB;IAC1D;IAEA,OAAOL;AACT;AAEA,OAAO,eAAef,4BAA4BM,MAIjD;IACC,MAAMQ,UAAU,MAAMb,8BAA8B;QAClDoB,qBAAqBf,QAAQe,uBAAuB5B,OAAO6B,oCAAoC;QAC/FC,wBACEjB,QAAQiB,0BAA0B9B,OAAO+B,uCAAuC;QAClFP,OAAOX,QAAQW,SAASxB,OAAOgC,4BAA4B;IAC7D;IACA,OAAO;QAACX;IAAO;AACjB;AAEA,OAAO,eAAepB,yCAAyCY,MAG9D;IACC,MAAMQ,UAAU,MAAMnB,2CAA2C;QAC/D+B,eAAepB,QAAQoB,iBAAiBjC,OAAOkC,qCAAqC;QACpFV,OAAOX,QAAQW,SAASxB,OAAOmC,oCAAoC;IACrE;IACA,OAAO;QAACd;IAAO;AACjB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provisioner-capability-snapshots.d.ts","sourceRoot":"","sources":["../../src/core/provisioner-capability-snapshots.ts"],"names":[],"mappings":"AAGA,wBAAgB,uCAAuC,CAAC,MAAM,EAAE;IAC9D,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,GAAG,OAAO,CAAC,OAAO,CAAC,CAKnB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { config } from '#config.js';
|
|
2
|
+
import { hasActiveWorkspaceProvisionerCapability as hasActiveWorkspaceProvisionerCapabilityDb } from '#db/provisioner-capability-snapshots.js';
|
|
3
|
+
export function hasActiveWorkspaceProvisionerCapability(params) {
|
|
4
|
+
return hasActiveWorkspaceProvisionerCapabilityDb({
|
|
5
|
+
...params,
|
|
6
|
+
windowSeconds: config.PROVISIONER_ACTIVE_WINDOW_SECONDS
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=provisioner-capability-snapshots.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/provisioner-capability-snapshots.ts"],"sourcesContent":["import {config} from '#config.js';\nimport {hasActiveWorkspaceProvisionerCapability as hasActiveWorkspaceProvisionerCapabilityDb} from '#db/provisioner-capability-snapshots.js';\n\nexport function hasActiveWorkspaceProvisionerCapability(params: {\n workspaceId: string;\n requiredLabels: string[];\n}): Promise<boolean> {\n return hasActiveWorkspaceProvisionerCapabilityDb({\n ...params,\n windowSeconds: config.PROVISIONER_ACTIVE_WINDOW_SECONDS,\n });\n}\n"],"names":["config","hasActiveWorkspaceProvisionerCapability","hasActiveWorkspaceProvisionerCapabilityDb","params","windowSeconds","PROVISIONER_ACTIVE_WINDOW_SECONDS"],"mappings":"AAAA,SAAQA,MAAM,QAAO,aAAa;AAClC,SAAQC,2CAA2CC,yCAAyC,QAAO,0CAA0C;AAE7I,OAAO,SAASD,wCAAwCE,MAGvD;IACC,OAAOD,0CAA0C;QAC/C,GAAGC,MAAM;QACTC,eAAeJ,OAAOK,iCAAiC;IACzD;AACF"}
|
|
@@ -10,6 +10,12 @@ export interface CreateWorkspaceProvisionerTokenResult {
|
|
|
10
10
|
rawToken: string;
|
|
11
11
|
}
|
|
12
12
|
export declare function createWorkspaceProvisionerToken(params: CreateWorkspaceProvisionerTokenParams): Promise<CreateWorkspaceProvisionerTokenResult>;
|
|
13
|
+
export interface CreateInstallationProvisionerTokenParams {
|
|
14
|
+
createdByUserId: string;
|
|
15
|
+
name?: string | undefined;
|
|
16
|
+
ttlSeconds?: number | undefined;
|
|
17
|
+
}
|
|
18
|
+
export declare function createInstallationProvisionerToken(params: CreateInstallationProvisionerTokenParams): Promise<CreateWorkspaceProvisionerTokenResult>;
|
|
13
19
|
export declare function listUsableProvisionerTokens(workspaceId: string): Promise<ProvisionerToken[]>;
|
|
14
20
|
export declare function listActiveProvisioners(workspaceId: string): Promise<ActiveProvisionerToken[]>;
|
|
15
21
|
export declare function revokeWorkspaceProvisionerToken(params: {
|
|
@@ -17,4 +23,8 @@ export declare function revokeWorkspaceProvisionerToken(params: {
|
|
|
17
23
|
workspaceId: string;
|
|
18
24
|
revokedByUserId: string;
|
|
19
25
|
}): Promise<ProvisionerToken>;
|
|
26
|
+
export declare function revokeInstallationProvisionerToken(params: {
|
|
27
|
+
tokenId: string;
|
|
28
|
+
revokedByUserId: string;
|
|
29
|
+
}): Promise<ProvisionerToken>;
|
|
20
30
|
//# sourceMappingURL=provisioner-tokens.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provisioner-tokens.d.ts","sourceRoot":"","sources":["../../src/core/provisioner-tokens.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"provisioner-tokens.d.ts","sourceRoot":"","sources":["../../src/core/provisioner-tokens.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAC,sBAAsB,EAAE,gBAAgB,EAAC,MAAM,iCAAiC,CAAC;AAG9F,MAAM,WAAW,qCAAqC;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAED,MAAM,WAAW,qCAAqC;IACpD,KAAK,EAAE,gBAAgB,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,qCAAqC,GAC5C,OAAO,CAAC,qCAAqC,CAAC,CAehD;AAED,MAAM,WAAW,wCAAwC;IACvD,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAED,wBAAsB,kCAAkC,CACtD,MAAM,EAAE,wCAAwC,GAC/C,OAAO,CAAC,qCAAqC,CAAC,CAYhD;AAED,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAE5F;AAED,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAK7F;AAED,wBAAsB,+BAA+B,CAAC,MAAM,EAAE;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAI5B;AAED,wBAAsB,kCAAkC,CAAC,MAAM,EAAE;IAC/D,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAI5B"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken } from '@shipfox/node-tokens';
|
|
2
|
-
import { createProvisionerToken, listActiveProvisionerTokens, listUsableProvisionerTokensByWorkspaceId, revokeProvisionerToken } from '#db/provisioner-tokens.js';
|
|
2
|
+
import { createProvisionerToken, listActiveProvisionerTokens, listUsableProvisionerTokensByWorkspaceId, revokeInstallationProvisionerToken as revokeInstallationProvisionerTokenDb, revokeProvisionerToken } from '#db/provisioner-tokens.js';
|
|
3
3
|
import { config } from '../config.js';
|
|
4
4
|
import { ProvisionerTokenNotFoundError } from './errors.js';
|
|
5
5
|
export async function createWorkspaceProvisionerToken(params) {
|
|
6
6
|
const rawToken = generateOpaqueToken('provisionerToken');
|
|
7
7
|
const expiresAt = params.ttlSeconds ? new Date(Date.now() + params.ttlSeconds * 1000) : undefined;
|
|
8
8
|
const token = await createProvisionerToken({
|
|
9
|
+
scope: 'workspace',
|
|
9
10
|
workspaceId: params.workspaceId,
|
|
10
11
|
hashedToken: hashOpaqueToken(rawToken),
|
|
11
12
|
prefix: extractDisplayPrefix(rawToken),
|
|
@@ -18,6 +19,22 @@ export async function createWorkspaceProvisionerToken(params) {
|
|
|
18
19
|
rawToken
|
|
19
20
|
};
|
|
20
21
|
}
|
|
22
|
+
export async function createInstallationProvisionerToken(params) {
|
|
23
|
+
const rawToken = generateOpaqueToken('provisionerToken');
|
|
24
|
+
const expiresAt = params.ttlSeconds ? new Date(Date.now() + params.ttlSeconds * 1000) : undefined;
|
|
25
|
+
const token = await createProvisionerToken({
|
|
26
|
+
scope: 'installation',
|
|
27
|
+
hashedToken: hashOpaqueToken(rawToken),
|
|
28
|
+
prefix: extractDisplayPrefix(rawToken),
|
|
29
|
+
name: params.name,
|
|
30
|
+
createdByUserId: params.createdByUserId,
|
|
31
|
+
expiresAt
|
|
32
|
+
});
|
|
33
|
+
return {
|
|
34
|
+
token,
|
|
35
|
+
rawToken
|
|
36
|
+
};
|
|
37
|
+
}
|
|
21
38
|
export function listUsableProvisionerTokens(workspaceId) {
|
|
22
39
|
return listUsableProvisionerTokensByWorkspaceId(workspaceId);
|
|
23
40
|
}
|
|
@@ -32,5 +49,10 @@ export async function revokeWorkspaceProvisionerToken(params) {
|
|
|
32
49
|
if (!token) throw new ProvisionerTokenNotFoundError(params.tokenId);
|
|
33
50
|
return token;
|
|
34
51
|
}
|
|
52
|
+
export async function revokeInstallationProvisionerToken(params) {
|
|
53
|
+
const token = await revokeInstallationProvisionerTokenDb(params);
|
|
54
|
+
if (!token) throw new ProvisionerTokenNotFoundError(params.tokenId);
|
|
55
|
+
return token;
|
|
56
|
+
}
|
|
35
57
|
|
|
36
58
|
//# sourceMappingURL=provisioner-tokens.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/provisioner-tokens.ts"],"sourcesContent":["import {extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken} from '@shipfox/node-tokens';\nimport {\n createProvisionerToken,\n listActiveProvisionerTokens,\n listUsableProvisionerTokensByWorkspaceId,\n revokeProvisionerToken,\n} from '#db/provisioner-tokens.js';\nimport {config} from '../config.js';\nimport type {ActiveProvisionerToken, ProvisionerToken} from './entities/provisioner-token.js';\nimport {ProvisionerTokenNotFoundError} from './errors.js';\n\nexport interface CreateWorkspaceProvisionerTokenParams {\n workspaceId: string;\n createdByUserId: string;\n name?: string | undefined;\n ttlSeconds?: number | undefined;\n}\n\nexport interface CreateWorkspaceProvisionerTokenResult {\n token: ProvisionerToken;\n rawToken: string;\n}\n\nexport async function createWorkspaceProvisionerToken(\n params: CreateWorkspaceProvisionerTokenParams,\n): Promise<CreateWorkspaceProvisionerTokenResult> {\n const rawToken = generateOpaqueToken('provisionerToken');\n const expiresAt = params.ttlSeconds ? new Date(Date.now() + params.ttlSeconds * 1000) : undefined;\n\n const token = await createProvisionerToken({\n workspaceId: params.workspaceId,\n hashedToken: hashOpaqueToken(rawToken),\n prefix: extractDisplayPrefix(rawToken),\n name: params.name,\n createdByUserId: params.createdByUserId,\n expiresAt,\n });\n\n return {token, rawToken};\n}\n\nexport function listUsableProvisionerTokens(workspaceId: string): Promise<ProvisionerToken[]> {\n return listUsableProvisionerTokensByWorkspaceId(workspaceId);\n}\n\nexport function listActiveProvisioners(workspaceId: string): Promise<ActiveProvisionerToken[]> {\n return listActiveProvisionerTokens({\n workspaceId,\n windowSeconds: config.PROVISIONER_ACTIVE_WINDOW_SECONDS,\n });\n}\n\nexport async function revokeWorkspaceProvisionerToken(params: {\n tokenId: string;\n workspaceId: string;\n revokedByUserId: string;\n}): Promise<ProvisionerToken> {\n const token = await revokeProvisionerToken(params);\n if (!token) throw new ProvisionerTokenNotFoundError(params.tokenId);\n return token;\n}\n"],"names":["extractDisplayPrefix","generateOpaqueToken","hashOpaqueToken","createProvisionerToken","listActiveProvisionerTokens","listUsableProvisionerTokensByWorkspaceId","revokeProvisionerToken","config","ProvisionerTokenNotFoundError","createWorkspaceProvisionerToken","params","rawToken","expiresAt","ttlSeconds","Date","now","undefined","token","workspaceId","hashedToken","prefix","name","createdByUserId","listUsableProvisionerTokens","listActiveProvisioners","windowSeconds","PROVISIONER_ACTIVE_WINDOW_SECONDS","revokeWorkspaceProvisionerToken","tokenId"],"mappings":"AAAA,SAAQA,oBAAoB,EAAEC,mBAAmB,EAAEC,eAAe,QAAO,uBAAuB;AAChG,SACEC,sBAAsB,EACtBC,2BAA2B,EAC3BC,wCAAwC,EACxCC,sBAAsB,QACjB,4BAA4B;AACnC,SAAQC,MAAM,QAAO,eAAe;AAEpC,SAAQC,6BAA6B,QAAO,cAAc;AAc1D,OAAO,eAAeC,gCACpBC,MAA6C;IAE7C,MAAMC,
|
|
1
|
+
{"version":3,"sources":["../../src/core/provisioner-tokens.ts"],"sourcesContent":["import {extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken} from '@shipfox/node-tokens';\nimport {\n createProvisionerToken,\n listActiveProvisionerTokens,\n listUsableProvisionerTokensByWorkspaceId,\n revokeInstallationProvisionerToken as revokeInstallationProvisionerTokenDb,\n revokeProvisionerToken,\n} from '#db/provisioner-tokens.js';\nimport {config} from '../config.js';\nimport type {ActiveProvisionerToken, ProvisionerToken} from './entities/provisioner-token.js';\nimport {ProvisionerTokenNotFoundError} from './errors.js';\n\nexport interface CreateWorkspaceProvisionerTokenParams {\n workspaceId: string;\n createdByUserId: string;\n name?: string | undefined;\n ttlSeconds?: number | undefined;\n}\n\nexport interface CreateWorkspaceProvisionerTokenResult {\n token: ProvisionerToken;\n rawToken: string;\n}\n\nexport async function createWorkspaceProvisionerToken(\n params: CreateWorkspaceProvisionerTokenParams,\n): Promise<CreateWorkspaceProvisionerTokenResult> {\n const rawToken = generateOpaqueToken('provisionerToken');\n const expiresAt = params.ttlSeconds ? new Date(Date.now() + params.ttlSeconds * 1000) : undefined;\n\n const token = await createProvisionerToken({\n scope: 'workspace',\n workspaceId: params.workspaceId,\n hashedToken: hashOpaqueToken(rawToken),\n prefix: extractDisplayPrefix(rawToken),\n name: params.name,\n createdByUserId: params.createdByUserId,\n expiresAt,\n });\n\n return {token, rawToken};\n}\n\nexport interface CreateInstallationProvisionerTokenParams {\n createdByUserId: string;\n name?: string | undefined;\n ttlSeconds?: number | undefined;\n}\n\nexport async function createInstallationProvisionerToken(\n params: CreateInstallationProvisionerTokenParams,\n): Promise<CreateWorkspaceProvisionerTokenResult> {\n const rawToken = generateOpaqueToken('provisionerToken');\n const expiresAt = params.ttlSeconds ? new Date(Date.now() + params.ttlSeconds * 1000) : undefined;\n const token = await createProvisionerToken({\n scope: 'installation',\n hashedToken: hashOpaqueToken(rawToken),\n prefix: extractDisplayPrefix(rawToken),\n name: params.name,\n createdByUserId: params.createdByUserId,\n expiresAt,\n });\n return {token, rawToken};\n}\n\nexport function listUsableProvisionerTokens(workspaceId: string): Promise<ProvisionerToken[]> {\n return listUsableProvisionerTokensByWorkspaceId(workspaceId);\n}\n\nexport function listActiveProvisioners(workspaceId: string): Promise<ActiveProvisionerToken[]> {\n return listActiveProvisionerTokens({\n workspaceId,\n windowSeconds: config.PROVISIONER_ACTIVE_WINDOW_SECONDS,\n });\n}\n\nexport async function revokeWorkspaceProvisionerToken(params: {\n tokenId: string;\n workspaceId: string;\n revokedByUserId: string;\n}): Promise<ProvisionerToken> {\n const token = await revokeProvisionerToken(params);\n if (!token) throw new ProvisionerTokenNotFoundError(params.tokenId);\n return token;\n}\n\nexport async function revokeInstallationProvisionerToken(params: {\n tokenId: string;\n revokedByUserId: string;\n}): Promise<ProvisionerToken> {\n const token = await revokeInstallationProvisionerTokenDb(params);\n if (!token) throw new ProvisionerTokenNotFoundError(params.tokenId);\n return token;\n}\n"],"names":["extractDisplayPrefix","generateOpaqueToken","hashOpaqueToken","createProvisionerToken","listActiveProvisionerTokens","listUsableProvisionerTokensByWorkspaceId","revokeInstallationProvisionerToken","revokeInstallationProvisionerTokenDb","revokeProvisionerToken","config","ProvisionerTokenNotFoundError","createWorkspaceProvisionerToken","params","rawToken","expiresAt","ttlSeconds","Date","now","undefined","token","scope","workspaceId","hashedToken","prefix","name","createdByUserId","createInstallationProvisionerToken","listUsableProvisionerTokens","listActiveProvisioners","windowSeconds","PROVISIONER_ACTIVE_WINDOW_SECONDS","revokeWorkspaceProvisionerToken","tokenId"],"mappings":"AAAA,SAAQA,oBAAoB,EAAEC,mBAAmB,EAAEC,eAAe,QAAO,uBAAuB;AAChG,SACEC,sBAAsB,EACtBC,2BAA2B,EAC3BC,wCAAwC,EACxCC,sCAAsCC,oCAAoC,EAC1EC,sBAAsB,QACjB,4BAA4B;AACnC,SAAQC,MAAM,QAAO,eAAe;AAEpC,SAAQC,6BAA6B,QAAO,cAAc;AAc1D,OAAO,eAAeC,gCACpBC,MAA6C;IAE7C,MAAMC,WAAWZ,oBAAoB;IACrC,MAAMa,YAAYF,OAAOG,UAAU,GAAG,IAAIC,KAAKA,KAAKC,GAAG,KAAKL,OAAOG,UAAU,GAAG,QAAQG;IAExF,MAAMC,QAAQ,MAAMhB,uBAAuB;QACzCiB,OAAO;QACPC,aAAaT,OAAOS,WAAW;QAC/BC,aAAapB,gBAAgBW;QAC7BU,QAAQvB,qBAAqBa;QAC7BW,MAAMZ,OAAOY,IAAI;QACjBC,iBAAiBb,OAAOa,eAAe;QACvCX;IACF;IAEA,OAAO;QAACK;QAAON;IAAQ;AACzB;AAQA,OAAO,eAAea,mCACpBd,MAAgD;IAEhD,MAAMC,WAAWZ,oBAAoB;IACrC,MAAMa,YAAYF,OAAOG,UAAU,GAAG,IAAIC,KAAKA,KAAKC,GAAG,KAAKL,OAAOG,UAAU,GAAG,QAAQG;IACxF,MAAMC,QAAQ,MAAMhB,uBAAuB;QACzCiB,OAAO;QACPE,aAAapB,gBAAgBW;QAC7BU,QAAQvB,qBAAqBa;QAC7BW,MAAMZ,OAAOY,IAAI;QACjBC,iBAAiBb,OAAOa,eAAe;QACvCX;IACF;IACA,OAAO;QAACK;QAAON;IAAQ;AACzB;AAEA,OAAO,SAASc,4BAA4BN,WAAmB;IAC7D,OAAOhB,yCAAyCgB;AAClD;AAEA,OAAO,SAASO,uBAAuBP,WAAmB;IACxD,OAAOjB,4BAA4B;QACjCiB;QACAQ,eAAepB,OAAOqB,iCAAiC;IACzD;AACF;AAEA,OAAO,eAAeC,gCAAgCnB,MAIrD;IACC,MAAMO,QAAQ,MAAMX,uBAAuBI;IAC3C,IAAI,CAACO,OAAO,MAAM,IAAIT,8BAA8BE,OAAOoB,OAAO;IAClE,OAAOb;AACT;AAEA,OAAO,eAAeb,mCAAmCM,MAGxD;IACC,MAAMO,QAAQ,MAAMZ,qCAAqCK;IACzD,IAAI,CAACO,OAAO,MAAM,IAAIT,8BAA8BE,OAAOoB,OAAO;IAClE,OAAOb;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/core/rate-limit.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/core/rate-limit.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,yBAAyB,EAC1B,MAAM,0BAA0B,CAAC;AAKlC,MAAM,MAAM,sBAAsB,GAAG,kBAAkB,GAAG,oBAAoB,CAAC;AAC/E,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG,iBAAiB,CAAC;AACtE,MAAM,MAAM,uBAAuB,GAAG,gBAAgB,CAAC;AACvD,MAAM,MAAM,sBAAsB,GAAG,eAAe,CAAC;AAErD,MAAM,WAAW,2BAA4B,SAAQ,sBAAsB;IACzE,MAAM,EAAE,sBAAsB,CAAC;IAC/B,KAAK,EAAE,qBAAqB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED,qBAAa,6BAA8B,SAAQ,sBAAsB,CACvE,sBAAsB,EACtB,qBAAqB,CACtB;gBACa,MAAM,EAAE;QAClB,MAAM,EAAE,sBAAsB,CAAC;QAC/B,KAAK,EAAE,qBAAqB,CAAC;QAC7B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,oBAAoB,EAAE,MAAM,CAAC;KAC9B;CAIF;AAED,qBAAa,gCAAiC,SAAQ,yBAAyB,CAC7E,sBAAsB,EACtB,qBAAqB,CACtB;gBACa,MAAM,EAAE;QAClB,MAAM,EAAE,sBAAsB,CAAC;QAC/B,KAAK,EAAE,qBAAqB,CAAC;QAC7B,oBAAoB,EAAE,MAAM,CAAC;QAC7B,KAAK,EAAE,OAAO,CAAC;KAChB;CAIF;AAID,wBAAgB,8BAA8B,CAAC,MAAM,EAAE;IACrD,MAAM,EAAE,sBAAsB,CAAC;IAC/B,KAAK,EAAE,qBAAqB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAQT;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAoC9F"}
|
package/dist/core/rate-limit.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { config as authConfig } from '@shipfox/api-auth/config';
|
|
1
|
+
import { rateLimitIdentifierKey } from '@shipfox/node-auth-root-key';
|
|
3
2
|
import { checkRateLimit, hashRateLimitIdentifier, RateLimitExceededError, RateLimitUnavailableError } from '@shipfox/node-rate-limit';
|
|
4
3
|
import { config } from '#config.js';
|
|
5
4
|
import { consumeRunnersRateLimit, pruneExpiredRunnersRateLimits } from '#db/rate-limits.js';
|
|
@@ -17,7 +16,6 @@ export class RunnersRateLimitUnavailableError extends RateLimitUnavailableError
|
|
|
17
16
|
}
|
|
18
17
|
}
|
|
19
18
|
const IDENTIFIER_HASH_DOMAIN = 'shipfox.runners.rate-limit.identifier.v1';
|
|
20
|
-
const IDENTIFIER_SECRET_DERIVATION_DOMAIN = 'shipfox.runners.rate-limit.identifier-secret.v1';
|
|
21
19
|
export function hashRunnersRateLimitIdentifier(params) {
|
|
22
20
|
return hashRateLimitIdentifier({
|
|
23
21
|
action: params.action,
|
|
@@ -65,10 +63,7 @@ export async function checkRunnersRateLimit(params) {
|
|
|
65
63
|
}
|
|
66
64
|
}
|
|
67
65
|
function effectiveIdentifierSecret() {
|
|
68
|
-
|
|
69
|
-
return config.RATE_LIMIT_IDENTIFIER_SECRET;
|
|
70
|
-
}
|
|
71
|
-
return createHmac('sha256', authConfig.AUTH_JWT_SECRET).update(IDENTIFIER_SECRET_DERIVATION_DOMAIN).digest();
|
|
66
|
+
return rateLimitIdentifierKey();
|
|
72
67
|
}
|
|
73
68
|
|
|
74
69
|
//# sourceMappingURL=rate-limit.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/rate-limit.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../src/core/rate-limit.ts"],"sourcesContent":["import {rateLimitIdentifierKey} from '@shipfox/node-auth-root-key';\nimport {\n checkRateLimit,\n hashRateLimitIdentifier,\n RateLimitExceededError,\n type RateLimitOutcome,\n type RateLimitPolicy,\n RateLimitUnavailableError,\n} from '@shipfox/node-rate-limit';\nimport {config} from '#config.js';\nimport {consumeRunnersRateLimit, pruneExpiredRunnersRateLimits} from '#db/rate-limits.js';\nimport {recordRunnersRateLimitCheck, recordRunnersRateLimitPruneFailure} from '#metrics/index.js';\n\nexport type RunnersRateLimitAction = 'provisioner-mint' | 'ephemeral-register';\nexport type RunnersRateLimitScope = 'provisioner' | 'ephemeral-token';\nexport type RunnersRateLimitOutcome = RateLimitOutcome;\nexport type RunnersRateLimitPolicy = RateLimitPolicy;\n\nexport interface CheckRunnersRateLimitParams extends RunnersRateLimitPolicy {\n action: RunnersRateLimitAction;\n scope: RunnersRateLimitScope;\n identifier: string;\n now?: Date | undefined;\n timeoutMs?: number | undefined;\n}\n\nexport class RunnersRateLimitExceededError extends RateLimitExceededError<\n RunnersRateLimitAction,\n RunnersRateLimitScope\n> {\n constructor(params: {\n action: RunnersRateLimitAction;\n scope: RunnersRateLimitScope;\n retryAfterSeconds: number;\n identifierHmacPrefix: string;\n }) {\n super(params);\n this.name = 'RunnersRateLimitExceededError';\n }\n}\n\nexport class RunnersRateLimitUnavailableError extends RateLimitUnavailableError<\n RunnersRateLimitAction,\n RunnersRateLimitScope\n> {\n constructor(params: {\n action: RunnersRateLimitAction;\n scope: RunnersRateLimitScope;\n identifierHmacPrefix: string;\n cause: unknown;\n }) {\n super(params);\n this.name = 'RunnersRateLimitUnavailableError';\n }\n}\n\nconst IDENTIFIER_HASH_DOMAIN = 'shipfox.runners.rate-limit.identifier.v1';\n\nexport function hashRunnersRateLimitIdentifier(params: {\n action: RunnersRateLimitAction;\n scope: RunnersRateLimitScope;\n identifier: string;\n}): string {\n return hashRateLimitIdentifier({\n action: params.action,\n scope: params.scope,\n identifier: params.identifier,\n secret: effectiveIdentifierSecret(),\n domain: IDENTIFIER_HASH_DOMAIN,\n });\n}\n\nexport async function checkRunnersRateLimit(params: CheckRunnersRateLimitParams): Promise<void> {\n try {\n await checkRateLimit({\n action: params.action,\n scope: params.scope,\n identifier: params.identifier,\n limit: params.limit,\n windowSeconds: params.windowSeconds,\n identifierSecret: effectiveIdentifierSecret(),\n identifierHashDomain: IDENTIFIER_HASH_DOMAIN,\n consume: consumeRunnersRateLimit,\n prune: pruneExpiredRunnersRateLimits,\n onCheck: recordRunnersRateLimitCheck,\n onPruneFailure: recordRunnersRateLimitPruneFailure,\n now: params.now,\n timeoutMs: params.timeoutMs ?? config.RUNNERS_RATE_LIMIT_TIMEOUT_MS,\n });\n } catch (error) {\n if (error instanceof RateLimitExceededError) {\n throw new RunnersRateLimitExceededError({\n action: error.action,\n scope: error.scope,\n retryAfterSeconds: error.retryAfterSeconds,\n identifierHmacPrefix: error.identifierHmacPrefix,\n });\n }\n if (error instanceof RateLimitUnavailableError) {\n throw new RunnersRateLimitUnavailableError({\n action: error.action,\n scope: error.scope,\n identifierHmacPrefix: error.identifierHmacPrefix,\n cause: error.cause,\n });\n }\n throw error;\n }\n}\n\nfunction effectiveIdentifierSecret(): Uint8Array {\n return rateLimitIdentifierKey();\n}\n"],"names":["rateLimitIdentifierKey","checkRateLimit","hashRateLimitIdentifier","RateLimitExceededError","RateLimitUnavailableError","config","consumeRunnersRateLimit","pruneExpiredRunnersRateLimits","recordRunnersRateLimitCheck","recordRunnersRateLimitPruneFailure","RunnersRateLimitExceededError","params","name","RunnersRateLimitUnavailableError","IDENTIFIER_HASH_DOMAIN","hashRunnersRateLimitIdentifier","action","scope","identifier","secret","effectiveIdentifierSecret","domain","checkRunnersRateLimit","limit","windowSeconds","identifierSecret","identifierHashDomain","consume","prune","onCheck","onPruneFailure","now","timeoutMs","RUNNERS_RATE_LIMIT_TIMEOUT_MS","error","retryAfterSeconds","identifierHmacPrefix","cause"],"mappings":"AAAA,SAAQA,sBAAsB,QAAO,8BAA8B;AACnE,SACEC,cAAc,EACdC,uBAAuB,EACvBC,sBAAsB,EAGtBC,yBAAyB,QACpB,2BAA2B;AAClC,SAAQC,MAAM,QAAO,aAAa;AAClC,SAAQC,uBAAuB,EAAEC,6BAA6B,QAAO,qBAAqB;AAC1F,SAAQC,2BAA2B,EAAEC,kCAAkC,QAAO,oBAAoB;AAelG,OAAO,MAAMC,sCAAsCP;IAIjD,YAAYQ,MAKX,CAAE;QACD,KAAK,CAACA;QACN,IAAI,CAACC,IAAI,GAAG;IACd;AACF;AAEA,OAAO,MAAMC,yCAAyCT;IAIpD,YAAYO,MAKX,CAAE;QACD,KAAK,CAACA;QACN,IAAI,CAACC,IAAI,GAAG;IACd;AACF;AAEA,MAAME,yBAAyB;AAE/B,OAAO,SAASC,+BAA+BJ,MAI9C;IACC,OAAOT,wBAAwB;QAC7Bc,QAAQL,OAAOK,MAAM;QACrBC,OAAON,OAAOM,KAAK;QACnBC,YAAYP,OAAOO,UAAU;QAC7BC,QAAQC;QACRC,QAAQP;IACV;AACF;AAEA,OAAO,eAAeQ,sBAAsBX,MAAmC;IAC7E,IAAI;QACF,MAAMV,eAAe;YACnBe,QAAQL,OAAOK,MAAM;YACrBC,OAAON,OAAOM,KAAK;YACnBC,YAAYP,OAAOO,UAAU;YAC7BK,OAAOZ,OAAOY,KAAK;YACnBC,eAAeb,OAAOa,aAAa;YACnCC,kBAAkBL;YAClBM,sBAAsBZ;YACtBa,SAASrB;YACTsB,OAAOrB;YACPsB,SAASrB;YACTsB,gBAAgBrB;YAChBsB,KAAKpB,OAAOoB,GAAG;YACfC,WAAWrB,OAAOqB,SAAS,IAAI3B,OAAO4B,6BAA6B;QACrE;IACF,EAAE,OAAOC,OAAO;QACd,IAAIA,iBAAiB/B,wBAAwB;YAC3C,MAAM,IAAIO,8BAA8B;gBACtCM,QAAQkB,MAAMlB,MAAM;gBACpBC,OAAOiB,MAAMjB,KAAK;gBAClBkB,mBAAmBD,MAAMC,iBAAiB;gBAC1CC,sBAAsBF,MAAME,oBAAoB;YAClD;QACF;QACA,IAAIF,iBAAiB9B,2BAA2B;YAC9C,MAAM,IAAIS,iCAAiC;gBACzCG,QAAQkB,MAAMlB,MAAM;gBACpBC,OAAOiB,MAAMjB,KAAK;gBAClBmB,sBAAsBF,MAAME,oBAAoB;gBAChDC,OAAOH,MAAMG,KAAK;YACpB;QACF;QACA,MAAMH;IACR;AACF;AAEA,SAASd;IACP,OAAOpB;AACT"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare function issueRunnerActivationToken(params: {
|
|
2
|
+
runnerInstanceId: string;
|
|
3
|
+
provisionerId: string;
|
|
4
|
+
ttlSeconds: number;
|
|
5
|
+
}): Promise<string | null>;
|
|
6
|
+
export declare function getRunnerAssignment(params: {
|
|
7
|
+
runnerInstanceId: string;
|
|
8
|
+
provisionerId: string;
|
|
9
|
+
}): Promise<{
|
|
10
|
+
workspaceId: string | null;
|
|
11
|
+
runnerSessionId: string | null;
|
|
12
|
+
} | null>;
|
|
13
|
+
//# sourceMappingURL=runner-activation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner-activation.d.ts","sourceRoot":"","sources":["../../src/core/runner-activation.ts"],"names":[],"mappings":"AAMA,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,CAyCzB;AAED,wBAAsB,mBAAmB,CAAC,MAAM,EAAE;IAChD,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;CACvB;;;UAeA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken } from '@shipfox/node-tokens';
|
|
2
|
+
import { and, eq, isNull, sql } from 'drizzle-orm';
|
|
3
|
+
import { db } from '#db/db.js';
|
|
4
|
+
import { runnerActivationTokens } from '#db/schema/runner-activation-tokens.js';
|
|
5
|
+
import { providerRunners } from '#db/schema/runner-instances.js';
|
|
6
|
+
export async function issueRunnerActivationToken(params) {
|
|
7
|
+
return await db().transaction(async (tx)=>{
|
|
8
|
+
await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${`runners_activation:${params.runnerInstanceId}`}))`);
|
|
9
|
+
const [runner] = await tx.select({
|
|
10
|
+
workspaceId: providerRunners.workspaceId,
|
|
11
|
+
runnerSessionId: providerRunners.runnerSessionId,
|
|
12
|
+
state: providerRunners.state
|
|
13
|
+
}).from(providerRunners).where(and(eq(providerRunners.id, params.runnerInstanceId), eq(providerRunners.provisionerId, params.provisionerId))).limit(1).for('update');
|
|
14
|
+
if (!runner?.workspaceId || runner.runnerSessionId || runner.state !== 'running') return null;
|
|
15
|
+
await tx.update(runnerActivationTokens).set({
|
|
16
|
+
revokedAt: sql`now()`
|
|
17
|
+
}).where(and(eq(runnerActivationTokens.runnerInstanceId, params.runnerInstanceId), isNull(runnerActivationTokens.consumedAt), isNull(runnerActivationTokens.revokedAt)));
|
|
18
|
+
const rawToken = generateOpaqueToken('runnerActivationToken');
|
|
19
|
+
await tx.insert(runnerActivationTokens).values({
|
|
20
|
+
runnerInstanceId: params.runnerInstanceId,
|
|
21
|
+
hashedToken: hashOpaqueToken(rawToken),
|
|
22
|
+
prefix: extractDisplayPrefix(rawToken),
|
|
23
|
+
expiresAt: new Date(Date.now() + params.ttlSeconds * 1000)
|
|
24
|
+
});
|
|
25
|
+
return rawToken;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
export async function getRunnerAssignment(params) {
|
|
29
|
+
const [runner] = await db().select({
|
|
30
|
+
workspaceId: providerRunners.workspaceId,
|
|
31
|
+
runnerSessionId: providerRunners.runnerSessionId
|
|
32
|
+
}).from(providerRunners).where(and(eq(providerRunners.id, params.runnerInstanceId), eq(providerRunners.provisionerId, params.provisionerId))).limit(1);
|
|
33
|
+
return runner?.workspaceId && !runner.runnerSessionId ? runner : null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=runner-activation.js.map
|
|
@@ -0,0 +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 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}\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","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;AACjD,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;QACnC,MAAMA,GAAGC,OAAO,CACdR,GAAG,CAAC,sCAAsC,EAAE,CAAC,mBAAmB,EAAEK,OAAOI,gBAAgB,EAAE,CAAC,EAAE,CAAC;QAEjG,MAAM,CAACC,OAAO,GAAG,MAAMH,GACpBI,MAAM,CAAC;YACNC,aAAaT,gBAAgBS,WAAW;YACxCC,iBAAiBV,gBAAgBU,eAAe;YAChDC,OAAOX,gBAAgBW,KAAK;QAC9B,GACCC,IAAI,CAACZ,iBACLa,KAAK,CACJnB,IACEC,GAAGK,gBAAgBc,EAAE,EAAEZ,OAAOI,gBAAgB,GAC9CX,GAAGK,gBAAgBe,aAAa,EAAEb,OAAOa,aAAa,IAGzDC,KAAK,CAAC,GACNC,GAAG,CAAC;QACP,IAAI,CAACV,QAAQE,eAAeF,OAAOG,eAAe,IAAIH,OAAOI,KAAK,KAAK,WAAW,OAAO;QAEzF,MAAMP,GACHc,MAAM,CAACnB,wBACPoB,GAAG,CAAC;YAACC,WAAWvB,GAAG,CAAC,KAAK,CAAC;QAAA,GAC1BgB,KAAK,CACJnB,IACEC,GAAGI,uBAAuBO,gBAAgB,EAAEJ,OAAOI,gBAAgB,GACnEV,OAAOG,uBAAuBsB,UAAU,GACxCzB,OAAOG,uBAAuBqB,SAAS;QAG7C,MAAME,WAAW9B,oBAAoB;QACrC,MAAMY,GAAGmB,MAAM,CAACxB,wBAAwByB,MAAM,CAAC;YAC7ClB,kBAAkBJ,OAAOI,gBAAgB;YACzCmB,aAAahC,gBAAgB6B;YAC7BI,QAAQnC,qBAAqB+B;YAC7BK,WAAW,IAAIC,KAAKA,KAAKC,GAAG,KAAK3B,OAAO4B,UAAU,GAAG;QACvD;QACA,OAAOR;IACT;AACF;AAEA,OAAO,eAAeS,oBAAoB7B,MAGzC;IACC,MAAM,CAACK,OAAO,GAAG,MAAMT,KACpBU,MAAM,CAAC;QACNC,aAAaT,gBAAgBS,WAAW;QACxCC,iBAAiBV,gBAAgBU,eAAe;IAClD,GACCE,IAAI,CAACZ,iBACLa,KAAK,CACJnB,IACEC,GAAGK,gBAAgBc,EAAE,EAAEZ,OAAOI,gBAAgB,GAC9CX,GAAGK,gBAAgBe,aAAa,EAAEb,OAAOa,aAAa,IAGzDC,KAAK,CAAC;IACT,OAAOT,QAAQE,eAAe,CAACF,OAAOG,eAAe,GAAGH,SAAS;AACnE"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { RunnerToolCapabilitiesDto } from '@shipfox/api-runners-dto';
|
|
2
|
+
export declare class RunnerBootstrapTokenInvalidError extends Error {
|
|
3
|
+
constructor();
|
|
4
|
+
}
|
|
5
|
+
export declare class RunnerControlSessionInvalidError extends Error {
|
|
6
|
+
constructor();
|
|
7
|
+
}
|
|
8
|
+
export declare function createRunnerInstancesWithBootstrapTokens(params: {
|
|
9
|
+
provisionerId: string;
|
|
10
|
+
providerKind?: string | null;
|
|
11
|
+
runnerInstances: Array<{
|
|
12
|
+
templateKey?: string | null;
|
|
13
|
+
}>;
|
|
14
|
+
ttlSeconds: number;
|
|
15
|
+
}): Promise<Array<{
|
|
16
|
+
runnerInstanceId: string;
|
|
17
|
+
bootstrapToken: string;
|
|
18
|
+
}>>;
|
|
19
|
+
export declare function exchangeRunnerBootstrapToken(params: {
|
|
20
|
+
rawToken: string;
|
|
21
|
+
ttlSeconds: number;
|
|
22
|
+
}): Promise<{
|
|
23
|
+
runnerInstanceId: string;
|
|
24
|
+
controlSessionToken: string;
|
|
25
|
+
expiresAt: Date;
|
|
26
|
+
}>;
|
|
27
|
+
export declare function resolveRunnerControlSession(rawToken: string): Promise<{
|
|
28
|
+
id: string;
|
|
29
|
+
runnerInstanceId: string;
|
|
30
|
+
provisionerId: string;
|
|
31
|
+
} | undefined>;
|
|
32
|
+
export declare function enrollRunnerControlSession(params: {
|
|
33
|
+
runnerInstanceId: string;
|
|
34
|
+
provisionerId: string;
|
|
35
|
+
labels: string[];
|
|
36
|
+
capabilities?: RunnerToolCapabilitiesDto | null;
|
|
37
|
+
providerKind: string;
|
|
38
|
+
protocolVersion: string;
|
|
39
|
+
}): Promise<void>;
|
|
40
|
+
export declare function attachRunnerControlProviderId(params: {
|
|
41
|
+
runnerInstanceId: string;
|
|
42
|
+
provisionerId: string;
|
|
43
|
+
providerRunnerId: string;
|
|
44
|
+
}): Promise<boolean>;
|
|
45
|
+
export declare function touchRunnerControlSession(runnerInstanceId: string, provisionerId: string): Promise<void>;
|
|
46
|
+
//# sourceMappingURL=runner-control-sessions.d.ts.map
|
|
@@ -0,0 +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;AAUxE,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;QAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAC,CAAC,CAAC;IACtD,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,KAAK,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC,CA+BrE;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,IAAI,CAAC,CAsBhB;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,iBAoB9F"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken } from '@shipfox/node-tokens';
|
|
2
|
+
import { canonicalizeLabels } from '@shipfox/runner-labels';
|
|
3
|
+
import { and, eq, gt, isNull, notInArray, or, sql } from 'drizzle-orm';
|
|
4
|
+
import { db } from '#db/db.js';
|
|
5
|
+
import { terminalStates } from '#db/runner-instances.js';
|
|
6
|
+
import { provisionerTokens } from '#db/schema/provisioner-tokens.js';
|
|
7
|
+
import { runnerBootstrapTokens, runnerControlSessions } from '#db/schema/runner-control-sessions.js';
|
|
8
|
+
import { providerRunners } from '#db/schema/runner-instances.js';
|
|
9
|
+
export class RunnerBootstrapTokenInvalidError extends Error {
|
|
10
|
+
constructor(){
|
|
11
|
+
super('Runner bootstrap token is invalid, expired, or has already been used');
|
|
12
|
+
this.name = 'RunnerBootstrapTokenInvalidError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export class RunnerControlSessionInvalidError extends Error {
|
|
16
|
+
constructor(){
|
|
17
|
+
super('Runner control session is invalid, expired, or closed');
|
|
18
|
+
this.name = 'RunnerControlSessionInvalidError';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export async function createRunnerInstancesWithBootstrapTokens(params) {
|
|
22
|
+
const expiresAt = new Date(Date.now() + params.ttlSeconds * 1000);
|
|
23
|
+
return await db().transaction(async (tx)=>{
|
|
24
|
+
const instances = await tx.insert(providerRunners).values(params.runnerInstances.map((runner)=>({
|
|
25
|
+
provisionerId: params.provisionerId,
|
|
26
|
+
providerKind: params.providerKind ?? null,
|
|
27
|
+
templateKey: runner.templateKey ?? null,
|
|
28
|
+
state: 'starting',
|
|
29
|
+
labels: [],
|
|
30
|
+
reportedAt: new Date()
|
|
31
|
+
}))).returning({
|
|
32
|
+
id: providerRunners.id
|
|
33
|
+
});
|
|
34
|
+
const results = instances.map((instance)=>({
|
|
35
|
+
runnerInstanceId: instance.id,
|
|
36
|
+
bootstrapToken: generateOpaqueToken('runnerBootstrapToken')
|
|
37
|
+
}));
|
|
38
|
+
await tx.insert(runnerBootstrapTokens).values(results.map((result)=>({
|
|
39
|
+
runnerInstanceId: result.runnerInstanceId,
|
|
40
|
+
provisionerId: params.provisionerId,
|
|
41
|
+
hashedToken: hashOpaqueToken(result.bootstrapToken),
|
|
42
|
+
prefix: extractDisplayPrefix(result.bootstrapToken),
|
|
43
|
+
expiresAt
|
|
44
|
+
})));
|
|
45
|
+
return results;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
export async function exchangeRunnerBootstrapToken(params) {
|
|
49
|
+
const controlSessionToken = generateOpaqueToken('runnerControlSession');
|
|
50
|
+
const expiresAt = new Date(Date.now() + params.ttlSeconds * 1000);
|
|
51
|
+
return await db().transaction(async (tx)=>{
|
|
52
|
+
const [bootstrap] = await tx.update(runnerBootstrapTokens).set({
|
|
53
|
+
consumedAt: sql`now()`
|
|
54
|
+
}).where(and(eq(runnerBootstrapTokens.hashedToken, hashOpaqueToken(params.rawToken)), isNull(runnerBootstrapTokens.consumedAt), isNull(runnerBootstrapTokens.revokedAt), gt(runnerBootstrapTokens.expiresAt, sql`now()`))).returning();
|
|
55
|
+
if (!bootstrap) throw new RunnerBootstrapTokenInvalidError();
|
|
56
|
+
const [session] = await tx.insert(runnerControlSessions).values({
|
|
57
|
+
runnerInstanceId: bootstrap.runnerInstanceId,
|
|
58
|
+
provisionerId: bootstrap.provisionerId,
|
|
59
|
+
hashedToken: hashOpaqueToken(controlSessionToken),
|
|
60
|
+
prefix: extractDisplayPrefix(controlSessionToken),
|
|
61
|
+
expiresAt
|
|
62
|
+
}).returning({
|
|
63
|
+
id: runnerControlSessions.id
|
|
64
|
+
});
|
|
65
|
+
if (!session) throw new Error('Runner control session insert returned no row');
|
|
66
|
+
return {
|
|
67
|
+
runnerInstanceId: bootstrap.runnerInstanceId,
|
|
68
|
+
controlSessionToken,
|
|
69
|
+
expiresAt
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
export async function resolveRunnerControlSession(rawToken) {
|
|
74
|
+
const [session] = await db().select({
|
|
75
|
+
id: runnerControlSessions.id,
|
|
76
|
+
runnerInstanceId: runnerControlSessions.runnerInstanceId,
|
|
77
|
+
provisionerId: runnerControlSessions.provisionerId
|
|
78
|
+
}).from(runnerControlSessions).leftJoin(provisionerTokens, eq(provisionerTokens.id, runnerControlSessions.provisionerId)).where(and(eq(runnerControlSessions.hashedToken, hashOpaqueToken(rawToken)), isNull(runnerControlSessions.closedAt), or(isNull(provisionerTokens.id), isNull(provisionerTokens.revokedAt)), gt(runnerControlSessions.expiresAt, sql`now()`))).limit(1);
|
|
79
|
+
return session;
|
|
80
|
+
}
|
|
81
|
+
export async function enrollRunnerControlSession(params) {
|
|
82
|
+
const updated = await db().update(providerRunners).set({
|
|
83
|
+
labels: [
|
|
84
|
+
...canonicalizeLabels(params.labels)
|
|
85
|
+
],
|
|
86
|
+
providerKind: params.providerKind,
|
|
87
|
+
protocolVersion: params.protocolVersion,
|
|
88
|
+
capabilities: params.capabilities ?? null,
|
|
89
|
+
state: 'running',
|
|
90
|
+
reportedAt: sql`now()`,
|
|
91
|
+
updatedAt: sql`now()`
|
|
92
|
+
}).where(and(eq(providerRunners.id, params.runnerInstanceId), eq(providerRunners.provisionerId, params.provisionerId), notInArray(providerRunners.state, [
|
|
93
|
+
...terminalStates
|
|
94
|
+
]))).returning({
|
|
95
|
+
id: providerRunners.id
|
|
96
|
+
});
|
|
97
|
+
if (!updated[0]) throw new RunnerControlSessionInvalidError();
|
|
98
|
+
await touchRunnerControlSession(params.runnerInstanceId, params.provisionerId);
|
|
99
|
+
}
|
|
100
|
+
export async function attachRunnerControlProviderId(params) {
|
|
101
|
+
const rows = await db().update(providerRunners).set({
|
|
102
|
+
providerRunnerId: params.providerRunnerId,
|
|
103
|
+
updatedAt: sql`now()`
|
|
104
|
+
}).where(and(eq(providerRunners.id, params.runnerInstanceId), eq(providerRunners.provisionerId, params.provisionerId), isNull(providerRunners.providerRunnerId), notInArray(providerRunners.state, [
|
|
105
|
+
...terminalStates
|
|
106
|
+
]))).returning({
|
|
107
|
+
id: providerRunners.id
|
|
108
|
+
});
|
|
109
|
+
return rows.length === 1;
|
|
110
|
+
}
|
|
111
|
+
export async function touchRunnerControlSession(runnerInstanceId, provisionerId) {
|
|
112
|
+
await db().update(runnerControlSessions).set({
|
|
113
|
+
lastSeenAt: sql`now()`
|
|
114
|
+
}).where(and(eq(runnerControlSessions.runnerInstanceId, runnerInstanceId), eq(runnerControlSessions.provisionerId, provisionerId), isNull(runnerControlSessions.closedAt)));
|
|
115
|
+
await db().update(providerRunners).set({
|
|
116
|
+
reportedAt: sql`now()`,
|
|
117
|
+
updatedAt: sql`now()`
|
|
118
|
+
}).where(and(eq(providerRunners.id, runnerInstanceId), eq(providerRunners.provisionerId, provisionerId)));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
//# sourceMappingURL=runner-control-sessions.js.map
|
|
@@ -0,0 +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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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { RunnerInstance, RunnerInstanceState } from '#core/entities/runner-instance.js';
|
|
2
|
+
import { type RunnerInstanceReportEvent } from '#db/index.js';
|
|
3
|
+
import type { RunnerInstanceBoundJobExecution } from '#db/job-executions.js';
|
|
4
|
+
export interface ReportRunnerInstancesParams {
|
|
5
|
+
workspaceId: string | null;
|
|
6
|
+
provisionerId: string;
|
|
7
|
+
events: RunnerInstanceReportEvent[];
|
|
8
|
+
}
|
|
9
|
+
export declare function createPlannedProvisionedCapacity(params: {
|
|
10
|
+
provisionerId: string;
|
|
11
|
+
providerKind: string | null;
|
|
12
|
+
templateKey: string | null;
|
|
13
|
+
}): Promise<{
|
|
14
|
+
capacityId: string;
|
|
15
|
+
}>;
|
|
16
|
+
export declare function attachProviderRunnerId(params: {
|
|
17
|
+
capacityId: string;
|
|
18
|
+
provisionerId: string;
|
|
19
|
+
providerRunnerId: string;
|
|
20
|
+
}): Promise<boolean>;
|
|
21
|
+
export interface ReportRunnerInstancesResult {
|
|
22
|
+
accepted: number;
|
|
23
|
+
reservationsReleased: number;
|
|
24
|
+
}
|
|
25
|
+
export interface ReconcileRunnerInstancesParams {
|
|
26
|
+
workspaceId: string | null;
|
|
27
|
+
provisionerId: string;
|
|
28
|
+
observedRunnerInstanceIds: string[];
|
|
29
|
+
}
|
|
30
|
+
export type ReconcileDesiredIntent = 'keep' | 'terminate';
|
|
31
|
+
type ReconcileDesiredIntentReason = 'job-cancelled' | 'terminal-state';
|
|
32
|
+
export interface ReconciledBoundJobExecution {
|
|
33
|
+
jobId: string;
|
|
34
|
+
jobExecutionId: string;
|
|
35
|
+
workflowRunAttemptId: string;
|
|
36
|
+
lastHeartbeatAt: Date;
|
|
37
|
+
cancellationRequestedAt: Date | null;
|
|
38
|
+
}
|
|
39
|
+
export interface ReconciledRunnerInstance {
|
|
40
|
+
providerRunnerId: string;
|
|
41
|
+
state: RunnerInstanceState | null;
|
|
42
|
+
reservationId: string | null;
|
|
43
|
+
runnerSessionId: string | null;
|
|
44
|
+
boundJobExecution: ReconciledBoundJobExecution | null;
|
|
45
|
+
desiredIntent: ReconcileDesiredIntent;
|
|
46
|
+
desiredIntentReason: ReconcileDesiredIntentReason | null;
|
|
47
|
+
}
|
|
48
|
+
export interface ReconcileRunnerInstancesResult {
|
|
49
|
+
runners: ReconciledRunnerInstance[];
|
|
50
|
+
terminatedAbsentRunnerInstanceIds: string[];
|
|
51
|
+
}
|
|
52
|
+
export type ActiveRunnerState = 'starting' | 'running' | 'stopping' | 'busy';
|
|
53
|
+
export interface ActiveRunner {
|
|
54
|
+
runnerSessionId: string | null;
|
|
55
|
+
providerRunnerId: string | null;
|
|
56
|
+
provisionerId: string | null;
|
|
57
|
+
state: ActiveRunnerState;
|
|
58
|
+
labels: string[];
|
|
59
|
+
templateKey: string | null;
|
|
60
|
+
providerKind: string | null;
|
|
61
|
+
jobId: string | null;
|
|
62
|
+
workflowRunAttemptId: string | null;
|
|
63
|
+
projectId: string | null;
|
|
64
|
+
reportedAt: Date | null;
|
|
65
|
+
lastHeartbeatAt: Date | null;
|
|
66
|
+
}
|
|
67
|
+
export declare function reportRunnerInstances(params: ReportRunnerInstancesParams): Promise<ReportRunnerInstancesResult>;
|
|
68
|
+
export declare function reconcileRunnerInstances(params: ReconcileRunnerInstancesParams): Promise<ReconcileRunnerInstancesResult>;
|
|
69
|
+
export declare function reconcileRunnerInstancesFromDbResult(params: {
|
|
70
|
+
observedRunnerInstanceIds: string[];
|
|
71
|
+
observedRows: RunnerInstance[];
|
|
72
|
+
boundJobExecutionsByRunnerInstanceId: Map<string, RunnerInstanceBoundJobExecution>;
|
|
73
|
+
}): ReconciledRunnerInstance[];
|
|
74
|
+
export declare function listActiveRunners(params: {
|
|
75
|
+
workspaceId: string;
|
|
76
|
+
}): Promise<ActiveRunner[]>;
|
|
77
|
+
export declare function desiredIntent(row: RunnerInstance | undefined, boundJobExecution: RunnerInstanceBoundJobExecution | undefined): ReconcileDesiredIntent;
|
|
78
|
+
export {};
|
|
79
|
+
//# sourceMappingURL=runner-instances.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner-instances.d.ts","sourceRoot":"","sources":["../../src/core/runner-instances.ts"],"names":[],"mappings":"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"}
|