microsandbox-rb 0.8.0 → 0.8.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 06dc745a315d5d79f21e702032d45a984dbf53110e3375bb560de9cb008866d6
4
- data.tar.gz: 9168ece64600356ce88ed3c3ed42cc88f4354f3619abfdc32fabd578745cf6c4
3
+ metadata.gz: f8cc1edaf4e221fe6e4addf4eea0d06e63370dd73bbcb1a7eb4d13e91bac7b40
4
+ data.tar.gz: 17f18d5aefead5fbb584a7b06ecd82d0aade2394c3e9c48aafd0f5d98673abfd
5
5
  SHA512:
6
- metadata.gz: d8fed4d0957be541dd5de600dd24386ff7b62d9933e45e244a49200185989cb8427279c80234038a4355aee296fdc96ec1cd5738e4bcf3fae48b27388f7dcad5
7
- data.tar.gz: 9310a3b2d3a0322e701bc85cbfe6b820576b4254c3d49099bbfcab07690421c1e2d9705d0106e1d2931fb3516a0d462401758d5393552810427a6891ed6fc79e
6
+ metadata.gz: e7c98769be2508875e54b1449d290c18b63af3189af497d311c6222073b6018290950faa4438c165f656928d175e6f6a50ec0f7af6323a8174dbf0e460b99042
7
+ data.tar.gz: 7a8edef36f6f7e3c12a5075e684d64ca71570350dd678ebcd3b819a9ebfab309007e2b71e348f1c0925ab8e3beb474787aeec741935f5e803676f5ce00daf513
data/CHANGELOG.md CHANGED
@@ -8,6 +8,38 @@ wraps, and the README's Versioning section keeps the full gem→runtime map.
8
8
 
9
9
  ## [Unreleased]
10
10
 
