Commits
eio moves to a dev commit: it adds portable Net socket options, so a
consumer can set TCP_NODELAY and friends without linking eio.unix. Every package
that depends on eio carries the pin, since opam resolves pin-depends per package
and not from the root.
The solo5 and unikraft cross-toolchains move to wip-macos+runtime_events+lto,
one branch carrying macOS cross-build support, an in-process runtime_events ring
and a flambda compiler that defaults to link-time DCE. The unikernel arms link
with -use-lto, so the compiler has to carry those patches.
These packages are published only to the opam overlay, not the public
opam-repository. Without the repo-add line a reader who runs opam install
gets nothing and has to hunt down the overlay URL by hand.
no_privileged (the default proxy policy) blocked a pod/container only when
the privileged flag was set. A CreateContainer with privileged=false but a
writable host mount, a host or CDI device, a host namespace, or added
capabilities was forwarded unchanged -- each is a host-breakout surface as
broad as privileged. Extend the container hook to also deny those (a
read-only host mount still passes, so the kubelet's configmap/secret/token
mounts keep working), and deny host namespaces on the pod-sandbox hook too.
Across the packages monopam lint flagged: declare the libraries each
package actually uses (test-only ones scoped with-test, dev tools and
benches scoped with-dev-setup), drop the opam deps and dune (libraries)
entries nothing references, declare pin-depends for the wire and zarith
git pins so a standalone opam install can resolve them, and point the
five stale dune-project source URLs at the names sources.toml already
uses. The generated .opam files are regenerated to match.
Where monopam lint and merlint's project rules disagree, merlint wins:
[protocol] packages keep probe linked (E932), CSV-trace interop tests
keep csv (E825), and dev-scope deps carry the right filter (E943).
The few dead-lib reports that remain are monopam lint blind spots, not
real dead deps: usage reached only through an mdx README block (slirp),
through copy_files# (vz), or inside a library's own private modules
(builder), plus a tar gz dep kept live for a stub test still to write.
cri-api is I/O-free protobuf message types and gRPC method definitions
with no state machine, so the protocol tag (E946: a state machine over a
codec) was wrong. Tag it codec.binary.
Remove libraries that no module in the stanza directory
references (monopam lint dead-lib).
The cri synopsis read as the description of the whole repo in
llms.txt, and the README package table predated the cri-api split:
it labelled cri as the IO-free types (those are cri-api), omitted
cri-api, and referred to crict/crictd/crict-proxy binaries that are
now subcommands of the single cri binary.
Comment reflow and header reindent produced by the new ocamlformat;
no code changes.
Mirrors upstream k8s.io/cri-api: the IO-free types + gRPC service definitions
(module Cri, incl. the folded Cri.Runner) live in a package named cri-api, and
the all-in-one cri binary gets its own executable-only package named cri. The
library keeps (name cri) so the module stays Cri; only its public_name and opam
package change. cri-client/cri-server depend on cri-api; cri-server drops the
binary (cri-client/eio_main return to with-test for its tests). The binary's
entry module is main.ml with cmd_* helpers, public_name cri.
cri-runner was its own opam package but is I/O-free (deps: cri + fmt), like the
main cri types -- a separate package only paid off for a future real runtime
backend depending on just the interface, which doesn't exist. Fold it in:
lib/runner.ml is now the Cri.Runner module (BACKEND renamed to the idiomatic S),
the cri-runner package/opam are dropped (4 pkgs -> 3), and its test moves to
test/test_runner.ml. Consumers use Cri.Runner.S / Cri.Runner.Memory. Build, the
49-test suite (incl. the runner cases) and merlint all pass.
Add ocaml-cri, the gRPC/protobuf sibling of ocaml-docker: IO-free
protobuf message types and gRPC method definitions for the full
RuntimeService and ImageService (41 RPCs, ~180 messages), a runtime
BACKEND boundary with an in-memory simulator, an Eio server and the
cri binary, an Eio client, and a body-aware Server.Proxy gateway that
gates and rewrites RPCs by policy between a kubelet and an upstream
runtime. Built on nox-protobuf + nox-grpc + nox-grpc-eio; the spec is
cri-api v0.36.1.
The three CRI binaries (crictd/crict-proxy/crict) are merged into one `cri`
tool with subcommands (cri serve / cri proxy / cri version ...), mirroring
etco. Point the criclient interop at `cri serve` and `cri proxy`.
Mirror the etcd clientv3 interop for CRI: test/criclient drives our server with
k8s.io/cri-api (the kubelet's RuntimeService/ImageService client) as the oracle,
over the standard CRI unix socket. run.sh runs two phases:
1. cri-api client -> crictd (the in-memory fake server)
2. cri-api client -> crict-proxy (the transparent allow_all proxy) ->
crictd, or a real runtime via UPSTREAM=<sock> (e.g. containerd)
covering Version/Status, the pod+container lifecycle (run/create/start/status/
list/stop/remove) and the image lifecycle (pull/list/status/remove). Both phases
pass, proving the fake and the proxy are wire-conformant with the real client.
Gated behind CRI_LIVE=1 (dune @criclient alias), SKIPs without a Go toolchain --
the same shape as the existing critest interop.
eio moves to a dev commit: it adds portable Net socket options, so a
consumer can set TCP_NODELAY and friends without linking eio.unix. Every package
that depends on eio carries the pin, since opam resolves pin-depends per package
and not from the root.
The solo5 and unikraft cross-toolchains move to wip-macos+runtime_events+lto,
one branch carrying macOS cross-build support, an in-process runtime_events ring
and a flambda compiler that defaults to link-time DCE. The unikernel arms link
with -use-lto, so the compiler has to carry those patches.
no_privileged (the default proxy policy) blocked a pod/container only when
the privileged flag was set. A CreateContainer with privileged=false but a
writable host mount, a host or CDI device, a host namespace, or added
capabilities was forwarded unchanged -- each is a host-breakout surface as
broad as privileged. Extend the container hook to also deny those (a
read-only host mount still passes, so the kubelet's configmap/secret/token
mounts keep working), and deny host namespaces on the pod-sandbox hook too.
Across the packages monopam lint flagged: declare the libraries each
package actually uses (test-only ones scoped with-test, dev tools and
benches scoped with-dev-setup), drop the opam deps and dune (libraries)
entries nothing references, declare pin-depends for the wire and zarith
git pins so a standalone opam install can resolve them, and point the
five stale dune-project source URLs at the names sources.toml already
uses. The generated .opam files are regenerated to match.
Where monopam lint and merlint's project rules disagree, merlint wins:
[protocol] packages keep probe linked (E932), CSV-trace interop tests
keep csv (E825), and dev-scope deps carry the right filter (E943).
The few dead-lib reports that remain are monopam lint blind spots, not
real dead deps: usage reached only through an mdx README block (slirp),
through copy_files# (vz), or inside a library's own private modules
(builder), plus a tar gz dep kept live for a stub test still to write.
The cri synopsis read as the description of the whole repo in
llms.txt, and the README package table predated the cri-api split:
it labelled cri as the IO-free types (those are cri-api), omitted
cri-api, and referred to crict/crictd/crict-proxy binaries that are
now subcommands of the single cri binary.
Mirrors upstream k8s.io/cri-api: the IO-free types + gRPC service definitions
(module Cri, incl. the folded Cri.Runner) live in a package named cri-api, and
the all-in-one cri binary gets its own executable-only package named cri. The
library keeps (name cri) so the module stays Cri; only its public_name and opam
package change. cri-client/cri-server depend on cri-api; cri-server drops the
binary (cri-client/eio_main return to with-test for its tests). The binary's
entry module is main.ml with cmd_* helpers, public_name cri.
cri-runner was its own opam package but is I/O-free (deps: cri + fmt), like the
main cri types -- a separate package only paid off for a future real runtime
backend depending on just the interface, which doesn't exist. Fold it in:
lib/runner.ml is now the Cri.Runner module (BACKEND renamed to the idiomatic S),
the cri-runner package/opam are dropped (4 pkgs -> 3), and its test moves to
test/test_runner.ml. Consumers use Cri.Runner.S / Cri.Runner.Memory. Build, the
49-test suite (incl. the runner cases) and merlint all pass.
Add ocaml-cri, the gRPC/protobuf sibling of ocaml-docker: IO-free
protobuf message types and gRPC method definitions for the full
RuntimeService and ImageService (41 RPCs, ~180 messages), a runtime
BACKEND boundary with an in-memory simulator, an Eio server and the
cri binary, an Eio client, and a body-aware Server.Proxy gateway that
gates and rewrites RPCs by policy between a kubelet and an upstream
runtime. Built on nox-protobuf + nox-grpc + nox-grpc-eio; the spec is
cri-api v0.36.1.
Mirror the etcd clientv3 interop for CRI: test/criclient drives our server with
k8s.io/cri-api (the kubelet's RuntimeService/ImageService client) as the oracle,
over the standard CRI unix socket. run.sh runs two phases:
1. cri-api client -> crictd (the in-memory fake server)
2. cri-api client -> crict-proxy (the transparent allow_all proxy) ->
crictd, or a real runtime via UPSTREAM=<sock> (e.g. containerd)
covering Version/Status, the pod+container lifecycle (run/create/start/status/
list/stop/remove) and the image lifecycle (pull/list/status/remove). Both phases
pass, proving the fake and the proxy are wire-conformant with the real client.
Gated behind CRI_LIVE=1 (dune @criclient alias), SKIPs without a Go toolchain --
the same shape as the existing critest interop.