@kici-dev/orchestrator 0.6.1 → 0.7.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/agent/dispatcher.d.ts +10 -1
- package/dist/agent/host-roster.d.ts +8 -3
- package/dist/agent/registry.d.ts +60 -5
- package/dist/app.d.ts +10 -5
- package/dist/cache/dep-cache.d.ts +14 -6
- package/dist/cache/global-eval-round-cache.d.ts +1 -1
- package/dist/cache/index.d.ts +1 -1
- package/dist/cache/source-cache.d.ts +92 -15
- package/dist/cancel/cancel-run.d.ts +20 -2
- package/dist/cancel/sweep-stuck-cancelling.d.ts +30 -0
- package/dist/cli/api-client.d.ts +10 -0
- package/dist/cli/commands/agent-service/logs.d.ts +1 -1
- package/dist/cli/commands/agent-service/restart.d.ts +1 -1
- package/dist/cli/commands/agent-service/start.d.ts +1 -1
- package/dist/cli/commands/agent-service/status.d.ts +1 -1
- package/dist/cli/commands/agent-service/stop.d.ts +1 -1
- package/dist/cli/commands/agent-service/uninstall.d.ts +1 -1
- package/dist/cli/commands/agent.d.ts +25 -0
- package/dist/cli/commands/config.d.ts +16 -0
- package/dist/cli/commands/db-backup.d.ts +46 -0
- package/dist/cli/commands/held-run.d.ts +9 -0
- package/dist/cli/commands/orchestrator-service/drain.d.ts +2 -19
- package/dist/cli/commands/orchestrator-service/index.d.ts +9 -1
- package/dist/cli/commands/orchestrator-service/install-env.d.ts +43 -2
- package/dist/cli/commands/orchestrator-service/logs.d.ts +1 -1
- package/dist/cli/commands/orchestrator-service/restart.d.ts +1 -1
- package/dist/cli/commands/orchestrator-service/start.d.ts +1 -1
- package/dist/cli/commands/orchestrator-service/status.d.ts +17 -1
- package/dist/cli/commands/orchestrator-service/stop.d.ts +1 -1
- package/dist/cli/commands/orchestrator-service/uninstall.d.ts +1 -1
- package/dist/cli/commands/orchestrator-service/upgrade.d.ts +2 -1
- package/dist/cli/commands/rotate.d.ts +1 -1
- package/dist/cli/commands/shared/env-file-mode.d.ts +16 -0
- package/dist/cli/commands/shared/upgrade-hooks.d.ts +32 -0
- package/dist/cli/commands/shared/upgrade-safety.d.ts +81 -0
- package/dist/cli/commands/shared/versioned-upgrade.d.ts +67 -12
- package/dist/cli/commands/source.d.ts +1 -0
- package/dist/cli/commands/token.d.ts +4 -0
- package/dist/cli/commands/trust-policy.d.ts +57 -1
- package/dist/cli/join.d.ts +1 -1
- package/dist/cli/service/backup-timer.d.ts +108 -0
- package/dist/cli/service/compose-path.d.ts +11 -0
- package/dist/cli/service/compose.d.ts +22 -0
- package/dist/cli/service/deploy-env.d.ts +10 -11
- package/dist/cli/service/env-assignment.d.ts +24 -0
- package/dist/cli/service/index.d.ts +2 -2
- package/dist/cli/service/instance/resolve.d.ts +71 -7
- package/dist/cli/service/instance/types.d.ts +15 -0
- package/dist/cli/service/launchd.d.ts +7 -0
- package/dist/cli/service/systemd.d.ts +1 -0
- package/dist/cli/service/types.d.ts +36 -0
- package/dist/cli/service/windows.d.ts +16 -0
- package/dist/cli/wizard/orchestrator-wizard.d.ts +12 -3
- package/dist/cli/wizard/prompts.d.ts +7 -0
- package/dist/cli.js +12525 -9298
- package/dist/cluster/cluster-settings-reader.d.ts +2 -2
- package/dist/cluster/coordinator.d.ts +11 -0
- package/dist/cluster/instance-heartbeat.d.ts +96 -0
- package/dist/cluster/join-client.d.ts +55 -5
- package/dist/cluster/join-handler.d.ts +1 -0
- package/dist/cluster/orphan-recovery.d.ts +16 -0
- package/dist/cluster/peer-registry.d.ts +10 -0
- package/dist/concurrency/dispatch-next-queued.d.ts +1 -13
- package/dist/concurrency/index.d.ts +1 -2
- package/dist/concurrency/queue-manager.d.ts +63 -18
- package/dist/config/env-overlay.d.ts +3 -2
- package/dist/config.d.ts +24 -0
- package/dist/contexts/release-queued-holds.d.ts +23 -1
- package/dist/dashboard/attestation-filters.d.ts +2 -0
- package/dist/dashboard/handler.d.ts +22 -2
- package/dist/db/deferred-indexes.d.ts +72 -0
- package/dist/db/migration-test-harness.d.ts +22 -0
- package/dist/db/migrations/131_execution_jobs_git_credentials.d.ts +30 -0
- package/dist/db/migrations/132_execution_runs_trigger_event.d.ts +23 -0
- package/dist/db/migrations/133_dispatch_queue_source_tar_digest.d.ts +23 -0
- package/dist/db/migrations/134_dispatch_queue_ownership.d.ts +4 -0
- package/dist/db/migrations/135_cluster_settings_retention_days.d.ts +4 -0
- package/dist/db/migrations/136_master_key_wrapped_tables_key_version.d.ts +4 -0
- package/dist/db/migrations/137_execution_runs_pr_head_context.d.ts +4 -0
- package/dist/db/migrations/138_execution_runs_subject_trigger_event.d.ts +4 -0
- package/dist/db/migrations/139_admin_token_subject.d.ts +4 -0
- package/dist/db/migrations/140_dispatch_queue_canonical_labels.d.ts +54 -0
- package/dist/db/migrations/141_event_log_shed.d.ts +15 -0
- package/dist/db/migrator.d.ts +47 -0
- package/dist/db/notify-listener.d.ts +60 -0
- package/dist/db/synthetic-job-ids.d.ts +24 -0
- package/dist/db/types.d.ts +169 -4
- package/dist/deployment/deployment-identity.d.ts +31 -1
- package/dist/diagnostics/checks/index.d.ts +2 -1
- package/dist/diagnostics/checks/retention.d.ts +24 -0
- package/dist/diagnostics/types.d.ts +7 -0
- package/dist/events/event-router.d.ts +1 -1
- package/dist/fault-injection-types.d.ts +53 -0
- package/dist/firecracker/host-network.d.ts +63 -8
- package/dist/git/credential-broker.d.ts +35 -2
- package/dist/git/inherited-secret.d.ts +7 -2
- package/dist/git/job-context.d.ts +7 -4
- package/dist/helpers/secure-write.d.ts +35 -0
- package/dist/index.js +196 -67
- package/dist/metrics/prometheus.d.ts +116 -1
- package/dist/oidc/db-signer.d.ts +27 -5
- package/dist/oidc/id-token-claims.d.ts +33 -2
- package/dist/oidc/oidc-mint-registration.d.ts +6 -0
- package/dist/oidc/orchestrator-mint.d.ts +8 -0
- package/dist/oidc/reconcile-signing-key.d.ts +37 -0
- package/dist/orchestrator-core.d.ts +9 -3
- package/dist/pipeline/decorating-secret-resolver.d.ts +1 -1
- package/dist/pipeline/dispatch-matched-workflow.d.ts +65 -14
- package/dist/pipeline/manual-schedule.d.ts +1 -0
- package/dist/pipeline/process-webhook.d.ts +20 -2
- package/dist/pipeline/route-or-dispatch-jobs.d.ts +7 -0
- package/dist/pipeline/run-event-context.d.ts +39 -0
- package/dist/policy/dashboard-write-policy-listener.d.ts +1 -1
- package/dist/policy/dashboard-write-policy.d.ts +47 -1
- package/dist/provenance/dispatch-context.d.ts +46 -0
- package/dist/provenance/verify-deferred-capture.d.ts +39 -0
- package/dist/providers/github/auth.d.ts +9 -0
- package/dist/providers/github/deliveries.d.ts +118 -0
- package/dist/providers/universal-git/config.d.ts +1 -1
- package/dist/queue/cleanup.d.ts +13 -0
- package/dist/queue/job-queue.d.ts +162 -14
- package/dist/queue/retention.d.ts +105 -0
- package/dist/reporting/execution-tracker.d.ts +87 -36
- package/dist/routes/admin-db.d.ts +5 -0
- package/dist/routes/admin-events.d.ts +13 -0
- package/dist/routes/admin-held-runs.d.ts +11 -1
- package/dist/routes/admin-org-settings.d.ts +9 -0
- package/dist/routes/admin-runs.d.ts +7 -4
- package/dist/routes/admin-sources.d.ts +15 -0
- package/dist/routes/admin-trust-policy.d.ts +11 -0
- package/dist/routes/admin.d.ts +25 -0
- package/dist/scaler/backend-factory.d.ts +16 -0
- package/dist/scaler/bare-metal-backend.d.ts +22 -4
- package/dist/scaler/config.d.ts +6 -3
- package/dist/scaler/container-backend.d.ts +102 -3
- package/dist/scaler/container-hostconfig.d.ts +60 -0
- package/dist/scaler/file-tail.d.ts +25 -2
- package/dist/scaler/firecracker-api.d.ts +9 -1
- package/dist/scaler/firecracker-backend.d.ts +135 -2
- package/dist/scaler/host-access.d.ts +59 -0
- package/dist/scaler/index.d.ts +1 -0
- package/dist/scaler/manager.d.ts +33 -0
- package/dist/scaler/scaler-state-store.d.ts +6 -0
- package/dist/scaler/types.d.ts +5 -7
- package/dist/secrets/config.d.ts +48 -0
- package/dist/secrets/dashboard-encryption-key.d.ts +19 -0
- package/dist/secrets/ephemeral-keys.d.ts +9 -3
- package/dist/secrets/index.d.ts +3 -1
- package/dist/secrets/job-secret-gate.d.ts +76 -0
- package/dist/secrets/master-key-rotation.d.ts +65 -0
- package/dist/secrets/secret-output-crypto.d.ts +17 -0
- package/dist/secrets/secret-resolver.d.ts +23 -6
- package/dist/secrets/source-credentials.d.ts +1 -1
- package/dist/secrets/token-manager.d.ts +4 -1
- package/dist/security/reduced-privilege-note.d.ts +5 -0
- package/dist/security/trust-policy-gate.d.ts +70 -6
- package/dist/security/trust-tier.d.ts +31 -0
- package/dist/server.d.ts +1 -1
- package/dist/server.js +10661 -5282
- package/dist/sources/source-manager.d.ts +1 -1
- package/dist/stale-detector/stale-dispatch-candidates.d.ts +43 -0
- package/dist/standalone.js +9258 -4122
- package/dist/storage/loopback-guard.d.ts +53 -6
- package/dist/webhook/event-log.d.ts +14 -1
- package/dist/webhook/generic-sources-listener.d.ts +1 -1
- package/dist/webhook/ingest-admission.d.ts +24 -0
- package/dist/webhook/ingest-overflow-replayer.d.ts +78 -14
- package/dist/webhook/ingest-overflow-types.d.ts +13 -1
- package/dist/webhook/register-source-bundle.d.ts +23 -0
- package/dist/webhook/relay-reinject.d.ts +11 -12
- package/dist/webhook/shed-breadcrumb.d.ts +15 -0
- package/dist/ws/git-credential-relay.d.ts +41 -12
- package/dist/ws/platform-client.d.ts +28 -5
- package/installer-image-digests.json +3 -3
- package/package.json +4 -4
- package/sbom.spdx.json +53 -53
- package/dist/concurrency/group-tracker.d.ts +0 -51
- package/dist/scaler/nftables.d.ts +0 -111
|
@@ -20,8 +20,44 @@ export interface BackupManifest {
|
|
|
20
20
|
clusterId: string | null;
|
|
21
21
|
hostname: string;
|
|
22
22
|
}
|
|
23
|
+
export interface CreateDbBackupOptions {
|
|
24
|
+
/** libpq connection URL of the database to dump. */
|
|
25
|
+
databaseUrl: string;
|
|
26
|
+
/** Absolute or relative path the `.dump` archive is written to. */
|
|
27
|
+
outputPath: string;
|
|
28
|
+
/** Handle used to insert the `backup_runs` row. */
|
|
29
|
+
db: Kysely<Database>;
|
|
30
|
+
/** Pool used to read the server version, key generation, and cluster id. */
|
|
31
|
+
pool: import('pg').Pool;
|
|
32
|
+
/** Timestamp stamped into the manifest. */
|
|
33
|
+
now: Date;
|
|
34
|
+
}
|
|
35
|
+
export interface CreateDbBackupResult {
|
|
36
|
+
outputPath: string;
|
|
37
|
+
byteSize: number;
|
|
38
|
+
manifest: BackupManifest;
|
|
39
|
+
}
|
|
23
40
|
export declare function manifestPath(dumpPath: string): string;
|
|
41
|
+
/** `kici-orchestrator-backup-<timestamp>.dump` — no directory component. */
|
|
42
|
+
export declare function dumpFileName(now: Date): string;
|
|
24
43
|
export declare function defaultDumpPath(now: Date): string;
|
|
44
|
+
/** Timestamped dump path inside a retention directory. */
|
|
45
|
+
export declare function dumpPathIn(dir: string, now: Date): string;
|
|
46
|
+
export interface PruneIo {
|
|
47
|
+
readdir: (dir: string) => Promise<string[]>;
|
|
48
|
+
mtimeMs: (p: string) => Promise<number>;
|
|
49
|
+
unlink: (p: string) => Promise<void>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Keep the newest {@link keep} `.dump` files in {@link dir} and delete the
|
|
53
|
+
* rest, each with its `.manifest.json` sidecar. Newest is decided by
|
|
54
|
+
* modification time, with the filename as a tiebreak because the timestamped
|
|
55
|
+
* names sort chronologically. Returns every path removed.
|
|
56
|
+
*
|
|
57
|
+
* A `keep` of 0 or less disables pruning: retention is opt-in, so a
|
|
58
|
+
* misconfigured value must never empty the directory.
|
|
59
|
+
*/
|
|
60
|
+
export declare function pruneBackupDir(dir: string, keep: number, io?: PruneIo): Promise<string[]>;
|
|
25
61
|
export declare function parsePgToolMajor(versionOutput: string): number;
|
|
26
62
|
export declare function serverVersionMajor(numStr: string): number;
|
|
27
63
|
export declare function assertToolVersionCompatible(toolMajor: number, serverMajor: number, tool: 'pg_dump' | 'pg_restore'): void;
|
|
@@ -57,6 +93,16 @@ export declare function buildBackupManifest(input: {
|
|
|
57
93
|
migrationsHash: string;
|
|
58
94
|
hostname: string;
|
|
59
95
|
}): BackupManifest;
|
|
96
|
+
/**
|
|
97
|
+
* Take one orchestrator database backup: pre-flight the `pg_dump` version,
|
|
98
|
+
* dump to {@link CreateDbBackupOptions.outputPath}, write the sidecar manifest,
|
|
99
|
+
* and record the `backup_runs` row.
|
|
100
|
+
*
|
|
101
|
+
* Prints nothing and never exits the process — every failure surfaces as a
|
|
102
|
+
* thrown Error so the caller decides how to report it. That is what lets both
|
|
103
|
+
* `kici-admin db backup` and the pre-upgrade hook share one implementation.
|
|
104
|
+
*/
|
|
105
|
+
export declare function createDbBackup(opts: CreateDbBackupOptions): Promise<CreateDbBackupResult>;
|
|
60
106
|
/**
|
|
61
107
|
* Message to print after a restore about the secret-key requirement. Returns
|
|
62
108
|
* null when the dump carried no encrypted secrets (nothing to warn about),
|
|
@@ -16,6 +16,15 @@
|
|
|
16
16
|
* one is. That refusal is surfaced verbatim rather than reworded here, so the
|
|
17
17
|
* CLI cannot drift from what the server actually said.
|
|
18
18
|
*
|
|
19
|
+
* A decision answers as the admin token by default, whose `service:` subject
|
|
20
|
+
* satisfies no `{user}` or `{team}` clause — enough for a hold that names
|
|
21
|
+
* nobody, and nothing at all for one that does. `--as <user-id>` answers as a
|
|
22
|
+
* member of the approval directory instead, the one `kici-admin trust-policy
|
|
23
|
+
* directory-set` writes, so a clause-bearing hold on an independent
|
|
24
|
+
* orchestrator has an answer rather than only an expiry. An id the directory
|
|
25
|
+
* does not carry is refused: an unvalidated subject would let a token satisfy
|
|
26
|
+
* any clause by naming it.
|
|
27
|
+
*
|
|
19
28
|
* A hold is named the same way `kici approve` names one — `--job` / `--step` /
|
|
20
29
|
* `--hold-type` / `--hold`, resolved by the shared `resolveHeldRunId` — so an
|
|
21
30
|
* operator disambiguating a doubly-held job types the same flags on either
|
|
@@ -8,24 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { Command } from 'commander';
|
|
10
10
|
import type { AdminApiClient } from '../../api-client.js';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
jobsRunning: number;
|
|
14
|
-
};
|
|
15
|
-
export interface WaitOpts {
|
|
16
|
-
timeoutMs: number;
|
|
17
|
-
intervalMs: number;
|
|
18
|
-
now?: () => number;
|
|
19
|
-
sleep?: (ms: number) => Promise<void>;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Poll `poll` until jobsRunning hits 0 or the timeout elapses. Pure with an
|
|
23
|
-
* injectable clock + sleep so it is testable without real time.
|
|
24
|
-
*/
|
|
25
|
-
export declare function waitForQuiesce(poll: () => Promise<Snapshot>, opts: WaitOpts): Promise<{
|
|
26
|
-
quiesced: boolean;
|
|
27
|
-
jobsRunning: number;
|
|
28
|
-
}>;
|
|
11
|
+
import { waitForQuiesce } from '../shared/upgrade-safety.js';
|
|
12
|
+
export { waitForQuiesce };
|
|
29
13
|
export declare function registerOrchestratorDrain(orchestrator: Command, getClient: () => AdminApiClient): void;
|
|
30
|
-
export {};
|
|
31
14
|
//# sourceMappingURL=drain.d.ts.map
|
|
@@ -11,5 +11,13 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import type { Command } from 'commander';
|
|
13
13
|
import type { AdminApiClient } from '../../api-client.js';
|
|
14
|
-
export declare function registerOrchestratorServiceCommands(program: Command, getClient: () => AdminApiClient
|
|
14
|
+
export declare function registerOrchestratorServiceCommands(program: Command, getClient: () => AdminApiClient,
|
|
15
|
+
/**
|
|
16
|
+
* Non-exiting client factory for the upgrade command. Its drain and
|
|
17
|
+
* schema-guard steps improve on a path that previously did neither, so an
|
|
18
|
+
* install with no admin credentials must still be able to upgrade — and
|
|
19
|
+
* `getClient` exits the process rather than throwing, which a caller cannot
|
|
20
|
+
* catch.
|
|
21
|
+
*/
|
|
22
|
+
tryGetClient: () => AdminApiClient | null): void;
|
|
15
23
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* command action stays small and the decision + stub content are unit-testable
|
|
8
8
|
* without driving the whole install through Commander.
|
|
9
9
|
*/
|
|
10
|
+
import { OrchestratorMode } from '@kici-dev/engine';
|
|
10
11
|
import type { OrchestratorSourceHint } from '../../wizard/orchestrator-wizard.js';
|
|
11
12
|
/** Which config source the install writes the env file from. */
|
|
12
13
|
export type InstallEnvMode = 'wizard' | 'env-file' | 'stub';
|
|
@@ -17,6 +18,20 @@ export interface WriteInstallEnvResult {
|
|
|
17
18
|
}
|
|
18
19
|
/** Public compose quickstart, pointed at from the stub env file. */
|
|
19
20
|
export declare const COMPOSE_QUICKSTART_URL = "https://docs.kici.dev/user/quickstart/compose/";
|
|
21
|
+
/** Direct-ingress guide, pointed at from the stub env file's KICI_WEBHOOK_PUBLIC_URL line. */
|
|
22
|
+
export declare const GITHUB_INGRESS_URL = "https://docs.kici.dev/operator/orchestrator/github-ingress/";
|
|
23
|
+
/**
|
|
24
|
+
* Operating mode a fresh install writes when the operator names none.
|
|
25
|
+
*
|
|
26
|
+
* `hybrid` is a superset of `platform`: the orchestrator accepts every
|
|
27
|
+
* Platform-relayed webhook exactly as `platform` does, and additionally serves
|
|
28
|
+
* its own ingress route, which verifies the HMAC signature before it acts on a
|
|
29
|
+
* delivery. It requires no configuration beyond what `platform` requires, so an
|
|
30
|
+
* orchestrator whose port nothing reaches behaves identically to a `platform`
|
|
31
|
+
* one — while an operator who later exposes that port stops losing pushes to a
|
|
32
|
+
* relay outage.
|
|
33
|
+
*/
|
|
34
|
+
export declare const DEFAULT_INSTALL_MODE: OrchestratorMode;
|
|
20
35
|
export interface WizardModeInput {
|
|
21
36
|
/** --wizard=true / --no-wizard=false / undefined when neither is passed. */
|
|
22
37
|
wizard?: boolean;
|
|
@@ -40,10 +55,12 @@ export declare function resolveWizardMode(input: WizardModeInput): InstallEnvMod
|
|
|
40
55
|
/**
|
|
41
56
|
* Build the stub env file: every required key with an inline explanation, a
|
|
42
57
|
* generation command for the two secrets, and a pointer to the compose
|
|
43
|
-
* quickstart. Fills KICI_DATABASE_URL from a --dev container URL when present
|
|
58
|
+
* quickstart. Fills KICI_DATABASE_URL from a --dev container URL when present,
|
|
59
|
+
* and KICI_MODE from `--mode` when the operator named one.
|
|
44
60
|
*/
|
|
45
61
|
export declare function buildStubEnv(opts: {
|
|
46
62
|
devDbUrl?: string;
|
|
63
|
+
mode?: OrchestratorMode;
|
|
47
64
|
}): string;
|
|
48
65
|
export interface WriteInstallEnvArgs {
|
|
49
66
|
mode: InstallEnvMode;
|
|
@@ -52,7 +69,31 @@ export interface WriteInstallEnvArgs {
|
|
|
52
69
|
envFileSource?: string;
|
|
53
70
|
/** Dev-provisioned DB URL, threaded into the stub / appended to an env file. */
|
|
54
71
|
devDbUrl?: string;
|
|
72
|
+
/**
|
|
73
|
+
* Operating mode from `--mode`. Written into the stub, and preselected in the
|
|
74
|
+
* wizard's mode prompt. Unset falls back to {@link DEFAULT_INSTALL_MODE}.
|
|
75
|
+
*/
|
|
76
|
+
orchestratorMode?: OrchestratorMode;
|
|
77
|
+
/**
|
|
78
|
+
* Whether the operator actually typed `--mode`, as opposed to Commander
|
|
79
|
+
* filling in {@link DEFAULT_INSTALL_MODE}.
|
|
80
|
+
*
|
|
81
|
+
* Only the env-file path needs the distinction. The file the operator hands
|
|
82
|
+
* in may already declare `KICI_MODE`, and the install bakes the service unit's
|
|
83
|
+
* entry point from that value — so a defaulted `hybrid` must never overwrite a
|
|
84
|
+
* joined cluster's `independent`, while a named `--mode` must.
|
|
85
|
+
*/
|
|
86
|
+
modeExplicit?: boolean;
|
|
55
87
|
}
|
|
56
|
-
/**
|
|
88
|
+
/**
|
|
89
|
+
* Materialise the env file for the resolved mode.
|
|
90
|
+
*
|
|
91
|
+
* Every write path ends at {@link ENV_FILE_MODE}: the file carries the secrets
|
|
92
|
+
* master key, so it must never be group- or world-readable. Each path that
|
|
93
|
+
* creates or replaces the file stages it through a sibling temporary at that
|
|
94
|
+
* mode, so the destination never exists more permissively even briefly. The
|
|
95
|
+
* trailing chmod tightens the one path that only appends — a file that was
|
|
96
|
+
* already there at looser permissions.
|
|
97
|
+
*/
|
|
57
98
|
export declare function writeInstallEnvFile(args: WriteInstallEnvArgs): Promise<WriteInstallEnvResult>;
|
|
58
99
|
//# sourceMappingURL=install-env.d.ts.map
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* and output format. Delegates to the platform-specific service
|
|
6
6
|
* manager's logs() method.
|
|
7
7
|
*
|
|
8
|
-
* Target resolution goes through
|
|
8
|
+
* Target resolution goes through resolveInstanceTarget — the same priority chain
|
|
9
9
|
* every lifecycle command uses (--instance-dir > --name > CWD manifest >
|
|
10
10
|
* refusal with candidate list).
|
|
11
11
|
*/
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* `kici-admin orchestrator restart` command.
|
|
3
3
|
*
|
|
4
4
|
* Restarts the orchestrator service. Target resolution goes through
|
|
5
|
-
*
|
|
5
|
+
* resolveInstanceTarget — the same priority chain every lifecycle command uses
|
|
6
6
|
* (--instance-dir > --name > CWD manifest > refusal with candidate list).
|
|
7
7
|
* `--name` has no default; every invocation must resolve via one of the
|
|
8
8
|
* above paths.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* `kici-admin orchestrator start` command.
|
|
3
3
|
*
|
|
4
4
|
* Starts the orchestrator service. Target resolution goes through
|
|
5
|
-
*
|
|
5
|
+
* resolveInstanceTarget — the same priority chain every lifecycle command uses
|
|
6
6
|
* (--instance-dir > --name > CWD manifest > refusal with candidate list).
|
|
7
7
|
* `--name` has no default; every invocation must resolve via one of the
|
|
8
8
|
* above paths.
|
|
@@ -5,10 +5,26 @@
|
|
|
5
5
|
* the running orchestrator's health API for KiCI-specific info
|
|
6
6
|
* (mode, DB connectivity, agents, jobs, scaler).
|
|
7
7
|
*
|
|
8
|
-
* Target resolution goes through
|
|
8
|
+
* Target resolution goes through resolveInstanceTarget — the same priority chain
|
|
9
9
|
* every lifecycle command uses (--instance-dir > --name > CWD manifest >
|
|
10
10
|
* refusal with candidate list).
|
|
11
11
|
*/
|
|
12
12
|
import type { Command } from 'commander';
|
|
13
|
+
import { type ServicePlatform } from '../../service/index.js';
|
|
14
|
+
/**
|
|
15
|
+
* The config files this install owns, for an operator who wants to inspect
|
|
16
|
+
* them. Derived from the instance manifest and the env file on disk, not from
|
|
17
|
+
* the running service, so it answers just as well for a stopped one.
|
|
18
|
+
*
|
|
19
|
+
* No path is checked for existence: on bare metal such a check would pass, but
|
|
20
|
+
* a compose install names host paths the check would have to run against a
|
|
21
|
+
* container, blanking the answer for the shape that needs it most.
|
|
22
|
+
*/
|
|
23
|
+
export declare function formatConfigPaths(args: {
|
|
24
|
+
platform: ServicePlatform;
|
|
25
|
+
serviceName: string;
|
|
26
|
+
envFilePath: string;
|
|
27
|
+
envContent: string;
|
|
28
|
+
}): string[];
|
|
13
29
|
export declare function registerStatusCommand(parent: Command): void;
|
|
14
30
|
//# sourceMappingURL=status.d.ts.map
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* `kici-admin orchestrator stop` command.
|
|
3
3
|
*
|
|
4
4
|
* Stops the orchestrator service. Target resolution goes through
|
|
5
|
-
*
|
|
5
|
+
* resolveInstanceTarget — the same priority chain every lifecycle command uses
|
|
6
6
|
* (--instance-dir > --name > CWD manifest > refusal with candidate list).
|
|
7
7
|
* `--name` has no default; every invocation must resolve via one of the
|
|
8
8
|
* above paths.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* `kici-admin orchestrator uninstall` command.
|
|
3
3
|
*
|
|
4
4
|
* Removes the orchestrator service registration. Target resolution goes
|
|
5
|
-
* through
|
|
5
|
+
* through resolveInstanceTarget — the same priority chain every lifecycle command
|
|
6
6
|
* uses (--instance-dir > --name > CWD manifest > refusal with candidate list).
|
|
7
7
|
* The manifest stays on disk so subsequent commands can still reference the
|
|
8
8
|
* deploy folder; the host-wide index entry is dropped unconditionally so a
|
|
@@ -17,5 +17,6 @@
|
|
|
17
17
|
* of the above paths.
|
|
18
18
|
*/
|
|
19
19
|
import type { Command } from 'commander';
|
|
20
|
-
|
|
20
|
+
import type { AdminApiClient } from '../../api-client.js';
|
|
21
|
+
export declare function registerUpgradeCommand(parent: Command, tryGetClient: () => AdminApiClient | null): void;
|
|
21
22
|
//# sourceMappingURL=upgrade.d.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Key rotation command for kici-admin.
|
|
3
3
|
*
|
|
4
|
-
* Re-encrypts
|
|
4
|
+
* Re-encrypts every master-key-wrapped store with the current master key.
|
|
5
5
|
*/
|
|
6
6
|
import type { Command } from 'commander';
|
|
7
7
|
import type { AdminApiClient } from '../api-client.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permissions for a service env file written by `kici-admin`.
|
|
3
|
+
*
|
|
4
|
+
* Both installers write a file that carries credentials — the orchestrator's
|
|
5
|
+
* holds KICI_SECRET_KEY, KICI_DATABASE_URL and KICI_PLATFORM_TOKEN, the
|
|
6
|
+
* agent's holds KICI_AGENT_TOKEN — so neither may be group- or
|
|
7
|
+
* world-readable. The same mode guards the temporary Postgres password file in
|
|
8
|
+
* `orchestrator-service/install.ts` and the peer credential file in
|
|
9
|
+
* `cluster/peer-credentials.ts`.
|
|
10
|
+
*
|
|
11
|
+
* The guarantee is POSIX-only. Node maps a mode onto Windows by toggling the
|
|
12
|
+
* read-only attribute and changes no ACL, so a Windows install must restrict
|
|
13
|
+
* the file itself.
|
|
14
|
+
*/
|
|
15
|
+
export declare const ENV_FILE_MODE = 384;
|
|
16
|
+
//# sourceMappingURL=env-file-mode.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { AdminApiClient } from '../../api-client.js';
|
|
2
|
+
import type { UpgradeHooks } from './versioned-upgrade.js';
|
|
3
|
+
/**
|
|
4
|
+
* Resolve the database URL the pre-upgrade dump connects with.
|
|
5
|
+
*
|
|
6
|
+
* The instance's env file is the authority — the same file the service itself
|
|
7
|
+
* is started from — so the dump is taken against exactly the database the
|
|
8
|
+
* running orchestrator uses, not whatever the operator's shell happens to
|
|
9
|
+
* export.
|
|
10
|
+
*/
|
|
11
|
+
export declare function readDatabaseUrlFromEnvFile(contents: string): string | null;
|
|
12
|
+
export interface BuildUpgradeHooksIo {
|
|
13
|
+
readFile: (p: string) => string;
|
|
14
|
+
now?: () => Date;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Build the hook set for an orchestrator upgrade.
|
|
18
|
+
*
|
|
19
|
+
* `instanceDir` is resolved lazily, at the moment a hook runs, because the
|
|
20
|
+
* upgrade resolves its target after the command is registered.
|
|
21
|
+
*/
|
|
22
|
+
export declare function buildUpgradeHooks(tryGetClient: () => AdminApiClient | null, io?: BuildUpgradeHooksIo): UpgradeHooks;
|
|
23
|
+
/**
|
|
24
|
+
* Read `KICI_DATABASE_URL` from the instance env file, falling back to the
|
|
25
|
+
* process environment.
|
|
26
|
+
*
|
|
27
|
+
* Throws rather than returning null: an upgrade that cannot find the database
|
|
28
|
+
* must refuse loudly, since a silent skip is exactly the failure this hook
|
|
29
|
+
* exists to prevent.
|
|
30
|
+
*/
|
|
31
|
+
export declare function resolveDatabaseUrl(envFilePath: string, readFile: (p: string) => string): string;
|
|
32
|
+
//# sourceMappingURL=upgrade-hooks.d.ts.map
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/** The drain snapshot both the CLI verb and this module poll. */
|
|
2
|
+
export interface DrainSnapshot {
|
|
3
|
+
draining: boolean;
|
|
4
|
+
jobsRunning: number;
|
|
5
|
+
}
|
|
6
|
+
export interface WaitOpts {
|
|
7
|
+
timeoutMs: number;
|
|
8
|
+
intervalMs: number;
|
|
9
|
+
now?: () => number;
|
|
10
|
+
sleep?: (ms: number) => Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Poll until no jobs are running, or the deadline passes.
|
|
14
|
+
*
|
|
15
|
+
* Extracted so the upgrade and `kici-admin orchestrator drain --wait` share one
|
|
16
|
+
* implementation rather than two that can disagree about what quiesced means.
|
|
17
|
+
*/
|
|
18
|
+
export declare function waitForQuiesce(poll: () => Promise<DrainSnapshot>, opts: WaitOpts): Promise<{
|
|
19
|
+
quiesced: boolean;
|
|
20
|
+
jobsRunning: number;
|
|
21
|
+
}>;
|
|
22
|
+
/** One entry of `GET /api/v1/admin/db/migrate/status`. */
|
|
23
|
+
export interface MigrationStatusRow {
|
|
24
|
+
name: string;
|
|
25
|
+
status: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The last applied migration reported by a running service.
|
|
29
|
+
*
|
|
30
|
+
* Returns null when nothing has been applied — a fresh database — which the
|
|
31
|
+
* caller must not confuse with "could not read it".
|
|
32
|
+
*/
|
|
33
|
+
export declare function appliedHead(rows: readonly MigrationStatusRow[]): string | null;
|
|
34
|
+
/** Migrations applied after `head`, in ledger order. */
|
|
35
|
+
export declare function migrationsAfter(rows: readonly MigrationStatusRow[], head: string): string[];
|
|
36
|
+
export type SchemaGuardVerdict = {
|
|
37
|
+
kind: 'ok';
|
|
38
|
+
} | {
|
|
39
|
+
kind: 'unknown-head';
|
|
40
|
+
message: string;
|
|
41
|
+
} | {
|
|
42
|
+
kind: 'ahead';
|
|
43
|
+
extra: string[];
|
|
44
|
+
message: string;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Decide whether the version pointer may move.
|
|
48
|
+
*
|
|
49
|
+
* Three outcomes, and the middle one is the compatibility shim: an instance
|
|
50
|
+
* installed before `migrationHeads` existed has no recorded head, and refusing
|
|
51
|
+
* there would break the documented `--rollback` on exactly the installs that
|
|
52
|
+
* predate the guard. So an unknown head warns loudly and falls through to the
|
|
53
|
+
* existing confirmation prompt; the map is populated at the next version
|
|
54
|
+
* change, arming the guard one upgrade later.
|
|
55
|
+
*/
|
|
56
|
+
export declare function schemaGuardVerdict(input: {
|
|
57
|
+
targetVersion: string;
|
|
58
|
+
recordedHead: string | null | undefined;
|
|
59
|
+
liveRows: readonly MigrationStatusRow[];
|
|
60
|
+
}): SchemaGuardVerdict;
|
|
61
|
+
/** Merge one version's head into the manifest map, never replacing it. */
|
|
62
|
+
export declare function mergeMigrationHead(existing: Record<string, string> | undefined, version: string, head: string | null): Record<string, string> | undefined;
|
|
63
|
+
/** Read the live applied head, returning null when the service cannot answer. */
|
|
64
|
+
export declare function readLiveMigrationRows(fetchStatus: () => Promise<{
|
|
65
|
+
migrations: MigrationStatusRow[];
|
|
66
|
+
}>): Promise<MigrationStatusRow[] | null>;
|
|
67
|
+
/** Format the reason a pre-upgrade backup could not be taken. */
|
|
68
|
+
export declare function backupRefusalMessage(reason: string): string;
|
|
69
|
+
/**
|
|
70
|
+
* Format the drain-timeout refusal.
|
|
71
|
+
*
|
|
72
|
+
* The refusal leaves the coordinator draining — deliberately, so the in-flight
|
|
73
|
+
* jobs finish without new ones piling up behind them. But a drained
|
|
74
|
+
* coordinator accepts nothing, so the message has to say so and name the way
|
|
75
|
+
* back; an operator who reads only "wait and re-run" does not know their CI is
|
|
76
|
+
* stalled meanwhile.
|
|
77
|
+
*/
|
|
78
|
+
export declare function drainTimeoutMessage(jobsRunning: number, timeoutSeconds: number): string;
|
|
79
|
+
/** Describe a failure to reach the admin API during the pre-stop phase. */
|
|
80
|
+
export declare function adminApiUnavailable(action: string, err: unknown): string;
|
|
81
|
+
//# sourceMappingURL=upgrade-safety.d.ts.map
|
|
@@ -9,13 +9,14 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { type NpmInstallTarget, type ResolvedInstance, type ServiceManager, type ServicePlatform } from '../../service/index.js';
|
|
11
11
|
import type { LaunchSpec, ServiceConfig } from '../../service/types.js';
|
|
12
|
+
import { type MigrationStatusRow } from './upgrade-safety.js';
|
|
12
13
|
/** Component types that can be upgraded. */
|
|
13
14
|
type UpgradeComponent = 'orchestrator' | 'agent';
|
|
14
15
|
/** Options for the versioned upgrade command. */
|
|
15
16
|
interface VersionedUpgradeOptions {
|
|
16
17
|
platform?: ServicePlatform;
|
|
17
18
|
/**
|
|
18
|
-
* Service name. No default — targeting flows through {@link
|
|
19
|
+
* Service name. No default — targeting flows through {@link resolveInstanceTarget}
|
|
19
20
|
* which consumes `name`, `instanceDir`, or the CWD manifest in priority order.
|
|
20
21
|
*/
|
|
21
22
|
name?: string;
|
|
@@ -34,6 +35,50 @@ interface VersionedUpgradeOptions {
|
|
|
34
35
|
* self-driving the npm install (the pre-staged / air-gapped path).
|
|
35
36
|
*/
|
|
36
37
|
restartOnly?: boolean;
|
|
38
|
+
/** Skip the pre-upgrade dump. Loud: printed as a banner and echoed at the end. */
|
|
39
|
+
skipBackup?: boolean;
|
|
40
|
+
/** Where the pre-upgrade dump goes. Defaults to `<instanceDir>/backups`. */
|
|
41
|
+
backupDir?: string;
|
|
42
|
+
/** Skip quiescing the coordinator before the restart. */
|
|
43
|
+
noDrain?: boolean;
|
|
44
|
+
/** Seconds to wait for in-flight jobs to finish. Default 300. */
|
|
45
|
+
drainTimeout?: string;
|
|
46
|
+
/**
|
|
47
|
+
* On a rollback whose database is ahead of the target, revert the schema to
|
|
48
|
+
* the target's recorded head first, through the still-running newer service.
|
|
49
|
+
*/
|
|
50
|
+
migrateDown?: boolean;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The orchestrator-only pre-stop steps, injected so the agent upgrade can pass
|
|
54
|
+
* none and stay unchanged, and so each is testable without a live service.
|
|
55
|
+
*/
|
|
56
|
+
export interface UpgradeHooks {
|
|
57
|
+
/** Read the live migration ledger from the running service. */
|
|
58
|
+
migrationStatus?: () => Promise<{
|
|
59
|
+
migrations: MigrationStatusRow[];
|
|
60
|
+
}>;
|
|
61
|
+
/** Put the coordinator into drain and poll until quiesced. */
|
|
62
|
+
drain?: (timeoutSeconds: number) => Promise<{
|
|
63
|
+
quiesced: boolean;
|
|
64
|
+
jobsRunning: number;
|
|
65
|
+
}>;
|
|
66
|
+
/** Revert the schema to `head` through the running service. */
|
|
67
|
+
migrateDown?: (head: string) => Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Take the pre-upgrade dump, returning where it landed.
|
|
70
|
+
*
|
|
71
|
+
* `envFilePath` comes from the instance manifest, so the dump is taken
|
|
72
|
+
* against exactly the database the running service uses rather than whatever
|
|
73
|
+
* the operator's shell exports.
|
|
74
|
+
*/
|
|
75
|
+
backup?: (args: {
|
|
76
|
+
outputPath: string;
|
|
77
|
+
envFilePath: string;
|
|
78
|
+
}) => Promise<{
|
|
79
|
+
outputPath: string;
|
|
80
|
+
byteSize: number;
|
|
81
|
+
}>;
|
|
37
82
|
}
|
|
38
83
|
/**
|
|
39
84
|
* Resolved upgrade target: the manifest-backed ServiceConfig the upgrade
|
|
@@ -44,12 +89,21 @@ export interface UpgradeTarget {
|
|
|
44
89
|
config: ServiceConfig;
|
|
45
90
|
installBase: string;
|
|
46
91
|
resolvedInstance: ResolvedInstance;
|
|
92
|
+
/** The driver that manages this install — built for {@link UpgradeTarget.platform}. */
|
|
93
|
+
manager: ServiceManager;
|
|
94
|
+
/**
|
|
95
|
+
* The install's own platform: `platformOverride ?? manifest.platform`. Every
|
|
96
|
+
* downstream question the upgrade asks — the root check, the launcher name,
|
|
97
|
+
* whether the current version reads a symlink or a version file — is about
|
|
98
|
+
* the layout on disk, so it is answered from the install, not the host.
|
|
99
|
+
*/
|
|
100
|
+
platform: ServicePlatform;
|
|
47
101
|
}
|
|
48
102
|
/**
|
|
49
103
|
* Resolve the upgrade target via the folder-anchored model and build the
|
|
50
104
|
* ServiceConfig + installBase the rest of the upgrade flow needs.
|
|
51
105
|
*
|
|
52
|
-
* Priority chain (delegated to {@link
|
|
106
|
+
* Priority chain (delegated to {@link resolveInstanceTarget}):
|
|
53
107
|
* 1. `opts.instanceDir` — read manifest at that path.
|
|
54
108
|
* 2. `opts.name` — match against listInstances() output.
|
|
55
109
|
* 3. CWD manifest — read `./.kici-<component>.json`.
|
|
@@ -65,9 +119,12 @@ export declare function resolveUpgradeTarget(args: {
|
|
|
65
119
|
instanceDir?: string;
|
|
66
120
|
name?: string;
|
|
67
121
|
};
|
|
68
|
-
|
|
122
|
+
/** The `--platform` flag. When set it forces the driver, as it always has. */
|
|
123
|
+
platformOverride?: ServicePlatform;
|
|
69
124
|
isUserLevel: boolean;
|
|
70
125
|
kiciRoot: string;
|
|
126
|
+
/** Driver factory. Defaults to the service barrel's createServiceManager. */
|
|
127
|
+
createManager?: (platform: ServicePlatform) => Promise<ServiceManager>;
|
|
71
128
|
}): Promise<UpgradeTarget>;
|
|
72
129
|
/**
|
|
73
130
|
* Install base for a KiCI component instance.
|
|
@@ -220,15 +277,7 @@ export declare function installGlobalPackage(target: NpmInstallTarget, version:
|
|
|
220
277
|
ok: boolean;
|
|
221
278
|
stderr: string;
|
|
222
279
|
};
|
|
223
|
-
export declare function performVersionedUpgrade(component: UpgradeComponent, opts: VersionedUpgradeOptions): Promise<void>;
|
|
224
|
-
/**
|
|
225
|
-
* Stop the service, switch the active version pointer to an already-installed
|
|
226
|
-
* versioned directory (atomic symlink on Unix; uninstall→install + version file
|
|
227
|
-
* on Windows), restart, and persist the new `kiciVersion` into the manifest.
|
|
228
|
-
*
|
|
229
|
-
* Shared by `--rollback` (switch to the previous version) and `--pick` (switch
|
|
230
|
-
* to any chosen installed version).
|
|
231
|
-
*/
|
|
280
|
+
export declare function performVersionedUpgrade(component: UpgradeComponent, opts: VersionedUpgradeOptions, hooks?: UpgradeHooks): Promise<void>;
|
|
232
281
|
export declare function switchToInstalledVersion(args: {
|
|
233
282
|
component: UpgradeComponent;
|
|
234
283
|
platform: ServicePlatform;
|
|
@@ -237,6 +286,12 @@ export declare function switchToInstalledVersion(args: {
|
|
|
237
286
|
manager: ServiceManager;
|
|
238
287
|
resolvedInstance: ResolvedInstance;
|
|
239
288
|
targetVersion: string;
|
|
289
|
+
/** Orchestrator-only pre-stop capabilities. Omitted by the agent upgrade. */
|
|
290
|
+
hooks?: UpgradeHooks;
|
|
291
|
+
/** Revert the schema to the target's recorded head before switching. */
|
|
292
|
+
migrateDown?: boolean;
|
|
293
|
+
/** Skip the confirmation the unknown-head warning falls through to. */
|
|
294
|
+
yes?: boolean;
|
|
240
295
|
}): Promise<void>;
|
|
241
296
|
export {};
|
|
242
297
|
//# sourceMappingURL=versioned-upgrade.d.ts.map
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* source update <routingKey> Update a GitHub source
|
|
10
10
|
* source update-generic <id> Update a generic source
|
|
11
11
|
* source remove <routingKey> Remove a source (GitHub or generic with --generic flag)
|
|
12
|
+
* source redeliver <routingKey> Replay a window of GitHub webhook deliveries
|
|
12
13
|
* source enable <id> Enable a generic source
|
|
13
14
|
* source disable <id> Disable a generic source
|
|
14
15
|
*
|
|
@@ -15,5 +15,9 @@ import type { AdminApiClient } from '../api-client.js';
|
|
|
15
15
|
* other input so a typo never silently creates a non-expiring token.
|
|
16
16
|
*/
|
|
17
17
|
export declare function parseExpiresAt(input: string, now?: Date): Date;
|
|
18
|
+
/**
|
|
19
|
+
* Format tokens as a table.
|
|
20
|
+
*/
|
|
21
|
+
export declare function formatTokenTable(tokens: any[]): string;
|
|
18
22
|
export declare function registerTokenCommands(program: Command, getClient: () => AdminApiClient): void;
|
|
19
23
|
//# sourceMappingURL=token.d.ts.map
|