opensandbox-cli 0.1.1__tar.gz → 1.1.1__tar.gz
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.
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/.gitignore +18 -0
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/PKG-INFO +176 -14
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/README.md +170 -9
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/pyproject.toml +9 -6
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/__init__.py +1 -1
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/__main__.py +1 -1
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/client.py +1 -6
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/commands/__init__.py +1 -1
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/commands/command.py +72 -60
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/commands/config_cmd.py +47 -58
- opensandbox_cli-1.1.1/src/opensandbox_cli/commands/credential_vault.py +306 -0
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/commands/devops.py +1 -10
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/commands/diagnostics.py +13 -16
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/commands/egress.py +1 -1
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/commands/file.py +55 -31
- opensandbox_cli-1.1.1/src/opensandbox_cli/commands/sandbox.py +1057 -0
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/commands/skills.py +1 -4
- opensandbox_cli-1.1.1/src/opensandbox_cli/commands/snapshot.py +170 -0
- opensandbox_cli-1.1.1/src/opensandbox_cli/commands/template.py +324 -0
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/config.py +1 -1
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/main.py +7 -6
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/output.py +29 -87
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/skill_registry.py +35 -4
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/skills/opensandbox-command-execution.md +2 -1
- opensandbox_cli-1.1.1/src/opensandbox_cli/skills/opensandbox-credential-vault.md +136 -0
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/skills/opensandbox-file-operations.md +4 -1
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/skills/opensandbox-sandbox-lifecycle.md +64 -1
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/skills/opensandbox-sandbox-troubleshooting.md +8 -11
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/utils.py +38 -41
- opensandbox_cli-0.1.1/src/opensandbox_cli/commands/sandbox.py +0 -580
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/LICENSE +0 -0
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/py.typed +0 -0
- {opensandbox_cli-0.1.1 → opensandbox_cli-1.1.1}/src/opensandbox_cli/skills/opensandbox-network-egress.md +0 -0
|
@@ -269,6 +269,19 @@ nbdist/
|
|
|
269
269
|
generated/
|
|
270
270
|
**/generated/**
|
|
271
271
|
|
|
272
|
+
# Fast Sandbox FastPath gRPC stubs are committed intentionally (deterministic protoc
|
|
273
|
+
# output; the server package needs them at install time, so they are checked
|
|
274
|
+
# in rather than regenerated).
|
|
275
|
+
!server/opensandbox_server/services/fast_sandbox/generated/
|
|
276
|
+
!server/opensandbox_server/services/fast_sandbox/generated/**
|
|
277
|
+
server/opensandbox_server/services/fast_sandbox/generated/__pycache__/
|
|
278
|
+
|
|
279
|
+
# execd eBPF kernel BTF dumps (bpf2go build-time only, never committed —
|
|
280
|
+
# see components/execd/pkg/ebpf/prog/audit.bpf.c; regenerate with:
|
|
281
|
+
# bpftool btf dump file /sys/kernel/btf/vmlinux format c > .../vmlinux.h)
|
|
282
|
+
components/execd/pkg/ebpf/prog/vmlinux.h
|
|
283
|
+
components/execd/pkg/ebpf/prog/vmlinux_*.h
|
|
284
|
+
|
|
272
285
|
# gVisor runtime binaries (downloaded dynamically)
|
|
273
286
|
kubernetes/test/kind/gvisor/runsc
|
|
274
287
|
kubernetes/test/kind/gvisor/containerd-shim-runsc-v1
|
|
@@ -276,3 +289,8 @@ bin/
|
|
|
276
289
|
obj/
|
|
277
290
|
|
|
278
291
|
.qoder/
|
|
292
|
+
/.vs
|
|
293
|
+
|
|
294
|
+
# fast-sandbox pinned source checkout (materialized by
|
|
295
|
+
# manifests/release/build-fast-sandbox.sh from manifests/third-party/fast-sandbox.commit)
|
|
296
|
+
.fast-sandbox/
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: opensandbox-cli
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1.1.1
|
|
4
4
|
Summary: OpenSandbox CLI - Command-line interface for managing sandboxes
|
|
5
5
|
Project-URL: Homepage, https://open-sandbox.ai
|
|
6
|
-
Project-URL: Repository, https://github.com/
|
|
6
|
+
Project-URL: Repository, https://github.com/opensandbox-group/OpenSandbox
|
|
7
7
|
Project-URL: Documentation, https://open-sandbox.ai
|
|
8
|
-
Project-URL: Issues, https://github.com/
|
|
8
|
+
Project-URL: Issues, https://github.com/opensandbox-group/OpenSandbox/issues
|
|
9
9
|
Author-email: OpenSandbox Team <ninan.nn@alibaba-inc.com>
|
|
10
10
|
License: Apache License
|
|
11
11
|
Version 2.0, January 2004
|
|
@@ -224,10 +224,11 @@ Classifier: Topic :: Software Development :: Libraries
|
|
|
224
224
|
Classifier: Typing :: Typed
|
|
225
225
|
Requires-Python: >=3.10
|
|
226
226
|
Requires-Dist: click<9.0,>=8.1.0
|
|
227
|
-
Requires-Dist: opensandbox<
|
|
227
|
+
Requires-Dist: opensandbox<2.0.0,>=1.1.1
|
|
228
228
|
Requires-Dist: pyyaml<7.0,>=6.0
|
|
229
229
|
Requires-Dist: rich<14.0,>=13.0.0
|
|
230
230
|
Requires-Dist: tomli>=2.0.0; python_version < '3.11'
|
|
231
|
+
Requires-Dist: tomlkit<1.0,>=0.13.0
|
|
231
232
|
Description-Content-Type: text/markdown
|
|
232
233
|
|
|
233
234
|
# OpenSandbox CLI
|
|
@@ -235,9 +236,11 @@ Description-Content-Type: text/markdown
|
|
|
235
236
|
`osb` is the command-line interface for OpenSandbox. It is built for the common day-to-day flows:
|
|
236
237
|
|
|
237
238
|
- create and manage sandboxes
|
|
239
|
+
- build golden-image templates and create sandboxes from templates or snapshots
|
|
238
240
|
- run commands inside a sandbox
|
|
239
241
|
- read and modify sandbox files
|
|
240
242
|
- inspect runtime egress policy
|
|
243
|
+
- manage sandbox-local Credential Vault state
|
|
241
244
|
- collect low-level diagnostics
|
|
242
245
|
- install OpenSandbox-specific skills for coding agents
|
|
243
246
|
|
|
@@ -282,6 +285,7 @@ opensandbox-server
|
|
|
282
285
|
osb config init
|
|
283
286
|
osb config set connection.domain localhost:8080
|
|
284
287
|
osb config set connection.protocol http
|
|
288
|
+
osb config set connection.api_key <your-api-key>
|
|
285
289
|
osb config show -o json
|
|
286
290
|
```
|
|
287
291
|
|
|
@@ -379,6 +383,109 @@ osb sandbox create \
|
|
|
379
383
|
--volumes-file volumes.json
|
|
380
384
|
```
|
|
381
385
|
|
|
386
|
+
Create with Credential Vault proxy enabled:
|
|
387
|
+
|
|
388
|
+
```bash
|
|
389
|
+
osb sandbox create --image python:3.12 --network-policy-file network-policy.json --credential-proxy -o json
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
Create from a template (golden image):
|
|
393
|
+
|
|
394
|
+
```bash
|
|
395
|
+
osb sandbox create --template <template-id> --timeout 30m -o json
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
Template mode fixes the workload shape on the server: `--image`, `--env`,
|
|
399
|
+
`--resource`, `--entrypoint`, `--volumes-file`, and `--credential-proxy` cannot
|
|
400
|
+
be combined with `--template`. Only `--timeout` (required), `--metadata`,
|
|
401
|
+
`--extension`, and `--network-policy-file` may accompany it. Only templates in
|
|
402
|
+
the `Succeeded` phase can be used. See [Manage templates](#manage-templates).
|
|
403
|
+
|
|
404
|
+
Create from a snapshot:
|
|
405
|
+
|
|
406
|
+
```bash
|
|
407
|
+
osb sandbox create --snapshot-id <snapshot-id> --timeout 30m -o json
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
`--image`, `--template`, and `--snapshot-id` are mutually exclusive.
|
|
411
|
+
|
|
412
|
+
Create from a request file (`-f`, like `kubectl apply -f`):
|
|
413
|
+
|
|
414
|
+
```bash
|
|
415
|
+
osb sandbox create -f sandbox-request.json -o json
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
`sandbox-request.json` uses the public `CreateSandboxRequest` JSON format
|
|
419
|
+
(camelCase keys):
|
|
420
|
+
|
|
421
|
+
```json
|
|
422
|
+
{
|
|
423
|
+
"image": "python:3.12",
|
|
424
|
+
"timeout": 1800,
|
|
425
|
+
"resourceLimits": { "cpu": "1", "memory": "2Gi" },
|
|
426
|
+
"entrypoint": ["python", "-m", "http.server"],
|
|
427
|
+
"networkPolicy": {
|
|
428
|
+
"defaultAction": "deny",
|
|
429
|
+
"egress": [{ "action": "allow", "target": "pypi.org" }]
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
- Exactly one of `image` (string or `{ "uri": ..., "auth": { "username": ..., "password": ... } }`),
|
|
435
|
+
`templateId`, or `snapshotId` is required; `timeout` is integer seconds, or
|
|
436
|
+
`null` for manual cleanup.
|
|
437
|
+
- Supported fields: `image`, `templateId`, `snapshotId`, `platform`, `timeout`,
|
|
438
|
+
`resourceLimits`, `resourceRequests`, `env`, `metadata`, `extensions`,
|
|
439
|
+
`entrypoint`, `networkPolicy`, `credentialProxy`, `secureAccess`, `volumes`,
|
|
440
|
+
`lifecycle`.
|
|
441
|
+
- `-f` cannot be combined with request-building flags; `--skip-health-check`,
|
|
442
|
+
`--ready-timeout`, and `-o` still apply. In template mode the file may only
|
|
443
|
+
set `timeout`, `metadata`, `extensions`, and `networkPolicy` alongside
|
|
444
|
+
`templateId` (a finite `timeout` is required).
|
|
445
|
+
|
|
446
|
+
### Manage templates
|
|
447
|
+
|
|
448
|
+
Templates are golden-image builds; the build runs asynchronously, so poll
|
|
449
|
+
`template get` until the status phase is `Succeeded`. Template management
|
|
450
|
+
requires a Kubernetes-backed runtime.
|
|
451
|
+
|
|
452
|
+
```bash
|
|
453
|
+
osb template create --image python:3.12 --publish s3://bucket/publish -o json
|
|
454
|
+
osb template get <template-id> -o json
|
|
455
|
+
osb template list -o json
|
|
456
|
+
osb template delete <template-id> -o json
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
`template create` also accepts `--resource cpu=1 memory=512Mi disk=2Gi`,
|
|
460
|
+
`--entrypoint` (repeat per argv item), `--env KEY=VALUE`, `--metadata
|
|
461
|
+
KEY=VALUE`, `--format native|overlaybd`, `--readiness-probe`, and
|
|
462
|
+
`--warmup-seconds`. Or pass a request file in the public `CreateTemplateRequest`
|
|
463
|
+
JSON format:
|
|
464
|
+
|
|
465
|
+
```bash
|
|
466
|
+
osb template create -f template-request.json -o json
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
```json
|
|
470
|
+
{
|
|
471
|
+
"image": "python:3.12",
|
|
472
|
+
"publish": "s3://bucket/publish",
|
|
473
|
+
"resourceLimits": { "cpu": "1", "memory": "512Mi" },
|
|
474
|
+
"readiness": { "probe": "tcp://127.0.0.1:44772", "warmupSeconds": 60 }
|
|
475
|
+
}
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
### Manage snapshots
|
|
479
|
+
|
|
480
|
+
Snapshots capture a sandbox's state and can back new sandboxes.
|
|
481
|
+
|
|
482
|
+
```bash
|
|
483
|
+
osb snapshot create <sandbox-id> --name golden -o json
|
|
484
|
+
osb snapshot get <snapshot-id> -o json
|
|
485
|
+
osb snapshot list --sandbox-id <sandbox-id> -o json
|
|
486
|
+
osb snapshot delete <snapshot-id> -o json
|
|
487
|
+
```
|
|
488
|
+
|
|
382
489
|
### List and inspect sandboxes
|
|
383
490
|
|
|
384
491
|
```bash
|
|
@@ -390,6 +497,17 @@ osb sandbox metrics <sandbox-id>
|
|
|
390
497
|
osb sandbox metrics <sandbox-id> --watch -o raw
|
|
391
498
|
```
|
|
392
499
|
|
|
500
|
+
### Pause a sandbox
|
|
501
|
+
|
|
502
|
+
Pause is asynchronous. `Pause request accepted` confirms that the server accepted
|
|
503
|
+
the request, not that the sandbox has reached the `Paused` state. Poll the sandbox
|
|
504
|
+
until the transition finishes:
|
|
505
|
+
|
|
506
|
+
```bash
|
|
507
|
+
osb sandbox pause <sandbox-id>
|
|
508
|
+
osb sandbox get <sandbox-id> -o json
|
|
509
|
+
```
|
|
510
|
+
|
|
393
511
|
### Expose a service
|
|
394
512
|
|
|
395
513
|
```bash
|
|
@@ -412,6 +530,21 @@ osb command status <sandbox-id> <execution-id> -o json
|
|
|
412
530
|
osb command logs <sandbox-id> <execution-id> -o json
|
|
413
531
|
```
|
|
414
532
|
|
|
533
|
+
Background start errors or a stream ending before startup confirmation make the
|
|
534
|
+
CLI exit non-zero without success metadata. After a successful start, use
|
|
535
|
+
`command status` and `command logs` to check the process's eventual result.
|
|
536
|
+
|
|
537
|
+
By default the payload after `--` is joined into one shell command string, so
|
|
538
|
+
pipelines, redirection, and `$VAR` expansion work as in a terminal. Add `--argv`
|
|
539
|
+
to pass the arguments to the executable as a literal argv list (no shell) when
|
|
540
|
+
values such as `$HOME`, quotes, embedded spaces, or empty strings must reach the
|
|
541
|
+
process unchanged. `--argv` needs a sandbox image whose execd accepts argv
|
|
542
|
+
requests:
|
|
543
|
+
|
|
544
|
+
```bash
|
|
545
|
+
osb command run <sandbox-id> -o raw --argv -- python3 -c "import sys; print(sys.argv[1:])" "a b" '$HOME' "x'y" ""
|
|
546
|
+
```
|
|
547
|
+
|
|
415
548
|
Persistent shell session:
|
|
416
549
|
|
|
417
550
|
```bash
|
|
@@ -433,6 +566,11 @@ osb file replace <sandbox-id> /workspace/app.py --old old --new new -o json
|
|
|
433
566
|
osb file chmod <sandbox-id> /workspace/script.sh --mode 755 -o json
|
|
434
567
|
```
|
|
435
568
|
|
|
569
|
+
Downloads replace regular files only on success; a failed or interrupted
|
|
570
|
+
download preserves any existing regular file. Existing devices and named pipes
|
|
571
|
+
receive data directly. Stdout aliases (such as `/dev/stdout`) stream only the file
|
|
572
|
+
bytes, without a success message. See the [CLI guide](../docs/cli/index.md#work-with-files).
|
|
573
|
+
|
|
436
574
|
### Manage runtime egress policy
|
|
437
575
|
|
|
438
576
|
Inspect current policy:
|
|
@@ -453,26 +591,46 @@ If you are debugging connectivity, verify behavior with an actual command:
|
|
|
453
591
|
osb command run <sandbox-id> -o raw -- curl -I https://pypi.org
|
|
454
592
|
```
|
|
455
593
|
|
|
594
|
+
### Manage Credential Vault
|
|
595
|
+
|
|
596
|
+
Credential Vault operations call the sandbox egress sidecar through the Python SDK.
|
|
597
|
+
Create the sandbox with `--credential-proxy` and an explicit network policy before
|
|
598
|
+
writing vault state.
|
|
599
|
+
|
|
600
|
+
```bash
|
|
601
|
+
osb credential-vault create <sandbox-id> --file vault.yaml -o json
|
|
602
|
+
osb credential-vault get <sandbox-id> -o json
|
|
603
|
+
osb credential-vault patch <sandbox-id> --file mutation.yaml -o json
|
|
604
|
+
osb credential-vault credential list <sandbox-id> -o json
|
|
605
|
+
osb credential-vault binding list <sandbox-id> -o json
|
|
606
|
+
osb credential-vault delete <sandbox-id> -o json
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
Use `--file -` to read a JSON/YAML payload from stdin. Do not pass plaintext
|
|
610
|
+
credential values as command-line flags; keep them in the payload stream or file.
|
|
611
|
+
|
|
456
612
|
### Collect diagnostics
|
|
457
613
|
|
|
458
614
|
Use the stable diagnostics commands for API-backed log and event descriptors.
|
|
459
615
|
|
|
460
616
|
```bash
|
|
461
|
-
osb diagnostics events <sandbox-id> --scope lifecycle -o raw
|
|
462
617
|
osb diagnostics events <sandbox-id> --scope runtime -o raw
|
|
618
|
+
osb diagnostics events <sandbox-id> --scope all -o raw
|
|
463
619
|
osb diagnostics logs <sandbox-id> --scope container -o raw
|
|
464
|
-
osb diagnostics logs <sandbox-id> --scope
|
|
620
|
+
osb diagnostics logs <sandbox-id> --scope all -o json
|
|
465
621
|
osb diagnostics events <sandbox-id> --scope runtime -o json
|
|
466
622
|
osb diagnostics logs <sandbox-id> --scope container -o yaml
|
|
467
623
|
```
|
|
468
624
|
|
|
469
|
-
`--scope` is required for stable diagnostics.
|
|
470
|
-
`container` for logs, and `
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
625
|
+
`--scope` is required for stable diagnostics. The built-in server supports
|
|
626
|
+
`container` and `all` for logs, and `runtime` and `all` for events. It returns
|
|
627
|
+
`DIAGNOSTICS_SCOPE_UNSUPPORTED` for unavailable scopes, including lifecycle events.
|
|
628
|
+
Best-effort scopes may include a `warnings` field when the backend can only
|
|
629
|
+
provide a subset. Raw output prints inline
|
|
630
|
+
diagnostic text, or the content URL when diagnostics are delivered as a
|
|
631
|
+
temporary URL. Structured CLI output follows the SDK/Python field style, for
|
|
632
|
+
example `content_url`, `content_length`, and `expires_at`. Older server builds
|
|
633
|
+
may still return `DIAGNOSTICS_NOT_IMPLEMENTED` for scoped diagnostics.
|
|
476
634
|
|
|
477
635
|
Legacy DevOps diagnostics remain experimental. Prefer `osb diagnostics logs/events`
|
|
478
636
|
for stable API-backed log and event collection.
|
|
@@ -506,6 +664,8 @@ Not every command supports every format. Use `--help` on the specific command wh
|
|
|
506
664
|
The main command groups are:
|
|
507
665
|
|
|
508
666
|
- `osb sandbox`: lifecycle management
|
|
667
|
+
- `osb template`: golden-image template builds
|
|
668
|
+
- `osb snapshot`: snapshot management
|
|
509
669
|
- `osb command`: command execution and persistent sessions
|
|
510
670
|
- `osb file`: file and directory operations
|
|
511
671
|
- `osb egress`: runtime egress policy
|
|
@@ -518,6 +678,8 @@ Explore them directly:
|
|
|
518
678
|
|
|
519
679
|
```bash
|
|
520
680
|
osb sandbox --help
|
|
681
|
+
osb template --help
|
|
682
|
+
osb snapshot --help
|
|
521
683
|
osb command --help
|
|
522
684
|
osb file --help
|
|
523
685
|
osb skills --help
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
`osb` is the command-line interface for OpenSandbox. It is built for the common day-to-day flows:
|
|
4
4
|
|
|
5
5
|
- create and manage sandboxes
|
|
6
|
+
- build golden-image templates and create sandboxes from templates or snapshots
|
|
6
7
|
- run commands inside a sandbox
|
|
7
8
|
- read and modify sandbox files
|
|
8
9
|
- inspect runtime egress policy
|
|
10
|
+
- manage sandbox-local Credential Vault state
|
|
9
11
|
- collect low-level diagnostics
|
|
10
12
|
- install OpenSandbox-specific skills for coding agents
|
|
11
13
|
|
|
@@ -50,6 +52,7 @@ opensandbox-server
|
|
|
50
52
|
osb config init
|
|
51
53
|
osb config set connection.domain localhost:8080
|
|
52
54
|
osb config set connection.protocol http
|
|
55
|
+
osb config set connection.api_key <your-api-key>
|
|
53
56
|
osb config show -o json
|
|
54
57
|
```
|
|
55
58
|
|
|
@@ -147,6 +150,109 @@ osb sandbox create \
|
|
|
147
150
|
--volumes-file volumes.json
|
|
148
151
|
```
|
|
149
152
|
|
|
153
|
+
Create with Credential Vault proxy enabled:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
osb sandbox create --image python:3.12 --network-policy-file network-policy.json --credential-proxy -o json
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Create from a template (golden image):
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
osb sandbox create --template <template-id> --timeout 30m -o json
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Template mode fixes the workload shape on the server: `--image`, `--env`,
|
|
166
|
+
`--resource`, `--entrypoint`, `--volumes-file`, and `--credential-proxy` cannot
|
|
167
|
+
be combined with `--template`. Only `--timeout` (required), `--metadata`,
|
|
168
|
+
`--extension`, and `--network-policy-file` may accompany it. Only templates in
|
|
169
|
+
the `Succeeded` phase can be used. See [Manage templates](#manage-templates).
|
|
170
|
+
|
|
171
|
+
Create from a snapshot:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
osb sandbox create --snapshot-id <snapshot-id> --timeout 30m -o json
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
`--image`, `--template`, and `--snapshot-id` are mutually exclusive.
|
|
178
|
+
|
|
179
|
+
Create from a request file (`-f`, like `kubectl apply -f`):
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
osb sandbox create -f sandbox-request.json -o json
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
`sandbox-request.json` uses the public `CreateSandboxRequest` JSON format
|
|
186
|
+
(camelCase keys):
|
|
187
|
+
|
|
188
|
+
```json
|
|
189
|
+
{
|
|
190
|
+
"image": "python:3.12",
|
|
191
|
+
"timeout": 1800,
|
|
192
|
+
"resourceLimits": { "cpu": "1", "memory": "2Gi" },
|
|
193
|
+
"entrypoint": ["python", "-m", "http.server"],
|
|
194
|
+
"networkPolicy": {
|
|
195
|
+
"defaultAction": "deny",
|
|
196
|
+
"egress": [{ "action": "allow", "target": "pypi.org" }]
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
- Exactly one of `image` (string or `{ "uri": ..., "auth": { "username": ..., "password": ... } }`),
|
|
202
|
+
`templateId`, or `snapshotId` is required; `timeout` is integer seconds, or
|
|
203
|
+
`null` for manual cleanup.
|
|
204
|
+
- Supported fields: `image`, `templateId`, `snapshotId`, `platform`, `timeout`,
|
|
205
|
+
`resourceLimits`, `resourceRequests`, `env`, `metadata`, `extensions`,
|
|
206
|
+
`entrypoint`, `networkPolicy`, `credentialProxy`, `secureAccess`, `volumes`,
|
|
207
|
+
`lifecycle`.
|
|
208
|
+
- `-f` cannot be combined with request-building flags; `--skip-health-check`,
|
|
209
|
+
`--ready-timeout`, and `-o` still apply. In template mode the file may only
|
|
210
|
+
set `timeout`, `metadata`, `extensions`, and `networkPolicy` alongside
|
|
211
|
+
`templateId` (a finite `timeout` is required).
|
|
212
|
+
|
|
213
|
+
### Manage templates
|
|
214
|
+
|
|
215
|
+
Templates are golden-image builds; the build runs asynchronously, so poll
|
|
216
|
+
`template get` until the status phase is `Succeeded`. Template management
|
|
217
|
+
requires a Kubernetes-backed runtime.
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
osb template create --image python:3.12 --publish s3://bucket/publish -o json
|
|
221
|
+
osb template get <template-id> -o json
|
|
222
|
+
osb template list -o json
|
|
223
|
+
osb template delete <template-id> -o json
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
`template create` also accepts `--resource cpu=1 memory=512Mi disk=2Gi`,
|
|
227
|
+
`--entrypoint` (repeat per argv item), `--env KEY=VALUE`, `--metadata
|
|
228
|
+
KEY=VALUE`, `--format native|overlaybd`, `--readiness-probe`, and
|
|
229
|
+
`--warmup-seconds`. Or pass a request file in the public `CreateTemplateRequest`
|
|
230
|
+
JSON format:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
osb template create -f template-request.json -o json
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
```json
|
|
237
|
+
{
|
|
238
|
+
"image": "python:3.12",
|
|
239
|
+
"publish": "s3://bucket/publish",
|
|
240
|
+
"resourceLimits": { "cpu": "1", "memory": "512Mi" },
|
|
241
|
+
"readiness": { "probe": "tcp://127.0.0.1:44772", "warmupSeconds": 60 }
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Manage snapshots
|
|
246
|
+
|
|
247
|
+
Snapshots capture a sandbox's state and can back new sandboxes.
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
osb snapshot create <sandbox-id> --name golden -o json
|
|
251
|
+
osb snapshot get <snapshot-id> -o json
|
|
252
|
+
osb snapshot list --sandbox-id <sandbox-id> -o json
|
|
253
|
+
osb snapshot delete <snapshot-id> -o json
|
|
254
|
+
```
|
|
255
|
+
|
|
150
256
|
### List and inspect sandboxes
|
|
151
257
|
|
|
152
258
|
```bash
|
|
@@ -158,6 +264,17 @@ osb sandbox metrics <sandbox-id>
|
|
|
158
264
|
osb sandbox metrics <sandbox-id> --watch -o raw
|
|
159
265
|
```
|
|
160
266
|
|
|
267
|
+
### Pause a sandbox
|
|
268
|
+
|
|
269
|
+
Pause is asynchronous. `Pause request accepted` confirms that the server accepted
|
|
270
|
+
the request, not that the sandbox has reached the `Paused` state. Poll the sandbox
|
|
271
|
+
until the transition finishes:
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
osb sandbox pause <sandbox-id>
|
|
275
|
+
osb sandbox get <sandbox-id> -o json
|
|
276
|
+
```
|
|
277
|
+
|
|
161
278
|
### Expose a service
|
|
162
279
|
|
|
163
280
|
```bash
|
|
@@ -180,6 +297,21 @@ osb command status <sandbox-id> <execution-id> -o json
|
|
|
180
297
|
osb command logs <sandbox-id> <execution-id> -o json
|
|
181
298
|
```
|
|
182
299
|
|
|
300
|
+
Background start errors or a stream ending before startup confirmation make the
|
|
301
|
+
CLI exit non-zero without success metadata. After a successful start, use
|
|
302
|
+
`command status` and `command logs` to check the process's eventual result.
|
|
303
|
+
|
|
304
|
+
By default the payload after `--` is joined into one shell command string, so
|
|
305
|
+
pipelines, redirection, and `$VAR` expansion work as in a terminal. Add `--argv`
|
|
306
|
+
to pass the arguments to the executable as a literal argv list (no shell) when
|
|
307
|
+
values such as `$HOME`, quotes, embedded spaces, or empty strings must reach the
|
|
308
|
+
process unchanged. `--argv` needs a sandbox image whose execd accepts argv
|
|
309
|
+
requests:
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
osb command run <sandbox-id> -o raw --argv -- python3 -c "import sys; print(sys.argv[1:])" "a b" '$HOME' "x'y" ""
|
|
313
|
+
```
|
|
314
|
+
|
|
183
315
|
Persistent shell session:
|
|
184
316
|
|
|
185
317
|
```bash
|
|
@@ -201,6 +333,11 @@ osb file replace <sandbox-id> /workspace/app.py --old old --new new -o json
|
|
|
201
333
|
osb file chmod <sandbox-id> /workspace/script.sh --mode 755 -o json
|
|
202
334
|
```
|
|
203
335
|
|
|
336
|
+
Downloads replace regular files only on success; a failed or interrupted
|
|
337
|
+
download preserves any existing regular file. Existing devices and named pipes
|
|
338
|
+
receive data directly. Stdout aliases (such as `/dev/stdout`) stream only the file
|
|
339
|
+
bytes, without a success message. See the [CLI guide](../docs/cli/index.md#work-with-files).
|
|
340
|
+
|
|
204
341
|
### Manage runtime egress policy
|
|
205
342
|
|
|
206
343
|
Inspect current policy:
|
|
@@ -221,26 +358,46 @@ If you are debugging connectivity, verify behavior with an actual command:
|
|
|
221
358
|
osb command run <sandbox-id> -o raw -- curl -I https://pypi.org
|
|
222
359
|
```
|
|
223
360
|
|
|
361
|
+
### Manage Credential Vault
|
|
362
|
+
|
|
363
|
+
Credential Vault operations call the sandbox egress sidecar through the Python SDK.
|
|
364
|
+
Create the sandbox with `--credential-proxy` and an explicit network policy before
|
|
365
|
+
writing vault state.
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
osb credential-vault create <sandbox-id> --file vault.yaml -o json
|
|
369
|
+
osb credential-vault get <sandbox-id> -o json
|
|
370
|
+
osb credential-vault patch <sandbox-id> --file mutation.yaml -o json
|
|
371
|
+
osb credential-vault credential list <sandbox-id> -o json
|
|
372
|
+
osb credential-vault binding list <sandbox-id> -o json
|
|
373
|
+
osb credential-vault delete <sandbox-id> -o json
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
Use `--file -` to read a JSON/YAML payload from stdin. Do not pass plaintext
|
|
377
|
+
credential values as command-line flags; keep them in the payload stream or file.
|
|
378
|
+
|
|
224
379
|
### Collect diagnostics
|
|
225
380
|
|
|
226
381
|
Use the stable diagnostics commands for API-backed log and event descriptors.
|
|
227
382
|
|
|
228
383
|
```bash
|
|
229
|
-
osb diagnostics events <sandbox-id> --scope lifecycle -o raw
|
|
230
384
|
osb diagnostics events <sandbox-id> --scope runtime -o raw
|
|
385
|
+
osb diagnostics events <sandbox-id> --scope all -o raw
|
|
231
386
|
osb diagnostics logs <sandbox-id> --scope container -o raw
|
|
232
|
-
osb diagnostics logs <sandbox-id> --scope
|
|
387
|
+
osb diagnostics logs <sandbox-id> --scope all -o json
|
|
233
388
|
osb diagnostics events <sandbox-id> --scope runtime -o json
|
|
234
389
|
osb diagnostics logs <sandbox-id> --scope container -o yaml
|
|
235
390
|
```
|
|
236
391
|
|
|
237
|
-
`--scope` is required for stable diagnostics.
|
|
238
|
-
`container` for logs, and `
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
392
|
+
`--scope` is required for stable diagnostics. The built-in server supports
|
|
393
|
+
`container` and `all` for logs, and `runtime` and `all` for events. It returns
|
|
394
|
+
`DIAGNOSTICS_SCOPE_UNSUPPORTED` for unavailable scopes, including lifecycle events.
|
|
395
|
+
Best-effort scopes may include a `warnings` field when the backend can only
|
|
396
|
+
provide a subset. Raw output prints inline
|
|
397
|
+
diagnostic text, or the content URL when diagnostics are delivered as a
|
|
398
|
+
temporary URL. Structured CLI output follows the SDK/Python field style, for
|
|
399
|
+
example `content_url`, `content_length`, and `expires_at`. Older server builds
|
|
400
|
+
may still return `DIAGNOSTICS_NOT_IMPLEMENTED` for scoped diagnostics.
|
|
244
401
|
|
|
245
402
|
Legacy DevOps diagnostics remain experimental. Prefer `osb diagnostics logs/events`
|
|
246
403
|
for stable API-backed log and event collection.
|
|
@@ -274,6 +431,8 @@ Not every command supports every format. Use `--help` on the specific command wh
|
|
|
274
431
|
The main command groups are:
|
|
275
432
|
|
|
276
433
|
- `osb sandbox`: lifecycle management
|
|
434
|
+
- `osb template`: golden-image template builds
|
|
435
|
+
- `osb snapshot`: snapshot management
|
|
277
436
|
- `osb command`: command execution and persistent sessions
|
|
278
437
|
- `osb file`: file and directory operations
|
|
279
438
|
- `osb egress`: runtime egress policy
|
|
@@ -286,6 +445,8 @@ Explore them directly:
|
|
|
286
445
|
|
|
287
446
|
```bash
|
|
288
447
|
osb sandbox --help
|
|
448
|
+
osb template --help
|
|
449
|
+
osb snapshot --help
|
|
289
450
|
osb command --help
|
|
290
451
|
osb file --help
|
|
291
452
|
osb skills --help
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2026
|
|
1
|
+
# Copyright 2026 The OpenSandbox Authors.
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -42,18 +42,21 @@ classifiers = [
|
|
|
42
42
|
"Typing :: Typed",
|
|
43
43
|
]
|
|
44
44
|
dependencies = [
|
|
45
|
-
|
|
45
|
+
# `command run --argv` passes a list to commands.run; the SDK accepts a
|
|
46
|
+
# list there from 0.1.17. Release the CLI only after that SDK is published.
|
|
47
|
+
"opensandbox>=1.1.1,<2.0.0",
|
|
46
48
|
"click>=8.1.0,<9.0",
|
|
47
49
|
"rich>=13.0.0,<14.0",
|
|
48
50
|
"pyyaml>=6.0,<7.0",
|
|
51
|
+
"tomlkit>=0.13.0,<1.0",
|
|
49
52
|
"tomli>=2.0.0; python_version < '3.11'",
|
|
50
53
|
]
|
|
51
54
|
|
|
52
55
|
[project.urls]
|
|
53
56
|
Homepage = "https://open-sandbox.ai"
|
|
54
|
-
Repository = "https://github.com/
|
|
57
|
+
Repository = "https://github.com/opensandbox-group/OpenSandbox"
|
|
55
58
|
Documentation = "https://open-sandbox.ai"
|
|
56
|
-
Issues = "https://github.com/
|
|
59
|
+
Issues = "https://github.com/opensandbox-group/OpenSandbox/issues"
|
|
57
60
|
|
|
58
61
|
[project.scripts]
|
|
59
62
|
opensandbox = "opensandbox_cli.main:cli"
|
|
@@ -64,8 +67,8 @@ source = "vcs"
|
|
|
64
67
|
|
|
65
68
|
[tool.hatch.version.raw-options]
|
|
66
69
|
root = ".."
|
|
67
|
-
tag_regex = "^
|
|
68
|
-
git_describe_command = 'git describe --dirty --tags --long --match "
|
|
70
|
+
tag_regex = "^release-(?P<version>\\d+\\.\\d+\\.\\d+(?:[\\.\\w\\+\\-]*)?)$"
|
|
71
|
+
git_describe_command = 'git describe --dirty --tags --long --match "release-*"'
|
|
69
72
|
fallback_version = "0.1.1"
|
|
70
73
|
|
|
71
74
|
[tool.hatch.build]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2026
|
|
1
|
+
# Copyright 2026 The OpenSandbox Authors.
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -90,15 +90,10 @@ class ClientContext:
|
|
|
90
90
|
self._manager = SandboxManagerSync.create(self.connection_config)
|
|
91
91
|
return self._manager
|
|
92
92
|
|
|
93
|
-
def resolve_sandbox_id(self, sandbox_id: str) -> str:
|
|
94
|
-
"""Return the sandbox ID exactly as provided by the user."""
|
|
95
|
-
return sandbox_id
|
|
96
|
-
|
|
97
93
|
def connect_sandbox(
|
|
98
94
|
self, sandbox_id: str, *, skip_health_check: bool = True
|
|
99
95
|
) -> SandboxSync:
|
|
100
96
|
"""Connect to an existing sandbox by ID."""
|
|
101
|
-
sandbox_id = self.resolve_sandbox_id(sandbox_id)
|
|
102
97
|
return SandboxSync.connect(
|
|
103
98
|
sandbox_id,
|
|
104
99
|
connection_config=self.connection_config,
|