@kici-dev/agent 0.1.27 → 0.3.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/bootstrap/ensure-init-runner.d.ts +23 -22
- package/dist/bootstrap/payload-source.d.ts +32 -0
- package/dist/bootstrap/probe-platform.d.ts +21 -0
- package/dist/bootstrap/restage-agent.d.ts +43 -0
- package/dist/bootstrap/run-restage.d.ts +12 -0
- package/dist/bootstrap/s3-payload-source.d.ts +35 -0
- package/dist/bootstrap/ssh-exec.d.ts +14 -0
- package/dist/bootstrap/stage-agent-payload.d.ts +41 -0
- package/dist/checkout/changed-files.d.ts +34 -0
- package/dist/config.d.ts +36 -14
- package/dist/container-ts-loader-hook.js +147710 -0
- package/dist/execution/artifacts/artifact-engine.d.ts +51 -0
- package/dist/execution/dep-installer.d.ts +3 -3
- package/dist/execution/job-runner.d.ts +24 -6
- package/dist/execution/log-streamer.d.ts +17 -2
- package/dist/execution/rule-evaluator.d.ts +1 -12
- package/dist/execution/sandbox/container-hardening.d.ts +80 -0
- package/dist/execution/sandbox/container-sandbox.d.ts +54 -0
- package/dist/execution/sandbox/container-ts-loader-hook.d.ts +26 -0
- package/dist/execution/sandbox/fork-runner.d.ts +14 -0
- package/dist/execution/sandbox/index.d.ts +2 -1
- package/dist/execution/sandbox/ipc-protocol.d.ts +79 -3
- package/dist/execution/sandbox/step-loop.d.ts +4 -0
- package/dist/execution/sandbox/types.d.ts +25 -4
- package/dist/execution/sandbox/workflow-runner.d.ts +111 -5
- package/dist/execution/streaming-zx-log.d.ts +11 -3
- package/dist/execution/tmp-gc.d.ts +22 -7
- package/dist/execution/workflow-loader.d.ts +32 -1
- package/dist/index.js +44 -45
- package/dist/provenance/statement-builder.d.ts +3 -2
- package/dist/server.d.ts +1 -1
- package/dist/server.js +1256 -171
- package/dist/workflow-runner-bundle.js +215403 -0
- package/dist/workflow-runner.js +886 -244
- package/dist/ws/orchestrator-client.d.ts +105 -1
- package/package.json +14 -12
- package/sbom.spdx.json +1090 -1721
|
@@ -1,32 +1,33 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent-side init-runner bring-up.
|
|
3
|
-
*
|
|
4
|
-
* Runs in the AGENT process (never the workflow sandbox), so the bring-up SSH
|
|
5
|
-
* key and bootstrap token the orchestrator hands back never reach user
|
|
6
|
-
* workflow code. The flow:
|
|
7
|
-
*
|
|
8
|
-
* 1. Call the orchestrator's privileged `kici.ensureInitRunner` handler — it
|
|
9
|
-
* gates on this agent's `kici:capability:ssh-transport` capability,
|
|
10
|
-
* resolves the target's reach + SSH key, mints a single-use bootstrap
|
|
11
|
-
* token, audits, and returns the material (or `{ broughtUp: false }` when
|
|
12
|
-
* the target already has a live agent).
|
|
13
|
-
* 2. Over SSH (ephemeral key, never on disk): drop a launcher onto the target
|
|
14
|
-
* that starts `kici-agent` with the bootstrap env (token + agent id +
|
|
15
|
-
* orchestrator URL + labels), and start it detached.
|
|
16
|
-
*
|
|
17
|
-
* The init-runner then connects → `auth.request` (bootstrap token) →
|
|
18
|
-
* `agent.register` auto-enroll as a temporary `kici:init` agent.
|
|
19
|
-
*/
|
|
20
1
|
import { type SshDeps } from './ssh-exec.js';
|
|
2
|
+
import { type DeliveryMode } from './stage-agent-payload.js';
|
|
3
|
+
import type { AgentPayloadSource } from './payload-source.js';
|
|
21
4
|
/** Transport that relays an API request to the orchestrator and awaits the result. */
|
|
22
5
|
export type ApiTransport = (method: string, params: Record<string, unknown>) => Promise<unknown>;
|
|
23
6
|
export interface EnsureInitRunnerDeps extends SshDeps {
|
|
24
7
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
8
|
+
* A fixed command used to start the init-runner on the target — the
|
|
9
|
+
* golden-image escape hatch. When set, payload staging is SKIPPED (the image
|
|
10
|
+
* already ships `kici-agent` + a Node runtime at this path). Leave unset for a
|
|
11
|
+
* stock rescue box: the payload source below is staged instead.
|
|
28
12
|
*/
|
|
29
13
|
agentCommand?: string;
|
|
14
|
+
/**
|
|
15
|
+
* The source of the self-contained agent+Node payload staged onto a bare box.
|
|
16
|
+
* When set (and no `agentCommand` override), `ensureInitRunner` probes the
|
|
17
|
+
* target platform, stages the version-keyed payload, and boots it on its
|
|
18
|
+
* vendored Node. Constructed from `KICI_AGENT_PAYLOAD_DIR` at the agent entry.
|
|
19
|
+
*/
|
|
20
|
+
payloadSource?: AgentPayloadSource;
|
|
21
|
+
/**
|
|
22
|
+
* Force the delivery mode, overriding the orchestrator's per-host choice.
|
|
23
|
+
* Normally the orchestrator picks the mode (from the host's `s3_reachable`
|
|
24
|
+
* hint) and returns it in the bring-up material; this is a test/escape hatch.
|
|
25
|
+
*/
|
|
26
|
+
delivery?: DeliveryMode;
|
|
27
|
+
/** Override the on-box extract dir (default `/opt/kici-init`). */
|
|
28
|
+
extractDir?: string;
|
|
29
|
+
/** Ops-agent-side file-hash boundary, injectable for tests. */
|
|
30
|
+
hashLocalFile?: (filePath: string) => Promise<string>;
|
|
30
31
|
}
|
|
31
32
|
/**
|
|
32
33
|
* Bring up a temporary init-runner on `targetAgentId`. Returns `{ broughtUp }`:
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { AgentPlatform } from '@kici-dev/shared';
|
|
2
|
+
/** A staged payload ready to deliver: a local tarball path + its expected hash. */
|
|
3
|
+
export interface StagedPayload {
|
|
4
|
+
tarballPath: string;
|
|
5
|
+
/** The expected sha256 (hex), or `null` when the producer wrote no sidecar. */
|
|
6
|
+
sha256: string | null;
|
|
7
|
+
}
|
|
8
|
+
/** Resolves the payload tarball for a given platform + version. */
|
|
9
|
+
export interface AgentPayloadSource {
|
|
10
|
+
resolve(platform: AgentPlatform, version: string): Promise<StagedPayload>;
|
|
11
|
+
}
|
|
12
|
+
/** Filesystem boundary — injectable so unit tests need no real files. */
|
|
13
|
+
export interface PayloadFs {
|
|
14
|
+
exists(filePath: string): Promise<boolean>;
|
|
15
|
+
readFile(filePath: string): Promise<string>;
|
|
16
|
+
}
|
|
17
|
+
/** Default fs boundary backed by `node:fs/promises`. */
|
|
18
|
+
export declare const defaultPayloadFs: PayloadFs;
|
|
19
|
+
/**
|
|
20
|
+
* Reads version-keyed payloads from a local directory:
|
|
21
|
+
* `<baseDir>/<version>/kici-agent-<platform>.tar.gz` with an optional
|
|
22
|
+
* `.sha256` sidecar (the producer writes a `<hex> <basename>` line — we parse
|
|
23
|
+
* the leading hex token). Selected via `KICI_AGENT_PAYLOAD_DIR`; the air-gap /
|
|
24
|
+
* offline fallback when no object-storage source is configured.
|
|
25
|
+
*/
|
|
26
|
+
export declare class LocalDirPayloadSource implements AgentPayloadSource {
|
|
27
|
+
private readonly baseDir;
|
|
28
|
+
private readonly fs;
|
|
29
|
+
constructor(baseDir: string, fs?: PayloadFs);
|
|
30
|
+
resolve(platform: AgentPlatform, version: string): Promise<StagedPayload>;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=payload-source.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Probe a bring-up target's platform over SSH.
|
|
3
|
+
*
|
|
4
|
+
* A stock rescue box has nothing but sshd — no `kici-agent`, no Node — so we
|
|
5
|
+
* cannot ask the box what to run; we must ask what it IS, then stage the
|
|
6
|
+
* matching self-contained payload. One `uname -s -m` (+ a libc check) maps to
|
|
7
|
+
* an `AgentPlatform`; an unsupported target (musl-only, non-Linux, unknown
|
|
8
|
+
* arch) throws early, naming what was detected, rather than staging bytes that
|
|
9
|
+
* won't boot.
|
|
10
|
+
*/
|
|
11
|
+
import { AgentPlatform } from '@kici-dev/shared';
|
|
12
|
+
import { type SshDeps } from './ssh-exec.js';
|
|
13
|
+
import type { HostReach } from './reach.js';
|
|
14
|
+
/**
|
|
15
|
+
* Map `uname -s -m` (+ libc line) output to an `AgentPlatform`. Pure + directly
|
|
16
|
+
* unit-tested. Throws a self-describing error for any unsupported target.
|
|
17
|
+
*/
|
|
18
|
+
export declare function parseUname(stdout: string): AgentPlatform;
|
|
19
|
+
/** SSH into `reach` and detect its `AgentPlatform` (one probe, fail-fast on unsupported). */
|
|
20
|
+
export declare function probeTargetPlatform(reach: HostReach, privateKey: string, deps?: SshDeps): Promise<AgentPlatform>;
|
|
21
|
+
//# sourceMappingURL=probe-platform.d.ts.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { AgentPlatform } from '@kici-dev/shared';
|
|
2
|
+
import { type SshDeps } from './ssh-exec.js';
|
|
3
|
+
import type { HostReach } from './reach.js';
|
|
4
|
+
import { type DeliveryMode } from './stage-agent-payload.js';
|
|
5
|
+
import type { AgentPayloadSource } from './payload-source.js';
|
|
6
|
+
/**
|
|
7
|
+
* How to drain + restart the target's agent after the swap. The ops agent runs
|
|
8
|
+
* `stop` (a graceful drain — SIGTERM + grace) then `start`. For a systemd unit
|
|
9
|
+
* this is `systemctl --user restart <svc>`; for a bare-process fixture it is a
|
|
10
|
+
* kill + relaunch of the install's own launcher (the box's persistent token
|
|
11
|
+
* lives in its env, so no reconnect material is threaded here).
|
|
12
|
+
*/
|
|
13
|
+
export interface RestartSpec {
|
|
14
|
+
stop: string;
|
|
15
|
+
start: string;
|
|
16
|
+
}
|
|
17
|
+
export interface RestageOpts {
|
|
18
|
+
/** Target platform; probed over SSH when omitted. */
|
|
19
|
+
platform?: AgentPlatform;
|
|
20
|
+
/** Target version to converge the host onto (the orchestrator's version). */
|
|
21
|
+
version: string;
|
|
22
|
+
/** How the payload reaches the box (ssh-push | s3-direct). */
|
|
23
|
+
delivery: DeliveryMode;
|
|
24
|
+
/** Folder-anchored install base (default `/opt/kici-agent`). */
|
|
25
|
+
installDir?: string;
|
|
26
|
+
/** Drain + restart commands run after the atomic swap. */
|
|
27
|
+
restart: RestartSpec;
|
|
28
|
+
}
|
|
29
|
+
export interface RestageDeps extends SshDeps {
|
|
30
|
+
/** Payload source for the `ssh-push` delivery path (unused for `s3-direct`). */
|
|
31
|
+
payloadSource?: AgentPayloadSource;
|
|
32
|
+
/** Ops-agent-side file-hash boundary, injectable for tests. */
|
|
33
|
+
hashLocalFile?: (filePath: string) => Promise<string>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Re-stage the target version onto `reach` and restart its agent. Returns
|
|
37
|
+
* `{ restaged: false }` when the host is already on the target version (no
|
|
38
|
+
* stage, no swap, no restart), `{ restaged: true }` when this call swapped it.
|
|
39
|
+
*/
|
|
40
|
+
export declare function restageAgent(reach: HostReach, privateKey: string, opts: RestageOpts, deps: RestageDeps): Promise<{
|
|
41
|
+
restaged: boolean;
|
|
42
|
+
}>;
|
|
43
|
+
//# sourceMappingURL=restage-agent.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type RestageDeps } from './restage-agent.js';
|
|
2
|
+
/** Transport that relays an API request to the orchestrator and awaits the result. */
|
|
3
|
+
export type ApiTransport = (method: string, params: Record<string, unknown>) => Promise<unknown>;
|
|
4
|
+
/**
|
|
5
|
+
* Drive one external-actor re-stage: fetch the material, probe the target
|
|
6
|
+
* platform, resolve delivery, then stage + swap + restart via {@link restageAgent}.
|
|
7
|
+
* Returns `{ restaged: false }` when the host is already on the target version.
|
|
8
|
+
*/
|
|
9
|
+
export declare function runRestage(transport: ApiTransport, targetAgentId: string, deps: RestageDeps): Promise<{
|
|
10
|
+
restaged: boolean;
|
|
11
|
+
}>;
|
|
12
|
+
//# sourceMappingURL=run-restage.d.ts.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type AgentPlatform } from '@kici-dev/shared';
|
|
2
|
+
import type { AgentPayloadSource, StagedPayload } from './payload-source.js';
|
|
3
|
+
/** What the orchestrator returns for a presign request. */
|
|
4
|
+
export interface PresignedPayload {
|
|
5
|
+
url: string;
|
|
6
|
+
/** The expected sha256 (hex), or null when the producer wrote no sidecar. */
|
|
7
|
+
sha256: string | null;
|
|
8
|
+
}
|
|
9
|
+
export interface S3PayloadSourceDeps {
|
|
10
|
+
/**
|
|
11
|
+
* Ask the orchestrator to mint a presigned download URL for the version-keyed
|
|
12
|
+
* payload. Bound to the `kici.presignAgentPackage` RPC over the agent-WS
|
|
13
|
+
* channel; the orchestrator keys the presign by its own version + the probed
|
|
14
|
+
* platform. Returns null when no payload object exists for the version.
|
|
15
|
+
*/
|
|
16
|
+
presign(platform: AgentPlatform, version: string): Promise<PresignedPayload | null>;
|
|
17
|
+
/** Stream a URL to a local file (binary-safe). Injectable for tests. */
|
|
18
|
+
fetchToFile(url: string, dest: string): Promise<void>;
|
|
19
|
+
/** Local cache root; payloads land under `<cacheDir>/<version>/…` (cache-once). */
|
|
20
|
+
cacheDir: string;
|
|
21
|
+
/** Filesystem existence check for the cache-once short-circuit. Injectable. */
|
|
22
|
+
exists?(filePath: string): Promise<boolean>;
|
|
23
|
+
}
|
|
24
|
+
export declare class S3PayloadSource implements AgentPayloadSource {
|
|
25
|
+
private readonly deps;
|
|
26
|
+
constructor(deps: S3PayloadSourceDeps);
|
|
27
|
+
resolve(platform: AgentPlatform, version: string): Promise<StagedPayload>;
|
|
28
|
+
}
|
|
29
|
+
/** Default cache root the ops agent stores pulled payloads under (cache-once). */
|
|
30
|
+
export declare function defaultPayloadCacheDir(): string;
|
|
31
|
+
/** Default existence check for the cache-once short-circuit. */
|
|
32
|
+
export declare function payloadFileExists(filePath: string): Promise<boolean>;
|
|
33
|
+
/** Stream a (presigned) URL into a local file, binary-safe (no in-memory buffer). */
|
|
34
|
+
export declare function fetchUrlToFile(url: string, dest: string): Promise<void>;
|
|
35
|
+
//# sourceMappingURL=s3-payload-source.d.ts.map
|
|
@@ -55,4 +55,18 @@ export declare function sshPush(reach: HostReach, privateKey: string, localBytes
|
|
|
55
55
|
port?: number;
|
|
56
56
|
hostKeyMode?: SshHostKeyMode;
|
|
57
57
|
}, deps?: SshDeps): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* Ship a local FILE to a remote path over `scp` (a binary channel), using the
|
|
60
|
+
* same ephemeral-key discipline as `sshExec`/`sshPush`.
|
|
61
|
+
*
|
|
62
|
+
* Unlike `sshPush` — which pipes a JS string through `ssh 'cat > path'` and so
|
|
63
|
+
* corrupts binary payloads (a ~50 MB tarball) — `scp` streams the file's raw
|
|
64
|
+
* bytes untouched. This is the ONLY sanctioned path for a binary payload
|
|
65
|
+
* transfer; the string `cat >` path is for text (launcher scripts) only. Throws
|
|
66
|
+
* on a non-zero exit (a payload push must succeed end-to-end).
|
|
67
|
+
*/
|
|
68
|
+
export declare function sshPushFile(reach: HostReach, privateKey: string, localFilePath: string, remotePath: string, opts?: {
|
|
69
|
+
port?: number;
|
|
70
|
+
hostKeyMode?: SshHostKeyMode;
|
|
71
|
+
}, deps?: SshDeps): Promise<void>;
|
|
58
72
|
//# sourceMappingURL=ssh-exec.d.ts.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { AgentPlatform } from '@kici-dev/shared';
|
|
2
|
+
import { type SshDeps } from './ssh-exec.js';
|
|
3
|
+
import type { HostReach } from './reach.js';
|
|
4
|
+
import type { AgentPayloadSource } from './payload-source.js';
|
|
5
|
+
/**
|
|
6
|
+
* How the payload reaches the box. `s3-direct` carries the box-pullable
|
|
7
|
+
* presigned URL + the expected sha256 the box verifies before extract (so the
|
|
8
|
+
* payload never transits the ops agent).
|
|
9
|
+
*/
|
|
10
|
+
export type DeliveryMode = {
|
|
11
|
+
mode: 'ssh-push';
|
|
12
|
+
} | {
|
|
13
|
+
mode: 's3-direct';
|
|
14
|
+
presignedUrl: string;
|
|
15
|
+
sha256: string;
|
|
16
|
+
};
|
|
17
|
+
export interface StageDeps extends SshDeps {
|
|
18
|
+
/**
|
|
19
|
+
* Where payload tarballs come from for the `ssh-push` path (object storage via
|
|
20
|
+
* `S3PayloadSource`, or a local dir for air-gap). Not needed for `s3-direct`
|
|
21
|
+
* (the box pulls the presigned URL itself).
|
|
22
|
+
*/
|
|
23
|
+
payloadSource?: AgentPayloadSource;
|
|
24
|
+
/** Where the payload is extracted on the box (default `/opt/kici-init`). */
|
|
25
|
+
extractDir?: string;
|
|
26
|
+
/** Ops-agent-side file-hash boundary, injectable for tests. Defaults to a streamed sha256. */
|
|
27
|
+
hashLocalFile?: (filePath: string) => Promise<string>;
|
|
28
|
+
}
|
|
29
|
+
export interface StageOpts {
|
|
30
|
+
platform: AgentPlatform;
|
|
31
|
+
version: string;
|
|
32
|
+
delivery: DeliveryMode;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Stage a payload onto `reach` and return the launcher path the caller runs as
|
|
36
|
+
* the init-runner's `agentCommand`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function stageAgentPayload(reach: HostReach, privateKey: string, opts: StageOpts, deps: StageDeps): Promise<{
|
|
39
|
+
launcherPath: string;
|
|
40
|
+
}>;
|
|
41
|
+
//# sourceMappingURL=stage-agent-payload.d.ts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { EventPayload } from '@kici-dev/sdk';
|
|
2
|
+
import type { ChangedFilesStatus } from '@kici-dev/engine';
|
|
3
|
+
import type { GitAuth } from './git-clone.js';
|
|
4
|
+
/** Result of computing the changed-files list from the local clone. */
|
|
5
|
+
export interface ChangedFilesResult {
|
|
6
|
+
files: string[];
|
|
7
|
+
status: ChangedFilesStatus;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Authentication context threaded into every git invocation so the deepen /
|
|
11
|
+
* fetch calls that reach the remote are authenticated the same way the clone
|
|
12
|
+
* was. The clone's own credentials are ephemeral (git-clone.ts wipes the SSH
|
|
13
|
+
* key and never persists the token into `.git/config`), so a fetch here would
|
|
14
|
+
* otherwise run unauthenticated and fail on a private remote.
|
|
15
|
+
*/
|
|
16
|
+
export interface GitAuthCtx {
|
|
17
|
+
/** Per-command `-c` flags (http.extraHeader for basic auth). */
|
|
18
|
+
args: string[];
|
|
19
|
+
/** Env overrides (GIT_SSH_COMMAND for ssh auth). */
|
|
20
|
+
env?: Record<string, string>;
|
|
21
|
+
/** Tears down any temp SSH key material. */
|
|
22
|
+
cleanup?: () => Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
/** Build the auth context for the fetches, mirroring git-clone.ts's auth. */
|
|
25
|
+
export declare function buildAuthCtx(auth: GitAuth | undefined): Promise<GitAuthCtx>;
|
|
26
|
+
/**
|
|
27
|
+
* Compute the changed-files list from the agent's local clone (HEAD is the
|
|
28
|
+
* checked-out head commit). Ground truth for job/step rule evaluation. `auth`
|
|
29
|
+
* (the same credentials used for the clone) authenticates the deepen / fetch
|
|
30
|
+
* calls so a private remote resolves. Returns `unavailable` for diff-less
|
|
31
|
+
* events (schedule/tag/manual) or any git failure — never throws.
|
|
32
|
+
*/
|
|
33
|
+
export declare function computeChangedFiles(workDir: string, event: EventPayload, auth?: GitAuth): Promise<ChangedFilesResult>;
|
|
34
|
+
//# sourceMappingURL=changed-files.d.ts.map
|
package/dist/config.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
/** Execution mode for the agent's sandbox backend. Mirrors the runtime enum. */
|
|
3
3
|
export declare const ExecutionMode: z.ZodEnum<{
|
|
4
|
-
container: "container";
|
|
5
4
|
"bare-metal": "bare-metal";
|
|
5
|
+
container: "container";
|
|
6
6
|
firecracker: "firecracker";
|
|
7
7
|
}>;
|
|
8
8
|
export type ExecutionMode = z.infer<typeof ExecutionMode>;
|
|
@@ -14,8 +14,8 @@ declare const configSchema: z.ZodObject<{
|
|
|
14
14
|
roles: z.ZodPipe<z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<string[] | undefined, string | undefined>>, z.ZodTransform<string[] | undefined, string[] | undefined>>;
|
|
15
15
|
port: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
16
16
|
logLevel: z.ZodDefault<z.ZodEnum<{
|
|
17
|
-
error: "error";
|
|
18
17
|
debug: "debug";
|
|
18
|
+
error: "error";
|
|
19
19
|
info: "info";
|
|
20
20
|
warn: "warn";
|
|
21
21
|
}>>;
|
|
@@ -26,22 +26,30 @@ declare const configSchema: z.ZodObject<{
|
|
|
26
26
|
dockerKeepFailed: z.ZodPipe<z.ZodDefault<z.ZodString>, z.ZodTransform<boolean, string>>;
|
|
27
27
|
jobHeartbeatIntervalMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
28
28
|
backpressureMode: z.ZodDefault<z.ZodEnum<{
|
|
29
|
-
pause: "pause";
|
|
30
29
|
drop: "drop";
|
|
30
|
+
pause: "pause";
|
|
31
31
|
}>>;
|
|
32
|
+
agentPayloadDir: z.ZodOptional<z.ZodString>;
|
|
33
|
+
agentCommand: z.ZodOptional<z.ZodString>;
|
|
32
34
|
sandbox: z.ZodPipe<z.ZodDefault<z.ZodString>, z.ZodTransform<boolean, string>>;
|
|
33
35
|
trustedEnv: z.ZodPipe<z.ZodDefault<z.ZodString>, z.ZodTransform<boolean, string>>;
|
|
34
36
|
inPlace: z.ZodPipe<z.ZodDefault<z.ZodString>, z.ZodTransform<boolean, string>>;
|
|
35
37
|
sandboxNetwork: z.ZodDefault<z.ZodEnum<{
|
|
36
|
-
isolated: "isolated";
|
|
37
38
|
host: "host";
|
|
39
|
+
isolated: "isolated";
|
|
38
40
|
}>>;
|
|
41
|
+
sandboxHardened: z.ZodPipe<z.ZodDefault<z.ZodString>, z.ZodTransform<boolean, string>>;
|
|
42
|
+
sandboxReadonlyRootfs: z.ZodPipe<z.ZodDefault<z.ZodString>, z.ZodTransform<boolean, string>>;
|
|
43
|
+
sandboxUser: z.ZodOptional<z.ZodString>;
|
|
44
|
+
sandboxPidsLimit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
45
|
+
sandboxMemoryBytes: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
46
|
+
sandboxNanoCpus: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
39
47
|
scalerManaged: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<boolean, string | undefined>>;
|
|
40
48
|
scalerIdleTimeoutMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
41
49
|
scalerPendingDispatchTimeoutMs: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
42
50
|
executionMode: z.ZodOptional<z.ZodEnum<{
|
|
43
|
-
container: "container";
|
|
44
51
|
"bare-metal": "bare-metal";
|
|
52
|
+
container: "container";
|
|
45
53
|
firecracker: "firecracker";
|
|
46
54
|
}>>;
|
|
47
55
|
otelExporterOtlpEndpoint: z.ZodOptional<z.ZodString>;
|
|
@@ -62,30 +70,38 @@ export type AppConfig = z.infer<typeof configSchema> & {
|
|
|
62
70
|
*/
|
|
63
71
|
export declare const envDef: import("@kici-dev/shared/env").DefineEnvResult<{
|
|
64
72
|
orchestratorUrl: string;
|
|
73
|
+
agentId?: string | undefined;
|
|
65
74
|
labels: string[];
|
|
66
75
|
properties: Record<string, string | number | boolean>;
|
|
67
76
|
roles: string[] | undefined;
|
|
68
77
|
port: number;
|
|
69
|
-
logLevel: "
|
|
78
|
+
logLevel: "debug" | "error" | "info" | "warn";
|
|
79
|
+
agentToken?: string | undefined;
|
|
80
|
+
githubToken?: string | undefined;
|
|
70
81
|
maxLogSizeBytes: number;
|
|
71
82
|
defaultStepTimeoutMs: number;
|
|
72
83
|
dockerKeepFailed: boolean;
|
|
73
84
|
jobHeartbeatIntervalMs: number;
|
|
74
|
-
backpressureMode: "
|
|
85
|
+
backpressureMode: "drop" | "pause";
|
|
86
|
+
agentPayloadDir?: string | undefined;
|
|
87
|
+
agentCommand?: string | undefined;
|
|
75
88
|
sandbox: boolean;
|
|
76
89
|
trustedEnv: boolean;
|
|
77
90
|
inPlace: boolean;
|
|
78
|
-
sandboxNetwork: "
|
|
91
|
+
sandboxNetwork: "host" | "isolated";
|
|
92
|
+
sandboxHardened: boolean;
|
|
93
|
+
sandboxReadonlyRootfs: boolean;
|
|
94
|
+
sandboxUser?: string | undefined;
|
|
95
|
+
sandboxPidsLimit: number;
|
|
96
|
+
sandboxMemoryBytes: number;
|
|
97
|
+
sandboxNanoCpus: number;
|
|
79
98
|
scalerManaged: boolean;
|
|
80
99
|
scalerIdleTimeoutMs: number;
|
|
81
100
|
scalerPendingDispatchTimeoutMs: number;
|
|
101
|
+
executionMode?: "bare-metal" | "container" | "firecracker" | undefined;
|
|
102
|
+
otelExporterOtlpEndpoint?: string | undefined;
|
|
82
103
|
concurrencyWaitTimeoutMs: number;
|
|
83
104
|
isOrchestratorHost: boolean;
|
|
84
|
-
agentId?: string | undefined;
|
|
85
|
-
agentToken?: string | undefined;
|
|
86
|
-
githubToken?: string | undefined;
|
|
87
|
-
executionMode?: "container" | "bare-metal" | "firecracker" | undefined;
|
|
88
|
-
otelExporterOtlpEndpoint?: string | undefined;
|
|
89
105
|
}>;
|
|
90
106
|
/**
|
|
91
107
|
* Load and validate agent configuration from environment variables.
|
|
@@ -108,7 +124,13 @@ export declare const envDef: import("@kici-dev/shared/env").DefineEnvResult<{
|
|
|
108
124
|
* - KICI_SANDBOX (default: false) — enable bubblewrap (bwrap) namespace isolation for bare-metal execution
|
|
109
125
|
* - KICI_TRUSTED_ENV (default: false) — trusted fleet-agent profile: pass the ambient host env (minus the agent's own KiCI identity secrets) through to steps
|
|
110
126
|
* - KICI_IN_PLACE (default: false) — in-place no-clone profile: for a file:// source, use the real repo path as workDir and skip the clone (the routed deploy:stg profile)
|
|
111
|
-
* - KICI_SANDBOX_NETWORK (default: isolated, options: isolated | host) — when sandbox=true
|
|
127
|
+
* - KICI_SANDBOX_NETWORK (default: isolated, options: isolated | host) — sandbox network posture for BOTH backends: the bwrap network namespace (when sandbox=true) and the container job network. `host` shares the host network (container backend also binds host /etc/hosts read-only for name resolution); applies to the container backend under the default hardened posture (KICI_SANDBOX_HARDENED=true)
|
|
128
|
+
* - KICI_SANDBOX_HARDENED (default: true) — hardened-by-default job containers (CapDrop ALL, no-new-privileges, cgroup caps, tmpfs /tmp); set false to roll back to the legacy unhardened posture
|
|
129
|
+
* - KICI_SANDBOX_READONLY_ROOTFS (default: false) — opt-in read-only container rootfs (/tmp stays a writable tmpfs)
|
|
130
|
+
* - KICI_SANDBOX_USER (optional) — container user override (uid, uid:gid, or name); honors the image user when unset
|
|
131
|
+
* - KICI_SANDBOX_PIDS_LIMIT (default: 512) — max PIDs in the job container cgroup
|
|
132
|
+
* - KICI_SANDBOX_MEMORY_BYTES (default: 2 GiB) — memory cap in bytes for the job container cgroup
|
|
133
|
+
* - KICI_SANDBOX_NANO_CPUS (default: 2 CPUs) — CPU cap in nano-CPUs for the job container cgroup
|
|
112
134
|
* - KICI_SCALER_MANAGED (set to "1" by the orchestrator's auto-scaler — agent self-shuts down on idle)
|
|
113
135
|
* - KICI_SCALER_IDLE_TIMEOUT (ms, default 5000) — how long a scaler-managed agent waits before shutdown after going idle
|
|
114
136
|
* - KICI_SCALER_PENDING_DISPATCH_TIMEOUT (ms, default 60000) — extended idle window when register.ack signals a queued bound job
|