microsandbox-rb 0.5.9 → 0.5.10
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +77 -0
- data/Cargo.lock +90 -45
- data/DESIGN.md +7 -3
- data/README.md +91 -26
- data/ext/microsandbox/Cargo.toml +4 -4
- data/ext/microsandbox/extconf.rb +6 -2
- data/ext/microsandbox/src/backend.rs +170 -0
- data/ext/microsandbox/src/error.rs +6 -0
- data/ext/microsandbox/src/image.rs +7 -7
- data/ext/microsandbox/src/lib.rs +27 -4
- data/ext/microsandbox/src/sandbox.rs +172 -58
- data/ext/microsandbox/src/volume.rs +6 -1
- data/lib/microsandbox/errors.rb +6 -0
- data/lib/microsandbox/exec_handle.rb +14 -11
- data/lib/microsandbox/fs.rb +7 -7
- data/lib/microsandbox/image.rb +1 -1
- data/lib/microsandbox/network.rb +19 -19
- data/lib/microsandbox/patch.rb +8 -8
- data/lib/microsandbox/sandbox.rb +199 -75
- data/lib/microsandbox/snapshot.rb +2 -2
- data/lib/microsandbox/ssh.rb +2 -2
- data/lib/microsandbox/version.rb +2 -2
- data/lib/microsandbox/volume.rb +3 -3
- data/lib/microsandbox.rb +61 -0
- data/sig/microsandbox.rbs +31 -13
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d4d9e8db2dddac7a22c2910c82a56603e95ad702d328c6a020f514997d29859c
|
|
4
|
+
data.tar.gz: 5f19089f8d1d0f18d5d930cf49576d25862f02323495ffa02db683f57a3439cd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 88e44654909dd3f39ac23c6cf682bd62519bbaf7f57ca24f611a66e05bb66c825919fc1f2be6f9044513c99508bfedd412e5c72c1f15fc8b66c3ac11ee2b78ac
|
|
7
|
+
data.tar.gz: 00b0f44a4568107891a2ce9a623950245457ea51d0700f45333b96fec7eb73e6572b8b9b67b4147490423687fa1ff7dcb96b6edd29c2aa28c3ed22807eab7bdb
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,83 @@ upstream microsandbox runtime.
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.5.10] - 2026-06-22
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **Streaming stdin pipe for `exec_stream`/`shell_stream`** (`stdin: :pipe`).
|
|
14
|
+
Opens a writable `ExecHandle#stdin` sink (`ExecStdin`) lifted out of the core
|
|
15
|
+
handle via `take_stdin`, distinct from the existing fixed-bytes `stdin:`
|
|
16
|
+
buffer. This is the load-bearing primitive for driving an interactive
|
|
17
|
+
long-running process (e.g. a `claude` CLI) over `exec_stream` from a host
|
|
18
|
+
reactor. The published `0.5.9` shipped without it (`stdin: :pipe` was fed as
|
|
19
|
+
the literal byte string `"pipe"`), so any consumer of the streaming sink must
|
|
20
|
+
require `>= 0.5.10`.
|
|
21
|
+
|
|
22
|
+
Adopts the upstream **microsandbox `v0.5.8`** runtime (was `v0.5.7`), whose
|
|
23
|
+
backend-routing rewrite (upstream PR #754) both adds new surface and reshapes the
|
|
24
|
+
sandbox lifecycle.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- **BREAKING — sandbox lifecycle split (mirrors the official Python/Node SDKs).**
|
|
29
|
+
Upstream `v0.5.8` split the lifecycle across a live `Sandbox` and a lightweight
|
|
30
|
+
`SandboxHandle`. The gem follows suit:
|
|
31
|
+
- The live `Microsandbox::Sandbox` (from `Sandbox.create`/`Sandbox.start`) now
|
|
32
|
+
exposes `#stop`, `#stop_and_wait`, `#kill`, `#drain`, `#wait`, `#status`,
|
|
33
|
+
`#detach`, and `#owns_lifecycle?`. `#stop` and `#kill` **no longer take a
|
|
34
|
+
`timeout:`** keyword; `#stop` performs the graceful SIGTERM→SIGKILL
|
|
35
|
+
escalation (10s default) the official SDKs use.
|
|
36
|
+
- `#request_stop`, `#request_kill`, `#request_drain`, `#wait_until_stopped`,
|
|
37
|
+
and a custom stop/kill timeout have **moved off** the live `Sandbox` onto the
|
|
38
|
+
controllable `Microsandbox::SandboxHandle` (see Added).
|
|
39
|
+
- **BREAKING — `Sandbox.get`/`.list`/`.list_with` now return a controllable
|
|
40
|
+
`Microsandbox::SandboxHandle`** instead of a read-only `SandboxInfo`. The
|
|
41
|
+
handle keeps the same metadata accessors (`name`, `status`, `created_at`,
|
|
42
|
+
`updated_at`, `running?`, `stopped?`). `Microsandbox::SandboxInfo` remains as a
|
|
43
|
+
deprecated constant alias for `SandboxHandle`.
|
|
44
|
+
- `SandboxStatus` gained two values, `:created` and `:starting` (cloud-only
|
|
45
|
+
today), so `#status` may now return them.
|
|
46
|
+
|
|
47
|
+
### Added
|
|
48
|
+
|
|
49
|
+
- **Backend routing** — `Microsandbox.set_default_backend(kind, url:, api_key:,
|
|
50
|
+
profile:)`, `Microsandbox.with_backend(kind, …) { … }` (a scoped, restoring
|
|
51
|
+
override), and `Microsandbox.default_backend_kind`. Without configuration the
|
|
52
|
+
runtime resolves a backend lazily from `MSB_BACKEND`, `MSB_API_URL` +
|
|
53
|
+
`MSB_API_KEY`, `MSB_PROFILE`, and `~/.microsandbox/config.json` (honoring
|
|
54
|
+
`MSB_CONFIG_PATH`). The cloud backend supports a documented subset
|
|
55
|
+
(create/start/stop/remove/get/list, one-shot exec, follow log streaming);
|
|
56
|
+
unsupported operations raise `UnsupportedError`. Under a cloud backend,
|
|
57
|
+
`Sandbox.create`/`.start` skip local `msb`/`libkrunfw` runtime provisioning
|
|
58
|
+
(it isn't needed), so cloud-only hosts no longer trigger a spurious download.
|
|
59
|
+
- **`Microsandbox::SandboxHandle`** — the controllable handle returned by
|
|
60
|
+
`Sandbox.get`/`.list`/`.list_with`: `#stop`, `#stop_with_timeout(secs)`,
|
|
61
|
+
`#kill`, `#kill_with_timeout(secs)`, `#request_stop`, `#request_kill`,
|
|
62
|
+
`#request_drain`, `#wait_until_stopped` (→ `SandboxStopResult`), plus the
|
|
63
|
+
metadata accessors. Mirrors the official SDKs' `SandboxHandle`.
|
|
64
|
+
- **`Sandbox#stop_and_wait` / `Sandbox#wait`** — return a `Microsandbox::ExitStatus`
|
|
65
|
+
(`#exit_code`, `#success?`). **`Sandbox#drain`** triggers a graceful drain.
|
|
66
|
+
**`Sandbox#status`** fetches the live status from the backend.
|
|
67
|
+
- **`Microsandbox.libkrunfw_path=`** — overrides the `libkrunfw` shared-library
|
|
68
|
+
path (SDK tier of the resolver; `MSB_LIBKRUNFW_PATH` still wins). Mirrors
|
|
69
|
+
`runtime_path=`.
|
|
70
|
+
- **`Microsandbox::CloudHttpError`** (`cloud-http`) and
|
|
71
|
+
**`Microsandbox::UnsupportedError`** (`unsupported`) — distinct from the
|
|
72
|
+
existing `UnsupportedOperationError`.
|
|
73
|
+
|
|
74
|
+
### Fixed
|
|
75
|
+
|
|
76
|
+
- **Reject invalid durations with a clear `ArgumentError`** — negative, `NaN`,
|
|
77
|
+
and infinite values passed to `timeout:` (`exec`/`shell`),
|
|
78
|
+
`SandboxHandle#stop_with_timeout`/`#kill_with_timeout`, `replace_with_timeout:`,
|
|
79
|
+
and `metrics_stream(interval:)` are rejected in Ruby before reaching the native
|
|
80
|
+
layer, where they would otherwise panic across the FFI boundary
|
|
81
|
+
(`Duration::from_secs_f64` panics on exactly those inputs).
|
|
82
|
+
- **Reject contradictory `image:` + `from_snapshot:`** — `Sandbox.create` now
|
|
83
|
+
raises `ArgumentError` when both are given (a sandbox boots from exactly one
|
|
84
|
+
rootfs source), failing fast instead of after a runtime round-trip.
|
|
85
|
+
|
|
9
86
|
## [0.5.9] - 2026-06-18
|
|
10
87
|
|
|
11
88
|
Closes the remaining roadmap items, bringing the binding surface to parity with
|
data/Cargo.lock
CHANGED
|
@@ -3003,8 +3003,8 @@ dependencies = [
|
|
|
3003
3003
|
|
|
3004
3004
|
[[package]]
|
|
3005
3005
|
name = "microsandbox"
|
|
3006
|
-
version = "0.5.
|
|
3007
|
-
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.
|
|
3006
|
+
version = "0.5.8"
|
|
3007
|
+
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.8#47d0cdf1ef3b4b41885eb3efd67b759fd5540e9e"
|
|
3008
3008
|
dependencies = [
|
|
3009
3009
|
"anyhow",
|
|
3010
3010
|
"astral-tokio-tar",
|
|
@@ -3031,6 +3031,7 @@ dependencies = [
|
|
|
3031
3031
|
"microsandbox-network",
|
|
3032
3032
|
"microsandbox-protocol",
|
|
3033
3033
|
"microsandbox-runtime",
|
|
3034
|
+
"microsandbox-types",
|
|
3034
3035
|
"microsandbox-utils",
|
|
3035
3036
|
"nix 0.31.3",
|
|
3036
3037
|
"notify",
|
|
@@ -3047,6 +3048,7 @@ dependencies = [
|
|
|
3047
3048
|
"tempfile",
|
|
3048
3049
|
"thiserror 2.0.18",
|
|
3049
3050
|
"tokio",
|
|
3051
|
+
"tokio-tungstenite",
|
|
3050
3052
|
"tracing",
|
|
3051
3053
|
"typed-builder",
|
|
3052
3054
|
"which",
|
|
@@ -3054,8 +3056,8 @@ dependencies = [
|
|
|
3054
3056
|
|
|
3055
3057
|
[[package]]
|
|
3056
3058
|
name = "microsandbox-agent-client"
|
|
3057
|
-
version = "0.5.
|
|
3058
|
-
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.
|
|
3059
|
+
version = "0.5.8"
|
|
3060
|
+
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.8#47d0cdf1ef3b4b41885eb3efd67b759fd5540e9e"
|
|
3059
3061
|
dependencies = [
|
|
3060
3062
|
"ciborium",
|
|
3061
3063
|
"microsandbox-protocol",
|
|
@@ -3067,8 +3069,8 @@ dependencies = [
|
|
|
3067
3069
|
|
|
3068
3070
|
[[package]]
|
|
3069
3071
|
name = "microsandbox-db"
|
|
3070
|
-
version = "0.5.
|
|
3071
|
-
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.
|
|
3072
|
+
version = "0.5.8"
|
|
3073
|
+
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.8#47d0cdf1ef3b4b41885eb3efd67b759fd5540e9e"
|
|
3072
3074
|
dependencies = [
|
|
3073
3075
|
"async-trait",
|
|
3074
3076
|
"sea-orm",
|
|
@@ -3079,8 +3081,8 @@ dependencies = [
|
|
|
3079
3081
|
|
|
3080
3082
|
[[package]]
|
|
3081
3083
|
name = "microsandbox-filesystem"
|
|
3082
|
-
version = "0.5.
|
|
3083
|
-
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.
|
|
3084
|
+
version = "0.5.8"
|
|
3085
|
+
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.8#47d0cdf1ef3b4b41885eb3efd67b759fd5540e9e"
|
|
3084
3086
|
dependencies = [
|
|
3085
3087
|
"libc",
|
|
3086
3088
|
"microsandbox-utils",
|
|
@@ -3092,8 +3094,8 @@ dependencies = [
|
|
|
3092
3094
|
|
|
3093
3095
|
[[package]]
|
|
3094
3096
|
name = "microsandbox-image"
|
|
3095
|
-
version = "0.5.
|
|
3096
|
-
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.
|
|
3097
|
+
version = "0.5.8"
|
|
3098
|
+
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.8#47d0cdf1ef3b4b41885eb3efd67b759fd5540e9e"
|
|
3097
3099
|
dependencies = [
|
|
3098
3100
|
"astral-tokio-tar",
|
|
3099
3101
|
"async-compression",
|
|
@@ -3118,8 +3120,8 @@ dependencies = [
|
|
|
3118
3120
|
|
|
3119
3121
|
[[package]]
|
|
3120
3122
|
name = "microsandbox-metrics"
|
|
3121
|
-
version = "0.5.
|
|
3122
|
-
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.
|
|
3123
|
+
version = "0.5.8"
|
|
3124
|
+
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.8#47d0cdf1ef3b4b41885eb3efd67b759fd5540e9e"
|
|
3123
3125
|
dependencies = [
|
|
3124
3126
|
"chrono",
|
|
3125
3127
|
"libc",
|
|
@@ -3129,8 +3131,8 @@ dependencies = [
|
|
|
3129
3131
|
|
|
3130
3132
|
[[package]]
|
|
3131
3133
|
name = "microsandbox-migration"
|
|
3132
|
-
version = "0.5.
|
|
3133
|
-
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.
|
|
3134
|
+
version = "0.5.8"
|
|
3135
|
+
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.8#47d0cdf1ef3b4b41885eb3efd67b759fd5540e9e"
|
|
3134
3136
|
dependencies = [
|
|
3135
3137
|
"sea-orm-migration",
|
|
3136
3138
|
"serde_json",
|
|
@@ -3138,8 +3140,8 @@ dependencies = [
|
|
|
3138
3140
|
|
|
3139
3141
|
[[package]]
|
|
3140
3142
|
name = "microsandbox-network"
|
|
3141
|
-
version = "0.5.
|
|
3142
|
-
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.
|
|
3143
|
+
version = "0.5.8"
|
|
3144
|
+
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.8#47d0cdf1ef3b4b41885eb3efd67b759fd5540e9e"
|
|
3143
3145
|
dependencies = [
|
|
3144
3146
|
"base64",
|
|
3145
3147
|
"bytes",
|
|
@@ -3178,11 +3180,12 @@ dependencies = [
|
|
|
3178
3180
|
|
|
3179
3181
|
[[package]]
|
|
3180
3182
|
name = "microsandbox-protocol"
|
|
3181
|
-
version = "0.5.
|
|
3182
|
-
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.
|
|
3183
|
+
version = "0.5.8"
|
|
3184
|
+
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.8#47d0cdf1ef3b4b41885eb3efd67b759fd5540e9e"
|
|
3183
3185
|
dependencies = [
|
|
3184
3186
|
"chrono",
|
|
3185
3187
|
"ciborium",
|
|
3188
|
+
"microsandbox-types",
|
|
3186
3189
|
"serde",
|
|
3187
3190
|
"serde_bytes",
|
|
3188
3191
|
"strum 0.28.0",
|
|
@@ -3192,19 +3195,21 @@ dependencies = [
|
|
|
3192
3195
|
|
|
3193
3196
|
[[package]]
|
|
3194
3197
|
name = "microsandbox-runtime"
|
|
3195
|
-
version = "0.5.
|
|
3196
|
-
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.
|
|
3198
|
+
version = "0.5.8"
|
|
3199
|
+
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.8#47d0cdf1ef3b4b41885eb3efd67b759fd5540e9e"
|
|
3197
3200
|
dependencies = [
|
|
3198
3201
|
"bytes",
|
|
3199
3202
|
"chrono",
|
|
3200
3203
|
"clap",
|
|
3201
3204
|
"crossbeam-queue",
|
|
3202
3205
|
"libc",
|
|
3206
|
+
"microsandbox-agent-client",
|
|
3203
3207
|
"microsandbox-db",
|
|
3204
3208
|
"microsandbox-filesystem",
|
|
3205
3209
|
"microsandbox-metrics",
|
|
3206
3210
|
"microsandbox-network",
|
|
3207
3211
|
"microsandbox-protocol",
|
|
3212
|
+
"microsandbox-types",
|
|
3208
3213
|
"microsandbox-utils",
|
|
3209
3214
|
"msb_krun",
|
|
3210
3215
|
"nix 0.31.3",
|
|
@@ -3218,10 +3223,22 @@ dependencies = [
|
|
|
3218
3223
|
"tracing",
|
|
3219
3224
|
]
|
|
3220
3225
|
|
|
3226
|
+
[[package]]
|
|
3227
|
+
name = "microsandbox-types"
|
|
3228
|
+
version = "0.5.8"
|
|
3229
|
+
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.8#47d0cdf1ef3b4b41885eb3efd67b759fd5540e9e"
|
|
3230
|
+
dependencies = [
|
|
3231
|
+
"chrono",
|
|
3232
|
+
"serde",
|
|
3233
|
+
"serde_json",
|
|
3234
|
+
"sha2 0.11.0",
|
|
3235
|
+
"thiserror 2.0.18",
|
|
3236
|
+
]
|
|
3237
|
+
|
|
3221
3238
|
[[package]]
|
|
3222
3239
|
name = "microsandbox-utils"
|
|
3223
|
-
version = "0.5.
|
|
3224
|
-
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.
|
|
3240
|
+
version = "0.5.8"
|
|
3241
|
+
source = "git+https://github.com/superradcompany/microsandbox?tag=v0.5.8#47d0cdf1ef3b4b41885eb3efd67b759fd5540e9e"
|
|
3225
3242
|
dependencies = [
|
|
3226
3243
|
"dirs",
|
|
3227
3244
|
"libc",
|
|
@@ -3232,7 +3249,7 @@ dependencies = [
|
|
|
3232
3249
|
|
|
3233
3250
|
[[package]]
|
|
3234
3251
|
name = "microsandbox_rb"
|
|
3235
|
-
version = "0.5.
|
|
3252
|
+
version = "0.5.10"
|
|
3236
3253
|
dependencies = [
|
|
3237
3254
|
"chrono",
|
|
3238
3255
|
"futures",
|
|
@@ -3306,9 +3323,9 @@ dependencies = [
|
|
|
3306
3323
|
|
|
3307
3324
|
[[package]]
|
|
3308
3325
|
name = "msb_krun"
|
|
3309
|
-
version = "0.1.
|
|
3326
|
+
version = "0.1.17"
|
|
3310
3327
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3311
|
-
checksum = "
|
|
3328
|
+
checksum = "72a554acf513be16b336fbcd4a9bab29a78b06a5ddf94e917481cfeafc1078f5"
|
|
3312
3329
|
dependencies = [
|
|
3313
3330
|
"crossbeam-channel",
|
|
3314
3331
|
"kvm-bindings",
|
|
@@ -3326,9 +3343,9 @@ dependencies = [
|
|
|
3326
3343
|
|
|
3327
3344
|
[[package]]
|
|
3328
3345
|
name = "msb_krun_arch"
|
|
3329
|
-
version = "0.1.
|
|
3346
|
+
version = "0.1.17"
|
|
3330
3347
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3331
|
-
checksum = "
|
|
3348
|
+
checksum = "9d270d914cee3125cf71734b9a5aa60fe7d9648f09511999199424e0fe1a88c6"
|
|
3332
3349
|
dependencies = [
|
|
3333
3350
|
"kvm-bindings",
|
|
3334
3351
|
"kvm-ioctls",
|
|
@@ -3342,15 +3359,15 @@ dependencies = [
|
|
|
3342
3359
|
|
|
3343
3360
|
[[package]]
|
|
3344
3361
|
name = "msb_krun_arch_gen"
|
|
3345
|
-
version = "0.1.
|
|
3362
|
+
version = "0.1.17"
|
|
3346
3363
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3347
|
-
checksum = "
|
|
3364
|
+
checksum = "8372d1e4e8c853e20ffb5568a4cc3f930a2bf1ce25bc346812ac7b84e84639d4"
|
|
3348
3365
|
|
|
3349
3366
|
[[package]]
|
|
3350
3367
|
name = "msb_krun_cpuid"
|
|
3351
|
-
version = "0.1.
|
|
3368
|
+
version = "0.1.17"
|
|
3352
3369
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3353
|
-
checksum = "
|
|
3370
|
+
checksum = "179542321455c65a8e4b14c09bc8443227a89cd46ef2c9c06f0ee1ab11f510ea"
|
|
3354
3371
|
dependencies = [
|
|
3355
3372
|
"kvm-bindings",
|
|
3356
3373
|
"kvm-ioctls",
|
|
@@ -3359,9 +3376,9 @@ dependencies = [
|
|
|
3359
3376
|
|
|
3360
3377
|
[[package]]
|
|
3361
3378
|
name = "msb_krun_devices"
|
|
3362
|
-
version = "0.1.
|
|
3379
|
+
version = "0.1.17"
|
|
3363
3380
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3364
|
-
checksum = "
|
|
3381
|
+
checksum = "67350e76fd466e1a089b89fa548ba85a92f237c2d3dab179ba675cfd18eb9a39"
|
|
3365
3382
|
dependencies = [
|
|
3366
3383
|
"bitflags 1.3.2",
|
|
3367
3384
|
"capng",
|
|
@@ -3387,9 +3404,9 @@ dependencies = [
|
|
|
3387
3404
|
|
|
3388
3405
|
[[package]]
|
|
3389
3406
|
name = "msb_krun_hvf"
|
|
3390
|
-
version = "0.1.
|
|
3407
|
+
version = "0.1.17"
|
|
3391
3408
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3392
|
-
checksum = "
|
|
3409
|
+
checksum = "13eaca12857149c3552007a18c7f863ccc6b4dddcf2863c0bcc8fbc2aa2d4c6e"
|
|
3393
3410
|
dependencies = [
|
|
3394
3411
|
"crossbeam-channel",
|
|
3395
3412
|
"libloading",
|
|
@@ -3399,9 +3416,9 @@ dependencies = [
|
|
|
3399
3416
|
|
|
3400
3417
|
[[package]]
|
|
3401
3418
|
name = "msb_krun_kernel"
|
|
3402
|
-
version = "0.1.
|
|
3419
|
+
version = "0.1.17"
|
|
3403
3420
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3404
|
-
checksum = "
|
|
3421
|
+
checksum = "514f7493860978b08819fdcc4ef3d1887fd4d2b5e26ad0a0eabcec005410df94"
|
|
3405
3422
|
dependencies = [
|
|
3406
3423
|
"msb_krun_utils",
|
|
3407
3424
|
"vm-memory 0.16.2",
|
|
@@ -3409,9 +3426,9 @@ dependencies = [
|
|
|
3409
3426
|
|
|
3410
3427
|
[[package]]
|
|
3411
3428
|
name = "msb_krun_polly"
|
|
3412
|
-
version = "0.1.
|
|
3429
|
+
version = "0.1.17"
|
|
3413
3430
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3414
|
-
checksum = "
|
|
3431
|
+
checksum = "08ebbb0336b9cd8dcffa9c47d01a729de4f83c39fc099620f4f9c4d8ef69f460"
|
|
3415
3432
|
dependencies = [
|
|
3416
3433
|
"libc",
|
|
3417
3434
|
"msb_krun_utils",
|
|
@@ -3419,18 +3436,18 @@ dependencies = [
|
|
|
3419
3436
|
|
|
3420
3437
|
[[package]]
|
|
3421
3438
|
name = "msb_krun_smbios"
|
|
3422
|
-
version = "0.1.
|
|
3439
|
+
version = "0.1.17"
|
|
3423
3440
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3424
|
-
checksum = "
|
|
3441
|
+
checksum = "f25cb991386c6aca7c74d0bd8b327a807290830e439fbb473c5e1b62a7c66d32"
|
|
3425
3442
|
dependencies = [
|
|
3426
3443
|
"vm-memory 0.16.2",
|
|
3427
3444
|
]
|
|
3428
3445
|
|
|
3429
3446
|
[[package]]
|
|
3430
3447
|
name = "msb_krun_utils"
|
|
3431
|
-
version = "0.1.
|
|
3448
|
+
version = "0.1.17"
|
|
3432
3449
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3433
|
-
checksum = "
|
|
3450
|
+
checksum = "b7104f87f235ef5cc320ffa760b7cd3635960b58cdc5e1ec89df852fc538f042"
|
|
3434
3451
|
dependencies = [
|
|
3435
3452
|
"bitflags 1.3.2",
|
|
3436
3453
|
"crossbeam-channel",
|
|
@@ -3443,9 +3460,9 @@ dependencies = [
|
|
|
3443
3460
|
|
|
3444
3461
|
[[package]]
|
|
3445
3462
|
name = "msb_krun_vmm"
|
|
3446
|
-
version = "0.1.
|
|
3463
|
+
version = "0.1.17"
|
|
3447
3464
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3448
|
-
checksum = "
|
|
3465
|
+
checksum = "6742a7fba174849b924a370bfba0fe7be8435253bff26303aec34ac89641ae63"
|
|
3449
3466
|
dependencies = [
|
|
3450
3467
|
"bzip2",
|
|
3451
3468
|
"crossbeam-channel",
|
|
@@ -6009,6 +6026,18 @@ dependencies = [
|
|
|
6009
6026
|
"tokio",
|
|
6010
6027
|
]
|
|
6011
6028
|
|
|
6029
|
+
[[package]]
|
|
6030
|
+
name = "tokio-tungstenite"
|
|
6031
|
+
version = "0.29.0"
|
|
6032
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
6033
|
+
checksum = "8f72a05e828585856dacd553fba484c242c46e391fb0e58917c942ee9202915c"
|
|
6034
|
+
dependencies = [
|
|
6035
|
+
"futures-util",
|
|
6036
|
+
"log",
|
|
6037
|
+
"tokio",
|
|
6038
|
+
"tungstenite",
|
|
6039
|
+
]
|
|
6040
|
+
|
|
6012
6041
|
[[package]]
|
|
6013
6042
|
name = "tokio-util"
|
|
6014
6043
|
version = "0.7.18"
|
|
@@ -6151,6 +6180,22 @@ version = "0.2.5"
|
|
|
6151
6180
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
6152
6181
|
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
|
6153
6182
|
|
|
6183
|
+
[[package]]
|
|
6184
|
+
name = "tungstenite"
|
|
6185
|
+
version = "0.29.0"
|
|
6186
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
6187
|
+
checksum = "6c01152af293afb9c7c2a57e4b559c5620b421f6d133261c60dd2d0cdb38e6b8"
|
|
6188
|
+
dependencies = [
|
|
6189
|
+
"bytes",
|
|
6190
|
+
"data-encoding",
|
|
6191
|
+
"http",
|
|
6192
|
+
"httparse",
|
|
6193
|
+
"log",
|
|
6194
|
+
"rand 0.9.4",
|
|
6195
|
+
"sha1 0.10.6",
|
|
6196
|
+
"thiserror 2.0.18",
|
|
6197
|
+
]
|
|
6198
|
+
|
|
6154
6199
|
[[package]]
|
|
6155
6200
|
name = "typed-builder"
|
|
6156
6201
|
version = "0.23.2"
|
data/DESIGN.md
CHANGED
|
@@ -126,9 +126,13 @@ git. The override must never be committed — it would break container builds.
|
|
|
126
126
|
## Implemented surface (v1) vs roadmap
|
|
127
127
|
|
|
128
128
|
**Implemented:** sandbox lifecycle (`create`/`start`/`get`/`list`/`list_with`/
|
|
129
|
-
`remove
|
|
130
|
-
`
|
|
131
|
-
|
|
129
|
+
`remove`; the live `Sandbox` exposes `stop`/`stop_and_wait`/`kill`/`drain`/
|
|
130
|
+
`wait` (→ `ExitStatus`) / `status` / `detach` / `owns_lifecycle?`, while the
|
|
131
|
+
controllable `SandboxHandle` from `get`/`list` carries the fine-grained
|
|
132
|
+
`stop_with_timeout`/`request_stop`/`request_kill`/`request_drain`/
|
|
133
|
+
`wait_until_stopped` (→ `SandboxStopResult`) controls — the v0.5.8 live-vs-handle
|
|
134
|
+
split that mirrors the official SDKs), backend routing (`set_default_backend`/
|
|
135
|
+
`with_backend`/`default_backend_kind`), block form), `exec`/`shell` with collected `ExecOutput`,
|
|
132
136
|
**streaming** `exec_stream`/`shell_stream` (`ExecHandle` is `Enumerable` over
|
|
133
137
|
`ExecEvent`s, with stdin sink + signal/kill/resize), the full guest filesystem
|
|
134
138
|
API (`fs.read`/`write`/`list`/`mkdir`/`remove`/`stat`/…), `metrics`,
|
data/README.md
CHANGED
|
@@ -4,7 +4,31 @@ Lightweight microVM sandboxes for Ruby — run AI agents and untrusted code with
|
|
|
4
4
|
|
|
5
5
|
The `microsandbox-rb` gem provides native bindings to the [microsandbox](https://github.com/superradcompany/microsandbox) runtime via a Rust extension (magnus). It spins up real microVMs (not containers) in under 100 ms, runs standard OCI (Docker) images, and gives you full control over command execution, the guest filesystem, networking, and metrics — all from an idiomatic, **synchronous** Ruby API. There is no daemon to install and no server to connect to: the runtime is embedded directly in your process.
|
|
6
6
|
|
|
7
|
-
This is an **unofficial, community-maintained** Ruby implementation — not part of the official SDK family
|
|
7
|
+
This is an **unofficial, community-maintained** Ruby implementation — not part of the official SDK family — though it wraps the same core engine.
|
|
8
|
+
|
|
9
|
+
## Upstream & acknowledgements
|
|
10
|
+
|
|
11
|
+
`microsandbox-rb` exists only because of the excellent work by the [Super Rad
|
|
12
|
+
Company](https://github.com/superradcompany) team on the upstream
|
|
13
|
+
**microsandbox** runtime. All the hard parts — the microVM engine, the guest
|
|
14
|
+
`agentd`, the networking stack — are theirs; this gem is a thin Ruby skin over
|
|
15
|
+
them. Our deepest thanks to the maintainers and community. 🙏
|
|
16
|
+
|
|
17
|
+
- **Website & docs** — <https://microsandbox.dev> · [documentation](https://docs.microsandbox.dev)
|
|
18
|
+
- **Official repository** — [superradcompany/microsandbox](https://github.com/superradcompany/microsandbox)
|
|
19
|
+
- **Official SDKs** —
|
|
20
|
+
[Rust](https://github.com/superradcompany/microsandbox/tree/main/sdk) ·
|
|
21
|
+
[Python](https://github.com/superradcompany/microsandbox/tree/main/sdk/python) ·
|
|
22
|
+
[TypeScript / Node](https://github.com/superradcompany/microsandbox/tree/main/sdk/node-ts) ·
|
|
23
|
+
[Go](https://github.com/superradcompany/microsandbox/tree/main/sdk/go)
|
|
24
|
+
- **Agents** — [Agent Skills](https://github.com/superradcompany/skills) · [MCP server](https://github.com/superradcompany/microsandbox-mcp)
|
|
25
|
+
- **Community** — [Discord](https://discord.gg/T95Y3XnEAK)
|
|
26
|
+
|
|
27
|
+
> **Not affiliated.** This gem is an independent, community-maintained project.
|
|
28
|
+
> It is **not** built, endorsed, or supported by Super Rad Company or the
|
|
29
|
+
> microsandbox team. Please don't direct questions about this gem to the
|
|
30
|
+
> upstream project — open an issue here instead. **Contributions are very
|
|
31
|
+
> welcome — PRs welcome!** See [Contributing](#contributing).
|
|
8
32
|
|
|
9
33
|
## Features
|
|
10
34
|
|
|
@@ -97,17 +121,33 @@ sb = Microsandbox::Sandbox.create("box", image: "public.ecr.aws/docker/library/a
|
|
|
97
121
|
begin
|
|
98
122
|
# ...
|
|
99
123
|
ensure
|
|
100
|
-
sb.stop # graceful (
|
|
101
|
-
# sb.
|
|
124
|
+
sb.stop # graceful (SIGTERM→SIGKILL escalation, 10s default)
|
|
125
|
+
# sb.stop_and_wait # graceful, then wait → ExitStatus(#exit_code, #success?)
|
|
126
|
+
# sb.kill # force (SIGKILL); sb.drain for a graceful drain
|
|
102
127
|
end
|
|
103
128
|
|
|
104
|
-
# Inspect / manage existing sandboxes
|
|
105
|
-
|
|
106
|
-
|
|
129
|
+
# Inspect / manage existing sandboxes. `get`/`list` return a controllable
|
|
130
|
+
# SandboxHandle (the live `stop`/`kill`/`drain`/`wait` live on the object from
|
|
131
|
+
# `create`/`start`; fine-grained control lives on the handle).
|
|
132
|
+
Microsandbox::Sandbox.list # => [Microsandbox::SandboxHandle, ...]
|
|
133
|
+
h = Microsandbox::Sandbox.get("box") # => Microsandbox::SandboxHandle
|
|
134
|
+
h.status # :running, :stopped, :created, ...
|
|
135
|
+
h.stop_with_timeout(5) # custom escalation timeout
|
|
136
|
+
h.request_stop # fire-and-return; pair with #wait_until_stopped
|
|
137
|
+
h.request_kill
|
|
138
|
+
h.request_drain
|
|
139
|
+
h.wait_until_stopped # => Microsandbox::SandboxStopResult
|
|
107
140
|
Microsandbox::Sandbox.start("box") # restart a stopped sandbox
|
|
108
141
|
Microsandbox::Sandbox.remove("box") # remove a stopped sandbox
|
|
109
142
|
```
|
|
110
143
|
|
|
144
|
+
> **v0.5.8 lifecycle change.** Upstream split the lifecycle into the live
|
|
145
|
+
> `Sandbox` and a controllable `SandboxHandle`, and the gem mirrors it. The live
|
|
146
|
+
> `Sandbox#stop`/`#kill` no longer take a `timeout:`; `#request_stop`/
|
|
147
|
+
> `#request_kill`/`#request_drain`/`#wait_until_stopped` and a custom stop timeout
|
|
148
|
+
> now live on the `SandboxHandle` from `Sandbox.get`. `Sandbox.get`/`.list` return
|
|
149
|
+
> a `SandboxHandle` (was a read-only `SandboxInfo`, kept as a deprecated alias).
|
|
150
|
+
|
|
111
151
|
### Configuration
|
|
112
152
|
|
|
113
153
|
```ruby
|
|
@@ -197,8 +237,9 @@ Microsandbox::Sandbox.create("stream", image: "public.ecr.aws/docker/library/pyt
|
|
|
197
237
|
print event.text if event.stdout?
|
|
198
238
|
end
|
|
199
239
|
# or: out = handle.collect → ExecOutput (drain to the end)
|
|
200
|
-
# interactive stdin:
|
|
201
|
-
#
|
|
240
|
+
# interactive stdin — create the stream with stdin: :pipe to get a writable sink:
|
|
241
|
+
# h = sb.exec_stream("cat", [], stdin: :pipe)
|
|
242
|
+
# sink = h.stdin; sink.write("data\n"); sink.close # close sends EOF
|
|
202
243
|
# control: handle.signal(15), handle.kill, handle.resize(rows, cols)
|
|
203
244
|
end
|
|
204
245
|
```
|
|
@@ -307,8 +348,32 @@ Microsandbox.installed? # => true/false
|
|
|
307
348
|
Microsandbox.install # download + install the runtime (idempotent)
|
|
308
349
|
Microsandbox.runtime_path # => "/Users/you/.microsandbox/bin/msb"
|
|
309
350
|
Microsandbox.runtime_path = "/opt/microsandbox/bin/msb" # override
|
|
351
|
+
Microsandbox.libkrunfw_path = "/opt/microsandbox/lib/libkrunfw.dylib" # override (set-once)
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### Backend routing
|
|
355
|
+
|
|
356
|
+
As of v0.5.8 every operation runs through a backend. The default is the local
|
|
357
|
+
libkrun backend; without any configuration nothing changes. A backend can be
|
|
358
|
+
selected programmatically or via the environment:
|
|
359
|
+
|
|
360
|
+
```ruby
|
|
361
|
+
Microsandbox.default_backend_kind # => :local (or :cloud)
|
|
362
|
+
Microsandbox.set_default_backend(:cloud, url: "https://api.example.com", api_key: ENV["MSB_API_KEY"])
|
|
363
|
+
# or a named profile from ~/.microsandbox/config.json:
|
|
364
|
+
Microsandbox.set_default_backend(:cloud, profile: "prod")
|
|
365
|
+
|
|
366
|
+
# Scoped override (restored afterward, even on error):
|
|
367
|
+
Microsandbox.with_backend(:local) { Microsandbox::Sandbox.create("box", image: "alpine") { |sb| ... } }
|
|
310
368
|
```
|
|
311
369
|
|
|
370
|
+
Resolution order when no backend is set programmatically: `MSB_BACKEND`
|
|
371
|
+
(`local`/`cloud`) → `MSB_API_URL` + `MSB_API_KEY` → `MSB_PROFILE` → the
|
|
372
|
+
`active_profile` in `~/.microsandbox/config.json` (path overridable via
|
|
373
|
+
`MSB_CONFIG_PATH`) → local. The cloud backend currently supports a subset of
|
|
374
|
+
operations (create/start/stop/remove/get/list, one-shot exec, follow log
|
|
375
|
+
streaming); unsupported operations raise `Microsandbox::UnsupportedError`.
|
|
376
|
+
|
|
312
377
|
## Development
|
|
313
378
|
|
|
314
379
|
```bash
|
|
@@ -335,21 +400,9 @@ bundle exec rake compile
|
|
|
335
400
|
## Releasing
|
|
336
401
|
|
|
337
402
|
Releases are automated by `.github/workflows/release.yml` via RubyGems
|
|
338
|
-
**Trusted Publishing** (OIDC) — there is no API key to store as a secret.
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
publisher at <https://rubygems.org/profile/oidc/pending_trusted_publishers>:
|
|
342
|
-
|
|
343
|
-
| Field | Value |
|
|
344
|
-
|-------|-------|
|
|
345
|
-
| RubyGems gem name | `microsandbox-rb` |
|
|
346
|
-
| Repository owner | `ya-luotao` |
|
|
347
|
-
| Repository name | `microsandbox-rb` |
|
|
348
|
-
| Workflow filename | `release.yml` |
|
|
349
|
-
| Environment | *(leave blank)* |
|
|
350
|
-
|
|
351
|
-
On the first successful push the pending publisher auto-converts to a permanent
|
|
352
|
-
one bound to the gem.
|
|
403
|
+
**Trusted Publishing** (OIDC) — there is no API key to store as a secret. The
|
|
404
|
+
trusted publisher is already configured for this gem, so no per-release secret
|
|
405
|
+
or credential setup is needed.
|
|
353
406
|
|
|
354
407
|
**Each release:**
|
|
355
408
|
|
|
@@ -377,9 +430,12 @@ one bound to the gem.
|
|
|
377
430
|
|
|
378
431
|
See [DESIGN.md](DESIGN.md) for the architecture and the implemented-surface
|
|
379
432
|
section. The binding now covers the full official-SDK surface: sandbox
|
|
380
|
-
lifecycle (
|
|
381
|
-
`
|
|
382
|
-
`
|
|
433
|
+
lifecycle (the live `Sandbox` `stop`/`stop_and_wait`/`kill`/`drain`/`wait`/
|
|
434
|
+
`status`/`detach`/`owns_lifecycle?`, plus the `SandboxHandle` controls
|
|
435
|
+
`stop_with_timeout`/`request_stop`/`request_kill`/`request_drain`/
|
|
436
|
+
`wait_until_stopped` from `Sandbox.get`, and label-filtered `list_with`),
|
|
437
|
+
backend routing (`set_default_backend`/`with_backend`/`default_backend_kind`),
|
|
438
|
+
`exec`/`shell` (collected and streaming), interactive `attach`/
|
|
383
439
|
`attach_shell`, the full guest filesystem, metrics (per-sandbox,
|
|
384
440
|
`Microsandbox.all_sandbox_metrics`, and streaming `metrics_stream`/`log_stream`),
|
|
385
441
|
logs, OCI image-cache management, named volumes, snapshots (create/list/verify/
|
|
@@ -393,6 +449,15 @@ export/import + boot-from-snapshot), **rootfs patches** (`Microsandbox::Patch`),
|
|
|
393
449
|
`registry_auth`/`registry_insecure`/`registry_ca_certs` for private and
|
|
394
450
|
authenticated registries.
|
|
395
451
|
|
|
452
|
+
## Contributing
|
|
453
|
+
|
|
454
|
+
This is a community-maintained gem and **contributions are very welcome** —
|
|
455
|
+
bug reports, fixes, docs, and feature work alike. Open an
|
|
456
|
+
[issue](https://github.com/ya-luotao/microsandbox-rb/issues) or send a
|
|
457
|
+
[pull request](https://github.com/ya-luotao/microsandbox-rb/pulls); PRs target
|
|
458
|
+
`main`. Before pushing, run the local gate (Rust `fmt`/`clippy`, `standardrb`,
|
|
459
|
+
and unit specs) — see [Development](#development).
|
|
460
|
+
|
|
396
461
|
## License
|
|
397
462
|
|
|
398
463
|
Apache-2.0. See [LICENSE](LICENSE).
|
data/ext/microsandbox/Cargo.toml
CHANGED
|
@@ -6,8 +6,8 @@ name = "microsandbox_rb"
|
|
|
6
6
|
description = "Ruby SDK native extension for microsandbox — secure, fast microVM-based sandboxing."
|
|
7
7
|
# Must equal Microsandbox::VERSION (lib/microsandbox/version.rb) — Native.version
|
|
8
8
|
# returns this via env!("CARGO_PKG_VERSION") and version_spec.rb asserts equality.
|
|
9
|
-
# The core-crate dependency below stays pinned at its own tag (v0.5.
|
|
10
|
-
version = "0.5.
|
|
9
|
+
# The core-crate dependency below stays pinned at its own tag (v0.5.8).
|
|
10
|
+
version = "0.5.10"
|
|
11
11
|
authors = ["Super Rad Company <development@superrad.company>"]
|
|
12
12
|
repository = "https://github.com/superradcompany/microsandbox"
|
|
13
13
|
license = "Apache-2.0"
|
|
@@ -35,8 +35,8 @@ rb-sys = "0.9"
|
|
|
35
35
|
# `.cargo/config.toml.example`). "ssh" matches the feature set the Python/Node
|
|
36
36
|
# SDKs ship with; default features add "prebuilt" (provisions msb + libkrunfw at
|
|
37
37
|
# build time), "net", and "keyring".
|
|
38
|
-
microsandbox = { git = "https://github.com/superradcompany/microsandbox", tag = "v0.5.
|
|
39
|
-
microsandbox-network = { git = "https://github.com/superradcompany/microsandbox", tag = "v0.5.
|
|
38
|
+
microsandbox = { git = "https://github.com/superradcompany/microsandbox", tag = "v0.5.8", default-features = true, features = ["ssh"] }
|
|
39
|
+
microsandbox-network = { git = "https://github.com/superradcompany/microsandbox", tag = "v0.5.8" }
|
|
40
40
|
|
|
41
41
|
# Async core bridged to Ruby's synchronous API via a blocking tokio runtime.
|
|
42
42
|
tokio = { version = "1", features = ["rt-multi-thread", "sync", "time"] }
|