rightsize 0.7.9 → 0.7.12

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.
Files changed (103) hide show
  1. package/README.md +6 -4
  2. package/dist/backend-docker/backend.d.ts +29 -3
  3. package/dist/backend-docker/backend.d.ts.map +1 -1
  4. package/dist/backend-docker/backend.js +30 -3
  5. package/dist/backend-docker/backend.js.map +1 -1
  6. package/dist/backend-msb/backend.d.ts +657 -83
  7. package/dist/backend-msb/backend.d.ts.map +1 -1
  8. package/dist/backend-msb/backend.js +1319 -149
  9. package/dist/backend-msb/backend.js.map +1 -1
  10. package/dist/backend-msb/commands.d.ts +162 -16
  11. package/dist/backend-msb/commands.d.ts.map +1 -1
  12. package/dist/backend-msb/commands.js +228 -32
  13. package/dist/backend-msb/commands.js.map +1 -1
  14. package/dist/backend-msb/network-links.d.ts +86 -1
  15. package/dist/backend-msb/network-links.d.ts.map +1 -1
  16. package/dist/backend-msb/network-links.js +119 -4
  17. package/dist/backend-msb/network-links.js.map +1 -1
  18. package/dist/backend-msb/provisioner.d.ts +1 -1
  19. package/dist/backend-msb/provisioner.d.ts.map +1 -1
  20. package/dist/backend-msb/provisioner.js +1 -1
  21. package/dist/backend-msb/provisioner.js.map +1 -1
  22. package/dist/backend-msb/restore-access-denied.d.ts +50 -0
  23. package/dist/backend-msb/restore-access-denied.d.ts.map +1 -0
  24. package/dist/backend-msb/restore-access-denied.js +52 -0
  25. package/dist/backend-msb/restore-access-denied.js.map +1 -0
  26. package/dist/backend-msb/restore-broker.d.ts +181 -0
  27. package/dist/backend-msb/restore-broker.d.ts.map +1 -0
  28. package/dist/backend-msb/restore-broker.js +264 -0
  29. package/dist/backend-msb/restore-broker.js.map +1 -0
  30. package/dist/backend-msb/sandbox-already-exists.d.ts +32 -0
  31. package/dist/backend-msb/sandbox-already-exists.d.ts.map +1 -0
  32. package/dist/backend-msb/sandbox-already-exists.js +35 -0
  33. package/dist/backend-msb/sandbox-already-exists.js.map +1 -0
  34. package/dist/backend-msb/snapshot-create.d.ts +22 -0
  35. package/dist/backend-msb/snapshot-create.d.ts.map +1 -0
  36. package/dist/backend-msb/snapshot-create.js +33 -0
  37. package/dist/backend-msb/snapshot-create.js.map +1 -0
  38. package/dist/backend-msb/snapshot-import.d.ts +30 -14
  39. package/dist/backend-msb/snapshot-import.d.ts.map +1 -1
  40. package/dist/backend-msb/snapshot-import.js +35 -17
  41. package/dist/backend-msb/snapshot-import.js.map +1 -1
  42. package/dist/backend-msb/snapshot-rm.d.ts +28 -0
  43. package/dist/backend-msb/snapshot-rm.d.ts.map +1 -0
  44. package/dist/backend-msb/snapshot-rm.js +30 -0
  45. package/dist/backend-msb/snapshot-rm.js.map +1 -0
  46. package/dist/core/backend.d.ts +68 -23
  47. package/dist/core/backend.d.ts.map +1 -1
  48. package/dist/core/checkpoint/api.d.ts +2 -2
  49. package/dist/core/checkpoint/api.js +2 -2
  50. package/dist/core/checkpoint/registry.d.ts +46 -0
  51. package/dist/core/checkpoint/registry.d.ts.map +1 -1
  52. package/dist/core/checkpoint/registry.js +44 -3
  53. package/dist/core/checkpoint/registry.js.map +1 -1
  54. package/dist/core/errors.d.ts +49 -0
  55. package/dist/core/errors.d.ts.map +1 -1
  56. package/dist/core/errors.js +61 -0
  57. package/dist/core/errors.js.map +1 -1
  58. package/dist/core/free-ports.d.ts +18 -0
  59. package/dist/core/free-ports.d.ts.map +1 -1
  60. package/dist/core/free-ports.js +61 -0
  61. package/dist/core/free-ports.js.map +1 -1
  62. package/dist/core/generic-container.d.ts +101 -12
  63. package/dist/core/generic-container.d.ts.map +1 -1
  64. package/dist/core/generic-container.js +399 -71
  65. package/dist/core/generic-container.js.map +1 -1
  66. package/dist/core/model.d.ts +40 -3
  67. package/dist/core/model.d.ts.map +1 -1
  68. package/dist/core/network.d.ts +6 -2
  69. package/dist/core/network.d.ts.map +1 -1
  70. package/dist/core/network.js +4 -1
  71. package/dist/core/network.js.map +1 -1
  72. package/dist/core/reuse/hash.d.ts +12 -0
  73. package/dist/core/reuse/hash.d.ts.map +1 -1
  74. package/dist/core/reuse/hash.js +1 -0
  75. package/dist/core/reuse/hash.js.map +1 -1
  76. package/dist/core/reuse/registry.d.ts +10 -1
  77. package/dist/core/reuse/registry.d.ts.map +1 -1
  78. package/dist/core/reuse/registry.js +15 -1
  79. package/dist/core/reuse/registry.js.map +1 -1
  80. package/dist/core/sandbox-name.d.ts +3 -0
  81. package/dist/core/sandbox-name.d.ts.map +1 -0
  82. package/dist/core/sandbox-name.js +19 -0
  83. package/dist/core/sandbox-name.js.map +1 -0
  84. package/dist/index.d.ts +2 -2
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.js +1 -1
  87. package/dist/index.js.map +1 -1
  88. package/dist/modules/cassandra.d.ts +12 -12
  89. package/dist/modules/cassandra.js +13 -13
  90. package/dist/modules/cassandra.js.map +1 -1
  91. package/dist/modules/minio.d.ts +5 -3
  92. package/dist/modules/minio.d.ts.map +1 -1
  93. package/dist/modules/minio.js +14 -4
  94. package/dist/modules/minio.js.map +1 -1
  95. package/dist/modules/postgres.d.ts +2 -2
  96. package/dist/modules/postgres.d.ts.map +1 -1
  97. package/dist/modules/postgres.js +11 -9
  98. package/dist/modules/postgres.js.map +1 -1
  99. package/package.json +1 -1
  100. package/dist/backend-msb/snapshot-list.d.ts +0 -43
  101. package/dist/backend-msb/snapshot-list.d.ts.map +0 -1
  102. package/dist/backend-msb/snapshot-list.js +0 -53
  103. package/dist/backend-msb/snapshot-list.js.map +0 -1
