microsandbox-rb 0.9.2 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +176 -0
- data/Cargo.lock +126 -141
- data/README.md +63 -9
- data/ext/microsandbox/Cargo.toml +4 -4
- data/ext/microsandbox/src/error.rs +10 -0
- data/ext/microsandbox/src/image.rs +38 -0
- data/ext/microsandbox/src/sandbox.rs +357 -36
- data/ext/microsandbox/src/snapshot.rs +79 -35
- data/lib/microsandbox/errors.rb +4 -0
- data/lib/microsandbox/image.rb +38 -0
- data/lib/microsandbox/modification.rb +108 -0
- data/lib/microsandbox/network.rb +139 -31
- data/lib/microsandbox/root_disk.rb +58 -0
- data/lib/microsandbox/sandbox.rb +285 -23
- data/lib/microsandbox/snapshot.rb +87 -37
- data/lib/microsandbox/version.rb +2 -2
- data/lib/microsandbox.rb +2 -0
- data/sig/microsandbox.rbs +75 -12
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 05d5b2e1200b6aff7dc7801259558a202064a01cac529ea55f2390790b7f84bb
|
|
4
|
+
data.tar.gz: d4d357393a51e2b642dd9d6fc6e899a6a92a3895bf98495a01714fbdbb76c0ed
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 994d487f8a606de2664566519ba28964fcc1053e9277b768945472dfac105d34a48479b1677d8598fde596b4d5c9f37a31970d2cf3e3a2065f98a12fdfe85322
|
|
7
|
+
data.tar.gz: c0d57191ef9fc97845c773216dd19194dbad4dd0c58f3525989d16df0c37088749fe880ccd89b53d71f9f9454c149429886de208b36cda2de4210f23b4bc05f8
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,182 @@ All notable changes to this gem are documented here. The format is based on
|
|
|
6
6
|
microsandbox runtime it embeds; each release notes the upstream runtime tag it
|
|
7
7
|
wraps, and the README's Versioning section keeps the full gem→runtime map.
|
|
8
8
|
|
|
9
|
+
## [0.11.0] - 2026-07-27
|
|
10
|
+
|
|
11
|
+
Adopts upstream runtime **`v0.6.6` → `v0.6.7`** and mirrors its breaking SDK
|
|
12
|
+
surface, keeping parity with the Python/Node SDKs (which ship the same renames
|
|
13
|
+
without compatibility aliases). The bundled runtime also carries the fix for
|
|
14
|
+
**GHSA-4vq3-cjpp-v7fg** (`msb copy` symlink traversal: a sandboxed workload
|
|
15
|
+
could make a later CLI copy-out overwrite an arbitrary host file — the SDK
|
|
16
|
+
`fs`/`copy_to_host` paths were not affected).
|
|
17
|
+
|
|
18
|
+
### Breaking
|
|
19
|
+
|
|
20
|
+
- **Network presets `public_only`/`non_local` are removed** (upstream #1198),
|
|
21
|
+
replaced by composable **profiles** `:public` / `:private` / `:host`:
|
|
22
|
+
`network: [:public, :private]`, single-profile sugar `network: :public`, or
|
|
23
|
+
`NetworkPolicy.from_profiles(:public, :host)`. Any non-empty profile set
|
|
24
|
+
automatically allows gateway DNS. The replacements are rule-for-rule
|
|
25
|
+
equivalent (`public_only` ≡ `[:public]`, which is still the default policy;
|
|
26
|
+
`non_local` ≡ `[:public, :private]`); the removed spellings (and
|
|
27
|
+
`NetworkPolicy.public_only`/`.non_local`) now raise an `ArgumentError` with
|
|
28
|
+
that migration guidance. `network: :none`/`:allow_all` (and their aliases)
|
|
29
|
+
and `network: :default` keep working unchanged. In the Hash form,
|
|
30
|
+
`profiles:` composes with `rules:`/`default_egress:`/`default_ingress:`/deny
|
|
31
|
+
lists; explicit `rules:` are evaluated **before** the profile expansion
|
|
32
|
+
(matching the upstream CLI), so a narrower override such as
|
|
33
|
+
`Rule.deny_dns` wins over a profile's allows under first-match-wins.
|
|
34
|
+
- **`Snapshot.create` is re-keyed by the snapshot's own name** (upstream
|
|
35
|
+
#1118): `Snapshot.create(name, from_sandbox:, dest_dir:, labels:, force:,
|
|
36
|
+
record_integrity:, resumable:)` — the positional argument is now the
|
|
37
|
+
snapshot name (was: the source sandbox), `from_sandbox:` is required, and
|
|
38
|
+
`path:` is replaced by `dest_dir:`, a **parent directory** (the artifact
|
|
39
|
+
always lands at `dest_dir/<name>`). `record_integrity:` is now a no-op
|
|
40
|
+
(schema-1 descriptors always record integrity); `resumable:` is accepted and
|
|
41
|
+
raises `UnsupportedError` until VM pause/resume lands upstream.
|
|
42
|
+
- **`Snapshot.export`/`Snapshot.import` are renamed `Snapshot.save`/
|
|
43
|
+
`Snapshot.load`** (same parameters), matching the Python/Node rename.
|
|
44
|
+
- **`SandboxHandle#snapshot_to` is removed** (deleted upstream). Use
|
|
45
|
+
`Snapshot.create(name, from_sandbox: handle_name, dest_dir: dir)` for
|
|
46
|
+
explicit placement.
|
|
47
|
+
- **`SnapshotVerifyReport#not_recorded?` is removed** and `#status` is always
|
|
48
|
+
`:verified`: integrity is now mandatory at snapshot-create time, so the
|
|
49
|
+
"not recorded" outcome no longer exists (a mismatch raises
|
|
50
|
+
`SnapshotIntegrityError` as before).
|
|
51
|
+
- **`SnapshotInfo#size_bytes`/`#format`/`#fstype` are now nilable** — nil for
|
|
52
|
+
the new checkpoint-state snapshots (file-state snapshots, the only kind
|
|
53
|
+
producible today, still populate all three).
|
|
54
|
+
|
|
55
|
+
### Added
|
|
56
|
+
|
|
57
|
+
- **Structured root disk** (upstream #1165) — `Sandbox.create(root_disk:)`
|
|
58
|
+
configures the OCI sandbox's writable layer: an Integer (managed ext4 upper
|
|
59
|
+
size cap in MiB, the old `oci_upper_size:` meaning), or a `RootDisk` factory
|
|
60
|
+
Hash: `RootDisk.managed(8192)`, `RootDisk.tmpfs(2048)` (RAM-backed, pristine
|
|
61
|
+
rootfs on every boot; size ≤ sandbox memory; not snapshot/patchable), or
|
|
62
|
+
`RootDisk.disk("./scratch.img", format:, fstype:)` (user-supplied image
|
|
63
|
+
attached writable; never created/resized/deleted by the runtime).
|
|
64
|
+
`oci_upper_size:` remains as a deprecated alias (warns; conflicts with
|
|
65
|
+
`root_disk:`).
|
|
66
|
+
- **`Image.load` / `Image.save`** (upstream #1151/#1174) — move OCI images in
|
|
67
|
+
and out of the local cache as `docker save`-style or OCI Image Layout
|
|
68
|
+
archives: `Image.load("./app.tar", tag: "app:dev")` (pass `"-"` to read
|
|
69
|
+
stdin; returns the loaded `ImageInfo`s) and
|
|
70
|
+
`Image.save("alpine:latest", output_path: "./alpine.tar", format: :docker)`.
|
|
71
|
+
- **`Rule.allow_dns` / `Rule.deny_dns`** — the gateway-DNS rule pair the
|
|
72
|
+
profiles expand to (egress → group `:host`, udp+tcp, port 53), for use in
|
|
73
|
+
custom policies (`deny_dns` upstream #1198).
|
|
74
|
+
- **Snapshot descriptor metadata** on `SnapshotInfo`: `#scope` (`:disk` /
|
|
75
|
+
`:resumable`), `#state_kind` (`"file"`/`"checkpoint"`), `#checkpoint_id`,
|
|
76
|
+
`#checkpoint_manifest_digest`, and the index columns `#locality`,
|
|
77
|
+
`#availability`, `#migration_state`, `#migration_error_code`.
|
|
78
|
+
- **`SnapshotMigrationError`** — raised when the automatic v0.6.6→v0.6.7
|
|
79
|
+
snapshot-descriptor migration is blocked and needs repair (new core
|
|
80
|
+
`SnapshotMigration` variant, upstream #1200).
|
|
81
|
+
- **`follow_root_symlinks:` volume flag** — per-mount opt-out of the runtime's
|
|
82
|
+
new default-on mount-root symlink protection (upstream #1149; bind/named
|
|
83
|
+
mounts only). The Rust SDK exposes the same switch; Python/Node defer it.
|
|
84
|
+
|
|
85
|
+
### Changed
|
|
86
|
+
|
|
87
|
+
- **Snapshot artifacts migrate on first use** (upstream #1200): the runtime
|
|
88
|
+
rewrites each v0.6.6 `manifest.json` descriptor to the v0.6.7
|
|
89
|
+
`snapshot.json` (keeping the old file as `.manifest.json.legacy`) at backend
|
|
90
|
+
connect, after which gems ≤ 0.10.x can no longer read those artifacts —
|
|
91
|
+
rolling back requires the upstream `msb self downgrade` tooling.
|
|
92
|
+
- **Bind/named mount roots refuse symlinked roots by default** (upstream
|
|
93
|
+
#1149) — opt out per mount with `follow_root_symlinks: true`.
|
|
94
|
+
- **DNS rebind protection is fail-closed for unspecified addresses** (upstream
|
|
95
|
+
#1198): `0.0.0.0`/`::` no longer classify as `public`, so a `public`-profile
|
|
96
|
+
sandbox can't be steered to them via DNS answers.
|
|
97
|
+
- `ModificationPlan` change/conflict entries for the managed upper now report
|
|
98
|
+
`field: "root_disk_size"` (was `"oci_upper_size"`) — the runtime's canonical
|
|
99
|
+
field name, passed through verbatim as always.
|
|
100
|
+
- Duplicate secret placeholders across secret entries are now allowed
|
|
101
|
+
(upstream #1178); snapshotting a tmpfs or disk-image root disk fails with a
|
|
102
|
+
purposeful `InvalidConfigError` (upstream #1169).
|
|
103
|
+
|
|
104
|
+
## [0.10.0] - 2026-07-09
|
|
105
|
+
|
|
106
|
+
Ruby bindings for the additive `v0.6.6` SDK surface (upstream #1099 / #1128),
|
|
107
|
+
bringing the gem to parity with the Python and Node SDKs, which already ship
|
|
108
|
+
this API. The embedded runtime tag is unchanged (`v0.6.6`); this is a pure
|
|
109
|
+
binding addition with no breaking change.
|
|
110
|
+
|
|
111
|
+
### Added
|
|
112
|
+
|
|
113
|
+
- **Live sandbox modification** — `Sandbox#modify` and `SandboxHandle#modify`
|
|
114
|
+
plan or apply a change to a running (or stopped) sandbox without recreating
|
|
115
|
+
it: resize CPU/memory (`cpus:`, `max_cpus:`, `memory:`, `max_memory:`, MiB),
|
|
116
|
+
adjust `env:`/`remove_env:`, `labels:`/`remove_labels:`, and `workdir:`, and
|
|
117
|
+
rotate/remove secrets (`secrets:` keyed by name with mutually-exclusive
|
|
118
|
+
`env:`/`store:`/`value:` plus `placeholder:`/`allowed_hosts:`,
|
|
119
|
+
`remove_secrets:`). `policy:` selects `:no_restart` (default), `:next_start`,
|
|
120
|
+
or `:restart`; `dry_run: true` computes the plan without applying it. Returns
|
|
121
|
+
a typed `ModificationPlan` (`#sandbox`, `#status`, `#applied?`, `#policy`,
|
|
122
|
+
`#changes`, `#conflicts`, `#warnings`, `#resize_status`) whose nested entries
|
|
123
|
+
are frozen, symbol-keyed Hashes carrying the runtime's canonical snake_case
|
|
124
|
+
fields verbatim.
|
|
125
|
+
- **Health checks** — `Sandbox#ping` / `SandboxHandle#ping` return a
|
|
126
|
+
`PingResult` (`#name`, `#latency` in seconds, `#latency_ms`) confirming the
|
|
127
|
+
guest agent is reachable **without** refreshing the idle timer; `#touch`
|
|
128
|
+
returns a `TouchResult` (`#name`, `#activity_seq`) that explicitly refreshes
|
|
129
|
+
the idle-activity timer. On the handle, both raise `SandboxNotRunningError`
|
|
130
|
+
for a stopped sandbox (it is not started implicitly).
|
|
131
|
+
- **Create-time resource ceilings** — `Sandbox.create` accepts `max_cpus:` and
|
|
132
|
+
`max_memory:` (MiB), the boot-time maxima a later live `modify` can grow up
|
|
133
|
+
to (each defaults to its `cpus:`/`memory:` value and must be >= it).
|
|
134
|
+
- **`SandboxNotRunningError`** is now raised by the runtime's not-running guard
|
|
135
|
+
(the class already existed; the new core `SandboxNotRunning` variant is now
|
|
136
|
+
mapped to it instead of falling back to the base `Error`).
|
|
137
|
+
|
|
138
|
+
Deliberately **not** exposed, matching the Python and Node SDKs (both surface
|
|
139
|
+
these only through the CLI): `modify`'s `oci_upper_size` overlay-grow field, and
|
|
140
|
+
the `SandboxMetricsReport` / per-sandbox metrics-report helpers.
|
|
141
|
+
|
|
142
|
+
## [0.9.3] - 2026-07-09
|
|
143
|
+
|
|
144
|
+
Adopts upstream runtime **`v0.6.3` → `v0.6.6`** (spanning upstream `v0.6.4` and
|
|
145
|
+
`v0.6.6`; `v0.6.5` was yanked upstream — its GitHub release was pulled and the
|
|
146
|
+
type-model refactor it shipped, #1014, was reverted in `v0.6.6`, #1143). The
|
|
147
|
+
upstream SDK crate's public API grew only *additive* surface (live
|
|
148
|
+
modify/resize, ping/touch — Ruby bindings for these land in the next minor),
|
|
149
|
+
so this is a pure runtime bump with no Ruby API change.
|
|
150
|
+
|
|
151
|
+
### Fixed
|
|
152
|
+
|
|
153
|
+
- **Snapshot restore survives upstream tag republishes** (upstream #1130):
|
|
154
|
+
restore now pulls the OCI image by its pinned manifest digest
|
|
155
|
+
(`<repo>@sha256:…`) instead of re-resolving the mutable tag, fixing a fatal
|
|
156
|
+
`v0.6.3` regression where a republished base-image tag made existing
|
|
157
|
+
snapshots unrestorable.
|
|
158
|
+
- **Fragmented UDP and PMTU relay traffic is forwarded correctly** (upstream
|
|
159
|
+
#1086) by the sandbox network relay.
|
|
160
|
+
- **`exec` termination kills the whole process group, not just the direct
|
|
161
|
+
child** (upstream #1104): guest commands that spawn children (e.g. shell
|
|
162
|
+
pipelines) no longer leave orphaned grandchildren running after a kill.
|
|
163
|
+
- **Stop waits tolerate ephemeral cleanup** (upstream #1087, inherited in
|
|
164
|
+
`Sandbox#stop`/`SandboxHandle#wait_until_stopped`): if an ephemeral
|
|
165
|
+
sandbox's persisted state is cleaned up while a stop wait is in flight, the
|
|
166
|
+
wait now resolves to a synthetic `stopped` result instead of raising
|
|
167
|
+
`SandboxNotFoundError`. Persistent sandboxes are unaffected.
|
|
168
|
+
- **Filesystem snapshot `readdir` streams entries** (upstream #1133), fixing
|
|
169
|
+
unbounded memory growth (RSS leak) when listing very large directories.
|
|
170
|
+
|
|
171
|
+
### Changed
|
|
172
|
+
|
|
173
|
+
- **Embedded runtime is now `v0.6.6`** (`Microsandbox::RUNTIME_VERSION` /
|
|
174
|
+
`Microsandbox.runtime_version`). Also inherited:
|
|
175
|
+
- `Sandbox.create`/`.start` persist an active-config snapshot of the booted
|
|
176
|
+
sandbox in the runtime database (upstream SDK behavior; groundwork for
|
|
177
|
+
live modification).
|
|
178
|
+
- The runtime's shutdown flush timeout can be overridden via the
|
|
179
|
+
`MSB_SHUTDOWN_FLUSH_TIMEOUT_MS` environment variable (upstream #1088).
|
|
180
|
+
- The prebuilt `msb` binary gains `modify`/`ping`/`restart`/`touch`
|
|
181
|
+
subcommands and `metrics --watch`; these are CLI-level for now — the
|
|
182
|
+
corresponding Ruby APIs (`#modify`, `#ping`, `#touch`) ship in the next
|
|
183
|
+
minor release.
|
|
184
|
+
|
|
9
185
|
## [0.9.2] - 2026-07-08
|
|
10
186
|
|
|
11
187
|
Adopts upstream runtime **`v0.6.2` → `v0.6.3`**. No Ruby API change; the
|