Skip to content

Commit d5ee127

Browse files
authored
Merge pull request #1 from vmg-dev/docs/platform-guides
Add platform guides and distro integration test matrix
2 parents 45d8c41 + 7d9ecde commit d5ee127

10 files changed

Lines changed: 387 additions & 48 deletions

File tree

.github/workflows/ci.yml

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,37 @@ jobs:
3333
integration-tests:
3434
runs-on: ubuntu-latest
3535
needs: build-and-test
36-
timeout-minutes: 40
36+
timeout-minutes: 50
37+
strategy:
38+
fail-fast: false
39+
matrix:
40+
include:
41+
- distro: alpine
42+
image: alpine:3.20
43+
probe_path: /etc/alpine-release
44+
probe_command: cat /etc/alpine-release
45+
probe_expect: "3.20"
46+
- distro: debian
47+
image: debian:bookworm-slim
48+
probe_path: /etc/debian_version
49+
probe_command: cat /etc/debian_version
50+
probe_expect: "12"
51+
- distro: ubuntu
52+
image: ubuntu:24.04
53+
probe_path: /etc/os-release
54+
probe_command: . /etc/os-release; echo "$ID:$VERSION_ID"
55+
probe_expect: ubuntu:24.04
56+
- distro: fedora
57+
image: fedora:41
58+
probe_path: /etc/fedora-release
59+
probe_command: cat /etc/fedora-release
60+
probe_expect: "Fedora release 41"
61+
- distro: archlinux
62+
image: archlinux:latest
63+
probe_path: /etc/os-release
64+
probe_command: . /etc/os-release; echo "$ID"
65+
probe_expect: arch
66+
name: integration-tests (${{ matrix.distro }})
3767

3868
steps:
3969
- name: Checkout
@@ -52,10 +82,16 @@ jobs:
5282
sudo apt-get update
5383
sudo apt-get install -y qemu-system-x86 e2fsprogs
5484
85+
- name: Prime Gondolin guest assets
86+
run: bun --eval 'import { ensureGuestAssets } from "@earendil-works/gondolin"; await ensureGuestAssets();'
87+
5588
- name: Run integration tests
5689
env:
5790
INTEGRATION_PLATFORM: linux/amd64
58-
INTEGRATION_IMAGE: busybox:latest
91+
INTEGRATION_IMAGE: ${{ matrix.image }}
92+
INTEGRATION_ROOTFS_CHECK_PATH: ${{ matrix.probe_path }}
93+
INTEGRATION_VM_CHECK_COMMAND: ${{ matrix.probe_command }}
94+
INTEGRATION_VM_CHECK_EXPECT: ${{ matrix.probe_expect }}
5995
run: bun run test:integration
6096

6197
e2e-smoke:
@@ -80,6 +116,9 @@ jobs:
80116
sudo apt-get update
81117
sudo apt-get install -y qemu-system-x86 e2fsprogs
82118
119+
- name: Prime Gondolin guest assets
120+
run: bun --eval 'import { ensureGuestAssets } from "@earendil-works/gondolin"; await ensureGuestAssets();'
121+
83122
- name: Run end-to-end smoke test
84123
env:
85124
PLATFORM: linux/amd64

README.md

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# docker2vm
22

