pi-microsandbox 0.1.0 → 0.2.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.
- package/README.md +21 -16
- package/docs/commands.md +3 -2
- package/docs/configuration.md +35 -4
- package/docs/development.md +96 -8
- package/docs/getting-started.md +25 -21
- package/docs/images.md +16 -8
- package/docs/safety.md +25 -5
- package/docs/storage.md +14 -0
- package/docs/troubleshooting.md +24 -0
- package/extensions/pi-msb/command.ts +5 -0
- package/extensions/pi-msb/config.ts +65 -6
- package/extensions/pi-msb/control.ts +95 -14
- package/extensions/pi-msb/flock.ts +94 -0
- package/extensions/pi-msb/locks.ts +5 -84
- package/extensions/pi-msb/sandbox-manager.ts +56 -7
- package/extensions/pi-msb/types.ts +18 -0
- package/native/flock/prebuilds/darwin-arm64/flock.node +0 -0
- package/native/flock/prebuilds/linux-arm64-gnu/flock.node +0 -0
- package/native/flock/prebuilds/linux-x64-gnu/flock.node +0 -0
- package/package.json +10 -7
package/README.md
CHANGED
|
@@ -39,34 +39,39 @@ Keep your everyday defaults in global config and project-specific settings in
|
|
|
39
39
|
variables and session overrides let you adjust a particular run without
|
|
40
40
|
rewriting the project's setup.
|
|
41
41
|
|
|
42
|
-
The agent gets an environment built for the job.
|
|
43
|
-
|
|
42
|
+
The agent gets an environment built for the job. Image cohorts built from this
|
|
43
|
+
version include Docker Engine 29.8.0, Buildx 0.37.1, and Compose 5.5.1. The
|
|
44
|
+
daemon and its containers run inside the microVM; pi-microsandbox never connects them to the
|
|
45
|
+
host Docker socket. You don't have to make the same decisions every time you
|
|
46
|
+
start it.
|
|
44
47
|
|
|
45
48
|
[Configure your project's sandbox →](docs/configuration.md)
|
|
46
49
|
|
|
47
50
|
## Get started
|
|
48
51
|
|
|
49
|
-
You'll need Pi, **Node.js 22.19.0+**, and
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
You'll need Pi, **Node.js 22.19.0+**, and one of the supported host targets:
|
|
53
|
+
Apple Silicon macOS (`darwin-arm64`), GNU Linux x86_64
|
|
54
|
+
(`linux-x64-gnu`), or GNU Linux arm64 (`linux-arm64-gnu`). Live sandboxes also
|
|
55
|
+
need host virtualization support. The POSIX lock addon is bundled and installs
|
|
56
|
+
without lifecycle scripts or a compiler.
|
|
52
57
|
[Full requirements and installation help →](docs/getting-started.md)
|
|
53
58
|
|
|
54
|
-
Install
|
|
59
|
+
Install pi-microsandbox:
|
|
55
60
|
|
|
56
61
|
```sh
|
|
57
|
-
|
|
62
|
+
pi install npm:pi-microsandbox
|
|
58
63
|
```
|
|
59
64
|
|
|
60
|
-
|
|
61
|
-
runtime
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
Then install pi-microsandbox:
|
|
65
|
+
That command also installs the pinned Microsandbox SDK, CLI, and matching
|
|
66
|
+
platform runtime. A separate Microsandbox installation is not required on a
|
|
67
|
+
supported host. Keep npm optional dependencies enabled so npm installs the
|
|
68
|
+
platform package.
|
|
66
69
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
If the platform package is unavailable, you can provide a standalone `msb`
|
|
71
|
+
binary with `MSB_PATH`. See the official
|
|
72
|
+
[Microsandbox documentation](https://docs.microsandbox.dev/) for standalone
|
|
73
|
+
installation and runtime troubleshooting. The documentation in this repository
|
|
74
|
+
covers the Pi integration.
|
|
70
75
|
|
|
71
76
|
From a Git repository, start Pi with its own isolated workspace:
|
|
72
77
|
|
package/docs/commands.md
CHANGED
|
@@ -23,8 +23,9 @@ The extension registers `/msb`:
|
|
|
23
23
|
/msb help
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
`/msb status` reports the full sandbox name, mode, image, PID, age,
|
|
27
|
-
and retained volume metadata
|
|
26
|
+
`/msb status` reports the full sandbox name, mode, image, PID, age, Docker
|
|
27
|
+
mode/readiness/version/storage driver, branch/SHA, and retained volume metadata
|
|
28
|
+
when available. Six-character IDs in UI text are
|
|
28
29
|
display abbreviations only. `/msb prune` walks all SDK list pages and reports
|
|
29
30
|
removed, kept, and error entries; **volumes are never pruned**.
|
|
30
31
|
|
package/docs/configuration.md
CHANGED
|
@@ -15,9 +15,11 @@ The following is a small project example:
|
|
|
15
15
|
```toml
|
|
16
16
|
# .pi-msb.toml
|
|
17
17
|
mode = "git"
|
|
18
|
-
image = "ghcr.io/hcohe/pi-microsandbox:1.
|
|
18
|
+
image = "ghcr.io/hcohe/pi-microsandbox:1.1.0@sha256:ab4e99d4232f827b3f295ff3210437e01446dbb672ef0d0c78358566170ac86c"
|
|
19
19
|
pull_policy = "if-missing"
|
|
20
20
|
bootstrap_tools = "auto"
|
|
21
|
+
cpus = 4
|
|
22
|
+
memory_mib = 8192
|
|
21
23
|
idle_timeout_sec = 600
|
|
22
24
|
fallback_mode = "block"
|
|
23
25
|
show_footer = true # Default; set false to hide the MSB footer status.
|
|
@@ -26,6 +28,10 @@ show_footer = true # Default; set false to hide the MSB footer status.
|
|
|
26
28
|
mode = "default" # default | open | allowlist | deny
|
|
27
29
|
allow_dns = true
|
|
28
30
|
|
|
31
|
+
[docker]
|
|
32
|
+
mode = "auto" # auto | require | disabled
|
|
33
|
+
startup_timeout_ms = 15000
|
|
34
|
+
|
|
29
35
|
# Project secrets should use references, not literals.
|
|
30
36
|
[[secrets]]
|
|
31
37
|
env = "NPM_TOKEN"
|
|
@@ -50,17 +56,40 @@ Important configuration behavior:
|
|
|
50
56
|
contents, custom image workflows, and the required guest commands.
|
|
51
57
|
`bootstrap_tools = "auto"` probes those commands and uses noninteractive
|
|
52
58
|
`apt-get` under the configured network policy when a custom image is missing
|
|
53
|
-
them. `false` blocks with the missing command list instead.
|
|
59
|
+
them. `false` blocks with the missing command list instead. New sandboxes use
|
|
60
|
+
4 CPUs and 8192 MiB by default; set `cpus` and `memory_mib` lower if the host
|
|
61
|
+
cannot support that allocation.
|
|
62
|
+
- `docker.mode = "auto"` starts the guest daemon when the image has Docker and
|
|
63
|
+
reports `missing` for older or custom images without it. `"require"` blocks
|
|
64
|
+
sandbox preparation if Docker is absent or cannot start. `"disabled"` leaves
|
|
65
|
+
the installed daemon stopped. `startup_timeout_ms` must be an integer from 1
|
|
66
|
+
through 300000. Readiness is pinned to the managed guest Unix socket and
|
|
67
|
+
ignores inherited Docker client endpoint settings. Docker state stays on the
|
|
68
|
+
disposable guest root filesystem. Small builds should have at least 1 GiB; larger Compose stacks usually need
|
|
69
|
+
2 GiB or more.
|
|
54
70
|
- `network.mode = "default"` leaves the SDK's default policy in place. `open`
|
|
55
71
|
allows all network traffic, including private/host access; `allowlist` is
|
|
56
72
|
default-deny with configured host/DNS rules; `deny` disables networking.
|
|
57
73
|
Published ports default to loopback unless a bind address is specified.
|
|
74
|
+
Nested containers remain subject to this outer policy. A Docker `-p` mapping
|
|
75
|
+
exposes a port only inside the microVM. Host access also needs a matching
|
|
76
|
+
`network.publish_ports` entry created with the sandbox, for example
|
|
77
|
+
`publish_ports = ["127.0.0.1:8080:8080"]` together with `docker run -p
|
|
78
|
+
0.0.0.0:8080:8080 ...`. Docker's random host-port form cannot create that
|
|
79
|
+
outer mapping.
|
|
58
80
|
- Secrets require a non-empty `allow_hosts` list. `$ENV:NAME` and `$FILE:path`
|
|
59
81
|
references are resolved only while constructing the SDK builder. Effective
|
|
60
|
-
config, warnings, errors, and `/msb config` redact literal values.
|
|
82
|
+
config, warnings, errors, and `/msb config` redact literal values. Process
|
|
83
|
+
control variables such as `DOCKER_HOST`, `DOCKER_CONTEXT`, `PATH`,
|
|
84
|
+
`BASH_ENV`, and `LD_PRELOAD` cannot be forwarded with `host_env` or injected
|
|
85
|
+
as secrets.
|
|
61
86
|
- Directory/file mounts have absolute guest paths. Project mounts outside the
|
|
62
87
|
repository must be read-only unless a global/session policy authorizes the
|
|
63
|
-
write. Mounts may not overlap or shadow the project mount
|
|
88
|
+
write. Mounts may not overlap or shadow the project mount, reserved `/tmp`,
|
|
89
|
+
protected guest system trees such as `/usr`, `/bin`, `/proc`, and `/sys`, or
|
|
90
|
+
Docker runtime paths such as `/run`, `/var/run`, and `/var/lib/docker`.
|
|
91
|
+
Host mount sources are canonicalized before use; socket targets, including
|
|
92
|
+
Docker sockets reached through symlink aliases, are rejected.
|
|
64
93
|
- The legacy `host_ro_allowlist` is converted to canonical read-only mounts and
|
|
65
94
|
emits a deprecation warning.
|
|
66
95
|
|
|
@@ -71,6 +100,8 @@ PI_MSB_DISABLE=1 # explicit host/off mode
|
|
|
71
100
|
PI_MSB_MODE=none # nested scalar example
|
|
72
101
|
PI_MSB_PULL_POLICY=always # recheck mutable custom image tags on creation
|
|
73
102
|
PI_MSB_NETWORK__MODE=deny # nested environment key
|
|
103
|
+
PI_MSB_DOCKER__MODE=require # require a working guest Docker daemon
|
|
104
|
+
PI_MSB_DOCKER__STARTUP_TIMEOUT_MS=30000
|
|
74
105
|
PI_MSB_FALLBACK_MODE=host # opt into automatic host fallback
|
|
75
106
|
PI_MSB_SHOW_FOOTER=false # hide the MSB status from Pi's footer
|
|
76
107
|
PI_MSB_ROUTE_TOOLS='read,write' # POSIX delimiter for simple arrays
|
package/docs/development.md
CHANGED
|
@@ -12,19 +12,87 @@ To test from source without installing the npm package globally:
|
|
|
12
12
|
git clone https://github.com/hcohe/pi-microsandbox.git
|
|
13
13
|
cd pi-microsandbox
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
npm ci
|
|
15
|
+
npm ci --ignore-scripts=true
|
|
17
16
|
npm run typecheck
|
|
18
17
|
npm test
|
|
19
18
|
npm run smoke # extension-load smoke; no sandbox starts
|
|
20
19
|
npm run check # all three commands above
|
|
21
20
|
npm audit --omit=dev
|
|
22
|
-
npm pack --dry-run --json
|
|
23
21
|
```
|
|
24
22
|
|
|
25
23
|
The smoke and unit tests do not require KVM, image pulls, or a live sandbox.
|
|
26
24
|
The boot-speed check and live matrix below are explicit VM tests.
|
|
27
25
|
|
|
26
|
+
To test the current extension and default image together, run:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
just dev
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`dev-flock` builds and smoke-tests the native owner-lock addon for the current
|
|
33
|
+
host. `dev-image` builds the current `default` variant as
|
|
34
|
+
`pi-microsandbox-dev:local` and imports it into Microsandbox's separate image
|
|
35
|
+
cache. `dev` runs both prerequisites, then starts Pi with this checkout's
|
|
36
|
+
extension explicitly loaded alongside your normal discovered extensions. It
|
|
37
|
+
forces the local image with `pull_policy = "never"`, requires Docker, and uses
|
|
38
|
+
4 CPUs and 8192 MiB. Docker caching keeps repeat builds short
|
|
39
|
+
when image inputs have not changed. Pass Pi arguments directly, for example:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
just dev --continue
|
|
43
|
+
just dev "Run docker info and report the storage driver"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Run `just dev-image` by itself when you only need to refresh the local image.
|
|
47
|
+
|
|
48
|
+
### Bundled flock addon
|
|
49
|
+
|
|
50
|
+
Consumers receive prebuilt lock addons and do not need native build tools. Only
|
|
51
|
+
contributors building or changing the addon need Python, a C compiler, and the
|
|
52
|
+
platform build tools used by node-gyp (`make` on GNU Linux or Xcode command-line
|
|
53
|
+
tools on macOS). On one of the three supported targets, run:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
npm ci --ignore-scripts=true
|
|
57
|
+
npm run build:flock
|
|
58
|
+
npm run smoke:flock
|
|
59
|
+
npm run check
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The build writes
|
|
63
|
+
`native/flock/prebuilds/<target>/flock.node` for the current target. These
|
|
64
|
+
outputs are ignored by Git and must not be committed. CI builds
|
|
65
|
+
`darwin-arm64`, `linux-x64-gnu`, and `linux-arm64-gnu` separately on native
|
|
66
|
+
runners, then loads the same binary under Node 22.19.0 and Node 24.
|
|
67
|
+
|
|
68
|
+
### Assemble a package from CI artifacts
|
|
69
|
+
|
|
70
|
+
A complete package needs all three `flock-<target>` artifacts from one CI run.
|
|
71
|
+
Download each artifact into one empty artifact root, create a staging checkout
|
|
72
|
+
from the same commit's Git archive, then give both paths to the assembler:
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
run_id=GITHUB_ACTIONS_RUN_ID
|
|
76
|
+
mkdir -p .tmp
|
|
77
|
+
artifact_root="$(mktemp -d "$PWD/.tmp/flock-artifacts.XXXXXX")"
|
|
78
|
+
staging="$(mktemp -d "$PWD/.tmp/package-staging.XXXXXX")"
|
|
79
|
+
pack_dir="$(mktemp -d "$PWD/.tmp/package-pack.XXXXXX")"
|
|
80
|
+
|
|
81
|
+
for target in darwin-arm64 linux-x64-gnu linux-arm64-gnu; do
|
|
82
|
+
gh run download "$run_id" --name "flock-$target" --dir "$artifact_root"
|
|
83
|
+
done
|
|
84
|
+
|
|
85
|
+
git archive HEAD | tar -x -C "$staging"
|
|
86
|
+
npm run assemble:package -- "$artifact_root" "$staging"
|
|
87
|
+
pack_json="$(npm pack "$staging" --json --pack-destination "$pack_dir")"
|
|
88
|
+
tarball="$(node -e 'const value=JSON.parse(process.argv[1]); const results=Array.isArray(value)?value:Object.values(value); if(results.length!==1) throw new Error(`expected one pack result, got ${results.length}`); process.stdout.write(results[0].filename)' "$pack_json")"
|
|
89
|
+
npm run package-smoke -- "$pack_dir/$tarball"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Use artifacts built from the same commit as `HEAD`. The assembler rejects
|
|
93
|
+
missing, extra, or symlinked artifacts and keeps generated binaries out of the
|
|
94
|
+
source checkout.
|
|
95
|
+
|
|
28
96
|
## Boot speed regression test
|
|
29
97
|
|
|
30
98
|
With [`just`](https://just.systems/) installed, measure the awaited sandbox boot
|
|
@@ -71,14 +139,20 @@ Without that variable the script prints a `SKIP` line for every scenario and
|
|
|
71
139
|
exits successfully; this skip path does not validate virtualization. If
|
|
72
140
|
virtualization is unavailable, it prints the reason and skips the matrix rather
|
|
73
141
|
than reporting false failures. Set `PI_MSB_LIVE_IMAGE` to select the main live
|
|
74
|
-
test image; the default is `ghcr.io/hcohe/pi-microsandbox:latest`.
|
|
142
|
+
test image; the default is `ghcr.io/hcohe/pi-microsandbox:latest`. The main
|
|
143
|
+
scenarios use `pull_policy = "always"` by default. To test an image already
|
|
144
|
+
imported with `msb load`, set `PI_MSB_LIVE_PULL_POLICY=never`; do not use that
|
|
145
|
+
override as evidence for a published image.
|
|
75
146
|
The prepared-image scenario boots all six latest variant tags under
|
|
76
147
|
`network.mode = "deny"` with bootstrap disabled. Set
|
|
77
148
|
`PI_MSB_LIVE_PREPARED_IMAGES` to a comma-separated image cohort, or use the
|
|
78
149
|
legacy singular `PI_MSB_LIVE_PREPARED_IMAGE` to test one image. The live matrix
|
|
79
150
|
uses `pull_policy = "always"` intentionally so mutable development tags cannot
|
|
80
|
-
remain stale on the self-hosted runner. Review the output to confirm that
|
|
81
|
-
|
|
151
|
+
remain stale on the self-hosted runner. Review the output to confirm that every scenario reports `PASS`, not `SKIP`.
|
|
152
|
+
Docker release validation must cover daemon readiness, bridge DNS and HTTPS,
|
|
153
|
+
user-defined networking, Buildx, Compose, idle wake, double port publishing,
|
|
154
|
+
and nested-container enforcement for deny and allowlist policies. A skipped
|
|
155
|
+
Docker scenario is not release evidence.
|
|
82
156
|
|
|
83
157
|
## Image development
|
|
84
158
|
|
|
@@ -89,7 +163,17 @@ variant's mutable latest tag and a commit-specific tag. Release builds pin the
|
|
|
89
163
|
Ubuntu image digest and one dated apt snapshot for all variants, while published
|
|
90
164
|
images restore normal apt sources for project use. See [Images](images.md#add-a-language-variant)
|
|
91
165
|
for the modular installer and verifier architecture, contribution rules, and
|
|
92
|
-
local validation commands.
|
|
166
|
+
local validation commands. Docker changes must also pass:
|
|
167
|
+
|
|
168
|
+
```sh
|
|
169
|
+
node scripts/image-variants.mjs matrix
|
|
170
|
+
shellcheck -e SC1091 default-image/install/*.sh default-image/verify/*.sh
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
The common image verifier checks Docker Engine 29.8.0, containerd 2.3.4, runc
|
|
174
|
+
1.5.1, Buildx 0.37.1, Compose 5.5.1, and Ubuntu's iptables-nft/nftables tools.
|
|
175
|
+
Docker daemon and nested-container behavior require the live microVM matrix;
|
|
176
|
+
they cannot be validated during a Dockerfile build.
|
|
93
177
|
|
|
94
178
|
## Releases
|
|
95
179
|
|
|
@@ -98,7 +182,11 @@ canonical changelog. The first npm publication is a human-run local publish of
|
|
|
98
182
|
the reviewed tarball with interactive npm 2FA. Subsequent releases publish
|
|
99
183
|
directly to npm with OIDC only after a maintainer publishes the matching GitHub
|
|
100
184
|
Release and approves the protected `npm` GitHub Environment. Release automation
|
|
101
|
-
must not use a long-lived npm token.
|
|
185
|
+
must not use a long-lived npm token. Release CI builds every flock artifact from
|
|
186
|
+
the release commit, assembles a temporary staging tree, records each binary's
|
|
187
|
+
SHA-256, smoke-tests the exact tarball on every supported target, and packs only
|
|
188
|
+
once. The publish job downloads and publishes those verified bytes without
|
|
189
|
+
repacking.
|
|
102
190
|
|
|
103
191
|
The sandbox image workflow publishes all six AMD64 and ARM64 variants to
|
|
104
192
|
`ghcr.io/hcohe/pi-microsandbox`. An `image-vX.Y.Z` Git tag publishes the
|
package/docs/getting-started.md
CHANGED
|
@@ -9,27 +9,26 @@ require one of these hosts:
|
|
|
9
9
|
|
|
10
10
|
| Host | Architecture | Virtualization requirement |
|
|
11
11
|
| --- | --- | --- |
|
|
12
|
-
| macOS | Apple Silicon (arm64) | Apple virtualization support available to the process |
|
|
13
|
-
| Linux | x86_64 or arm64 (
|
|
14
|
-
|
|
15
|
-
Windows
|
|
16
|
-
microsandbox runtime has preview Windows support, but this package
|
|
17
|
-
|
|
18
|
-
KVM passthrough or nested virtualization; many hosted
|
|
19
|
-
provide it. Package loading and non-live tests do not
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
to a working `msb` binary. These alternatives do not remove the host
|
|
12
|
+
| macOS | Apple Silicon (`darwin-arm64`) | Apple virtualization support available to the process |
|
|
13
|
+
| GNU Linux | x86_64 (`linux-x64-gnu`) or arm64 (`linux-arm64-gnu`) | KVM enabled, with `/dev/kvm` accessible to the process |
|
|
14
|
+
|
|
15
|
+
Windows, Intel macOS, and musl Linux are not supported by pi-microsandbox. The
|
|
16
|
+
upstream microsandbox runtime has preview Windows support, but this package
|
|
17
|
+
deliberately supports only the three targets above. A Linux container or
|
|
18
|
+
virtual machine also needs KVM passthrough or nested virtualization; many hosted
|
|
19
|
+
environments do not provide it. Package loading and non-live tests do not
|
|
20
|
+
require virtualization.
|
|
21
|
+
|
|
22
|
+
pi-microsandbox includes a prebuilt POSIX lock addon for each supported target.
|
|
23
|
+
It is loaded lazily when an owner lock is first needed. Consumer installation
|
|
24
|
+
does not compile native code or require Python, a C/C++ toolchain, or npm
|
|
25
|
+
lifecycle scripts; installation with scripts disabled is supported.
|
|
26
|
+
|
|
27
|
+
Keep optional dependencies enabled. `microsandbox@0.6.16` supplies its CLI,
|
|
28
|
+
native addon, and runtime binaries through an optional platform package. If that
|
|
29
|
+
platform package is missing, reinstall with optional dependencies enabled,
|
|
30
|
+
install the matching Microsandbox platform package, or set `MSB_PATH` to a
|
|
31
|
+
working standalone `msb` binary. These alternatives do not remove the host
|
|
33
32
|
virtualization requirement.
|
|
34
33
|
|
|
35
34
|
## Install
|
|
@@ -40,6 +39,11 @@ Install the package for the current user with Pi:
|
|
|
40
39
|
pi install npm:pi-microsandbox
|
|
41
40
|
```
|
|
42
41
|
|
|
42
|
+
This is the only package installation step on a supported host. The dependency
|
|
43
|
+
includes the Microsandbox SDK and CLI; its matching optional platform package
|
|
44
|
+
includes the host runtime. You do not need to run the standalone Microsandbox
|
|
45
|
+
installer first.
|
|
46
|
+
|
|
43
47
|
Before starting a sandbox, review [configuration](configuration.md) and choose a
|
|
44
48
|
[published variant or custom image](images.md) if the versioned default image
|
|
45
49
|
does not fit the project.
|
package/docs/images.md
CHANGED
|
@@ -15,7 +15,7 @@ Push an exact `image-vVERSION` Git tag to publish a release cohort. Package
|
|
|
15
15
|
|
|
16
16
|
| Variant | Contents | Release tag | Latest tag |
|
|
17
17
|
| --- | --- | --- | --- |
|
|
18
|
-
| `base` | Required guest commands
|
|
18
|
+
| `base` | Required guest commands, CA certificates, Docker 29.8.0, Buildx 0.37.1, and Compose 5.5.1; no language toolchain | `base-VERSION` | `base-latest` |
|
|
19
19
|
| `node` | Base plus Node.js 24.21.0, npm, pnpm 12.3.4, Yarn 1.22.22, and native addon build support | `node-VERSION` | `node-latest` |
|
|
20
20
|
| `python` | Base plus Ubuntu Python 3, pip, uv/uvx 0.12.12, and native extension build support | `python-VERSION` | `python-latest` |
|
|
21
21
|
| `rust` | Base plus Rust 1.98.0, Cargo, rustup, and native dependency build support | `rust-VERSION` | `rust-latest` |
|
|
@@ -23,8 +23,12 @@ Push an exact `image-vVERSION` Git tag to publish a release cohort. Package
|
|
|
23
23
|
| `default` | Base plus the Node.js, Python, Rust, and Go modules above | `VERSION` | `latest` |
|
|
24
24
|
|
|
25
25
|
The base contract includes `bash`, `sh`, `git`, `rg`, `file`, `cat`, `mkdir`,
|
|
26
|
-
`rm`,
|
|
27
|
-
|
|
26
|
+
`rm`, Docker Engine and CLI 29.8.0, containerd 2.3.4, runc 1.5.1, Buildx
|
|
27
|
+
0.37.1, Compose 5.5.1, and the Ubuntu iptables-nft and nftables tools. CA
|
|
28
|
+
certificates support HTTPS Git operations. Docker is part of the common base
|
|
29
|
+
rather than a language toolchain, so all six variants built from this version
|
|
30
|
+
contain it. The extension's digest-pinned default changes only after that cohort
|
|
31
|
+
has been published and verified.
|
|
28
32
|
|
|
29
33
|
Select a variant in trusted project configuration:
|
|
30
34
|
|
|
@@ -46,10 +50,10 @@ an updated mutable tag, or `"never"` to require a cached local image.
|
|
|
46
50
|
[`default-image/variants.json`](../default-image/variants.json) is the single
|
|
47
51
|
source of variant composition and tag names. The workflow passes each entry's
|
|
48
52
|
toolchain list to one generic
|
|
49
|
-
[`default-image/Dockerfile`](../default-image/Dockerfile).
|
|
50
|
-
`default-image/install/<language>.sh`
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
[`default-image/Dockerfile`](../default-image/Dockerfile). The common Docker installer runs before the modular
|
|
54
|
+
`default-image/install/<language>.sh` scripts. The corresponding common
|
|
55
|
+
verifier checks Docker and its CLI plugins in every variant; language verifiers
|
|
56
|
+
then exercise each selected toolchain.
|
|
53
57
|
|
|
54
58
|
The `default` variant runs the same Node.js, Python, Rust, and Go modules as the
|
|
55
59
|
individual variants. It does not have a duplicate package list. This keeps an
|
|
@@ -63,7 +67,11 @@ can install current packages at runtime.
|
|
|
63
67
|
## Build a custom image
|
|
64
68
|
|
|
65
69
|
A custom image must provide `bash`, `sh`, `git`, `rg`, `file`, `cat`, `mkdir`,
|
|
66
|
-
and `rm`.
|
|
70
|
+
and `rm`. Docker is optional for custom images. The default `docker.mode =
|
|
71
|
+
"auto"` records it as missing and continues; use `docker.mode = "require"` when
|
|
72
|
+
the image contract must include a working daemon. pi-microsandbox does not
|
|
73
|
+
install Docker during sandbox startup. Install CA certificates if the guest
|
|
74
|
+
will use Git over HTTPS. With
|
|
67
75
|
`bootstrap_tools = "auto"`, pi-microsandbox can install missing required
|
|
68
76
|
commands through `apt-get` when the network policy permits it. A prepared image
|
|
69
77
|
is required when bootstrap is disabled or package repositories are unavailable.
|
package/docs/safety.md
CHANGED
|
@@ -19,11 +19,31 @@ The default is fail-closed:
|
|
|
19
19
|
after a sandbox failure and is shown as `MSB host fallback`.
|
|
20
20
|
- A project cannot replace another process's sandbox: ownership is a
|
|
21
21
|
non-blocking kernel `flock` acquired before any sandbox or volume mutation.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
The small bundled POSIX addon is loaded lazily, has no install script, and
|
|
23
|
+
never falls back to a racy PID check. Stale sandbox pruning never removes
|
|
24
|
+
volumes.
|
|
25
|
+
|
|
26
|
+
The extension entry point does not import the native SDK or load the flock
|
|
27
|
+
addon. Unsupported hosts can still load Pi and remain blocked or explicitly
|
|
28
|
+
off. pi-microsandbox supports Apple Silicon macOS and GNU Linux x86_64 or arm64
|
|
29
|
+
with KVM; Windows, Intel macOS, and musl Linux are not supported.
|
|
30
|
+
|
|
31
|
+
## Docker inside the guest
|
|
32
|
+
|
|
33
|
+
The Docker daemon runs inside the microVM and listens only on the guest Unix
|
|
34
|
+
socket. Access to that socket is root-equivalent inside the guest, not on the
|
|
35
|
+
host. Readiness probes explicitly select that socket and reject unverified
|
|
36
|
+
socket ownership. Docker and process-control environment variables are cleared
|
|
37
|
+
for preparation, and configuration cannot forward them. Mounts that shadow
|
|
38
|
+
protected guest executables or Docker runtime paths are rejected. The extension never mounts the host Docker
|
|
39
|
+
socket, starts a host daemon, or copies host Docker configuration and registry
|
|
40
|
+
credentials into the guest.
|
|
41
|
+
|
|
42
|
+
A container can still reach anything already mounted into the microVM. In
|
|
43
|
+
`direct` mode that includes the host project directory; in Git mode it includes
|
|
44
|
+
the retained workspace; explicitly configured mounts are visible too. Treat a
|
|
45
|
+
Dockerfile or Compose file as guest-root code and use read-only mounts where
|
|
46
|
+
possible. Container egress remains behind the Microsandbox network policy.
|
|
27
47
|
|
|
28
48
|
## Host-read exceptions
|
|
29
49
|
|
package/docs/storage.md
CHANGED
|
@@ -15,6 +15,20 @@
|
|
|
15
15
|
routed edits modify the live host directory. `none` is useful for testing path
|
|
16
16
|
behavior and starts empty; it is not a retained workspace.
|
|
17
17
|
|
|
18
|
+
## Inner Docker state
|
|
19
|
+
|
|
20
|
+
Docker stores images, layers, containers, and build cache under
|
|
21
|
+
`/var/lib/docker` on the sandbox root filesystem. It uses the `vfs` storage
|
|
22
|
+
driver because nested overlay filesystems and project-backed mounts cannot be
|
|
23
|
+
assumed to support `overlay2`. This state disappears when the sandbox is
|
|
24
|
+
removed. It is not written to the project mount or retained Git volume, and
|
|
25
|
+
separate sessions do not share an inner Docker cache.
|
|
26
|
+
|
|
27
|
+
A stopped sandbox may retain that state until it is restarted or removed, but a
|
|
28
|
+
retained Git workspace does not preserve it. Do not move Docker's data root
|
|
29
|
+
onto the Git volume. A persistent Docker cache would need a separate managed
|
|
30
|
+
volume and cleanup policy.
|
|
31
|
+
|
|
18
32
|
## Git and retained volumes
|
|
19
33
|
|
|
20
34
|
Git mode never bind-mounts the host checkout. On boot, pi-microsandbox captures the
|
package/docs/troubleshooting.md
CHANGED
|
@@ -17,4 +17,28 @@
|
|
|
17
17
|
command list or allow the configured network policy to reach the package
|
|
18
18
|
repositories. Deny mode cannot bootstrap an image missing those commands.
|
|
19
19
|
|
|
20
|
+
## Docker daemon problems
|
|
21
|
+
|
|
22
|
+
`/msb status` shows the configured Docker mode, readiness, server version, and
|
|
23
|
+
storage driver. Inside an active sandbox, start or recheck the daemon with:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
pi-msb-docker-start 15000
|
|
27
|
+
docker info
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Startup logs are guest-local at `/var/log/pi-msb-dockerd.log`. Check the network
|
|
31
|
+
prerequisites with `iptables --version` (it should report `nf_tables`), `nft
|
|
32
|
+
--version`, and `sysctl net.ipv4.ip_forward` (it should be `1`). The daemon uses
|
|
33
|
+
`vfs`; slower builds and higher disk use are expected compared with `overlay2`.
|
|
34
|
+
Increase `memory_mib` or `docker.startup_timeout_ms` if startup is killed or
|
|
35
|
+
large builds run out of memory. Small builds should have at least 1 GiB and
|
|
36
|
+
larger Compose stacks should have 2 GiB or more; the default is 8 GiB.
|
|
37
|
+
|
|
38
|
+
A published container port needs two mappings. Configure the outer
|
|
39
|
+
`network.publish_ports` mapping before sandbox creation, then use Docker `-p`
|
|
40
|
+
inside the guest. A Docker mapping by itself is not reachable from the host.
|
|
41
|
+
Pull and container-egress failures under `deny` or `allowlist` are expected;
|
|
42
|
+
do not bypass the outer policy or mount the host Docker socket as a workaround.
|
|
43
|
+
|
|
20
44
|
For installation prerequisites, see [installation and requirements](getting-started.md). To test a live sandbox from source, see the [live test matrix](development.md#live-test-matrix).
|
|
@@ -198,6 +198,11 @@ function fullState(state: RuntimeState): string {
|
|
|
198
198
|
lines.push(`Image: ${info.image}`);
|
|
199
199
|
lines.push(`PID: ${info.pid}`);
|
|
200
200
|
lines.push(`Age: ${displayTime(info.createdAt)}`);
|
|
201
|
+
lines.push(`Docker mode: ${info.docker.mode}`);
|
|
202
|
+
lines.push(`Docker readiness: ${info.docker.readiness}`);
|
|
203
|
+
if (info.docker.version) lines.push(`Docker version: ${info.docker.version}`);
|
|
204
|
+
if (info.docker.storageDriver) lines.push(`Docker storage driver: ${info.docker.storageDriver}`);
|
|
205
|
+
if (info.docker.reason) lines.push(`Docker reason: ${info.docker.reason}`);
|
|
201
206
|
if (info.seedBranch) lines.push(`Branch: ${info.seedBranch}`);
|
|
202
207
|
if (info.seedSha) lines.push(`Seed SHA: ${info.seedSha}`);
|
|
203
208
|
if (info.volumeName) lines.push(`Retained volume: ${info.volumeName}`);
|