plugin-preempt
| Placement | compiled-in (in-process) |
| Source | github.com/opencharly/plugin-preempt/candy/plugin-preempt |
| Version | 2026.183.0000 |
| Candy | plugin-preempt |
This plugin is listed in charly/charly.yml’s compiled_plugins:, so its providers are compiled into the charly binary and register in-process.
Providers
Section titled “Providers”The reserved words this plugin serves:
preempt— command classarbiter— verb class
What it does
Section titled “What it does”COMPILED-IN charly plugin owning the RESOURCE ARBITER (cutover C9) — the final core-externalization cutover. It serves TWO capabilities:
-
verb:arbiter — the exclusive/shared resource arbiter, the 1225-LOC coordination logic MOVED OUT of charly core (the former charly/preempt.go ResourceArbiter): acquire/release exclusive+shared leases, stop + restore preemptible holders, the crash-safe lease ledger (~/.local/share/charly/preemption/leases.yml), GPU-resource poisoning (device_lock-wedge containment), owner liveness, and the vfio<->nvidia driver-mode arbitration math (arbiter.go + arbiter_support.go). The arbiter reaches its HOST dependencies — the project config, the VM/pod lifecycle, the GPU driver flip — that it cannot hold across the module boundary over TWO generic reverse legs: gather/resources read the generic Executor.InvokeProvider(“build”,“project”) envelope (K1-unblock wave 1 — the former bespoke arbiter reverse-RPC channel
- its host handler are DELETED); the other 6 (running / stop[+wait] / start / switchMode / ensureCDI / gpuCDI) run over Executor.InvokeProvider (FLOOR-SLIM-proper Unit-8, holder_dispatch.go — a prior cutover). The former in-core PROXY (charly/preempt.go newResourceArbiter + acquire*/release* shims) is DELETED (K-wave 2 cone CONTESTED — zero production callers after the check-bed/start/vm/cmd/arbiter-bracket consumers all went peer-dispatch; the sole survivor is the op=“remove” release chain in charly/host_build_pod_lifecycle_dispatch.go, host-process CHARLY_PREEMPT_LEASE state a placement-agnostic plugin cannot own).
-
command:preempt — the operator
charly preempt status/restoreCLI. It OWNS the CLI grammar + the lease-table formatting and reaches its OWN peer capability verb:arbiter DIRECTLY via InvokeProvider over the in-proc reverse channel (no hidden__preempt-*forward, no in-core proxy hop). No ad-hoc podman/virsh (R4).
PLACEMENT — COMPILED-IN (listed in the embedded charly/charly.yml compiled_plugins:). The arbiter is on the deploy / vm-create / check-bed hot paths and needs the LOCAL lease ledger + the LOCAL project config, so in-proc is the right placement (like candy/plugin-gpu); the reverse channel is in-proc (no gRPC broker), the SAME dispatchBuild pattern. The cmd/serve binary backs the out-of-process placement.
The DRIVER-SWITCH (vfio<->nvidia rebind) that the arbiter’s switchMode seam drives now lives in candy/plugin-gpu (C9, 1B); the host receives the arbiter’s switchMode call and routes it there via the core gpu shims (a plugin->plugin edge through the host).
R10: the disposable check-preempt-arbiter-pod bed exercises the FULL acquire/preempt path with ZERO GPU — a preemptible pod holder on a SYNTHETIC selector-less token (test-lock) + a requires_exclusive claimant, so AcquireExclusive -> holdersToStop -> stopHolders+wait -> lease persisted -> applyMode SKIPS (no gpu selector) -> claim, then teardown -> ReleaseClaimant -> restoreHolders, all THROUGH the externalized dispatch + the resolved-project envelope (gather/resources) + InvokeProvider (the rest).
Parameter schema
Section titled “Parameter schema”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.
schema/preempt.cue
Section titled “schema/preempt.cue”// plugin-preempt's OWN self-contained CUE schema — the SINGLE SOURCE for this plugin's// declaration surface, served over the Describe channel (there is no schema-less// plugin). SELF-CONTAINED: it references no base def, so it compiles STANDALONE (the// property the SDK's serve-side compile and `cue exp gengotypes` both need).//// The plugin serves `verb:arbiter` (the exclusive/shared resource arbiter, reached// peer-to-peer via InvokeProvider) and `command:preempt` (the operator CLI). Neither// declares a structured plugin_input, so this schema DOCUMENTS the capability pair.#PreemptPlugin: { // What the plugin does, in one line (the public-docs surface). contract: string & !=""
// The capabilities the plugin serves. verbs: ["arbiter"] commands: ["preempt"]}See also the candy reference for this candy’s install surface.