@shipfox/api-runners 5.0.0 → 7.0.1
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 +80 -0
- package/dist/config.d.ts +5 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +54 -7
- package/dist/config.js.map +1 -1
- 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/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} +7 -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 +9 -5
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +6 -3
- 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-assignments.d.ts +6 -0
- package/dist/core/runner-assignments.d.ts.map +1 -0
- package/dist/core/runner-assignments.js +6 -0
- package/dist/core/runner-assignments.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 +72 -0
- package/dist/core/runner-instances.d.ts.map +1 -0
- package/dist/core/runner-instances.js +165 -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/db.d.ts +2698 -1054
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/db.js +9 -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-assignments.d.ts +7 -0
- package/dist/db/runner-assignments.d.ts.map +1 -0
- package/dist/db/runner-assignments.js +55 -0
- package/dist/db/runner-assignments.js.map +1 -0
- package/dist/db/runner-instances.d.ts +84 -0
- package/dist/db/runner-instances.d.ts.map +1 -0
- package/dist/db/runner-instances.js +497 -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/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} +105 -34
- package/dist/db/schema/runner-instances.d.ts.map +1 -0
- package/dist/db/schema/{provisioned-runners.js → runner-instances.js} +23 -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 +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +45 -39
- 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 +1 -2
- package/dist/presentation/dto/index.d.ts.map +1 -1
- package/dist/presentation/dto/index.js +1 -2
- package/dist/presentation/dto/index.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-runner-instances.d.ts +2 -0
- package/dist/presentation/routes/assign-runner-instances.d.ts.map +1 -0
- package/dist/presentation/routes/assign-runner-instances.js +40 -0
- package/dist/presentation/routes/assign-runner-instances.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 +80 -51
- package/dist/presentation/routes/index.js.map +1 -1
- 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 +8 -0
- package/dist/presentation/routes/runner-enrollment.d.ts.map +1 -0
- package/dist/presentation/routes/runner-enrollment.js +212 -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 +91 -24
- package/drizzle/meta/0000_snapshot.json +392 -63
- package/package.json +21 -16
- package/src/config.test.ts +0 -26
- package/src/config.ts +48 -7
- package/src/core/demand.test.ts +29 -29
- package/src/core/demand.ts +22 -22
- 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} +6 -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 +37 -22
- 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-assignments.ts +9 -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 +301 -0
- package/src/core/runner-sessions.test.ts +112 -22
- package/src/core/runner-sessions.ts +25 -14
- package/src/db/db.ts +9 -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 +30 -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/runner-assignments.test.ts +163 -0
- package/src/db/runner-assignments.ts +115 -0
- package/src/db/{provisioned-runners.test.ts → runner-instances.test.ts} +442 -353
- package/src/db/runner-instances.ts +922 -0
- package/src/db/runner-sessions.test.ts +19 -6
- package/src/db/runner-sessions.ts +78 -2
- 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} +28 -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 +38 -27
- 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 +4 -8
- 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-runner-instances.ts +49 -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 +91 -44
- 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/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 +319 -0
- package/src/presentation/routes/runner-enrollment.ts +196 -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 +4 -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/mint-registration-tokens.d.ts +0 -5
- package/dist/presentation/dto/mint-registration-tokens.d.ts.map +0 -1
- package/dist/presentation/dto/mint-registration-tokens.js +0 -19
- package/dist/presentation/dto/mint-registration-tokens.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/mint-registration-tokens.d.ts +0 -2
- package/dist/presentation/routes/mint-registration-tokens.d.ts.map +0 -1
- package/dist/presentation/routes/mint-registration-tokens.js +0 -74
- package/dist/presentation/routes/mint-registration-tokens.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/dto/mint-registration-tokens.ts +0 -35
- package/src/presentation/routes/mint-registration-tokens.test.ts +0 -453
- package/src/presentation/routes/mint-registration-tokens.ts +0 -82
- package/src/presentation/routes/reconcile-provisioned-runners.ts +0 -30
- package/test/factories/provisioned-runner.ts +0 -78
package/src/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {dirname, resolve} from 'node:path';
|
|
2
2
|
import {fileURLToPath} from 'node:url';
|
|
3
|
+
import type {AuthInterModuleClient} from '@shipfox/api-auth-dto/inter-module';
|
|
3
4
|
import {runnersEventSchemas} from '@shipfox/api-runners-dto';
|
|
4
5
|
import {
|
|
5
6
|
WORKFLOWS_JOB_EXECUTION_TIMED_OUT,
|
|
@@ -7,25 +8,19 @@ import {
|
|
|
7
8
|
} from '@shipfox/api-workflows-dto';
|
|
8
9
|
import {type ShipfoxModule, subscriberFactory} from '@shipfox/node-module';
|
|
9
10
|
import {db, migrationsPath, runnersOutbox} from '#db/index.js';
|
|
11
|
+
import type {CreateRunnersModuleOptions} from '#installation-provisioning.js';
|
|
10
12
|
import {registerRunnersServiceMetrics} from '#metrics/index.js';
|
|
11
13
|
import {
|
|
12
14
|
createProvisionerTokenAuthMethod,
|
|
15
|
+
createRunnerControlSessionAuthMethod,
|
|
13
16
|
createRunnerRegistrationTokenAuthMethod,
|
|
17
|
+
createRunnerRoutes,
|
|
14
18
|
onWorkflowsJobExecutionTimedOut,
|
|
15
|
-
routes,
|
|
16
19
|
} from '#presentation/index.js';
|
|
20
|
+
import {createRunnersInterModulePresentation} from '#presentation/inter-module.js';
|
|
17
21
|
import {createRunnersMaintenanceActivities} from '#temporal/activities/index.js';
|
|
18
22
|
import {RUNNERS_MAINTENANCE_TASK_QUEUE} from '#temporal/constants.js';
|
|
19
23
|
|
|
20
|
-
export {
|
|
21
|
-
type MintEphemeralRegistrationTokenParams,
|
|
22
|
-
type MintEphemeralRegistrationTokenResult,
|
|
23
|
-
type MintEphemeralRegistrationTokensBatchParams,
|
|
24
|
-
type MintEphemeralRegistrationTokensBatchProvisionedRunner,
|
|
25
|
-
type MintEphemeralRegistrationTokensBatchResult,
|
|
26
|
-
mintEphemeralRegistrationToken,
|
|
27
|
-
mintEphemeralRegistrationTokensBatch,
|
|
28
|
-
} from '#core/ephemeral-registration-tokens.js';
|
|
29
24
|
export {
|
|
30
25
|
type EffectiveRunnerToolCapabilitiesResult,
|
|
31
26
|
getEffectiveRunnerToolCapabilities,
|
|
@@ -38,26 +33,42 @@ export {
|
|
|
38
33
|
isJobLeaseActive,
|
|
39
34
|
releaseJobExecution,
|
|
40
35
|
} from '#db/index.js';
|
|
36
|
+
export type {
|
|
37
|
+
CreateRunnersModuleOptions,
|
|
38
|
+
InstallationProvisioningPolicy,
|
|
39
|
+
} from '#installation-provisioning.js';
|
|
41
40
|
|
|
42
41
|
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
43
42
|
const workflowsPath = resolve(packageRoot, 'dist/temporal/workflows/index.js');
|
|
44
43
|
|
|
45
44
|
const subscriber = subscriberFactory<WorkflowsEventMapDto>();
|
|
46
45
|
|
|
47
|
-
export
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
},
|
|
62
|
-
|
|
63
|
-
|
|
46
|
+
export function createRunnersModule({
|
|
47
|
+
auth,
|
|
48
|
+
...options
|
|
49
|
+
}: CreateRunnersModuleOptions & {auth: AuthInterModuleClient}): ShipfoxModule {
|
|
50
|
+
return {
|
|
51
|
+
name: 'runners',
|
|
52
|
+
database: {db, migrationsPath},
|
|
53
|
+
auth: [
|
|
54
|
+
createRunnerRegistrationTokenAuthMethod(),
|
|
55
|
+
createRunnerControlSessionAuthMethod(),
|
|
56
|
+
createProvisionerTokenAuthMethod(),
|
|
57
|
+
],
|
|
58
|
+
routes: createRunnerRoutes(auth, options),
|
|
59
|
+
metrics: registerRunnersServiceMetrics,
|
|
60
|
+
publishers: [{name: 'runners', table: runnersOutbox, db, eventSchemas: runnersEventSchemas}],
|
|
61
|
+
subscribers: [subscriber(WORKFLOWS_JOB_EXECUTION_TIMED_OUT, onWorkflowsJobExecutionTimedOut)],
|
|
62
|
+
workers: [
|
|
63
|
+
{
|
|
64
|
+
taskQueue: RUNNERS_MAINTENANCE_TASK_QUEUE,
|
|
65
|
+
workflowsPath,
|
|
66
|
+
activities: createRunnersMaintenanceActivities,
|
|
67
|
+
workflows: [
|
|
68
|
+
{name: 'stuckJobDetector', id: 'stuck-job-detector', cronSchedule: '* * * * *'},
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
interModulePresentations: [createRunnersInterModulePresentation()],
|
|
73
|
+
};
|
|
74
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lets an application host choose which workspaces may receive installation-provisioned capacity.
|
|
3
|
+
* The runners module passes candidate IDs in batches so host policy can apply its own entitlement
|
|
4
|
+
* or tenancy rules without exposing those rules from this package.
|
|
5
|
+
*/
|
|
6
|
+
export interface InstallationProvisioningPolicy {
|
|
7
|
+
filterEligibleWorkspaceIds(workspaceIds: readonly string[]): Promise<ReadonlySet<string>>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface CreateRunnersModuleOptions {
|
|
11
|
+
installationProvisioning?: {
|
|
12
|
+
policy: InstallationProvisioningPolicy;
|
|
13
|
+
};
|
|
14
|
+
}
|
package/src/metrics/index.ts
CHANGED
|
@@ -2,11 +2,11 @@ export {
|
|
|
2
2
|
jobExecutionClaimedCount,
|
|
3
3
|
jobExecutionEnqueuedCount,
|
|
4
4
|
jobExecutionLeaseExpiredCount,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
providerRunnerAbsentTerminatedCount,
|
|
6
|
+
providerRunnerCountDivergenceCount,
|
|
7
|
+
providerRunnerReconcileCallCount,
|
|
8
|
+
providerRunnerTerminateIntentHonoredCount,
|
|
9
|
+
providerRunnerTerminateIntentIssuedCount,
|
|
10
10
|
recordRunnersRateLimitCheck,
|
|
11
11
|
recordRunnersRateLimitPruneFailure,
|
|
12
12
|
} from './instance.js';
|
package/src/metrics/instance.ts
CHANGED
|
@@ -19,51 +19,62 @@ export const jobExecutionLeaseExpiredCount = meter.createCounter<Record<string,
|
|
|
19
19
|
{description: 'Job execution leases reaped after passing the heartbeat threshold'},
|
|
20
20
|
);
|
|
21
21
|
|
|
22
|
-
export const
|
|
22
|
+
export const providerRunnerReportCount = meter.createCounter<{
|
|
23
23
|
state: 'starting' | 'running' | 'stopping' | 'stopped' | 'failed' | 'terminated';
|
|
24
|
-
}>('
|
|
24
|
+
}>('runners_provider_runner_reported', {
|
|
25
25
|
description: 'Provisioned runner lifecycle reports accepted by state',
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
-
export const
|
|
29
|
-
'
|
|
28
|
+
export const runnerBootstrapExchangeCount = meter.createCounter<{
|
|
29
|
+
outcome: 'accepted' | 'rejected';
|
|
30
|
+
}>('runners_runner_bootstrap_exchange', {
|
|
31
|
+
description: 'Runner bootstrap-token exchanges by outcome',
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export const runnerControlHeartbeatCount = meter.createCounter<Record<string, never>>(
|
|
35
|
+
'runners_runner_control_heartbeat',
|
|
36
|
+
{description: 'Pre-workspace runner-control heartbeats accepted'},
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
export const providerRunnerReapedCount = meter.createCounter<Record<string, never>>(
|
|
40
|
+
'runners_provider_runner_reaped',
|
|
30
41
|
{
|
|
31
42
|
description: 'Stale provisioned runners marked failed by backend maintenance',
|
|
32
43
|
},
|
|
33
44
|
);
|
|
34
45
|
|
|
35
|
-
export const
|
|
46
|
+
export const providerRunnerCountDivergenceCount = meter.createCounter<{
|
|
36
47
|
template_key?: string;
|
|
37
48
|
state: 'starting' | 'running';
|
|
38
49
|
direction: 'backend-higher' | 'advertised-higher';
|
|
39
|
-
}>('
|
|
50
|
+
}>('runners_provider_runner_count_divergence', {
|
|
40
51
|
description:
|
|
41
52
|
'Absolute difference between provisioner-advertised and backend-observed provisioned runner counts',
|
|
42
53
|
});
|
|
43
54
|
|
|
44
|
-
export const
|
|
45
|
-
'
|
|
55
|
+
export const providerRunnerReconcileCallCount = meter.createCounter<Record<string, never>>(
|
|
56
|
+
'runners_provider_runner_reconcile_called',
|
|
46
57
|
{description: 'Provisioned runner reconcile calls completed successfully'},
|
|
47
58
|
);
|
|
48
59
|
|
|
49
|
-
export const
|
|
50
|
-
'
|
|
60
|
+
export const providerRunnerAbsentTerminatedCount = meter.createCounter<Record<string, never>>(
|
|
61
|
+
'runners_provider_runner_absent_terminated',
|
|
51
62
|
{
|
|
52
63
|
description:
|
|
53
64
|
'Owned provisioned runners marked terminated because they were absent from reconcile',
|
|
54
65
|
},
|
|
55
66
|
);
|
|
56
67
|
|
|
57
|
-
export const
|
|
68
|
+
export const providerRunnerTerminateIntentIssuedCount = meter.createCounter<{
|
|
58
69
|
surface: 'poll-demand' | 'reconcile';
|
|
59
70
|
reason: 'job-cancelled' | 'terminal-state';
|
|
60
|
-
}>('
|
|
71
|
+
}>('runners_provider_runner_terminate_intent_issued', {
|
|
61
72
|
description: 'Provisioned runner terminate intents returned to provisioners',
|
|
62
73
|
});
|
|
63
74
|
|
|
64
|
-
export const
|
|
75
|
+
export const providerRunnerTerminateIntentHonoredCount = meter.createCounter<{
|
|
65
76
|
reason: 'job-cancelled';
|
|
66
|
-
}>('
|
|
77
|
+
}>('runners_provider_runner_terminate_intent_honored', {
|
|
67
78
|
description: 'Provisioned runner terminate intents honored by first transition to terminated',
|
|
68
79
|
});
|
|
69
80
|
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export {createProvisionerTokenAuthMethod} from './provisioner-token-auth.js';
|
|
2
|
+
export {
|
|
3
|
+
authenticateRunnerControlSession,
|
|
4
|
+
createRunnerControlSessionAuthMethod,
|
|
5
|
+
} from './runner-control-session-auth.js';
|
|
2
6
|
export {
|
|
3
7
|
createRunnerRegistrationTokenAuthMethod,
|
|
4
8
|
getRunnerContext,
|
|
@@ -48,10 +48,14 @@ export function createProvisionerTokenAuthMethod(): AuthMethod {
|
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
const context: ProvisionerContext =
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
const context: ProvisionerContext =
|
|
52
|
+
provisionerToken.scope === 'installation'
|
|
53
|
+
? {provisionerTokenId: provisionerToken.id, scope: 'installation'}
|
|
54
|
+
: {
|
|
55
|
+
provisionerTokenId: provisionerToken.id,
|
|
56
|
+
scope: 'workspace',
|
|
57
|
+
workspaceId: provisionerToken.workspaceId,
|
|
58
|
+
};
|
|
55
59
|
|
|
56
60
|
await touchProvisionerLastSeen({
|
|
57
61
|
tokenId: provisionerToken.id,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AUTH_RUNNER_CONTROL_SESSION,
|
|
3
|
+
setRunnerControlSessionContext,
|
|
4
|
+
} from '@shipfox/api-auth-context';
|
|
5
|
+
import {type AuthMethod, ClientError, extractBearerToken} from '@shipfox/node-fastify';
|
|
6
|
+
import {getTokenType} from '@shipfox/node-tokens';
|
|
7
|
+
import {resolveRunnerControlSession} from '#core/runner-control-sessions.js';
|
|
8
|
+
|
|
9
|
+
export function createRunnerControlSessionAuthMethod(): AuthMethod {
|
|
10
|
+
return {
|
|
11
|
+
name: AUTH_RUNNER_CONTROL_SESSION,
|
|
12
|
+
authenticate: authenticateRunnerControlSession,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export async function authenticateRunnerControlSession(
|
|
17
|
+
request: Parameters<AuthMethod['authenticate']>[0],
|
|
18
|
+
) {
|
|
19
|
+
const rawToken = extractBearerToken(request.headers.authorization);
|
|
20
|
+
if (!rawToken || getTokenType(rawToken) !== 'runnerControlSession') {
|
|
21
|
+
throw new ClientError('Invalid runner control session', 'unauthorized', {status: 401});
|
|
22
|
+
}
|
|
23
|
+
const session = await resolveRunnerControlSession(rawToken);
|
|
24
|
+
if (!session)
|
|
25
|
+
throw new ClientError('Invalid runner control session', 'unauthorized', {status: 401});
|
|
26
|
+
setRunnerControlSessionContext(request, {
|
|
27
|
+
runnerControlSessionId: session.id,
|
|
28
|
+
runnerInstanceId: session.runnerInstanceId,
|
|
29
|
+
provisionerId: session.provisionerId,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import {AUTH_RUNNER_REGISTRATION_TOKEN} from '@shipfox/api-auth-context';
|
|
2
2
|
import {type AuthMethod, ClientError, extractBearerToken} from '@shipfox/node-fastify';
|
|
3
3
|
import {getTokenType, hashOpaqueToken} from '@shipfox/node-tokens';
|
|
4
|
+
import {and, eq, gt, isNull, or, sql} from 'drizzle-orm';
|
|
4
5
|
import type {FastifyRequest} from 'fastify';
|
|
6
|
+
import {db} from '#db/db.js';
|
|
5
7
|
import {resolveEphemeralRegistrationTokenByHash} from '#db/ephemeral-registration-tokens.js';
|
|
6
8
|
import {resolveManualRegistrationTokenByHash} from '#db/manual-registration-tokens.js';
|
|
9
|
+
import {provisionerTokens} from '#db/schema/provisioner-tokens.js';
|
|
10
|
+
import {runnerActivationTokens} from '#db/schema/runner-activation-tokens.js';
|
|
11
|
+
import {providerRunners} from '#db/schema/runner-instances.js';
|
|
7
12
|
|
|
8
13
|
const RUNNER_CONTEXT_KEY = 'runner';
|
|
9
14
|
|
|
@@ -19,8 +24,9 @@ export type RunnerRegistrationContext =
|
|
|
19
24
|
workspaceId: string;
|
|
20
25
|
provisionerId: string;
|
|
21
26
|
reservationId: string | null;
|
|
22
|
-
|
|
23
|
-
}
|
|
27
|
+
providerRunnerId: string;
|
|
28
|
+
}
|
|
29
|
+
| {kind: 'activation'; activationTokenId: string; workspaceId: string};
|
|
24
30
|
|
|
25
31
|
export function getRunnerContext(request: FastifyRequest): RunnerRegistrationContext {
|
|
26
32
|
const context = (request as unknown as Record<string, unknown>)[RUNNER_CONTEXT_KEY] as
|
|
@@ -45,6 +51,36 @@ export function createRunnerRegistrationTokenAuthMethod(): AuthMethod {
|
|
|
45
51
|
|
|
46
52
|
const tokenType = getTokenType(rawToken);
|
|
47
53
|
|
|
54
|
+
if (tokenType === 'runnerActivationToken') {
|
|
55
|
+
const [activation] = await db()
|
|
56
|
+
.select({id: runnerActivationTokens.id, workspaceId: providerRunners.workspaceId})
|
|
57
|
+
.from(runnerActivationTokens)
|
|
58
|
+
.innerJoin(
|
|
59
|
+
providerRunners,
|
|
60
|
+
eq(providerRunners.id, runnerActivationTokens.runnerInstanceId),
|
|
61
|
+
)
|
|
62
|
+
.leftJoin(provisionerTokens, eq(provisionerTokens.id, providerRunners.provisionerId))
|
|
63
|
+
.where(
|
|
64
|
+
and(
|
|
65
|
+
eq(runnerActivationTokens.hashedToken, hashOpaqueToken(rawToken)),
|
|
66
|
+
isNull(runnerActivationTokens.consumedAt),
|
|
67
|
+
isNull(runnerActivationTokens.revokedAt),
|
|
68
|
+
gt(runnerActivationTokens.expiresAt, sql`now()`),
|
|
69
|
+
or(isNull(provisionerTokens.id), isNull(provisionerTokens.revokedAt)),
|
|
70
|
+
isNull(providerRunners.runnerSessionId),
|
|
71
|
+
),
|
|
72
|
+
)
|
|
73
|
+
.limit(1);
|
|
74
|
+
if (!activation?.workspaceId)
|
|
75
|
+
throw new ClientError('Invalid runner registration token', 'unauthorized', {status: 401});
|
|
76
|
+
(request as unknown as Record<string, unknown>)[RUNNER_CONTEXT_KEY] = {
|
|
77
|
+
kind: 'activation',
|
|
78
|
+
activationTokenId: activation.id,
|
|
79
|
+
workspaceId: activation.workspaceId,
|
|
80
|
+
} satisfies RunnerRegistrationContext;
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
48
84
|
if (tokenType === 'ephemeralRegistrationToken') {
|
|
49
85
|
const ephemeralToken = await resolveEphemeralRegistrationTokenByHash(
|
|
50
86
|
hashOpaqueToken(rawToken),
|
|
@@ -68,7 +104,7 @@ export function createRunnerRegistrationTokenAuthMethod(): AuthMethod {
|
|
|
68
104
|
workspaceId: ephemeralToken.workspaceId,
|
|
69
105
|
provisionerId: ephemeralToken.provisionerId,
|
|
70
106
|
reservationId: ephemeralToken.reservationId,
|
|
71
|
-
|
|
107
|
+
providerRunnerId: ephemeralToken.providerRunnerId,
|
|
72
108
|
} satisfies RunnerRegistrationContext;
|
|
73
109
|
return;
|
|
74
110
|
}
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
export {toActiveProvisionerDto} from './active-provisioner.js';
|
|
2
2
|
export {toManualRegistrationTokenDto} from './manual-registration-token.js';
|
|
3
|
-
export {
|
|
4
|
-
toMintRegistrationTokensProvisionedRunners,
|
|
5
|
-
toMintRegistrationTokensResponseDto,
|
|
6
|
-
} from './mint-registration-tokens.js';
|
|
7
3
|
export {toPollDemandResponseDto} from './poll-demand.js';
|
|
4
|
+
export {toProvisionerTokenDto} from './provisioner-token.js';
|
|
8
5
|
export {
|
|
9
6
|
toActiveRunnersResponseDto,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} from './
|
|
13
|
-
export {toProvisionerTokenDto} from './provisioner-token.js';
|
|
7
|
+
toReconcileRunnerInstancesResponseDto,
|
|
8
|
+
toReportRunnerInstancesResponseDto,
|
|
9
|
+
} from './runner-instances.js';
|
|
@@ -4,6 +4,7 @@ import type {PollDemandResult} from '#core/demand.js';
|
|
|
4
4
|
export function toPollDemandResponseDto(result: PollDemandResult): PollDemandResponseDto {
|
|
5
5
|
return {
|
|
6
6
|
stats: result.stats.map((stat) => ({
|
|
7
|
+
...(stat.workspaceId ? {workspace_id: stat.workspaceId} : {}),
|
|
7
8
|
labels: stat.labels,
|
|
8
9
|
queued: stat.queued,
|
|
9
10
|
reserved: stat.reserved,
|
|
@@ -11,10 +12,11 @@ export function toPollDemandResponseDto(result: PollDemandResult): PollDemandRes
|
|
|
11
12
|
})),
|
|
12
13
|
reservations: result.reservations.map((reservation) => ({
|
|
13
14
|
reservation_id: reservation.reservationId,
|
|
15
|
+
...(reservation.workspaceId ? {workspace_id: reservation.workspaceId} : {}),
|
|
14
16
|
labels: reservation.labels,
|
|
15
17
|
count: reservation.count,
|
|
16
18
|
expires_at: reservation.expiresAt.toISOString(),
|
|
17
19
|
})),
|
|
18
|
-
|
|
20
|
+
terminate_provider_runner_ids: result.terminateRunnerInstanceIds,
|
|
19
21
|
};
|
|
20
22
|
}
|
|
@@ -3,6 +3,7 @@ import type {ProvisionerToken} from '#core/entities/provisioner-token.js';
|
|
|
3
3
|
export function toProvisionerTokenDto(token: ProvisionerToken): {
|
|
4
4
|
id: string;
|
|
5
5
|
workspace_id: string;
|
|
6
|
+
scope: 'workspace';
|
|
6
7
|
prefix: string;
|
|
7
8
|
name: string | null;
|
|
8
9
|
created_by_user_id: string;
|
|
@@ -13,6 +14,9 @@ export function toProvisionerTokenDto(token: ProvisionerToken): {
|
|
|
13
14
|
created_at: string;
|
|
14
15
|
updated_at: string;
|
|
15
16
|
} {
|
|
17
|
+
if (token.scope !== 'workspace') {
|
|
18
|
+
throw new Error('Installation provisioner tokens cannot be returned from workspace routes');
|
|
19
|
+
}
|
|
16
20
|
return {
|
|
17
21
|
id: token.id,
|
|
18
22
|
workspace_id: token.workspaceId,
|
|
@@ -25,5 +29,6 @@ export function toProvisionerTokenDto(token: ProvisionerToken): {
|
|
|
25
29
|
last_seen_at: token.lastSeenAt?.toISOString() ?? null,
|
|
26
30
|
created_at: token.createdAt.toISOString(),
|
|
27
31
|
updated_at: token.updatedAt.toISOString(),
|
|
32
|
+
scope: 'workspace',
|
|
28
33
|
};
|
|
29
34
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
ActiveRunner,
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
} from '#core/
|
|
3
|
+
ReconcileRunnerInstancesResult,
|
|
4
|
+
ReportRunnerInstancesResult,
|
|
5
|
+
} from '#core/runner-instances.js';
|
|
6
6
|
|
|
7
|
-
export function
|
|
7
|
+
export function toReportRunnerInstancesResponseDto(result: ReportRunnerInstancesResult): {
|
|
8
8
|
accepted: number;
|
|
9
9
|
reservations_released: number;
|
|
10
10
|
} {
|
|
@@ -14,12 +14,10 @@ export function toReportProvisionedRunnersResponseDto(result: ReportProvisionedR
|
|
|
14
14
|
};
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export function
|
|
18
|
-
result: ReconcileProvisionedRunnersResult,
|
|
19
|
-
): {
|
|
17
|
+
export function toReconcileRunnerInstancesResponseDto(result: ReconcileRunnerInstancesResult): {
|
|
20
18
|
runners: Array<{
|
|
21
|
-
|
|
22
|
-
state:
|
|
19
|
+
provider_runner_id: string;
|
|
20
|
+
state: ReconcileRunnerInstancesResult['runners'][number]['state'];
|
|
23
21
|
reservation_id: string | null;
|
|
24
22
|
runner_session_id: string | null;
|
|
25
23
|
bound_job: {
|
|
@@ -28,13 +26,13 @@ export function toReconcileProvisionedRunnersResponseDto(
|
|
|
28
26
|
last_heartbeat_at: string;
|
|
29
27
|
cancellation_requested_at: string | null;
|
|
30
28
|
} | null;
|
|
31
|
-
desired_intent:
|
|
29
|
+
desired_intent: ReconcileRunnerInstancesResult['runners'][number]['desiredIntent'];
|
|
32
30
|
}>;
|
|
33
|
-
|
|
31
|
+
terminated_absent_provider_runner_ids: string[];
|
|
34
32
|
} {
|
|
35
33
|
return {
|
|
36
34
|
runners: result.runners.map((runner) => ({
|
|
37
|
-
|
|
35
|
+
provider_runner_id: runner.providerRunnerId,
|
|
38
36
|
state: runner.state,
|
|
39
37
|
reservation_id: runner.reservationId,
|
|
40
38
|
runner_session_id: runner.runnerSessionId,
|
|
@@ -49,14 +47,14 @@ export function toReconcileProvisionedRunnersResponseDto(
|
|
|
49
47
|
: null,
|
|
50
48
|
desired_intent: runner.desiredIntent,
|
|
51
49
|
})),
|
|
52
|
-
|
|
50
|
+
terminated_absent_provider_runner_ids: result.terminatedAbsentRunnerInstanceIds,
|
|
53
51
|
};
|
|
54
52
|
}
|
|
55
53
|
|
|
56
54
|
export function toActiveRunnersResponseDto(runners: ActiveRunner[]): {
|
|
57
55
|
runners: Array<{
|
|
58
56
|
runner_session_id: string | null;
|
|
59
|
-
|
|
57
|
+
provider_runner_id: string | null;
|
|
60
58
|
provisioner_id: string | null;
|
|
61
59
|
state: ActiveRunner['state'];
|
|
62
60
|
labels: string[];
|
|
@@ -72,7 +70,7 @@ export function toActiveRunnersResponseDto(runners: ActiveRunner[]): {
|
|
|
72
70
|
return {
|
|
73
71
|
runners: runners.map((runner) => ({
|
|
74
72
|
runner_session_id: runner.runnerSessionId,
|
|
75
|
-
|
|
73
|
+
provider_runner_id: runner.providerRunnerId,
|
|
76
74
|
provisioner_id: runner.provisionerId,
|
|
77
75
|
state: runner.state,
|
|
78
76
|
labels: runner.labels,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export {
|
|
2
2
|
createProvisionerTokenAuthMethod,
|
|
3
|
+
createRunnerControlSessionAuthMethod,
|
|
3
4
|
createRunnerRegistrationTokenAuthMethod,
|
|
4
5
|
} from './auth/index.js';
|
|
5
|
-
export {
|
|
6
|
+
export {createRunnerRoutes, createRunnerRoutes as routes} from './routes/index.js';
|
|
6
7
|
export {onWorkflowsJobExecutionTimedOut} from './subscribers/on-workflows-job-execution-timed-out.js';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {runnersInterModuleContract} from '@shipfox/api-runners-dto/inter-module';
|
|
2
|
+
import {isInterModuleKnownError} from '@shipfox/inter-module';
|
|
3
|
+
import {EmptyRequiredLabelsError} from '#core/errors.js';
|
|
4
|
+
import {toEnqueueJobExecutionKnownError} from './inter-module.js';
|
|
5
|
+
|
|
6
|
+
describe('Runners inter-module presentation', () => {
|
|
7
|
+
test('maps empty scheduling labels to the published contract error', () => {
|
|
8
|
+
const result = toEnqueueJobExecutionKnownError(new EmptyRequiredLabelsError());
|
|
9
|
+
|
|
10
|
+
expect(
|
|
11
|
+
isInterModuleKnownError(runnersInterModuleContract.methods.enqueueJobExecution, result) &&
|
|
12
|
+
result.code,
|
|
13
|
+
).toBe('empty-required-labels');
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {runnersInterModuleContract} from '@shipfox/api-runners-dto/inter-module';
|
|
2
|
+
import {
|
|
3
|
+
createInterModuleKnownError,
|
|
4
|
+
defineInterModulePresentation,
|
|
5
|
+
type InterModulePresentation,
|
|
6
|
+
} from '@shipfox/inter-module';
|
|
7
|
+
import {EmptyRequiredLabelsError} from '#core/errors.js';
|
|
8
|
+
import {getEffectiveRunnerToolCapabilities} from '#core/runner-tool-capabilities.js';
|
|
9
|
+
import {
|
|
10
|
+
cancelRunnerJobs,
|
|
11
|
+
enqueueJobExecution,
|
|
12
|
+
isJobLeaseActive,
|
|
13
|
+
releaseJobExecution,
|
|
14
|
+
} from '#db/job-executions.js';
|
|
15
|
+
|
|
16
|
+
export function createRunnersInterModulePresentation(): InterModulePresentation<
|
|
17
|
+
typeof runnersInterModuleContract
|
|
18
|
+
> {
|
|
19
|
+
return defineInterModulePresentation(runnersInterModuleContract, {
|
|
20
|
+
enqueueJobExecution: async (input) => {
|
|
21
|
+
try {
|
|
22
|
+
await enqueueJobExecution(input);
|
|
23
|
+
return {};
|
|
24
|
+
} catch (error) {
|
|
25
|
+
throw toEnqueueJobExecutionKnownError(error);
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
releaseJobExecution: async (input) => {
|
|
29
|
+
await releaseJobExecution(input);
|
|
30
|
+
return {};
|
|
31
|
+
},
|
|
32
|
+
cancelJobs: async (input) => {
|
|
33
|
+
await cancelRunnerJobs(input);
|
|
34
|
+
return {};
|
|
35
|
+
},
|
|
36
|
+
getLeaseState: async (input) => ({active: await isJobLeaseActive(input)}),
|
|
37
|
+
getEffectiveRunnerToolCapabilities: async (input) => {
|
|
38
|
+
const result = await getEffectiveRunnerToolCapabilities(input);
|
|
39
|
+
return {capabilities: result.capabilities, reportFresh: result.reportFresh};
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function toEnqueueJobExecutionKnownError(error: unknown): unknown {
|
|
45
|
+
if (error instanceof EmptyRequiredLabelsError) {
|
|
46
|
+
return createInterModuleKnownError(
|
|
47
|
+
runnersInterModuleContract.methods.enqueueJobExecution,
|
|
48
|
+
'empty-required-labels',
|
|
49
|
+
{},
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
return error;
|
|
53
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {requireProvisionerContext} from '@shipfox/api-auth-context';
|
|
2
|
+
import {
|
|
3
|
+
assignRunnerInstancesBodySchema,
|
|
4
|
+
assignRunnerInstancesResponseSchema,
|
|
5
|
+
} from '@shipfox/api-runners-dto';
|
|
6
|
+
import {ClientError, defineRoute} from '@shipfox/node-fastify';
|
|
7
|
+
import {
|
|
8
|
+
ReservationExpiredError,
|
|
9
|
+
ReservationNotFoundError,
|
|
10
|
+
RunnerInstanceAlreadyAssignedError,
|
|
11
|
+
RunnerInstanceNotAssignableError,
|
|
12
|
+
} from '#core/errors.js';
|
|
13
|
+
import {assignRunnerInstances} from '#core/runner-assignments.js';
|
|
14
|
+
|
|
15
|
+
export const assignRunnerInstancesRoute = defineRoute({
|
|
16
|
+
method: 'POST',
|
|
17
|
+
path: '/runner-instances/assignments',
|
|
18
|
+
description: 'Assign enrolled runner instances to an owned demand reservation',
|
|
19
|
+
schema: {
|
|
20
|
+
body: assignRunnerInstancesBodySchema,
|
|
21
|
+
response: {200: assignRunnerInstancesResponseSchema},
|
|
22
|
+
},
|
|
23
|
+
errorHandler: (error) => {
|
|
24
|
+
if (error instanceof ReservationNotFoundError)
|
|
25
|
+
throw new ClientError('Reservation not found', 'reservation-not-found', {status: 404});
|
|
26
|
+
if (error instanceof ReservationExpiredError)
|
|
27
|
+
throw new ClientError('Reservation has expired', 'reservation-expired', {status: 409});
|
|
28
|
+
if (
|
|
29
|
+
error instanceof RunnerInstanceAlreadyAssignedError ||
|
|
30
|
+
error instanceof RunnerInstanceNotAssignableError
|
|
31
|
+
)
|
|
32
|
+
throw new ClientError(
|
|
33
|
+
'Runner instance cannot be assigned',
|
|
34
|
+
'runner-instance-not-assignable',
|
|
35
|
+
{status: 409},
|
|
36
|
+
);
|
|
37
|
+
throw error;
|
|
38
|
+
},
|
|
39
|
+
handler: async (request) => {
|
|
40
|
+
const {provisionerTokenId} = requireProvisionerContext(request);
|
|
41
|
+
return {
|
|
42
|
+
runner_instance_ids: await assignRunnerInstances({
|
|
43
|
+
provisionerId: provisionerTokenId,
|
|
44
|
+
reservationId: request.body.reservation_id,
|
|
45
|
+
runnerInstanceIds: request.body.runner_instance_ids,
|
|
46
|
+
}),
|
|
47
|
+
};
|
|
48
|
+
},
|
|
49
|
+
});
|
|
@@ -14,9 +14,8 @@ export const getProvisionerMeRoute = defineRoute({
|
|
|
14
14
|
handler: (request) => {
|
|
15
15
|
const context = requireProvisionerContext(request);
|
|
16
16
|
|
|
17
|
-
return
|
|
18
|
-
id: context.provisionerTokenId,
|
|
19
|
-
|
|
20
|
-
};
|
|
17
|
+
return context.scope === 'workspace'
|
|
18
|
+
? {id: context.provisionerTokenId, scope: 'workspace', workspace_id: context.workspaceId}
|
|
19
|
+
: {id: context.provisionerTokenId, scope: 'installation'};
|
|
21
20
|
},
|
|
22
21
|
});
|
|
@@ -17,8 +17,8 @@ import {requestJobExecutionCancellation} from '#db/job-executions.js';
|
|
|
17
17
|
import {runnerSessions} from '#db/schema/runner-sessions.js';
|
|
18
18
|
import {runningJobExecutions} from '#db/schema/running-job-executions.js';
|
|
19
19
|
import {createRunnerRegistrationTokenAuthMethod} from '#presentation/auth/index.js';
|
|
20
|
-
import {pendingJobFactory, runnerSessionFactory} from '#test/index.js';
|
|
21
|
-
import {
|
|
20
|
+
import {pendingJobFactory, runnerSessionFactory, runnersTestAuthClient} from '#test/index.js';
|
|
21
|
+
import {createRunnerRoutes} from './index.js';
|
|
22
22
|
|
|
23
23
|
const fakeUserAuth: AuthMethod = {
|
|
24
24
|
name: AUTH_USER,
|
|
@@ -57,7 +57,7 @@ describe('POST /runners/jobs/:jobId/heartbeat', () => {
|
|
|
57
57
|
createLeaseTokenAuthMethod(),
|
|
58
58
|
fakeProvisionerAuth,
|
|
59
59
|
],
|
|
60
|
-
routes:
|
|
60
|
+
routes: createRunnerRoutes(runnersTestAuthClient),
|
|
61
61
|
swagger: false,
|
|
62
62
|
});
|
|
63
63
|
await app.ready();
|
|
@@ -82,6 +82,7 @@ describe('POST /runners/jobs/:jobId/heartbeat', () => {
|
|
|
82
82
|
}> {
|
|
83
83
|
const pending = await pendingJobFactory.create({workspaceId});
|
|
84
84
|
const claimed = await claimJobExecution({
|
|
85
|
+
auth: runnersTestAuthClient,
|
|
85
86
|
workspaceId,
|
|
86
87
|
runnerSessionId,
|
|
87
88
|
sessionLabels: ['linux', 'x64'],
|