@kici-dev/orchestrator 0.1.27 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__test-helpers__/mock-db.d.ts +2 -0
- package/dist/agent/dispatcher.d.ts +52 -2
- package/dist/agent/host-roster-reaper.d.ts +1 -2
- package/dist/agent/host-roster.d.ts +34 -0
- package/dist/agent/ownership-refusal.d.ts +12 -0
- package/dist/agent/ownership-tracker.d.ts +64 -16
- package/dist/agent/token-store.d.ts +13 -0
- package/dist/agent-packaging/availability.d.ts +27 -0
- package/dist/agent-packaging/build-package.d.ts +16 -0
- package/dist/agent-packaging/download.d.ts +30 -0
- package/dist/agent-packaging/index.d.ts +9 -0
- package/dist/agent-packaging/install-closure.d.ts +30 -0
- package/dist/agent-packaging/node-binary.d.ts +26 -0
- package/dist/agent-packaging/refresh.d.ts +50 -0
- package/dist/agent-packaging/store.d.ts +15 -0
- package/dist/agent-packaging/upload.d.ts +24 -0
- package/dist/app-on-error.d.ts +29 -0
- package/dist/app.d.ts +56 -4
- package/dist/artifacts/artifact-store.d.ts +233 -0
- package/dist/artifacts/failure-messages.d.ts +46 -0
- package/dist/audit/access-log.d.ts +18 -1
- package/dist/cache/dep-cache.d.ts +15 -0
- package/dist/cache/user-cache.d.ts +37 -0
- package/dist/cancel/cancel-run.d.ts +10 -3
- package/dist/cancel/dashboard-cancel-handler.d.ts +19 -0
- package/dist/cli/api-client.d.ts +22 -1
- package/dist/cli/commands/agent-package.d.ts +34 -0
- package/dist/cli/commands/check-run.d.ts +26 -0
- package/dist/cli/commands/cluster-settings.d.ts +55 -0
- package/dist/cli/commands/dashboard-encryption-key.d.ts +3 -0
- package/dist/cli/commands/db-backup.d.ts +71 -0
- package/dist/cli/commands/orchestrator-service/drain.d.ts +31 -0
- package/dist/cli/commands/orchestrator-service/index.d.ts +7 -4
- package/dist/cli/commands/orchestrator-service/install-env.d.ts +58 -0
- package/dist/cli/commands/secret.d.ts +45 -1
- package/dist/cli/commands/shared/admin-cli-access-log.d.ts +46 -0
- package/dist/cli/commands/shared/versioned-upgrade.d.ts +65 -2
- package/dist/cli/commands/signing-key.d.ts +3 -0
- package/dist/cli/commands/source.d.ts +12 -0
- package/dist/cli/commands/token.d.ts +9 -0
- package/dist/cli/commands/trust-policy.d.ts +48 -0
- package/dist/cli/join.d.ts +1 -1
- package/dist/cli/service/index.d.ts +2 -2
- package/dist/cli/service/instance/manifest.d.ts +17 -0
- package/dist/cli/service/instance/resolve.d.ts +11 -0
- package/dist/cli/wizard/orchestrator-wizard.d.ts +39 -11
- package/dist/cli.js +9818 -3408
- package/dist/cluster/cluster-settings-reader.d.ts +78 -0
- package/dist/cluster/coordinator.d.ts +81 -9
- package/dist/cluster/join-client.d.ts +1 -1
- package/dist/cluster/leader-gated-scheduler.d.ts +50 -0
- package/dist/cluster/orphan-recovery.d.ts +14 -0
- package/dist/cluster/peer-client.d.ts +12 -2
- package/dist/cluster/peer-handler.d.ts +15 -4
- package/dist/cluster/peer-registry.d.ts +12 -0
- package/dist/cluster/verified-issuer-poller.d.ts +11 -0
- package/dist/cluster/verified-issuer.d.ts +63 -0
- package/dist/cold-store/tables/access-log.d.ts +1 -1
- package/dist/cold-store/tables/event-log.d.ts +1 -1
- package/dist/cold-store/tables/execution-jobs.d.ts +1 -1
- package/dist/cold-store/tables/execution-runs.d.ts +1 -1
- package/dist/cold-store/tables/execution-steps.d.ts +1 -1
- package/dist/cold-store/tables/secret-audit-log.d.ts +1 -1
- package/dist/config/loader.d.ts +1 -1
- package/dist/config/resolver.d.ts +2 -1
- package/dist/config/schema.d.ts +8 -6
- package/dist/config/types.d.ts +3 -2
- package/dist/config.d.ts +363 -53
- package/dist/contexts/context-store.d.ts +21 -8
- package/dist/contexts/glob-specificity.d.ts +30 -0
- package/dist/contexts/held-runs.d.ts +51 -19
- package/dist/contexts/protection/aggregate.d.ts +2 -2
- package/dist/contexts/protection/concurrency-gate.d.ts +0 -3
- package/dist/contexts/protection/reviewer-gate.d.ts +0 -3
- package/dist/contexts/protection/satisfiability.d.ts +1 -1
- package/dist/contexts/protection/trust-gate.d.ts +0 -3
- package/dist/contexts/protection/wait-timer-gate.d.ts +0 -3
- package/dist/cron/cron-scheduler.d.ts +24 -4
- package/dist/cron/cron-store.d.ts +21 -7
- package/dist/dashboard/attestation-filters.d.ts +92 -74
- package/dist/dashboard/handler.d.ts +35 -1
- package/dist/db/migration-test-harness.d.ts +41 -0
- package/dist/db/migrations/069_reroute_tunables.d.ts +21 -0
- package/dist/db/migrations/070_execution_runs_failure_class.d.ts +4 -0
- package/dist/db/migrations/071_batch_accumulation.d.ts +26 -0
- package/dist/db/migrations/072_dispatch_queue_run_id_index.d.ts +15 -0
- package/dist/db/migrations/073_org_settings_ingest_concurrency.d.ts +13 -0
- package/dist/db/migrations/074_normalize_zero_concurrency_limit.d.ts +13 -0
- package/dist/db/migrations/075_ingest_overflow_buffer.d.ts +16 -0
- package/dist/db/migrations/076_artifacts.d.ts +19 -0
- package/dist/db/migrations/077_backup_runs.d.ts +13 -0
- package/dist/db/migrations/078_org_settings_backup_staleness.d.ts +12 -0
- package/dist/db/migrations/079_org_settings_scaler_spawn_timeout.d.ts +14 -0
- package/dist/db/migrations/080_cluster_settings.d.ts +17 -0
- package/dist/db/migrations/081_org_settings_queue_timeout.d.ts +19 -0
- package/dist/db/migrations/082_host_s3_reachable.d.ts +16 -0
- package/dist/db/migrations/083_org_settings_artifact_caps.d.ts +18 -0
- package/dist/db/migrations/084_orchestrator_signing_keys.d.ts +20 -0
- package/dist/db/migrations/085_cluster_settings_reroute_flap_grace_ms.d.ts +12 -0
- package/dist/db/migrations/086_cluster_settings_max_fanout_hosts.d.ts +12 -0
- package/dist/db/migrations/087_cluster_settings_event_router_rate_limit.d.ts +12 -0
- package/dist/db/migrations/088_cluster_settings_cache_max_tarball_bytes.d.ts +12 -0
- package/dist/db/migrations/089_cluster_settings_cache_ttl_days.d.ts +12 -0
- package/dist/db/migrations/090_cluster_settings_concurrency_wait_timeout_ms.d.ts +12 -0
- package/dist/db/migrations/091_cluster_settings_agent_token_ttl_ms.d.ts +12 -0
- package/dist/db/migrations/092_cluster_settings_version.d.ts +16 -0
- package/dist/db/migrations/093_org_settings_sandbox_allowlist.d.ts +4 -0
- package/dist/db/migrations/094_dashboard_encryption_keys.d.ts +21 -0
- package/dist/db/migrations/095_dashboard_write_policy_tristate.d.ts +20 -0
- package/dist/db/migrations/096_multi_schedule_cron_last_fired.d.ts +4 -0
- package/dist/db/migrations/097_execution_runs_pr_number.d.ts +4 -0
- package/dist/db/migrations/098_execution_runs_customer_id.d.ts +4 -0
- package/dist/db/migrations/099_cluster_settings_dashboard_verified_issuer.d.ts +21 -0
- package/dist/db/migrations/100_held_runs_hold_type_vocabulary.d.ts +31 -0
- package/dist/db/migrations/101_contexts_hold_expiry_drop_default.d.ts +31 -0
- package/dist/db/migrations/102_dispatch_queue_agent_id.d.ts +20 -0
- package/dist/db/migrations/103_cluster_settings_ownership_db_check_timeout_ms.d.ts +20 -0
- package/dist/db/migrations/104_check_run_terminal_sent.d.ts +22 -0
- package/dist/db/migrations/105_org_trust_policy.d.ts +19 -0
- package/dist/db/migrations/106_cluster_settings_check_run_tracking_ttl_days.d.ts +18 -0
- package/dist/db/migrations/107_check_run_tracking_updated_at_index.d.ts +23 -0
- package/dist/db/repos/dashboard-encryption-keys-repo.d.ts +48 -0
- package/dist/db/repos/signing-keys-repo.d.ts +34 -0
- package/dist/db/types.d.ts +421 -7
- package/dist/deployment/deployment-identity.d.ts +87 -2
- package/dist/diagnostics/checks/backup.d.ts +18 -0
- package/dist/diagnostics/checks/index.d.ts +2 -1
- package/dist/diagnostics/fleet-collector.d.ts +1 -1
- package/dist/drain/drain-controller.d.ts +52 -0
- package/dist/events/batch-accumulator.d.ts +63 -0
- package/dist/events/circuit-breaker.d.ts +9 -3
- package/dist/events/event-emitter.d.ts +31 -0
- package/dist/events/event-retry-scanner.d.ts +12 -2
- package/dist/events/event-router.d.ts +29 -0
- package/dist/firecracker/host-network.d.ts +2 -0
- package/dist/firecracker/net-interfaces.d.ts +14 -0
- package/dist/github-app-name-refresher/github-app-name-refresher.d.ts +18 -8
- package/dist/index.d.ts +2 -0
- package/dist/index.js +604 -16
- package/dist/lockfile-cache.d.ts +4 -0
- package/dist/lockfile-validate.d.ts +16 -9
- package/dist/metrics/prometheus.d.ts +112 -15
- package/dist/oidc/aws-kms-signer.d.ts +37 -0
- package/dist/oidc/command-signer.d.ts +23 -0
- package/dist/oidc/db-signer.d.ts +48 -0
- package/dist/oidc/id-token-claims.d.ts +22 -9
- package/dist/oidc/jwt.d.ts +5 -2
- package/dist/oidc/local-dev-signer.d.ts +1 -1
- package/dist/oidc/oidc-mint-registration.d.ts +27 -11
- package/dist/oidc/orchestrator-mint.d.ts +97 -0
- package/dist/oidc/orchestrator-signer-factory.d.ts +33 -0
- package/dist/oidc/reconcile-signing-key.d.ts +21 -0
- package/dist/oidc/signer.d.ts +25 -0
- package/dist/oidc/signing-key-status.d.ts +23 -0
- package/dist/orchestrator-core.d.ts +42 -2
- package/dist/pipeline/decorating-secret-resolver.d.ts +3 -2
- package/dist/pipeline/dispatch-matched-workflow.d.ts +41 -0
- package/dist/pipeline/install-secrets-resolver.d.ts +12 -1
- package/dist/pipeline/manual-schedule.d.ts +20 -13
- package/dist/pipeline/pending-workflow-context.d.ts +1 -1
- package/dist/pipeline/process-webhook.d.ts +57 -2
- package/dist/pipeline/processor.d.ts +44 -8
- package/dist/pipeline/rerun.d.ts +12 -13
- package/dist/pipeline/resolve-sandbox-grant.d.ts +28 -0
- package/dist/pipeline/route-or-dispatch-jobs.d.ts +71 -0
- package/dist/pipeline/sandbox-allowlist-reader.d.ts +33 -0
- package/dist/policy/dashboard-write-policy.d.ts +9 -4
- package/dist/provenance/backfill-run.d.ts +1 -0
- package/dist/provenance/trust-root.d.ts +13 -0
- package/dist/providers/generic/normalizer.d.ts +1 -1
- package/dist/providers/github/auth.d.ts +1 -1
- package/dist/providers/github/changed-files.d.ts +14 -6
- package/dist/providers/github/check-status-poster.d.ts +19 -3
- package/dist/providers/github/contributor-resolver.d.ts +1 -1
- package/dist/providers/github/lock-file.d.ts +1 -1
- package/dist/providers/github/normalizer.d.ts +1 -1
- package/dist/providers/github/repo-url.d.ts +1 -1
- package/dist/providers/local/lock-file-fetcher.d.ts +1 -1
- package/dist/providers/local/normalizer.d.ts +1 -1
- package/dist/providers/local/repo-url-builder.d.ts +1 -1
- package/dist/providers/universal-git/changed-files.d.ts +8 -7
- package/dist/providers/universal-git/clone-token.d.ts +1 -1
- package/dist/providers/universal-git/config.d.ts +4 -4
- package/dist/providers/universal-git/index.d.ts +5 -1
- package/dist/providers/universal-git/lock-file.d.ts +6 -1
- package/dist/providers/universal-git/normalizer.d.ts +1 -1
- package/dist/providers/universal-git/repo-url.d.ts +1 -1
- package/dist/queue/cleanup.d.ts +69 -8
- package/dist/queue/job-queue.d.ts +94 -14
- package/dist/queue/scheduled-job.d.ts +2 -2
- package/dist/registration/registration-index.d.ts +1 -1
- package/dist/reporting/agent-failure-category.d.ts +4 -1
- package/dist/reporting/check-run-reporter.d.ts +34 -14
- package/dist/reporting/check-run-tracking-store.d.ts +70 -8
- package/dist/reporting/execution-tracker.d.ts +156 -10
- package/dist/reporting/fs-log-storage.d.ts +31 -2
- package/dist/reporting/job-check-run-completion.d.ts +50 -0
- package/dist/reporting/log-chunk-sink.d.ts +47 -0
- package/dist/reporting/log-retention.d.ts +16 -0
- package/dist/reporting/log-storage.d.ts +64 -4
- package/dist/reporting/log-writer.d.ts +22 -7
- package/dist/reporting/peer-log-normalize.d.ts +14 -0
- package/dist/reporting/run-aggregator.d.ts +32 -32
- package/dist/reporting/s3-log-storage.d.ts +102 -8
- package/dist/routes/admin-auth.d.ts +90 -0
- package/dist/routes/admin-cluster-settings.d.ts +31 -0
- package/dist/routes/admin-events.d.ts +3 -0
- package/dist/routes/admin-orchestrator-drain.d.ts +35 -0
- package/dist/routes/admin-runs.d.ts +9 -0
- package/dist/routes/admin-sources.d.ts +7 -0
- package/dist/routes/admin-trust-policy.d.ts +49 -0
- package/dist/routes/admin.d.ts +15 -1
- package/dist/routes/github-webhook.d.ts +9 -3
- package/dist/routes/provenance-oidc.d.ts +38 -0
- package/dist/routes/verify-attestation.d.ts +21 -0
- package/dist/scaler/bare-metal-backend.d.ts +9 -2
- package/dist/scaler/config.d.ts +25 -4
- package/dist/scaler/container-backend.d.ts +9 -1
- package/dist/scaler/firecracker-backend.d.ts +29 -2
- package/dist/scaler/index.d.ts +1 -1
- package/dist/scaler/manager.d.ts +166 -8
- package/dist/scaler/pending-scale-sweeper.d.ts +35 -0
- package/dist/scaler/types.d.ts +75 -6
- package/dist/secrets/backend-registry.d.ts +32 -1
- package/dist/secrets/dashboard-encryption-key.d.ts +48 -0
- package/dist/secrets/ephemeral-keys.d.ts +16 -0
- package/dist/secrets/pg-secret-store.d.ts +10 -0
- package/dist/secrets/rbac.d.ts +5 -1
- package/dist/secrets/routing-key-scope.d.ts +6 -0
- package/dist/secrets/scope-routing.d.ts +126 -0
- package/dist/secrets/secret-resolver.d.ts +1 -14
- package/dist/secrets/token-manager.d.ts +5 -1
- package/dist/security/contributor-cache.d.ts +9 -1
- package/dist/security/trust-policy-gate.d.ts +117 -0
- package/dist/security/trust-policy-store.d.ts +78 -0
- package/dist/server.js +35769 -25052
- package/dist/sources/source-manager.d.ts +24 -0
- package/dist/stale-detector/stale-run-detector.d.ts +7 -0
- package/dist/standalone.js +34831 -25317
- package/dist/storage/filesystem.d.ts +17 -0
- package/dist/storage/key-discriminator.d.ts +20 -0
- package/dist/storage/s3.d.ts +2 -0
- package/dist/storage/types.d.ts +16 -0
- package/dist/webhook/dedup.d.ts +9 -1
- package/dist/webhook/event-log.d.ts +13 -2
- package/dist/webhook/generic-sources-listener.d.ts +4 -0
- package/dist/webhook/ingest-admission.d.ts +140 -0
- package/dist/webhook/ingest-overflow-buffer.d.ts +27 -0
- package/dist/webhook/ingest-overflow-replayer.d.ts +49 -0
- package/dist/webhook/ingest-overflow-types.d.ts +73 -0
- package/dist/webhook/loop-lag-source.d.ts +40 -0
- package/dist/webhook/observed-relay-guard.d.ts +40 -0
- package/dist/webhook/org-ingest-cap-reader.d.ts +24 -0
- package/dist/webhook/register-source-bundle.d.ts +3 -0
- package/dist/webhook/relay-reinject.d.ts +43 -0
- package/dist/worker/in-memory-job-queue.d.ts +8 -3
- package/dist/worker-core.d.ts +10 -0
- package/dist/ws/agent-api-registry.d.ts +20 -0
- package/dist/ws/agent-handler.d.ts +63 -7
- package/dist/ws/bringup-api.d.ts +99 -0
- package/dist/ws/dashboard-context-handler.d.ts +28 -10
- package/dist/ws/dashboard-run-state-handler.d.ts +31 -0
- package/dist/ws/failure-messages.d.ts +29 -0
- package/dist/ws/oidc-token-relay.d.ts +9 -0
- package/dist/ws/ownership-gate.d.ts +22 -0
- package/dist/ws/platform-client.d.ts +96 -1
- package/dist/ws/replay-chunker.d.ts +37 -0
- package/installer-image-digests.json +3 -3
- package/package.json +22 -21
- package/sbom.spdx.json +1240 -1788
package/dist/scaler/config.d.ts
CHANGED
|
@@ -9,6 +9,13 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { z } from 'zod';
|
|
11
11
|
import type { ScalerConfig } from './types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Default cap on concurrent `backend.spawn` operations per backend when a
|
|
14
|
+
* scaler entry does not set `maxConcurrentSpawns`. Bounds the provisioning rate
|
|
15
|
+
* (image pull + create + start) so a burst of queued jobs cannot storm the
|
|
16
|
+
* container socket / registry.
|
|
17
|
+
*/
|
|
18
|
+
export declare const DEFAULT_MAX_CONCURRENT_SPAWNS = 8;
|
|
12
19
|
/**
|
|
13
20
|
* Zod schema for network policy configuration on a label set.
|
|
14
21
|
* Controls RFC1918 and internet access for spawned agents.
|
|
@@ -67,8 +74,8 @@ export declare const labelSetConfigSchema: z.ZodObject<{
|
|
|
67
74
|
containerSocket: z.ZodDefault<z.ZodBoolean>;
|
|
68
75
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
69
76
|
backpressureMode: z.ZodOptional<z.ZodEnum<{
|
|
70
|
-
pause: "pause";
|
|
71
77
|
drop: "drop";
|
|
78
|
+
pause: "pause";
|
|
72
79
|
}>>;
|
|
73
80
|
networkPolicy: z.ZodOptional<z.ZodObject<{
|
|
74
81
|
allowlist: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -90,6 +97,7 @@ export declare const firecrackerNetworkSchema: z.ZodObject<{
|
|
|
90
97
|
gateway: z.ZodDefault<z.ZodString>;
|
|
91
98
|
netmask: z.ZodDefault<z.ZodString>;
|
|
92
99
|
table: z.ZodDefault<z.ZodString>;
|
|
100
|
+
autoProvisionHost: z.ZodDefault<z.ZodBoolean>;
|
|
93
101
|
}, z.core.$strip>;
|
|
94
102
|
/**
|
|
95
103
|
* Zod schema for the complete scaler configuration file.
|
|
@@ -160,11 +168,12 @@ export declare const scalerFileSchema: z.ZodObject<{
|
|
|
160
168
|
scalers: z.ZodArray<z.ZodObject<{
|
|
161
169
|
name: z.ZodString;
|
|
162
170
|
type: z.ZodEnum<{
|
|
163
|
-
container: "container";
|
|
164
171
|
"bare-metal": "bare-metal";
|
|
172
|
+
container: "container";
|
|
165
173
|
firecracker: "firecracker";
|
|
166
174
|
}>;
|
|
167
175
|
maxAgents: z.ZodNumber;
|
|
176
|
+
maxConcurrentSpawns: z.ZodDefault<z.ZodNumber>;
|
|
168
177
|
labelSets: z.ZodArray<z.ZodObject<{
|
|
169
178
|
labels: z.ZodArray<z.ZodString>;
|
|
170
179
|
image: z.ZodOptional<z.ZodString>;
|
|
@@ -212,8 +221,8 @@ export declare const scalerFileSchema: z.ZodObject<{
|
|
|
212
221
|
containerSocket: z.ZodDefault<z.ZodBoolean>;
|
|
213
222
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
214
223
|
backpressureMode: z.ZodOptional<z.ZodEnum<{
|
|
215
|
-
pause: "pause";
|
|
216
224
|
drop: "drop";
|
|
225
|
+
pause: "pause";
|
|
217
226
|
}>>;
|
|
218
227
|
networkPolicy: z.ZodOptional<z.ZodObject<{
|
|
219
228
|
allowlist: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -228,9 +237,9 @@ export declare const scalerFileSchema: z.ZodObject<{
|
|
|
228
237
|
host: z.ZodOptional<z.ZodString>;
|
|
229
238
|
socketPath: z.ZodOptional<z.ZodString>;
|
|
230
239
|
runtime: z.ZodDefault<z.ZodEnum<{
|
|
240
|
+
auto: "auto";
|
|
231
241
|
docker: "docker";
|
|
232
242
|
podman: "podman";
|
|
233
|
-
auto: "auto";
|
|
234
243
|
}>>;
|
|
235
244
|
orchestratorUrl: z.ZodOptional<z.ZodString>;
|
|
236
245
|
extraHosts: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -241,6 +250,17 @@ export declare const scalerFileSchema: z.ZodObject<{
|
|
|
241
250
|
idleTimeoutSeconds: z.ZodDefault<z.ZodNumber>;
|
|
242
251
|
}, z.core.$strip>>;
|
|
243
252
|
mandatoryLabels: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
253
|
+
platform: z.ZodOptional<z.ZodObject<{
|
|
254
|
+
os: z.ZodEnum<{
|
|
255
|
+
linux: "linux";
|
|
256
|
+
macos: "macos";
|
|
257
|
+
windows: "windows";
|
|
258
|
+
}>;
|
|
259
|
+
arch: z.ZodEnum<{
|
|
260
|
+
arm64: "arm64";
|
|
261
|
+
x64: "x64";
|
|
262
|
+
}>;
|
|
263
|
+
}, z.core.$strict>>;
|
|
244
264
|
roles: z.ZodPipe<z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
245
265
|
all: "all";
|
|
246
266
|
builder: "builder";
|
|
@@ -274,6 +294,7 @@ export declare const scalerFileSchema: z.ZodObject<{
|
|
|
274
294
|
gateway: z.ZodDefault<z.ZodString>;
|
|
275
295
|
netmask: z.ZodDefault<z.ZodString>;
|
|
276
296
|
table: z.ZodDefault<z.ZodString>;
|
|
297
|
+
autoProvisionHost: z.ZodDefault<z.ZodBoolean>;
|
|
277
298
|
}, z.core.$strip>>;
|
|
278
299
|
}, z.core.$strip>;
|
|
279
300
|
/**
|
|
@@ -44,6 +44,12 @@ export interface ContainerScalerBackendOptions {
|
|
|
44
44
|
tokenStore?: AgentTokenStore;
|
|
45
45
|
/** TTL for ephemeral agent tokens in ms. Default: 1 hour. */
|
|
46
46
|
tokenTtlMs?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Live resolver for the ephemeral agent-token TTL (ms). When set, called per
|
|
49
|
+
* spawn so the leader can serve the fleet-wide
|
|
50
|
+
* `cluster_settings.agent_token_ttl_ms` override; falls back to `tokenTtlMs`.
|
|
51
|
+
*/
|
|
52
|
+
tokenTtlProvider?: () => Promise<number>;
|
|
47
53
|
/** Agent roles for this scaler. undefined = all, [] = execution only. */
|
|
48
54
|
roles?: string[];
|
|
49
55
|
}
|
|
@@ -67,6 +73,8 @@ export declare class ContainerScalerBackend implements ScalerBackend {
|
|
|
67
73
|
private readonly tokenStore?;
|
|
68
74
|
/** TTL for ephemeral agent tokens in ms */
|
|
69
75
|
private readonly tokenTtlMs;
|
|
76
|
+
/** Live per-spawn resolver for the ephemeral agent-token TTL (ms). */
|
|
77
|
+
private readonly tokenTtlProvider?;
|
|
70
78
|
/** Agent roles for this scaler. undefined = all, [] = execution only. */
|
|
71
79
|
private readonly roles;
|
|
72
80
|
/** ID of the isolated bridge network (set after creation/discovery) */
|
|
@@ -113,7 +121,7 @@ export declare class ContainerScalerBackend implements ScalerBackend {
|
|
|
113
121
|
get logsSource(): string;
|
|
114
122
|
get labelSets(): LabelSetConfig[];
|
|
115
123
|
getActiveCount(): number;
|
|
116
|
-
spawn(labelSet: string[], agentId: string, orchestratorUrl: string, onEvent?: ScalerEventCallback, effectiveLimits?: EffectiveLimits, spawnContext?: SpawnContext): Promise<ManagedAgent>;
|
|
124
|
+
spawn(labelSet: string[], agentId: string, orchestratorUrl: string, onEvent?: ScalerEventCallback, effectiveLimits?: EffectiveLimits, spawnContext?: SpawnContext, signal?: AbortSignal): Promise<ManagedAgent>;
|
|
117
125
|
getScalerContext(agentId: string): Record<string, unknown> | undefined;
|
|
118
126
|
destroy(managedId: string): Promise<void>;
|
|
119
127
|
/**
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
import { type ToolRequirement } from '@kici-dev/shared';
|
|
20
20
|
import type { IpAllocator, IpAllocationResult } from './ip-allocator.js';
|
|
21
21
|
import type { AgentTokenStore } from '../agent/token-store.js';
|
|
22
|
-
import
|
|
22
|
+
import { type FirecrackerBridgeConfig, type BridgeHealth, type ExecOptions } from '../firecracker/host-network.js';
|
|
23
|
+
import type { ScalerBackend, ScalerEntry, ManagedAgent, LabelSetConfig, ScalerEventCallback, ValidationResult, EffectiveLimits, SpawnContext } from './types.js';
|
|
23
24
|
/**
|
|
24
25
|
* Infrastructure interfaces that share the `kici-` prefix but must NEVER be
|
|
25
26
|
* deleted by the orphan sweep. Bridges (kici-br0/kici-br1) carry all VM
|
|
@@ -73,6 +74,12 @@ export interface FirecrackerScalerBackendOptions {
|
|
|
73
74
|
tokenStore?: AgentTokenStore;
|
|
74
75
|
/** TTL for ephemeral agent tokens in ms. Default: 1 hour. */
|
|
75
76
|
tokenTtlMs?: number;
|
|
77
|
+
/**
|
|
78
|
+
* Live resolver for the ephemeral agent-token TTL (ms). When set, called per
|
|
79
|
+
* spawn so the leader can serve the fleet-wide
|
|
80
|
+
* `cluster_settings.agent_token_ttl_ms` override; falls back to `tokenTtlMs`.
|
|
81
|
+
*/
|
|
82
|
+
tokenTtlProvider?: () => Promise<number>;
|
|
76
83
|
/** Agent roles for this scaler. undefined = all, [] = execution only. */
|
|
77
84
|
roles?: string[];
|
|
78
85
|
/**
|
|
@@ -83,6 +90,16 @@ export interface FirecrackerScalerBackendOptions {
|
|
|
83
90
|
* @default false
|
|
84
91
|
*/
|
|
85
92
|
requireSudo?: boolean;
|
|
93
|
+
/**
|
|
94
|
+
* When true, `ensureHostReady()` verifies and provisions this host bridge on
|
|
95
|
+
* startup (self-heal). Threaded from `firecracker.autoProvisionHost`. When
|
|
96
|
+
* false the method is a no-op. @default false (cores pass the real value)
|
|
97
|
+
*/
|
|
98
|
+
autoProvisionHost?: boolean;
|
|
99
|
+
/** Injectable bridge verifier (tests). @default host-network verifyBridge */
|
|
100
|
+
verifyBridgeFn?: (cfg: FirecrackerBridgeConfig, opts: ExecOptions) => Promise<BridgeHealth>;
|
|
101
|
+
/** Injectable bridge provisioner (tests). @default host-network provisionBridge */
|
|
102
|
+
provisionBridgeFn?: (cfg: FirecrackerBridgeConfig, opts: ExecOptions) => Promise<void>;
|
|
86
103
|
}
|
|
87
104
|
export declare class FirecrackerScalerBackend implements ScalerBackend {
|
|
88
105
|
readonly type: "firecracker";
|
|
@@ -109,8 +126,12 @@ export declare class FirecrackerScalerBackend implements ScalerBackend {
|
|
|
109
126
|
private readonly table;
|
|
110
127
|
private readonly tokenStore?;
|
|
111
128
|
private readonly tokenTtlMs;
|
|
129
|
+
private readonly tokenTtlProvider?;
|
|
112
130
|
private readonly roles;
|
|
113
131
|
private readonly requireSudo;
|
|
132
|
+
private readonly autoProvisionHost;
|
|
133
|
+
private readonly verifyBridgeFn;
|
|
134
|
+
private readonly provisionBridgeFn;
|
|
114
135
|
/** Tracks all managed VM agents by ManagedAgent.id */
|
|
115
136
|
private readonly agents;
|
|
116
137
|
/** Periodic orphan sweep timer (null when stopped). */
|
|
@@ -124,7 +145,7 @@ export declare class FirecrackerScalerBackend implements ScalerBackend {
|
|
|
124
145
|
static getRequiredTools(entry: ScalerEntry): ToolRequirement[];
|
|
125
146
|
get labelSets(): LabelSetConfig[];
|
|
126
147
|
getActiveCount(): number;
|
|
127
|
-
spawn(labelSet: string[], agentId: string, orchestratorUrl: string, onEvent?: ScalerEventCallback, effectiveLimits?: EffectiveLimits): Promise<ManagedAgent>;
|
|
148
|
+
spawn(labelSet: string[], agentId: string, orchestratorUrl: string, onEvent?: ScalerEventCallback, effectiveLimits?: EffectiveLimits, _spawnContext?: SpawnContext, _signal?: AbortSignal): Promise<ManagedAgent>;
|
|
128
149
|
getScalerContext(agentId: string): Record<string, unknown> | undefined;
|
|
129
150
|
/**
|
|
130
151
|
* Bridge config for host-network diagnostics (read-only snapshot).
|
|
@@ -138,6 +159,12 @@ export declare class FirecrackerScalerBackend implements ScalerBackend {
|
|
|
138
159
|
bridgeCidr: string;
|
|
139
160
|
table: string;
|
|
140
161
|
};
|
|
162
|
+
/**
|
|
163
|
+
* Verify and (if needed) provision this backend's host bridge on startup.
|
|
164
|
+
* No-op unless autoProvisionHost is set. Throws on a real provision failure;
|
|
165
|
+
* ScalerManager.ensureHostsReady catches per-backend and degrades this scaler.
|
|
166
|
+
*/
|
|
167
|
+
ensureHostReady(): Promise<void>;
|
|
141
168
|
destroy(managedId: string): Promise<void>;
|
|
142
169
|
shutdownAll(): Promise<void>;
|
|
143
170
|
/**
|
package/dist/scaler/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Supports Docker, bare-metal, and Firecracker backends with YAML configuration,
|
|
6
6
|
* label-set matching, and warm pool management.
|
|
7
7
|
*/
|
|
8
|
-
export type { ResourceLimits, LabelSetConfig, ManagedAgent, ScaleResult, ValidationResult, ScalerBackend, ScalerConfig, ScalerEntry, ScalerEvent, WarmPoolConfig, FirecrackerNetworkConfig, } from './types.js';
|
|
8
|
+
export type { ResourceLimits, LabelSetConfig, ManagedAgent, ScaleResult, ValidationResult, ScalerBackend, ScalerConfig, ScalerEntry, ScalerEvent, ScalerRedispatchTrigger, WarmPoolConfig, FirecrackerNetworkConfig, } from './types.js';
|
|
9
9
|
export { loadScalerConfig, scalerFileSchema, firecrackerNetworkSchema, parseMemoryString, } from './config.js';
|
|
10
10
|
export { normalizeLabelSet, labelSetsMatch, detectLabelSetOverlaps, findBackendForLabels, } from './label-matcher.js';
|
|
11
11
|
export { ContainerScalerBackend, detectRuntime } from './container-backend.js';
|
package/dist/scaler/manager.d.ts
CHANGED
|
@@ -10,6 +10,27 @@ import type { ResourceRequest } from '@kici-dev/engine';
|
|
|
10
10
|
import type { BackendFailureSummary } from './failure-tracker.js';
|
|
11
11
|
import type { ScalerBackend, ScalerConfig, ScaleResult, ScalerEvent, ResourceCap, ValidationResult } from './types.js';
|
|
12
12
|
import type { ScalerStateStore, ScalerStateRecovery } from './scaler-state-store.js';
|
|
13
|
+
/**
|
|
14
|
+
* Counting semaphore that throttles the number of concurrent async operations.
|
|
15
|
+
*
|
|
16
|
+
* Used to bound how many `backend.spawn` provisioning operations (image pull +
|
|
17
|
+
* container create + start) run at once per backend, so a burst of in-cap jobs
|
|
18
|
+
* cannot storm the container socket / registry.
|
|
19
|
+
*
|
|
20
|
+
* Slots are handed directly to the next waiter on release (rather than bumping a
|
|
21
|
+
* counter the woken task re-decrements), so a task arriving in the microtask gap
|
|
22
|
+
* between a release and a woken waiter cannot jump the queue and transiently
|
|
23
|
+
* exceed the cap. The slot is always released in `run`'s `finally`, so a failed
|
|
24
|
+
* or throwing operation never leaks a slot and wedges the queue.
|
|
25
|
+
*/
|
|
26
|
+
export declare class SpawnSemaphore {
|
|
27
|
+
private available;
|
|
28
|
+
private readonly waiters;
|
|
29
|
+
constructor(max: number);
|
|
30
|
+
private acquire;
|
|
31
|
+
private release;
|
|
32
|
+
run<T>(fn: () => Promise<T>): Promise<T>;
|
|
33
|
+
}
|
|
13
34
|
/**
|
|
14
35
|
* Resolved per-job resource amounts (cpus + bytes) for both `requests` and
|
|
15
36
|
* `limits`. The scaler manager produces this from the job's declared resources
|
|
@@ -115,6 +136,10 @@ export declare class ScalerManager {
|
|
|
115
136
|
private readonly globalUsage;
|
|
116
137
|
/** Per-scaler machine-pool name (set when scalers reference a pool). */
|
|
117
138
|
private readonly scalerMachinePools;
|
|
139
|
+
/** Per-scaler cap on concurrent `backend.spawn` operations (provisioning-rate throttle). */
|
|
140
|
+
private readonly maxConcurrentSpawns;
|
|
141
|
+
/** Per-scaler spawn throttles, created lazily from `maxConcurrentSpawns`. */
|
|
142
|
+
private readonly spawnSemaphores;
|
|
118
143
|
/** Outstanding reservations keyed by agentId; used to release on disconnect. */
|
|
119
144
|
private readonly reservations;
|
|
120
145
|
/**
|
|
@@ -160,6 +185,23 @@ export declare class ScalerManager {
|
|
|
160
185
|
* External callback for relaying correlated scaler events (e.g. to execution tracker).
|
|
161
186
|
*/
|
|
162
187
|
private readonly onScalerEvent?;
|
|
188
|
+
/** Coordinator drain predicate; when true, requestScale() no-ops (no fresh
|
|
189
|
+
* agents spawned for the held Pending backlog). Defaults to never-draining. */
|
|
190
|
+
private readonly isDraining;
|
|
191
|
+
/**
|
|
192
|
+
* Optional callback fired (debounced) whenever scaler capacity frees — an
|
|
193
|
+
* ephemeral agent released its reservation on disconnect, a spawn failed, or a
|
|
194
|
+
* managed agent completed its job. Wired by the composition roots to the
|
|
195
|
+
* dispatcher's capacity-freed re-drive so jobs that got an `at-capacity`
|
|
196
|
+
* verdict get re-offered to the scaler the moment a slot opens, instead of
|
|
197
|
+
* sitting pending until they time out. Assigned after construction because it
|
|
198
|
+
* references the dispatcher, which is built after the manager.
|
|
199
|
+
*/
|
|
200
|
+
onCapacityFreed?: () => void;
|
|
201
|
+
/** Trailing-debounce timer coalescing a burst of releases into one re-drive. */
|
|
202
|
+
private capacityFreedTimer;
|
|
203
|
+
/** Trailing debounce window for {@link notifyCapacityFreed}. */
|
|
204
|
+
private static readonly CAPACITY_FREED_DEBOUNCE_MS;
|
|
163
205
|
private readonly warmPool;
|
|
164
206
|
/**
|
|
165
207
|
* Optional DB-backed state store. When wired (production path), every
|
|
@@ -169,6 +211,10 @@ export declare class ScalerManager {
|
|
|
169
211
|
* Unit tests can omit the store and operate from in-memory Maps only.
|
|
170
212
|
*/
|
|
171
213
|
private readonly stateStore?;
|
|
214
|
+
/** Cluster-wide default deadline (ms) for a single `backend.spawn`. */
|
|
215
|
+
private readonly spawnTimeoutMs;
|
|
216
|
+
/** Optional per-org spawn-deadline resolver (production path; DB-backed). */
|
|
217
|
+
private readonly resolveSpawnTimeoutMs?;
|
|
172
218
|
constructor(deps: {
|
|
173
219
|
config: ScalerConfig;
|
|
174
220
|
backends: Array<{
|
|
@@ -194,17 +240,64 @@ export declare class ScalerManager {
|
|
|
194
240
|
/** Orchestrator instance id (used in ledger rows for ownership). */
|
|
195
241
|
instanceId: string;
|
|
196
242
|
};
|
|
243
|
+
/** Coordinator drain predicate. When true, requestScale() declines to spawn
|
|
244
|
+
* fresh capacity for the held Pending backlog. Defaults to never-draining. */
|
|
245
|
+
isDraining?: () => boolean;
|
|
246
|
+
/**
|
|
247
|
+
* Cluster-wide default deadline (ms) for a single `backend.spawn`. Always
|
|
248
|
+
* supplied (from config.scalerSpawnTimeoutMs); the per-org resolver, when
|
|
249
|
+
* present, overrides it per tenant.
|
|
250
|
+
*/
|
|
251
|
+
spawnTimeoutMs: number;
|
|
252
|
+
/**
|
|
253
|
+
* Optional per-org resolver for the spawn deadline: given the job's org
|
|
254
|
+
* (jobConfig.cacheOrgId, undefined for warm-pool spawns), returns the
|
|
255
|
+
* effective timeout, falling back to the cluster default internally. Wired
|
|
256
|
+
* in orchestrator-core (has DB); omitted by the worker + unit tests → the
|
|
257
|
+
* cluster default spawnTimeoutMs is used.
|
|
258
|
+
*/
|
|
259
|
+
resolveSpawnTimeoutMs?: (orgId: string | undefined) => Promise<number>;
|
|
197
260
|
});
|
|
198
261
|
/** Per-scaler mandatoryLabels (taint-style opt-in gate). */
|
|
199
262
|
private readonly scalerMandatoryLabels;
|
|
263
|
+
/** Declared structured platform per scaler (undefined = host-derive / linux default). */
|
|
264
|
+
private readonly scalerPlatform;
|
|
265
|
+
/**
|
|
266
|
+
* Warn when a pool declares a plain platform-ish label (matched by the legacy
|
|
267
|
+
* denylist) but omits the structured `platform` field. The denylist is a
|
|
268
|
+
* migration shim; declaring `platform` is the canonical way to taint a pool.
|
|
269
|
+
*/
|
|
270
|
+
private warnOnUnstructuredPlatformLabels;
|
|
271
|
+
/**
|
|
272
|
+
* Resolve the pool's platform for label + taint derivation. Precedence:
|
|
273
|
+
* 1. A declared `platform` field always wins (even on a linux host).
|
|
274
|
+
* 2. Otherwise a bare-metal pool derives its platform from the host OS/arch.
|
|
275
|
+
* 3. Otherwise (container / firecracker, undeclared) returns null — those
|
|
276
|
+
* pools run linux agents and are not auto-tainted; only an explicit
|
|
277
|
+
* declared platform or a legacy denylist label taints them.
|
|
278
|
+
* Returns null when a bare-metal host's OS/arch is not a supported enum value
|
|
279
|
+
* (the caller falls back to the raw host-label derivation for labels).
|
|
280
|
+
*/
|
|
281
|
+
private resolveScalerPlatform;
|
|
282
|
+
/**
|
|
283
|
+
* Effective taint gate for a scaler: its configured mandatoryLabels plus the
|
|
284
|
+
* platform-taint labels derived from the pool's resolved structured platform,
|
|
285
|
+
* unioned with the legacy plain-label denylist shim. A pool declaring a
|
|
286
|
+
* non-default platform (`windows`, `macos`, `arm64`, …) only accepts jobs that
|
|
287
|
+
* request that platform. Container / firecracker pools resolve to linux and
|
|
288
|
+
* carry no taint; calling it uniformly is safe.
|
|
289
|
+
*/
|
|
290
|
+
private effectiveMandatoryLabels;
|
|
200
291
|
/**
|
|
201
292
|
* Build enriched scaler entries with auto-labels injected into each label set.
|
|
202
293
|
* This ensures label matching accounts for auto-injected labels (kici:role:*,
|
|
203
294
|
* kici:os:*, kici:arch:*, kici:agent:*, kici:scaler:*) that agents receive
|
|
204
295
|
* at spawn time.
|
|
205
296
|
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
297
|
+
* The os/arch labels derive from the pool's resolved structured platform
|
|
298
|
+
* (declared field wins, else host-derive for bare-metal, else linux), and the
|
|
299
|
+
* mandatory labels combine the per-scaler config gate with the platform taint,
|
|
300
|
+
* so the label matcher applies the gate alongside subset matching.
|
|
208
301
|
*/
|
|
209
302
|
private getEnrichedScalerEntries;
|
|
210
303
|
/**
|
|
@@ -214,12 +307,28 @@ export declare class ScalerManager {
|
|
|
214
307
|
* back to scaler defaults). Used by per-scaler / per-orchestrator / per-machine
|
|
215
308
|
* resource caps; the cap math is wired up by ScalerManager itself.
|
|
216
309
|
*/
|
|
217
|
-
|
|
310
|
+
/**
|
|
311
|
+
* Run a single backend spawn under the resolved spawn deadline. Returns the
|
|
312
|
+
* ManagedAgent on success. On deadline: aborts the signal (so the backend's
|
|
313
|
+
* threaded container-runtime/HTTP calls cancel and its own catch cleans up)
|
|
314
|
+
* AND rejects, so the caller's semaphore `run()` finally releases the slot
|
|
315
|
+
* even if the backend's unwind stalls in a non-abortable spot. The backing
|
|
316
|
+
* spawn promise gets a no-op catch attached so a late abort-rejection doesn't
|
|
317
|
+
* surface as an unhandled rejection.
|
|
318
|
+
*/
|
|
319
|
+
private runSpawnWithTimeout;
|
|
320
|
+
requestScale(labels: string[], jobId: string, runId: string, excludeLabels?: string[], resources?: ResourceRequest, orgId?: string): Promise<ScaleResult>;
|
|
218
321
|
/**
|
|
219
322
|
* Run a critical section under the reservation lock. Serializes concurrent
|
|
220
323
|
* `requestScale()` calls so the check+reserve sequence is atomic.
|
|
221
324
|
*/
|
|
222
325
|
private runWithReservationLock;
|
|
326
|
+
/**
|
|
327
|
+
* Lazily resolve the per-backend spawn throttle, sized by the scaler's
|
|
328
|
+
* `maxConcurrentSpawns` (falling back to the cluster default). One semaphore
|
|
329
|
+
* per backend name, since each backend has its own container socket.
|
|
330
|
+
*/
|
|
331
|
+
private spawnSemaphoreFor;
|
|
223
332
|
/**
|
|
224
333
|
* Resolve the effective `{ requests, limits }` for a job at this scaler.
|
|
225
334
|
*
|
|
@@ -259,6 +368,15 @@ export declare class ScalerManager {
|
|
|
259
368
|
* references a pool.
|
|
260
369
|
*/
|
|
261
370
|
private releaseAll;
|
|
371
|
+
/**
|
|
372
|
+
* Signal that scaler capacity freed. Trailing-debounced by
|
|
373
|
+
* {@link CAPACITY_FREED_DEBOUNCE_MS} so a burst of simultaneous releases (and
|
|
374
|
+
* the onJobComplete → onAgentDisconnect pair for a single-use agent) coalesces
|
|
375
|
+
* into one re-drive pass that runs after the last release settles. No-op when
|
|
376
|
+
* no callback is wired. The timer is `unref`'d so it never keeps the process
|
|
377
|
+
* alive, and cleared on shutdown.
|
|
378
|
+
*/
|
|
379
|
+
private notifyCapacityFreed;
|
|
262
380
|
/**
|
|
263
381
|
* Subtract the given `requests` from the per-scaler and global in-memory
|
|
264
382
|
* counters. Used both by `releaseAll()` and by the rollback path when a
|
|
@@ -284,7 +402,9 @@ export declare class ScalerManager {
|
|
|
284
402
|
* Used by the caller to eagerly dispatch the bound job before the
|
|
285
403
|
* agent's idle timer fires, skipping the generic queue drain race.
|
|
286
404
|
* - `mandatoryLabels` (always populated for scaler-managed agents): the
|
|
287
|
-
* spawning scaler's `mandatoryLabels` gate
|
|
405
|
+
* spawning scaler's effective `mandatoryLabels` gate — its configured
|
|
406
|
+
* labels plus the platform taint derived from the pool's declared OS/arch.
|
|
407
|
+
* Threaded into the
|
|
288
408
|
* AgentRegistry so the queue-drain path (`onAgentAvailable` →
|
|
289
409
|
* `dequeueForLabels`) and the eager-dispatch path
|
|
290
410
|
* (`dispatchBoundJob` → `dequeueById`) both reject queued jobs whose
|
|
@@ -359,6 +479,29 @@ export declare class ScalerManager {
|
|
|
359
479
|
* Firecracker backend's `getBridgeConfig()`).
|
|
360
480
|
*/
|
|
361
481
|
getBackend(name: string): ScalerBackend | undefined;
|
|
482
|
+
/**
|
|
483
|
+
* Whether some configured backend could spawn capacity for this label set —
|
|
484
|
+
* the same `findBackendForLabels` match `requestScale` makes, asked without
|
|
485
|
+
* spawning anything.
|
|
486
|
+
*
|
|
487
|
+
* Read by the queue-expiry sweep to tell a fleet/label problem apart from a
|
|
488
|
+
* capacity one: a job whose labels no agent AND no backend can serve could
|
|
489
|
+
* never have run (`unroutable`), while a job whose backend matched but whose
|
|
490
|
+
* spawn kept failing is a provisioning/capacity problem (`timed_out_stale`),
|
|
491
|
+
* and mislabelling the latter would tell an operator to fix a `runsOn` that
|
|
492
|
+
* is perfectly correct.
|
|
493
|
+
*
|
|
494
|
+
* Exact labels only — the scaler's own routing (`requestScale`) matches on
|
|
495
|
+
* exact labels, so a regex `runsOn` matcher is not expressible here. On a
|
|
496
|
+
* scaler-configured orchestrator that makes the answer conservative for a
|
|
497
|
+
* pattern-only `runsOn`: a backend whose labelSets carry no mandatory labels
|
|
498
|
+
* matches the empty exact set, so such a job is reported routable and settles
|
|
499
|
+
* `timed_out_stale` rather than `unroutable`. That loses precision, never
|
|
500
|
+
* safety — the job is still terminal and the run still fails, which is the
|
|
501
|
+
* invariant that matters. Tightening it means teaching scaler routing about
|
|
502
|
+
* patterns, which would change where jobs actually spawn.
|
|
503
|
+
*/
|
|
504
|
+
hasBackendForLabels(labels: string[], excludeLabels?: string[]): boolean;
|
|
362
505
|
/**
|
|
363
506
|
* Get scaler-specific configuration metadata for a managed agent.
|
|
364
507
|
* Returns undefined for non-scaler-managed (static) agents.
|
|
@@ -370,10 +513,25 @@ export declare class ScalerManager {
|
|
|
370
513
|
*/
|
|
371
514
|
start(): void;
|
|
372
515
|
/**
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
*
|
|
516
|
+
* Provision/heal every backend's host prerequisites before spawning starts.
|
|
517
|
+
* Awaits each backend's optional ensureHostReady, catching per-backend so one
|
|
518
|
+
* scaler's host-prep failure degrades only that scaler (its spawns will fail
|
|
519
|
+
* with clear errors + the firecracker-network diagnostic reports it) rather
|
|
520
|
+
* than aborting orchestrator startup.
|
|
521
|
+
*/
|
|
522
|
+
ensureHostsReady(): Promise<void>;
|
|
523
|
+
/**
|
|
524
|
+
* Remove spawning entries whose `backend.spawn` started more than 5 minutes
|
|
525
|
+
* ago but never registered via WS (e.g., process/container crashed on
|
|
526
|
+
* startup). Without cleanup, these entries would leak in spawningAgents
|
|
527
|
+
* forever.
|
|
528
|
+
*
|
|
529
|
+
* The window is measured from `spawnStartedAt` (when the throttled spawn
|
|
530
|
+
* actually began), NOT from `spawnedAt` (enqueue time): a spawn still waiting
|
|
531
|
+
* behind the per-backend spawn semaphore has not started and must not be
|
|
532
|
+
* reaped mid-queue during a large burst. Recovered orphan entries carry
|
|
533
|
+
* `spawnStartedAt` set to their persisted enqueue time, so they are subject to
|
|
534
|
+
* the normal window.
|
|
377
535
|
*/
|
|
378
536
|
private pruneStaleSpawningEntries;
|
|
379
537
|
private persistSpawningAgent;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface PendingScaleSweeperOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Re-drive callback — the dispatcher's `retryPendingScaleRequests` bound to
|
|
4
|
+
* the `sweep` trigger. Returns the number of jobs re-driven (logged when > 0).
|
|
5
|
+
*/
|
|
6
|
+
redrive: () => Promise<number>;
|
|
7
|
+
/** Sweep interval in milliseconds. */
|
|
8
|
+
intervalMs: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Leader-gated periodic backstop for the scaler capacity-freed re-drive.
|
|
12
|
+
*
|
|
13
|
+
* The capacity-freed hook (`ScalerManager.onCapacityFreed`) handles the common
|
|
14
|
+
* case with near-zero latency, but it can miss edge cases: a spawn that failed
|
|
15
|
+
* silently, a reservation freed on a non-leader coordinator, or a lost event.
|
|
16
|
+
* This sweeper re-runs the SAME `retryPendingScaleRequests` on a timer so a
|
|
17
|
+
* pending at-capacity job is never stranded past one interval.
|
|
18
|
+
*
|
|
19
|
+
* Modeled on `HostRosterReaper` / `EventRetryScanner`: started/stopped via the
|
|
20
|
+
* Raft leadership callbacks, a single timer cleared on `stop()`. Leader-only so
|
|
21
|
+
* multiple coordinators don't each drive the same queue.
|
|
22
|
+
*/
|
|
23
|
+
export declare class PendingScaleSweeper {
|
|
24
|
+
private readonly redrive;
|
|
25
|
+
private readonly intervalMs;
|
|
26
|
+
private timer;
|
|
27
|
+
private isLeader;
|
|
28
|
+
constructor(opts: PendingScaleSweeperOptions);
|
|
29
|
+
onBecomeLeader(): void;
|
|
30
|
+
onLoseLeadership(): void;
|
|
31
|
+
stop(): void;
|
|
32
|
+
/** One sweep pass. Public for tests. Never throws (logs and keeps ticking). */
|
|
33
|
+
tick(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=pending-scale-sweeper.d.ts.map
|
package/dist/scaler/types.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { z } from 'zod';
|
|
8
8
|
import { ScalerEventType } from '@kici-dev/engine';
|
|
9
|
-
import type { ResourceRequest, ResourceSpec, ScalerBackendType } from '@kici-dev/engine';
|
|
9
|
+
import type { ResourceRequest, ResourceSpec, ScalerBackendType, ScalerPlatform } from '@kici-dev/engine';
|
|
10
10
|
export type { ResourceRequest, ResourceSpec } from '@kici-dev/engine';
|
|
11
11
|
export { ScalerEventType } from '@kici-dev/engine';
|
|
12
12
|
/**
|
|
@@ -73,6 +73,22 @@ export interface NetworkPolicy {
|
|
|
73
73
|
/** Block all outbound traffic except allowlisted ranges */
|
|
74
74
|
denyAll?: boolean;
|
|
75
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Image pull policy for container-backend agent images.
|
|
78
|
+
*
|
|
79
|
+
* - `IfNotPresent` (default): pull only when the image is not already local.
|
|
80
|
+
* KiCI agent images are pinned + immutable, so re-pulling on every spawn only
|
|
81
|
+
* storms the registry/socket.
|
|
82
|
+
* - `Always`: re-pull on every spawn. Set this on a label set that tracks a
|
|
83
|
+
* moving tag (e.g. `:latest`) or otherwise needs a fresh image each spawn.
|
|
84
|
+
* - `Never`: never pull; fail if the image is absent.
|
|
85
|
+
*/
|
|
86
|
+
export declare const ImagePullPolicy: z.ZodEnum<{
|
|
87
|
+
Always: "Always";
|
|
88
|
+
IfNotPresent: "IfNotPresent";
|
|
89
|
+
Never: "Never";
|
|
90
|
+
}>;
|
|
91
|
+
export type ImagePullPolicy = z.infer<typeof ImagePullPolicy>;
|
|
76
92
|
/**
|
|
77
93
|
* Configuration for a single label-set mapping within a scaler backend.
|
|
78
94
|
* Maps an exact set of labels to the agent provisioning details.
|
|
@@ -82,8 +98,8 @@ export interface LabelSetConfig {
|
|
|
82
98
|
labels: string[];
|
|
83
99
|
/** Container image (Docker backend) */
|
|
84
100
|
image?: string;
|
|
85
|
-
/** Image pull policy:
|
|
86
|
-
imagePullPolicy?:
|
|
101
|
+
/** Image pull policy: IfNotPresent (default), Always, or Never */
|
|
102
|
+
imagePullPolicy?: ImagePullPolicy;
|
|
87
103
|
/** Path to agent binary (bare-metal backend) */
|
|
88
104
|
binaryPath?: string;
|
|
89
105
|
/**
|
|
@@ -154,7 +170,23 @@ export type ScaleResult = {
|
|
|
154
170
|
} | {
|
|
155
171
|
action: 'failed';
|
|
156
172
|
error: string;
|
|
173
|
+
}
|
|
174
|
+
/** Scale-up declined without attempting a spawn (e.g. coordinator draining). */
|
|
175
|
+
| {
|
|
176
|
+
action: 'skipped';
|
|
177
|
+
reason: string;
|
|
157
178
|
};
|
|
179
|
+
/**
|
|
180
|
+
* What triggered a pending-scale re-drive (`Dispatcher.retryPendingScaleRequests`):
|
|
181
|
+
* the near-zero-latency capacity-freed `hook` fired from `ScalerManager`, or the
|
|
182
|
+
* leader-gated periodic `sweep` backstop. Used as the `trigger` label on the
|
|
183
|
+
* `kici_orch_scaler_redispatch_total` counter.
|
|
184
|
+
*/
|
|
185
|
+
export declare const ScalerRedispatchTrigger: z.ZodEnum<{
|
|
186
|
+
hook: "hook";
|
|
187
|
+
sweep: "sweep";
|
|
188
|
+
}>;
|
|
189
|
+
export type ScalerRedispatchTrigger = z.infer<typeof ScalerRedispatchTrigger>;
|
|
158
190
|
/**
|
|
159
191
|
* Result of a configuration validation or reload operation.
|
|
160
192
|
*/
|
|
@@ -184,7 +216,8 @@ export interface ScalerBackend {
|
|
|
184
216
|
* True for bare-metal and Firecracker (local processes / local VMs) and for
|
|
185
217
|
* container backends using a local runtime socket; false when the backend
|
|
186
218
|
* provisions elsewhere (remote container runtime, future cloud backends).
|
|
187
|
-
* Drives the static spawning-host display on the
|
|
219
|
+
* Drives the static spawning-host display on the dashboard Infrastructure
|
|
220
|
+
* page.
|
|
188
221
|
*/
|
|
189
222
|
readonly spawnsOnLocalHost: boolean;
|
|
190
223
|
/** Current count of agents managed by this backend (including spawning) */
|
|
@@ -205,7 +238,14 @@ export interface ScalerBackend {
|
|
|
205
238
|
* @returns The managed agent tracking object
|
|
206
239
|
* @throws If the label set is not supported by this backend
|
|
207
240
|
*/
|
|
208
|
-
spawn(labelSet: string[], agentId: string, orchestratorUrl: string, onEvent?: ScalerEventCallback, effectiveLimits?: EffectiveLimits, spawnContext?: SpawnContext
|
|
241
|
+
spawn(labelSet: string[], agentId: string, orchestratorUrl: string, onEvent?: ScalerEventCallback, effectiveLimits?: EffectiveLimits, spawnContext?: SpawnContext,
|
|
242
|
+
/**
|
|
243
|
+
* Optional abort signal from the ScalerManager spawn-timeout wrapper. When
|
|
244
|
+
* aborted, backends thread it into any long-running provisioning I/O
|
|
245
|
+
* (container-runtime requests, HTTP calls) so a hung provision cancels
|
|
246
|
+
* instead of pinning the per-backend spawn-semaphore slot.
|
|
247
|
+
*/
|
|
248
|
+
signal?: AbortSignal): Promise<ManagedAgent>;
|
|
209
249
|
/**
|
|
210
250
|
* Destroy a specific managed agent.
|
|
211
251
|
* Docker: docker rm -f; Bare-metal: SIGTERM -> SIGKILL
|
|
@@ -224,6 +264,14 @@ export interface ScalerBackend {
|
|
|
224
264
|
* Used by the orchestrator to enrich job.context before forwarding to Platform.
|
|
225
265
|
*/
|
|
226
266
|
getScalerContext?(agentId: string): Record<string, unknown> | undefined;
|
|
267
|
+
/**
|
|
268
|
+
* Provision or heal this backend's host prerequisites before it spawns.
|
|
269
|
+
* Called once by ScalerManager during startup. Optional — only backends with
|
|
270
|
+
* host-side setup (Firecracker's bridge) implement it; container/bare-metal
|
|
271
|
+
* omit it. May throw; the manager catches per-backend and degrades that
|
|
272
|
+
* scaler rather than aborting orchestrator startup.
|
|
273
|
+
*/
|
|
274
|
+
ensureHostReady?(): Promise<void>;
|
|
227
275
|
/**
|
|
228
276
|
* Reload configuration (called on SIGHUP).
|
|
229
277
|
* Returns validation errors if new config is invalid.
|
|
@@ -250,6 +298,12 @@ export interface FirecrackerNetworkConfig {
|
|
|
250
298
|
netmask?: string;
|
|
251
299
|
/** nft table name for this coordinator's host bridge @default 'kici' */
|
|
252
300
|
table?: string;
|
|
301
|
+
/**
|
|
302
|
+
* When true (default), the orchestrator verifies and provisions this host
|
|
303
|
+
* bridge on startup (self-heal), so a fresh Firecracker host needs no manual
|
|
304
|
+
* `kici-admin firecracker provision`. @default true
|
|
305
|
+
*/
|
|
306
|
+
autoProvisionHost?: boolean;
|
|
253
307
|
}
|
|
254
308
|
/**
|
|
255
309
|
* Parsed and validated scaler configuration from YAML.
|
|
@@ -293,8 +347,15 @@ export interface ScalerEntry {
|
|
|
293
347
|
name: string;
|
|
294
348
|
/** Backend type */
|
|
295
349
|
type: Exclude<ScalerBackendType, 'kubernetes'>;
|
|
296
|
-
/** Maximum concurrent agents for this scaler */
|
|
350
|
+
/** Maximum concurrent agents for this scaler (population cap) */
|
|
297
351
|
maxAgents: number;
|
|
352
|
+
/**
|
|
353
|
+
* Maximum concurrent `backend.spawn` operations for this scaler
|
|
354
|
+
* (provisioning-rate throttle). Orthogonal to `maxAgents`: excess in-cap
|
|
355
|
+
* spawns queue and drain at this rate rather than storming the socket.
|
|
356
|
+
* Defaults to `DEFAULT_MAX_CONCURRENT_SPAWNS` at config-load.
|
|
357
|
+
*/
|
|
358
|
+
maxConcurrentSpawns: number;
|
|
298
359
|
/** Label-set to image/binary mappings */
|
|
299
360
|
labelSets: LabelSetConfig[];
|
|
300
361
|
/** Container runtime host (e.g. 'tcp://192.168.1.10:2376'). Works for both Docker and Podman remote. */
|
|
@@ -319,6 +380,14 @@ export interface ScalerEntry {
|
|
|
319
380
|
* `labelSets`. Default: `[]` (no gating).
|
|
320
381
|
*/
|
|
321
382
|
mandatoryLabels?: string[];
|
|
383
|
+
/**
|
|
384
|
+
* Structured platform of this pool's agents. When set, the auto-injected
|
|
385
|
+
* `kici:os:*` / `kici:arch:*` labels AND the mandatory platform taint both
|
|
386
|
+
* derive from this single field. Optional: when omitted, bare-metal pools
|
|
387
|
+
* derive the platform from the host OS/arch, and container / firecracker
|
|
388
|
+
* pools default to linux.
|
|
389
|
+
*/
|
|
390
|
+
readonly platform?: ScalerPlatform;
|
|
322
391
|
/**
|
|
323
392
|
* Agent roles this scaler handles. scaler-entry level, not per-label-set.
|
|
324
393
|
* - undefined (not set): handles all job types including build and init (backward compat,)
|