3-
`docker2vm` converts OCI container images (or Dockerfiles via BuildKit) into VM-compatible outputs. Today, the runtime materialization target is Gondolin.
3+
`docker2vm` converts OCI container images (or Dockerfiles via BuildKit) into VM-compatible outputs. Today, the runtime materialization target is [Gondolin](https://github.com/earendil-works/gondolin).
44

5-
It follows an OCI-first flow inspired by "Docker without Docker":
5+
It follows an OCI-first flow inspired by ["Docker without Docker"](https://fly.io/blog/docker-without-docker/):
66

77
- resolve/pull an OCI image
88
- apply layers to a root filesystem
@@ -16,6 +16,7 @@ Docker containers share the host kernel. Gondolin runs workloads inside a VM, so
1616

1717
## Current features
1818

19+
- pinned Gondolin runtime dependency (`@earendil-works/gondolin@0.2.1`) for guest-asset retrieval
1920
- `oci2gondolin` core converter
2021
- input: `--image`, `--oci-layout`, `--oci-tar` (exactly one)
2122
- platform: `linux/amd64`, `linux/arm64`
@@ -36,28 +37,23 @@ Docker containers share the host kernel. Gondolin runs workloads inside a VM, so
3637

3738
## Requirements
3839

39-
- Bun >= 1.2
40-
- `e2fsprogs` (`mke2fs`, `debugfs`)
41-
- QEMU (for runtime smoke checks via `gondolin exec`)
42-
- Docker (only required for `dockerfile2gondolin`)
40+
- Bun >= 1.2https://bun.com/
41+
- `e2fsprogs` (`mke2fs`, `debugfs`)https://e2fsprogs.sourceforge.net/
42+
- QEMU (for runtime smoke checks) — https://www.qemu.org/download/
43+
- Docker (only required for `dockerfile2gondolin`)https://docs.docker.com/get-docker/
4344

44-
macOS helpers:
45+
`docker2vm` uses `@earendil-works/gondolin@0.2.1` as a runtime dependency and resolves/downloads guest assets automatically during conversion.
4546

46-
```bash
47-
brew install e2fsprogs qemu
48-
```
47+
If you also want to run generated assets with `gondolin exec`, install the Gondolin CLI:
48+
- CLI docs: https://earendil-works.github.io/gondolin/cli/
49+
- Package: https://www.npmjs.com/package/@earendil-works/gondolin
4950

50-
Ubuntu helpers:
51-
52-
```bash
53-
sudo apt-get install -y e2fsprogs qemu-system-x86
54-
```
51+
> On macOS, `docker2vm` checks common Homebrew `e2fsprogs` locations automatically; updating `PATH` is usually optional.
5552
56-
## Install
53+
## Platform setup guides
5754

58-
```bash
59-
bun install
60-
```
55+
- [macOS guide](./docs/macos.md)
56+
- [Linux guide](./docs/linux.md)
6157

6258
## Quickstart
6359

@@ -75,6 +71,32 @@ bun run build
7571
bun run test:integration
7672
```
7773

74+
The CI integration matrix currently validates:
75+
76+
- `alpine:3.20`
77+
- `debian:bookworm-slim`
78+
- `ubuntu:24.04`
79+
- `fedora:41`
80+
- `archlinux:latest`
81+
82+
For each distro row, tests run a distro-specific probe command (for example `/etc/debian_version`, `/etc/fedora-release`, etc.), assert that probe does **not** match on the base Gondolin guest image, and verify `/bin/busybox` executes inside the converted image.
83+
84+
### Choosing the build platform (`--platform`)
85+
86+
`--platform` selects which OCI image variant to convert, and should match the architecture you plan to run in Gondolin. This applies to both `oci2gondolin` and `dockerfile2gondolin`.
87+
88+
- Apple Silicon / arm64 Linux hosts: `linux/arm64`
89+
- Intel / amd64 hosts: `linux/amd64`
90+
- If omitted, both commands default from host arch (`x64 -> linux/amd64`, `arm64 -> linux/arm64`).
91+
- You can always override manually with `--platform linux/amd64` or `--platform linux/arm64`.
92+
93+
For helper scripts:
94+
95+
- `e2e:smoke` uses `PLATFORM`
96+
- integration tests use `INTEGRATION_PLATFORM`
97+
98+
Cross-arch builds are possible at image-selection time, but for reliable runtime execution you should use a platform that matches the runtime guest architecture.
99+
78100
### 2) Convert image -> assets
79101

80102
```bash
@@ -88,7 +110,7 @@ bun run oci2gondolin -- \
88110
### 3) Run with Gondolin
89111

90112
```bash
91-
GONDOLIN_GUEST_DIR=./out/busybox-assets bunx gondolin exec -- /bin/busybox echo hello
113+
GONDOLIN_GUEST_DIR=./out/busybox-assets gondolin exec -- /bin/busybox echo hello
92114
```
93115

94116
## Dockerfile flow
@@ -113,7 +135,7 @@ bun run dockerfile2gondolin -- \
113135
Then run:
114136

115137
```bash
116-
GONDOLIN_GUEST_DIR=./out/demo-assets bunx gondolin exec -- /usr/games/cowsay "hello"
138+
GONDOLIN_GUEST_DIR=./out/demo-assets gondolin exec -- /usr/games/cowsay "hello"
117139
```
118140

119141
## End-to-end smoke test
@@ -176,4 +198,5 @@ dockerfile2gondolin --file PATH --context PATH --out PATH [options]
176198
## Repo notes
177199

178200
- This repo is standalone; Gondolin core is not modified.
201+
- Gondolin upstream repository: https://github.com/earendil-works/gondolin
179202
- `out/` is generated output and ignored by git.

bun.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/linux.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Linux setup guide
2+
3+
This guide is for running `docker2vm` on Linux hosts.
4+
5+
`docker2vm` includes a pinned Gondolin runtime dependency (`@earendil-works/gondolin@0.2.1`) to resolve guest assets during conversion.
6+
7+
## 1) Install required tools
8+
9+
Install tools using their official docs/download pages:
10+
11+
- Bun: https://bun.com/
12+
- QEMU: https://www.qemu.org/download/
13+
- e2fsprogs: https://e2fsprogs.sourceforge.net/
14+
15+
If you want Dockerfile conversion (`dockerfile2gondolin`), also install Docker + Buildx:
16+
17+
- Docker: https://docs.docker.com/get-docker/
18+
- Buildx: https://docs.docker.com/build/buildx/install/
19+
20+
## 2) Optional: install Gondolin CLI (for running generated assets)
21+
22+
`docker2vm` is tested with `@earendil-works/gondolin@0.2.1` and can fetch guest assets automatically during conversion.
23+
24+
Use Gondolin CLI install docs:
25+
26+
- https://earendil-works.github.io/gondolin/cli/
27+
- Package page: https://www.npmjs.com/package/@earendil-works/gondolin
28+
29+
## 3) Verify toolchain
30+
31+
```bash
32+
bun --version
33+
qemu-system-x86_64 --version
34+
mke2fs -V
35+
debugfs -V
36+
gondolin --help >/dev/null
37+
```
38+
39+
## 4) Validate from source checkout
40+
41+
```bash
42+
bun run test
43+
bun run typecheck
44+
bun run build
45+
```
46+
47+
## 5) Choose the build platform
48+
49+
Use a platform that matches the architecture you will run in Gondolin.
50+
51+
- `uname -m` => `x86_64` or `amd64`: use `linux/amd64`
52+
- `uname -m` => `aarch64` or `arm64`: use `linux/arm64`
53+
54+
`oci2gondolin` defaults automatically from host arch if `--platform` is omitted, but passing it explicitly is recommended.
55+
56+
Example:
57+
58+
```bash
59+
bun run oci2gondolin -- \
60+
--image busybox:latest \
61+
--platform linux/amd64 \
62+
--mode assets \
63+
--out ./out/busybox-assets
64+
```
65+
66+
## 6) Run integration + smoke checks
67+
68+
amd64 host:
69+
70+
```bash
71+
INTEGRATION_PLATFORM=linux/amd64 bun run test:integration
72+
PLATFORM=linux/amd64 bun run e2e:smoke
73+
```
74+
75+
arm64 host:
76+
77+
```bash
78+
INTEGRATION_PLATFORM=linux/arm64 bun run test:integration
79+
PLATFORM=linux/arm64 bun run e2e:smoke
80+
```
81+
82+
## Notes on virtualization performance
83+
84+
- If `/dev/kvm` is available, QEMU can use hardware acceleration.
85+
- If `/dev/kvm` is unavailable (common in CI), the project falls back to TCG emulation (slower but functional).
86+
87+
## Troubleshooting
88+
89+
### `sandbox_stopped` / VM exits quickly
90+
91+
Confirm QEMU is installed and that you are using a platform that matches your host and assets.
92+
93+
### `mke2fs` or `debugfs` missing
94+
95+
Reinstall `e2fsprogs` and verify the commands are available in your shell.

docs/macos.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# macOS setup guide
2+
3+
This guide is for running `docker2vm` on macOS (Apple Silicon or Intel).
4+
5+
`docker2vm` includes a pinned Gondolin runtime dependency (`@earendil-works/gondolin@0.2.1`) to resolve guest assets during conversion.
6+
7+
## 1) Install required tools
8+
9+
Install tools using their official docs/download pages:
10+
11+
- Bun: https://bun.com/
12+
- QEMU: https://www.qemu.org/download/
13+
- e2fsprogs: https://e2fsprogs.sourceforge.net/
14+
15+
If you want Dockerfile conversion (`dockerfile2gondolin`), also install Docker Desktop:
16+
- https://docs.docker.com/desktop/setup/install/mac-install/
17+
18+
## 2) Optional: add `e2fsprogs` binaries to `PATH`
19+
20+
With Homebrew, `e2fsprogs` is often keg-only. `docker2vm` checks common Homebrew locations automatically, so a PATH change is usually **not required** for normal usage.
21+
22+
If you want to run `mke2fs` / `debugfs` manually in your shell:
23+
24+
```bash
25+
export PATH="$(brew --prefix e2fsprogs)/sbin:$PATH"
26+
```
27+
28+
To persist it, add that `export PATH=...` line to your shell profile (`~/.zshrc`, `~/.bashrc`, `~/.profile`, etc.).
29+
30+
## 3) Optional: install Gondolin CLI (for running generated assets)
31+
32+
`docker2vm` is tested with `@earendil-works/gondolin@0.2.1` and can fetch guest assets automatically during conversion.
33+
34+
Gondolin CLI docs:
35+
- https://earendil-works.github.io/gondolin/cli/
36+
37+
Package page:
38+
- https://www.npmjs.com/package/@earendil-works/gondolin
39+
40+
## 4) Verify toolchain
41+
42+
```bash
43+
bun --version
44+
qemu-system-aarch64 --version || qemu-system-x86_64 --version
45+
"$(brew --prefix e2fsprogs)/sbin/mke2fs" -V
46+
"$(brew --prefix e2fsprogs)/sbin/debugfs" -V
47+
gondolin --help >/dev/null
48+
```
49+
50+
## 5) Validate from source checkout
51+
52+
```bash
53+
bun run test
54+
bun run typecheck
55+
bun run build
56+
```
57+
58+
## 6) Choose the build platform
59+
60+
Use a platform that matches the architecture you will run in Gondolin.
61+
62+
- Apple Silicon (`uname -m` => `arm64`): use `linux/arm64`
63+
- Intel Mac (`uname -m` => `x86_64`): use `linux/amd64`
64+
65+
`oci2gondolin` defaults automatically from host arch if `--platform` is omitted, but passing it explicitly is recommended.
66+
67+
Example:
68+
69+
```bash
70+
bun run oci2gondolin -- \
71+
--image busybox:latest \
72+
--platform linux/arm64 \
73+
--mode assets \
74+
--out ./out/busybox-assets
75+
```
76+
77+
## 7) Run integration + smoke checks
78+
79+
Apple Silicon:
80+
81+
```bash
82+
INTEGRATION_PLATFORM=linux/arm64 bun run test:integration
83+
PLATFORM=linux/arm64 bun run e2e:smoke
84+
```
85+
86+
Intel Mac:
87+
88+
```bash
89+
INTEGRATION_PLATFORM=linux/amd64 bun run test:integration
90+
PLATFORM=linux/amd64 bun run e2e:smoke
91+
```
92+
93+
## Troubleshooting
94+
95+
### `mke2fs` / `debugfs` not found
96+
97+
`docker2vm` should find common Homebrew locations automatically. If your install uses a custom prefix, either add it to `PATH` or point `GONDOLIN_GUEST_DIR` to prepared assets and verify `e2fsprogs` binaries are installed.
98+
99+
### Case-sensitive filename conflicts during conversion
100+
101+
Some images include paths that conflict on case-insensitive filesystems.
102+
103+
Use a case-sensitive APFS location for temporary work/output (for example, a case-sensitive volume) and retry.

0 commit comments

Comments
 (0)