@@ -1,9 +1,14 @@
1
1
  /**
2
2
  * Pure msb CLI argv construction. Every spelling here was checked against the
3
3
  * real `msb` binary, not guessed from `--help` text alone. ATTACHED mode (no
4
- * `-d`) is the whole ballgame: `msb run -d` boots the microVM but never runs
5
- * the image's own ENTRYPOINT/CMD, only attached mode does — see
6
- * `MsbCliBackend.start` for the supervision this forces.
4
+ * `-d`) is the whole ballgame for `run()`: `msb run -d` runs the image's own
5
+ * ENTRYPOINT/CMD too, so attached mode isn't about starting the workload —
6
+ * see `MsbCliBackend.start` for the supervision it forces instead.
7
+ * `restore()` is a
8
+ * different shape entirely — see its own doc and `MsbCliBackend.bootRestoreOnce`'s
9
+ * for why: `msb restore` always detaches and exits once activation is
10
+ * confirmed, well before the sandbox itself finishes booting, and it is
11
+ * never held open as a supervisor the way `run` is.
7
12
  */
8
13
  export const MsbCommands = {
9
14
  run(spec) {
@@ -26,8 +31,18 @@ export const MsbCommands = {
26
31
  if (spec.networkDisabled) {
27
32
  argv.push("--net", "private");
28
33
  }
34
+ // One rule per linked UDP target: a bare --net-rule (no --net flag) is
35
+ // PREPENDED to msb's default policy, so public internet, DNS, and this
36
+ // sandbox's own published-port ingress all keep working — only these
37
+ // specific host UDP ports open up, nothing broader.
38
+ for (const port of spec.hostUdpEgressPorts ?? []) {
39
+ argv.push("--net-rule", `allow@host:udp:${port}`);
40
+ }
29
41
  for (const port of spec.ports) {
30
- argv.push("-p", `${port.hostPort}:${port.guestPort}`);
42
+ // "/udp" only for a udp binding — the plain "HOST:GUEST" spelling for
43
+ // tcp is byte-identical to before this suffix existed, since msb (like
44
+ // docker) treats an unmarked port publish as tcp by default.
45
+ argv.push("-p", `${port.hostPort}:${port.guestPort}${port.protocol === "udp" ? "/udp" : ""}`);
31
46
  }
32
47
  for (const [key, value] of spec.env) {
33
48
  argv.push("-e", `${key}=${value}`);
@@ -50,15 +65,12 @@ export const MsbCommands = {
50
65
  for (const mount of spec.mounts) {
51
66
  argv.push("--mount-file", `${mount.hostPath}:${mount.guestPath}:${mount.readOnly ? "ro" : "rw"},nodev`);
52
67
  }
53
- if (spec.checkpointRef !== undefined) {
54
- // `--from-snapshot` is mutually exclusive with the IMAGE positional arg —
55
- // the snapshot itself pins the image (see MsbCliBackend's own doc on
56
- // fromCheckpoint/checkpointRef).
57
- argv.push("--from-snapshot", spec.checkpointRef);
58
- }
59
- else {
60
- argv.push(spec.image);
61
- }
68
+ // `checkpointRef` never reaches here: msb 0.7.1 removed `run --from-snapshot`
69
+ // outright (clap rejects it as an unexpected argument now), so a spec that
70
+ // carries a checkpointRef is routed to `restore()` below, one layer up in
71
+ // `MsbCliBackend.bootOnce` — this function only ever builds an ordinary
72
+ // image boot.
73
+ argv.push(spec.image);
62
74
  if (spec.command !== undefined) {
63
75
  // undefined => the image's own ENTRYPOINT/CMD runs unmodified.
64
76
  argv.push("--", ...spec.command);
@@ -66,36 +78,194 @@ export const MsbCommands = {
66
78
  return argv;
67
79
  },
68
80
  /**
69
- * `msb snapshot create --from <sandbox> <name>` — requires `sandbox`
70
- * STOPPED; writes a sparse disk snapshot under `~/.microsandbox/snapshots/<name>`,
71
- * or under `<destDir>/<name>` when `destDir` is given (path-ref checkpoints).
81
+ * `msb restore <ref> --name <name> [-m SIZE] [--no-net] [--volume
82
+ * SOURCE:GUEST:OPTS]... [-p HOST:GUEST]...` — the checkpoint-reboot argv,
83
+ * replacing the removed `run --from-snapshot` (msb 0.7.1 moved restore to
84
+ * this dedicated subcommand). NEVER emits `--disk-only`: EMPIRICALLY
85
+ * VERIFIED against a real msb 0.7.1 binary, a disk-scope snapshot — the
86
+ * only kind `msb snapshot create --from-sandbox` produces, and therefore
87
+ * the only kind this library's checkpoints ever restore — REJECTS that
88
+ * flag outright (`invalid config: disk_only requires a full snapshot with
89
+ * checkpoint state`). Restoring a disk-scope snapshot is inherently a cold
90
+ * boot of the captured disk with no processes/RAM resumed — the same
91
+ * semantics the old `run --from-snapshot` boot and the removed
92
+ * `--disk-only` flag both had, and the only restore mode this library's
93
+ * checkpoint contract documents — so nothing observable changes for
94
+ * callers; only the argv shrinks by one flag msb no longer accepts here.
95
+ *
96
+ * Deliberately narrower than `run()` in one respect only: `msb restore`
97
+ * has no `-e`/`--env` flag at all, so env is never threaded through here —
98
+ * a restore replays the sandbox's own captured configuration, which makes
99
+ * re-passing env redundant (see `GenericContainer.fromCheckpoint`'s own
100
+ * doc on why an env the caller has actually changed beyond the
101
+ * checkpoint's own is refused before this is ever reached, rather than
102
+ * silently dropped here). There is likewise no `--root-disk` equivalent —
103
+ * the snapshot pins the root disk, and `withDiskLimit()` on a
104
+ * `fromCheckpoint()` container is rejected at `start()` before any backend
105
+ * call.
106
+ *
107
+ * Mounts and network are NOT in that category — they thread through here,
108
+ * mirroring `run()`'s own `--mount-file`/`--net private`. Per msb's own
109
+ * source (`sdk/rust/lib/sandbox/restore_builder.rs`'s `RestoreBuilder::new`),
110
+ * every restore starts with `mounts`/`ports`/`vsock` CLEARED and
111
+ * `restore_resources.require_complete` true — they are the destination's
112
+ * OWN fresh bindings for this specific restore, not something msb
113
+ * re-derives from the snapshot, and an un-resupplied captured external
114
+ * mount is a hard failure, not a silent drop. `createCheckpoint`'s
115
+ * stop/snapshot/reboot cycle (see `MsbCliBackend.createCheckpoint`) hands
116
+ * this function `handle.spec` itself — the ORIGINAL sandbox's live
117
+ * `mounts`/`networkDisabled` exactly as the caller set them via
118
+ * `.withCopyFileToContainer()`/`.withNetworkDisabled()`, not anything
119
+ * "carried over from a captured spec" — so they must be re-emitted here or
120
+ * they silently vanish across the reboot (or, if msb classifies the
121
+ * now-missing mount as a required external resource, throw instead).
122
+ * `GenericContainer.fromCheckpoint()` is the unrelated case the checkpoints
123
+ * guide's "network topology, mounts, and keepAlive are never carried over
124
+ * from the source spec" actually describes: it never copies
125
+ * `cp.spec.mounts`/`networkDisabled` onto the new container's own builder
126
+ * state in the first place (see its own doc), so a `fromCheckpoint()`
127
+ * container's `spec.mounts` is `[]` and `networkDisabled` is `false`
128
+ * unless the caller adds them back explicitly via
129
+ * `.withCopyFileToContainer()`/`.withNetworkDisabled()` on it directly —
130
+ * in which case this function threads those through exactly the same as
131
+ * for any other spec, as it should.
132
+ *
133
+ * `--volume SOURCE:GUEST[:OPTIONS]` is restore's own mount flag (`-v`
134
+ * short form; `RestoreResourceArgs.volume` in
135
+ * crates/cli/lib/commands/restore.rs) — spelled differently from `run()`'s
136
+ * `--mount-file`, but parsed by the identical shared grammar
137
+ * (`parse_cli_mount_spec`, confirmed in crates/cli/lib/commands/common.rs:
138
+ * `--volume`'s `parse_restore_volume` and `--mount-file`'s
139
+ * `apply_explicit_file_mount` both call it with the same
140
+ * `CliMountOptionSupport`), so `run()`'s own comment on why the option
141
+ * block (`ro`/`rw,nodev`) is always spelled out rather than left to
142
+ * defaults applies here verbatim. `--no-net` is restore's equivalent of
143
+ * `run()`'s `--net private`: msb's own default restore network policy is
144
+ * open (`RestoreBuilder::new` clears mounts/ports/vsock/user but never
145
+ * touches the network policy field, so it keeps whatever a fresh
146
+ * `SandboxBuilder`'s default is — the same open-by-default policy `run()`
147
+ * itself relies on when `networkDisabled` is unset), so `--no-net` is
148
+ * emitted only when `networkDisabled` is true, exactly mirroring `run()`'s
149
+ * own `--net private` condition.
150
+ */
151
+ restore(spec) {
152
+ if (spec.checkpointRef === undefined) {
153
+ throw new Error("MsbCommands.restore requires spec.checkpointRef");
154
+ }
155
+ const argv = ["restore", spec.checkpointRef, "--name", spec.name];
156
+ if (spec.memoryLimitMb !== undefined) {
157
+ argv.push("-m", `${spec.memoryLimitMb}M`);
158
+ }
159
+ if (spec.networkDisabled) {
160
+ argv.push("--no-net");
161
+ }
162
+ // Unlike run(), a bare --net-rule here is not additive: msb's restore
163
+ // drops whatever CLI policy the ORIGINAL sandbox booted with and falls
164
+ // back to its own default, so this has to re-supply the complete
165
+ // replacement policy, not just the extra rule. --net-rule only parses
166
+ // on restore alongside --net-default (there is no --net profile flag
167
+ // here, unlike run's --net private), and --net-default governs BOTH
168
+ // directions at once — so the published-port ingress a plain default
169
+ // policy gives for free must be re-added explicitly as
170
+ // allow:ingress@any, or this sandbox's own -p bindings restore
171
+ // unreachable.
172
+ const hostUdpEgressPorts = spec.hostUdpEgressPorts ?? [];
173
+ if (hostUdpEgressPorts.length > 0) {
174
+ const rules = ["allow@public", "allow@dns", ...hostUdpEgressPorts.map((port) => `allow@host:udp:${port}`), "allow:ingress@any"];
175
+ argv.push("--net-default", "deny", "--net-rule", rules.join(","));
176
+ }
177
+ for (const port of spec.ports) {
178
+ // Same "/udp"-only-for-udp spelling as run() above — a checkpoint
179
+ // reboot re-publishes each binding's ORIGINAL protocol, never
180
+ // defaulting a udp binding back to tcp on restore.
181
+ argv.push("-p", `${port.hostPort}:${port.guestPort}${port.protocol === "udp" ? "/udp" : ""}`);
182
+ }
183
+ for (const mount of spec.mounts) {
184
+ // Same option grammar and Windows rationale as `run()`'s `--mount-file` —
185
+ // see this function's own doc.
186
+ argv.push("--volume", `${mount.hostPath}:${mount.guestPath}:${mount.readOnly ? "ro" : "rw"},nodev`);
187
+ }
188
+ return argv;
189
+ },
190
+ /**
191
+ * `msb snapshot create --from-sandbox <sandbox> <name>` — requires
192
+ * `sandbox` STOPPED. `name` is a caller-supplied label, EMPIRICALLY
193
+ * VERIFIED against a real msb 0.7.1 binary to no longer determine where
194
+ * the artifact lands: it only appears in msb's own index (as
195
+ * `<sandbox>:<name>`, visible in `msb snapshot list`) and in `snapshot
196
+ * inspect` output. The artifact itself always lands under
197
+ * `<destDir-or-default>/<sandbox>/snap_<32-hex-digest>` — a
198
+ * content-addressed path `name` has no say over — which is why
199
+ * `MsbCliBackend.createCheckpoint` parses it back out of this command's
200
+ * own stdout (see `parseSnapshotCreateArtifactPath`) instead of
201
+ * constructing it. `destDir` (this library's own `--dest-dir`, when the
202
+ * ref is a path ref) still controls the artifact's PARENT directory —
203
+ * `<destDir>/<sandbox>/snap_<digest>` when given, msb's own default
204
+ * snapshot store (`~/.microsandbox/snapshots/<sandbox>/snap_<digest>`)
205
+ * otherwise.
72
206
  */
73
207
  snapshotCreate(sandbox, name, destDir) {
74
- const argv = ["snapshot", "create", "--from", sandbox, name];
208
+ const argv = ["snapshot", "create", "--from-sandbox", sandbox, name];
75
209
  if (destDir !== undefined) {
76
210
  argv.push("--dest-dir", destDir);
77
211
  }
78
212
  return argv;
79
213
  },
80
- /** `msb snapshot rm <name>` — best-effort per `removeCheckpoint`'s own contract; "not found" is fine. */
81
- snapshotRemove(name) {
82
- return ["snapshot", "rm", name];
214
+ /**
215
+ * `msb snapshot rm <ref> -f` — best-effort per `removeCheckpoint`'s own
216
+ * contract; "not found" is fine. `ref` must be the snapshot's own artifact
217
+ * PATH, never a bare name or `group:member` form: EMPIRICALLY VERIFIED
218
+ * against a real msb 0.7.1 binary, name-based removal does not resolve —
219
+ * the artifact path is the only address that reliably works. `-f` forces
220
+ * the removal; without it a plain `msb snapshot rm` prompts for
221
+ * confirmation, which would hang a non-interactive CLI invocation forever.
222
+ * A non-zero exit can ALSO mean msb refused because `ref` is the current
223
+ * head of older siblings from the same source sandbox — see
224
+ * `isSnapshotHeadRemovalRefused`, which `removeCheckpoint` propagates
225
+ * rather than swallowing alongside an ordinary "not found."
226
+ */
227
+ snapshotRemove(ref) {
228
+ return ["snapshot", "rm", ref, "-f"];
83
229
  },
84
- /** `msb snapshot inspect <name>` — exit 0 means the snapshot exists, non-zero means it doesn't; `hasCheckpoint`'s backend call. */
85
- snapshotInspect(name) {
86
- return ["snapshot", "inspect", name];
230
+ /**
231
+ * `msb snapshot inspect <ref>` — exit 0 means the snapshot exists,
232
+ * non-zero means it doesn't (or the probe itself failed); `hasCheckpoint`'s
233
+ * backend call for a bare-name ref. `ref` should be the snapshot's own
234
+ * artifact PATH for the same reason `snapshotRemove` requires one —
235
+ * EMPIRICALLY VERIFIED against a real msb 0.7.1 binary, name-based inspect
236
+ * does not resolve either.
237
+ */
238
+ snapshotInspect(ref) {
239
+ return ["snapshot", "inspect", ref];
87
240
  },
88
- /** `msb snapshot save <ref> <dest>` — writes a `.tar.zst` artifact archive; deliberately never `--with-image` (its import fails an integrity check in 0.6.6, see the checkpoints guide). `exportCheckpoint`'s backend call. */
241
+ /**
242
+ * `msb snapshot save <ref> <dest>` — writes a `.tar.zst` artifact archive;
243
+ * deliberately never `--with-image` (see the checkpoints guide — this
244
+ * library doesn't bundle the OCI image into the archive yet, though
245
+ * upstream supports it). Upstream renamed the subcommand
246
+ * from `export` to `save` for msb 0.7.1 (EMPIRICALLY VERIFIED against a
247
+ * real 0.7.1 binary — `snapshot export` no longer exists at all); `<ref>`
248
+ * and `<dest>` are still plain positionals with the explicit filename
249
+ * preserved, so nothing about the argv shape besides the verb changes.
250
+ * `exportCheckpoint`'s backend call.
251
+ */
89
252
  snapshotExport(ref, dest) {
90
253
  return ["snapshot", "save", ref, dest];
91
254
  },
92
- /** `msb snapshot load <archive>` — unpacks into a digest-derived directory under `~/.microsandbox/snapshots/`, never the original name; `importCheckpoint`'s backend call. */
93
- snapshotImport(archive) {
94
- return ["snapshot", "load", archive];
95
- },
96
- /** `msb snapshot list --format json` — full `digest`/`name`/`artifact_path`/`image_ref` entries, used to CONFIRM an imported snapshot's digest-dir basename is present (the basename itself, not the `digest` field, is the effective ref — the full digest does not resolve as a snapshot ref). */
97
- snapshotList() {
98
- return ["snapshot", "list", "--format", "json"];
255
+ /**
256
+ * `msb snapshot load <archive> --dest <destDir>` — upstream renamed the
257
+ * subcommand from `import` to `load` for msb 0.7.1 (EMPIRICALLY VERIFIED
258
+ * against a real 0.7.1 binary — `snapshot import` no longer exists at
259
+ * all) and added `--dest`, which this always passes: omitting it imports
260
+ * into msb's own global default snapshot store instead of this library's
261
+ * checkpoints directory, which is exactly the placement bug `--dest`
262
+ * exists to avoid (mirrors `snapshotCreate`'s own `--dest-dir`, a
263
+ * differently-spelled flag on a different subcommand). `destDir` is
264
+ * always the checkpoints cache directory (see `MsbCliBackend.importCheckpoint`).
265
+ * `importCheckpoint`'s backend call.
266
+ */
267
+ snapshotImport(archive, destDir) {
268
+ return ["snapshot", "load", archive, "--dest", destDir];
99
269
  },
100
270
  /** `msb copy -q <hostPath> <name>:<containerPath>` — host-to-guest transfer, `cp -r`-style destination naming for a directory source. */
101
271
  copyIn(hostPath, name, containerPath) {
@@ -108,6 +278,30 @@ export const MsbCommands = {
108
278
  exec(name, cmd) {
109
279
  return ["exec", name, "--", ...cmd];
110
280
  },
281
+ /**
282
+ * `msb exec -e KEY=VALUE... <name> -- <cmd...>` — the workload-revival exec
283
+ * variant `MsbCliBackend.reviveWorkload` spawns to restart a restored
284
+ * sandbox's captured workload with its ORIGINAL env (a restore's own `msb
285
+ * restore` has no `-e`/`--env` flag at all — see `restore()`'s own doc —
286
+ * so this is the one place that env reaches a restored sandbox's guest).
287
+ * Distinct from the plain `exec()` builder above, which every other
288
+ * one-shot exec call this backend makes (the `nc` probe, `/etc/hosts`
289
+ * alias install, `mkdir -p`, ...) uses and which never carries env — those
290
+ * calls have no reason to widen the guest command's environment, and
291
+ * `msb exec` accepts `-e` at all only because a genuine workload restart
292
+ * needs it. `-e` is repeatable (mirrors `run()`'s own `-e`) and is emitted
293
+ * right after `exec`, before the sandbox NAME positional — the same
294
+ * relative placement `run()` gives its own `-e` flags among its other
295
+ * options, ahead of the trailing positional(s).
296
+ */
297
+ execWithEnv(name, env, cmd) {
298
+ const argv = ["exec"];
299
+ for (const [key, value] of env) {
300
+ argv.push("-e", `${key}=${value}`);
301
+ }
302
+ argv.push(name, "--", ...cmd);
303
+ return argv;
304
+ },
111
305
  execStream(name, cmd) {
112
306
  return ["exec", "--stream", name, "--", ...cmd];
113
307
  },
@@ -119,7 +313,9 @@ export const MsbCommands = {
119
313
  * diagnostics channel, distinct from the workload log `logs()` above
120
314
  * fetches. This is where the boot-completion marker line lives (see
121
315
  * `hasSandboxStartedMarker`); the fast-exit post-mortem classification in
122
- * `MsbCliBackend.bootOnce` is this builder's only caller.
316
+ * `MsbCliBackend.bootRunOnce` and the restore poll's own failure
317
+ * diagnostics in `MsbCliBackend.bootRestoreOnce` are this builder's only
318
+ * callers.
123
319
  */
124
320
  systemLog(name) {
125
321
  return ["logs", name, "--source", "system", "--tail", "1000"];
@@ -1 +1 @@
1
- {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/backend-msb/commands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/backend-msb/commands.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,92 @@
1
1
  import type { NetworkLink } from "../core/backend.js";
2
- /** Two siblings publishing the same guest port on one network have nowhere distinct to tunnel to. */
2
+ /**
3
+ * Two siblings publishing the same guest port ON THE SAME PROTOCOL have
4
+ * nowhere distinct to route to — checked per (protocol, guestPort), not
5
+ * guestPort alone, so a container exposing one guest port on BOTH
6
+ * protocols (DNS's 53, say) is never flagged: its TCP and UDP links each
7
+ * get their own independent route (an exec-tunnel, a forwarder script) and
8
+ * never collide with each other.
9
+ */
3
10
  export declare function requireNoDuplicateGuestPorts(links: readonly NetworkLink[]): void;
4
11
  export declare function requireAliasesAreValid(links: readonly NetworkLink[]): void;
5
12
  /** The `sh -c` script that appends one `/etc/hosts` line per distinct alias. */
6
13
  export declare function hostsAliasScript(links: readonly NetworkLink[]): string;
14
+ /** Where a UDP link's forwarder script/log live in the guest — the name itself is load-bearing: it is grepped back out of `/proc/<pid>/cmdline` by the script's own supervisor loop below. */
15
+ export declare function udpForwarderScriptPath(guestPort: number): string;
16
+ /** The forwarder's own launch log, tailed into a readiness-timeout error to give it something to diagnose from. */
17
+ export declare function udpForwarderLogPath(guestPort: number): string;
18
+ /**
19
+ * The in-guest UDP forwarder, one instance per linked UDP port: relays
20
+ * `guestPort` to `<gateway IPv4>:<targetHostPort>`, where the target's own
21
+ * host-published UDP port is listening. busybox `nc -u -l` locks onto the
22
+ * FIRST client's source port forever and never forks for a second one, so
23
+ * this supervises a chain of single-client listeners instead: each `nc`
24
+ * relays through a fresh `timeout 60 nc` leg to the target and, the moment
25
+ * it locks onto a client, this starts the next listener behind it. "Locked
26
+ * onto a client" is read from `/proc/$pid/cmdline`, not the process's own
27
+ * `comm` — busybox `timeout` keeps the ORIGINAL pid for the program it
28
+ * wraps and only forks the timer, so `comm` reads `nc` again once a client
29
+ * has connected, indistinguishable from the pre-connection listener by name
30
+ * alone. The FIRST inner wait blocks WHILE `cmdline` still contains this
31
+ * script's own `rz-udp-link` path: immediately after `&` forks the child,
32
+ * its cmdline is still THIS script's (the shell hasn't exec'd `nc` yet), and
33
+ * treating that as "locked" starts a flood of listeners on top of one
34
+ * another. The SECOND inner wait blocks WHILE `cmdline` still contains
35
+ * ` -l ` — the listener's own unlocked marker; once that's gone the
36
+ * listener has locked onto a client, and the loop starts the next one.
37
+ * `timeout 60` bounds each individual client's relay — msb's own UDP
38
+ * sessions idle out after 60s, so a client that keeps sending past that
39
+ * gets a fresh relay rather than a wedged one. The gateway's IPv4 literal
40
+ * (never the `host.microsandbox.internal` name) is read once from
41
+ * `/etc/hosts`; `: ${H:=host.microsandbox.internal}` falls back to the name
42
+ * itself when `/etc/hosts` carries no IPv4 gateway line. That name also
43
+ * resolves to an IPv6 gateway, which msb rewrites to `::1`, where the
44
+ * target's 127.0.0.1-bound port never listens.
45
+ *
46
+ * No argument here is ever quoted, and the script carries no `"` anywhere:
47
+ * on Windows hosts the JDK's default `ProcessBuilder` command-line building
48
+ * wraps an exec argument in quotes without escaping embedded ones, so a `"`
49
+ * reaching an exec argument this backend builds comes out mangled on
50
+ * `msb.exe`. Every variable in this script is a number (`$P`, `$HP`,
51
+ * `$pid`) or an IP literal (`$H`), so unquoted word-splitting is never a
52
+ * hazard.
53
+ */
54
+ export declare const UDP_FORWARDER_SCRIPT = "P=$1; HP=$2\nH=$(awk -v n=host.microsandbox.internal '$2 == n && $1 ~ /^[0-9.]+$/ { print $1; exit }' /etc/hosts)\n: ${H:=host.microsandbox.internal}\nwhile true; do\n nc -u -l -p $P -e timeout 60 nc -u $H $HP &\n pid=$!\n while [ -e /proc/$pid ] && grep -q rz-udp-link /proc/$pid/cmdline 2>/dev/null; do sleep 0.01; done\n while [ -e /proc/$pid ] && tr '\\0' ' ' < /proc/$pid/cmdline 2>/dev/null | grep -q -- ' -l '; do sleep 0.05; done\n [ -e /proc/$pid ] || sleep 0.2\ndone";
55
+ /**
56
+ * Capability probe for the forwarder's own dependencies — run once per
57
+ * `installNetworkLinks` call, only when at least one UDP link is present.
58
+ * The plain `command -v nc` the TCP exec-tunnel already probes says nothing
59
+ * about `-e`/`-u` or `timeout`, all three of which the forwarder needs.
60
+ * busybox prints its own usage to STDERR on `--help` with a non-zero exit,
61
+ * hence the `2>&1` merge rather than trusting the exit code alone.
62
+ */
63
+ export declare function udpForwarderProbeScript(): string;
64
+ /**
65
+ * The "one exec" that installs and launches a UDP link's forwarder: writes
66
+ * `UDP_FORWARDER_SCRIPT` to `udpForwarderScriptPath(guestPort)` via a QUOTED
67
+ * heredoc (`<<'EOF'`, never expanded while writing — the script's own `$1`/
68
+ * `$P`/`$pid`/... must reach the file literally, not this shell's
69
+ * evaluation of them), then launches it DETACHED, redirecting its output to
70
+ * `udpForwarderLogPath(guestPort)`. Launched as a FILE argument to `sh`
71
+ * (`sh <path>`), never `sh -c` with the content inlined: the script's own
72
+ * pre-exec wait (see `UDP_FORWARDER_SCRIPT`'s own doc) greps the freshly
73
+ * forked child's cmdline for `rz-udp-link`, which is only there because the
74
+ * path itself carries that substring — an inlined `-c` invocation's cmdline
75
+ * never would. A detached background process survives this exec session;
76
+ * guest processes die with the sandbox, so a UDP link needs no host-side
77
+ * teardown, and a checkpoint reboot's link replay simply reruns this
78
+ * against the rebooted (tmpfs-backed) `/tmp`.
79
+ */
80
+ export declare function installUdpForwarderScript(guestPort: number, targetHostPort: number): string;
81
+ /**
82
+ * True (exit 0) once `guestPort` shows up bound in `/proc/net/udp` or
83
+ * `/proc/net/udp6` — polled at a short interval after launching the
84
+ * forwarder, since `nc -u -l`'s bind happens after process startup and
85
+ * prints nothing to signal it. Matches on the LAST 4 hex digits of the
86
+ * local-address column (`<addr>:<PORT-hex>`) rather than the whole column,
87
+ * since the address part varies (`00000000` for an unbound-interface
88
+ * listener) and only the port is what this needs to confirm; `NR>1` skips
89
+ * the header line both files start with.
90
+ */
91
+ export declare function udpReadinessProbeScript(guestPort: number): string;
7
92
  //# sourceMappingURL=network-links.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"network-links.d.ts","sourceRoot":"","sources":["../../src/backend-msb/network-links.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAUtD,qGAAqG;AACrG,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,GAAG,IAAI,CAWhF;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,GAAG,IAAI,CAW1E;AAED,gFAAgF;AAChF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,GAAG,MAAM,CAGtE"}
1
+ {"version":3,"file":"network-links.d.ts","sourceRoot":"","sources":["../../src/backend-msb/network-links.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAUtD;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,GAAG,IAAI,CAYhF;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,GAAG,IAAI,CAW1E;AAED,gFAAgF;AAChF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,GAAG,MAAM,CAGtE;AAED,8LAA8L;AAC9L,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED,mHAAmH;AACnH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,oBAAoB,seAS5B,CAAC;AAEN;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAKhD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAO3F;AAOD;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAMjE"}
@@ -5,14 +5,22 @@ const BACKEND_NAME = "microsandbox";
5
5
  // that could break out of the quoting, not to enforce a strict hostname
6
6
  // grammar.
7
7
  const ALIAS_CHARSET = /^[A-Za-z0-9._-]+$/;
8
- /** Two siblings publishing the same guest port on one network have nowhere distinct to tunnel to. */
8
+ /**
9
+ * Two siblings publishing the same guest port ON THE SAME PROTOCOL have
10
+ * nowhere distinct to route to — checked per (protocol, guestPort), not
11
+ * guestPort alone, so a container exposing one guest port on BOTH
12
+ * protocols (DNS's 53, say) is never flagged: its TCP and UDP links each
13
+ * get their own independent route (an exec-tunnel, a forwarder script) and
14
+ * never collide with each other.
15
+ */
9
16
  export function requireNoDuplicateGuestPorts(links) {
10
17
  const seen = new Set();
11
18
  for (const link of links) {
12
- if (seen.has(link.guestPort)) {
13
- throw new UnsupportedByBackendError(`two siblings exposing the same guest port ${link.guestPort} on one network`, BACKEND_NAME);
19
+ const key = `${link.protocol}:${link.guestPort}`;
20
+ if (seen.has(key)) {
21
+ throw new UnsupportedByBackendError(`two siblings exposing the same ${link.protocol} guest port ${link.guestPort} on one network`, BACKEND_NAME);
14
22
  }
15
- seen.add(link.guestPort);
23
+ seen.add(key);
16
24
  }
17
25
  }
18
26
  export function requireAliasesAreValid(links) {
@@ -28,4 +36,111 @@ export function hostsAliasScript(links) {
28
36
  const aliases = [...new Set(links.map((l) => l.alias))];
29
37
  return aliases.map((alias) => `echo '127.0.0.1 ${alias}' >> /etc/hosts`).join("; ");
30
38
  }
39
+ /** Where a UDP link's forwarder script/log live in the guest — the name itself is load-bearing: it is grepped back out of `/proc/<pid>/cmdline` by the script's own supervisor loop below. */
40
+ export function udpForwarderScriptPath(guestPort) {
41
+ return `/tmp/rz-udp-link-${guestPort}.sh`;
42
+ }
43
+ /** The forwarder's own launch log, tailed into a readiness-timeout error to give it something to diagnose from. */
44
+ export function udpForwarderLogPath(guestPort) {
45
+ return `/tmp/rz-udp-link-${guestPort}.log`;
46
+ }
47
+ /**
48
+ * The in-guest UDP forwarder, one instance per linked UDP port: relays
49
+ * `guestPort` to `<gateway IPv4>:<targetHostPort>`, where the target's own
50
+ * host-published UDP port is listening. busybox `nc -u -l` locks onto the
51
+ * FIRST client's source port forever and never forks for a second one, so
52
+ * this supervises a chain of single-client listeners instead: each `nc`
53
+ * relays through a fresh `timeout 60 nc` leg to the target and, the moment
54
+ * it locks onto a client, this starts the next listener behind it. "Locked
55
+ * onto a client" is read from `/proc/$pid/cmdline`, not the process's own
56
+ * `comm` — busybox `timeout` keeps the ORIGINAL pid for the program it
57
+ * wraps and only forks the timer, so `comm` reads `nc` again once a client
58
+ * has connected, indistinguishable from the pre-connection listener by name
59
+ * alone. The FIRST inner wait blocks WHILE `cmdline` still contains this
60
+ * script's own `rz-udp-link` path: immediately after `&` forks the child,
61
+ * its cmdline is still THIS script's (the shell hasn't exec'd `nc` yet), and
62
+ * treating that as "locked" starts a flood of listeners on top of one
63
+ * another. The SECOND inner wait blocks WHILE `cmdline` still contains
64
+ * ` -l ` — the listener's own unlocked marker; once that's gone the
65
+ * listener has locked onto a client, and the loop starts the next one.
66
+ * `timeout 60` bounds each individual client's relay — msb's own UDP
67
+ * sessions idle out after 60s, so a client that keeps sending past that
68
+ * gets a fresh relay rather than a wedged one. The gateway's IPv4 literal
69
+ * (never the `host.microsandbox.internal` name) is read once from
70
+ * `/etc/hosts`; `: ${H:=host.microsandbox.internal}` falls back to the name
71
+ * itself when `/etc/hosts` carries no IPv4 gateway line. That name also
72
+ * resolves to an IPv6 gateway, which msb rewrites to `::1`, where the
73
+ * target's 127.0.0.1-bound port never listens.
74
+ *
75
+ * No argument here is ever quoted, and the script carries no `"` anywhere:
76
+ * on Windows hosts the JDK's default `ProcessBuilder` command-line building
77
+ * wraps an exec argument in quotes without escaping embedded ones, so a `"`
78
+ * reaching an exec argument this backend builds comes out mangled on
79
+ * `msb.exe`. Every variable in this script is a number (`$P`, `$HP`,
80
+ * `$pid`) or an IP literal (`$H`), so unquoted word-splitting is never a
81
+ * hazard.
82
+ */
83
+ export const UDP_FORWARDER_SCRIPT = `P=$1; HP=$2
84
+ H=$(awk -v n=host.microsandbox.internal '$2 == n && $1 ~ /^[0-9.]+$/ { print $1; exit }' /etc/hosts)
85
+ : \${H:=host.microsandbox.internal}
86
+ while true; do
87
+ nc -u -l -p $P -e timeout 60 nc -u $H $HP &
88
+ pid=$!
89
+ while [ -e /proc/$pid ] && grep -q rz-udp-link /proc/$pid/cmdline 2>/dev/null; do sleep 0.01; done
90
+ while [ -e /proc/$pid ] && tr '\\0' ' ' < /proc/$pid/cmdline 2>/dev/null | grep -q -- ' -l '; do sleep 0.05; done
91
+ [ -e /proc/$pid ] || sleep 0.2
92
+ done`;
93
+ /**
94
+ * Capability probe for the forwarder's own dependencies — run once per
95
+ * `installNetworkLinks` call, only when at least one UDP link is present.
96
+ * The plain `command -v nc` the TCP exec-tunnel already probes says nothing
97
+ * about `-e`/`-u` or `timeout`, all three of which the forwarder needs.
98
+ * busybox prints its own usage to STDERR on `--help` with a non-zero exit,
99
+ * hence the `2>&1` merge rather than trusting the exit code alone.
100
+ */
101
+ export function udpForwarderProbeScript() {
102
+ return ("command -v nc >/dev/null && command -v timeout >/dev/null && " +
103
+ "nc --help 2>&1 | grep -q -- '-e PROG' && nc --help 2>&1 | grep -q -- '-u'");
104
+ }
105
+ /**
106
+ * The "one exec" that installs and launches a UDP link's forwarder: writes
107
+ * `UDP_FORWARDER_SCRIPT` to `udpForwarderScriptPath(guestPort)` via a QUOTED
108
+ * heredoc (`<<'EOF'`, never expanded while writing — the script's own `$1`/
109
+ * `$P`/`$pid`/... must reach the file literally, not this shell's
110
+ * evaluation of them), then launches it DETACHED, redirecting its output to
111
+ * `udpForwarderLogPath(guestPort)`. Launched as a FILE argument to `sh`
112
+ * (`sh <path>`), never `sh -c` with the content inlined: the script's own
113
+ * pre-exec wait (see `UDP_FORWARDER_SCRIPT`'s own doc) greps the freshly
114
+ * forked child's cmdline for `rz-udp-link`, which is only there because the
115
+ * path itself carries that substring — an inlined `-c` invocation's cmdline
116
+ * never would. A detached background process survives this exec session;
117
+ * guest processes die with the sandbox, so a UDP link needs no host-side
118
+ * teardown, and a checkpoint reboot's link replay simply reruns this
119
+ * against the rebooted (tmpfs-backed) `/tmp`.
120
+ */
121
+ export function installUdpForwarderScript(guestPort, targetHostPort) {
122
+ const scriptPath = udpForwarderScriptPath(guestPort);
123
+ const logPath = udpForwarderLogPath(guestPort);
124
+ return (`cat > ${scriptPath} <<'EOF'\n${UDP_FORWARDER_SCRIPT}\nEOF\n` +
125
+ `nohup sh ${scriptPath} ${guestPort} ${targetHostPort} >${logPath} 2>&1 &`);
126
+ }
127
+ /** `guestPort` as 4 uppercase hex digits — `/proc/net/udp{,6}`'s own local-address-column encoding (5000 → `"1388"`). */
128
+ function guestPortHex(guestPort) {
129
+ return guestPort.toString(16).toUpperCase().padStart(4, "0");
130
+ }
131
+ /**
132
+ * True (exit 0) once `guestPort` shows up bound in `/proc/net/udp` or
133
+ * `/proc/net/udp6` — polled at a short interval after launching the
134
+ * forwarder, since `nc -u -l`'s bind happens after process startup and
135
+ * prints nothing to signal it. Matches on the LAST 4 hex digits of the
136
+ * local-address column (`<addr>:<PORT-hex>`) rather than the whole column,
137
+ * since the address part varies (`00000000` for an unbound-interface
138
+ * listener) and only the port is what this needs to confirm; `NR>1` skips
139
+ * the header line both files start with.
140
+ */
141
+ export function udpReadinessProbeScript(guestPort) {
142
+ const hex = guestPortHex(guestPort);
143
+ return (`awk -v p=':${hex}' 'NR>1 && substr($2, length($2)-4) == p {f=1} END {exit !f}' ` +
144
+ "/proc/net/udp /proc/net/udp6");
145
+ }
31
146
  //# sourceMappingURL=network-links.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"network-links.js","sourceRoot":"","sources":["../../src/backend-msb/network-links.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAG9D,MAAM,YAAY,GAAG,cAAc,CAAC;AAEpC,wEAAwE;AACxE,0EAA0E;AAC1E,wEAAwE;AACxE,WAAW;AACX,MAAM,aAAa,GAAG,mBAAmB,CAAC;AAE1C,qGAAqG;AACrG,MAAM,UAAU,4BAA4B,CAAC,KAA6B;IACxE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,yBAAyB,CACjC,6CAA6C,IAAI,CAAC,SAAS,iBAAiB,EAC5E,YAAY,CACb,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAA6B;IAClE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACnD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,yBAAyB,CACjC,kBAAkB,KAAK,GAAG,EAC1B,YAAY,EACZ,yEAAyE,CAC1E,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,gBAAgB,CAAC,KAA6B;IAC5D,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACxD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,mBAAmB,KAAK,iBAAiB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACtF,CAAC"}
1
+ {"version":3,"file":"network-links.js","sourceRoot":"","sources":["../../src/backend-msb/network-links.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@ import type { Platform } from "./platform.js";
4
4
  * while msb 0.6.10-0.6.13 were broken on Windows (fixed upstream in 0.6.14).
5
5
  * MSB_PATH users on Windows must avoid 0.6.10-0.6.13.
6
6
  */
7
- export declare const MSB_VERSION = "0.6.18";
7
+ export declare const MSB_VERSION = "0.7.1";
8
8
  /** Test seam: the full resolution logic parameterized over the release base URL, cache dir, and environment. */
9
9
  export declare function ensureInstalledAt(baseUrl: string, cacheDir: string, env: Record<string, string | undefined>): Promise<string>;
10
10
  /** Resolves (downloading and verifying if needed) a runnable `msb` binary path, using the real GitHub release base, `RIGHTSIZE_CACHE_DIR`, and `process.env`. */
@@ -1 +1 @@
1
- {"version":3,"file":"provisioner.d.ts","sourceRoot":"","sources":["../../src/backend-msb/provisioner.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;;;GAIG;AACH,eAAO,MAAM,WAAW,WAAW,CAAC;AAiRpC,gHAAgH;AAChH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GACtC,OAAO,CAAC,MAAM,CAAC,CA8CjB;AAED,iKAAiK;AACjK,wBAAgB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAEjD;AAED,2GAA2G;AAC3G,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAEzE;AAED,gHAAgH;AAChH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;;;;;;;GAQG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAEf"}
1
+ {"version":3,"file":"provisioner.d.ts","sourceRoot":"","sources":["../../src/backend-msb/provisioner.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;;;GAIG;AACH,eAAO,MAAM,WAAW,UAAU,CAAC;AAiRnC,gHAAgH;AAChH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GACtC,OAAO,CAAC,MAAM,CAAC,CA8CjB;AAED,iKAAiK;AACjK,wBAAgB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAEjD;AAED,2GAA2G;AAC3G,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAEzE;AAED,gHAAgH;AAChH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;;;;;;;GAQG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAEf"}
@@ -12,7 +12,7 @@ import { PlatformInfo } from "./platform.js";
12
12
  * while msb 0.6.10-0.6.13 were broken on Windows (fixed upstream in 0.6.14).
13
13
  * MSB_PATH users on Windows must avoid 0.6.10-0.6.13.
14
14
  */
15
- export const MSB_VERSION = "0.6.18";
15
+ export const MSB_VERSION = "0.7.1";
16
16
  function releaseBaseUrl(version) {
17
17
  return `https://github.com/superradcompany/microsandbox/releases/download/v${version}`;
18
18
  }