@alibaba-group/opensandbox 0.1.4 → 0.1.6
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 +102 -34
- package/dist/{chunk-OYTPXLWE.js → chunk-AFWIGM3C.js} +139 -29
- package/dist/chunk-AFWIGM3C.js.map +1 -0
- package/dist/cjs/index.cjs +277 -53
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/internal.cjs +137 -28
- package/dist/cjs/internal.cjs.map +1 -1
- package/dist/index.d.ts +33 -8
- package/dist/index.js +140 -25
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +292 -15
- package/dist/internal.js +1 -1
- package/dist/{sandboxes-Dc0G4ShU.d.ts → sandboxes-C-AZxcv6.d.ts} +234 -158
- package/package.json +4 -2
- package/src/adapters/commandsAdapter.ts +189 -27
- package/src/adapters/egressAdapter.ts +46 -0
- package/src/adapters/sandboxesAdapter.ts +8 -3
- package/src/api/egress.ts +184 -0
- package/src/api/execd.ts +216 -1
- package/src/api/lifecycle.ts +59 -13
- package/src/core/constants.ts +2 -1
- package/src/core/exceptions.ts +5 -4
- package/src/factory/adapterFactory.ts +13 -1
- package/src/factory/defaultAdapterFactory.ts +27 -2
- package/src/index.ts +3 -1
- package/src/models/execd.ts +12 -0
- package/src/models/execution.ts +2 -1
- package/src/models/sandboxes.ts +52 -7
- package/src/openapi/egressClient.ts +45 -0
- package/src/sandbox.ts +102 -25
- package/src/services/egress.ts +27 -0
- package/src/services/execdCommands.ts +27 -1
- package/src/services/sandboxes.ts +1 -1
- package/dist/chunk-OYTPXLWE.js.map +0 -1
package/src/api/execd.ts
CHANGED
|
@@ -17,6 +17,13 @@
|
|
|
17
17
|
* Do not make direct changes to the file.
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* NOTE: The session-related path types and operations in this file (e.g. /session, runInSession)
|
|
23
|
+
* are generated from the execd OpenAPI spec. They are not the recommended runtime entry point.
|
|
24
|
+
* Use `sandbox.commands.createSession()`, `sandbox.commands.runInSession()`, and
|
|
25
|
+
* `sandbox.commands.deleteSession()` instead.
|
|
26
|
+
*/
|
|
20
27
|
export interface paths {
|
|
21
28
|
"/ping": {
|
|
22
29
|
parameters: {
|
|
@@ -143,6 +150,71 @@ export interface paths {
|
|
|
143
150
|
patch?: never;
|
|
144
151
|
trace?: never;
|
|
145
152
|
};
|
|
153
|
+
"/session": {
|
|
154
|
+
parameters: {
|
|
155
|
+
query?: never;
|
|
156
|
+
header?: never;
|
|
157
|
+
path?: never;
|
|
158
|
+
cookie?: never;
|
|
159
|
+
};
|
|
160
|
+
get?: never;
|
|
161
|
+
put?: never;
|
|
162
|
+
/**
|
|
163
|
+
* Create bash session (create_session)
|
|
164
|
+
* @description Creates a new bash session and returns a session ID for subsequent run_in_session requests.
|
|
165
|
+
* The session maintains shell state (e.g. working directory, environment) across multiple
|
|
166
|
+
* code executions. Request body is optional; an empty body uses default options (no cwd override).
|
|
167
|
+
*/
|
|
168
|
+
post: operations["createSession"];
|
|
169
|
+
delete?: never;
|
|
170
|
+
options?: never;
|
|
171
|
+
head?: never;
|
|
172
|
+
patch?: never;
|
|
173
|
+
trace?: never;
|
|
174
|
+
};
|
|
175
|
+
"/session/{sessionId}/run": {
|
|
176
|
+
parameters: {
|
|
177
|
+
query?: never;
|
|
178
|
+
header?: never;
|
|
179
|
+
path?: never;
|
|
180
|
+
cookie?: never;
|
|
181
|
+
};
|
|
182
|
+
get?: never;
|
|
183
|
+
put?: never;
|
|
184
|
+
/**
|
|
185
|
+
* Run command in bash session (run_in_session)
|
|
186
|
+
* @description Executes a shell command in an existing bash session and streams the output in real-time via SSE
|
|
187
|
+
* (Server-Sent Events). The session must have been created by create_session. Supports
|
|
188
|
+
* optional working directory override and timeout (milliseconds).
|
|
189
|
+
*/
|
|
190
|
+
post: operations["runInSession"];
|
|
191
|
+
delete?: never;
|
|
192
|
+
options?: never;
|
|
193
|
+
head?: never;
|
|
194
|
+
patch?: never;
|
|
195
|
+
trace?: never;
|
|
196
|
+
};
|
|
197
|
+
"/session/{sessionId}": {
|
|
198
|
+
parameters: {
|
|
199
|
+
query?: never;
|
|
200
|
+
header?: never;
|
|
201
|
+
path?: never;
|
|
202
|
+
cookie?: never;
|
|
203
|
+
};
|
|
204
|
+
get?: never;
|
|
205
|
+
put?: never;
|
|
206
|
+
post?: never;
|
|
207
|
+
/**
|
|
208
|
+
* Delete bash session (delete_session)
|
|
209
|
+
* @description Deletes an existing bash session by ID. Terminates the underlying shell process
|
|
210
|
+
* and releases resources. The session ID must have been returned by create_session.
|
|
211
|
+
*/
|
|
212
|
+
delete: operations["deleteSession"];
|
|
213
|
+
options?: never;
|
|
214
|
+
head?: never;
|
|
215
|
+
patch?: never;
|
|
216
|
+
trace?: never;
|
|
217
|
+
};
|
|
146
218
|
"/command": {
|
|
147
219
|
parameters: {
|
|
148
220
|
query?: never;
|
|
@@ -158,7 +230,8 @@ export interface paths {
|
|
|
158
230
|
* The command can run in foreground or background mode. The response includes stdout, stderr,
|
|
159
231
|
* execution status, and completion events.
|
|
160
232
|
* Optionally specify `timeout` (milliseconds) to enforce a maximum runtime; the server will
|
|
161
|
-
* terminate the process when the timeout is reached.
|
|
233
|
+
* terminate the process when the timeout is reached. You can also pass `uid`/`gid` to run
|
|
234
|
+
* with specific user/group IDs, and `envs` to inject environment variables.
|
|
162
235
|
*/
|
|
163
236
|
post: operations["runCommand"];
|
|
164
237
|
/**
|
|
@@ -471,6 +544,41 @@ export interface paths {
|
|
|
471
544
|
export type webhooks = Record<string, never>;
|
|
472
545
|
export interface components {
|
|
473
546
|
schemas: {
|
|
547
|
+
/** @description Request to create a bash session (optional body; empty treated as defaults) */
|
|
548
|
+
CreateSessionRequest: {
|
|
549
|
+
/**
|
|
550
|
+
* @description Working directory for the session (optional)
|
|
551
|
+
* @example /workspace
|
|
552
|
+
*/
|
|
553
|
+
cwd?: string;
|
|
554
|
+
};
|
|
555
|
+
/** @description Response for create_session */
|
|
556
|
+
CreateSessionResponse: {
|
|
557
|
+
/**
|
|
558
|
+
* @description Unique session ID for run_in_session and delete_session
|
|
559
|
+
* @example session-abc123
|
|
560
|
+
*/
|
|
561
|
+
session_id: string;
|
|
562
|
+
};
|
|
563
|
+
/** @description Request to run a command in an existing bash session */
|
|
564
|
+
RunInSessionRequest: {
|
|
565
|
+
/**
|
|
566
|
+
* @description Shell command to execute in the session
|
|
567
|
+
* @example echo "Hello"
|
|
568
|
+
*/
|
|
569
|
+
command: string;
|
|
570
|
+
/**
|
|
571
|
+
* @description Working directory override for this run (optional)
|
|
572
|
+
* @example /workspace
|
|
573
|
+
*/
|
|
574
|
+
cwd?: string;
|
|
575
|
+
/**
|
|
576
|
+
* Format: int64
|
|
577
|
+
* @description Maximum execution time in milliseconds (optional; server may not enforce if omitted)
|
|
578
|
+
* @example 30000
|
|
579
|
+
*/
|
|
580
|
+
timeout?: number;
|
|
581
|
+
};
|
|
474
582
|
/** @description Request to create a code execution context */
|
|
475
583
|
CodeContextRequest: {
|
|
476
584
|
/**
|
|
@@ -527,6 +635,28 @@ export interface components {
|
|
|
527
635
|
* @example 60000
|
|
528
636
|
*/
|
|
529
637
|
timeout?: number;
|
|
638
|
+
/**
|
|
639
|
+
* Format: int32
|
|
640
|
+
* @description Unix user ID used to run the command. If `gid` is provided, `uid` is required.
|
|
641
|
+
* @example 1000
|
|
642
|
+
*/
|
|
643
|
+
uid?: number;
|
|
644
|
+
/**
|
|
645
|
+
* Format: int32
|
|
646
|
+
* @description Unix group ID used to run the command. Requires `uid` to be provided.
|
|
647
|
+
* @example 1000
|
|
648
|
+
*/
|
|
649
|
+
gid?: number;
|
|
650
|
+
/**
|
|
651
|
+
* @description Environment variables injected into the command process.
|
|
652
|
+
* @example {
|
|
653
|
+
* "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
|
654
|
+
* "PYTHONUNBUFFERED": "1"
|
|
655
|
+
* }
|
|
656
|
+
*/
|
|
657
|
+
envs?: {
|
|
658
|
+
[key: string]: string;
|
|
659
|
+
};
|
|
530
660
|
};
|
|
531
661
|
/** @description Command execution status (foreground or background) */
|
|
532
662
|
CommandStatusResponse: {
|
|
@@ -1046,6 +1176,91 @@ export interface operations {
|
|
|
1046
1176
|
500: components["responses"]["InternalServerError"];
|
|
1047
1177
|
};
|
|
1048
1178
|
};
|
|
1179
|
+
createSession: {
|
|
1180
|
+
parameters: {
|
|
1181
|
+
query?: never;
|
|
1182
|
+
header?: never;
|
|
1183
|
+
path?: never;
|
|
1184
|
+
cookie?: never;
|
|
1185
|
+
};
|
|
1186
|
+
requestBody?: {
|
|
1187
|
+
content: {
|
|
1188
|
+
"application/json": components["schemas"]["CreateSessionRequest"];
|
|
1189
|
+
};
|
|
1190
|
+
};
|
|
1191
|
+
responses: {
|
|
1192
|
+
/** @description Session created successfully */
|
|
1193
|
+
200: {
|
|
1194
|
+
headers: {
|
|
1195
|
+
[name: string]: unknown;
|
|
1196
|
+
};
|
|
1197
|
+
content: {
|
|
1198
|
+
"application/json": components["schemas"]["CreateSessionResponse"];
|
|
1199
|
+
};
|
|
1200
|
+
};
|
|
1201
|
+
400: components["responses"]["BadRequest"];
|
|
1202
|
+
500: components["responses"]["InternalServerError"];
|
|
1203
|
+
};
|
|
1204
|
+
};
|
|
1205
|
+
runInSession: {
|
|
1206
|
+
parameters: {
|
|
1207
|
+
query?: never;
|
|
1208
|
+
header?: never;
|
|
1209
|
+
path: {
|
|
1210
|
+
/**
|
|
1211
|
+
* @description Session ID returned by create_session
|
|
1212
|
+
* @example session-abc123
|
|
1213
|
+
*/
|
|
1214
|
+
sessionId: string;
|
|
1215
|
+
};
|
|
1216
|
+
cookie?: never;
|
|
1217
|
+
};
|
|
1218
|
+
requestBody: {
|
|
1219
|
+
content: {
|
|
1220
|
+
"application/json": components["schemas"]["RunInSessionRequest"];
|
|
1221
|
+
};
|
|
1222
|
+
};
|
|
1223
|
+
responses: {
|
|
1224
|
+
/** @description Stream of execution events */
|
|
1225
|
+
200: {
|
|
1226
|
+
headers: {
|
|
1227
|
+
[name: string]: unknown;
|
|
1228
|
+
};
|
|
1229
|
+
content: {
|
|
1230
|
+
"text/event-stream": components["schemas"]["ServerStreamEvent"];
|
|
1231
|
+
};
|
|
1232
|
+
};
|
|
1233
|
+
400: components["responses"]["BadRequest"];
|
|
1234
|
+
500: components["responses"]["InternalServerError"];
|
|
1235
|
+
};
|
|
1236
|
+
};
|
|
1237
|
+
deleteSession: {
|
|
1238
|
+
parameters: {
|
|
1239
|
+
query?: never;
|
|
1240
|
+
header?: never;
|
|
1241
|
+
path: {
|
|
1242
|
+
/**
|
|
1243
|
+
* @description Session ID to delete
|
|
1244
|
+
* @example session-abc123
|
|
1245
|
+
*/
|
|
1246
|
+
sessionId: string;
|
|
1247
|
+
};
|
|
1248
|
+
cookie?: never;
|
|
1249
|
+
};
|
|
1250
|
+
requestBody?: never;
|
|
1251
|
+
responses: {
|
|
1252
|
+
/** @description Session deleted successfully */
|
|
1253
|
+
200: {
|
|
1254
|
+
headers: {
|
|
1255
|
+
[name: string]: unknown;
|
|
1256
|
+
};
|
|
1257
|
+
content?: never;
|
|
1258
|
+
};
|
|
1259
|
+
400: components["responses"]["BadRequest"];
|
|
1260
|
+
404: components["responses"]["NotFound"];
|
|
1261
|
+
500: components["responses"]["InternalServerError"];
|
|
1262
|
+
};
|
|
1263
|
+
};
|
|
1049
1264
|
runCommand: {
|
|
1050
1265
|
parameters: {
|
|
1051
1266
|
query?: never;
|
package/src/api/lifecycle.ts
CHANGED
|
@@ -470,9 +470,9 @@ export interface components {
|
|
|
470
470
|
};
|
|
471
471
|
/**
|
|
472
472
|
* Format: date-time
|
|
473
|
-
* @description Timestamp when sandbox will auto-terminate
|
|
473
|
+
* @description Timestamp when sandbox will auto-terminate. Omitted when manual cleanup is enabled.
|
|
474
474
|
*/
|
|
475
|
-
expiresAt
|
|
475
|
+
expiresAt?: string;
|
|
476
476
|
/**
|
|
477
477
|
* Format: date-time
|
|
478
478
|
* @description Sandbox creation timestamp
|
|
@@ -503,9 +503,9 @@ export interface components {
|
|
|
503
503
|
entrypoint: string[];
|
|
504
504
|
/**
|
|
505
505
|
* Format: date-time
|
|
506
|
-
* @description Timestamp when sandbox will auto-terminate
|
|
506
|
+
* @description Timestamp when sandbox will auto-terminate. Omitted when manual cleanup is enabled.
|
|
507
507
|
*/
|
|
508
|
-
expiresAt
|
|
508
|
+
expiresAt?: string;
|
|
509
509
|
/**
|
|
510
510
|
* Format: date-time
|
|
511
511
|
* @description Sandbox creation timestamp
|
|
@@ -588,9 +588,12 @@ export interface components {
|
|
|
588
588
|
image: components["schemas"]["ImageSpec"];
|
|
589
589
|
/**
|
|
590
590
|
* @description Sandbox timeout in seconds. The sandbox will automatically terminate after this duration.
|
|
591
|
-
*
|
|
591
|
+
* The maximum is controlled by the server configuration (`server.max_sandbox_timeout_seconds`).
|
|
592
|
+
* Omit this field or set it to null to disable automatic expiration and require explicit cleanup.
|
|
593
|
+
* Note: manual cleanup support is runtime-dependent; Kubernetes providers may reject
|
|
594
|
+
* omitted or null timeout when the underlying workload provider does not support non-expiring sandboxes.
|
|
592
595
|
*/
|
|
593
|
-
timeout
|
|
596
|
+
timeout?: number | null;
|
|
594
597
|
/**
|
|
595
598
|
* @description Runtime resource constraints for the sandbox instance.
|
|
596
599
|
* SDK clients should provide sensible defaults (e.g., cpu: "500m", memory: "512Mi").
|
|
@@ -659,6 +662,9 @@ export interface components {
|
|
|
659
662
|
* **Best Practices**:
|
|
660
663
|
* - **Namespacing**: Use prefixed keys (e.g., `storage.id`) to prevent collisions.
|
|
661
664
|
* - **Pass-through**: SDKs and middleware must treat this object as opaque and pass it through transparently.
|
|
665
|
+
*
|
|
666
|
+
* **Well-known keys**:
|
|
667
|
+
* - `access.renew.extend.seconds` (optional): Decimal integer string from **300** to **86400** (5 minutes to 24 hours inclusive). Opts the sandbox into OSEP-0009 renew-on-access and sets per-renewal extension seconds. Omit to disable. Invalid values are rejected at creation with HTTP 400 (validated on the lifecycle create endpoint via `validate_extensions` in server `src/extensions/validation.py`).
|
|
662
668
|
*/
|
|
663
669
|
extensions?: {
|
|
664
670
|
[key: string]: string;
|
|
@@ -758,7 +764,7 @@ export interface components {
|
|
|
758
764
|
/**
|
|
759
765
|
* @description Storage mount definition for a sandbox. Each volume entry contains:
|
|
760
766
|
* - A unique name identifier
|
|
761
|
-
* - Exactly one backend struct (host, pvc, etc.) with backend-specific fields
|
|
767
|
+
* - Exactly one backend struct (host, pvc, ossfs, etc.) with backend-specific fields
|
|
762
768
|
* - Common mount settings (mountPath, readOnly, subPath)
|
|
763
769
|
*/
|
|
764
770
|
Volume: {
|
|
@@ -769,6 +775,7 @@ export interface components {
|
|
|
769
775
|
name: string;
|
|
770
776
|
host?: components["schemas"]["Host"];
|
|
771
777
|
pvc?: components["schemas"]["PVC"];
|
|
778
|
+
ossfs?: components["schemas"]["OSSFS"];
|
|
772
779
|
/**
|
|
773
780
|
* @description Absolute path inside the container where the volume is mounted.
|
|
774
781
|
* Must start with '/'.
|
|
@@ -781,6 +788,7 @@ export interface components {
|
|
|
781
788
|
readOnly: boolean;
|
|
782
789
|
/**
|
|
783
790
|
* @description Optional subdirectory under the backend path to mount.
|
|
791
|
+
* For `ossfs` backend, this field is used as the bucket prefix.
|
|
784
792
|
* Must be a relative path without '..' components.
|
|
785
793
|
*/
|
|
786
794
|
subPath?: string;
|
|
@@ -795,23 +803,61 @@ export interface components {
|
|
|
795
803
|
Host: {
|
|
796
804
|
/**
|
|
797
805
|
* @description Absolute path on the host filesystem to mount.
|
|
798
|
-
* Must start with '/'
|
|
806
|
+
* Must start with '/' (Unix) or a drive letter such as 'C:\' or 'D:/'
|
|
807
|
+
* (Windows), and be under an allowed prefix.
|
|
799
808
|
*/
|
|
800
809
|
path: string;
|
|
801
810
|
};
|
|
802
811
|
/**
|
|
803
|
-
* @description
|
|
804
|
-
*
|
|
812
|
+
* @description Platform-managed named volume backend. A runtime-neutral abstraction
|
|
813
|
+
* for referencing a pre-existing, platform-managed named volume.
|
|
814
|
+
*
|
|
815
|
+
* - Kubernetes: maps to a PersistentVolumeClaim in the same namespace.
|
|
816
|
+
* - Docker: maps to a Docker named volume (created via `docker volume create`).
|
|
805
817
|
*
|
|
806
|
-
*
|
|
818
|
+
* The volume must already exist on the target platform before sandbox
|
|
819
|
+
* creation.
|
|
807
820
|
*/
|
|
808
821
|
PVC: {
|
|
809
822
|
/**
|
|
810
|
-
* @description Name of the
|
|
811
|
-
*
|
|
823
|
+
* @description Name of the volume on the target platform.
|
|
824
|
+
* In Kubernetes this is the PVC name; in Docker this is the named
|
|
825
|
+
* volume name. Must be a valid DNS label.
|
|
812
826
|
*/
|
|
813
827
|
claimName: string;
|
|
814
828
|
};
|
|
829
|
+
/**
|
|
830
|
+
* @description Alibaba Cloud OSS mount backend via ossfs.
|
|
831
|
+
*
|
|
832
|
+
* The runtime mounts a host-side OSS path under `storage.ossfs_mount_root`
|
|
833
|
+
* and bind-mounts the resolved path into the sandbox container.
|
|
834
|
+
* Prefix selection is expressed via `Volume.subPath`.
|
|
835
|
+
* In Docker runtime, OSSFS backend requires OpenSandbox Server to run on a Linux host with FUSE support.
|
|
836
|
+
*/
|
|
837
|
+
OSSFS: {
|
|
838
|
+
/** @description OSS bucket name. */
|
|
839
|
+
bucket: string;
|
|
840
|
+
/** @description OSS endpoint (e.g., `oss-cn-hangzhou.aliyuncs.com`). */
|
|
841
|
+
endpoint: string;
|
|
842
|
+
/**
|
|
843
|
+
* @description ossfs major version used by runtime mount integration.
|
|
844
|
+
* @default 2.0
|
|
845
|
+
* @enum {string}
|
|
846
|
+
*/
|
|
847
|
+
version: "1.0" | "2.0";
|
|
848
|
+
/**
|
|
849
|
+
* @description Additional ossfs mount options.
|
|
850
|
+
* Runtime encodes options by `version`:
|
|
851
|
+
* - `1.0`: mounts with `ossfs ... -o <option>`
|
|
852
|
+
* - `2.0`: mounts with `ossfs2 mount ... -c <config-file>` and encodes options as `--<option>` lines in the config file
|
|
853
|
+
* Option values must be provided as raw payloads without leading `-`.
|
|
854
|
+
*/
|
|
855
|
+
options?: string[];
|
|
856
|
+
/** @description OSS access key ID for inline credentials mode. */
|
|
857
|
+
accessKeyId: string;
|
|
858
|
+
/** @description OSS access key secret for inline credentials mode. */
|
|
859
|
+
accessKeySecret: string;
|
|
860
|
+
};
|
|
815
861
|
};
|
|
816
862
|
responses: {
|
|
817
863
|
/** @description Error response envelope */
|
package/src/core/constants.ts
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
// limitations under the License.
|
|
14
14
|
|
|
15
15
|
export const DEFAULT_EXECD_PORT = 44772;
|
|
16
|
+
export const DEFAULT_EGRESS_PORT = 18080;
|
|
16
17
|
|
|
17
18
|
export const DEFAULT_ENTRYPOINT: string[] = ["tail", "-f", "/dev/null"];
|
|
18
19
|
|
|
@@ -26,4 +27,4 @@ export const DEFAULT_READY_TIMEOUT_SECONDS = 30;
|
|
|
26
27
|
export const DEFAULT_HEALTH_CHECK_POLLING_INTERVAL_MILLIS = 200;
|
|
27
28
|
|
|
28
29
|
export const DEFAULT_REQUEST_TIMEOUT_SECONDS = 30;
|
|
29
|
-
export const DEFAULT_USER_AGENT = "OpenSandbox-JS-SDK/0.1.
|
|
30
|
+
export const DEFAULT_USER_AGENT = "OpenSandbox-JS-SDK/0.1.6";
|
package/src/core/exceptions.ts
CHANGED
|
@@ -44,6 +44,7 @@ interface SandboxExceptionOpts {
|
|
|
44
44
|
message?: string;
|
|
45
45
|
cause?: unknown;
|
|
46
46
|
error?: SandboxError;
|
|
47
|
+
requestId?: string;
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
/**
|
|
@@ -55,32 +56,32 @@ export class SandboxException extends Error {
|
|
|
55
56
|
readonly name: string = "SandboxException";
|
|
56
57
|
readonly error: SandboxError;
|
|
57
58
|
readonly cause?: unknown;
|
|
59
|
+
readonly requestId?: string;
|
|
58
60
|
|
|
59
61
|
constructor(opts: SandboxExceptionOpts = {}) {
|
|
60
62
|
super(opts.message);
|
|
61
63
|
this.cause = opts.cause;
|
|
62
64
|
this.error = opts.error ?? new SandboxError(SandboxError.INTERNAL_UNKNOWN_ERROR);
|
|
65
|
+
this.requestId = opts.requestId;
|
|
63
66
|
}
|
|
64
67
|
}
|
|
65
68
|
|
|
66
69
|
export class SandboxApiException extends SandboxException {
|
|
67
70
|
readonly name: string = "SandboxApiException";
|
|
68
71
|
readonly statusCode?: number;
|
|
69
|
-
readonly requestId?: string;
|
|
70
72
|
readonly rawBody?: unknown;
|
|
71
73
|
|
|
72
74
|
constructor(opts: SandboxExceptionOpts & {
|
|
73
75
|
statusCode?: number;
|
|
74
|
-
requestId?: string;
|
|
75
76
|
rawBody?: unknown;
|
|
76
77
|
}) {
|
|
77
78
|
super({
|
|
78
79
|
message: opts.message,
|
|
79
80
|
cause: opts.cause,
|
|
80
81
|
error: opts.error ?? new SandboxError(SandboxError.UNEXPECTED_RESPONSE, opts.message),
|
|
82
|
+
requestId: opts.requestId,
|
|
81
83
|
});
|
|
82
84
|
this.statusCode = opts.statusCode;
|
|
83
|
-
this.requestId = opts.requestId;
|
|
84
85
|
this.rawBody = opts.rawBody;
|
|
85
86
|
}
|
|
86
87
|
}
|
|
@@ -131,4 +132,4 @@ export class InvalidArgumentException extends SandboxException {
|
|
|
131
132
|
error: new SandboxError(SandboxError.INVALID_ARGUMENT, opts.message),
|
|
132
133
|
});
|
|
133
134
|
}
|
|
134
|
-
}
|
|
135
|
+
}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import type { ConnectionConfig } from "../config/connection.js";
|
|
16
16
|
import type { SandboxFiles } from "../services/filesystem.js";
|
|
17
|
+
import type { Egress } from "../services/egress.js";
|
|
17
18
|
import type { ExecdCommands } from "../services/execdCommands.js";
|
|
18
19
|
import type { ExecdHealth } from "../services/execdHealth.js";
|
|
19
20
|
import type { ExecdMetrics } from "../services/execdMetrics.js";
|
|
@@ -41,6 +42,16 @@ export interface ExecdStack {
|
|
|
41
42
|
metrics: ExecdMetrics;
|
|
42
43
|
}
|
|
43
44
|
|
|
45
|
+
export interface CreateEgressStackOptions {
|
|
46
|
+
connectionConfig: ConnectionConfig;
|
|
47
|
+
egressBaseUrl: string;
|
|
48
|
+
endpointHeaders?: Record<string, string>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface EgressStack {
|
|
52
|
+
egress: Egress;
|
|
53
|
+
}
|
|
54
|
+
|
|
44
55
|
/**
|
|
45
56
|
* Factory abstraction to keep `Sandbox` and `SandboxManager` decoupled from concrete adapter implementations.
|
|
46
57
|
*
|
|
@@ -49,4 +60,5 @@ export interface ExecdStack {
|
|
|
49
60
|
export interface AdapterFactory {
|
|
50
61
|
createLifecycleStack(opts: CreateLifecycleStackOptions): LifecycleStack;
|
|
51
62
|
createExecdStack(opts: CreateExecdStackOptions): ExecdStack;
|
|
52
|
-
|
|
63
|
+
createEgressStack(opts: CreateEgressStackOptions): EgressStack;
|
|
64
|
+
}
|
|
@@ -13,15 +13,25 @@
|
|
|
13
13
|
// limitations under the License.
|
|
14
14
|
|
|
15
15
|
import { createExecdClient } from "../openapi/execdClient.js";
|
|
16
|
+
import { createEgressClient } from "../openapi/egressClient.js";
|
|
16
17
|
import { createLifecycleClient } from "../openapi/lifecycleClient.js";
|
|
17
18
|
|
|
18
19
|
import { CommandsAdapter } from "../adapters/commandsAdapter.js";
|
|
20
|
+
import { EgressAdapter } from "../adapters/egressAdapter.js";
|
|
19
21
|
import { FilesystemAdapter } from "../adapters/filesystemAdapter.js";
|
|
20
22
|
import { HealthAdapter } from "../adapters/healthAdapter.js";
|
|
21
23
|
import { MetricsAdapter } from "../adapters/metricsAdapter.js";
|
|
22
24
|
import { SandboxesAdapter } from "../adapters/sandboxesAdapter.js";
|
|
23
25
|
|
|
24
|
-
import type {
|
|
26
|
+
import type {
|
|
27
|
+
AdapterFactory,
|
|
28
|
+
CreateEgressStackOptions,
|
|
29
|
+
CreateExecdStackOptions,
|
|
30
|
+
CreateLifecycleStackOptions,
|
|
31
|
+
EgressStack,
|
|
32
|
+
ExecdStack,
|
|
33
|
+
LifecycleStack,
|
|
34
|
+
} from "./adapterFactory.js";
|
|
25
35
|
|
|
26
36
|
export class DefaultAdapterFactory implements AdapterFactory {
|
|
27
37
|
createLifecycleStack(opts: CreateLifecycleStackOptions): LifecycleStack {
|
|
@@ -66,8 +76,23 @@ export class DefaultAdapterFactory implements AdapterFactory {
|
|
|
66
76
|
metrics,
|
|
67
77
|
};
|
|
68
78
|
}
|
|
79
|
+
|
|
80
|
+
createEgressStack(opts: CreateEgressStackOptions): EgressStack {
|
|
81
|
+
const headers: Record<string, string> = {
|
|
82
|
+
...(opts.connectionConfig.headers ?? {}),
|
|
83
|
+
...(opts.endpointHeaders ?? {}),
|
|
84
|
+
};
|
|
85
|
+
const egressClient = createEgressClient({
|
|
86
|
+
baseUrl: opts.egressBaseUrl,
|
|
87
|
+
headers,
|
|
88
|
+
fetch: opts.connectionConfig.fetch,
|
|
89
|
+
});
|
|
90
|
+
return {
|
|
91
|
+
egress: new EgressAdapter(egressClient),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
69
94
|
}
|
|
70
95
|
|
|
71
96
|
export function createDefaultAdapterFactory(): AdapterFactory {
|
|
72
97
|
return new DefaultAdapterFactory();
|
|
73
|
-
}
|
|
98
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -39,6 +39,7 @@ export type {
|
|
|
39
39
|
NetworkPolicy,
|
|
40
40
|
NetworkRule,
|
|
41
41
|
NetworkRuleAction,
|
|
42
|
+
OSSFS,
|
|
42
43
|
PVC,
|
|
43
44
|
RenewSandboxExpirationRequest,
|
|
44
45
|
RenewSandboxExpirationResponse,
|
|
@@ -91,6 +92,7 @@ export { ExecutionEventDispatcher } from "./models/executionEventDispatcher.js";
|
|
|
91
92
|
|
|
92
93
|
export {
|
|
93
94
|
DEFAULT_ENTRYPOINT,
|
|
95
|
+
DEFAULT_EGRESS_PORT,
|
|
94
96
|
DEFAULT_EXECD_PORT,
|
|
95
97
|
DEFAULT_RESOURCE_LIMITS,
|
|
96
98
|
DEFAULT_TIMEOUT_SECONDS,
|
|
@@ -112,4 +114,4 @@ export type {
|
|
|
112
114
|
SetPermissionEntry,
|
|
113
115
|
WriteEntry,
|
|
114
116
|
} from "./models/filesystem.js";
|
|
115
|
-
export type { SandboxFiles } from "./services/filesystem.js";
|
|
117
|
+
export type { SandboxFiles } from "./services/filesystem.js";
|
package/src/models/execd.ts
CHANGED
|
@@ -63,6 +63,18 @@ export interface RunCommandOpts {
|
|
|
63
63
|
* If omitted, the server will not enforce any timeout.
|
|
64
64
|
*/
|
|
65
65
|
timeoutSeconds?: number;
|
|
66
|
+
/**
|
|
67
|
+
* Unix user ID used to run the command process.
|
|
68
|
+
*/
|
|
69
|
+
uid?: number;
|
|
70
|
+
/**
|
|
71
|
+
* Unix group ID used to run the command process. Requires `uid`.
|
|
72
|
+
*/
|
|
73
|
+
gid?: number;
|
|
74
|
+
/**
|
|
75
|
+
* Environment variables injected into the command process.
|
|
76
|
+
*/
|
|
77
|
+
envs?: Record<string, string>;
|
|
66
78
|
}
|
|
67
79
|
|
|
68
80
|
export interface CommandStatus {
|
package/src/models/execution.ts
CHANGED
|
@@ -54,6 +54,7 @@ export interface Execution {
|
|
|
54
54
|
result: ExecutionResult[];
|
|
55
55
|
error?: ExecutionError;
|
|
56
56
|
complete?: ExecutionComplete;
|
|
57
|
+
exitCode?: number | null;
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
export interface ExecutionHandlers {
|
|
@@ -68,4 +69,4 @@ export interface ExecutionHandlers {
|
|
|
68
69
|
onExecutionComplete?: (c: ExecutionComplete) => void | Promise<void>;
|
|
69
70
|
onError?: (err: ExecutionError) => void | Promise<void>;
|
|
70
71
|
onInit?: (init: ExecutionInit) => void | Promise<void>;
|
|
71
|
-
}
|
|
72
|
+
}
|