Skip to content

plugin-distro

Placement compiled-in (in-process)
Source github.com/opencharly/charly/candy/plugin-distro
Version 2026.176.3203
Candy plugin-distro

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:

  • distro — kind class

The distro plugin KIND relocated into a candy: a KIND provider dispatching via the pb Invoke(OpLoad) envelope (decode the authored distro: entity into its core spec type, re-marshal as canonical JSON). Serves itself in BOTH placements (compiled-in OR out-of-process) like the matching/exampleprobe verbs + the init kind — no kit contract needed (kinds are pb-shape).

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.

// The BUILT-IN `distro` plugin's OWN CUE schema — the typed input for the `distro`
// KIND (the per-distro build vocabulary, formerly a core `distro:` kind decoded into
// the typed core map uf.Distro). It is the SINGLE SOURCE for this plugin's params,
// used two ways (the same contract the reference exampleprobe/process, the
// package-group/agent/module/sidecar plugins, and core `spec` use):
//
// 1. GENERATE the Go param struct — `cue exp gengotypes` (driven by task cue:gen,
// which wraps this with `package params` + `@go(params)`) emits
// ../params/cue_types_gen.go.
// 2. VALIDATE authored input AT RUNTIME — the builtin serves this source over the
// Describe channel (InProcTransport) exactly like an external serves it over
// gRPC; the host splices it onto the base (base ++ plugin) and validates every
// authored `distro:` entity body against #DistroInput BEFORE runPluginKind
// dispatches (validateAuthoredPluginInput(ClassKind, "distro", …)) — the
// kind-class analogue of the verb plugin_input gate.
//
// SELF-CONTAINED: it references NO base def — every shared shape (#CacheMount /
// #PhaseSet / #PhaseTemplates from _common.cue) is reproduced standalone here (prefix
// #Ds), so it compiles standalone (gengotypes + the load-gate compile) AND splices
// onto the base (the base ++ plugin splice exists to detect a def-name collision with
// the base, not to resolve base refs). It is a faithful reproduction of the core
// #Distro (schema/distro.cue) — the same authored WIRE keys, so the host validates a
// real distro entity (incl. the binary-embedded build vocabulary), and the plugin's
// Invoke canonicalises the body back through the core spec.Distro type (which DistroDef
// aliases and the generator/format code consumes via the Distros() accessor).
//
// NAME: in node-form the entity name is the top-level node KEY, not a body field, so
// the assembled entity body NEVER carries `name`; #Distro has no name field either, so
// there is nothing to make optional here. @go() annotations are dropped (they steer the
// CORE spec codegen only; the validator ignores attributes, the plugin Invoke decodes
// into spec.Distro, so the generated params struct's Go names are cosmetic for a builtin).
#DistroInput: {
inherits?: string & =~"^[a-z0-9]+(-[a-z0-9]+)*$"
inherit_packages?: bool
version?: string & =~"^[0-9]+(\\.[0-9]+)*$"
bootstrap?: #DsBootstrap
workaround?: [...string]
format?: {[string]: #DsFormat}
base_user?: #DsBaseUser
pacstrap?: #DsPacstrap
debootstrap?: #DsDebootstrap
alpine_bootstrap?: #DsAlpineBootstrap
bootloader?: #DsBootloader
dnf?: #DsDnf
}
// install_cmd is the bootstrap command; ubuntu sets it to "" (kept WITHOUT
// `& !=""` so the empty-string base case validates).
#DsBootstrap: {
install_cmd: string
package?: [...string]
cache_mount?: [...#DsCacheMount]
}
#DsFormat: {
cache_mount?: [...#DsCacheMount]
section_field?: {[string]: "list" | "list_of_maps"}
install_template?: string
uninstall_template?: string
phase?: #DsPhaseSet
validate?: [...#DsFormatRule]
secondary?: bool
local_pkg?: #DsLocalPkg
}
#DsFormatRule: {
field: string & !=""
rule: string & !=""
}
#DsLocalPkg: {
pkg_glob: string & !=""
source_sentinel: string & !=""
build_template: string & !=""
install_template: string & !=""
probe: string & !=""
dep_builder?: string
download_template?: string
}
#DsPacstrap: {
base_package?: [...string]
keyring_init_cmd?: string
mirrorlist_url?: string & =~"^https?://"
extra_repo?: [...#DsPacstrapRepo]
runtime_pacman_conf?: string
}
#DsPacstrapRepo: {
name: string & !=""
server: string & =~"^https?://"
siglevel?: string
}
#DsDebootstrap: {
suite?: string
mirror?: string & =~"^https?://"
variant?: string
components?: string
include_package?: [...string]
base_package?: [...string]
extra_repo?: [...#DsDebootstrapRepo]
}
#DsDebootstrapRepo: {
name: string & !=""
url: string & =~"^https?://"
suite?: string
components?: string
}
#DsAlpineBootstrap: {
mirror_url?: string & =~"^https?://"
}
#DsBootloader: {
install_template?: string
initramfs_template?: string
fstab_template?: string
}
#DsBaseUser: {
name: string & !=""
uid: int & >=0
gid: int & >=0
home: string & =~"^/"
}
#DsDnf: {
max_parallel_downloads?: int & >=1
fastestmirror?: bool
}
// reproduces #CacheMount (schema/_common.cue) standalone.
#DsCacheMount: {
dst: string & =~"^/"
sharing?: *"locked" | "shared" | "private"
owned?: bool
}
// reproduces #PhaseSet / #PhaseTemplates (schema/_common.cue) standalone.
#DsPhaseSet: {
prepare?: #DsPhaseTemplates
install?: #DsPhaseTemplates
cleanup?: #DsPhaseTemplates
}
#DsPhaseTemplates: {
container?: string
host?: string
}

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