vmshared

package
v0.2026218.338 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 6, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Code-assisted alias surface for the CUE-single-source cutover (WF-B THE REPOINT).

Every charly hand param struct that has a spec counterpart is now a zero-churn Go type alias onto charly/spec — the generated (cue exp gengotypes) types plus the hand-written union/state types, exposed under their charly names via spec/charly_names.go. The hand struct DEFINITIONS were deleted; these aliases keep every existing reference (`BoxConfig{…}`, `[]ServiceEntry`, …) compiling against the single CUE source of truth. Pure methods moved INTO package spec; methods that reach package-main internals are free functions here taking a *spec.X. See CHANGELOG.

NOT aliased (name collisions where the package-main type is a DIFFERENT concept, kept hand-written): CalVer (version.go computation struct, vs the spec.CalVer scalar), CandyRef (refs.go ref struct, vs the spec.CandyRef scalar), Candy (layers.go resolved-candy runtime struct, vs spec.Candy the param — aliased as CandyYAML instead).

Index

Constants

View Source
const (
	PollLocal  = spec.PollLocal
	PollRemote = spec.PollRemote
	PollHeavy  = spec.PollHeavy

	ReadinessAbsoluteCapFallback     = spec.ReadinessAbsoluteCapFallback
	ReadinessIntervalHeavyFallback   = spec.ReadinessIntervalHeavyFallback
	ReadinessIntervalLocalFallback   = spec.ReadinessIntervalLocalFallback
	ReadinessIntervalRemoteFallback  = spec.ReadinessIntervalRemoteFallback
	ReadinessNoProgressFallback      = spec.ReadinessNoProgressFallback
	ReadinessPerAttemptFallback      = spec.ReadinessPerAttemptFallback
	ReadinessPerAttemptHeavyFallback = spec.ReadinessPerAttemptHeavyFallback
	ReadinessStopGraceFallback       = spec.ReadinessStopGraceFallback
)
View Source
const VmStateDirEnv = "CHARLY_VM_STATE_DIR"

vm_state_root.go — the ONE root-path resolver for per-VM host state (~/.local/share/charly/vm/<domain>/ — ssh keys, known_hosts, seed ISO, the per-domain disk overlay, snapshots/, instance.yml). Bed-robustness batch item 6 (the "global ~/.local/share/charly/vm non-worktree-scoping footgun"): a libvirt DOMAIN name is derived PURELY from the deploy name (VmDomainIdentity), with no project/worktree component, so two concurrent checkouts (separate `git worktree`s, the project's own standing multi-worktree / multi-teammate development model) that happen to run the SAME bed/deploy name — the common case, since bed names like "check-charly-vm" are fixed identifiers shared across every worktree of the same repo — collide on the SAME host state directory (and, more severely, the SAME libvirt domain). VmStateRoot is the single override point: set CHARLY_VM_STATE_DIR to a worktree-distinct path (e.g. in a per-worktree wrapper/.envrc) and every VM state file for that invocation lands under it instead of the shared default — the SAME env-var-override pattern already established for CHARLY_REPO_CACHE / CHARLY_REPO_OVERRIDE / CHARLY_PROJECT_DIR. Default behavior (no env var set) is UNCHANGED — this is purely additive, zero-risk for the common single-worktree case. Every VM state-path call site (charly core, candy/plugin-vm, candy/plugin-deploy-vm, this package's own vm_snapshot.go) routes through this ONE function (R3 — the literal `filepath.Join(home, ".local", "share", "charly", "vm")` was previously duplicated across 7+ files) so the override applies uniformly, never partially.

Variables

View Source
var (
	BoolPtrDefaultTrue       = boolPtrDefaultTrue
	BoolPtrToYesNo           = boolPtrToYesNo
	BoolPtrTrue              = boolPtrTrue
	ComposePackages          = composePackages
	ComposeRunCmd            = composeRunCmd
	ComposeUsers             = composeUsers
	DefaultMachineForArch    = defaultMachineForArch
	FormatForDistroID        = hostenv.FormatForDistroID
	LoadRegistry             = loadRegistry
	OpenOutputPath           = openOutputPath
	OvmfCandidatesForDistro  = ovmfCandidatesForDistro
	ParseGlibcVersion        = hostenv.ParseGlibcVersion
	RegistryPath             = registryPath
	ResolveCloudInitSSHUser  = resolveCloudInitSSHUser
	ResolveCPUDefaults       = resolveCPUDefaults
	SaveRegistry             = saveRegistry
	SnapshotExternalDiskPath = snapshotExternalDiskPath
	SnapshotsDir             = snapshotsDir
	SplitOsReleaseLine       = hostenv.SplitOsReleaseLine
	SplitPortForward         = splitPortForward
	VmDiskPath               = vmDiskPath
	WriterForPath            = writerForPath
)

Re-exported functions.

View Source
var (
	CreateInternalSnapshot    func(opts SnapshotCreateOpts) error
	DeleteInternalSnapshot    func(vmName string, entry *SnapshotEntry) error
	RevertInternalSnapshot    func(vmName string, entry *SnapshotEntry) error
	PromoteInternalToExternal func(vmName string, entry *SnapshotEntry, outPath string) error
	CreateExternalSnapshot    func(opts SnapshotCreateOpts, outFile string) error
	DeleteExternalSnapshot    func(vmName string, entry *SnapshotEntry) error
	RevertExternalSnapshot    func(vmName string, entry *SnapshotEntry) error
)

