Skip to content

plugin-deploy-pod

Placement runtime (out-of-process over gRPC)
Source github.com/opencharly/plugin-deploy-pod/candy/plugin-deploy-pod
Candy plugin-deploy-pod

This plugin is not listed in charly/charly.yml’s compiled_plugins:. It is not part of the shipped binary: charly builds and loads it out-of-process over gRPC when a plan references one of its words (the coexist path).

The reserved words this plugin serves:

  • pod — deploy class

OUT-OF-TREE charly DEPLOY plugin serving the pod deploy SUBSTRATE — target: pod (the DEFAULT substrate: a deployment run as a container image via quadlet/podman). A standalone Go module (go.mod + main.go) served over go-plugin gRPC via the charly plugin SDK; charly’s loader host-builds the provider binary and connects it OUT-OF-PROCESS (LocalTransport). The host’s plugin-side deploy target Invokes it (OpExecute) with the deployment’s InstallPlan VIEWS + a venue descriptor and the host’s executor served on the broker. Unlike deploy:vm (whose plugin WALKS the plan inside the guest), pod bakes its install steps INTO the image at BUILD time: the host’s pod lifecycle hook (pod_deploy_lifecycle.go) drives the overlay container image build in PrepareVenue — but P11c DISSOLVED the render OUT of charly core INTO this candy: the host prep (hostBuildOverlay) returns the OverlayBuildReply envelope (ResolvedProject + Plans + base-image metadata + per-overlay-candy security + parent bind-mount volumes), and the candy imports sdk/deploykit+buildkit+kit DIRECTLY (IMPORT-PURITY, ZERO-ALIASES), constructs the deploykit.Generator itself (the shared NewRenderGeneratorFromProject helper — the SAME source candy/plugin-build uses, R3), renders the overlay Containerfile in its own code, and runs podman build + the deploy-name alias tag via its served host executor. Each per-step Containerfile fragment is rendered HOST-SIDE over the generic “step-emit” host-builder (deploykit.OCITarget.EmitStepOp → HostBuild(“step-emit”,“oci-emit-step”,…) → the host’s dispatchOCIStep, byte-identical to the former in-core emitStep) — so the render lives in the candy while each step fragment crosses the reverse channel. The bed runner / charly start configs + starts the container. So there is NO per-step venue walk for pod: this plugin’s Invoke does NOT call kit.WalkPlans — it returns an EMPTY DeployReply (pod teardown is charly remove + drop overlay images, owned by the host lifecycle hook’s PostTeardown). The pod-substrate sibling of candy/plugin-deploy-vm; the host’s pod lifecycle hook owns the container lifecycle (overlay build + config/start/remove + the charly update rebuild gate), this plugin serves the substrate word out-of-process. P11 (Ruling C): the pod config-WRITE also moved here — the OpConfigWrite Op renders the quadlet/.pod/sidecar/tunnel file CONTENTS (via the deploykit GenerateQuadlet/GeneratePodQuadlet/GenerateSidecarQuadlet/ GenerateTunnelUnit generators) and os.WriteFiles them at the host-resolved absolute paths + exact modes (0600/0600/0600/0644). charly config (host) resolves the QuadletConfig + computes the paths + provisions dirs/secrets + runs the systemctl/enc/seed side-effects, then connects this plugin on-demand (connectPluginByWordRef, like the credential/vm/kube host out-calls) and Invokes OpConfigWrite — so the WRITE is the plugin’s, byte-identical to the former in-core write phase.

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-deploy-pod'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 `deploy: pod` substrate word and its venue lifecycle.
#DeployPodPlugin: {
// The deploy substrate word this plugin serves.
deploy: "pod"
// The substrate owns a venue lifecycle (prepare-venue/start/stop/…).
lifecycle: true
// What the plugin does, in one line (the public-docs surface).
contract: string & !=""
}

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