Skip to content

plugin-oci

Placement compiled-in (in-process)
Source github.com/opencharly/plugin-oci/candy/plugin-oci
Version 2026.194.1200
Candy plugin-oci

This plugin is listed in charly/charly.yml’s compiled_plugins:, so its providers are compiled into the charly binary and register in-process.

The reserved words this plugin serves:

  • oci — verb class

OUT-OF-TREE charly plugin serving the oci VERB (verb:oci) — the OCI IMAGE ENGINE externalized from charly core (the P14a cutover). It OWNS the go-containerregistry stack: the layer-MERGE engine (merge.go: planMerge → executeMerge → mergeLayers with full whiteout handling, plus the podman/skopeo daemon save/load) and the remote-image adopt-user PROBE (inspect_user.go: /etc/passwd lookup at a configured uid). Both run HOST-SIDE and exec podman/skopeo themselves — the verb:libvirt precedent — so go-containerregistry lives HERE, and charly/go.mod links it NOWHERE.

It is DUAL-PLACEMENT: its importable provider package (NewProvider/NewMeta, serving verb:oci) is COMPILED INTO charly when listed in charly.yml compiled_plugins: (the DEFAULT — the merge + adopt-user probes sit on the core BUILD PATH and must resolve project-lessly and reliably, mirroring the compiled-in verb:libvirt / verb:tunnel / verb:enc profile; registered in-process via registerCompiledPlugin), and the SAME provider is served OUT-OF-PROCESS over go-plugin gRPC by the cmd/serve shim (host-built + connected via LocalTransport) when it is not. Placement is invisible above the provider registry.

verb:oci is a pure INTERNAL RPC verb — NEVER authored as an oci: check step (it declares no structured InputDef, and it ships its OWN self-contained CUE schema, schema/oci.cue, served over Describe — there is NO schema-less plugin). It is keyed by an OciOp env discriminator (mirroring the vm plugin’s VmOp): oci_op=merge decodes a spec.MergeRequest and returns a spec.MergeReply (layer counts + progress Notes the host prints; a per-merge failure rides Reply.Error), oci_op=inspect-user decodes a spec.ImageUserInput and returns a spec.UserInfo, and oci_op=cache-push / cache-pull move a whole named spec/cache.ArtifactStore (already a standard OCI Image Layout) to and from an OCI registry — the registry transport for the OCI-manifest-native cache (opencharly/spec#148): push = layout.ImageIndex → remote.WriteIndex, pull = remote.Index → layout.Write, auth via authn.DefaultKeychain. charly box merge (candy/plugin-box’s mergeOneBox, P14) and candy/plugin-build’s drive both reach it DIRECTLY via Executor.InvokeProvider (verb:oci) — the F10 peer-dispatch leg; the ONE remaining core consumer is generate.go’s adopt-user resolution, reached via the oci_plugin.go shim (still core-side, K1-gated — see that file’s own migration-inventory note). The MERGE engine’s byte-identical relocation is locked by the candy’s TestMergeEngineGoldenParity (the merged-layer DiffID golden); the cache transport’s lossless round-trip by TestCacheTransportDeterministic and its live push/pull by TestCachePushPullLiveRoundTrip (LIVE_REGISTRY-gated).

The CUE schema below is the authoritative grammar for this plugin’s input. It is the same single source that generates the plugin’s Go parameter types and answers the runtime Describe RPC, so this page cannot disagree with either.

// plugin-oci's OWN self-contained CUE schema — the SINGLE SOURCE for this plugin's
// served declaration surface (there is no schema-less plugin: every plugin ships a
// non-empty schema over Describe).
//
// SELF-CONTAINED and PACKAGE-LESS: it references no base def and carries no package
// clause, so it compiles STANDALONE — the property the SDK's serve-side compile needs
// and the property that lets the host splice `base ++ plugin` at the load gate
// (registerPluginUnitSchema); a self-contained schema that will not splice is a LOUD
// load failure.
//
// NO GO CONSUMER: the plugin declares no typed `plugin_input` (its authored input is
// its pass-through CLI grammar), so this schema generates NO `params` package and has
// NO `cue exp gengotypes` artifact — it is the SERVED documentation/config surface,
// not a code-generation source.
//
// It DOCUMENTS the internal `verb: oci` op vocabulary — `merge` / `inspect-user` / `cache-push` / `cache-pull` — keyed by the `oci_op` env discriminator. The host's merge / inspect-user / cache consumers reach the verb directly.
#OciPlugin: {
// The verb word the plugin serves.
verb: "oci"
// What the verb does, in one line (the public-docs surface).
contract: string & !=""
// The internal ops the verb dispatches, keyed by the `oci_op` env discriminator.
ops: ["merge", "inspect-user", "cache-push", "cache-pull"]
}

See also the candy reference for this candy’s install surface.