Snapshot backends. Core wires host-side RPC wrappers (vm_snapshot_client.go) that drive the out-of-process plugin; the plugin wires the in-process go-libvirt implementations (vm_snapshot_internal.go / vm_snapshot_libvirt.go).

View Source
var (
	ErrPollStalled     = spec.ErrPollStalled
	ErrPollCapExceeded = spec.ErrPollCapExceeded
	ErrPollFatal       = spec.ErrPollFatal
	ErrPollConfig      = spec.ErrPollConfig

	// ResolveReadiness + PollUntil are re-exported functions (the resolver + the
	// poll driver).
	ResolveReadiness = spec.ResolveReadiness
	PollUntil        = spec.PollUntil
)
View Source
var CompareGlibc = hostenv.CompareGlibc

CompareGlibc re-exports hostenv.CompareGlibc. See spec/hostenv/hostdistro.go.

View Source
var DetectHostDistro = hostenv.DetectHostDistro

DetectHostDistro re-exports hostenv.DetectHostDistro. See spec/hostenv/hostdistro.go.

View Source
var DetectHostGlibc = hostenv.DetectHostGlibc

DetectHostGlibc re-exports hostenv.DetectHostGlibc. See spec/hostenv/hostdistro.go.

View Source
var ParseLibvirtURI = spec.ParseLibvirtURI

ParseLibvirtURI re-exports spec.ParseLibvirtURI. See spec/spec/libvirt_uri.go.

View Source
var SplitVmAddress = spec.SplitVmAddress

SplitVmAddress re-exports spec.SplitVmAddress. See spec/spec/vm_domain.go.

View Source
var StartLibvirtUserSession = hostenv.StartLibvirtUserSession

StartLibvirtUserSession re-exports hostenv.StartLibvirtUserSession. Stubbable per-package (a caller that stubs THIS var must also call THIS var — plugin-vm does). See spec/hostenv/libvirt_session.go.

View Source
var UnmarshalEmbeddedDefaults func(dst any)

UnmarshalEmbeddedDefaults decodes the consumer's embedded build vocabulary (the ovmf_paths / ovmf_distro_aliases directives the OVMF resolver reads) into dst. Core reads its embedded charly.yml; the plugin reads its embedded build_defaults.yml.

View Source
var ValidateEgress func(kind, label string, data []byte) error

ValidateEgress gates a generated cloud-init document against its CUE egress schema before the bytes are emitted (RenderCloudInit in cloud_init_render.go).

View Source
var VmDomainIdentity = spec.VmDomainIdentity
View Source
var VmNameFromDeployName = spec.VmNameFromDeployName

VmNameFromDeployName re-exports spec.VmNameFromDeployName. See spec/spec/vm_domain.go.

Functions

func DecrementSnapshotRefcount

func DecrementSnapshotRefcount(vmName, snapName string) error

DecrementSnapshotRefcount decreases the refcount. Floors at 0.

func DeleteSnapshot

func DeleteSnapshot(opts SnapshotDeleteOpts) error

DeleteSnapshot is the mode-aware deletion. Refuses while refcount > 0 unless Force is set.

func DetectRuntimeHostVendor

func DetectRuntimeHostVendor() string

DetectRuntimeHostVendor reads /proc/cpuinfo to identify the host CPU vendor (GenuineIntel | AuthenticAMD | ""). Used by RenderDomain / RenderQemuArgv to auto-append the correct nested-virt feature (vmx vs svm).

func EnsurePerVmNvram

func EnsurePerVmNvram(templatePath, perVmDir string) (string, error)

EnsurePerVmNvram copies the OVMF_VARS template to a per-VM NVRAM file on first use. Returns the absolute path of the per-VM NVRAM (which is what rt.NVRAMPath should be set to). Idempotent: if the per-VM file already exists, it's preserved (contains the guest's accumulated UEFI variables).

func IncrementSnapshotRefcount

func IncrementSnapshotRefcount(vmName, snapName string) error

IncrementSnapshotRefcount increases the refcount on the named snapshot. Used by clone/ephemeral instantiation paths.

func IsDeviceElement

func IsDeviceElement(snippet string) bool

IsDeviceElement returns true if the XML snippet's root element belongs inside <devices>.

func KeyToRootTmpfilesD

func KeyToRootTmpfilesD(pubkey string) string

KeyToRootTmpfilesD converts an SSH public key to a systemd tmpfiles.d config that creates /root/.ssh/authorized_keys. Matches bcvk's key_to_root_tmpfiles_d.

func KeyToUserTmpfilesD

func KeyToUserTmpfilesD(user, home, pubkey string) string

KeyToUserTmpfilesD generates a systemd tmpfiles.d config that delivers a per-VM SSH key for the named user. The user account itself must already exist in the rootfs (created at build time by the bootloader install template OR by cloud-init); this function only delivers the *key*, never bakes one into the image.

