Skip to content

ossein-docker: a docker-shaped front for build, run, pull, stop - #10

Merged
apostasie merged 2 commits into
mainfrom
claudio/20260907-ossein-docker
Sep 14, 2026
Merged

ossein-docker: a docker-shaped front for build, run, pull, stop#10
apostasie merged 2 commits into
mainfrom
claudio/20260907-ossein-docker

Conversation

@closer-claudio

@closer-claudio closer-claudio commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

cmd/ossein-docker: a docker-shaped front for the docker invocations farcloser projects actually make — build, run, pull, stop, version — with the flags they actually pass (surveyed: forkcloser/curl's build-posix.sh, the bench scripts, the website copy). Anything else is refused loudly (unknown flag/subcommand is an error, never a silent no-op). Meant to be installed as docker on the hermetic PATH (aqua packaging follows in limen once a release carries both binaries). Where docker and ossein disagree, docker wins.

What it does

  • run / pull / stop: execve into the sibling ossein (flags already docker-shaped). Translates docker's --cpus 1.5 (rounded up), --memory in docker's grammar (8g, 8gb, 512MiB, 1.5g), --network none; keeps -it, commas in -e, puts -- before the image. A run that sizes nothing gets the whole host (every CPU, all memory — backed lazily), as a docker container does; ossein run's own 2 vCPU / 4 GiB do not apply through the front. stop requires an id, as docker requires a container: a bare stop would have stopped every builder on the machine, which docker never does.
  • build / buildx build: the buildkit client library (pinned v0.32.0, same as the daemon image), not buildctl. Starts or reuses this directory's buildkit microVM via ossein buildkit --detach, sized like a daemon (the whole host); solves with dockerfile.v0 (context + Dockerfile as local mounts; -t -f --build-arg --platform --target --no-cache --pull --progress -q); exports an OCI layout and imports every -t tag into ossein's image cache, flattened right away — so docker run <tag> resolves offline. -q without -t is refused: docker would print an image ID, but an untagged build leaves ossein nothing runnable to name, and printing nothing would be the silent divergence this front exists to refuse.
  • Registry credentials for FROM: a Credentials-only session attachable backed by go-containerregistry's default keychain (docker login). Not buildkit's authprovider, which would have pulled docker/cli and an MPL-2.0 HTTP helper (rejected by the license lane).

ossein-side changes (first commit)

  • ossein buildkit --detach is now idempotent per cache: each instance records buildkit.json (cache dir + socket) in its state dir; a second detach for a cache a live instance serves reprints its BUILDKIT_HOST and exits 0 instead of failing on the lock. A booting instance is waited for, never killed. Foreground and explicit --sock unchanged.
  • --cpus 0 / --memory 0 on run and buildkit mean the whole host: the host's logical CPU count and physical memory, each capped at what Virtualization.framework allows for one guest (vm.HostMaxCPUs, vm.HostMaxMemoryMiB). The framework's own maximum is not the host's (64 CPUs on an 18-core machine), hence the cap on the host's count. 0 is docker's spelling of "no limit" and is what the front passes; ossein's defaults are untouched.
  • image.Import: records a locally built image under a tag exactly like a registry resolution; marked local so a reclaimed blob says "rebuild" rather than re-fetching a digest no registry has.
  • Drive-by fix: kong splits repeated flag values on commas by default, so ossein run -e LIST=a,b arrived as two variables. sep:"none" on -e, --env-file, -v.
  • What both binaries must agree on lives in internal/cli: the logger, the --log-level vocabulary, the exit convention, and cli.WholeHost — the one definition of "0 = the whole host" both sides use. One record builder, newResolution, serves Resolve and Import; an imported tag now carries the same manifest chain as a pulled one, and a record Resolve fails to write is logged, not swallowed.

Release / lint

Verification

  • just lint and just test green locally. Unit tests cover argv translation (including the whole-host default and docker's memory grammar), frontend attrs, tag normalization, OCI-layout selection (attestations skipped, platform matched, nested-index errors not masked), Import → offline Resolve → cached rootfs, instance discovery, the -q-without--t and bare-stop refusals.
  • Verified live on an 18-core / 64 GiB Mac with build/docker symlinked to ossein-docker:
    • docker build --build-arg GREETING=hi -t smoke:dev . → alpine pulled through the builder, RUN executed, tag imported; docker run --rm smoke:dev printed the build-arg'd file offline.
    • unsized docker run: guest saw nproc=18, 64 GiB; --cpus 1.5 --memory 1gb: nproc=2, 1 GiB.
    • -e LIST=a,b arrived intact; docker build -q . refused (125) with the message; -q -t printed the digest only; buildx build works; second ossein buildkit --detach said reusing; bare docker stop refused; docker stop <id> stopped only that one.
  • First consumer: forkcloser/curl's build-posix.sh (Forkcloser session), adapted to docker run … on macOS; its linux-arm64/amd64 legs will be run against this branch's just build output.

closer-claudio and others added 2 commits September 13, 2026 22:29
Every buildkit instance now records what it serves (buildkit.json in its
state dir: the cache directory it holds and its host socket), and
`ossein buildkit --detach` for a cache that a live instance already serves
reprints that instance's BUILDKIT_HOST and exits 0 instead of failing on
the lock. A still-booting instance is waited for, never killed: it is not
ours. The foreground path and an explicit --sock are unchanged.

image.Import records a locally built image (an OCI layout produced by a
build) under a tag, exactly as a registry resolution would be, so a later
`ossein run <tag>` resolves offline under the default pull policy. Such a
resolution is marked local: when its rootfs blob is reclaimed, the error
asks for a rebuild instead of re-fetching a digest no registry has. One
builder, newResolution, now produces the record for Resolve and Import
alike — digest and config derived from the image's own bytes, the
manifest chain kept — so an imported tag carries the same record shape as
a pulled one, and Resolve's Image is built from the record it just wrote
rather than from a second reading of the same image. A record Resolve
fails to write is logged, not swallowed; Import's is checked, as before.

`--cpus 0` and `--memory 0` on run and buildkit now mean the whole host:
every logical CPU and all physical memory, each capped at what
Virtualization.framework allows for one guest (pkg/vm HostMaxCPUs and
HostMaxMemoryMiB). 0 is docker's own spelling of "no limit", and it is
what the docker-shaped front passes when a script sizes nothing — a
container under a daemon gets the machine, and so does one under the
front. The framework's maximum is not the host's (64 CPUs on an 18-core
machine), which is why the cap is the host's count and not the
framework's. ossein's own defaults (2 vCPU / 4 GiB, 4 / 8 GiB for
buildkit) are untouched; 0 was never a usable value before.

Drive-by: kong splits repeated flag values on commas by default, so
`-e LIST=a,b` arrived as two variables. sep:"none" on -e, --env-file, -v.

What the two binaries must agree on moves to internal/cli: the process
logger, the --log-level vocabulary, the exit-status convention, and the
spelling of "the whole host" (cli.WholeHost) — named for what it holds,
the conventions of the product's command-line binaries, not for who
calls it. kong's `var cli CLI` in each main becomes `root` so the package
is never shadowed at the one place it is used.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: closer-claudio <claudio@farcloser.world>
cmd/ossein-docker implements the docker invocations farcloser projects
actually make, with the flags they actually pass (surveyed: build-curl's
build-posix.sh, the bench scripts, the website copy), and refuses
everything else loudly: an unknown flag or subcommand is a parse error,
never a silent no-op. Where docker and ossein disagree, docker wins.

- run, pull, stop: exec the sibling ossein binary (its flags are already
  docker-shaped); docker's resource syntax is translated — --cpus 1.5
  rounds up, --memory takes docker's grammar (8g, 8gb, 512MiB, 1.5g) —
  and --network none becomes --no-network. -it, commas in -e, -- before
  the image. A run that sizes nothing is sized like a docker container:
  the whole host (cli.WholeHost on both knobs), not ossein's defaults.
  stop requires an id, as docker requires a container: a bare stop would
  stop every builder on the machine, which docker never does.
- build (and buildx build): the buildkit client library, not buildctl.
  Starts or reuses this directory's buildkit microVM via `ossein buildkit
  --detach`, sized like a daemon (the whole host); solves with the
  dockerfile.v0 frontend (context and Dockerfile as local mounts; -t -f
  --build-arg --platform --target --no-cache --pull --progress -q);
  exports an OCI layout and imports every -t tag into ossein's image
  cache through image.Import, flattened right away — `docker run <tag>`
  then resolves offline. -q without -t is refused: docker would print an
  image ID, but an untagged build leaves ossein nothing runnable to name,
  and printing nothing would be exactly the silent divergence this front
  exists to refuse.
- registry credentials for FROM lines: a Credentials-only session
  attachable backed by go-containerregistry's default keychain (docker
  login), instead of buildkit's authprovider, which would have pulled
  docker/cli and an MPL-2.0 HTTP helper into the binary.

Release: a second goreleaser build in the same archive (no entitlement:
the front never touches Virtualization itself). go-licenses cannot locate
the Apache-2.0 license of the two in-toto modules the client pulls
(module-layout false positive, google/go-licenses#186): ignored in the
Justfile with the reason. go.mod carries the three direct dependencies,
tidied on main.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: closer-claudio <claudio@farcloser.world>
@closer-claudio
closer-claudio force-pushed the claudio/20260907-ossein-docker branch from 7484428 to 152652f Compare September 14, 2026 05:30
@apostasie
apostasie merged commit 4df70f7 into main Sep 14, 2026
11 checks passed
@apostasie
apostasie deleted the claudio/20260907-ossein-docker branch September 14, 2026 05:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants