@kici-dev/orchestrator 0.0.0 → 0.1.2
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/LICENSE +661 -0
- package/README.md +1 -6
- package/dist/__test-helpers__/mock-db.d.ts +103 -0
- package/dist/__test-helpers__/mock-ws.d.ts +13 -0
- package/dist/agent/dispatcher.d.ts +231 -0
- package/dist/agent/ownership-tracker.d.ts +46 -0
- package/dist/agent/registry.d.ts +255 -0
- package/dist/agent/token-store.d.ts +96 -0
- package/dist/app.d.ts +234 -0
- package/dist/audit/access-log.d.ts +92 -0
- package/dist/audit/sampling-rate-limiter.d.ts +41 -0
- package/dist/cache/build-coordinator.d.ts +42 -0
- package/dist/cache/dep-cache.d.ts +51 -0
- package/dist/cache/index.d.ts +16 -0
- package/dist/cache/pending-builds.d.ts +14 -0
- package/dist/cache/pending-dynamics.d.ts +15 -0
- package/dist/cache/pending-inits.d.ts +19 -0
- package/dist/cache/pending-tracker.d.ts +65 -0
- package/dist/cache/source-cache.d.ts +30 -0
- package/dist/cli/api-client.d.ts +411 -0
- package/dist/cli/commands/access-log.d.ts +30 -0
- package/dist/cli/commands/agent-service/index.d.ts +15 -0
- package/dist/cli/commands/agent-service/install.d.ts +9 -0
- package/dist/cli/commands/agent-service/logs.d.ts +9 -0
- package/dist/cli/commands/agent-service/restart.d.ts +8 -0
- package/dist/cli/commands/agent-service/start.d.ts +8 -0
- package/dist/cli/commands/agent-service/status.d.ts +10 -0
- package/dist/cli/commands/agent-service/stop.d.ts +8 -0
- package/dist/cli/commands/agent-service/uninstall.d.ts +9 -0
- package/dist/cli/commands/agent-service/upgrade.d.ts +11 -0
- package/dist/cli/commands/agent.d.ts +10 -0
- package/dist/cli/commands/api-key.d.ts +12 -0
- package/dist/cli/commands/audit.d.ts +9 -0
- package/dist/cli/commands/backend.d.ts +17 -0
- package/dist/cli/commands/cold-store-impl.d.ts +101 -0
- package/dist/cli/commands/cold-store.d.ts +30 -0
- package/dist/cli/commands/config.d.ts +16 -0
- package/dist/cli/commands/db.d.ts +19 -0
- package/dist/cli/commands/debug-bundle.d.ts +16 -0
- package/dist/cli/commands/diagnose.d.ts +15 -0
- package/dist/cli/commands/environment.d.ts +24 -0
- package/dist/cli/commands/event-dlq.d.ts +19 -0
- package/dist/cli/commands/event-log.d.ts +27 -0
- package/dist/cli/commands/event.d.ts +4 -0
- package/dist/cli/commands/execution.d.ts +17 -0
- package/dist/cli/commands/inspect-bundle.d.ts +16 -0
- package/dist/cli/commands/maintenance.d.ts +4 -0
- package/dist/cli/commands/orchestrator-service/index.d.ts +12 -0
- package/dist/cli/commands/orchestrator-service/install.d.ts +10 -0
- package/dist/cli/commands/orchestrator-service/logs.d.ts +10 -0
- package/dist/cli/commands/orchestrator-service/restart.d.ts +8 -0
- package/dist/cli/commands/orchestrator-service/start.d.ts +8 -0
- package/dist/cli/commands/orchestrator-service/status.d.ts +10 -0
- package/dist/cli/commands/orchestrator-service/stop.d.ts +8 -0
- package/dist/cli/commands/orchestrator-service/uninstall.d.ts +9 -0
- package/dist/cli/commands/orchestrator-service/upgrade.d.ts +12 -0
- package/dist/cli/commands/org-settings.d.ts +17 -0
- package/dist/cli/commands/peer.d.ts +13 -0
- package/dist/cli/commands/queue.d.ts +16 -0
- package/dist/cli/commands/registration.d.ts +18 -0
- package/dist/cli/commands/rotate.d.ts +9 -0
- package/dist/cli/commands/runs.d.ts +34 -0
- package/dist/cli/commands/secret.d.ts +12 -0
- package/dist/cli/commands/shared/db.d.ts +16 -0
- package/dist/cli/commands/shared/versioned-upgrade.d.ts +38 -0
- package/dist/cli/commands/source.d.ts +24 -0
- package/dist/cli/commands/token.d.ts +10 -0
- package/dist/cli/commands/workflow.d.ts +31 -0
- package/dist/cli/join.d.ts +14 -0
- package/dist/cli/kici-admin.d.ts +13 -0
- package/dist/cli/lazy-deps/cache.d.ts +17 -0
- package/dist/cli/lazy-deps/downloader.d.ts +33 -0
- package/dist/cli/lazy-deps/registry.d.ts +43 -0
- package/dist/cli/service/compose.d.ts +25 -0
- package/dist/cli/service/index.d.ts +24 -0
- package/dist/cli/service/launchd.d.ts +34 -0
- package/dist/cli/service/platform-detect.d.ts +59 -0
- package/dist/cli/service/systemd.d.ts +41 -0
- package/dist/cli/service/types.d.ts +91 -0
- package/dist/cli/service/windows.d.ts +20 -0
- package/dist/cli/wizard/agent-wizard.d.ts +24 -0
- package/dist/cli/wizard/orchestrator-wizard.d.ts +38 -0
- package/dist/cli/wizard/prompts.d.ts +23 -0
- package/dist/cli.js +11435 -0
- package/dist/cluster/cluster-identity.d.ts +59 -0
- package/dist/cluster/coordinator.d.ts +204 -0
- package/dist/cluster/health-api.d.ts +30 -0
- package/dist/cluster/index.d.ts +24 -0
- package/dist/cluster/join-client.d.ts +75 -0
- package/dist/cluster/join-handler.d.ts +58 -0
- package/dist/cluster/join-token.d.ts +94 -0
- package/dist/cluster/orphan-recovery.d.ts +67 -0
- package/dist/cluster/peer-client.d.ts +190 -0
- package/dist/cluster/peer-credentials.d.ts +108 -0
- package/dist/cluster/peer-crypto.d.ts +57 -0
- package/dist/cluster/peer-handler.d.ts +97 -0
- package/dist/cluster/peer-registry.d.ts +186 -0
- package/dist/cluster/raft-state.d.ts +36 -0
- package/dist/cluster/raft.d.ts +140 -0
- package/dist/cold-store/load-access-log-range.d.ts +73 -0
- package/dist/cold-store/load-event-log-range.d.ts +62 -0
- package/dist/cold-store/load-secret-audit-log-range.d.ts +38 -0
- package/dist/cold-store/orchestrator-cold-store.d.ts +58 -0
- package/dist/cold-store/tables/access-log.d.ts +80 -0
- package/dist/cold-store/tables/event-log.d.ts +70 -0
- package/dist/cold-store/tables/execution-jobs.d.ts +63 -0
- package/dist/cold-store/tables/execution-runs.d.ts +81 -0
- package/dist/cold-store/tables/execution-steps.d.ts +65 -0
- package/dist/cold-store/tables/secret-audit-log.d.ts +77 -0
- package/dist/concurrency/dispatch-next-queued.d.ts +63 -0
- package/dist/concurrency/group-tracker.d.ts +51 -0
- package/dist/concurrency/index.d.ts +3 -0
- package/dist/concurrency/queue-manager.d.ts +68 -0
- package/dist/concurrency/waiters.d.ts +58 -0
- package/dist/config/encryption.d.ts +82 -0
- package/dist/config/env-overlay.d.ts +45 -0
- package/dist/config/index.d.ts +16 -0
- package/dist/config/loader.d.ts +26 -0
- package/dist/config/reload.d.ts +113 -0
- package/dist/config/resolver.d.ts +47 -0
- package/dist/config/schema.d.ts +210 -0
- package/dist/config/shared-store.d.ts +142 -0
- package/dist/config/types.d.ts +218 -0
- package/dist/config.d.ts +249 -0
- package/dist/cron/cron-scheduler.d.ts +78 -0
- package/dist/cron/cron-store.d.ts +38 -0
- package/dist/dashboard/handler.d.ts +243 -0
- package/dist/db/client.d.ts +13 -0
- package/dist/db/migration-provider.d.ts +9 -0
- package/dist/db/migrations/001_initial.d.ts +8 -0
- package/dist/db/migrations/002_config_versions_key_version.d.ts +16 -0
- package/dist/db/migrations/003_access_log.d.ts +26 -0
- package/dist/db/migrations/004_rename_bundle_to_source.d.ts +19 -0
- package/dist/db/migrations/005_cold_store_chunk_counter.d.ts +19 -0
- package/dist/db/migrations/006_runs_jobs_steps_archived_at.d.ts +38 -0
- package/dist/db/migrations/007_audit_logs_archived_at.d.ts +42 -0
- package/dist/db/migrations/008_event_log_archived_at.d.ts +40 -0
- package/dist/db/migrations/009_access_log_trigram.d.ts +15 -0
- package/dist/db/migrations/010_cold_store_chunks.d.ts +34 -0
- package/dist/db/migrations/011_drop_source_secrets_notify.d.ts +21 -0
- package/dist/db/migrations/012_peer_credentials_active_uniq.d.ts +28 -0
- package/dist/db/migrations/013_execution_log_bytes.d.ts +21 -0
- package/dist/db/migrations/014_kici_events_lease_retry.d.ts +36 -0
- package/dist/db/migrations/015_org_settings_customer_scoped.d.ts +30 -0
- package/dist/db/migrations/016_org_settings_allow_http_npm.d.ts +15 -0
- package/dist/db/migrations/017_org_id_widen.d.ts +4 -0
- package/dist/db/migrations/018_org_id_prefix_backfill.d.ts +4 -0
- package/dist/db/migrator.d.ts +32 -0
- package/dist/db/types.d.ts +1266 -0
- package/dist/diagnostics/bundle-reader.d.ts +48 -0
- package/dist/diagnostics/bundle-writer.d.ts +57 -0
- package/dist/diagnostics/checks/agents.d.ts +10 -0
- package/dist/diagnostics/checks/certs.d.ts +9 -0
- package/dist/diagnostics/checks/config.d.ts +10 -0
- package/dist/diagnostics/checks/db.d.ts +9 -0
- package/dist/diagnostics/checks/disk.d.ts +9 -0
- package/dist/diagnostics/checks/index.d.ts +17 -0
- package/dist/diagnostics/checks/ws.d.ts +9 -0
- package/dist/diagnostics/index.d.ts +13 -0
- package/dist/diagnostics/runner.d.ts +23 -0
- package/dist/diagnostics/types.d.ts +38 -0
- package/dist/entry-helpers.d.ts +93 -0
- package/dist/environments/binding-store.d.ts +27 -0
- package/dist/environments/environment-store.d.ts +74 -0
- package/dist/environments/held-runs.d.ts +64 -0
- package/dist/environments/index.d.ts +10 -0
- package/dist/environments/protection/branch-gate.d.ts +5 -0
- package/dist/environments/protection/concurrency-gate.d.ts +7 -0
- package/dist/environments/protection/pipeline.d.ts +18 -0
- package/dist/environments/protection/reviewer-gate.d.ts +7 -0
- package/dist/environments/protection/trust-gate.d.ts +7 -0
- package/dist/environments/protection/wait-timer-gate.d.ts +7 -0
- package/dist/environments/variable-store.d.ts +39 -0
- package/dist/events/circuit-breaker.d.ts +33 -0
- package/dist/events/event-emitter.d.ts +55 -0
- package/dist/events/event-retry-scanner.d.ts +52 -0
- package/dist/events/event-router.d.ts +183 -0
- package/dist/events/event-store.d.ts +157 -0
- package/dist/events/trust-store.d.ts +54 -0
- package/dist/events/types.d.ts +61 -0
- package/dist/helpers/ip-extraction.d.ts +29 -0
- package/dist/helpers/rate-limiter.d.ts +23 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +772 -0
- package/dist/lockfile-cache.d.ts +39 -0
- package/dist/metrics/agent-metrics-aggregator.d.ts +116 -0
- package/dist/metrics/metrics-reporter.d.ts +40 -0
- package/dist/metrics/prometheus.d.ts +261 -0
- package/dist/metrics/scheduled-jobs.d.ts +20 -0
- package/dist/orchestrator-core.d.ts +193 -0
- package/dist/pipeline/dispatch-matched-workflow.d.ts +102 -0
- package/dist/pipeline/inline-eval.d.ts +28 -0
- package/dist/pipeline/install-secrets-resolver.d.ts +73 -0
- package/dist/pipeline/manual-schedule.d.ts +21 -0
- package/dist/pipeline/needs-scheduler.d.ts +85 -0
- package/dist/pipeline/process-webhook.d.ts +38 -0
- package/dist/pipeline/processor.d.ts +326 -0
- package/dist/pipeline/rerun.d.ts +79 -0
- package/dist/pipeline/test-pipeline.d.ts +110 -0
- package/dist/provider-registry.d.ts +122 -0
- package/dist/providers/generic/index.d.ts +23 -0
- package/dist/providers/generic/normalizer.d.ts +112 -0
- package/dist/providers/generic/verification.d.ts +47 -0
- package/dist/providers/github/auth.d.ts +60 -0
- package/dist/providers/github/changed-files.d.ts +51 -0
- package/dist/providers/github/check-status-poster.d.ts +35 -0
- package/dist/providers/github/contributor-resolver.d.ts +30 -0
- package/dist/providers/github/index.d.ts +20 -0
- package/dist/providers/github/lock-file.d.ts +32 -0
- package/dist/providers/github/normalizer.d.ts +103 -0
- package/dist/providers/github/repo-url.d.ts +35 -0
- package/dist/providers/internal/index.d.ts +32 -0
- package/dist/providers/internal/lock-file-fetcher.d.ts +34 -0
- package/dist/providers/internal/normalizer.d.ts +89 -0
- package/dist/providers/internal/repo-url-builder.d.ts +42 -0
- package/dist/providers/universal-git/changed-files.d.ts +42 -0
- package/dist/providers/universal-git/clone-token.d.ts +83 -0
- package/dist/providers/universal-git/config.d.ts +192 -0
- package/dist/providers/universal-git/index.d.ts +55 -0
- package/dist/providers/universal-git/lock-file.d.ts +71 -0
- package/dist/providers/universal-git/normalizer.d.ts +90 -0
- package/dist/providers/universal-git/repo-url.d.ts +50 -0
- package/dist/providers/universal-git/ssh-auth.d.ts +94 -0
- package/dist/queue/bootstrap.d.ts +50 -0
- package/dist/queue/cleanup.d.ts +41 -0
- package/dist/queue/depth-refresher.d.ts +65 -0
- package/dist/queue/job-queue.d.ts +343 -0
- package/dist/queue/scheduled-job.d.ts +91 -0
- package/dist/registration/extractor.d.ts +44 -0
- package/dist/registration/registration-index.d.ts +162 -0
- package/dist/registration/registration-store.d.ts +111 -0
- package/dist/reporting/check-run-summary.d.ts +102 -0
- package/dist/reporting/commit-status.d.ts +382 -0
- package/dist/reporting/execution-tracker.d.ts +538 -0
- package/dist/reporting/fs-log-storage.d.ts +41 -0
- package/dist/reporting/log-pull-handler.d.ts +35 -0
- package/dist/reporting/log-storage.d.ts +70 -0
- package/dist/reporting/log-writer.d.ts +45 -0
- package/dist/reporting/s3-log-storage.d.ts +42 -0
- package/dist/reporting/step-log-buffer.d.ts +57 -0
- package/dist/routes/admin-access-log.d.ts +34 -0
- package/dist/routes/admin-backends.d.ts +28 -0
- package/dist/routes/admin-config.d.ts +57 -0
- package/dist/routes/admin-db.d.ts +20 -0
- package/dist/routes/admin-environments.d.ts +42 -0
- package/dist/routes/admin-errors.d.ts +4 -0
- package/dist/routes/admin-event-dlq.d.ts +39 -0
- package/dist/routes/admin-event-log.d.ts +42 -0
- package/dist/routes/admin-events.d.ts +46 -0
- package/dist/routes/admin-maintenance.d.ts +22 -0
- package/dist/routes/admin-org-settings.d.ts +29 -0
- package/dist/routes/admin-queue-execution.d.ts +27 -0
- package/dist/routes/admin-registrations.d.ts +37 -0
- package/dist/routes/admin-runs.d.ts +57 -0
- package/dist/routes/admin-scheduled-jobs.d.ts +36 -0
- package/dist/routes/admin-sources.d.ts +18 -0
- package/dist/routes/admin.d.ts +103 -0
- package/dist/routes/capabilities.d.ts +24 -0
- package/dist/routes/diagnostics.d.ts +16 -0
- package/dist/routes/health.d.ts +20 -0
- package/dist/routes/test-trigger.d.ts +41 -0
- package/dist/routes/uploads.d.ts +38 -0
- package/dist/routes/webhooks.d.ts +36 -0
- package/dist/scaler/bare-metal-backend.d.ts +107 -0
- package/dist/scaler/config.d.ts +303 -0
- package/dist/scaler/container-backend.d.ts +125 -0
- package/dist/scaler/file-tail.d.ts +23 -0
- package/dist/scaler/firecracker-api.d.ts +100 -0
- package/dist/scaler/firecracker-backend.d.ts +263 -0
- package/dist/scaler/index.d.ts +24 -0
- package/dist/scaler/ip-allocator.d.ts +177 -0
- package/dist/scaler/label-matcher.d.ts +73 -0
- package/dist/scaler/log-forwarder.d.ts +54 -0
- package/dist/scaler/machine-ledger.d.ts +160 -0
- package/dist/scaler/manager.d.ts +338 -0
- package/dist/scaler/nftables.d.ts +85 -0
- package/dist/scaler/types.d.ts +388 -0
- package/dist/scaler/warm-pool.d.ts +81 -0
- package/dist/secrets/audit-logger.d.ts +65 -0
- package/dist/secrets/backend-health.d.ts +60 -0
- package/dist/secrets/backend-registry.d.ts +68 -0
- package/dist/secrets/backend-sync.d.ts +40 -0
- package/dist/secrets/cleanup.d.ts +40 -0
- package/dist/secrets/config.d.ts +51 -0
- package/dist/secrets/crypto.d.ts +49 -0
- package/dist/secrets/ephemeral-keys.d.ts +49 -0
- package/dist/secrets/index.d.ts +17 -0
- package/dist/secrets/pg-secret-store.d.ts +105 -0
- package/dist/secrets/rbac.d.ts +47 -0
- package/dist/secrets/secret-output-store.d.ts +46 -0
- package/dist/secrets/secret-resolver.d.ts +137 -0
- package/dist/secrets/source-credentials.d.ts +61 -0
- package/dist/secrets/token-manager.d.ts +63 -0
- package/dist/secrets/vault-secret-store.d.ts +85 -0
- package/dist/security/comment-handler.d.ts +67 -0
- package/dist/security/contributor-cache.d.ts +75 -0
- package/dist/security/global-workflow-policy.d.ts +72 -0
- package/dist/security/lock-source.d.ts +34 -0
- package/dist/security/trust-resolver.d.ts +108 -0
- package/dist/security/workflow-diff.d.ts +26 -0
- package/dist/server.d.ts +17 -0
- package/dist/server.js +48055 -0
- package/dist/sources/index.d.ts +10 -0
- package/dist/sources/source-manager.d.ts +63 -0
- package/dist/sources/source-store.d.ts +79 -0
- package/dist/sources/source-validator.d.ts +16 -0
- package/dist/stale-detector/stale-run-detector.d.ts +109 -0
- package/dist/standalone.d.ts +20 -0
- package/dist/standalone.js +41546 -0
- package/dist/storage/blob-routes.d.ts +20 -0
- package/dist/storage/filesystem.d.ts +60 -0
- package/dist/storage/index.d.ts +20 -0
- package/dist/storage/s3.d.ts +68 -0
- package/dist/storage/sign-url.d.ts +45 -0
- package/dist/storage/types.d.ts +98 -0
- package/dist/webhook/dedup.d.ts +44 -0
- package/dist/webhook/event-log.d.ts +83 -0
- package/dist/webhook/generic-sources.d.ts +169 -0
- package/dist/webhook/handler.d.ts +23 -0
- package/dist/webhook/relay-buffer.d.ts +96 -0
- package/dist/webhook/verify-inbound.d.ts +78 -0
- package/dist/worker/in-memory-execution-tracker.d.ts +94 -0
- package/dist/worker/in-memory-job-queue.d.ts +74 -0
- package/dist/worker/static-agent-token-store.d.ts +58 -0
- package/dist/worker/worker-status.d.ts +36 -0
- package/dist/worker-core.d.ts +74 -0
- package/dist/ws/agent-api-registry.d.ts +49 -0
- package/dist/ws/agent-handler.d.ts +176 -0
- package/dist/ws/agent-heartbeat.d.ts +45 -0
- package/dist/ws/dashboard-backends-handler.d.ts +51 -0
- package/dist/ws/dashboard-diagnostics-handler.d.ts +56 -0
- package/dist/ws/dashboard-env-handler.d.ts +107 -0
- package/dist/ws/dashboard-global-workflows-handler.d.ts +72 -0
- package/dist/ws/dashboard-registrations-handler.d.ts +84 -0
- package/dist/ws/event-buffer.d.ts +16 -0
- package/dist/ws/observer-handler.d.ts +42 -0
- package/dist/ws/observer-registry.d.ts +88 -0
- package/dist/ws/platform-client.d.ts +270 -0
- package/dist/ws/server-options.d.ts +15 -0
- package/package.json +87 -7
- package/sbom.spdx.json +14370 -0
- package/index.js +0 -3
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal-git repository URL builder.
|
|
3
|
+
*
|
|
4
|
+
* Implements the `RepoUrlBuilder` interface from `@kici-dev/engine`. Each
|
|
5
|
+
* universal-git source provides a `gitUrlTemplate` (e.g.
|
|
6
|
+
* `https://forgejo.example.com/{owner}/{name}.git` or
|
|
7
|
+
* `ssh://git@forgejo.example.com/{owner}/{name}.git`) plus a `repoIdentifier`
|
|
8
|
+
* that appears in the normalized webhook (typically `owner/name`). This class
|
|
9
|
+
* substitutes `{owner}`, `{name}`, and `{repo}` placeholders to build the
|
|
10
|
+
* concrete clone URL used by agents.
|
|
11
|
+
*/
|
|
12
|
+
import type { RepoUrlBuilder } from '@kici-dev/engine';
|
|
13
|
+
/**
|
|
14
|
+
* Universal-git implementation of RepoUrlBuilder.
|
|
15
|
+
*
|
|
16
|
+
* Bound to a single source's URL template — the orchestrator constructs one
|
|
17
|
+
* per registered universal-git source.
|
|
18
|
+
*/
|
|
19
|
+
export declare class UniversalGitRepoUrlBuilder implements RepoUrlBuilder {
|
|
20
|
+
private readonly gitUrlTemplate;
|
|
21
|
+
readonly provider: "generic";
|
|
22
|
+
constructor(gitUrlTemplate: string);
|
|
23
|
+
/**
|
|
24
|
+
* Build the clone URL by substituting placeholders in the template with
|
|
25
|
+
* values from the repo identifier (expected as `owner/name`).
|
|
26
|
+
*
|
|
27
|
+
* Accepts identifiers with a single slash (`owner/name`) or with multiple
|
|
28
|
+
* segments (GitLab groups: `group/subgroup/project`); the trailing segment
|
|
29
|
+
* is always treated as the repo name and everything before it as the
|
|
30
|
+
* owner path.
|
|
31
|
+
*/
|
|
32
|
+
buildCloneUrl(repoIdentifier: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Raw file URLs are not supported for universal-git sources — the agent
|
|
35
|
+
* always shallow-clones the repo to fetch files. Returning the clone URL
|
|
36
|
+
* keeps the interface contract honest; callers that need raw content must
|
|
37
|
+
* use the shallow-clone path instead.
|
|
38
|
+
*/
|
|
39
|
+
buildRawFileUrl(repoIdentifier: string, _ref: string, _path: string): string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Split `owner/name` or `group/subgroup/project` into the owner path plus
|
|
43
|
+
* the final repo name. Throws on malformed input so misconfigured sources
|
|
44
|
+
* fail loudly rather than producing broken clone URLs.
|
|
45
|
+
*/
|
|
46
|
+
export declare function splitRepoIdentifier(repoIdentifier: string): {
|
|
47
|
+
owner: string;
|
|
48
|
+
name: string;
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=repo-url.d.ts.map
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSH auth helper for universal-git sources.
|
|
3
|
+
*
|
|
4
|
+
* When a universal-git source uses `credentialType: 'ssh'`, the agent needs
|
|
5
|
+
* three things to run `git clone`:
|
|
6
|
+
* 1. The PEM-encoded private key materialized to a tempfile with mode 0600.
|
|
7
|
+
* 2. A `GIT_SSH_COMMAND` that points `ssh -i` at that tempfile.
|
|
8
|
+
* 3. A `StrictHostKeyChecking` policy that matches the source config —
|
|
9
|
+
* either `accept-new` (TOFU) or `yes` with a pinned `known_hosts` file.
|
|
10
|
+
*
|
|
11
|
+
* This module provides the orchestrator-side primitives for preparing those
|
|
12
|
+
* artefacts. It is used in two contexts:
|
|
13
|
+
* - **Agent-side** (Phase 4+): the agent receives the PEM + host-key policy
|
|
14
|
+
* in the dispatch message and materializes them before cloning.
|
|
15
|
+
* - **Lock-file fetcher** (Phase 2, this module's immediate consumer):
|
|
16
|
+
* the orchestrator shallow-clones the source repo itself at registration
|
|
17
|
+
* time, using the same SSH materialization path.
|
|
18
|
+
*
|
|
19
|
+
* All materialized tempfiles are created under `os.tmpdir()` in a private
|
|
20
|
+
* per-call subdirectory (`fs.mkdtempSync(.../kici-ugit-ssh-`)`), so
|
|
21
|
+
* concurrent clones never clobber each other. The returned `cleanup()`
|
|
22
|
+
* closure removes the directory recursively — callers MUST call it in a
|
|
23
|
+
* `finally` block.
|
|
24
|
+
*/
|
|
25
|
+
import type { SshHostKeyPolicy } from './config.js';
|
|
26
|
+
/** Material the caller has prepared (key file + optional known_hosts file). */
|
|
27
|
+
export interface SshAuthArtefacts {
|
|
28
|
+
/** Absolute path to the private key file (mode 0600). */
|
|
29
|
+
privateKeyPath: string;
|
|
30
|
+
/** Absolute path to the known_hosts file, if `policy === 'pinned'`. */
|
|
31
|
+
knownHostsPath?: string;
|
|
32
|
+
/** Complete GIT_SSH_COMMAND string to export when running git. */
|
|
33
|
+
gitSshCommand: string;
|
|
34
|
+
/** Dispose of every tempfile + the parent directory. Must be called. */
|
|
35
|
+
cleanup: () => Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Synchronous variant — used when the caller is already in synchronous
|
|
39
|
+
* lock-file fetching logic. The structure matches the async version so
|
|
40
|
+
* callers can swap freely.
|
|
41
|
+
*/
|
|
42
|
+
export interface SshAuthArtefactsSync {
|
|
43
|
+
privateKeyPath: string;
|
|
44
|
+
knownHostsPath?: string;
|
|
45
|
+
gitSshCommand: string;
|
|
46
|
+
cleanup: () => void;
|
|
47
|
+
}
|
|
48
|
+
/** Options common to both sync and async variants. */
|
|
49
|
+
export interface PrepareSshAuthOptions {
|
|
50
|
+
/** PEM-encoded private key. */
|
|
51
|
+
privateKey: string;
|
|
52
|
+
/** Host-key verification policy. */
|
|
53
|
+
policy: SshHostKeyPolicy;
|
|
54
|
+
/**
|
|
55
|
+
* OpenSSH known_hosts content. Required when `policy === 'pinned'`, ignored
|
|
56
|
+
* otherwise.
|
|
57
|
+
*/
|
|
58
|
+
knownHostsPem?: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Async: materialize the private key (and pinned known_hosts) into a private
|
|
62
|
+
* tempdir, returning paths + the `GIT_SSH_COMMAND` the agent should export.
|
|
63
|
+
*
|
|
64
|
+
* @throws If `policy === 'pinned'` and `knownHostsPem` is missing.
|
|
65
|
+
*/
|
|
66
|
+
export declare function prepareSshAuth(opts: PrepareSshAuthOptions): Promise<SshAuthArtefacts>;
|
|
67
|
+
/**
|
|
68
|
+
* Sync variant of `prepareSshAuth`. Semantics are identical; the caller
|
|
69
|
+
* receives a synchronous `cleanup()` closure.
|
|
70
|
+
*/
|
|
71
|
+
export declare function prepareSshAuthSync(opts: PrepareSshAuthOptions): SshAuthArtefactsSync;
|
|
72
|
+
/**
|
|
73
|
+
* Compose the GIT_SSH_COMMAND string. Honors the host-key policy:
|
|
74
|
+
* - `accept-new`: `StrictHostKeyChecking=accept-new` (TOFU on the per-call
|
|
75
|
+
* empty known_hosts file).
|
|
76
|
+
* - `pinned`: `StrictHostKeyChecking=yes` (rejects any unknown host key).
|
|
77
|
+
*
|
|
78
|
+
* Both policies pin `UserKnownHostsFile` to the per-call tempfile so the
|
|
79
|
+
* orchestrator never reads or writes the runtime user's
|
|
80
|
+
* `~/.ssh/known_hosts`. Without this, a stale entry there for a host:port
|
|
81
|
+
* we're cloning from blocks the connection (accept-new still rejects
|
|
82
|
+
* mismatches against cached keys). The per-call file is wiped by `cleanup()`.
|
|
83
|
+
*
|
|
84
|
+
* IdentitiesOnly=yes ensures ssh ignores any agent-forwarded keys and only
|
|
85
|
+
* uses the one we provided; this is critical in staging where the runner
|
|
86
|
+
* user may have a populated ssh-agent.
|
|
87
|
+
*/
|
|
88
|
+
export declare function composeGitSshCommand(privateKeyPath: string, policy: SshHostKeyPolicy, knownHostsPath: string): string;
|
|
89
|
+
/**
|
|
90
|
+
* Shell-quote a path for embedding in `GIT_SSH_COMMAND`. Single-quotes the
|
|
91
|
+
* string and escapes embedded single quotes — matches POSIX shell parsing.
|
|
92
|
+
*/
|
|
93
|
+
export declare function quoteShell(path: string): string;
|
|
94
|
+
//# sourceMappingURL=ssh-auth.d.ts.map
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestrator scheduled-jobs bootstrap helper.
|
|
3
|
+
*
|
|
4
|
+
* Composes `registerOrchestratorScheduledJob()` calls for all the
|
|
5
|
+
* orchestrator's periodic work. Returns an array of handles so the
|
|
6
|
+
* caller (orchestrator-core.ts) can thread them into
|
|
7
|
+
* `setupGracefulShutdown`.
|
|
8
|
+
*
|
|
9
|
+
* Commit 5 ships the infrastructure; Commit 6 migrates the three
|
|
10
|
+
* legacy setInterval schedulers (queue cleanup, secret cleanup,
|
|
11
|
+
* token cleanup) into this helper. Commit 7 adds the
|
|
12
|
+
* `cold-store-archive` entry.
|
|
13
|
+
*/
|
|
14
|
+
import type { Kysely } from 'kysely';
|
|
15
|
+
import type { Database } from '../db/types.js';
|
|
16
|
+
import { type OrchestratorScheduledJobHandle } from './scheduled-job.js';
|
|
17
|
+
export interface OrchestratorScheduledJobsDeps {
|
|
18
|
+
db: Kysely<Database>;
|
|
19
|
+
instanceId: string;
|
|
20
|
+
routingKey?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Overrides for the per-job handler + cadence. Callers pass the
|
|
24
|
+
* actual tick functions here — the bootstrap helper only composes
|
|
25
|
+
* registrations.
|
|
26
|
+
*/
|
|
27
|
+
export interface OrchestratorScheduledJobRegistrations {
|
|
28
|
+
cleanup?: {
|
|
29
|
+
intervalMs: number;
|
|
30
|
+
handler: () => Promise<void>;
|
|
31
|
+
};
|
|
32
|
+
orphanSecretCleanup?: {
|
|
33
|
+
intervalMs: number;
|
|
34
|
+
handler: () => Promise<void>;
|
|
35
|
+
};
|
|
36
|
+
tokenCleanup?: {
|
|
37
|
+
intervalMs: number;
|
|
38
|
+
handler: () => Promise<void>;
|
|
39
|
+
};
|
|
40
|
+
coldStoreArchive?: {
|
|
41
|
+
intervalMs: number;
|
|
42
|
+
handler: () => Promise<void>;
|
|
43
|
+
};
|
|
44
|
+
coldStorePurge?: {
|
|
45
|
+
intervalMs: number;
|
|
46
|
+
handler: () => Promise<void>;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export declare function bootstrapOrchestratorScheduledJobs(deps: OrchestratorScheduledJobsDeps, registrations: OrchestratorScheduledJobRegistrations): OrchestratorScheduledJobHandle[];
|
|
50
|
+
//# sourceMappingURL=bootstrap.d.ts.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
import type { Database } from '../db/types.js';
|
|
3
|
+
import type { ExecutionTracker } from '../reporting/execution-tracker.js';
|
|
4
|
+
import { JobQueue } from './job-queue.js';
|
|
5
|
+
/**
|
|
6
|
+
* Run a single cleanup pass: remove expired dedup_cache entries and
|
|
7
|
+
* mark expired dispatch_queue entries.
|
|
8
|
+
*
|
|
9
|
+
* When `extras` is provided, expired jobs are also forwarded to Platform
|
|
10
|
+
* as terminal status updates so the Platform execution_jobs projection
|
|
11
|
+
* stays in sync.
|
|
12
|
+
*
|
|
13
|
+
* Event-log row + payload retention used to live here too, but Phase E
|
|
14
|
+
* replaced the 30-day hard-delete with cold-store archive-then-delete
|
|
15
|
+
* (see `packages/orchestrator/src/cold-store/tables/event-log.ts`).
|
|
16
|
+
*
|
|
17
|
+
* @returns Counts of cleaned entries.
|
|
18
|
+
*/
|
|
19
|
+
export declare function runCleanup(dedup: {
|
|
20
|
+
cleanup(): Promise<number>;
|
|
21
|
+
}, queue: JobQueue, extras?: {
|
|
22
|
+
db: Kysely<Database>;
|
|
23
|
+
executionTracker: ExecutionTracker;
|
|
24
|
+
}): Promise<{
|
|
25
|
+
dedupDeleted: number;
|
|
26
|
+
queueExpired: number;
|
|
27
|
+
}>;
|
|
28
|
+
/**
|
|
29
|
+
* Build a per-tick handler for the queue-cleanup scheduled job.
|
|
30
|
+
*
|
|
31
|
+
* The cadence (`intervalMs`) and the periodic wrapper itself live in
|
|
32
|
+
* `packages/orchestrator/src/queue/scheduled-job.ts` — this factory
|
|
33
|
+
* just produces the tick function. `runCleanup` is unchanged.
|
|
34
|
+
*/
|
|
35
|
+
export declare function createCleanupHandler(dedup: {
|
|
36
|
+
cleanup(): Promise<number>;
|
|
37
|
+
}, queue: JobQueue, extras?: {
|
|
38
|
+
db: Kysely<Database>;
|
|
39
|
+
executionTracker: ExecutionTracker;
|
|
40
|
+
}): () => Promise<void>;
|
|
41
|
+
//# sourceMappingURL=cleanup.d.ts.map
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Periodic refresher for the dispatch-queue depth breakdown.
|
|
3
|
+
*
|
|
4
|
+
* Runs on a fixed interval (default 5s) — short enough that the
|
|
5
|
+
* Prometheus observable-gauge callback (which reads the JobQueue's
|
|
6
|
+
* synchronous cache) never serves data older than one refresh tick,
|
|
7
|
+
* long enough that a single orchestrator does not hammer the DB.
|
|
8
|
+
*
|
|
9
|
+
* Two responsibilities:
|
|
10
|
+
*
|
|
11
|
+
* 1. Call {@link JobQueue.getDepthBreakdown} to refresh the internal
|
|
12
|
+
* cache and feed {@link setDispatchQueueDepthBreakdown} so
|
|
13
|
+
* `kici_orch_dispatch_queue_depth` / `..._by_label` are always
|
|
14
|
+
* recent when Prometheus scrapes.
|
|
15
|
+
* 2. Watch for sustained backpressure: when the pending depth stays
|
|
16
|
+
* at or above {@link RefresherOptions.thresholdGetter | threshold}
|
|
17
|
+
* for two consecutive refreshes, emit a `logger.warn` that points
|
|
18
|
+
* operators at the per-label Grafana panel. The two-in-a-row
|
|
19
|
+
* guard suppresses transient spikes without needing a cooldown.
|
|
20
|
+
*
|
|
21
|
+
* Threshold is resolved lazily on every tick via `thresholdGetter` so
|
|
22
|
+
* live config reloads (SIGHUP / cluster propagation) take effect
|
|
23
|
+
* immediately without restarting the refresher.
|
|
24
|
+
*
|
|
25
|
+
* A threshold of `0` disables the warning entirely — the refresher
|
|
26
|
+
* still runs so metrics keep flowing.
|
|
27
|
+
*/
|
|
28
|
+
import type { Logger } from '@kici-dev/shared';
|
|
29
|
+
import { type JobQueue } from './job-queue.js';
|
|
30
|
+
export interface DepthRefresherOptions {
|
|
31
|
+
queue: JobQueue;
|
|
32
|
+
logger: Logger;
|
|
33
|
+
/**
|
|
34
|
+
* How often to refresh the cache / evaluate the warning threshold.
|
|
35
|
+
* Defaults to 5 seconds — short enough that Prometheus's default 15s
|
|
36
|
+
* scrape interval never sees data older than one tick.
|
|
37
|
+
*/
|
|
38
|
+
intervalMs?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Called on every tick to get the current backpressure warn
|
|
41
|
+
* threshold. `0` disables warnings.
|
|
42
|
+
*/
|
|
43
|
+
thresholdGetter: () => number;
|
|
44
|
+
/**
|
|
45
|
+
* Optional hook invoked after each successful tick, for tests.
|
|
46
|
+
*/
|
|
47
|
+
onTick?: (pendingDepth: number) => void;
|
|
48
|
+
}
|
|
49
|
+
export interface DepthRefresher {
|
|
50
|
+
/** Start the periodic timer. Idempotent. */
|
|
51
|
+
start(): void;
|
|
52
|
+
/** Stop the periodic timer. Idempotent. */
|
|
53
|
+
stop(): void;
|
|
54
|
+
/** Run one refresh synchronously (used at startup and in tests). */
|
|
55
|
+
refreshNow(): Promise<void>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Create a dispatch-queue depth refresher.
|
|
59
|
+
*
|
|
60
|
+
* The returned object is NOT started automatically — call `start()`
|
|
61
|
+
* after the orchestrator is otherwise ready. `stop()` must be called
|
|
62
|
+
* during shutdown to avoid leaking the interval handle.
|
|
63
|
+
*/
|
|
64
|
+
export declare function createDepthRefresher(options: DepthRefresherOptions): DepthRefresher;
|
|
65
|
+
//# sourceMappingURL=depth-refresher.d.ts.map
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { type Kysely } from 'kysely';
|
|
2
|
+
import type { ResourceRequest } from '@kici-dev/engine';
|
|
3
|
+
import type { Database } from '../db/types.js';
|
|
4
|
+
/** Info about an expired dispatch_queue entry, returned by markExpired(). */
|
|
5
|
+
export interface ExpiredJobInfo {
|
|
6
|
+
/** dispatch_queue row ID */
|
|
7
|
+
id: string;
|
|
8
|
+
runId: string;
|
|
9
|
+
jobName: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Point-in-time breakdown of dispatch_queue depth used for Prometheus gauges
|
|
13
|
+
* and operator-facing depth warnings.
|
|
14
|
+
*
|
|
15
|
+
* `byStatus` carries the raw COUNT(*) for each {@link DispatchQueueStatus.Pending}
|
|
16
|
+
* and {@link DispatchQueueStatus.Dispatched} bucket (other statuses are
|
|
17
|
+
* terminal and not surfaced here).
|
|
18
|
+
*
|
|
19
|
+
* `byLabel` is a flat rollup of pending-only jobs keyed by each distinct label
|
|
20
|
+
* in `runs_on_labels`. Multi-label jobs fan out: a job with `runs_on_labels =
|
|
21
|
+
* ['linux', 'x64']` contributes 1 to both `linux` and `x64`. This matches the
|
|
22
|
+
* "label pool" mental model operators use in Grafana (agents advertise their
|
|
23
|
+
* labels; the gauge answers "how many pending jobs want this label").
|
|
24
|
+
*/
|
|
25
|
+
export interface DispatchQueueDepthBreakdown {
|
|
26
|
+
byStatus: Partial<Record<DispatchQueueStatus, number>>;
|
|
27
|
+
byLabel: Record<string, number>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Status values for dispatch_queue entries.
|
|
31
|
+
*
|
|
32
|
+
* Lifecycle: pending → dispatched → completed | failed
|
|
33
|
+
* ↘ recovering → failed | dispatched (reclaimed)
|
|
34
|
+
* pending → expired (timeout)
|
|
35
|
+
*/
|
|
36
|
+
export declare enum DispatchQueueStatus {
|
|
37
|
+
Pending = "pending",
|
|
38
|
+
Dispatched = "dispatched",
|
|
39
|
+
Completed = "completed",
|
|
40
|
+
Failed = "failed",
|
|
41
|
+
Expired = "expired",
|
|
42
|
+
Recovering = "recovering"
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Input for enqueuing a job. Callers provide these fields;
|
|
46
|
+
* the queue generates id, status, created_at, and expires_at.
|
|
47
|
+
*/
|
|
48
|
+
export interface QueuedJobInput {
|
|
49
|
+
/**
|
|
50
|
+
* Optional pre-allocated job identifier. When set, the queue uses this
|
|
51
|
+
* exact id instead of generating one — required for the cluster reroute
|
|
52
|
+
* path so the sending coord can register execution_runs/execution_jobs
|
|
53
|
+
* rows under the same id the receiving worker dispatches against.
|
|
54
|
+
*/
|
|
55
|
+
jobId?: string;
|
|
56
|
+
runId: string;
|
|
57
|
+
workflowName: string;
|
|
58
|
+
jobName: string;
|
|
59
|
+
runsOnLabels: string[];
|
|
60
|
+
jobConfig: Record<string, unknown>;
|
|
61
|
+
repoUrl: string;
|
|
62
|
+
ref: string;
|
|
63
|
+
sha: string;
|
|
64
|
+
deliveryId: string;
|
|
65
|
+
/** Provider type (e.g., "github", "gitlab") */
|
|
66
|
+
provider: string;
|
|
67
|
+
/** Provider-specific context (e.g., { installationId: 42 } for GitHub) */
|
|
68
|
+
providerContext: Record<string, unknown>;
|
|
69
|
+
/** Routing key (e.g. "github:12345") for selecting the per-app provider
|
|
70
|
+
* bundle when dispatching. Required for multi-app safety. */
|
|
71
|
+
routingKey: string;
|
|
72
|
+
/** Override default timeout. 0 = indefinite (no expiry). */
|
|
73
|
+
timeoutMs?: number;
|
|
74
|
+
/** URL to pre-compiled bundle (from cache). Passed through to job.dispatch. */
|
|
75
|
+
sourceTarUrl?: string;
|
|
76
|
+
/** Content hash of the pre-compiled bundle for verification. */
|
|
77
|
+
sourceTarHash?: string;
|
|
78
|
+
/** URL to pre-built dependency tarball (from dep cache). Passed through to job.dispatch. */
|
|
79
|
+
depsUrl?: string;
|
|
80
|
+
/** SHA-256 hash of the dependency tarball for integrity verification. */
|
|
81
|
+
depsHash?: string;
|
|
82
|
+
/** Request trace ID for cross-tier correlation. Passed through to job.dispatch. */
|
|
83
|
+
requestId?: string;
|
|
84
|
+
/** Labels that the dispatched agent must NOT have. */
|
|
85
|
+
excludeLabels?: string[];
|
|
86
|
+
/**
|
|
87
|
+
* Per-job resource request and limit (K8s-style). Drives scaler cap accounting
|
|
88
|
+
* (`requests`) and kernel-side enforcement on the spawned agent (`limits`).
|
|
89
|
+
* Stored inside `jobConfig` JSON; this typed field is a convenience for callers.
|
|
90
|
+
*/
|
|
91
|
+
resources?: ResourceRequest;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Full queued job as stored in the database.
|
|
95
|
+
*/
|
|
96
|
+
export interface QueuedJob {
|
|
97
|
+
id: string;
|
|
98
|
+
runId: string;
|
|
99
|
+
workflowName: string;
|
|
100
|
+
jobName: string;
|
|
101
|
+
runsOnLabels: string[];
|
|
102
|
+
jobConfig: Record<string, unknown>;
|
|
103
|
+
repoUrl: string;
|
|
104
|
+
ref: string;
|
|
105
|
+
sha: string;
|
|
106
|
+
status: DispatchQueueStatus;
|
|
107
|
+
createdAt: string;
|
|
108
|
+
expiresAt: string | null;
|
|
109
|
+
deliveryId: string;
|
|
110
|
+
/** Provider type (e.g., "github", "gitlab") */
|
|
111
|
+
provider: string;
|
|
112
|
+
/** Provider-specific context */
|
|
113
|
+
providerContext: Record<string, unknown>;
|
|
114
|
+
/** Routing key (e.g. "github:12345") used to look up the per-app provider
|
|
115
|
+
* bundle on dispatch. Required for multi-app safety. */
|
|
116
|
+
routingKey: string;
|
|
117
|
+
/** URL to pre-compiled bundle (from cache). Passed through to job.dispatch. */
|
|
118
|
+
sourceTarUrl?: string;
|
|
119
|
+
/** Content hash of the pre-compiled bundle for verification. */
|
|
120
|
+
sourceTarHash?: string;
|
|
121
|
+
/** URL to pre-built dependency tarball (from dep cache). Passed through to job.dispatch. */
|
|
122
|
+
depsUrl?: string;
|
|
123
|
+
/** SHA-256 hash of the dependency tarball for integrity verification. */
|
|
124
|
+
depsHash?: string;
|
|
125
|
+
/** Request trace ID for cross-tier correlation. Passed through to job.dispatch. */
|
|
126
|
+
requestId?: string;
|
|
127
|
+
/** Labels that the dispatched agent must NOT have. */
|
|
128
|
+
excludeLabels: string[];
|
|
129
|
+
/**
|
|
130
|
+
* Per-job resource request and limit (K8s-style). Materialized from `jobConfig.resources`
|
|
131
|
+
* by `rowToQueuedJob` so callers can read it without re-parsing the JSON column.
|
|
132
|
+
*/
|
|
133
|
+
resources?: ResourceRequest;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* DB-backed FIFO job dispatch queue using Kysely (PostgreSQL only).
|
|
137
|
+
* Uses SQL-based JSONB containment queries (@> operator) for label matching.
|
|
138
|
+
*/
|
|
139
|
+
export declare class JobQueue {
|
|
140
|
+
private readonly db;
|
|
141
|
+
private readonly maxDepth;
|
|
142
|
+
private readonly defaultTimeoutMs;
|
|
143
|
+
/** 1-second TTL cache for pending depth count to avoid extra SELECT COUNT per enqueue. */
|
|
144
|
+
private depthCache;
|
|
145
|
+
/**
|
|
146
|
+
* 1-second TTL cache for the dispatch-queue depth breakdown (per-status + per-label).
|
|
147
|
+
* Fed by {@link JobQueue.getDepthBreakdown} and read synchronously by
|
|
148
|
+
* {@link JobQueue.readCachedDepthBreakdown} so the Prometheus observable
|
|
149
|
+
* gauge callback never issues an extra COUNT per scrape.
|
|
150
|
+
*/
|
|
151
|
+
private breakdownCache;
|
|
152
|
+
constructor(db: Kysely<Database>, options: {
|
|
153
|
+
maxDepth: number;
|
|
154
|
+
defaultTimeoutMs: number;
|
|
155
|
+
});
|
|
156
|
+
/**
|
|
157
|
+
* Enqueue a job. Checks depth first, rejects with 'queue full' if >= maxDepth.
|
|
158
|
+
* @returns The generated job ID.
|
|
159
|
+
*/
|
|
160
|
+
enqueue(job: QueuedJobInput): Promise<string>;
|
|
161
|
+
/**
|
|
162
|
+
* Dequeue the oldest pending job whose runsOnLabels are a subset of the
|
|
163
|
+
* provided agent labels. Uses SQL JSONB containment (@> operator) with
|
|
164
|
+
* GIN index for O(1) lookups instead of fetching all rows and filtering in JS.
|
|
165
|
+
*
|
|
166
|
+
* Semantics: agentLabels @> runs_on_labels (agent provides all labels the job requires).
|
|
167
|
+
* FOR UPDATE SKIP LOCKED prevents concurrent dequeue races between agents.
|
|
168
|
+
*
|
|
169
|
+
* When `agentMandatoryLabels` is non-empty, an additional containment check
|
|
170
|
+
* (`runs_on_labels @> agentMandatoryLabels`) enforces the
|
|
171
|
+
* Kubernetes-taint-style gate inherited from the spawning scaler: a gated
|
|
172
|
+
* agent only accepts jobs whose `runsOn` lists every gate label. The
|
|
173
|
+
* default (`[]`) is a no-op for static / non-scaler agents — every JSONB
|
|
174
|
+
* array trivially contains the empty array, so the predicate is vacuously
|
|
175
|
+
* true.
|
|
176
|
+
*
|
|
177
|
+
* @param agentLabels Labels the agent provides.
|
|
178
|
+
* @param agentMandatoryLabels Mandatory labels the spawning scaler declared
|
|
179
|
+
* (empty for static / non-scaler agents).
|
|
180
|
+
* @returns The matching job, or null if none found.
|
|
181
|
+
*/
|
|
182
|
+
dequeueForLabels(agentLabels: string[], agentMandatoryLabels?: string[]): Promise<QueuedJob | null>;
|
|
183
|
+
/**
|
|
184
|
+
* Atomically claim a specific pending job by ID, validating it still
|
|
185
|
+
* matches the agent's labels and isn't expired.
|
|
186
|
+
*
|
|
187
|
+
* Used by the eager-dispatch path: when the scaler spawned an agent for a
|
|
188
|
+
* specific queued job, the orchestrator claims that exact job on agent
|
|
189
|
+
* registration instead of racing the generic dequeueForLabels drain.
|
|
190
|
+
*
|
|
191
|
+
* Applies the same `agentMandatoryLabels` gate as `dequeueForLabels` so
|
|
192
|
+
* the eager-dispatch path can never claim a job that the scaler-side gate
|
|
193
|
+
* would have rejected (e.g. when the bound jobId outlived the scaler that
|
|
194
|
+
* spawned the agent and was reassigned to a different queued job).
|
|
195
|
+
*
|
|
196
|
+
* Returns null if the job is gone, no longer pending, expired, its label
|
|
197
|
+
* requirements are no longer satisfied by the agent, or the agent's gate
|
|
198
|
+
* is not satisfied by the job's `runsOn`.
|
|
199
|
+
*/
|
|
200
|
+
dequeueById(jobId: string, agentLabels: string[], agentMandatoryLabels?: string[]): Promise<QueuedJob | null>;
|
|
201
|
+
/**
|
|
202
|
+
* Insert a job directly with status='dispatched' (bypasses the queue).
|
|
203
|
+
* Used when an agent is immediately available and the job doesn't need to wait.
|
|
204
|
+
* @returns The generated job ID.
|
|
205
|
+
*/
|
|
206
|
+
insertDispatched(job: QueuedJobInput): Promise<string>;
|
|
207
|
+
/**
|
|
208
|
+
* Mark a job as dispatched.
|
|
209
|
+
*
|
|
210
|
+
* Note: agentId is not persisted in the dispatch_queue table.
|
|
211
|
+
* The dispatcher tracks agent-to-job mappings in memory (agentJobs Map).
|
|
212
|
+
* The dispatch_queue is a transient routing table, not the execution record.
|
|
213
|
+
*/
|
|
214
|
+
markDispatched(jobId: string, _agentId: string): Promise<void>;
|
|
215
|
+
/**
|
|
216
|
+
* Mark a job as failed.
|
|
217
|
+
*
|
|
218
|
+
* Note: reason is not persisted in the dispatch_queue table.
|
|
219
|
+
* Failure details are tracked in execution_jobs via the reporting pipeline.
|
|
220
|
+
* The dispatch_queue only tracks routing status transitions.
|
|
221
|
+
*/
|
|
222
|
+
markFailed(jobId: string, _reason: string): Promise<void>;
|
|
223
|
+
/**
|
|
224
|
+
* Mark a dispatched job as completed (terminal success).
|
|
225
|
+
*
|
|
226
|
+
* Only transitions rows from `Dispatched` or `Recovering`. A row that has
|
|
227
|
+
* already reached a terminal state (`Failed`, `Expired`, `Completed`,
|
|
228
|
+
* `Cancelled`) is left untouched — if the orchestrator already declared
|
|
229
|
+
* the job failed (e.g. build-coordinator timeout cascading through
|
|
230
|
+
* {@link failByRunId}), a late `job.complete` from the agent that was
|
|
231
|
+
* still working must NOT silently flip the row back to `Completed`.
|
|
232
|
+
*/
|
|
233
|
+
markCompleted(jobId: string): Promise<void>;
|
|
234
|
+
/**
|
|
235
|
+
* Expire timed-out pending jobs.
|
|
236
|
+
* SELECT-then-UPDATE so callers get the expired job details for forwarding.
|
|
237
|
+
* @returns Array of expired job info (id, runId, jobName).
|
|
238
|
+
*/
|
|
239
|
+
markExpired(): Promise<ExpiredJobInfo[]>;
|
|
240
|
+
/**
|
|
241
|
+
* Bulk-fail every still-non-terminal dispatch_queue entry for a run.
|
|
242
|
+
*
|
|
243
|
+
* Called from the run-level failure cascades in `ExecutionTracker`
|
|
244
|
+
* (`onBuildFailed`, `failRun`). At that point the run itself is being
|
|
245
|
+
* declared failed, so any dispatch_queue row still in `Pending`,
|
|
246
|
+
* `Recovering`, or `Dispatched` is by definition orphaned and must
|
|
247
|
+
* also be moved to `Failed` — leaving a `Dispatched` row in place
|
|
248
|
+
* keeps the row in a non-terminal state forever, which the build-timeout
|
|
249
|
+
* E2E (and any operator query for "is this run actually done") relies
|
|
250
|
+
* on never happening. The complementary {@link markCompleted} status
|
|
251
|
+
* guard ensures a late `job.complete` from the agent that was still
|
|
252
|
+
* working when the run was declared failed cannot flip the row back
|
|
253
|
+
* to `Completed`.
|
|
254
|
+
*
|
|
255
|
+
* @returns Number of affected rows.
|
|
256
|
+
*/
|
|
257
|
+
failByRunId(runId: string): Promise<number>;
|
|
258
|
+
/**
|
|
259
|
+
* Bulk-cancel all pending dispatch_queue entries for a run.
|
|
260
|
+
* Called when a run is cancelled via API.
|
|
261
|
+
* @returns Number of affected rows.
|
|
262
|
+
*/
|
|
263
|
+
cancelByRunId(runId: string): Promise<number>;
|
|
264
|
+
/**
|
|
265
|
+
* Get the current number of pending jobs.
|
|
266
|
+
* Uses a 1-second TTL cache to avoid extra SELECT COUNT per enqueue.
|
|
267
|
+
*/
|
|
268
|
+
getDepth(): Promise<number>;
|
|
269
|
+
/**
|
|
270
|
+
* Compute the current dispatch-queue depth breakdown (pending + dispatched),
|
|
271
|
+
* aggregated per status and, for pending rows, per label.
|
|
272
|
+
*
|
|
273
|
+
* Uses the same 1-second TTL cache pattern as {@link JobQueue.getDepth}: if
|
|
274
|
+
* the cached breakdown is still fresh (or was refreshed within the last
|
|
275
|
+
* second), the cached value is returned without issuing a query. This keeps
|
|
276
|
+
* the Prometheus gauge callback cheap on high-frequency scrapes and avoids
|
|
277
|
+
* any extra DB load during enqueue bursts.
|
|
278
|
+
*
|
|
279
|
+
* Multi-label jobs fan out: a pending row with `runs_on_labels = ['linux',
|
|
280
|
+
* 'x64']` contributes `1` to both the `linux` and `x64` entries in
|
|
281
|
+
* `byLabel`. The `byStatus` buckets always contain raw counts.
|
|
282
|
+
*/
|
|
283
|
+
getDepthBreakdown(): Promise<DispatchQueueDepthBreakdown>;
|
|
284
|
+
/**
|
|
285
|
+
* Return the most recently cached breakdown without issuing a DB query.
|
|
286
|
+
*
|
|
287
|
+
* Intended for synchronous contexts such as the OpenTelemetry observable
|
|
288
|
+
* gauge callback, which MUST NOT perform I/O. Callers are responsible for
|
|
289
|
+
* refreshing the cache periodically via {@link JobQueue.getDepthBreakdown}.
|
|
290
|
+
*/
|
|
291
|
+
readCachedDepthBreakdown(): DispatchQueueDepthBreakdown | null;
|
|
292
|
+
/**
|
|
293
|
+
* Get job IDs for a run that are currently dispatched or recovering.
|
|
294
|
+
* Used by the cancel-run API to send job.cancel to the right agents.
|
|
295
|
+
* Includes recovering jobs since they may still be reclaimed by a reconnecting agent.
|
|
296
|
+
*/
|
|
297
|
+
getDispatchedJobIdsByRunId(runId: string): Promise<string[]>;
|
|
298
|
+
/**
|
|
299
|
+
* Mark a job as recovering (agent disconnected, within grace period).
|
|
300
|
+
* Only transitions from 'dispatched' state for safety.
|
|
301
|
+
*/
|
|
302
|
+
markRecovering(jobId: string): Promise<void>;
|
|
303
|
+
/**
|
|
304
|
+
* Mark a job as failed only if it is still in 'recovering' state.
|
|
305
|
+
* Uses optimistic concurrency to avoid failing jobs that were reclaimed.
|
|
306
|
+
* @returns true if the update affected a row (job was still recovering).
|
|
307
|
+
*/
|
|
308
|
+
markFailedIfRecovering(jobId: string, _reason: string): Promise<boolean>;
|
|
309
|
+
/**
|
|
310
|
+
* Mark a job as dispatched only if it is still in 'recovering' state.
|
|
311
|
+
* Used when an agent reconnects and claims a recovering job.
|
|
312
|
+
* @returns true if the update affected a row (job was still recovering).
|
|
313
|
+
*/
|
|
314
|
+
markDispatchedIfRecovering(jobId: string): Promise<boolean>;
|
|
315
|
+
/**
|
|
316
|
+
* Get a single job by ID.
|
|
317
|
+
* Used to look up runId during recovery timer setup.
|
|
318
|
+
*/
|
|
319
|
+
getJobById(jobId: string): Promise<{
|
|
320
|
+
id: string;
|
|
321
|
+
runId: string;
|
|
322
|
+
status: DispatchQueueStatus;
|
|
323
|
+
} | null>;
|
|
324
|
+
/**
|
|
325
|
+
* Get all jobs matching a given status.
|
|
326
|
+
* Used on startup to find 'dispatched' jobs from a previous instance for recovery.
|
|
327
|
+
*/
|
|
328
|
+
getJobsByStatus(status: DispatchQueueStatus): Promise<Array<{
|
|
329
|
+
id: string;
|
|
330
|
+
runId: string;
|
|
331
|
+
status: DispatchQueueStatus;
|
|
332
|
+
}>>;
|
|
333
|
+
/**
|
|
334
|
+
* Get all pending jobs in FIFO order (for queue drain on agent connect).
|
|
335
|
+
*/
|
|
336
|
+
getPendingJobs(): Promise<QueuedJob[]>;
|
|
337
|
+
/**
|
|
338
|
+
* Convert a DB row to a QueuedJob object.
|
|
339
|
+
* Handles both auto-parsed JSONB arrays (from pg driver) and JSON strings (from tests).
|
|
340
|
+
*/
|
|
341
|
+
private rowToQueuedJob;
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=job-queue.d.ts.map
|