SMBIOS-vs-cloud-init priority: the key is written to a ROOT-owned, sshd- checked file at /etc/ssh/authorized_keys.d/<user>, and a sshd_config.d drop-in widens AuthorizedKeysFile to check BOTH ~/.ssh/authorized_keys (cloud-init's domain) AND that file. systemd-tmpfiles applies this BEFORE sshd starts, so the SMBIOS key is ALWAYS accepted even if cloud-init later rewrites the user's own authorized_keys — SMBIOS owns the drop-in location, cloud-init owns ~/.ssh, and sshd honors both. The key is ALSO written to ~/.ssh/authorized_keys as a fallback for any guest sshd that ignores the drop-in (so the key works whether or not the widened path takes effect).

The home path defaults to /home/<user> when empty.

func KillQemuByPID

func KillQemuByPID(stateDir string)

KillQemuByPID force-kills a direct-QEMU VM by the PID recorded in its state dir (the last-resort path when QMP graceful/force shutdown is unavailable). Pure OS process kill — no govmm.

func LibvirtSessionSocket

func LibvirtSessionSocket() string

LibvirtSessionSocket returns the path to the user's libvirt session socket. Modern libvirt (≥ 8.0) uses per-driver modular daemons (virtqemud-sock); legacy libvirt (< 8.0) uses the monolithic libvirt-sock. Probe the modular socket first (every current distro), fall back to legacy.

func LibvirtSessionSocketWithProbes

func LibvirtSessionSocketWithProbes() (picked string, probed []string)

func QemuSystemBinary

func QemuSystemBinary() string

QemuSystemBinary returns the architecture-appropriate QEMU binary name.

func RenderCloudInit

func RenderCloudInit(spec *VmSpec, rt CloudInitRuntimeParams) (userData, metaData, networkConfig string, err error)

RenderCloudInit produces the three NoCloud seed ISO payloads from a VmSpec plus runtime parameters. Pure function — no filesystem or network calls.

- userData → written to cidata/user-data (prefixed with #cloud-config) - metaData → written to cidata/meta-data (instance-id + hostname) - networkCfg → written to cidata/network-config (optional; empty if unset)

Defaults applied automatically (D15):

  1. VmSSH.User added to users: with sudo + ssh_authorized_keys (if the key-injection channel is enabled AND SSHPublicKey != "")
  2. Minimum packages: {openssh, curl, tar} unioned with user's Packages — delivered via the `packages:` cloud-config key on every distro EXCEPT pacman-family (arch/cachyos/manjaro/endeavouros), where it is instead PREPENDED to runcmd as `pacman -Sy --needed --noconfirm <union>` (db refresh + install-only; a bare -S 404s on rotated mirrors, and a full -Syu destabilizes the live guest — see the runcmd comment) and the `packages:` key is omitted entirely (R10 bed finding: cloud-init's own package-install module invokes `pacman -S` without `--needed`, so on an image that already ships the minimum set — e.g. every Arch cloud image — it unconditionally REINSTALLS them; reinstalling openssh re-triggers its post-install host-key-regen hook while the base image's own socket-activated sshd is already listening, racing a live key-file rewrite against new connections — the observed "reset during kex_exchange_identification, guest otherwise idle" signature. apt/dnf installs are naturally no-op-idempotent when the package is already present, so only the pacman-family path needs this rewrite; every other distro's render is BYTE-IDENTICAL to before this fix). Source.Distro is an OPTIONAL yaml field — a cloud_image source (e.g. eval-vm) commonly omits it, relying on base_user alone (a second live-bed finding: the first cut of this fix silently never fired for exactly that reason). effectiveDistro fills the ONE narrow gap this codebase already documents as supported-by-convention (resolveCloudInitSSHUser's own "arch" cloud_image fallback, below): empty Distro + kind=="cloud_image" + base_user=="arch" infers "arch". This is STRICTLY NARROWER than (and makes explicit) the pre-existing accidental behavior — composePackages' distro switch already defaulted an empty/unrecognized distro to the Arch/Fedora-shaped {openssh, sshd} output, so no caller this inference newly matches was ever getting anything else. Any other empty-distro image (base_user != "arch") stays on the safe, unchanged non-pacman path — an unknown image never gets a pacman command. The proper long-term fix is schema-level (distro required, or defaulted at entity-resolve time, for every cloud_image source) — tracked separately, not attempted here.
  3. Minimum runcmd: {systemctl enable --now sshd} prepended (after the pacman install command on pacman-family distros, per #2)
  4. charly_install: NOT a cloud-init concern — the vm deploy's PrepareVenue delivers charly post-boot (auto/scp stage it; skip verifies). No charly download runcmd.
  5. VmCloudInit.Extra: raw cloud-config YAML appended as a second document (separated by ---) if non-empty

func RenderQemuArgv

func RenderQemuArgv(spec *VmSpec, rt VmRuntimeParams, paths QemuRuntimePaths) []string

RenderQemuArgv produces the full argv for `qemu-system-<arch>` from a VmSpec + VmRuntimeParams + QemuRuntimePaths. Pure function — no filesystem or process state side effects.

Covers the intersection of libvirt schema features that map cleanly to QEMU: machine, cpu (D16 defaults), firmware (D17 pflash), disks (root + seed iso D5 + additional), network (user-mode hostfwd), SMBIOS credentials (D13), RNG, balloon, qemu-guest-agent channel.

Structured libvirt features without a QEMU mapping (virtiofs, launch_security beyond SEV, PCI hostdev, graphics/spice, TPM) are skipped with a warning comment inserted via the caller's log output — this function only returns argv.

func ResolveKeyInjectionChannels

func ResolveKeyInjectionChannels(spec *VmSpec) (smbios, cloudInit bool)

ResolveKeyInjectionChannels applies the D13 auto-defaults and explicit-wins merging to produce the effective (smbios, cloudInit) toggle state for a VmSpec. Returns the booleans persisted into VmDeployState.KeyInjectionResolved.

func ResolveOvmfForSpec

func ResolveOvmfForSpec(spec *VmSpec, vmStateDir string) (codePath, nvramPath string, err error)

ResolveOvmfForSpec is a convenience wrapper: detects the host distro, picks the correct OVMF_CODE/OVMF_VARS pair for the VmSpec's firmware setting, and provisions the per-VM NVRAM file. Returns (CodePath, NVRAMPath) — the two values needed to populate VmRuntimeParams.

Returns ("", "", nil) when firmware == "bios" (BIOS boot needs no firmware images).

func ResolveVmCpus

func ResolveVmCpus(spec *VmSpec) int

ResolveVmCpus picks the spec-declared CPU count or falls back to 2.

func ResolveVmRam

func ResolveVmRam(spec *VmSpec) string

ResolveVmRam picks the spec-declared RAM or falls back to "4G".

func RevertSnapshot

func RevertSnapshot(vmName, snapName string) error

RevertSnapshot is the mode-aware revert.

func SmbiosCredForRootSSH

func SmbiosCredForRootSSH(pubkey string) string

SmbiosCredForRootSSH is preserved as a compatibility wrapper for the existing call sites in vm.go (legacy bootc paths).

func SmbiosCredForSSH

func SmbiosCredForSSH(user, home, pubkey string) string

SmbiosCredForSSH generates the SMBIOS type 11 credential string that delivers a per-VM SSH key to the named user via systemd-tmpfiles. When user == "" or user == "root", the legacy /root/.ssh path is used. Returns: "io.systemd.credential.binary:tmpfiles.extra=<base64>"

func VmDiskDir

func VmDiskDir(vmName string) string

VmDiskDir returns the per-VM directory holding a built disk image (disk.qcow2) and, for cloud_image/bootstrap/clone sources, its NoCloud seed.iso. The path is namespaced by the DISK SOURCE (the kind:vm ENTITY), so it is the shared read-only BASE every per-deploy overlay backs onto — building or creating one entity never reuses a SIBLING entity's disk or — critically — its stale seed.iso, whose embedded SSH key would mismatch this VM's own id_ed25519 and silently break the deploy's authentication.

func VmStateRoot added in v0.2026203.730

func VmStateRoot() (string, error)

VmStateRoot resolves the root directory for per-VM host state. Honors CHARLY_VM_STATE_DIR when set (trimmed, must be non-empty, must be absolute — a relative override would resolve against whatever cwd happens to be active at each call site, defeating the whole point of a stable per-worktree pin); otherwise falls back to the default ~/.local/share/charly/vm.

func WriteJSON

func WriteJSON(w io.Writer, v any) error

WriteJSON encodes v as indented JSON to w (the `--json` output helper; the `charly vm snapshot list --json` path uses it).

func WriteSeedISO

func WriteSeedISO(outPath, userData, metaData, networkConfig string) error

WriteSeedISO builds a NoCloud cidata ISO at outPath. Takes the three rendered strings from RenderCloudInit (user-data, meta-data, and optional network-config) and shells out to xorriso to pack them into an ISO9660+Joliet+RockRidge image labeled cloudInitVolumeID.

The guest's cloud-init scans for a filesystem labeled "CIDATA" or "cidata" (it tries both cases) on first boot. Files inside:

user-data       — the #cloud-config YAML (required)
meta-data       — instance-id + hostname (required, can be empty)
network-config  — v2 network schema (optional)

Returns an error if xorriso isn't installed or the ISO write fails. charly doctor checks for xorriso and suggests the install package.

Types

type AURPackages

type AURPackages = spec.AUR

type AgentConfig

type AgentConfig = spec.Agent

type AliasConfig

type AliasConfig = spec.AliasConfig

type AliasYAML

type AliasYAML = spec.AliasYAML

type AlpineBootstrapDef

type AlpineBootstrapDef = spec.AlpineBootstrap

type AndroidAdbEndpoint

type AndroidAdbEndpoint = spec.AdbEndpoint

--- nested types renamed in spec (charly name != cue-def name) ---

type AndroidGoogleAccount

type AndroidGoogleAccount = spec.GoogleAccount

type AndroidSpec

type AndroidSpec = spec.AndroidSpec

type ApkPackageSpec

type ApkPackageSpec = spec.ApkPackageSpec

type BaseUserDef

type BaseUserDef = spec.BaseUser

type BootloaderDef

type BootloaderDef = spec.Bootloader

type BootstrapDef

type BootstrapDef = spec.Bootstrap

type BoxConfig

type BoxConfig = spec.BoxConfig

type BuildStageContext added in v0.2026189.748

type BuildStageContext = spec.BuildStageContext

type BuilderDef

type BuilderDef = spec.BuilderDef

type BundleNode

type BundleNode = spec.BundleNode

type CacheMountDef

type CacheMountDef = spec.CacheMount

type CandyArtifact

type CandyArtifact = spec.CandyArtifact

type CandyArtifactRewrite

type CandyArtifactRewrite = spec.CandyArtifactRewrite

type CandyCapabilities

type CandyCapabilities = spec.CandyCapabilities

type CandyPluginDecl

type CandyPluginDecl = spec.Plugin

type CandyYAML

type CandyYAML = spec.CandyYAML

type CloudInitRuntimeParams

type CloudInitRuntimeParams = spec.CloudInitRuntimeParams

CloudInitRuntimeParams — SPIKE (value-type relocation, #55 cluster 4): relocated to spec.CloudInitRuntimeParams (spec/spec/cloud_init_runtime_params.go). Zero-churn alias; RenderCloudInit (behavior) is unaffected.

type CopyDef

type CopyDef = spec.Copy

type CredentialMount

type CredentialMount = spec.CredentialMount

type DataYAML

type DataYAML = spec.DataYAML

type DebootstrapDef

type DebootstrapDef = spec.Debootstrap

type DebootstrapRepo

type DebootstrapRepo = spec.DebootstrapRepo

type DeployExpose

type DeployExpose = spec.DeployExpose

type DeployProbes

type DeployProbes = spec.DeployProbes

type DeployResources

type DeployResources = spec.DeployResources

type DeploySecretConfig

type DeploySecretConfig = spec.DeploySecret

type DeployStorage

type DeployStorage = spec.DeployStorage

type DeployVolumeConfig

type DeployVolumeConfig = spec.DeployVolume

type DistroDef

type DistroDef = spec.ResolvedDistro

type DistroPackages

type DistroPackages = spec.DistroPackages

type DnfConfig

type DnfConfig = spec.Dnf

type EnvDependency

type EnvDependency = spec.EnvDependency

type EphemeralLifetime

type EphemeralLifetime = spec.EphemeralLifetime

type EphemeralRuntime

type EphemeralRuntime = spec.EphemeralRuntime

type ExtractYAML

type ExtractYAML = spec.ExtractYAML

type FormatDef

type FormatDef = spec.Format

type FormatRule

type FormatRule = spec.FormatRule

type GpuSelector

type GpuSelector = spec.GpuSelector

type HooksConfig

type HooksConfig = spec.HooksConfig

type HostDistro

type HostDistro = hostenv.HostDistro

HostDistro re-exports hostenv.HostDistro (its PopulateTags/PrimaryTag/FormatHint methods ride the alias). See spec/hostenv/hostdistro.go.

type InitDef

type InitDef = spec.InitDef

type InstallContext added in v0.2026189.748

type InstallContext = spec.InstallContext

type InstallOptsConfig

type InstallOptsConfig = spec.InstallOptsConfig

type IterateConfig

type IterateConfig = spec.IterateConfig

type K8sDeployConfig

type K8sDeployConfig = spec.K8sDeploy

type K8sGatewayAPI

type K8sGatewayAPI = spec.K8sGatewayAPI

type K8sHostname

type K8sHostname = spec.K8sHostname

type K8sImagesDefaults

type K8sImagesDefaults = spec.K8sImagesDefaults

type K8sIngressDefaults

type K8sIngressDefaults = spec.K8sIngressDefaults

type K8sObservability

type K8sObservability = spec.K8sObservability

type K8sPatch

type K8sPatch = spec.K8sPatch

type K8sPodDefaults

type K8sPodDefaults = spec.K8sPodDefaults

type K8sResourceDefaults

type K8sResourceDefaults = spec.K8sResourceDefaults

type K8sResourceValues

type K8sResourceValues = spec.K8sResourceValues

type K8sResources

type K8sResources = spec.K8sResources

type K8sSecretsBackend

type K8sSecretsBackend = spec.K8sSecretsBackend

type K8sSpec

type K8sSpec = spec.K8sSpec

type K8sStorage

type K8sStorage = spec.K8sStorage

type LibvirtAudio

type LibvirtAudio = spec.LibvirtAudio

type LibvirtCPU

type LibvirtCPU = spec.LibvirtCPU

type LibvirtCPUCache

type LibvirtCPUCache = spec.LibvirtCPUCache

type LibvirtCPUFeature

type LibvirtCPUFeature = spec.LibvirtCPUFeature

type LibvirtCPUTopology

type LibvirtCPUTopology = spec.LibvirtCPUTopology

type LibvirtCPUTune

type LibvirtCPUTune = spec.LibvirtCPUTune

type LibvirtChannel

type LibvirtChannel = spec.LibvirtChannel

type LibvirtClock

type LibvirtClock = spec.LibvirtClock

type LibvirtConsole

type LibvirtConsole = spec.LibvirtConsole

type LibvirtDevices

type LibvirtDevices = spec.LibvirtDevices

type LibvirtDisk

type LibvirtDisk = spec.LibvirtDisk

type LibvirtDomain

type LibvirtDomain = spec.LibvirtDomain

type LibvirtEmulatorPin

type LibvirtEmulatorPin = spec.LibvirtEmulatorPin

type LibvirtFeatures

type LibvirtFeatures = spec.LibvirtFeatures

type LibvirtFilesystem

type LibvirtFilesystem = spec.LibvirtFilesystem

type LibvirtGraphics

type LibvirtGraphics = spec.LibvirtGraphics

type LibvirtGraphicsListen

type LibvirtGraphicsListen = spec.LibvirtGraphicsListen

type LibvirtGraphicsListeners

type LibvirtGraphicsListeners = spec.LibvirtGraphicsListeners

type LibvirtHostdev

type LibvirtHostdev = spec.LibvirtHostdev

type LibvirtHub

type LibvirtHub = spec.LibvirtHub

type LibvirtHugepages

type LibvirtHugepages = spec.LibvirtHugepages

type LibvirtHyperV

type LibvirtHyperV = spec.LibvirtHyperV

type LibvirtIOMMU

type LibvirtIOMMU = spec.LibvirtIOMMU

type LibvirtIOThreadPin

type LibvirtIOThreadPin = spec.LibvirtIOThreadPin

type LibvirtInput

type LibvirtInput = spec.LibvirtInput

type LibvirtInterface

type LibvirtInterface = spec.LibvirtInterface

type LibvirtKVM

type LibvirtKVM = spec.LibvirtKVM

type LibvirtLaunchSecurity

type LibvirtLaunchSecurity = spec.LibvirtLaunchSecurity

type LibvirtMemBalloon

type LibvirtMemBalloon = spec.LibvirtMemBalloon

type LibvirtMemTune

type LibvirtMemTune = spec.LibvirtMemTune

type LibvirtMemnode

type LibvirtMemnode = spec.LibvirtMemnode

type LibvirtMemoryBacking

type LibvirtMemoryBacking = spec.LibvirtMemoryBacking

type LibvirtNUMACell

type LibvirtNUMACell = spec.LibvirtNUMACell

type LibvirtNUMAMemory

type LibvirtNUMAMemory = spec.LibvirtNUMAMemory

type LibvirtNUMATune

type LibvirtNUMATune = spec.LibvirtNUMATune

type LibvirtPanic

type LibvirtPanic = spec.LibvirtPanic

type LibvirtParallel

type LibvirtParallel = spec.LibvirtParallel

type LibvirtPortForward

type LibvirtPortForward = spec.LibvirtPortForward

type LibvirtRNG

type LibvirtRNG = spec.LibvirtRNG

type LibvirtRedirDev

type LibvirtRedirDev = spec.LibvirtRedirDev

type LibvirtResource

type LibvirtResource = spec.LibvirtResource

type LibvirtSecLabel

type LibvirtSecLabel = spec.LibvirtSecLabel

type LibvirtSerial

type LibvirtSerial = spec.LibvirtSerial

type LibvirtShmem

type LibvirtShmem = spec.LibvirtShmem

type LibvirtSmartcard

type LibvirtSmartcard = spec.LibvirtSmartcard

type LibvirtSound

type LibvirtSound = spec.LibvirtSound

type LibvirtSpinlocks

type LibvirtSpinlocks = spec.LibvirtSpinlocks

type LibvirtSysInfo

type LibvirtSysInfo = spec.LibvirtSysInfo

type LibvirtTPM

type LibvirtTPM = spec.LibvirtTPM

type LibvirtTimer

type LibvirtTimer = spec.LibvirtTimer

type LibvirtURI

type LibvirtURI = spec.LibvirtURI

LibvirtURI re-exports spec.LibvirtURI (its IsLocal method rides the alias). See spec/spec/libvirt_uri.go.

type LibvirtUSB

type LibvirtUSB = spec.LibvirtUSB

type LibvirtVCPUPin

type LibvirtVCPUPin = spec.LibvirtVCPUPin

type LibvirtVendorID

type LibvirtVendorID = spec.LibvirtVendorID

type LibvirtVideo

type LibvirtVideo = spec.LibvirtVideo

type LibvirtVsock

type LibvirtVsock = spec.LibvirtVsock

type LibvirtWatchdog

type LibvirtWatchdog = spec.LibvirtWatchdog

type LocalPkgDef

type LocalPkgDef = spec.LocalPkg

type LocalSpec

type LocalSpec = spec.LocalSpec

type MCPServerYAML

type MCPServerYAML = spec.MCPServerYAML

type Matcher

type Matcher = spec.Matcher

type MatcherList

type MatcherList = spec.MatcherList

type MergeConfig

type MergeConfig = spec.MergeConfig

type Op

type Op = spec.Op

type OvmfPaths

type OvmfPaths struct {
	// CodePath is the OVMF_CODE firmware image. Read-only.
	CodePath string

	// VarsTemplate is the OVMF_VARS template with standard UEFI CA
	// keys pre-enrolled (when secure=true). The per-VM NVRAM file is
	// copied from this template on first VM create.
	VarsTemplate string

	// Secure indicates whether this is the secure-boot-enabled variant.
	Secure bool
}

OvmfPaths is the pair of firmware image paths needed to boot a UEFI VM: OVMF_CODE (read-only, shared across all VMs) and an OVMF_VARS template (read-only, copied to a per-VM writable NVRAM file on first VM create).

func ResolveOvmfPaths

func ResolveOvmfPaths(distroID string, secure bool) (OvmfPaths, error)

ResolveOvmfPaths picks the correct OVMF_CODE + OVMF_VARS paths for the host distro + secure-boot setting. Returns an error when no candidate path exists on disk so `charly vm create` fails with a clean remediation hint instead of a cryptic QEMU pflash error.

D17 path table:

Fedora         /usr/share/OVMF/OVMF_CODE{.secboot,}.fd
               /usr/share/OVMF/OVMF_VARS{.secboot,}.fd
Arch           /usr/share/edk2/x64/OVMF_CODE{.secboot,}.4m.fd
               /usr/share/edk2/x64/OVMF_VARS.4m.fd
Debian/Ubuntu  /usr/share/OVMF/OVMF_CODE_4M{.ms,}.fd
               /usr/share/OVMF/OVMF_VARS_4M{.ms,}.fd

type PackageItem

type PackageItem = spec.PackageItem

type PacstrapDef

type PacstrapDef = spec.Pacstrap

type PacstrapRepo

type PacstrapRepo = spec.PacstrapRepo

type PhaseSet

type PhaseSet = spec.PhaseSet

type PhaseTemplates

type PhaseTemplates = spec.PhaseTemplates

type PodSpec

type PodSpec = spec.PodSpec

type PollClass

type PollClass = spec.PollClass

type PollCondition

type PollCondition = spec.PollCondition

type PollConfig

type PollConfig = spec.PollConfig

type PortScope

type PortScope = spec.PortScope

type PortSpec

type PortSpec = spec.PortSpec

type PreemptibleConfig

type PreemptibleConfig = spec.PreemptibleConfig

type QemuRuntimePaths

type QemuRuntimePaths struct {
	// MonitorSocket — unix socket for the QEMU monitor (`-monitor`).
	MonitorSocket string

	// QmpSocket — unix socket for QMP (`-qmp`).
	QmpSocket string

	// ConsoleSocket — unix socket for the serial console (`-serial`).
	ConsoleSocket string

	// PidFile — `-pidfile` target.
	PidFile string
}

QemuRuntimePaths carries backend-specific paths that QEMU needs but libvirt doesn't (socket paths, pidfile). Composed with VmRuntimeParams when the QEMU backend renders its argv.

type ReadinessConfig

type ReadinessConfig = spec.ReadinessConfig

type ResolvedReadiness

type ResolvedReadiness = spec.ResolvedReadiness

type ResourceDef

type ResourceDef = spec.ResourceDef

type RouteYAML

type RouteYAML = spec.RouteYAML

type SSHTarget

type SSHTarget = spec.SSHTarget

SSHTarget aliases spec.SSHTarget — the parsed "[user@]host[:port]" form.

type SecretYAML

type SecretYAML = spec.SecretYAML

type SecurityConfig

type SecurityConfig = spec.SecurityConfig

type ServiceEntry

type ServiceEntry = spec.ServiceEntry

type ServiceOverrides

type ServiceOverrides = spec.CandyServiceOverrides

type ServiceSchemaDef

type ServiceSchemaDef = spec.InitServiceSchema

type ShellConfig

type ShellConfig = spec.Shell

type ShellSpec

type ShellSpec = spec.ShellSpec

type SidecarConfig

type SidecarConfig = spec.PodSidecar

type SidecarDef

type SidecarDef = spec.SidecarDef

type SidecarSecret

type SidecarSecret = spec.SidecarSecret

type SidecarVolume

type SidecarVolume = spec.SidecarVolume

type SnapshotCreateOpts

type SnapshotCreateOpts struct {
	// VmName is the kind:vm entity name (without charly- prefix).
	VmName string

	// SnapName is the new snapshot's name.
	SnapName string

	// Mode is "external" or "internal" — empty defaults to external.
	Mode string

	// Description is an optional human note.
	Description string

	// Quiesce, when true, requests guest-agent fsfreeze before
	// snapshotting (with libvirt's plain freeze as fallback).
	Quiesce bool

	// LibvirtBackend, when non-nil, overrides the auto-detected backend.
	// Default: probe via the caller's own backend-resolve (candy/plugin-vm's
	// resolveVmBackendPlugin).
	LibvirtBackend string
}

SnapshotCreateOpts parameterizes the creation of a snapshot.

type SnapshotDeleteOpts

type SnapshotDeleteOpts struct {
	VmName   string
	SnapName string
	// Force allows deletion even when refcount > 0. Default false.
	// Recommended only when the consuming clones/ephemerals have
	// already been destroyed and the registry is stale.
	Force bool
}

SnapshotDeleteOpts parameterizes deletion.

type SnapshotEntry

type SnapshotEntry struct {
	// Name uniquely identifies the snapshot within this VM.
	Name string `json:"name"`

	// Mode is "external" or "internal".
	Mode string `json:"mode"`

	// LibvirtName is the snapshot's name as known to libvirt. For
	// external mode, libvirt registers the snapshot as a domain
	// snapshot and we store the libvirt-side identifier here. For
	// internal mode, this matches Name (qemu-img embeds the literal
	// name).
	LibvirtName string `json:"libvirt_name,omitempty"`

	// DiskPath is the absolute path to the external snapshot file.
	// Empty for internal-mode snapshots.
	DiskPath string `json:"disk_path,omitempty"`

	// Description carries the operator-supplied note.
	Description string `json:"description,omitempty"`

	// Created is the RFC3339 creation timestamp.
	Created string `json:"created,omitempty"`

	// Parent is the prior snapshot in the implicit chain at create
	// time (whichever was current then). Informational; helps trace
	// backing-chain ancestry.
	Parent string `json:"parent,omitempty"`

	// Refcount tracks active clones / ephemerals depending on this
	// snapshot. delete refuses while > 0.
	Refcount int `json:"refcount"`

	// Quiesced records whether the snapshot was taken with guest-agent
	// fsfreeze active. Informational; helps an operator decide
	// whether the snapshot is consistent.
	Quiesced bool `json:"quiesced,omitempty"`
}

SnapshotEntry is one snapshot record. Mirrors VmSnapshotState plus on-disk-only fields (the registry is internal; VmSnapshotState is the charly.yml-facing mirror).

func CreateSnapshot

func CreateSnapshot(opts SnapshotCreateOpts) (*SnapshotEntry, error)

CreateSnapshot is the mode-aware orchestrator for `charly vm snapshot create`. Looks up the active VM, dispatches to the matching mode- specific implementation, and records the result in registry.json + meta.json.

func ListSnapshots

func ListSnapshots(vmName string) ([]*SnapshotEntry, error)

ListSnapshots returns the snapshots for a VM as a name-sorted slice.

func LookupSnapshot

func LookupSnapshot(vmName, snapName string) (*SnapshotEntry, error)

LookupSnapshot returns a snapshot entry by name or an error.

func PromoteSnapshot

func PromoteSnapshot(vmName, snapName string) (*SnapshotEntry, error)

PromoteSnapshot converts an internal snapshot to external mode by extracting it via `qemu-img convert` to a new qcow2 file in the snapshots directory. After promotion, the snapshot is usable as a clone backing target. The internal snapshot inside the primary qcow2 is left in place — promote is non-destructive.

type SnapshotRegistry

type SnapshotRegistry struct {
	// Version is the registry schema version. V1 is the initial release.
	Version int `json:"version"`

	// Snapshots is the unified set of snapshots known to charly for this
	// VM, keyed by Name. Both modes appear here.
	Snapshots map[string]*SnapshotEntry `json:"snapshots"`
}

SnapshotRegistry is the on-disk schema for snapshots/registry.json. Versioned so future shape evolutions can migrate cleanly.

type Step

type Step = spec.Step

type StepKeyword

type StepKeyword = spec.StepKeyword

type TunnelYAML

type TunnelYAML = spec.TunnelYAML

type VmCharlyInstall

type VmCharlyInstall = spec.VmCharlyInstall

type VmChecksum

type VmChecksum = spec.VmChecksum

type VmCloudInit

type VmCloudInit = spec.VmCloudInit

type VmCloudInitFile

type VmCloudInitFile = spec.VmCloudInitFile

type VmCloudInitMirrors

type VmCloudInitMirrors = spec.VmCloudInitMirrors

type VmCloudInitNetwork

type VmCloudInitNetwork = spec.VmCloudInitNetwork

type VmCloudInitUser

type VmCloudInitUser = spec.VmCloudInitUser

type VmDeployState

type VmDeployState = spec.VmDeployState

type VmKeyInjection

type VmKeyInjection = spec.VmKeyInjection

type VmKeyInjectionResolved

type VmKeyInjectionResolved = spec.VmKeyInjectionResolved

type VmNetwork

type VmNetwork = spec.VmNetwork

type VmRuntimeParams

type VmRuntimeParams struct {
	// Name is the libvirt domain name / QEMU process handle.
	Name string

	// QCOW2Path is the absolute path to the VM's root qcow2 disk.
	QCOW2Path string

	// SeedISOPath is the absolute path to the NoCloud cidata ISO.
	// Empty → no cdrom attached (bootc source with cloud-init disabled).
	SeedISOPath string

	// NVRAMPath is the absolute path to the per-VM UEFI NVRAM file.
	// Empty → firmware: bios (no pflash drives emitted).
	NVRAMPath string

	// OVMFCodePath is the absolute path to the OVMF_CODE firmware image.
	// Required when Firmware == "uefi-*"; empty when bios.
	OVMFCodePath string

	// HostArch is the host architecture string (e.g. "x86_64", "aarch64").
	HostArch string

	// HostCPUVendor is "GenuineIntel" | "AuthenticAMD" | "". Used to
	// auto-append +vmx or +svm in resolveCPUDefaults when mode defaults
	// to host-passthrough and the user hasn't explicitly disabled nested
	// virt.
	HostCPUVendor string

	// SMBIOSCredentials are pre-formatted systemd-credential oemString
	// entries (e.g. "io.systemd.credential.binary:tmpfiles.extra=<b64>").
	SMBIOSCredentials []string

	// RamMB is the resolved RAM in MiB (VmSpec.Ram parsed).
	RamMB int

	// Cpus is the resolved vCPU count (VmSpec.Cpus with defaults applied).
	Cpus int

	// SshPort is the host port forwarded to guest :22.
	SshPort int

	// ExtraPortForwards are additional "host:guest" TCP forwards on
	// top of the SSH port. Used with user-mode networking.
	ExtraPortForwards []string

	// VmStateDir is the absolute path to the per-VM state directory
	// (~/.local/share/charly/vm/charly-<name>/). Used by the libvirt YAML
	// bridge to expand `{{.VmStateDir}}` template references in
	// path-bearing libvirt attributes (channel <source path=>,
	// graphics socket paths). Populated by the create-time caller
	// (vm_create_spec.go::runVmSpecCreate) so author-supplied paths
	// stay portable across users without hardcoded /home/<x>.
	VmStateDir string
}

VmRuntimeParams carries the runtime-resolved state that the libvirt-XML and QEMU-argv emitters need but isn't in the author's VmSpec: the VM name, disk paths, SSH pubkey, host architecture, host CPU vendor, etc. Both RenderDomainXML (libvirt) and RenderQEMUArgs (qemu) consume the same struct so the "rendered from a common source" invariant is preserved.

type VmSSH

type VmSSH = spec.VmSSH

type VmSnapshotDecl

type VmSnapshotDecl = spec.VmSnapshotDecl

type VmSnapshotState

type VmSnapshotState = spec.VmSnapshotState

type VmSource

type VmSource = spec.VmSource

type VmSpec

type VmSpec = spec.ResolvedVm

type VolumeYAML

type VolumeYAML = spec.VolumeYAML

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL