model,cli,docs: medium-effort polish for v0.1.0
* model.ParseSize / FormatSizeBytes: pinned with table tests in
internal/model/types_test.go (TestParseSize 22 cases,
TestFormatSizeBytes 11 cases, TestParseSizeFormatRoundTrip 7
boundaries). Fixed the long-suffix regression: "4GiB", "512MiB",
"4KiB" now parse correctly (parser strips trailing IB before
inspecting the unit byte). Pinned current behaviour for
no-suffix input ("1024" treated as MiB) and FormatSizeBytes(0).
commands_image.go --size flag-help updated to show 4GiB now
that the parser accepts it.
* vm ports --json: matches the JSON-vs-table inconsistency between
vm stats (always JSON) and vm ports (always table). --json on
vm ports flips to the same printJSON path as vm stats. Default
table output unchanged. Other vm subcommands (show, stats,
logs, health, ping) didn't fit the identical pattern; left
alone.
* docs/oci-import.md architecture section moved to a new
docs/oci-import-internals.md (precedent: internal/daemon/
ARCHITECTURE.md). User-facing oci-import.md keeps a one-line
pointer for advanced reading.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4d8dca6b72
commit
d0997fd3b5
6 changed files with 196 additions and 42 deletions
44
docs/oci-import-internals.md
Normal file
44
docs/oci-import-internals.md
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# OCI import — internals
|
||||
|
||||
> **Advanced reading.** This document describes implementation details of the
|
||||
> OCI import pipeline. It is not needed for day-to-day use of
|
||||
> `banger image pull`. User-facing documentation is in
|
||||
> [`docs/oci-import.md`](oci-import.md).
|
||||
|
||||
## Architecture
|
||||
|
||||
`internal/imagepull/` owns the mechanics:
|
||||
|
||||
- **`Pull`** wraps `go-containerregistry`'s `remote.Image` with the
|
||||
`linux/amd64` platform pinned. Layer blobs cache under
|
||||
`~/.cache/banger/oci/blobs/` and populate lazily during flatten.
|
||||
- **`Flatten`** replays layers oldest-first into a staging directory,
|
||||
applies whiteouts, rejects unsafe paths plus filenames that banger's
|
||||
debugfs ownership fixup cannot encode safely. Returns a `Metadata`
|
||||
map of per-file uid/gid/mode from tar headers.
|
||||
- **`BuildExt4`** runs `mkfs.ext4 -F -d <staging> -E root_owner=0:0`
|
||||
at the size of the pre-truncated file — no mount, no sudo, no
|
||||
loopback. Requires `e2fsprogs ≥ 1.43`.
|
||||
- **`ApplyOwnership`** streams a batched `set_inode_field` script to
|
||||
`debugfs -w` to rewrite per-file uid/gid/mode to the captured tar-
|
||||
header values.
|
||||
- **`InjectGuestAgents`** uses the same `debugfs` scripting to drop
|
||||
banger's guest assets into the ext4 with root ownership:
|
||||
vsock agent binary, network bootstrap + unit, first-boot script +
|
||||
unit, `multi-user.target.wants` symlinks, vsock modules-load
|
||||
config, `/var/lib/banger/first-boot-pending` marker.
|
||||
|
||||
`internal/daemon/images_pull.go` orchestrates `pullFromOCI`:
|
||||
|
||||
1. Parse + validate the OCI ref, derive a default name when `--name`
|
||||
is omitted (`debian-bookworm` from
|
||||
`docker.io/library/debian:bookworm`).
|
||||
2. Resolve kernel info via `resolveKernelInputs` (auto-pulls from
|
||||
`kernelcat` if `--kernel-ref` names a catalog entry that isn't
|
||||
yet local).
|
||||
3. Stage at `<ImagesDir>/<id>.staging`; extract layers to a temp
|
||||
tree under `$TMPDIR`.
|
||||
4. `BuildExt4` → `ApplyOwnership` → `InjectGuestAgents`.
|
||||
5. `imagemgr.StageBootArtifacts` stages the kernel triple alongside.
|
||||
6. Atomic `os.Rename` publishes the artifact dir.
|
||||
7. Persist a `model.Image{Managed: true, …}` record.
|
||||
|
|
@ -61,41 +61,7 @@ banger image pull ghcr.io/myorg/devimg:v2 --kernel-ref generic-6.12
|
|||
|
||||
## Architecture
|
||||
|
||||
`internal/imagepull/` owns the mechanics:
|
||||
|
||||
- **`Pull`** wraps `go-containerregistry`'s `remote.Image` with the
|
||||
`linux/amd64` platform pinned. Layer blobs cache under
|
||||
`~/.cache/banger/oci/blobs/` and populate lazily during flatten.
|
||||
- **`Flatten`** replays layers oldest-first into a staging directory,
|
||||
applies whiteouts, rejects unsafe paths plus filenames that banger's
|
||||
debugfs ownership fixup cannot encode safely. Returns a `Metadata`
|
||||
map of per-file uid/gid/mode from tar headers.
|
||||
- **`BuildExt4`** runs `mkfs.ext4 -F -d <staging> -E root_owner=0:0`
|
||||
at the size of the pre-truncated file — no mount, no sudo, no
|
||||
loopback. Requires `e2fsprogs ≥ 1.43`.
|
||||
- **`ApplyOwnership`** streams a batched `set_inode_field` script to
|
||||
`debugfs -w` to rewrite per-file uid/gid/mode to the captured tar-
|
||||
header values.
|
||||
- **`InjectGuestAgents`** uses the same `debugfs` scripting to drop
|
||||
banger's guest assets into the ext4 with root ownership:
|
||||
vsock agent binary, network bootstrap + unit, first-boot script +
|
||||
unit, `multi-user.target.wants` symlinks, vsock modules-load
|
||||
config, `/var/lib/banger/first-boot-pending` marker.
|
||||
|
||||
`internal/daemon/images_pull.go` orchestrates `pullFromOCI`:
|
||||
|
||||
1. Parse + validate the OCI ref, derive a default name when `--name`
|
||||
is omitted (`debian-bookworm` from
|
||||
`docker.io/library/debian:bookworm`).
|
||||
2. Resolve kernel info via `resolveKernelInputs` (auto-pulls from
|
||||
`kernelcat` if `--kernel-ref` names a catalog entry that isn't
|
||||
yet local).
|
||||
3. Stage at `<ImagesDir>/<id>.staging`; extract layers to a temp
|
||||
tree under `$TMPDIR`.
|
||||
4. `BuildExt4` → `ApplyOwnership` → `InjectGuestAgents`.
|
||||
5. `imagemgr.StageBootArtifacts` stages the kernel triple alongside.
|
||||
6. Atomic `os.Rename` publishes the artifact dir.
|
||||
7. Persist a `model.Image{Managed: true, …}` record.
|
||||
> Implementation details live in [`docs/oci-import-internals.md`](oci-import-internals.md).
|
||||
|
||||
## Guest-side boot sequence
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue