@namzu/sandbox 14.0.0 → 16.0.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/CHANGELOG.md +924 -0
- package/README.md +369 -14
- package/dist/backends/aci-standby-pool/index.d.ts.map +1 -1
- package/dist/backends/aci-standby-pool/index.js +13 -1
- package/dist/backends/aci-standby-pool/index.js.map +1 -1
- package/dist/backends/docker/index.d.ts +169 -6
- package/dist/backends/docker/index.d.ts.map +1 -1
- package/dist/backends/docker/index.js +499 -85
- package/dist/backends/docker/index.js.map +1 -1
- package/dist/backends/firecracker/index.d.ts.map +1 -1
- package/dist/backends/firecracker/index.js +12 -2
- package/dist/backends/firecracker/index.js.map +1 -1
- package/dist/backends/firecracker/protocol.d.ts +459 -8
- package/dist/backends/firecracker/protocol.d.ts.map +1 -1
- package/dist/backends/firecracker/protocol.js +136 -0
- package/dist/backends/firecracker/protocol.js.map +1 -1
- package/dist/backends/firecracker/transport.d.ts +539 -6
- package/dist/backends/firecracker/transport.d.ts.map +1 -1
- package/dist/backends/firecracker/transport.js +1171 -24
- package/dist/backends/firecracker/transport.js.map +1 -1
- package/dist/backends/kubernetes/egress-policy.d.ts +1181 -13
- package/dist/backends/kubernetes/egress-policy.d.ts.map +1 -1
- package/dist/backends/kubernetes/egress-policy.js +2350 -31
- package/dist/backends/kubernetes/egress-policy.js.map +1 -1
- package/dist/backends/kubernetes/identity.d.ts +193 -0
- package/dist/backends/kubernetes/identity.d.ts.map +1 -0
- package/dist/backends/kubernetes/identity.js +147 -0
- package/dist/backends/kubernetes/identity.js.map +1 -0
- package/dist/backends/kubernetes/index.d.ts +678 -33
- package/dist/backends/kubernetes/index.d.ts.map +1 -1
- package/dist/backends/kubernetes/index.js +1180 -95
- package/dist/backends/kubernetes/index.js.map +1 -1
- package/dist/backends/kubernetes/ingress-policy.d.ts +375 -0
- package/dist/backends/kubernetes/ingress-policy.d.ts.map +1 -0
- package/dist/backends/kubernetes/ingress-policy.js +1050 -0
- package/dist/backends/kubernetes/ingress-policy.js.map +1 -0
- package/dist/backends/kubernetes/k8s-client.d.ts +213 -4
- package/dist/backends/kubernetes/k8s-client.d.ts.map +1 -1
- package/dist/backends/kubernetes/k8s-client.js +359 -52
- package/dist/backends/kubernetes/k8s-client.js.map +1 -1
- package/dist/backends/kubernetes/lease.d.ts +40 -14
- package/dist/backends/kubernetes/lease.d.ts.map +1 -1
- package/dist/backends/kubernetes/lease.js +68 -18
- package/dist/backends/kubernetes/lease.js.map +1 -1
- package/dist/backends/kubernetes/objects.d.ts +423 -3
- package/dist/backends/kubernetes/objects.d.ts.map +1 -1
- package/dist/backends/kubernetes/objects.js +364 -2
- package/dist/backends/kubernetes/objects.js.map +1 -1
- package/dist/backends/kubernetes/per-sandbox-policy.d.ts +219 -0
- package/dist/backends/kubernetes/per-sandbox-policy.d.ts.map +1 -0
- package/dist/backends/kubernetes/per-sandbox-policy.js +375 -0
- package/dist/backends/kubernetes/per-sandbox-policy.js.map +1 -0
- package/dist/backends/kubernetes/rbac.d.ts +153 -0
- package/dist/backends/kubernetes/rbac.d.ts.map +1 -0
- package/dist/backends/kubernetes/rbac.js +177 -0
- package/dist/backends/kubernetes/rbac.js.map +1 -0
- package/dist/backends/kubernetes/sandbox.d.ts +81 -14
- package/dist/backends/kubernetes/sandbox.d.ts.map +1 -1
- package/dist/backends/kubernetes/sandbox.js +149 -15
- package/dist/backends/kubernetes/sandbox.js.map +1 -1
- package/dist/backends/kubernetes/transport.d.ts +935 -9
- package/dist/backends/kubernetes/transport.d.ts.map +1 -1
- package/dist/backends/kubernetes/transport.js +1958 -62
- package/dist/backends/kubernetes/transport.js.map +1 -1
- package/dist/backends/kubernetes/workspace.d.ts +1149 -18
- package/dist/backends/kubernetes/workspace.d.ts.map +1 -1
- package/dist/backends/kubernetes/workspace.js +2825 -186
- package/dist/backends/kubernetes/workspace.js.map +1 -1
- package/dist/backends/remote-execution-controller.d.ts +14 -0
- package/dist/backends/remote-execution-controller.d.ts.map +1 -1
- package/dist/backends/remote-execution-controller.js.map +1 -1
- package/dist/index.d.ts +294 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +280 -10
- package/dist/index.js.map +1 -1
- package/dist/testing/sandbox-conformance.d.ts +39 -5
- package/dist/testing/sandbox-conformance.d.ts.map +1 -1
- package/dist/testing/sandbox-conformance.js +436 -5
- package/dist/testing/sandbox-conformance.js.map +1 -1
- package/package.json +3 -3
- package/src/backends/aci-standby-pool/index.ts +16 -1
- package/src/backends/docker/index.ts +617 -100
- package/src/backends/firecracker/index.ts +14 -2
- package/src/backends/firecracker/protocol.ts +514 -6
- package/src/backends/firecracker/transport.ts +1492 -40
- package/src/backends/kubernetes/egress-policy.ts +3334 -55
- package/src/backends/kubernetes/identity.ts +261 -0
- package/src/backends/kubernetes/index.ts +1785 -127
- package/src/backends/kubernetes/ingress-policy.ts +1344 -0
- package/src/backends/kubernetes/k8s-client.ts +444 -54
- package/src/backends/kubernetes/lease.ts +75 -19
- package/src/backends/kubernetes/objects.ts +626 -6
- package/src/backends/kubernetes/per-sandbox-policy.ts +497 -0
- package/src/backends/kubernetes/rbac.ts +192 -0
- package/src/backends/kubernetes/sandbox.ts +218 -20
- package/src/backends/kubernetes/transport.ts +2733 -124
- package/src/backends/kubernetes/workspace.ts +4476 -222
- package/src/backends/remote-execution-controller.ts +14 -0
- package/src/index.ts +668 -19
- package/src/testing/sandbox-conformance.ts +540 -5
|
@@ -52,21 +52,42 @@ export interface ExecRequest {
|
|
|
52
52
|
readonly stdin?: string;
|
|
53
53
|
readonly timeoutMs?: number;
|
|
54
54
|
readonly maxOutputBytes?: number;
|
|
55
|
+
/**
|
|
56
|
+
* Ask the guest to keep this command's output in its retained log, so a
|
|
57
|
+
* host that loses the data connection can reattach by execution id and
|
|
58
|
+
* read on from the offset it reached.
|
|
59
|
+
*
|
|
60
|
+
* Requires `executionId` — a log nobody can name is a log nobody can
|
|
61
|
+
* attach to — and requires the guest to advertise `execution-attach` in
|
|
62
|
+
* its `healthz` features. Omitted on every ordinary exec, which is why
|
|
63
|
+
* the default wire request is byte-for-byte what it has always been.
|
|
64
|
+
*/
|
|
65
|
+
readonly retainOutput?: boolean;
|
|
55
66
|
}
|
|
56
67
|
/**
|
|
57
68
|
* One NDJSON event the agent emits while streaming an `/execute`. The
|
|
58
69
|
* exact union the HTTP worker writes via `writeEvent`:
|
|
59
70
|
* { type: 'stdout_delta', data }
|
|
60
71
|
* { type: 'stderr_delta', data }
|
|
72
|
+
*
|
|
73
|
+
* A delta of an execution the guest was asked to RETAIN also carries
|
|
74
|
+
* `offset` and `nextOffset`: the bytes the chunk occupies in that
|
|
75
|
+
* execution's retained log. They are additive, ignored by every consumer
|
|
76
|
+
* that does not reattach, and they are the only correct source for a
|
|
77
|
+
* reattach cursor — see {@link parseExecEvent}.
|
|
61
78
|
* { type: 'result', exitCode, timedOut, durationMs, stdoutTruncated?, stderrTruncated? }
|
|
62
79
|
* { type: 'error', error }
|
|
63
80
|
*/
|
|
64
81
|
export type ExecEvent = {
|
|
65
82
|
readonly type: 'stdout_delta';
|
|
66
83
|
readonly data: string;
|
|
84
|
+
readonly offset?: number;
|
|
85
|
+
readonly nextOffset?: number;
|
|
67
86
|
} | {
|
|
68
87
|
readonly type: 'stderr_delta';
|
|
69
88
|
readonly data: string;
|
|
89
|
+
readonly offset?: number;
|
|
90
|
+
readonly nextOffset?: number;
|
|
70
91
|
} | {
|
|
71
92
|
readonly type: 'result';
|
|
72
93
|
readonly exitCode: number;
|
|
@@ -79,23 +100,140 @@ export type ExecEvent = {
|
|
|
79
100
|
readonly type: 'error';
|
|
80
101
|
readonly error: string;
|
|
81
102
|
};
|
|
103
|
+
/**
|
|
104
|
+
* One slice of a `write-file` body, for a body too large to cross the wire
|
|
105
|
+
* in a single frame.
|
|
106
|
+
*
|
|
107
|
+
* ADDITIVE, and deliberately so: the guest protocol version is unchanged,
|
|
108
|
+
* an agent that predates this field ignores it, and a host only ever sends
|
|
109
|
+
* it to an agent that advertised {@link WRITE_FILE_PARTS_FEATURE} in its
|
|
110
|
+
* `healthz` reply. The sequence writes a temporary sibling of the target
|
|
111
|
+
* (`WriteFileRequest.path` names the TEMP file while `part` is present, so
|
|
112
|
+
* an agent that dropped the field would overwrite the temp file rather
|
|
113
|
+
* than the target) and finishes with an atomic rename onto `renameTo`.
|
|
114
|
+
*/
|
|
115
|
+
export interface WriteFilePart {
|
|
116
|
+
/**
|
|
117
|
+
* Byte offset in the temp file this slice starts at. `0` creates or
|
|
118
|
+
* truncates it; any other value must equal the temp file's CURRENT
|
|
119
|
+
* size, so a lost, duplicated or reordered part is refused rather
|
|
120
|
+
* than silently producing a corrupt file.
|
|
121
|
+
*/
|
|
122
|
+
readonly offset?: number;
|
|
123
|
+
/** Last slice: rename the temp file onto {@link renameTo} once written. */
|
|
124
|
+
readonly final?: boolean;
|
|
125
|
+
/** The real target, required when {@link final} is true. */
|
|
126
|
+
readonly renameTo?: string;
|
|
127
|
+
/**
|
|
128
|
+
* Remove the temp file named by `path` and write nothing — the
|
|
129
|
+
* best-effort cleanup a host runs when a part sequence is abandoned.
|
|
130
|
+
* `content` is ignored.
|
|
131
|
+
*/
|
|
132
|
+
readonly discard?: boolean;
|
|
133
|
+
}
|
|
82
134
|
/** `/write-file` request body. `content` is base64. */
|
|
83
135
|
export interface WriteFileRequest {
|
|
84
136
|
readonly path: string;
|
|
85
137
|
readonly content: string;
|
|
86
138
|
readonly encoding: 'base64';
|
|
139
|
+
/** Present only for a chunked write; see {@link WriteFilePart}. */
|
|
140
|
+
readonly part?: WriteFilePart;
|
|
87
141
|
}
|
|
88
142
|
/** `/write-file` success response. */
|
|
89
143
|
export interface WriteFileResponse {
|
|
90
144
|
readonly ok: boolean;
|
|
91
145
|
readonly bytesWritten?: number;
|
|
146
|
+
/** Total size of the temp file after this part, for a chunked write. */
|
|
147
|
+
readonly sizeBytes?: number;
|
|
92
148
|
readonly error?: string;
|
|
93
149
|
}
|
|
94
|
-
/**
|
|
150
|
+
/**
|
|
151
|
+
* The `healthz` feature string an agent advertises when it implements
|
|
152
|
+
* {@link WriteFilePart}. A host that does not see it in `features` keeps
|
|
153
|
+
* to the single-frame write and its named too-large error.
|
|
154
|
+
*/
|
|
155
|
+
export declare const WRITE_FILE_PARTS_FEATURE = "write-file-parts";
|
|
156
|
+
/**
|
|
157
|
+
* The `healthz` feature string an agent advertises when it accepts a
|
|
158
|
+
* caller-chosen `executionId`, an `execute` carrying `retainOutput`, and
|
|
159
|
+
* the `attach-execution` op that replays a retained execution's output by
|
|
160
|
+
* byte offset.
|
|
161
|
+
*
|
|
162
|
+
* A host asking for a detachable command against a guest that does not
|
|
163
|
+
* advertise it is refused BEFORE the command is admitted, rather than
|
|
164
|
+
* starting one whose output nothing keeps.
|
|
165
|
+
*/
|
|
166
|
+
export declare const EXECUTION_ATTACH_FEATURE = "execution-attach";
|
|
167
|
+
/**
|
|
168
|
+
* `/read-file` request body.
|
|
169
|
+
*
|
|
170
|
+
* `offset`/`length` are ADDITIVE and gated exactly as {@link WriteFilePart}
|
|
171
|
+
* is: a host sends them only to an agent that advertised
|
|
172
|
+
* {@link READ_FILE_STREAM_FEATURE} in its `healthz` reply, because an agent
|
|
173
|
+
* that predates them ignores both and answers with the WHOLE file — which
|
|
174
|
+
* the caller would read as its slice. Omitting both is the whole-file read
|
|
175
|
+
* this op has always served, byte for byte.
|
|
176
|
+
*/
|
|
95
177
|
export interface ReadFileRequest {
|
|
96
178
|
readonly path: string;
|
|
97
179
|
readonly encoding: 'base64';
|
|
180
|
+
/** First byte of the slice. Defaults to 0 when only `length` is given. */
|
|
181
|
+
readonly offset?: number;
|
|
182
|
+
/**
|
|
183
|
+
* How many bytes to answer with. Defaults to the rest of the file, and
|
|
184
|
+
* is REFUSED rather than shortened above the guest's per-frame range
|
|
185
|
+
* ceiling (`NAMZU_AGENT_READ_FILE_RANGE_BYTES`, 1 MiB by default) — a
|
|
186
|
+
* whole file goes through {@link ReadFileStreamRequest} instead.
|
|
187
|
+
*/
|
|
188
|
+
readonly length?: number;
|
|
98
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* `read-file-stream` request body — one file as an ordered sequence of
|
|
192
|
+
* frames rather than one reply.
|
|
193
|
+
*
|
|
194
|
+
* `offset`/`length` are accepted and deliberately NOT capped: this op is
|
|
195
|
+
* where {@link ReadFileRequest}'s range ceiling sends a caller who wants
|
|
196
|
+
* more than one frame's worth.
|
|
197
|
+
*/
|
|
198
|
+
export interface ReadFileStreamRequest {
|
|
199
|
+
readonly path: string;
|
|
200
|
+
readonly offset?: number;
|
|
201
|
+
readonly length?: number;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Guest → host frames for one `read-file-stream`, in order: exactly one
|
|
205
|
+
* `meta`, zero or more `data`, then one `end` — or a single `error`
|
|
206
|
+
* instead of any of them — followed by the zero-length terminator.
|
|
207
|
+
*
|
|
208
|
+
* `data` is base64 for the same reason every other payload on this wire
|
|
209
|
+
* is: the frame body is UTF-8 JSON, which cannot carry arbitrary bytes.
|
|
210
|
+
*/
|
|
211
|
+
export type ReadFileStreamEvent = {
|
|
212
|
+
readonly type: 'meta';
|
|
213
|
+
/** The WHOLE file's size, never the slice's — how a caller knows where it ends. */
|
|
214
|
+
readonly sizeBytes: number;
|
|
215
|
+
readonly offset: number;
|
|
216
|
+
/** What this stream intends to send, after clamping to EOF. */
|
|
217
|
+
readonly length: number;
|
|
218
|
+
} | {
|
|
219
|
+
readonly type: 'data';
|
|
220
|
+
readonly data: string;
|
|
221
|
+
} | {
|
|
222
|
+
readonly type: 'end';
|
|
223
|
+
readonly bytesSent: number;
|
|
224
|
+
} | {
|
|
225
|
+
readonly type: 'error';
|
|
226
|
+
readonly error: string;
|
|
227
|
+
};
|
|
228
|
+
/**
|
|
229
|
+
* The `healthz` feature string an agent advertises when `read-file`
|
|
230
|
+
* honours {@link ReadFileRequest.offset}/`length` AND the
|
|
231
|
+
* `read-file-stream` op exists. ONE string for both halves because they
|
|
232
|
+
* ship together in `agent/agent.cjs` and no guest can have one without the
|
|
233
|
+
* other; a host that does not see it sends neither shape and keeps to the
|
|
234
|
+
* single whole-file reply.
|
|
235
|
+
*/
|
|
236
|
+
export declare const READ_FILE_STREAM_FEATURE = "read-file-stream";
|
|
99
237
|
/** Initial request for one interactive terminal process in the guest. */
|
|
100
238
|
export interface TerminalOpenRequest {
|
|
101
239
|
readonly command?: string;
|
|
@@ -104,6 +242,22 @@ export interface TerminalOpenRequest {
|
|
|
104
242
|
readonly env?: Record<string, string>;
|
|
105
243
|
readonly cols: number;
|
|
106
244
|
readonly rows: number;
|
|
245
|
+
/** See {@link StreamHeartbeat}. Absent → no heartbeat on this stream. */
|
|
246
|
+
readonly heartbeatMs?: number;
|
|
247
|
+
/**
|
|
248
|
+
* Name this terminal so it can be found again. Both fields are ADDITIVE
|
|
249
|
+
* and both are required together: a guest that predates them ignores
|
|
250
|
+
* them and serves the connection-bound terminal it always served, which
|
|
251
|
+
* is why a host only ever sends them to one advertising
|
|
252
|
+
* {@link SESSIONS_FEATURE}.
|
|
253
|
+
*
|
|
254
|
+
* With them, the PTY belongs to the guest's session registry rather than
|
|
255
|
+
* to this connection: output is read into a retained log whether or not
|
|
256
|
+
* anybody is attached, and closing the connection detaches instead of
|
|
257
|
+
* killing.
|
|
258
|
+
*/
|
|
259
|
+
readonly sessionId?: string;
|
|
260
|
+
readonly persistent?: boolean;
|
|
107
261
|
}
|
|
108
262
|
/** Host → guest messages after the terminal stream reports ready. */
|
|
109
263
|
export type TerminalInputEvent = {
|
|
@@ -116,24 +270,234 @@ export type TerminalInputEvent = {
|
|
|
116
270
|
} | {
|
|
117
271
|
readonly type: 'kill';
|
|
118
272
|
readonly signal?: string;
|
|
119
|
-
};
|
|
273
|
+
} | StreamHeartbeat;
|
|
120
274
|
/** Guest → host events carried for the lifetime of the terminal stream. */
|
|
121
|
-
export type TerminalOutputEvent = {
|
|
122
|
-
readonly type: 'ready';
|
|
123
|
-
} | {
|
|
275
|
+
export type TerminalOutputEvent = TerminalReadyEvent | {
|
|
124
276
|
readonly type: 'data';
|
|
125
277
|
readonly data: string;
|
|
278
|
+
/** Only on a session stream: where this chunk sits in the retained log. */
|
|
279
|
+
readonly stream?: SessionStreamName;
|
|
280
|
+
readonly offset?: number;
|
|
281
|
+
readonly nextOffset?: number;
|
|
126
282
|
} | {
|
|
127
283
|
readonly type: 'exit';
|
|
128
284
|
readonly exitCode: number;
|
|
129
285
|
readonly signal?: number;
|
|
130
|
-
|
|
286
|
+
readonly nextOffset?: number;
|
|
287
|
+
} | SessionDetachedEvent | {
|
|
131
288
|
readonly type: 'error';
|
|
132
289
|
readonly error: string;
|
|
133
|
-
};
|
|
290
|
+
} | StreamHeartbeat;
|
|
291
|
+
/**
|
|
292
|
+
* The opening frame of a terminal stream, and the one place the session ops
|
|
293
|
+
* add to it.
|
|
294
|
+
*
|
|
295
|
+
* Every session field is optional because a connection-bound terminal sends
|
|
296
|
+
* none of them, and a guest that predates the registry sends none either.
|
|
297
|
+
*/
|
|
298
|
+
export interface TerminalReadyEvent {
|
|
299
|
+
readonly type: 'ready';
|
|
300
|
+
readonly heartbeatMs?: number;
|
|
301
|
+
/**
|
|
302
|
+
* The guest agent PROCESS this stream reached — see
|
|
303
|
+
* {@link GUEST_BOOT_ID_FEATURE}. Absent from a guest that predates it, so
|
|
304
|
+
* nothing may require it.
|
|
305
|
+
*/
|
|
306
|
+
readonly guestBootId?: string;
|
|
307
|
+
readonly sessionId?: string;
|
|
308
|
+
readonly kind?: SessionKind;
|
|
309
|
+
readonly state?: SessionState;
|
|
310
|
+
/** Where the replay this stream is about to send begins. */
|
|
311
|
+
readonly fromOffset?: number;
|
|
312
|
+
/** Bytes evicted between what the reader asked for and what survived. */
|
|
313
|
+
readonly droppedBytes?: number;
|
|
314
|
+
/** One past the newest byte the guest had when the stream opened. */
|
|
315
|
+
readonly nextOffset?: number;
|
|
316
|
+
readonly exitCode?: number;
|
|
317
|
+
readonly signal?: number;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* The `healthz` feature string an agent advertises when it keeps a session
|
|
321
|
+
* registry: `terminal` with `{ sessionId, persistent: true }`, plus the
|
|
322
|
+
* `attach-session`, `start-detached`, `list-sessions` and `kill-session`
|
|
323
|
+
* ops.
|
|
324
|
+
*
|
|
325
|
+
* A host asking for any of them against a guest that does not advertise it
|
|
326
|
+
* is refused by name and never falls back to a connection-bound terminal: a
|
|
327
|
+
* caller that asked for a session is about to rely on coming back to it, and
|
|
328
|
+
* handing it one that dies with the socket would keep nothing and tell
|
|
329
|
+
* nobody.
|
|
330
|
+
*/
|
|
331
|
+
export declare const SESSIONS_FEATURE = "sessions";
|
|
332
|
+
/**
|
|
333
|
+
* `healthz.features` entry: every authenticated reply and every stream
|
|
334
|
+
* `ready` frame carries a `guestBootId` naming the agent PROCESS that
|
|
335
|
+
* answered.
|
|
336
|
+
*
|
|
337
|
+
* The field is optional on every shape that carries it and a host must treat
|
|
338
|
+
* an absent one as "this guest cannot tell me" rather than as a change — an
|
|
339
|
+
* image built before this existed answers exactly as it always did. The
|
|
340
|
+
* feature string is here for the one host that wants to REQUIRE the evidence
|
|
341
|
+
* (a Kubernetes workspace deciding whether a command's guest is still the
|
|
342
|
+
* one it started on) and needs to know before it relies on it.
|
|
343
|
+
*/
|
|
344
|
+
export declare const GUEST_BOOT_ID_FEATURE = "guest-boot-id";
|
|
345
|
+
/**
|
|
346
|
+
* The identity fields an authenticated reply may carry, and the whole of
|
|
347
|
+
* what an observer of one is allowed to read.
|
|
348
|
+
*
|
|
349
|
+
* Deliberately not the reply itself: an observer exists to follow the GUEST,
|
|
350
|
+
* and widening it to the payload would make every reply's content reachable
|
|
351
|
+
* from a hook whose job is a single opaque id.
|
|
352
|
+
*/
|
|
353
|
+
export interface GuestReplyIdentity {
|
|
354
|
+
readonly guestBootId?: string;
|
|
355
|
+
}
|
|
356
|
+
/** A PTY, or a program started with no terminal at all. */
|
|
357
|
+
export type SessionKind = 'terminal' | 'detached';
|
|
358
|
+
export type SessionState = 'running' | 'exited';
|
|
359
|
+
/** Which of the two streams a retained chunk came from. */
|
|
360
|
+
export type SessionStreamName = 'stdout' | 'stderr';
|
|
361
|
+
/** Why an attachment ended without the program exiting. */
|
|
362
|
+
export type SessionDetachReason = 'superseded' | 'slow_reader';
|
|
363
|
+
/**
|
|
364
|
+
* Sent to the attachment a session is taking away from it. It is never an
|
|
365
|
+
* exit: the program is still running, and the reason says who took it.
|
|
366
|
+
*/
|
|
367
|
+
export interface SessionDetachedEvent {
|
|
368
|
+
readonly type: 'detached';
|
|
369
|
+
readonly reason: SessionDetachReason;
|
|
370
|
+
}
|
|
371
|
+
/** Read one session's retained output, and optionally follow it live. */
|
|
372
|
+
export interface AttachSessionRequest {
|
|
373
|
+
readonly sessionId: string;
|
|
374
|
+
/** Byte offset to resume from. Default 0 — the whole retained log. */
|
|
375
|
+
readonly fromOffset?: number;
|
|
376
|
+
/**
|
|
377
|
+
* `false` replays what is retained and ends. Default `true`: stay
|
|
378
|
+
* attached, and — for a terminal session — accept input and resize.
|
|
379
|
+
*/
|
|
380
|
+
readonly follow?: boolean;
|
|
381
|
+
/** Resize the PTY on attach, for a terminal whose new reader has its own window. */
|
|
382
|
+
readonly cols?: number;
|
|
383
|
+
readonly rows?: number;
|
|
384
|
+
/** See {@link StreamHeartbeat}. Absent → no heartbeat on this stream. */
|
|
385
|
+
readonly heartbeatMs?: number;
|
|
386
|
+
}
|
|
387
|
+
/** Start a program with no terminal, which nothing but a kill ends. */
|
|
388
|
+
export interface StartDetachedRequest {
|
|
389
|
+
readonly sessionId: string;
|
|
390
|
+
readonly command: string;
|
|
391
|
+
readonly args?: readonly string[];
|
|
392
|
+
readonly cwd?: string;
|
|
393
|
+
readonly env?: Record<string, string>;
|
|
394
|
+
}
|
|
395
|
+
/** End one session and everything still in it. */
|
|
396
|
+
export interface KillSessionRequest {
|
|
397
|
+
readonly sessionId: string;
|
|
398
|
+
/** `SIGTERM`, `SIGKILL`, `SIGINT` or `SIGHUP`. Default `SIGKILL`. */
|
|
399
|
+
readonly signal?: string;
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* The `healthz` feature string an agent advertises when it implements the
|
|
403
|
+
* `quiesce` op: stop every process this guest is running — including ones
|
|
404
|
+
* no session and no execution owns — and go on serving `execute`,
|
|
405
|
+
* `read-file` and `write-file` afterwards.
|
|
406
|
+
*
|
|
407
|
+
* Gated exactly like {@link SESSIONS_FEATURE}: a host sends the op only to
|
|
408
|
+
* a guest that advertised it, because an agent that predates it answers
|
|
409
|
+
* `unknown_op: quiesce` and a host that read that as "nothing was running"
|
|
410
|
+
* would take its capture over a disk somebody is still writing to.
|
|
411
|
+
*/
|
|
412
|
+
export declare const QUIESCE_FEATURE = "quiesce";
|
|
413
|
+
/** Stop everything. `graceMs` bounds ONE round's SIGTERM window. */
|
|
414
|
+
export interface QuiesceRequest {
|
|
415
|
+
/**
|
|
416
|
+
* How long a round waits after `SIGTERM` before it escalates to
|
|
417
|
+
* `SIGKILL`. The guest refuses a value at or above its own
|
|
418
|
+
* cancel-confirmation timeout (5000ms by default) and defaults to
|
|
419
|
+
* 1000ms. It is NOT the pod's `terminationGracePeriodSeconds`.
|
|
420
|
+
*/
|
|
421
|
+
readonly graceMs?: number;
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* How wide the guest's scan was allowed to be — reported, so a narrowed
|
|
425
|
+
* scan is never silently weaker than the one the host asked for.
|
|
426
|
+
*
|
|
427
|
+
* - `pid-namespace` — every process in the guest's PID namespace but its
|
|
428
|
+
* init and the agent. What a shipped pod does.
|
|
429
|
+
* - `owned-sessions` — only the kernel sessions the guest's own registries
|
|
430
|
+
* own, which an agent that is not the init of its own PID namespace
|
|
431
|
+
* narrows itself to. It can miss a program that moved into a session of
|
|
432
|
+
* its own.
|
|
433
|
+
*/
|
|
434
|
+
export type QuiesceScope = 'pid-namespace' | 'owned-sessions';
|
|
435
|
+
/** One process a quiesce stopped, and the signal that stopped it. */
|
|
436
|
+
export interface QuiescedProcess {
|
|
437
|
+
readonly pid: number;
|
|
438
|
+
/**
|
|
439
|
+
* The kernel's short name for the executable (`/proc/<pid>/stat`), not
|
|
440
|
+
* the command line: this travels to the host, and a command line
|
|
441
|
+
* carries the workload's own arguments.
|
|
442
|
+
*/
|
|
443
|
+
readonly command: string;
|
|
444
|
+
readonly signal: 'SIGTERM' | 'SIGKILL';
|
|
445
|
+
}
|
|
446
|
+
/** What a successful `quiesce` answers with. */
|
|
447
|
+
export interface QuiesceReply {
|
|
448
|
+
readonly ok: true;
|
|
449
|
+
readonly stopped: readonly QuiescedProcess[];
|
|
450
|
+
readonly scope: QuiesceScope;
|
|
451
|
+
/** The window each round actually used, after the guest's own clamp. */
|
|
452
|
+
readonly graceMs: number;
|
|
453
|
+
/** Scan-and-signal passes performed. `0` means nothing was running. */
|
|
454
|
+
readonly rounds: number;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* The `healthz` feature string an agent advertises when it implements the
|
|
458
|
+
* `flush` op: run `syncfs(2)` over the workspace mount and answer only once
|
|
459
|
+
* it has returned.
|
|
460
|
+
*
|
|
461
|
+
* Gated exactly like {@link QUIESCE_FEATURE}, and for a sharper reason than
|
|
462
|
+
* any other feature in this file: an agent that predates the op answers
|
|
463
|
+
* `unknown_op: flush`, and a host that read that as "the disk is flushed"
|
|
464
|
+
* would take the pod away over pages that never reached the device. So the
|
|
465
|
+
* op is sent only to a guest that named it, and a guest that did not is
|
|
466
|
+
* reported as one that cannot flush rather than one that had nothing to.
|
|
467
|
+
*
|
|
468
|
+
* An agent that HAS the op advertises it only when it can actually perform
|
|
469
|
+
* one: the flush runs a program, and an image that stripped it has the code
|
|
470
|
+
* and nothing to run. Such a guest also answers `flush_unsupported` to an op
|
|
471
|
+
* sent anyway, which a host reads exactly as the missing string — because
|
|
472
|
+
* the alternative, an unconfirmed flush, is the shape that means "the disk
|
|
473
|
+
* may be missing writes" and would refuse that image's every suspend
|
|
474
|
+
* forever.
|
|
475
|
+
*/
|
|
476
|
+
export declare const FLUSH_FEATURE = "flush";
|
|
477
|
+
/** Flush the workspace filesystem. */
|
|
478
|
+
export interface FlushRequest {
|
|
479
|
+
/**
|
|
480
|
+
* How long the guest may spend on the `syncfs` before it reports the
|
|
481
|
+
* flush unconfirmed. The guest defaults to 10000ms
|
|
482
|
+
* (`NAMZU_AGENT_FLUSH_TIMEOUT_MS`). It is NOT the pod's
|
|
483
|
+
* `terminationGracePeriodSeconds`, which has to cover this and the
|
|
484
|
+
* guest's own termination drain together.
|
|
485
|
+
*/
|
|
486
|
+
readonly timeoutMs?: number;
|
|
487
|
+
}
|
|
488
|
+
/** What a successful `flush` answers with. */
|
|
489
|
+
export interface FlushReply {
|
|
490
|
+
readonly ok: true;
|
|
491
|
+
/** How long the `syncfs` itself took, as the guest measured it. */
|
|
492
|
+
readonly durationMs: number;
|
|
493
|
+
/** The mount the guest flushed — its workspace root. */
|
|
494
|
+
readonly workspace: string;
|
|
495
|
+
}
|
|
134
496
|
export interface TcpConnectRequest {
|
|
135
497
|
readonly host: '127.0.0.1' | '::1';
|
|
136
498
|
readonly port: number;
|
|
499
|
+
/** See {@link StreamHeartbeat}. Absent → no heartbeat on this stream. */
|
|
500
|
+
readonly heartbeatMs?: number;
|
|
137
501
|
}
|
|
138
502
|
export type TcpInputEvent = {
|
|
139
503
|
readonly type: 'data';
|
|
@@ -142,9 +506,11 @@ export type TcpInputEvent = {
|
|
|
142
506
|
readonly type: 'end';
|
|
143
507
|
} | {
|
|
144
508
|
readonly type: 'destroy';
|
|
145
|
-
};
|
|
509
|
+
} | StreamHeartbeat;
|
|
146
510
|
export type TcpOutputEvent = {
|
|
147
511
|
readonly type: 'ready';
|
|
512
|
+
readonly heartbeatMs?: number;
|
|
513
|
+
readonly guestBootId?: string;
|
|
148
514
|
} | {
|
|
149
515
|
readonly type: 'data';
|
|
150
516
|
readonly data: string;
|
|
@@ -153,14 +519,88 @@ export type TcpOutputEvent = {
|
|
|
153
519
|
} | {
|
|
154
520
|
readonly type: 'error';
|
|
155
521
|
readonly error: string;
|
|
522
|
+
} | StreamHeartbeat;
|
|
523
|
+
/**
|
|
524
|
+
* The one frame either side of an open `terminal` or `tcp-connect` stream
|
|
525
|
+
* may send to say it is still there.
|
|
526
|
+
*
|
|
527
|
+
* Once a stream reports `ready` the transport clears its read-idle timer,
|
|
528
|
+
* correctly: an interactive shell may sit silent for hours and a timer would
|
|
529
|
+
* kill a healthy one. So nothing was left that could tell that shell from a
|
|
530
|
+
* host that vanished without a FIN or an RST — a lost node, a partition, a
|
|
531
|
+
* middlebox that drops idle state. TCP keepalive proves only that the peer's
|
|
532
|
+
* KERNEL answers, and a `healthz` proves only that a FRESH connection is
|
|
533
|
+
* served; neither says anything about the stream in hand.
|
|
534
|
+
*
|
|
535
|
+
* **Negotiated per stream, in both directions.** The open request carries
|
|
536
|
+
* {@link TerminalOpenRequest.heartbeatMs} / {@link TcpConnectRequest.heartbeatMs};
|
|
537
|
+
* a guest that implements this echoes the interval it will use back in its
|
|
538
|
+
* `ready` event and only then starts sending, and the host only starts once
|
|
539
|
+
* that echo arrived. An agent that predates the field ignores it and echoes
|
|
540
|
+
* nothing, so the host behaves exactly as it did; an older HOST — which ends
|
|
541
|
+
* a stream with an error on any frame type it does not know — is never sent
|
|
542
|
+
* one, because it never asked.
|
|
543
|
+
*
|
|
544
|
+
* Anything arriving from the other side counts as proof of life, not just
|
|
545
|
+
* this frame and not even a whole frame: both sides count BYTES, so a single
|
|
546
|
+
* large frame that takes longer than the window to arrive cannot be read as
|
|
547
|
+
* the peer having gone away. {@link STREAM_HEARTBEAT_MISS_LIMIT} consecutive
|
|
548
|
+
* intervals with nothing at all end the stream: the host resolves `exited`
|
|
549
|
+
* with `exitCode: -1` (what a closed socket already produces) or resolves
|
|
550
|
+
* `closed`, and the guest runs the same close cleanup it runs for a socket
|
|
551
|
+
* that went away. Detection lands within those intervals plus at most one
|
|
552
|
+
* watchdog tick, since each side polls at a quarter of the interval rather
|
|
553
|
+
* than at it. Silence while a side has paused reading for backpressure is
|
|
554
|
+
* not silence — that side chose it, and the bytes are waiting in the kernel.
|
|
555
|
+
*/
|
|
556
|
+
export type StreamHeartbeat = {
|
|
557
|
+
readonly type: 'heartbeat';
|
|
156
558
|
};
|
|
559
|
+
/** Missed intervals that end a stream. Three, so one lost frame is not fatal. */
|
|
560
|
+
export declare const STREAM_HEARTBEAT_MISS_LIMIT = 3;
|
|
561
|
+
/**
|
|
562
|
+
* The shortest interval either side will run a heartbeat at.
|
|
563
|
+
*
|
|
564
|
+
* The interval arrives from the host, so the guest clamps it to this before
|
|
565
|
+
* using it and echoes the CLAMPED value — otherwise an authenticated host
|
|
566
|
+
* could ask for a fraction of a millisecond and leave the agent doing
|
|
567
|
+
* nothing but writing heartbeats.
|
|
568
|
+
*/
|
|
569
|
+
export declare const MIN_STREAM_HEARTBEAT_MS = 100;
|
|
570
|
+
/**
|
|
571
|
+
* How far above what it asked for a host will honour the guest's echo.
|
|
572
|
+
*
|
|
573
|
+
* The echo is a number from the pod, and the host does its own watchdog
|
|
574
|
+
* arithmetic with it: unclamped, a guest echoing a fraction of a millisecond
|
|
575
|
+
* makes the host tear the stream down on its first tick, and one echoing a
|
|
576
|
+
* day disables the host's detection entirely. A guest that clamps the way
|
|
577
|
+
* this one does always echoes a value inside the band, so the honest case is
|
|
578
|
+
* never altered.
|
|
579
|
+
*/
|
|
580
|
+
export declare const STREAM_HEARTBEAT_MAX_ECHO_FACTOR = 4;
|
|
581
|
+
/**
|
|
582
|
+
* The `healthz` feature string an agent advertises when it understands
|
|
583
|
+
* {@link StreamHeartbeat}. Informational for the host — the per-stream
|
|
584
|
+
* `ready` echo is what actually arms anything — and the honest answer for an
|
|
585
|
+
* operator reading a `healthz` reply to find out what an image can do.
|
|
586
|
+
*/
|
|
587
|
+
export declare const STREAM_HEARTBEAT_FEATURE = "stream-heartbeat";
|
|
157
588
|
/** `/read-file` response. `content` is base64 on success. */
|
|
158
589
|
export interface ReadFileResponse {
|
|
159
590
|
readonly ok: boolean;
|
|
160
591
|
readonly content?: string;
|
|
592
|
+
/** The WHOLE file's size, in both the whole-file and the ranged shape. */
|
|
161
593
|
readonly sizeBytes?: number;
|
|
162
594
|
readonly encoding?: string;
|
|
163
595
|
readonly error?: string;
|
|
596
|
+
/** Present only on a ranged reply: the first byte `content` starts at. */
|
|
597
|
+
readonly offset?: number;
|
|
598
|
+
/**
|
|
599
|
+
* Present only on a ranged reply: how many bytes `content` decodes to.
|
|
600
|
+
* Below the requested `length` when the range ran past EOF, which is an
|
|
601
|
+
* answer rather than an error.
|
|
602
|
+
*/
|
|
603
|
+
readonly bytesRead?: number;
|
|
164
604
|
}
|
|
165
605
|
/**
|
|
166
606
|
* Accumulates the streamed `/execute` NDJSON into a single
|
|
@@ -201,4 +641,15 @@ export declare class ExecResultAccumulator {
|
|
|
201
641
|
* ignored; malformed JSON and unknown/partial event shapes are refused.
|
|
202
642
|
*/
|
|
203
643
|
export declare function parseExecLine(line: string): ExecEvent | undefined;
|
|
644
|
+
/**
|
|
645
|
+
* The same structural validation over an event that has ALREADY been
|
|
646
|
+
* parsed out of its frame.
|
|
647
|
+
*
|
|
648
|
+
* Split out of {@link parseExecLine} for the caller that reads the exec
|
|
649
|
+
* stream frame by frame rather than as NDJSON text — the Kubernetes
|
|
650
|
+
* detached execution, which needs the raw object to read the retained-log
|
|
651
|
+
* offsets off it. One validation, two entry points: an ordinary exec and a
|
|
652
|
+
* detached one must never disagree about what a valid frame is.
|
|
653
|
+
*/
|
|
654
|
+
export declare function parseExecEvent(parsed: unknown): ExecEvent;
|
|
204
655
|
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../src/backends/firecracker/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAQvE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACvB;AAMD;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../src/backends/firecracker/protocol.ts"],"names":[],"mappings":"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"}
|