@slicervm/sdk 0.1.4 → 0.1.5
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/README.md +7 -0
- package/dist/index.cjs +166 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +138 -1
- package/dist/index.d.ts +138 -1
- package/dist/index.js +166 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -131,6 +131,91 @@ interface ExecResultBinary {
|
|
|
131
131
|
exitCode: number;
|
|
132
132
|
error?: string;
|
|
133
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* Launch parameters for a background exec. Mirrors the Go SDK's
|
|
136
|
+
* `ExecBackgroundRequest`. The child is detached at launch and survives
|
|
137
|
+
* client disconnect; manage it via `vm.bg.list/info/logs/kill/wait/remove`.
|
|
138
|
+
*
|
|
139
|
+
* `command` + `args` is the always-correct deterministic form (matches the
|
|
140
|
+
* `--cmd` / `--arg` CLI flags). For `$VAR` expansion or shell operators set
|
|
141
|
+
* `shell` to a shell path (e.g. `/bin/bash`) and pass the script as
|
|
142
|
+
* `command`; the agent runs `<shell> -lc "<command>"` in that case.
|
|
143
|
+
*/
|
|
144
|
+
interface BgExecRequest {
|
|
145
|
+
command: string;
|
|
146
|
+
args?: string[];
|
|
147
|
+
env?: string[];
|
|
148
|
+
uid?: number;
|
|
149
|
+
gid?: number;
|
|
150
|
+
cwd?: string;
|
|
151
|
+
/**
|
|
152
|
+
* Empty (default): direct exec. Set to a shell path (e.g. `/bin/bash`) for
|
|
153
|
+
* `$VAR` expansion, globs, and shell operators. With a shell, bash auto-
|
|
154
|
+
* `exec`s the last simple command in `-c` scripts so the daemon is the
|
|
155
|
+
* tracked PID for typical cases. Multi-statement scripts that need clean
|
|
156
|
+
* tree should write `exec` themselves.
|
|
157
|
+
*/
|
|
158
|
+
shell?: string;
|
|
159
|
+
/** Per-process ring buffer cap in bytes. Zero means server default (1 MiB). */
|
|
160
|
+
ringBytes?: number;
|
|
161
|
+
}
|
|
162
|
+
/** Returned by `vm.bg.exec` on success. */
|
|
163
|
+
interface BgExecResponse {
|
|
164
|
+
execId: string;
|
|
165
|
+
pid: number;
|
|
166
|
+
startedAt: string;
|
|
167
|
+
ringBytes: number;
|
|
168
|
+
}
|
|
169
|
+
/** Status of one background exec — returned by `vm.bg.list` and `vm.bg.info`. */
|
|
170
|
+
interface BgExecInfo {
|
|
171
|
+
execId: string;
|
|
172
|
+
pid: number;
|
|
173
|
+
command: string;
|
|
174
|
+
args?: string[];
|
|
175
|
+
cwd?: string;
|
|
176
|
+
uid?: number;
|
|
177
|
+
startedAt: string;
|
|
178
|
+
running: boolean;
|
|
179
|
+
/** Present once the child has exited. */
|
|
180
|
+
exitCode?: number;
|
|
181
|
+
signal?: string;
|
|
182
|
+
endedAt?: string;
|
|
183
|
+
bytesWritten: number;
|
|
184
|
+
bytesDropped: number;
|
|
185
|
+
/** Next frame id the agent will emit on this exec's log ring. */
|
|
186
|
+
nextId: number;
|
|
187
|
+
ringBytes: number;
|
|
188
|
+
}
|
|
189
|
+
interface BgKillOptions {
|
|
190
|
+
/** Signal name (e.g. `TERM`, `KILL`, `HUP`). Default: `TERM`. */
|
|
191
|
+
signal?: string;
|
|
192
|
+
/** Grace period before the agent escalates to `SIGKILL`. Server default 5000ms. */
|
|
193
|
+
graceMs?: number;
|
|
194
|
+
}
|
|
195
|
+
interface BgKillResponse {
|
|
196
|
+
execId: string;
|
|
197
|
+
pid: number;
|
|
198
|
+
running: boolean;
|
|
199
|
+
signalSent: string;
|
|
200
|
+
}
|
|
201
|
+
interface BgWaitExitResponse {
|
|
202
|
+
execId: string;
|
|
203
|
+
running: boolean;
|
|
204
|
+
exitCode?: number;
|
|
205
|
+
signal?: string;
|
|
206
|
+
endedAt?: string;
|
|
207
|
+
timedOut: boolean;
|
|
208
|
+
}
|
|
209
|
+
interface BgDeleteResponse {
|
|
210
|
+
execId: string;
|
|
211
|
+
reaped: boolean;
|
|
212
|
+
}
|
|
213
|
+
interface BgLogOptions {
|
|
214
|
+
/** Stream live frames after replaying ring contents. */
|
|
215
|
+
follow?: boolean;
|
|
216
|
+
/** Start cursor at frame N. Lower than the live cursor replays history; higher waits (when `follow`). */
|
|
217
|
+
fromId?: number;
|
|
218
|
+
}
|
|
134
219
|
interface FSEntry {
|
|
135
220
|
name: string;
|
|
136
221
|
type: 'file' | 'directory' | 'symlink' | string;
|
|
@@ -456,6 +541,7 @@ declare class VM {
|
|
|
456
541
|
readonly createdAt?: string;
|
|
457
542
|
readonly arch?: string;
|
|
458
543
|
readonly fs: VMFileSystem;
|
|
544
|
+
readonly bg: VMBg;
|
|
459
545
|
private readonly transport;
|
|
460
546
|
constructor(transport: TransportClient, init: VMInit);
|
|
461
547
|
delete(): Promise<void>;
|
|
@@ -505,6 +591,57 @@ declare class VM {
|
|
|
505
591
|
}): Promise<ExecResultBinary>;
|
|
506
592
|
execBuffered(req: ExecRequest): Promise<ExecResult>;
|
|
507
593
|
}
|
|
594
|
+
/**
|
|
595
|
+
* Per-VM background-exec operations. A bg exec is detached at launch (its own
|
|
596
|
+
* session leader), survives client disconnect, and writes stdout/stderr into a
|
|
597
|
+
* per-process ring buffer on the agent. Manage one with the `execId` returned
|
|
598
|
+
* from `exec()` plus `info`, `logs`, `kill`, `wait`, `remove`. The ring stays
|
|
599
|
+
* allocated after the child exits — call `remove()` to free its budget.
|
|
600
|
+
*/
|
|
601
|
+
declare class VMBg {
|
|
602
|
+
private readonly transport;
|
|
603
|
+
private readonly hostname;
|
|
604
|
+
constructor(transport: TransportClient, hostname: string);
|
|
605
|
+
/**
|
|
606
|
+
* Launch a long-running process. `command` + `args` is the deterministic
|
|
607
|
+
* exec form (no shell). Set `shell: '/bin/bash'` (or similar) to opt in
|
|
608
|
+
* to shell semantics — `$VAR` expansion, globs, `&&`/`||`, etc.
|
|
609
|
+
*/
|
|
610
|
+
exec(req: BgExecRequest): Promise<BgExecResponse>;
|
|
611
|
+
/** All background execs the agent currently tracks (running + exited-not-reaped). */
|
|
612
|
+
list(): Promise<BgExecInfo[]>;
|
|
613
|
+
/** Latest status snapshot for one bg exec. Throws 404 if reaped or never existed. */
|
|
614
|
+
info(execId: string): Promise<BgExecInfo>;
|
|
615
|
+
/**
|
|
616
|
+
* NDJSON log stream. Yields one frame per log line — `started`, `stdout`,
|
|
617
|
+
* `stderr`, `exit`, plus optional `gap` frames if the ring evicted history
|
|
618
|
+
* before the requested cursor. Frames carry `data` base64-encoded; the SDK
|
|
619
|
+
* also populates `dataBytes` / `stdoutBytes` / `stderrBytes` Buffers.
|
|
620
|
+
*
|
|
621
|
+
* `follow: false` (default) replays from the cursor and ends when the ring
|
|
622
|
+
* is drained. `follow: true` keeps the stream open until the child exits or
|
|
623
|
+
* the caller breaks out.
|
|
624
|
+
*/
|
|
625
|
+
logs(execId: string, opts?: BgLogOptions): AsyncGenerator<ExecFrame, void, void>;
|
|
626
|
+
/**
|
|
627
|
+
* Signal a running bg exec. Default: SIGTERM with a 5 s grace period before
|
|
628
|
+
* the agent escalates to SIGKILL. No-op (running=false) if the child has
|
|
629
|
+
* already exited.
|
|
630
|
+
*/
|
|
631
|
+
kill(execId: string, opts?: BgKillOptions): Promise<BgKillResponse>;
|
|
632
|
+
/**
|
|
633
|
+
* Long-poll until the child exits or `timeoutSec` elapses. Returns
|
|
634
|
+
* `timedOut: true` if the deadline hit. Server default for `timeoutSec=0`
|
|
635
|
+
* is 30 s.
|
|
636
|
+
*/
|
|
637
|
+
wait(execId: string, timeoutSec?: number): Promise<BgWaitExitResponse>;
|
|
638
|
+
/**
|
|
639
|
+
* Reap a bg exec's ring buffer + registry entry. Does NOT kill a running
|
|
640
|
+
* process — pair with `kill()` for "stop and clean up". After remove,
|
|
641
|
+
* info/logs/kill/wait return 410 Gone.
|
|
642
|
+
*/
|
|
643
|
+
remove(execId: string): Promise<BgDeleteResponse>;
|
|
644
|
+
}
|
|
508
645
|
|
|
509
646
|
/**
|
|
510
647
|
* Top-level namespaces on SlicerClient: hostGroups, vms, secrets.
|
|
@@ -575,4 +712,4 @@ declare class SlicerClient {
|
|
|
575
712
|
getInfo(): Promise<SlicerInfo>;
|
|
576
713
|
}
|
|
577
714
|
|
|
578
|
-
export { type AddressMapping, type AgentHealth, type CreateSecretRequest, type CreateVMOptions, type CreateVMRequest, type CreateVMResponse, type DeleteResponse, type ExecFrame, type ExecRequest, type ExecResult, type ExecResultBinary, type ExecStdio, ExecStdioBase64, ExecStdioText, type FSEntry, type FSMkdirRequest, type FSWatchEvent, type FSWatchEventType, type FSWatchRequest, Forwarder, type ForwarderListener, type ForwarderOptions, GiB, type HostGroup, HostGroupsAPI, type ListOptions, MiB, NonRootUser, type Secret, SecretExistsError, SecretsAPI, type ShutdownRequest, SlicerAPIError, SlicerClient, type SlicerClientOptions, type SlicerInfo, type UpdateSecretRequest, VM, VMFileSystem, type VMInfo, type VMInit, type VMLogs, type VMSnapshot, type VMStat, VMsAPI, type WaitOptions, parseAddressMapping, resolveTransport };
|
|
715
|
+
export { type AddressMapping, type AgentHealth, type BgDeleteResponse, type BgExecInfo, type BgExecRequest, type BgExecResponse, type BgKillOptions, type BgKillResponse, type BgLogOptions, type BgWaitExitResponse, type CreateSecretRequest, type CreateVMOptions, type CreateVMRequest, type CreateVMResponse, type DeleteResponse, type ExecFrame, type ExecRequest, type ExecResult, type ExecResultBinary, type ExecStdio, ExecStdioBase64, ExecStdioText, type FSEntry, type FSMkdirRequest, type FSWatchEvent, type FSWatchEventType, type FSWatchRequest, Forwarder, type ForwarderListener, type ForwarderOptions, GiB, type HostGroup, HostGroupsAPI, type ListOptions, MiB, NonRootUser, type Secret, SecretExistsError, SecretsAPI, type ShutdownRequest, SlicerAPIError, SlicerClient, type SlicerClientOptions, type SlicerInfo, type UpdateSecretRequest, VM, VMBg, VMFileSystem, type VMInfo, type VMInit, type VMLogs, type VMSnapshot, type VMStat, VMsAPI, type WaitOptions, parseAddressMapping, resolveTransport };
|
package/dist/index.d.ts
CHANGED
|
@@ -131,6 +131,91 @@ interface ExecResultBinary {
|
|
|
131
131
|
exitCode: number;
|
|
132
132
|
error?: string;
|
|
133
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* Launch parameters for a background exec. Mirrors the Go SDK's
|
|
136
|
+
* `ExecBackgroundRequest`. The child is detached at launch and survives
|
|
137
|
+
* client disconnect; manage it via `vm.bg.list/info/logs/kill/wait/remove`.
|
|
138
|
+
*
|
|
139
|
+
* `command` + `args` is the always-correct deterministic form (matches the
|
|
140
|
+
* `--cmd` / `--arg` CLI flags). For `$VAR` expansion or shell operators set
|
|
141
|
+
* `shell` to a shell path (e.g. `/bin/bash`) and pass the script as
|
|
142
|
+
* `command`; the agent runs `<shell> -lc "<command>"` in that case.
|
|
143
|
+
*/
|
|
144
|
+
interface BgExecRequest {
|
|
145
|
+
command: string;
|
|
146
|
+
args?: string[];
|
|
147
|
+
env?: string[];
|
|
148
|
+
uid?: number;
|
|
149
|
+
gid?: number;
|
|
150
|
+
cwd?: string;
|
|
151
|
+
/**
|
|
152
|
+
* Empty (default): direct exec. Set to a shell path (e.g. `/bin/bash`) for
|
|
153
|
+
* `$VAR` expansion, globs, and shell operators. With a shell, bash auto-
|
|
154
|
+
* `exec`s the last simple command in `-c` scripts so the daemon is the
|
|
155
|
+
* tracked PID for typical cases. Multi-statement scripts that need clean
|
|
156
|
+
* tree should write `exec` themselves.
|
|
157
|
+
*/
|
|
158
|
+
shell?: string;
|
|
159
|
+
/** Per-process ring buffer cap in bytes. Zero means server default (1 MiB). */
|
|
160
|
+
ringBytes?: number;
|
|
161
|
+
}
|
|
162
|
+
/** Returned by `vm.bg.exec` on success. */
|
|
163
|
+
interface BgExecResponse {
|
|
164
|
+
execId: string;
|
|
165
|
+
pid: number;
|
|
166
|
+
startedAt: string;
|
|
167
|
+
ringBytes: number;
|
|
168
|
+
}
|
|
169
|
+
/** Status of one background exec — returned by `vm.bg.list` and `vm.bg.info`. */
|
|
170
|
+
interface BgExecInfo {
|
|
171
|
+
execId: string;
|
|
172
|
+
pid: number;
|
|
173
|
+
command: string;
|
|
174
|
+
args?: string[];
|
|
175
|
+
cwd?: string;
|
|
176
|
+
uid?: number;
|
|
177
|
+
startedAt: string;
|
|
178
|
+
running: boolean;
|
|
179
|
+
/** Present once the child has exited. */
|
|
180
|
+
exitCode?: number;
|
|
181
|
+
signal?: string;
|
|
182
|
+
endedAt?: string;
|
|
183
|
+
bytesWritten: number;
|
|
184
|
+
bytesDropped: number;
|
|
185
|
+
/** Next frame id the agent will emit on this exec's log ring. */
|
|
186
|
+
nextId: number;
|
|
187
|
+
ringBytes: number;
|
|
188
|
+
}
|
|
189
|
+
interface BgKillOptions {
|
|
190
|
+
/** Signal name (e.g. `TERM`, `KILL`, `HUP`). Default: `TERM`. */
|
|
191
|
+
signal?: string;
|
|
192
|
+
/** Grace period before the agent escalates to `SIGKILL`. Server default 5000ms. */
|
|
193
|
+
graceMs?: number;
|
|
194
|
+
}
|
|
195
|
+
interface BgKillResponse {
|
|
196
|
+
execId: string;
|
|
197
|
+
pid: number;
|
|
198
|
+
running: boolean;
|
|
199
|
+
signalSent: string;
|
|
200
|
+
}
|
|
201
|
+
interface BgWaitExitResponse {
|
|
202
|
+
execId: string;
|
|
203
|
+
running: boolean;
|
|
204
|
+
exitCode?: number;
|
|
205
|
+
signal?: string;
|
|
206
|
+
endedAt?: string;
|
|
207
|
+
timedOut: boolean;
|
|
208
|
+
}
|
|
209
|
+
interface BgDeleteResponse {
|
|
210
|
+
execId: string;
|
|
211
|
+
reaped: boolean;
|
|
212
|
+
}
|
|
213
|
+
interface BgLogOptions {
|
|
214
|
+
/** Stream live frames after replaying ring contents. */
|
|
215
|
+
follow?: boolean;
|
|
216
|
+
/** Start cursor at frame N. Lower than the live cursor replays history; higher waits (when `follow`). */
|
|
217
|
+
fromId?: number;
|
|
218
|
+
}
|
|
134
219
|
interface FSEntry {
|
|
135
220
|
name: string;
|
|
136
221
|
type: 'file' | 'directory' | 'symlink' | string;
|
|
@@ -456,6 +541,7 @@ declare class VM {
|
|
|
456
541
|
readonly createdAt?: string;
|
|
457
542
|
readonly arch?: string;
|
|
458
543
|
readonly fs: VMFileSystem;
|
|
544
|
+
readonly bg: VMBg;
|
|
459
545
|
private readonly transport;
|
|
460
546
|
constructor(transport: TransportClient, init: VMInit);
|
|
461
547
|
delete(): Promise<void>;
|
|
@@ -505,6 +591,57 @@ declare class VM {
|
|
|
505
591
|
}): Promise<ExecResultBinary>;
|
|
506
592
|
execBuffered(req: ExecRequest): Promise<ExecResult>;
|
|
507
593
|
}
|
|
594
|
+
/**
|
|
595
|
+
* Per-VM background-exec operations. A bg exec is detached at launch (its own
|
|
596
|
+
* session leader), survives client disconnect, and writes stdout/stderr into a
|
|
597
|
+
* per-process ring buffer on the agent. Manage one with the `execId` returned
|
|
598
|
+
* from `exec()` plus `info`, `logs`, `kill`, `wait`, `remove`. The ring stays
|
|
599
|
+
* allocated after the child exits — call `remove()` to free its budget.
|
|
600
|
+
*/
|
|
601
|
+
declare class VMBg {
|
|
602
|
+
private readonly transport;
|
|
603
|
+
private readonly hostname;
|
|
604
|
+
constructor(transport: TransportClient, hostname: string);
|
|
605
|
+
/**
|
|
606
|
+
* Launch a long-running process. `command` + `args` is the deterministic
|
|
607
|
+
* exec form (no shell). Set `shell: '/bin/bash'` (or similar) to opt in
|
|
608
|
+
* to shell semantics — `$VAR` expansion, globs, `&&`/`||`, etc.
|
|
609
|
+
*/
|
|
610
|
+
exec(req: BgExecRequest): Promise<BgExecResponse>;
|
|
611
|
+
/** All background execs the agent currently tracks (running + exited-not-reaped). */
|
|
612
|
+
list(): Promise<BgExecInfo[]>;
|
|
613
|
+
/** Latest status snapshot for one bg exec. Throws 404 if reaped or never existed. */
|
|
614
|
+
info(execId: string): Promise<BgExecInfo>;
|
|
615
|
+
/**
|
|
616
|
+
* NDJSON log stream. Yields one frame per log line — `started`, `stdout`,
|
|
617
|
+
* `stderr`, `exit`, plus optional `gap` frames if the ring evicted history
|
|
618
|
+
* before the requested cursor. Frames carry `data` base64-encoded; the SDK
|
|
619
|
+
* also populates `dataBytes` / `stdoutBytes` / `stderrBytes` Buffers.
|
|
620
|
+
*
|
|
621
|
+
* `follow: false` (default) replays from the cursor and ends when the ring
|
|
622
|
+
* is drained. `follow: true` keeps the stream open until the child exits or
|
|
623
|
+
* the caller breaks out.
|
|
624
|
+
*/
|
|
625
|
+
logs(execId: string, opts?: BgLogOptions): AsyncGenerator<ExecFrame, void, void>;
|
|
626
|
+
/**
|
|
627
|
+
* Signal a running bg exec. Default: SIGTERM with a 5 s grace period before
|
|
628
|
+
* the agent escalates to SIGKILL. No-op (running=false) if the child has
|
|
629
|
+
* already exited.
|
|
630
|
+
*/
|
|
631
|
+
kill(execId: string, opts?: BgKillOptions): Promise<BgKillResponse>;
|
|
632
|
+
/**
|
|
633
|
+
* Long-poll until the child exits or `timeoutSec` elapses. Returns
|
|
634
|
+
* `timedOut: true` if the deadline hit. Server default for `timeoutSec=0`
|
|
635
|
+
* is 30 s.
|
|
636
|
+
*/
|
|
637
|
+
wait(execId: string, timeoutSec?: number): Promise<BgWaitExitResponse>;
|
|
638
|
+
/**
|
|
639
|
+
* Reap a bg exec's ring buffer + registry entry. Does NOT kill a running
|
|
640
|
+
* process — pair with `kill()` for "stop and clean up". After remove,
|
|
641
|
+
* info/logs/kill/wait return 410 Gone.
|
|
642
|
+
*/
|
|
643
|
+
remove(execId: string): Promise<BgDeleteResponse>;
|
|
644
|
+
}
|
|
508
645
|
|
|
509
646
|
/**
|
|
510
647
|
* Top-level namespaces on SlicerClient: hostGroups, vms, secrets.
|
|
@@ -575,4 +712,4 @@ declare class SlicerClient {
|
|
|
575
712
|
getInfo(): Promise<SlicerInfo>;
|
|
576
713
|
}
|
|
577
714
|
|
|
578
|
-
export { type AddressMapping, type AgentHealth, type CreateSecretRequest, type CreateVMOptions, type CreateVMRequest, type CreateVMResponse, type DeleteResponse, type ExecFrame, type ExecRequest, type ExecResult, type ExecResultBinary, type ExecStdio, ExecStdioBase64, ExecStdioText, type FSEntry, type FSMkdirRequest, type FSWatchEvent, type FSWatchEventType, type FSWatchRequest, Forwarder, type ForwarderListener, type ForwarderOptions, GiB, type HostGroup, HostGroupsAPI, type ListOptions, MiB, NonRootUser, type Secret, SecretExistsError, SecretsAPI, type ShutdownRequest, SlicerAPIError, SlicerClient, type SlicerClientOptions, type SlicerInfo, type UpdateSecretRequest, VM, VMFileSystem, type VMInfo, type VMInit, type VMLogs, type VMSnapshot, type VMStat, VMsAPI, type WaitOptions, parseAddressMapping, resolveTransport };
|
|
715
|
+
export { type AddressMapping, type AgentHealth, type BgDeleteResponse, type BgExecInfo, type BgExecRequest, type BgExecResponse, type BgKillOptions, type BgKillResponse, type BgLogOptions, type BgWaitExitResponse, type CreateSecretRequest, type CreateVMOptions, type CreateVMRequest, type CreateVMResponse, type DeleteResponse, type ExecFrame, type ExecRequest, type ExecResult, type ExecResultBinary, type ExecStdio, ExecStdioBase64, ExecStdioText, type FSEntry, type FSMkdirRequest, type FSWatchEvent, type FSWatchEventType, type FSWatchRequest, Forwarder, type ForwarderListener, type ForwarderOptions, GiB, type HostGroup, HostGroupsAPI, type ListOptions, MiB, NonRootUser, type Secret, SecretExistsError, SecretsAPI, type ShutdownRequest, SlicerAPIError, SlicerClient, type SlicerClientOptions, type SlicerInfo, type UpdateSecretRequest, VM, VMBg, VMFileSystem, type VMInfo, type VMInit, type VMLogs, type VMSnapshot, type VMStat, VMsAPI, type WaitOptions, parseAddressMapping, resolveTransport };
|
package/dist/index.js
CHANGED
|
@@ -734,6 +734,7 @@ var VM = class {
|
|
|
734
734
|
createdAt;
|
|
735
735
|
arch;
|
|
736
736
|
fs;
|
|
737
|
+
bg;
|
|
737
738
|
transport;
|
|
738
739
|
constructor(transport, init) {
|
|
739
740
|
this.transport = transport;
|
|
@@ -743,6 +744,7 @@ var VM = class {
|
|
|
743
744
|
if (init.createdAt !== void 0) this.createdAt = init.createdAt;
|
|
744
745
|
if (init.arch !== void 0) this.arch = init.arch;
|
|
745
746
|
this.fs = new VMFileSystem(transport, this.hostname);
|
|
747
|
+
this.bg = new VMBg(transport, this.hostname);
|
|
746
748
|
}
|
|
747
749
|
// --- lifecycle --------------------------------------------------------
|
|
748
750
|
async delete() {
|
|
@@ -944,6 +946,169 @@ function sleep(ms) {
|
|
|
944
946
|
function errMsg(e) {
|
|
945
947
|
return e instanceof Error ? e.message : String(e);
|
|
946
948
|
}
|
|
949
|
+
var VMBg = class {
|
|
950
|
+
constructor(transport, hostname) {
|
|
951
|
+
this.transport = transport;
|
|
952
|
+
this.hostname = hostname;
|
|
953
|
+
}
|
|
954
|
+
transport;
|
|
955
|
+
hostname;
|
|
956
|
+
/**
|
|
957
|
+
* Launch a long-running process. `command` + `args` is the deterministic
|
|
958
|
+
* exec form (no shell). Set `shell: '/bin/bash'` (or similar) to opt in
|
|
959
|
+
* to shell semantics — `$VAR` expansion, globs, `&&`/`||`, etc.
|
|
960
|
+
*/
|
|
961
|
+
async exec(req) {
|
|
962
|
+
if (!req.command) throw new Error("vm.bg.exec: command is required");
|
|
963
|
+
const q = new URLSearchParams();
|
|
964
|
+
q.set("background", "true");
|
|
965
|
+
q.set("cmd", req.command);
|
|
966
|
+
for (const a of req.args ?? []) q.append("args", a);
|
|
967
|
+
for (const e of req.env ?? []) q.append("env", e);
|
|
968
|
+
if (req.uid !== void 0 && req.uid !== 0) q.set("uid", String(req.uid));
|
|
969
|
+
if (req.gid !== void 0 && req.gid !== 0) q.set("gid", String(req.gid));
|
|
970
|
+
if (req.shell) q.set("shell", req.shell);
|
|
971
|
+
if (req.cwd) q.set("cwd", req.cwd);
|
|
972
|
+
if (req.ringBytes !== void 0 && req.ringBytes > 0) {
|
|
973
|
+
q.set("ring_bytes", String(req.ringBytes));
|
|
974
|
+
}
|
|
975
|
+
q.set("stdio", "base64");
|
|
976
|
+
const path3 = `/vm/${encodeURIComponent(this.hostname)}/exec?${q.toString()}`;
|
|
977
|
+
const wire = await this.transport.request("POST", path3);
|
|
978
|
+
return bgExecResponseFromWire(wire);
|
|
979
|
+
}
|
|
980
|
+
/** All background execs the agent currently tracks (running + exited-not-reaped). */
|
|
981
|
+
async list() {
|
|
982
|
+
const wire = await this.transport.request(
|
|
983
|
+
"GET",
|
|
984
|
+
`/vm/${encodeURIComponent(this.hostname)}/exec`
|
|
985
|
+
);
|
|
986
|
+
return (wire ?? []).map(bgExecInfoFromWire);
|
|
987
|
+
}
|
|
988
|
+
/** Latest status snapshot for one bg exec. Throws 404 if reaped or never existed. */
|
|
989
|
+
async info(execId) {
|
|
990
|
+
const wire = await this.transport.request(
|
|
991
|
+
"GET",
|
|
992
|
+
`/vm/${encodeURIComponent(this.hostname)}/exec/${encodeURIComponent(execId)}`
|
|
993
|
+
);
|
|
994
|
+
return bgExecInfoFromWire(wire);
|
|
995
|
+
}
|
|
996
|
+
/**
|
|
997
|
+
* NDJSON log stream. Yields one frame per log line — `started`, `stdout`,
|
|
998
|
+
* `stderr`, `exit`, plus optional `gap` frames if the ring evicted history
|
|
999
|
+
* before the requested cursor. Frames carry `data` base64-encoded; the SDK
|
|
1000
|
+
* also populates `dataBytes` / `stdoutBytes` / `stderrBytes` Buffers.
|
|
1001
|
+
*
|
|
1002
|
+
* `follow: false` (default) replays from the cursor and ends when the ring
|
|
1003
|
+
* is drained. `follow: true` keeps the stream open until the child exits or
|
|
1004
|
+
* the caller breaks out.
|
|
1005
|
+
*/
|
|
1006
|
+
async *logs(execId, opts = {}) {
|
|
1007
|
+
const q = new URLSearchParams();
|
|
1008
|
+
if (opts.follow) q.set("follow", "true");
|
|
1009
|
+
if (opts.fromId !== void 0 && opts.fromId > 0) q.set("from_id", String(opts.fromId));
|
|
1010
|
+
const path3 = `/vm/${encodeURIComponent(this.hostname)}/exec/${encodeURIComponent(execId)}/logs` + (q.toString() ? `?${q.toString()}` : "");
|
|
1011
|
+
for await (const raw of this.transport.requestNDJSON("GET", path3)) {
|
|
1012
|
+
const frame = normalizeExecFrame(raw);
|
|
1013
|
+
if (frame.encoding === "base64") {
|
|
1014
|
+
if (frame.data) frame.dataBytes = Buffer.from(frame.data, "base64");
|
|
1015
|
+
if (frame.stdout) frame.stdoutBytes = Buffer.from(frame.stdout, "base64");
|
|
1016
|
+
if (frame.stderr) frame.stderrBytes = Buffer.from(frame.stderr, "base64");
|
|
1017
|
+
}
|
|
1018
|
+
yield frame;
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
/**
|
|
1022
|
+
* Signal a running bg exec. Default: SIGTERM with a 5 s grace period before
|
|
1023
|
+
* the agent escalates to SIGKILL. No-op (running=false) if the child has
|
|
1024
|
+
* already exited.
|
|
1025
|
+
*/
|
|
1026
|
+
async kill(execId, opts = {}) {
|
|
1027
|
+
const body = {};
|
|
1028
|
+
if (opts.signal) body.signal = opts.signal;
|
|
1029
|
+
if (opts.graceMs !== void 0) body.grace_ms = opts.graceMs;
|
|
1030
|
+
const wire = await this.transport.request(
|
|
1031
|
+
"POST",
|
|
1032
|
+
`/vm/${encodeURIComponent(this.hostname)}/exec/${encodeURIComponent(execId)}/kill`,
|
|
1033
|
+
body
|
|
1034
|
+
);
|
|
1035
|
+
return bgKillResponseFromWire(wire);
|
|
1036
|
+
}
|
|
1037
|
+
/**
|
|
1038
|
+
* Long-poll until the child exits or `timeoutSec` elapses. Returns
|
|
1039
|
+
* `timedOut: true` if the deadline hit. Server default for `timeoutSec=0`
|
|
1040
|
+
* is 30 s.
|
|
1041
|
+
*/
|
|
1042
|
+
async wait(execId, timeoutSec = 0) {
|
|
1043
|
+
const q = new URLSearchParams();
|
|
1044
|
+
if (timeoutSec > 0) q.set("timeout", String(timeoutSec));
|
|
1045
|
+
const path3 = `/vm/${encodeURIComponent(this.hostname)}/exec/${encodeURIComponent(execId)}/wait-exit` + (q.toString() ? `?${q.toString()}` : "");
|
|
1046
|
+
const wire = await this.transport.request("GET", path3);
|
|
1047
|
+
return bgWaitExitFromWire(wire);
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1050
|
+
* Reap a bg exec's ring buffer + registry entry. Does NOT kill a running
|
|
1051
|
+
* process — pair with `kill()` for "stop and clean up". After remove,
|
|
1052
|
+
* info/logs/kill/wait return 410 Gone.
|
|
1053
|
+
*/
|
|
1054
|
+
async remove(execId) {
|
|
1055
|
+
const wire = await this.transport.request(
|
|
1056
|
+
"DELETE",
|
|
1057
|
+
`/vm/${encodeURIComponent(this.hostname)}/exec/${encodeURIComponent(execId)}`
|
|
1058
|
+
);
|
|
1059
|
+
return bgDeleteFromWire(wire);
|
|
1060
|
+
}
|
|
1061
|
+
};
|
|
1062
|
+
function bgExecResponseFromWire(w) {
|
|
1063
|
+
return {
|
|
1064
|
+
execId: w.exec_id,
|
|
1065
|
+
pid: w.pid,
|
|
1066
|
+
startedAt: w.started_at,
|
|
1067
|
+
ringBytes: w.ring_bytes
|
|
1068
|
+
};
|
|
1069
|
+
}
|
|
1070
|
+
function bgExecInfoFromWire(w) {
|
|
1071
|
+
const out = {
|
|
1072
|
+
execId: w.exec_id,
|
|
1073
|
+
pid: w.pid,
|
|
1074
|
+
command: w.command,
|
|
1075
|
+
startedAt: w.started_at,
|
|
1076
|
+
running: w.running,
|
|
1077
|
+
bytesWritten: w.bytes_written,
|
|
1078
|
+
bytesDropped: w.bytes_dropped,
|
|
1079
|
+
nextId: w.next_id,
|
|
1080
|
+
ringBytes: w.ring_bytes
|
|
1081
|
+
};
|
|
1082
|
+
if (w.args !== void 0) out.args = w.args;
|
|
1083
|
+
if (w.cwd !== void 0) out.cwd = w.cwd;
|
|
1084
|
+
if (w.uid !== void 0) out.uid = w.uid;
|
|
1085
|
+
if (w.exit_code !== void 0) out.exitCode = w.exit_code;
|
|
1086
|
+
if (w.signal !== void 0) out.signal = w.signal;
|
|
1087
|
+
if (w.ended_at !== void 0) out.endedAt = w.ended_at;
|
|
1088
|
+
return out;
|
|
1089
|
+
}
|
|
1090
|
+
function bgKillResponseFromWire(w) {
|
|
1091
|
+
return {
|
|
1092
|
+
execId: w.exec_id,
|
|
1093
|
+
pid: w.pid,
|
|
1094
|
+
running: w.running,
|
|
1095
|
+
signalSent: w.signal_sent
|
|
1096
|
+
};
|
|
1097
|
+
}
|
|
1098
|
+
function bgWaitExitFromWire(w) {
|
|
1099
|
+
const out = {
|
|
1100
|
+
execId: w.exec_id,
|
|
1101
|
+
running: w.running,
|
|
1102
|
+
timedOut: w.timed_out
|
|
1103
|
+
};
|
|
1104
|
+
if (w.exit_code !== void 0) out.exitCode = w.exit_code;
|
|
1105
|
+
if (w.signal !== void 0) out.signal = w.signal;
|
|
1106
|
+
if (w.ended_at !== void 0) out.endedAt = w.ended_at;
|
|
1107
|
+
return out;
|
|
1108
|
+
}
|
|
1109
|
+
function bgDeleteFromWire(w) {
|
|
1110
|
+
return { execId: w.exec_id, reaped: w.reaped };
|
|
1111
|
+
}
|
|
947
1112
|
|
|
948
1113
|
// src/namespaces.ts
|
|
949
1114
|
var HostGroupsAPI = class {
|
|
@@ -1113,6 +1278,6 @@ var SlicerClient = class _SlicerClient {
|
|
|
1113
1278
|
}
|
|
1114
1279
|
};
|
|
1115
1280
|
|
|
1116
|
-
export { ExecStdioBase64, ExecStdioText, Forwarder, GiB, HostGroupsAPI, MiB, NonRootUser, SecretExistsError, SecretsAPI, SlicerAPIError, SlicerClient, VM, VMFileSystem, VMsAPI, parseAddressMapping, resolveTransport };
|
|
1281
|
+
export { ExecStdioBase64, ExecStdioText, Forwarder, GiB, HostGroupsAPI, MiB, NonRootUser, SecretExistsError, SecretsAPI, SlicerAPIError, SlicerClient, VM, VMBg, VMFileSystem, VMsAPI, parseAddressMapping, resolveTransport };
|
|
1117
1282
|
//# sourceMappingURL=index.js.map
|
|
1118
1283
|
//# sourceMappingURL=index.js.map
|