@sandbank.dev/boxlite 0.3.2 → 0.3.4
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.
- package/README.md +9 -0
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +5 -6
- package/dist/local-client.d.ts.map +1 -1
- package/dist/local-client.js +203 -47
- package/dist/types.d.ts +3 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -63,6 +63,15 @@ const { stdout } = await sandbox.exec('echo hello')
|
|
|
63
63
|
await provider.destroy(sandbox.id)
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
+
### Local OCI rootfs (skip registry pull)
|
|
67
|
+
|
|
68
|
+
If `image` is an absolute path, it is treated as a local OCI layout directory:
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// Export image: skopeo copy docker-daemon:myimage:latest oci:~/.boxlite/myimage-oci:latest
|
|
72
|
+
const sandbox = await provider.create({ image: '/Users/you/.boxlite/myimage-oci' })
|
|
73
|
+
```
|
|
74
|
+
|
|
66
75
|
### OAuth2 authentication (remote mode)
|
|
67
76
|
|
|
68
77
|
```typescript
|
package/dist/adapter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,UAAU,EACV,YAAY,EAGZ,UAAU,EACV,cAAc,EACd,WAAW,EAIZ,MAAM,oBAAoB,CAAA;AAI3B,OAAO,KAAK,EAAE,oBAAoB,EAA6B,MAAM,YAAY,CAAA;AAoKjF,qBAAa,cAAe,YAAW,cAAc;IACnD,QAAQ,CAAC,IAAI,aAAY;IACzB,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC,UAAU,CAAC,CAAA;IAE9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyC;gBAEtD,MAAM,EAAE,oBAAoB;
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,UAAU,EACV,YAAY,EAGZ,UAAU,EACV,cAAc,EACd,WAAW,EAIZ,MAAM,oBAAoB,CAAA;AAI3B,OAAO,KAAK,EAAE,oBAAoB,EAA6B,MAAM,YAAY,CAAA;AAoKjF,qBAAa,cAAe,YAAW,cAAc;IACnD,QAAQ,CAAC,IAAI,aAAY;IACzB,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC,UAAU,CAAC,CAAA;IAE9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyC;gBAEtD,MAAM,EAAE,oBAAoB;IASlC,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC;IAiD5D,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAW/C,aAAa,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA0B1D,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU/C,8EAA8E;IACxE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAG/B"}
|
package/dist/adapter.js
CHANGED
|
@@ -153,17 +153,16 @@ export class BoxLiteAdapter {
|
|
|
153
153
|
this.config = config;
|
|
154
154
|
this.host = resolveHost(config);
|
|
155
155
|
this.client = createClient(config);
|
|
156
|
-
|
|
157
|
-
const caps = ['exec.stream', 'terminal', 'sleep', 'port.expose'];
|
|
158
|
-
if (config.mode !== 'local') {
|
|
159
|
-
caps.push('snapshot');
|
|
160
|
-
}
|
|
156
|
+
const caps = ['exec.stream', 'terminal', 'sleep', 'port.expose', 'snapshot'];
|
|
161
157
|
this.capabilities = new Set(caps);
|
|
162
158
|
}
|
|
163
159
|
async createSandbox(config) {
|
|
164
160
|
try {
|
|
161
|
+
// If image looks like an absolute path, treat it as a local OCI rootfs
|
|
162
|
+
const image = config.image ?? 'ubuntu:24.04';
|
|
163
|
+
const isLocalPath = image.startsWith('/');
|
|
165
164
|
const box = await this.client.createBox({
|
|
166
|
-
image:
|
|
165
|
+
...(isLocalPath ? { rootfs_path: image } : { image }),
|
|
167
166
|
cpu: config.resources?.cpu,
|
|
168
167
|
memory_mb: config.resources?.memory,
|
|
169
168
|
disk_size_gb: config.resources?.disk,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-client.d.ts","sourceRoot":"","sources":["../src/local-client.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAEV,aAAa,EAGb,kBAAkB,EAEnB,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"local-client.d.ts","sourceRoot":"","sources":["../src/local-client.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAEV,aAAa,EAGb,kBAAkB,EAEnB,MAAM,YAAY,CAAA;AAmfnB;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,kBAAkB,GAAG,aAAa,CAsRlF"}
|
package/dist/local-client.js
CHANGED
|
@@ -37,39 +37,28 @@ class Bridge:
|
|
|
37
37
|
if self._runtime is not None:
|
|
38
38
|
return
|
|
39
39
|
|
|
40
|
-
#
|
|
40
|
+
# Create a Boxlite runtime for the custom home_dir, then use SimpleBox
|
|
41
|
+
# with that runtime. SimpleBox's exec is more stable for rapid consecutive
|
|
42
|
+
# calls than Boxlite.create(BoxOptions).exec().
|
|
41
43
|
Options = getattr(boxlite, "Options", None)
|
|
42
44
|
Boxlite = getattr(boxlite, "Boxlite", None)
|
|
43
45
|
if Options and Boxlite:
|
|
44
46
|
try:
|
|
45
47
|
opts = Options(home_dir=self._home)
|
|
46
|
-
|
|
47
|
-
self._runtime = rt
|
|
48
|
-
return
|
|
48
|
+
self._boxlite_rt = Boxlite(opts)
|
|
49
49
|
except Exception:
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
for attr in ("BoxliteRuntime", "Runtime", "runtime"):
|
|
54
|
-
cls = getattr(boxlite, attr, None)
|
|
55
|
-
if cls is None:
|
|
56
|
-
continue
|
|
57
|
-
try:
|
|
58
|
-
rt = cls(home=self._home) if callable(cls) else cls
|
|
59
|
-
if asyncio.iscoroutinefunction(getattr(rt, "start", None)):
|
|
60
|
-
await rt.start()
|
|
61
|
-
self._runtime = rt
|
|
62
|
-
return
|
|
63
|
-
except Exception:
|
|
64
|
-
continue
|
|
50
|
+
self._boxlite_rt = None
|
|
51
|
+
else:
|
|
52
|
+
self._boxlite_rt = None
|
|
65
53
|
|
|
66
|
-
#
|
|
54
|
+
# Use SimpleBox with the runtime (handles home_dir correctly)
|
|
67
55
|
self._runtime = "simple_box"
|
|
68
56
|
|
|
69
57
|
async def create(self, params):
|
|
70
58
|
await self._ensure_runtime()
|
|
71
59
|
|
|
72
|
-
image = params
|
|
60
|
+
image = params.get("image", "")
|
|
61
|
+
rootfs = params.get("rootfs_path")
|
|
73
62
|
now = datetime.now(timezone.utc).isoformat()
|
|
74
63
|
|
|
75
64
|
# Normalize env/ports
|
|
@@ -82,7 +71,8 @@ class Bridge:
|
|
|
82
71
|
|
|
83
72
|
if self._runtime == "simple_box":
|
|
84
73
|
# SimpleBox uses: image, memory_mib, cpus, disk_size_gb, env, working_dir
|
|
85
|
-
|
|
74
|
+
# rootfs_path overrides image when provided (local OCI layout directory)
|
|
75
|
+
sb_kwargs = {"rootfs_path": rootfs} if rootfs else {"image": image}
|
|
86
76
|
if params.get("cpu") is not None:
|
|
87
77
|
sb_kwargs["cpus"] = params["cpu"]
|
|
88
78
|
if params.get("memory_mb") is not None:
|
|
@@ -96,6 +86,12 @@ class Bridge:
|
|
|
96
86
|
if ports is not None:
|
|
97
87
|
sb_kwargs["ports"] = ports
|
|
98
88
|
|
|
89
|
+
# Disable auto_remove so runtime.get() works after stop (needed for snapshot restore)
|
|
90
|
+
sb_kwargs["auto_remove"] = params.get("auto_remove", False)
|
|
91
|
+
|
|
92
|
+
# Pass the Boxlite runtime to SimpleBox so it uses the correct home_dir
|
|
93
|
+
if getattr(self, "_boxlite_rt", None) is not None:
|
|
94
|
+
sb_kwargs["runtime"] = self._boxlite_rt
|
|
99
95
|
sb = boxlite.SimpleBox(**sb_kwargs)
|
|
100
96
|
box = await sb.__aenter__()
|
|
101
97
|
box_id = str(getattr(box, "id", None)
|
|
@@ -107,21 +103,28 @@ class Bridge:
|
|
|
107
103
|
# Boxlite.create(BoxOptions(...), name=None)
|
|
108
104
|
BoxOptions = getattr(boxlite, "BoxOptions", None)
|
|
109
105
|
if BoxOptions is not None:
|
|
110
|
-
|
|
106
|
+
opt_kwargs = {}
|
|
107
|
+
if rootfs:
|
|
108
|
+
opt_kwargs["rootfs_path"] = rootfs
|
|
109
|
+
else:
|
|
110
|
+
opt_kwargs["image"] = image
|
|
111
111
|
if params.get("cpu") is not None:
|
|
112
|
-
|
|
112
|
+
opt_kwargs["cpus"] = params["cpu"]
|
|
113
113
|
if params.get("memory_mb") is not None:
|
|
114
|
-
|
|
114
|
+
opt_kwargs["memory_mib"] = params["memory_mb"]
|
|
115
115
|
if params.get("disk_size_gb") is not None:
|
|
116
|
-
|
|
116
|
+
opt_kwargs["disk_size_gb"] = params["disk_size_gb"]
|
|
117
117
|
if env is not None:
|
|
118
|
-
|
|
118
|
+
opt_kwargs["env"] = env
|
|
119
119
|
if params.get("working_dir") is not None:
|
|
120
|
-
|
|
120
|
+
opt_kwargs["working_dir"] = params["working_dir"]
|
|
121
|
+
if ports is not None:
|
|
122
|
+
opt_kwargs["ports"] = ports
|
|
123
|
+
opts = BoxOptions(**opt_kwargs)
|
|
121
124
|
box = await self._runtime.create(opts)
|
|
122
125
|
else:
|
|
123
126
|
# Legacy fallback: pass as kwargs
|
|
124
|
-
kwargs = {"image": image}
|
|
127
|
+
kwargs = {"rootfs_path": rootfs} if rootfs else {"image": image}
|
|
125
128
|
for k in ("cpu", "memory_mb", "disk_size_gb", "working_dir"):
|
|
126
129
|
if params.get(k) is not None:
|
|
127
130
|
kwargs[k] = params[k]
|
|
@@ -206,23 +209,61 @@ class Bridge:
|
|
|
206
209
|
if result is None:
|
|
207
210
|
raise RuntimeError(f"All exec strategies failed: {'; '.join(errors)}")
|
|
208
211
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
+
stdout = ""
|
|
213
|
+
stderr = ""
|
|
214
|
+
exit_code = 0
|
|
212
215
|
|
|
213
|
-
#
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
216
|
+
# Execution object (Boxlite runtime API): collect stdout/stderr streams, then wait
|
|
217
|
+
if hasattr(result, "wait") and callable(result.wait):
|
|
218
|
+
async def _collect(stream_fn):
|
|
219
|
+
try:
|
|
220
|
+
buf = bytearray()
|
|
221
|
+
async for chunk in stream_fn():
|
|
222
|
+
if isinstance(chunk, (bytes, bytearray)):
|
|
223
|
+
buf.extend(chunk)
|
|
224
|
+
else:
|
|
225
|
+
buf.extend(str(chunk).encode("utf-8"))
|
|
226
|
+
return buf.decode("utf-8", errors="replace")
|
|
227
|
+
except Exception:
|
|
228
|
+
return ""
|
|
229
|
+
|
|
230
|
+
# Read stdout/stderr concurrently to avoid pipe deadlocks
|
|
231
|
+
tasks = []
|
|
232
|
+
has_stdout = hasattr(result, "stdout") and callable(result.stdout)
|
|
233
|
+
has_stderr = hasattr(result, "stderr") and callable(result.stderr)
|
|
234
|
+
if has_stdout:
|
|
235
|
+
tasks.append(asyncio.create_task(_collect(result.stdout)))
|
|
236
|
+
if has_stderr:
|
|
237
|
+
tasks.append(asyncio.create_task(_collect(result.stderr)))
|
|
238
|
+
|
|
239
|
+
if tasks:
|
|
240
|
+
collected = await asyncio.gather(*tasks)
|
|
241
|
+
idx = 0
|
|
242
|
+
if has_stdout:
|
|
243
|
+
stdout = collected[idx]; idx += 1
|
|
244
|
+
if has_stderr:
|
|
245
|
+
stderr = collected[idx]
|
|
246
|
+
|
|
247
|
+
exec_result = await result.wait()
|
|
248
|
+
exit_code = int(getattr(exec_result, "exit_code",
|
|
249
|
+
getattr(exec_result, "returncode", 0)) or 0)
|
|
250
|
+
else:
|
|
251
|
+
# SimpleBox / legacy: result already has stdout/stderr as attributes
|
|
252
|
+
raw_stdout = getattr(result, "stdout", "")
|
|
253
|
+
raw_stderr = getattr(result, "stderr", "")
|
|
254
|
+
if callable(raw_stdout):
|
|
255
|
+
raw_stdout = raw_stdout()
|
|
256
|
+
if callable(raw_stderr):
|
|
257
|
+
raw_stderr = raw_stderr()
|
|
258
|
+
stdout = str(raw_stdout or "")
|
|
259
|
+
stderr = str(raw_stderr or "")
|
|
260
|
+
exit_code = int(getattr(result, "exit_code",
|
|
261
|
+
getattr(result, "returncode", 0)) or 0)
|
|
220
262
|
|
|
221
263
|
return {
|
|
222
|
-
"stdout":
|
|
223
|
-
"stderr":
|
|
224
|
-
"exit_code":
|
|
225
|
-
getattr(result, "returncode", 0)) or 0),
|
|
264
|
+
"stdout": stdout,
|
|
265
|
+
"stderr": stderr,
|
|
266
|
+
"exit_code": exit_code,
|
|
226
267
|
}
|
|
227
268
|
|
|
228
269
|
async def destroy(self, box_id):
|
|
@@ -260,6 +301,111 @@ class Bridge:
|
|
|
260
301
|
if box and hasattr(box, "start"):
|
|
261
302
|
await box.start()
|
|
262
303
|
|
|
304
|
+
def _get_box(self, box_id):
|
|
305
|
+
box = self._boxes.get(box_id)
|
|
306
|
+
if box is None:
|
|
307
|
+
raise ValueError(f"Box not found: {box_id}")
|
|
308
|
+
# SimpleBox wraps the real Box — unwrap to get snapshot handle
|
|
309
|
+
inner = getattr(box, "_box", box)
|
|
310
|
+
return inner
|
|
311
|
+
|
|
312
|
+
async def create_snapshot(self, box_id, name):
|
|
313
|
+
# boxlite snapshot uses fork_qcow2 (rename + COW child). If QEMU is
|
|
314
|
+
# running, its FD still points to the renamed inode, so post-snapshot
|
|
315
|
+
# writes corrupt the snapshot file. Must stop → snapshot → restart.
|
|
316
|
+
inner = self._get_box(box_id)
|
|
317
|
+
await inner.stop()
|
|
318
|
+
|
|
319
|
+
rt = getattr(self, "_boxlite_rt", None)
|
|
320
|
+
if rt is None:
|
|
321
|
+
raise RuntimeError("Cannot create snapshot: no Boxlite runtime")
|
|
322
|
+
fresh = await rt.get(box_id)
|
|
323
|
+
if fresh is None:
|
|
324
|
+
raise RuntimeError(f"Cannot get fresh handle for box {box_id}")
|
|
325
|
+
snap_handle = getattr(fresh, "snapshot", None)
|
|
326
|
+
if snap_handle is None:
|
|
327
|
+
raise RuntimeError("Fresh handle has no snapshot support")
|
|
328
|
+
|
|
329
|
+
info = await snap_handle.create(name=name)
|
|
330
|
+
snap_name = str(getattr(info, "name", name))
|
|
331
|
+
|
|
332
|
+
# Restart the VM with the new COW child disk
|
|
333
|
+
await fresh.__aenter__()
|
|
334
|
+
# Update SimpleBox/Box internal references
|
|
335
|
+
old_sb = self._simple_boxes.get(box_id)
|
|
336
|
+
old_box = self._boxes.get(box_id)
|
|
337
|
+
if old_sb and hasattr(old_sb, "_box"):
|
|
338
|
+
old_sb._box = fresh
|
|
339
|
+
old_sb._started = True
|
|
340
|
+
if old_box and hasattr(old_box, "_box"):
|
|
341
|
+
old_box._box = fresh
|
|
342
|
+
else:
|
|
343
|
+
self._boxes[box_id] = fresh
|
|
344
|
+
|
|
345
|
+
return {
|
|
346
|
+
"id": str(getattr(info, "id", snap_name)),
|
|
347
|
+
"box_id": box_id,
|
|
348
|
+
"name": snap_name,
|
|
349
|
+
"created_at": int(getattr(info, "created_at", 0)),
|
|
350
|
+
"size_bytes": int(getattr(info, "size_bytes", 0)),
|
|
351
|
+
"guest_disk_bytes": int(getattr(info, "guest_disk_bytes", 0) or 0),
|
|
352
|
+
"container_disk_bytes": int(getattr(info, "container_disk_bytes", 0) or 0),
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
async def restore_snapshot(self, box_id, name):
|
|
356
|
+
# Same stop → fresh handle pattern as create_snapshot.
|
|
357
|
+
# stop() also invalidates the LiteBox handle (cancels shutdown_token).
|
|
358
|
+
inner = self._get_box(box_id)
|
|
359
|
+
await inner.stop()
|
|
360
|
+
|
|
361
|
+
rt = getattr(self, "_boxlite_rt", None)
|
|
362
|
+
if rt is None:
|
|
363
|
+
raise RuntimeError("Cannot restore snapshot: no Boxlite runtime")
|
|
364
|
+
fresh = await rt.get(box_id)
|
|
365
|
+
if fresh is None:
|
|
366
|
+
raise RuntimeError(f"Cannot get fresh handle for box {box_id}")
|
|
367
|
+
fresh_snap = getattr(fresh, "snapshot", None)
|
|
368
|
+
if fresh_snap is None:
|
|
369
|
+
raise RuntimeError("Fresh handle has no snapshot support")
|
|
370
|
+
|
|
371
|
+
await fresh_snap.restore(name)
|
|
372
|
+
|
|
373
|
+
# Restart with the restored disk
|
|
374
|
+
await fresh.__aenter__()
|
|
375
|
+
# Update SimpleBox/Box internal references
|
|
376
|
+
old_sb = self._simple_boxes.get(box_id)
|
|
377
|
+
old_box = self._boxes.get(box_id)
|
|
378
|
+
if old_sb and hasattr(old_sb, "_box"):
|
|
379
|
+
old_sb._box = fresh
|
|
380
|
+
old_sb._started = True
|
|
381
|
+
if old_box and hasattr(old_box, "_box"):
|
|
382
|
+
old_box._box = fresh
|
|
383
|
+
else:
|
|
384
|
+
self._boxes[box_id] = fresh
|
|
385
|
+
|
|
386
|
+
async def list_snapshots(self, box_id):
|
|
387
|
+
inner = self._get_box(box_id)
|
|
388
|
+
snap_handle = getattr(inner, "snapshot", None)
|
|
389
|
+
if snap_handle is None:
|
|
390
|
+
raise RuntimeError("Box does not support snapshots")
|
|
391
|
+
snapshots = await snap_handle.list()
|
|
392
|
+
return [{
|
|
393
|
+
"id": str(getattr(s, "id", "")),
|
|
394
|
+
"box_id": box_id,
|
|
395
|
+
"name": str(getattr(s, "name", "")),
|
|
396
|
+
"created_at": int(getattr(s, "created_at", 0)),
|
|
397
|
+
"size_bytes": int(getattr(s, "size_bytes", 0)),
|
|
398
|
+
"guest_disk_bytes": int(getattr(s, "guest_disk_bytes", 0) or 0),
|
|
399
|
+
"container_disk_bytes": int(getattr(s, "container_disk_bytes", 0) or 0),
|
|
400
|
+
} for s in snapshots]
|
|
401
|
+
|
|
402
|
+
async def delete_snapshot(self, box_id, name):
|
|
403
|
+
inner = self._get_box(box_id)
|
|
404
|
+
snap_handle = getattr(inner, "snapshot", None)
|
|
405
|
+
if snap_handle is None:
|
|
406
|
+
raise RuntimeError("Box does not support snapshots")
|
|
407
|
+
await snap_handle.remove(name)
|
|
408
|
+
|
|
263
409
|
async def cleanup(self):
|
|
264
410
|
for box_id in list(self._boxes.keys()):
|
|
265
411
|
try:
|
|
@@ -311,6 +457,16 @@ async def main():
|
|
|
311
457
|
elif action == "stop":
|
|
312
458
|
await bridge.stop(cmd["box_id"])
|
|
313
459
|
result = {}
|
|
460
|
+
elif action == "create_snapshot":
|
|
461
|
+
result = await bridge.create_snapshot(cmd["box_id"], cmd["name"])
|
|
462
|
+
elif action == "restore_snapshot":
|
|
463
|
+
await bridge.restore_snapshot(cmd["box_id"], cmd["name"])
|
|
464
|
+
result = {}
|
|
465
|
+
elif action == "list_snapshots":
|
|
466
|
+
result = await bridge.list_snapshots(cmd["box_id"])
|
|
467
|
+
elif action == "delete_snapshot":
|
|
468
|
+
await bridge.delete_snapshot(cmd["box_id"], cmd["name"])
|
|
469
|
+
result = {}
|
|
314
470
|
elif action == "ping":
|
|
315
471
|
result = {"pong": True}
|
|
316
472
|
else:
|
|
@@ -542,16 +698,16 @@ export function createBoxLiteLocalClient(config) {
|
|
|
542
698
|
});
|
|
543
699
|
},
|
|
544
700
|
async createSnapshot(boxId, name) {
|
|
545
|
-
|
|
701
|
+
return send({ action: 'create_snapshot', box_id: boxId, name });
|
|
546
702
|
},
|
|
547
703
|
async restoreSnapshot(boxId, name) {
|
|
548
|
-
|
|
704
|
+
await send({ action: 'restore_snapshot', box_id: boxId, name });
|
|
549
705
|
},
|
|
550
706
|
async listSnapshots(boxId) {
|
|
551
|
-
|
|
707
|
+
return send({ action: 'list_snapshots', box_id: boxId });
|
|
552
708
|
},
|
|
553
709
|
async deleteSnapshot(boxId, name) {
|
|
554
|
-
|
|
710
|
+
await send({ action: 'delete_snapshot', box_id: boxId, name });
|
|
555
711
|
},
|
|
556
712
|
async dispose() {
|
|
557
713
|
if (process?.stdin?.writable) {
|
package/dist/types.d.ts
CHANGED
|
@@ -90,7 +90,9 @@ export interface BoxLiteSnapshot {
|
|
|
90
90
|
container_disk_bytes?: number;
|
|
91
91
|
}
|
|
92
92
|
export interface BoxLiteCreateParams {
|
|
93
|
-
image
|
|
93
|
+
image?: string;
|
|
94
|
+
/** Path to a local OCI layout directory. When set, overrides `image` (no registry pull). */
|
|
95
|
+
rootfs_path?: string;
|
|
94
96
|
name?: string;
|
|
95
97
|
cpu?: number;
|
|
96
98
|
memory_mb?: number;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sandbank.dev/boxlite",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "BoxLite bare-metal sandbox adapter for Sandbank",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"clean": "rm -rf dist"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@sandbank.dev/core": "^0.3.
|
|
35
|
+
"@sandbank.dev/core": "^0.3.4"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/node": "^25.3.0",
|