11
+ ## [0.8.1] - 2026-06-25
12
+
13
+ Gem-only release on the `v0.5.10` runtime (unchanged) — the two follow-ups to
14
+ `0.8.0`'s runtime adoption that review surfaced.
15
+
16
+ ### Added
17
+
18
+ - **Per-bind-mount guest-write quota override** (issue #19). An inline `volumes:`
19
+ bind mount now accepts a `quota_mib:` key to override the runtime's default
20
+ guest-write budget (4 GiB as of `v0.5.10`, documented in `0.8.0`), e.g.
21
+ `volumes: { "/out" => { bind: "/host/out", quota_mib: 16_384 } }`. The runtime
22
+ still applies the 4 GiB default when unset; there is no unbounded option, so
23
+ raise the value if a workload writes more. Valid on bind mounts only — the core
24
+ rejects it on tmpfs/disk/named mounts (set a named volume's quota via
25
+ `Volume.create(quota_mib:)`).
26
+
27
+ ### Fixed
28
+
29
+ - **Stale local runtime is now re-provisioned instead of boot-failing**
30
+ (issue #18). `Microsandbox.ensure_runtime!` short-circuited as soon as
31
+ `installed?` was true, but that check confirms only that the `msb`/`libkrunfw`
32
+ files *exist*, not that their version matches the runtime this gem build links.
33
+ An older `msb` left in `~/.microsandbox` by a previous gem version therefore
34
+ passed and then failed every `Sandbox.create` at boot on a host↔guest
35
+ wire-protocol mismatch (e.g. a `v0.5.8` `msb` rejecting the `--config-fd` flag
36
+ the `v0.5.10` runtime passes). `ensure_runtime!` now delegates to the
37
+ idempotent, version-correcting installer on first use even when the runtime is
38
+ present (a cheap `msb --version`; re-downloads only on absence/mismatch), so an
39
+ upgrade-over-stale-install self-heals. Source-gem installs were already
40
+ corrected at build time; this closes the gap for the precompiled-gem upgrade
41
+ path. `MICROSANDBOX_NO_AUTO_INSTALL` still fully opts out.
42
+
11
43
  ## [0.8.0] - 2026-06-25
12
44
 
13
45
  Adopts upstream runtime **`v0.5.10`** (up from the `v0.5.8` that `0.7.0` shipped).
data/Cargo.lock CHANGED
@@ -3249,7 +3249,7 @@ dependencies = [
3249
3249
 
3250
3250
  [[package]]
3251
3251
  name = "microsandbox_rb"
3252
- version = "0.8.0"
3252
+ version = "0.8.1"
3253
3253
  dependencies = [
3254
3254
  "chrono",
3255
3255
  "futures",
data/README.md CHANGED
@@ -398,6 +398,7 @@ Microsandbox.runtime_version # => "v0.5.10" (the embedded upstream runtime ta
398
398
  | `0.6.0` | `v0.5.8` | gem version decoupled from the upstream tag; adds `runtime_version` |
399
399
  | `0.7.0` | `v0.5.8` | SDK parity release (large binding-gap closure) |
400
400
  | `0.8.0` | `v0.5.10` | adopts upstream `v0.5.10` (idle-only heartbeat, config-fd hardening, **4 GiB default bind-mount quota**); supersedes the reverted `v0.5.9` attempt |
401
+ | `0.8.1` | `v0.5.10` | gem-only: re-provision a stale local runtime; per-bind-mount `quota_mib:` override |
401
402
 
402
403
  **Going forward** — the gem version moves on its own semver track and no longer
403
404
  mirrors the upstream tag:
@@ -7,7 +7,7 @@ description = "Ruby SDK native extension for microsandbox — secure, fast micro
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
9
  # The core-crate dependency below stays pinned at its own tag (v0.5.10).
10
- version = "0.8.0"
10
+ version = "0.8.1"
11
11
  authors = ["Super Rad Company <development@superrad.company>"]
12
12
  repository = "https://github.com/superradcompany/microsandbox"
13
13
  license = "Apache-2.0"
@@ -122,6 +122,10 @@ impl Sandbox {
122
122
  .ok_or_else(|| error::base_error("volume mount is missing :kind"))?;
123
123
  let source = conv::opt_string(m, "source")?;
124
124
  let size_mib = conv::opt_u32(m, "size_mib")?;
125
+ // Bind-mount guest-write quota override (MiB). The core's MountBuilder
126
+ // applies it to bind mounts only and rejects it on tmpfs/disk/named at
127
+ // build(); we forward it as-is so that validation lives in one place.
128
+ let quota_mib = conv::opt_u32(m, "quota_mib")?;
125
129
  let fstype = conv::opt_string(m, "fstype")?;
126
130
  let readonly = conv::opt_bool(m, "readonly")?;
127
131
  let noexec = conv::opt_bool(m, "noexec")?;
@@ -161,6 +165,9 @@ impl Sandbox {
161
165
  if let Some(n) = size_mib {
162
166
  mb = mb.size(n);
163
167
  }
168
+ if let Some(q) = quota_mib {
169
+ mb = mb.quota(q);
170
+ }
164
171
  if let Some(f) = format {
165
172
  mb = mb.format(f);
166
173
  }
@@ -230,7 +230,10 @@ module Microsandbox
230
230
  # `{ disk: "/img.raw", format: "raw", fstype: "ext4" }`. Any mount may add
231
231
  # flags `ro:`/`readonly:`, `noexec:`, `nosuid:`, `nodev:`, and (bind/named
232
232
  # only) `stat_virtualization:` (:strict/:relaxed/:off) and
233
- # `host_permissions:` (:private/:mirror).
233
+ # `host_permissions:` (:private/:mirror). A bind mount accepts
234
+ # `quota_mib:` to override the runtime's default guest-write budget
235
+ # (4 GiB as of `v0.5.10`); the core rejects it on tmpfs/disk/named (for a
236
+ # named volume, set its quota via {Volume.create}).
234
237
  # @param network [String, Symbol, NetworkPolicy, Hash, nil] network policy.
235
238
  # A preset name ("public_only" (default), "none", "allow_all",
236
239
  # "non_local"), a {NetworkPolicy} (e.g. {NetworkPolicy.custom}), or a Hash
@@ -677,11 +680,12 @@ module Microsandbox
677
680
  # Hashes for the native layer. A spec is a host path String (a read-write
678
681
  # bind mount) or a Hash describing the mount:
679
682
  # { bind: "/host", ro: true, noexec: true } # host bind mount
683
+ # { bind: "/host", quota_mib: 16_384 } # raise the 4 GiB cap
680
684
  # { named: "vol" } # named volume
681
685
  # { tmpfs: true, size_mib: 64 } # memory-backed
682
686
  # { disk: "/img.raw", format: "raw", fstype: "ext4" } # disk-image mount
683
687
  # Any mount may also carry stat_virtualization: (:strict/:relaxed/:off) and
684
- # host_permissions: (:private/:mirror).
688
+ # host_permissions: (:private/:mirror); a bind mount may carry quota_mib:.
685
689
  def normalize_volumes(volumes)
686
690
  volumes.map do |guest, spec|
687
691
  mount = {"guest" => guest.to_s}
@@ -722,6 +726,12 @@ module Microsandbox
722
726
  mount["size_mib"] = Integer(size) if size
723
727
  fstype = spec[:fstype] || spec["fstype"]
724
728
  mount["fstype"] = fstype.to_s if fstype
729
+ # Bind-mount guest-write quota (MiB). Overrides the runtime's default
730
+ # budget (4 GiB as of v0.5.10); the core applies it only to bind mounts
731
+ # and rejects it on tmpfs/disk/named. `0` is forwarded as-is (a zero
732
+ # budget), not treated as "unset".
733
+ quota = spec[:quota_mib] || spec["quota_mib"]
734
+ mount["quota_mib"] = Integer(quota) if quota
725
735
  end
726
736
 
727
737
  # Apply a volume spec Hash's mount flags. `ro:`/`readonly:` makes the mount
@@ -8,7 +8,7 @@ module Microsandbox
8
8
  # Versioning section of the README for the full gem-to-runtime map. Must equal
9
9
  # the native ext's Cargo crate version (`Native.version`), enforced by
10
10
  # spec/unit/version_spec.rb.
11
- VERSION = "0.8.0"
11
+ VERSION = "0.8.1"
12
12
 
13
13
  # The upstream microsandbox runtime release this gem build embeds — the `tag`
14
14
  # pinned on the `microsandbox`/`microsandbox-network` git deps in
data/lib/microsandbox.rb CHANGED
@@ -93,16 +93,27 @@ module Microsandbox
93
93
  Native.installed?
94
94
  end
95
95
 
96
- # Ensure the `msb` runtime + `libkrunfw` are present, provisioning them on
97
- # first use if not. Called automatically by {Sandbox.create}/{Sandbox.start}
98
- # so precompiled-gem users (who never ran the source build) get a working
99
- # runtime without a manual {install} step.
96
+ # Ensure the `msb` runtime + `libkrunfw` are present *and version-matched*,
97
+ # provisioning them on first use if not. Called automatically by
98
+ # {Sandbox.create}/{Sandbox.start} so precompiled-gem users (who never ran the
99
+ # source build) get a working runtime without a manual {install} step.
100
100
  #
101
- # The download is attempted at most once per process. Opt out by setting
101
+ # Runs at most once per process. Opt out by setting
102
102
  # `MICROSANDBOX_NO_AUTO_INSTALL` (e.g. air-gapped hosts that provision the
103
- # runtime out of band); the subsequent operation then surfaces the missing
104
- # runtime itself. Already-installed runtimes (e.g. source builds) skip
105
- # straight through with only a cheap presence check.
103
+ # runtime out of band); the runtime is then left untouched and a missing or
104
+ # stale one surfaces at the operation itself.
105
+ #
106
+ # NOTE: this delegates to {install} even when {installed?} is already true,
107
+ # rather than short-circuiting on presence. {installed?} (upstream
108
+ # `verify_installation`) only confirms the `msb`/`libkrunfw` files *exist*, not
109
+ # that their version matches the runtime this gem build links. {install} is
110
+ # idempotent and *version-correcting*: it runs a cheap `msb --version` and
111
+ # re-downloads ONLY when the binary is absent or its version differs, then
112
+ # no-ops. A presence-only short-circuit would let a stale `msb` left in
113
+ # `~/.microsandbox` by an older gem pass, then fail every {Sandbox.create} on a
114
+ # host↔guest wire-protocol mismatch (e.g. a `v0.5.8` `msb` rejecting the
115
+ # `--config-fd` flag the `v0.5.10` runtime passes). Keep the {install} call on
116
+ # this path — do not "optimize" it back to skip-when-present.
106
117
  # @return [nil]
107
118
  def ensure_runtime!
108
119
  return if @runtime_ready
@@ -111,14 +122,18 @@ module Microsandbox
111
122
  # uses the same lazy env/profile/config ladder every operation already
112
123
  # consults, so this adds no work for local hosts (the common case).
113
124
  return if default_backend_kind == :cloud
114
- if installed?
125
+ # Opted out: the caller manages the runtime out of band, so don't fetch,
126
+ # verify, or repair it here. Memoize the decision (the env var is stable for
127
+ # the process); the operation resolves `msb` itself and surfaces any problem.
128
+ if auto_install_disabled?
115
129
  @runtime_ready = true
116
130
  return
117
131
  end
118
- return if auto_install_disabled?
119
132
 
120
- warn "[microsandbox] runtime (msb + libkrunfw) not found; " \
121
- "downloading to ~/.microsandbox (set MICROSANDBOX_NO_AUTO_INSTALL to skip)..."
133
+ unless installed?
134
+ warn "[microsandbox] runtime (msb + libkrunfw) not found; " \
135
+ "downloading to ~/.microsandbox (set MICROSANDBOX_NO_AUTO_INSTALL to skip)..."
136
+ end
122
137
  install
123
138
  @runtime_ready = true
124
139
  nil
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: microsandbox-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - ya-luotao