Documentation
¶
Overview ¶
Package vm is the charly plugin housing charly's VM-subsystem IMPL. It is a dual-placement plugin — the SAME NewProvider()/NewMeta()/CliMain compile INTO charly in-process when listed in compiled_plugins (the canonical placement, P10), or cmd/serve serves them OUT-OF-PROCESS when they are not. It provides TWO capabilities.
verb:libvirt — the `charly check libvirt` probe verb plus the internal VM ops (domain-state / list-domains / resolve-spice / resolve-vnc / create / start / stop / destroy / snapshot-internal / domain-xml / list-all-domains) the spice/vnc/ssh/status/preempt consumers + the vm deploy target dispatch through the registry.
command:vm — `charly vm …` (build / create / start / stop / destroy / console / ssh / snapshot / gpu / import / clone / cp-box / list), the VM lifecycle CLI. COMPILED-IN, it dispatches IN-PROC via Invoke(OpRun) (runVmCommand → kong-parse the VmCmd tree — command.go), so the handlers run in charly's OWN process and inherit charly's real stdio/TTY natively (`charly vm console` / `charly vm ssh` stay interactive). They own the CLI + the libvirt/qemu engine (in-package) and reach the host-only Mechanisms over generic seams: the config loader + deploy ledger via HostBuild("config-resolve"/"config-persist"), the VM-disk build engine via HostBuild("vm-build"), egress via verb:egress, preempt via verb:arbiter, GPU via verb:gpu.
A standalone Go module (its own go.mod) carrying the go-libvirt + kata-containers/govmm + libvirt.org/go/libvirtxml stack, compiled into charly for the canonical placement. Both capabilities are advertised in Describe (NewMeta); command:vm's grammar is prescanned into the CLI.
vmshared_aliases.go — package-main bindings onto the shared VM/cloud-init package github.com/opencharly/sdk/vmshared, imported via the go.work replace of the charly module. The 17 shared VM/libvirt/cloud-init files used to be byte-for-byte duplicated here; they now live ONCE in vmshared. These bindings keep the plugin's package-main references compiling; the init() wires the plugin-side (in-process go-libvirt) implementations of the shared package's seams.
Index ¶
- Constants
- Variables
- func BuildClone(vmName string, spec *VmSpec, _, vmStateDir string) error
- func BuildLibvirtDomainXML(spec *VmSpec, rt VmRuntimeParams) (*libvirtxml.Domain, error)
- func CliMain(_ []string) int
- func DiffImported(name, domainName string) ([]string, error)
- func EmitDiskBuildScript(layout DiskLayout) (string, string, error)
- func EnsureMachine() (string, error)
- func InjectLibvirtXML(vmName string, snippets []string) error
- func InstallHint(binary string) string
- func IsRootless() (bool, error)
- func ListUnmanagedDomains() ([]string, error)
- func MemlockLimitBytes() (soft, hard uint64)
- func NewMeta() pb.PluginMetaServer
- func NewProvider() pb.ProviderServer
- func RegenerateSeedISO(spec *VmSpec, seedPath, vmStateDir string, existingState *VmDeployState) error
- func RenderDomainXML(spec *VmSpec, rt VmRuntimeParams) (string, error)
- func ResolveNewestLocalCalVer(_, _ string) (string, error)
- func TransferImageToGuest(ctx context.Context, de DeployExecutor, hostEngine, ref, as string, ...) error
- func ValidateEgress(kind, label string, data []byte) error
- func ValidateXMLEgress(kind, label, xmlStr string) error
- func VfioGroupAccessible(group int) bool
- func VmInstanceOverridePath(domainName string) (string, error)
- func WriteVmImportDeclaration(name string, spec *VmSpec) error
- type AutoDetectFlags
- type BaseUserDef
- type BootcVMResult
- type BootstrapVMResult
- type BuilderConfig
- type BuilderDef
- type BundleNode
- type CloudImageBuildResult
- type CloudInitRuntimeParams
- type DeployExecutor
- type DiskLayout
- type DisplayEndpoint
- type DistroConfig
- type DistroDef
- type EmitOpts
- type FormatDef
- type GuestAgent
- func (a *GuestAgent) Call(cmd string, args any, out any) error
- func (a *GuestAgent) Disks() ([]GuestDisk, error)
- func (a *GuestAgent) Exec(req GuestExecRequest) (int, error)
- func (a *GuestAgent) ExecAndWait(argv []string, capture bool, pollInterval time.Duration, maxWait time.Duration) (*GuestExecStatus, error)
- func (a *GuestAgent) ExecStatus(pid int) (*GuestExecStatus, error)
- func (a *GuestAgent) FSInfo() ([]GuestFS, error)
- func (a *GuestAgent) FileRead(path string) ([]byte, error)
- func (a *GuestAgent) FileWrite(path string, data []byte) error
- func (a *GuestAgent) FsFreeze() (int, error)
- func (a *GuestAgent) FsFreezeStatus() (string, error)
- func (a *GuestAgent) FsThaw() (int, error)
- func (a *GuestAgent) FsTrim(minimumBytes uint64) error
- func (a *GuestAgent) Hostname() (string, error)
- func (a *GuestAgent) Info() (*GuestAgentInfo, error)
- func (a *GuestAgent) MemoryBlockInfo() (*GuestMemoryBlockInfo, error)
- func (a *GuestAgent) NetworkInterfaces() ([]GuestNetworkInterface, error)
- func (a *GuestAgent) OSInfo() (*GuestOSInfo, error)
- func (a *GuestAgent) Ping() error
- func (a *GuestAgent) Time() (time.Time, error)
- func (a *GuestAgent) Users() ([]GuestUser, error)
- func (a *GuestAgent) VCPUs() ([]GuestVCPU, error)
- type GuestAgentInfo
- type GuestAgentSupportedCommand
- type GuestDisk
- type GuestExecRequest
- type GuestExecStatus
- type GuestFS
- type GuestMemoryBlockInfo
- type GuestNetworkIP
- type GuestNetworkInterface
- type GuestNetworkStatistic
- type GuestOSInfo
- type GuestUser
- type GuestVCPU
- type Lease
- type LibvirtAudio
- type LibvirtCPUTune
- type LibvirtChannel
- type LibvirtClock
- type LibvirtCmd
- type LibvirtConsole
- type LibvirtConsoleCmd
- type LibvirtDevices
- type LibvirtDisk
- type LibvirtDomain
- type LibvirtDomainXMLCmd
- type LibvirtEventsCmd
- type LibvirtFeatures
- type LibvirtFilesystem
- type LibvirtGraphics
- type LibvirtGraphicsListen
- type LibvirtGraphicsListeners
- type LibvirtGuestDisksCmd
- type LibvirtGuestExecCmd
- type LibvirtGuestFileGroup
- type LibvirtGuestFileReadCmd
- type LibvirtGuestFileWriteCmd
- type LibvirtGuestFsfreezeFreezeCmd
- type LibvirtGuestFsfreezeGroup
- type LibvirtGuestFsfreezeStatusCmd
- type LibvirtGuestFsfreezeThawCmd
- type LibvirtGuestFsinfoCmd
- type LibvirtGuestFstrimCmd
- type LibvirtGuestGroup
- type LibvirtGuestHostnameCmd
- type LibvirtGuestInfoCmd
- type LibvirtGuestInterfacesCmd
- type LibvirtGuestOsInfoCmd
- type LibvirtGuestPingCmd
- type LibvirtGuestTimeCmd
- type LibvirtGuestUsersCmd
- type LibvirtGuestVcpusCmd
- type LibvirtHostdev
- type LibvirtHyperV
- type LibvirtIOMMU
- type LibvirtInfoCmd
- type LibvirtInterface
- type LibvirtKVM
- type LibvirtLaunchSecurity
- type LibvirtListCmd
- type LibvirtMemBalloon
- type LibvirtMemTune
- type LibvirtMemoryBacking
- type LibvirtNUMATune
- type LibvirtParallel
- type LibvirtPasswdCmd
- type LibvirtQmpCmd
- type LibvirtRNG
- type LibvirtRedirDev
- type LibvirtResource
- type LibvirtScreenshotCmd
- type LibvirtSecLabel
- type LibvirtSendKeyCmd
- type LibvirtSerial
- type LibvirtShmem
- type LibvirtSmartcard
- type LibvirtSnapshotCreateCmd
- type LibvirtSnapshotDeleteCmd
- type LibvirtSnapshotGroup
- type LibvirtSnapshotInfoCmd
- type LibvirtSnapshotListCmd
- type LibvirtSnapshotRevertCmd
- type LibvirtSysInfo
- type LibvirtTPM
- type LibvirtURI
- type LibvirtVendorID
- type LibvirtVideo
- type LibvirtVsock
- type Op
- type QemuRuntimePaths
- type ReadinessConfig
- type ResolvedBox
- type ResolvedGpuSelector
- type ResolvedReadiness
- type ResolvedResource
- type ResolvedRuntime
- type SSHExecutor
- type SSHTunnel
- type SnapshotCreateOpts
- type SnapshotDeleteOpts
- type SnapshotEntry
- type VFIOGpu
- type VFIOPCIDevice
- type VFIOReport
- type VmBuildCmd
- type VmCloneCmd
- type VmCloudInit
- type VmCmd
- type VmConsoleCmd
- type VmCpBoxCmd
- type VmCreateCmd
- type VmDeployState
- type VmDestroyCmd
- type VmGpuCmd
- type VmGpuListCmd
- type VmGpuModeCmd
- type VmGpuPlanCmd
- type VmGpuRecoverCmd
- type VmGpuStatusCmd
- type VmImportCmd
- type VmInstanceOverride
- type VmListCmd
- type VmNetwork
- type VmRuntimeParams
- type VmScpCmd
- type VmSnapshotCmd
- type VmSnapshotCreateCmd
- type VmSnapshotDeleteCmd
- type VmSnapshotListCmd
- type VmSnapshotPromoteCmd
- type VmSnapshotRevertCmd
- type VmSource
- type VmSpec
- type VmSshCmd
- type VmSshStanza
- type VmStartCmd
- type VmStopCmd
- type VmTarget
- func (t *VmTarget) AgentReachable(timeout time.Duration) bool
- func (t *VmTarget) Close() error
- func (t *VmTarget) EnsureRunning() error
- func (t *VmTarget) Running() (bool, error)
- func (t *VmTarget) SpiceAddress() (host string, port int, passwd string, err error)
- func (t *VmTarget) SpiceEndpoint() (DisplayEndpoint, error)
- func (t *VmTarget) VncAddress() (host string, port int, passwd string, err error)
- func (t *VmTarget) VncEndpoint() (DisplayEndpoint, error)
Constants ¶
const (
PollRemote = vmshared.PollRemote
)
const UnifiedFileName = kit.UnifiedFileName
UnifiedFileName is the project config filename ("charly.yml") — kit owns the one copy.
Variables ¶
var ( RenderCloudInit = vmshared.RenderCloudInit ResolveOvmfForSpec = vmshared.ResolveOvmfForSpec ResolveKeyInjectionChannels = vmshared.ResolveKeyInjectionChannels WriteSeedISO = vmshared.WriteSeedISO CreateSnapshot = vmshared.CreateSnapshot ListSnapshots = vmshared.ListSnapshots LookupSnapshot = vmshared.LookupSnapshot PromoteSnapshot = vmshared.PromoteSnapshot RevertSnapshot = vmshared.RevertSnapshot IncrementSnapshotRefcount = vmshared.IncrementSnapshotRefcount EnsureSshConfigInclude = kit.EnsureSshConfigInclude RemoveSshConfigInclude = kit.RemoveSshConfigInclude RemoveVmSshStanza = kit.RemoveVmSshStanza ListVmSshAliases = kit.ListVmSshAliases VmSshAlias = kit.VmSshAlias WriteVmSshStanza = kit.WriteVmSshStanza )
Function/value aliases the moved handlers reference — the shared impls live once in vmshared/kit/deploykit.
var ( DeleteSnapshot = vmshared.DeleteSnapshot ErrPollFatal = vmshared.ErrPollFatal KeyToUserTmpfilesD = vmshared.KeyToUserTmpfilesD NewSSHTunnel = sshx.NewSSHTunnel ParseLibvirtURI = vmshared.ParseLibvirtURI RegisterTempCleanup = proclifecycle.RegisterTempCleanup RenderQemuArgv = vmshared.RenderQemuArgv SmbiosCredForSSH = vmshared.SmbiosCredForSSH UnregisterTempCleanup = proclifecycle.UnregisterTempCleanup )
var DetectVFIO = func() VFIOReport { reply := gpuProbeReply(spec.GpuProbeInput{Action: "detect-vfio"}) if reply.Vfio == nil { return VFIOReport{} } return *reply.Vfio }
DetectVFIO probes the host for IOMMU readiness + passthrough-capable GPUs (var for testability).
Functions ¶
func BuildClone ¶
BuildClone is the source.kind == "clone" build path.
vmName is the new VM (the clone target). spec is its VmSpec (source.from_vm and source.from_snapshot fully populated). outputDir is where output/qcow2/disk.qcow2 + output/qcow2/seed.iso will be written, mirroring the cloud_image build path's conventions.
func BuildLibvirtDomainXML ¶
func BuildLibvirtDomainXML(spec *VmSpec, rt VmRuntimeParams) (*libvirtxml.Domain, error)
BuildLibvirtDomainXML builds a libvirtxml.Domain tree. Exposed so callers (e.g. `charly check libvirt passwd`) can mutate the tree before marshaling.
func CliMain ¶
CliMain is the OUT-OF-PROCESS command entry — unreachable in the canonical compiled-in placement. command:vm's handlers reach the host reverse channel (config-resolve/persist, egress, arbiter, gpu), which is unavailable out-of-process, so this errors (like candy/plugin-preempt's CliMain).
func DiffImported ¶
DiffImported compares the live libvirt XML against the on-disk kind:vm entry's source-derived fields and returns a human-readable list of differences. Empty list means "no drift". Each line has the shape "field: <on-disk-value> → <fresh-value>".
Schema v4 (2026-05): reads through LoadUnified so any vm.yml / vms.yml pulled in via includes: is transparent. The canonical authoring root is charly.yml.
func EmitDiskBuildScript ¶
func EmitDiskBuildScript(layout DiskLayout) (string, string, error)
EmitDiskBuildScript renders the prelude (partition + format + mount) and finalize (unmount + qcow2 convert) halves of a privileged VM disk-build script. The caller stitches them around its own rootfs install body. Returns (prelude, finalize) on success.
func EnsureMachine ¶
EnsureMachine creates and starts a podman machine named "charly" if needed. Returns the rootful connection name to use with `podman --connection`. When created with --rootful, podman creates two connections: "charly" (rootless) and "charly-root" (rootful). We return "charly-root".
func InjectLibvirtXML ¶
InjectLibvirtXML modifies a libvirt domain's XML to include the given snippets. Device elements are inserted into <devices>, others replace/insert at <domain> level.
func InstallHint ¶
InstallHint returns a best-effort, host-distro-appropriate install command for a missing binary (machine.go's gvproxy-not-found message). The curated per-binary package-name table stays a core Mechanism (`charly doctor`, embedded charly.yml install_hints:); the VM plugin has no project loader, so it emits the package-manager form derived from the live host distro (sdk/vmshared) — enough for an error hint, with no core coupling.
func IsRootless ¶
IsRootless checks if podman is running in rootless mode.
func ListUnmanagedDomains ¶
ListUnmanagedDomains returns libvirt domains that are NOT recorded in charly's vm.yml (not yet imported).
func MemlockLimitBytes ¶
func MemlockLimitBytes() (soft, hard uint64)
MemlockLimitBytes returns the process RLIMIT_MEMLOCK (soft, hard) — VFIO pins guest RAM.
func NewMeta ¶
func NewMeta() pb.PluginMetaServer
NewMeta advertises BOTH capabilities via sdk.NewMeta: verb:libvirt (the libvirt check verb, nested under `charly check` at runtime like kube/adb/appium) and command:vm (the `charly vm …` CLI). The internal VM ops (resolution / lifecycle / snapshot / create) ride Invoke via special VmOp words and are NOT Describe classes — the moved VM CLI handlers + the display/status/preempt consumers dispatch them in-package / through the registry. The verb's plugin_input validates against the served #LibvirtVerbInput (the method enum + every libvirt-exclusive modifier moved here from core #Op in the schema-compaction cutover). command:vm is COMPILED-IN and dispatched IN-PROC via Invoke(OpRun) (runVmCommand, command.go) — its grammar is prescanned into the CLI from plugin.providers.
func NewProvider ¶
func NewProvider() pb.ProviderServer
NewProvider returns the vm provider (verb:libvirt + the internal VmOp Invoke surface).
func RegenerateSeedISO ¶
func RegenerateSeedISO(spec *VmSpec, seedPath, vmStateDir string, existingState *VmDeployState) error
RegenerateSeedISO re-renders cloud-init user-data/meta-data/network-config from the current VmSpec and overwrites the seed ISO in place. Used by `charly vm create` to pick up vm.yml edits (new runcmd entries, packages, network config, etc.) without requiring a full `charly vm build` rerun.
The qcow2 disk is left untouched — only the seed ISO is regenerated, which is cheap. Reuses the stored VmDeployState.InstanceID when supplied so cloud-init still treats the VM as the same instance.
func RenderDomainXML ¶
func RenderDomainXML(spec *VmSpec, rt VmRuntimeParams) (string, error)
RenderDomainXML produces the complete libvirt domain XML for a VM from a VmSpec plus runtime parameters. Builds a libvirtxml.Domain tree and marshals it. Pure function — no filesystem, network, or libvirt calls.
func ResolveNewestLocalCalVer ¶
ResolveNewestLocalCalVer is a best-effort local-image newest-CalVer resolver for `charly vm cp-box`. The core resolver (local_image.go) queries the local podman store; the plugin has no direct store access, so this returns empty and the caller uses the ref as-authored (correct for an explicit tag). cp-box is not exercised by the vm beds; a follow-up adds a generic local-image-resolve seam for the bare-ref newest-CalVer convenience. Signature matches core's (engine, ref) -> (resolved, err).
func TransferImageToGuest ¶
func TransferImageToGuest(ctx context.Context, de DeployExecutor, hostEngine, ref, as string, rootless bool, opts EmitOpts) error
TransferImageToGuest streams a host image into a VM guest's podman storage by piping `podman save <ref>` straight into `ssh <guest> [sudo] podman load` — NO intermediate tarball on either side. (A file-based copy fails for a multi-GB image because the guest's /tmp is a size-limited tmpfs.)
rootless selects WHICH guest podman storage:
- rootless == false → ROOT storage (`sudo podman`). For a `sudo podman run --device nvidia.com/gpu=all` consumer that needs /dev/nvidia* via root.
- rootless == true → the SSH user's ROOTLESS storage (`podman`, no sudo). This is what the nested-pod-in-VM deploy needs: plugin-deploy-vm's PostApply brings the pod up with the guest user's own `charly bundle from-box` (a --user quadlet), which reads the USER's podman storage — so the image must land there, not in root's. Rootless GPU works via CDI (/dev/nvidia* are world-rw; the nvidia-driver candy's boot service writes a world-readable /etc/cdi/nvidia.yaml).
VERIFIED transfer: `podman load` can exit 0 on a TRUNCATED stream and register an image whose overlay layers are incomplete — a `podman run` then fails with `faccessat …/storage/overlay/<hash>: no such file`. So the transfer is not trusted on the load exit code alone:
- The idempotency skip fires only when the guest already holds the target ref AND that image is verified intact (a name-only check would wrongly skip a present-but-torn image — the case a disposable VM bed hits when `charly update` recreates the domain over the SAME persistent qcow2, so the guest's prior — possibly partial — image survives).
- After a fresh load, the image is probed; on the overlay-corruption signature it is dropped and re-streamed ONCE; a second failure is a hard error (surfaced, never silently shipped as a broken image).
Requires an *SSHExecutor (the VM case). The GPU check bed is the first caller.
func ValidateEgress ¶
ValidateEgress validates a cloud-init artifact (the vmshared hook, called by RegenerateSeedISO → RenderCloudInit) against the egress schema via verb:egress. Wired onto vmshared.ValidateEgress in vmshared_aliases.go's init(). Best-effort graceful-degrade outside a command context (egressValidate).
func ValidateXMLEgress ¶
ValidateXMLEgress validates a rendered libvirt domain XML against the egress schema (verb:egress).
func VfioGroupAccessible ¶
VfioGroupAccessible reports whether the user can open /dev/vfio/<group>. group<0 → no IOMMU group.
func VmInstanceOverridePath ¶
VmInstanceOverridePath returns the canonical path for a domain's instance override file. The domainName is the libvirt/qemu domain identifier (typically "charly-<vmEntityName>").
func WriteVmImportDeclaration ¶
WriteVmImportDeclaration persists a kind:vm declaration with source.kind: imported into charly.yml. Schema v4 (2026-05) makes charly.yml the only canonical authoring target; a legacy vm.yml at the project root is loaded transparently via includes: but new entries land in charly.yml.
Types ¶
type AutoDetectFlags ¶
type AutoDetectFlags struct {
NoAutoDetect bool `long:"no-autodetect" help:"Disable automatic device detection"`
}
AutoDetectFlags is the plugin-local copy of core's --no-autodetect Kong flag struct. Core keeps its own (shell/start/config_image commands embed it too), so it is NOT moved; this trivial one-field CLI-flags struct is below the bar for cross-module export (R3 — the vm_phaseA_shims trivia line).
type BaseUserDef ¶
type BaseUserDef = vmshared.BaseUserDef
vm_move_aliases.go — package-vm bindings for the shared types the VM CLI handlers (moved out of charly core, P10) reference by their core short names. charly core reaches the same identities directly as vmshared.X/buildkit.X now (K3 ZERO-ALIASES dissolved charly/buildkit_aliases.go; only charly/vmshared_aliases.go remains, itself K4/K5 dissolving inventory): the shared model lives ONCE in sdk/vmshared + sdk/buildkit; these keep the moved handlers compiling unchanged.
type BootcVMResult ¶
type BootcVMResult struct {
DiskPath string
SeedIsoPath string
InstanceID string
BaseImageSHA256 string
CloudInitDigest string
}
BootcVMResult mirrors CloudImageBuildResult / BootstrapVMResult.
func BuildBootcVM ¶
func BuildBootcVM( spec *VmSpec, outputDir, vmStateDir string, existingState *VmDeployState, imageRef string, ) (BootcVMResult, error)
BuildBootcVM creates a fresh VM disk by running `bootc install to-disk` inside a privileged container that hosts the referenced kind:image entry. The bootc image carries its own kernel + initramfs + bootloader integration, so this path skips EmitDiskBuildScript (no chroot grub-install needed). It uses RunPrivileged for the privileged container and qemu-img convert raw → qcow2 (handled by bootc). imageRef is the PRE-RESOLVED bootc image ref (host-resolved via resolveBootcImageRef — a full ref passes through, an internal kind:image short name resolves to its newest local CalVer tag, never `:latest`).
type BootstrapVMResult ¶
type BootstrapVMResult struct {
DiskPath string
SeedIsoPath string
InstanceID string
BaseImageSHA256 string
CloudInitDigest string
}
BootstrapVMResult mirrors CloudImageBuildResult so callers can branch uniformly across VM source kinds.
func BuildBootstrapVM ¶
func BuildBootstrapVM( spec *VmSpec, outputDir, vmStateDir string, existingState *VmDeployState, distro *DistroDef, builder *BuilderDef, builderRef string, ) (BootstrapVMResult, error)
BuildBootstrapVM creates a fresh VM disk by:
- Running the bootstrap builder via RunPrivileged (pacstrap / debootstrap / alpine-bootstrap → rootfs.tar.gz), against the HOST-RESOLVED builder image ref.
- Partitioning a sparse disk + extracting the rootfs + running the distro's bootloader install template inside chroot.
- Converting raw → qcow2.
- Rendering the cloud-init seed ISO when spec.CloudInit is set.
Mirrors BuildCloudImage in shape so callers can swap implementations behind the source.kind discriminator. distro is already inheritance-flattened (host-side DistroConfig.ResolveInherits) and builderRef is already resolved + built (host-side ensureBuilderImageBuilt) — this engine only drives the exec.
type BuilderConfig ¶
type BuilderConfig = buildkit.BuilderConfig
vm_move_aliases.go — package-vm bindings for the shared types the VM CLI handlers (moved out of charly core, P10) reference by their core short names. charly core reaches the same identities directly as vmshared.X/buildkit.X now (K3 ZERO-ALIASES dissolved charly/buildkit_aliases.go; only charly/vmshared_aliases.go remains, itself K4/K5 dissolving inventory): the shared model lives ONCE in sdk/vmshared + sdk/buildkit; these keep the moved handlers compiling unchanged.
type BuilderDef ¶
type BuilderDef = vmshared.BuilderDef
vm_move_aliases.go — package-vm bindings for the shared types the VM CLI handlers (moved out of charly core, P10) reference by their core short names. charly core reaches the same identities directly as vmshared.X/buildkit.X now (K3 ZERO-ALIASES dissolved charly/buildkit_aliases.go; only charly/vmshared_aliases.go remains, itself K4/K5 dissolving inventory): the shared model lives ONCE in sdk/vmshared + sdk/buildkit; these keep the moved handlers compiling unchanged.
type BundleNode ¶
Spec-type aliases the moved handlers reference by their core (package main) short names. All are canonical sdk/spec wire types (the same identity core used via its own alias surface).
type CloudImageBuildResult ¶
type CloudImageBuildResult struct {
// DiskPath is the absolute path to the output qcow2 (a COW overlay
// on top of the cached base image).
DiskPath string
// SeedIsoPath is the absolute path to the NoCloud cidata ISO.
// Empty when the renderer produced no user-data (shouldn't happen
// for cloud_image sources, but defensive).
SeedIsoPath string
// InstanceID is the stable UUIDv4 persisted into VmDeployState.
InstanceID string
// BaseImageSHA256 is the sha256 of the fetched cached qcow2.
// Useful for audit / migration detection.
BaseImageSHA256 string
// CloudInitDigest is sha256 of the rendered user-data — used by
// the vm lifecycle to detect whether the seed ISO needs regeneration
// (drift from last-recorded digest).
CloudInitDigest string
}
CloudImageBuildResult summarizes what `buildCloudImage` produced so the caller (vm_build.go) can populate output paths and record state.
func BuildCloudImage ¶
func BuildCloudImage( spec *VmSpec, outputDir, vmStateDir string, existingState *VmDeployState, force bool, ) (CloudImageBuildResult, error)
BuildCloudImage is the pipeline for preparing a cloud-image VM disk:
- Fetch the base qcow2 via kit.FetchQcow2 (resumable, sha256-verified).
- qemu-img create a copy-on-write overlay at outputDir/disk.qcow2 with the cached base as its backing file.
- qemu-img resize the overlay to spec.DiskSize (cloud-utils-growpart inside the guest expands the partition at first boot).
- Resolve VmSSH key injection channels (D13 auto-defaults) and pick the SSH public key per spec.SSH.KeySource.
- Render cloud-init via RenderCloudInit.
- Pack user-data / meta-data / network-config into outputDir/seed.iso via WriteSeedISO.
The caller (vm_build.go) passes outputDir (e.g. "output/qcow2/" from the working project tree) and vmStateDir (e.g. ~/.local/share/charly/vm/charly-<vm>/) for runtime state persistence.
Idempotent: if existingState.InstanceID is set, the same instance-id is reused so cloud-init treats the VM as the same instance and honors first-boot-only directives the way the user expects. force rebuilds the disk base even when content-fresh; the default idempotent-skips a fresh base so N concurrent beds sharing this entity (serialized on the caller's per-entity build flock) build it ONCE and the rest reuse it — never rewriting a base a live per-domain overlay backs onto (P33). (P8b-rest: ported verbatim from charly/vm_cloud_image.go.)
type CloudInitRuntimeParams ¶
type CloudInitRuntimeParams = vmshared.CloudInitRuntimeParams
vm_move_aliases.go — package-vm bindings for the shared types the VM CLI handlers (moved out of charly core, P10) reference by their core short names. charly core reaches the same identities directly as vmshared.X/buildkit.X now (K3 ZERO-ALIASES dissolved charly/buildkit_aliases.go; only charly/vmshared_aliases.go remains, itself K4/K5 dissolving inventory): the shared model lives ONCE in sdk/vmshared + sdk/buildkit; these keep the moved handlers compiling unchanged.
type DeployExecutor ¶
type DeployExecutor = deploykit.DeployExecutor
vm_move_aliases.go — package-vm bindings for the shared types the VM CLI handlers (moved out of charly core, P10) reference by their core short names. charly core reaches the same identities directly as vmshared.X/buildkit.X now (K3 ZERO-ALIASES dissolved charly/buildkit_aliases.go; only charly/vmshared_aliases.go remains, itself K4/K5 dissolving inventory): the shared model lives ONCE in sdk/vmshared + sdk/buildkit; these keep the moved handlers compiling unchanged.
type DiskLayout ¶
type DiskLayout struct {
// SizeBytesOrSuffix is the size to allocate for the raw disk file (e.g. "20G", "10240M",
// "536870912"). Forwarded verbatim to `truncate -s`.
SizeBytesOrSuffix string
// Rootfs selects the root partition filesystem: "ext4" (default), "xfs", or "btrfs".
Rootfs string
// EspSizeMib sizes the EFI System Partition (FAT32). Default 512.
EspSizeMib int
// Mnt is the absolute path inside the container where the root partition gets mounted
// (default /mnt). Bootloader install templates render against this.
Mnt string
}
DiskLayout describes a partitioned VM disk to be built inside a privileged container by EmitDiskBuildScript. Used by both the pacstrap/debootstrap VM-bootstrap path and the bootc-VM install path (where the bootloader is provided by `bootc install` rather than by chroot grub-install).
type DisplayEndpoint ¶
type DisplayEndpoint = spec.VmDisplayEndpoint
DisplayEndpoint describes how to reach one graphics channel (SPICE or VNC) of a running VM. Callers that want a raw net.Conn should pass this to Dial().
IsSocket / SocketPath are set when the resolved <listen> element is `<listen type='socket'/>`. Host / Port are set for TCP-exposed listeners. The two are mutually exclusive — libvirt picks the first listener when there are several on one <graphics>, but charly always prefers the socket when present (matches virt-manager's auto-forwarding behavior).
TunnelNeeded is true when the VmTarget was resolved over a remote libvirt URI (qemu+ssh://…); callers must open an SSH-forwarded local endpoint via charly/ssh_tunnel.go before dialing.
DisplayEndpoint is spec.VmDisplayEndpoint (Cutover B unit 2, R-E4): this was a hand-written twin of the SAME shape charly-core's decode struct duplicated independently — an SDD violation (wire types are CUE-sourced without exception). Both now retype onto the ONE generated def (sdk/schema/vmclient.cue), R3.
type DistroConfig ¶
type DistroConfig = buildkit.DistroConfig
vm_move_aliases.go — package-vm bindings for the shared types the VM CLI handlers (moved out of charly core, P10) reference by their core short names. charly core reaches the same identities directly as vmshared.X/buildkit.X now (K3 ZERO-ALIASES dissolved charly/buildkit_aliases.go; only charly/vmshared_aliases.go remains, itself K4/K5 dissolving inventory): the shared model lives ONCE in sdk/vmshared + sdk/buildkit; these keep the moved handlers compiling unchanged.
type DistroDef ¶
vm_move_aliases.go — package-vm bindings for the shared types the VM CLI handlers (moved out of charly core, P10) reference by their core short names. charly core reaches the same identities directly as vmshared.X/buildkit.X now (K3 ZERO-ALIASES dissolved charly/buildkit_aliases.go; only charly/vmshared_aliases.go remains, itself K4/K5 dissolving inventory): the shared model lives ONCE in sdk/vmshared + sdk/buildkit; these keep the moved handlers compiling unchanged.
type EmitOpts ¶
vm_move_aliases.go — package-vm bindings for the shared types the VM CLI handlers (moved out of charly core, P10) reference by their core short names. charly core reaches the same identities directly as vmshared.X/buildkit.X now (K3 ZERO-ALIASES dissolved charly/buildkit_aliases.go; only charly/vmshared_aliases.go remains, itself K4/K5 dissolving inventory): the shared model lives ONCE in sdk/vmshared + sdk/buildkit; these keep the moved handlers compiling unchanged.
type FormatDef ¶
vm_move_aliases.go — package-vm bindings for the shared types the VM CLI handlers (moved out of charly core, P10) reference by their core short names. charly core reaches the same identities directly as vmshared.X/buildkit.X now (K3 ZERO-ALIASES dissolved charly/buildkit_aliases.go; only charly/vmshared_aliases.go remains, itself K4/K5 dissolving inventory): the shared model lives ONCE in sdk/vmshared + sdk/buildkit; these keep the moved handlers compiling unchanged.
type GuestAgent ¶
type GuestAgent struct {
// contains filtered or unexported fields
}
GuestAgent is a thin typed layer over libvirt's agent command RPC.
func NewGuestAgent ¶
NewGuestAgent wraps an open libvirt connection + domain.
func (*GuestAgent) Call ¶
func (a *GuestAgent) Call(cmd string, args any, out any) error
Call sends a JSON-RPC-style command and unmarshals the reply into `out` (which may be nil to ignore). `args` may be nil if the command takes no arguments.
func (*GuestAgent) Disks ¶
func (a *GuestAgent) Disks() ([]GuestDisk, error)
func (*GuestAgent) Exec ¶
func (a *GuestAgent) Exec(req GuestExecRequest) (int, error)
func (*GuestAgent) ExecAndWait ¶
func (a *GuestAgent) ExecAndWait(argv []string, capture bool, pollInterval time.Duration, maxWait time.Duration) (*GuestExecStatus, error)
ExecAndWait runs a command and polls until it completes or ctx expires.
func (*GuestAgent) ExecStatus ¶
func (a *GuestAgent) ExecStatus(pid int) (*GuestExecStatus, error)
func (*GuestAgent) FSInfo ¶
func (a *GuestAgent) FSInfo() ([]GuestFS, error)
func (*GuestAgent) FileRead ¶
func (a *GuestAgent) FileRead(path string) ([]byte, error)
FileRead reads a guest file via guest-file-open / guest-file-read / guest-file-close. Returns the concatenated contents (base64-decoded).
func (*GuestAgent) FileWrite ¶
func (a *GuestAgent) FileWrite(path string, data []byte) error
FileWrite writes `data` to a guest file (truncating). Uses guest-file-open / guest-file-write / guest-file-close.
func (*GuestAgent) FsFreeze ¶
func (a *GuestAgent) FsFreeze() (int, error)
FsFreeze freezes all guest filesystems (transactional snapshots). Returns the number of frozen filesystems.
func (*GuestAgent) FsFreezeStatus ¶
func (a *GuestAgent) FsFreezeStatus() (string, error)
FsFreezeStatus returns "thawed" or "frozen".
func (*GuestAgent) FsTrim ¶
func (a *GuestAgent) FsTrim(minimumBytes uint64) error
FsTrim issues TRIM/discard on all mounts.
func (*GuestAgent) Hostname ¶
func (a *GuestAgent) Hostname() (string, error)
Hostname returns the guest's hostname.
func (*GuestAgent) Info ¶
func (a *GuestAgent) Info() (*GuestAgentInfo, error)
func (*GuestAgent) MemoryBlockInfo ¶
func (a *GuestAgent) MemoryBlockInfo() (*GuestMemoryBlockInfo, error)
func (*GuestAgent) NetworkInterfaces ¶
func (a *GuestAgent) NetworkInterfaces() ([]GuestNetworkInterface, error)
func (*GuestAgent) OSInfo ¶
func (a *GuestAgent) OSInfo() (*GuestOSInfo, error)
func (*GuestAgent) Time ¶
func (a *GuestAgent) Time() (time.Time, error)
Time returns the guest's clock in nanoseconds since UNIX epoch.
func (*GuestAgent) Users ¶
func (a *GuestAgent) Users() ([]GuestUser, error)
func (*GuestAgent) VCPUs ¶
func (a *GuestAgent) VCPUs() ([]GuestVCPU, error)
type GuestAgentInfo ¶
type GuestAgentInfo struct {
Version string `json:"version"`
SupportedCommands []GuestAgentSupportedCommand `json:"supported_commands"`
}
Info returns the agent's supported command list.
type GuestDisk ¶
type GuestDisk struct {
Name string `json:"name"`
Partition bool `json:"partition,omitempty"`
Alias string `json:"alias,omitempty"`
BusType string `json:"bus-type,omitempty"`
Serial string `json:"serial,omitempty"`
Dependents []string `json:"dependents,omitempty"`
}
Disks returns the guest's block devices (QGA >= 5.2).
type GuestExecRequest ¶
type GuestExecRequest struct {
Path string `json:"path"`
Arg []string `json:"arg,omitempty"`
Env []string `json:"env,omitempty"`
InputData string `json:"input-data,omitempty"`
CaptureOutput bool `json:"capture-output,omitempty"`
}
Exec runs a command in the guest. `capture` is whether to capture stdout/stderr. Returns the PID immediately; use ExecStatus to poll.
type GuestExecStatus ¶
type GuestExecStatus struct {
Exited bool `json:"exited"`
ExitCode int `json:"exitcode,omitempty"`
Signal int `json:"signal,omitempty"`
OutData string `json:"out-data,omitempty"`
ErrData string `json:"err-data,omitempty"`
OutTruncated bool `json:"out-truncated,omitempty"`
ErrTruncated bool `json:"err-truncated,omitempty"`
}
ExecStatus polls an exec result. `Exited` indicates whether the command finished.
type GuestFS ¶
type GuestFS struct {
Name string `json:"name"`
Mountpoint string `json:"mountpoint"`
Type string `json:"type"`
UsedBytes uint64 `json:"used-bytes,omitempty"`
TotalBytes uint64 `json:"total-bytes,omitempty"`
Disk []map[string]any `json:"disk,omitempty"`
}
FSInfo returns mounted filesystem info.
type GuestMemoryBlockInfo ¶
type GuestMemoryBlockInfo struct {
Size uint64 `json:"size"`
}
MemoryBlockInfo returns guest memory hotplug state.
type GuestNetworkIP ¶
type GuestNetworkInterface ¶
type GuestNetworkInterface struct {
Name string `json:"name"`
HardwareAddress string `json:"hardware-address"`
IPAddresses []GuestNetworkIP `json:"ip-addresses"`
Statistics *GuestNetworkStatistic `json:"statistics,omitempty"`
}
NetworkInterfaces returns the guest's network interfaces.
type GuestNetworkStatistic ¶
type GuestNetworkStatistic struct {
RxBytes uint64 `json:"rx-bytes"`
RxPackets uint64 `json:"rx-packets"`
RxErrs uint64 `json:"rx-errs"`
RxDropped uint64 `json:"rx-dropped"`
TxBytes uint64 `json:"tx-bytes"`
TxPackets uint64 `json:"tx-packets"`
TxErrs uint64 `json:"tx-errs"`
TxDropped uint64 `json:"tx-dropped"`
}
type GuestOSInfo ¶
type GuestOSInfo struct {
ID string `json:"id"`
Name string `json:"name"`
PrettyName string `json:"pretty-name"`
Version string `json:"version"`
VersionID string `json:"version-id"`
KernelRelease string `json:"kernel-release"`
KernelVersion string `json:"kernel-version"`
Machine string `json:"machine"`
Variant string `json:"variant,omitempty"`
VariantID string `json:"variant-id,omitempty"`
}
OSInfo returns guest OS identification.
type GuestUser ¶
type GuestUser struct {
User string `json:"user"`
Domain string `json:"domain,omitempty"`
LoginTime float64 `json:"login-time"`
}
Users returns the list of logged-in users.
type GuestVCPU ¶
type GuestVCPU struct {
LogicalID uint `json:"logical-id"`
Online bool `json:"online"`
CanOffline bool `json:"can-offline"`
}
VCPUs returns guest-side vCPU online state.
type Lease ¶
type Lease struct {
// contains filtered or unexported fields
}
Lease is the acquire result (minimal — mirrors core's shape for the callers that ignore it).
type LibvirtAudio ¶
type LibvirtAudio = vmshared.LibvirtAudio
type LibvirtCPUTune ¶
type LibvirtCPUTune = vmshared.LibvirtCPUTune
type LibvirtChannel ¶
type LibvirtChannel = vmshared.LibvirtChannel
type LibvirtClock ¶
type LibvirtClock = vmshared.LibvirtClock
type LibvirtCmd ¶
type LibvirtCmd struct {
// Top-level verbs
List LibvirtListCmd `cmd:"" help:"List all libvirt domains on the session"`
Info LibvirtInfoCmd `cmd:"" help:"Show domain state, graphics, uptime"`
Screenshot LibvirtScreenshotCmd `cmd:"" help:"Capture VM framebuffer via DomainScreenshot"`
SendKey LibvirtSendKeyCmd `cmd:"" name:"send-key" help:"Inject keyboard events via DomainSendKey (alt path)"`
Passwd LibvirtPasswdCmd `cmd:"" help:"Set live graphics password (SPICE/VNC)"`
Qmp LibvirtQmpCmd `cmd:"" help:"Send raw QMP command to the domain"`
DomainXML LibvirtDomainXMLCmd `cmd:"" name:"domain-xml" help:"Dump the live domain XML"`
Console LibvirtConsoleCmd `cmd:"" help:"Tail serial console"`
Events LibvirtEventsCmd `cmd:"" help:"Watch domain lifecycle events"`
// Subgroups
Guest LibvirtGuestGroup `cmd:"" help:"qemu-guest-agent client (ping/info/exec/file/fsfreeze)"`
Snapshot LibvirtSnapshotGroup `cmd:"" help:"VM snapshots (list/create/revert/delete)"`
}
LibvirtCmd groups all libvirt-RPC test verbs.
type LibvirtConsole ¶
type LibvirtConsole = vmshared.LibvirtConsole
type LibvirtConsoleCmd ¶
type LibvirtConsoleCmd struct {
Vm string `arg:"" help:"VM name"`
Duration time.Duration `long:"duration" default:"5s" help:"Stream for this duration, then exit"`
// contains filtered or unexported fields
}
func (*LibvirtConsoleCmd) Run ¶
func (c *LibvirtConsoleCmd) Run() error
type LibvirtDevices ¶
type LibvirtDevices = vmshared.LibvirtDevices
type LibvirtDisk ¶
type LibvirtDisk = vmshared.LibvirtDisk
type LibvirtDomain ¶
type LibvirtDomain = vmshared.LibvirtDomain
type LibvirtDomainXMLCmd ¶
type LibvirtDomainXMLCmd struct {
Vm string `arg:"" help:"VM name"`
Config bool `long:"config" help:"Get inactive (on-disk) config instead of live"`
// contains filtered or unexported fields
}
func (*LibvirtDomainXMLCmd) Run ¶
func (c *LibvirtDomainXMLCmd) Run() error
type LibvirtEventsCmd ¶
type LibvirtEventsCmd struct {
Vm string `arg:"" optional:"" help:"VM name (empty = all domains)"`
Duration time.Duration `long:"duration" default:"10s" help:"Watch for this long"`
// contains filtered or unexported fields
}
func (*LibvirtEventsCmd) Run ¶
func (c *LibvirtEventsCmd) Run() error
type LibvirtFeatures ¶
type LibvirtFeatures = vmshared.LibvirtFeatures
type LibvirtFilesystem ¶
type LibvirtFilesystem = vmshared.LibvirtFilesystem
type LibvirtGraphics ¶
type LibvirtGraphics = vmshared.LibvirtGraphics
type LibvirtGraphicsListen ¶
type LibvirtGraphicsListen = vmshared.LibvirtGraphicsListen
type LibvirtGraphicsListeners ¶
type LibvirtGraphicsListeners = vmshared.LibvirtGraphicsListeners
type LibvirtGuestDisksCmd ¶
type LibvirtGuestDisksCmd struct {
Vm string `arg:"" help:"VM name"`
// contains filtered or unexported fields
}
func (*LibvirtGuestDisksCmd) Run ¶
func (c *LibvirtGuestDisksCmd) Run() error
type LibvirtGuestExecCmd ¶
type LibvirtGuestExecCmd struct {
Vm string `arg:"" help:"VM name"`
Argv []string `arg:"" help:"Command and arguments (e.g. 'uname -a')"`
Capture bool `long:"capture" default:"true" help:"Capture stdout/stderr"`
Wait time.Duration `long:"wait" default:"60s" help:"Max wait for command to complete"`
// contains filtered or unexported fields
}
func (*LibvirtGuestExecCmd) Run ¶
func (c *LibvirtGuestExecCmd) Run() error
type LibvirtGuestFileGroup ¶
type LibvirtGuestFileGroup struct {
Read LibvirtGuestFileReadCmd `cmd:"" help:"Read a guest file"`
Write LibvirtGuestFileWriteCmd `cmd:"" help:"Write a guest file (from stdin)"`
}
type LibvirtGuestFileReadCmd ¶
type LibvirtGuestFileReadCmd struct {
Vm string `arg:"" help:"VM name"`
Path string `arg:"" help:"Absolute path in guest"`
// contains filtered or unexported fields
}
func (*LibvirtGuestFileReadCmd) Run ¶
func (c *LibvirtGuestFileReadCmd) Run() error
type LibvirtGuestFileWriteCmd ¶
type LibvirtGuestFileWriteCmd struct {
Vm string `arg:"" help:"VM name"`
Path string `arg:"" help:"Absolute path in guest"`
// contains filtered or unexported fields
}
func (*LibvirtGuestFileWriteCmd) Run ¶
func (c *LibvirtGuestFileWriteCmd) Run() error
type LibvirtGuestFsfreezeFreezeCmd ¶
type LibvirtGuestFsfreezeFreezeCmd struct {
Vm string `arg:"" help:"VM name"`
// contains filtered or unexported fields
}
func (*LibvirtGuestFsfreezeFreezeCmd) Run ¶
func (c *LibvirtGuestFsfreezeFreezeCmd) Run() error
type LibvirtGuestFsfreezeGroup ¶
type LibvirtGuestFsfreezeGroup struct {
Status LibvirtGuestFsfreezeStatusCmd `cmd:"" help:"Report freeze status"`
Freeze LibvirtGuestFsfreezeFreezeCmd `cmd:"" help:"Freeze all filesystems"`
Thaw LibvirtGuestFsfreezeThawCmd `cmd:"" help:"Thaw frozen filesystems"`
}
type LibvirtGuestFsfreezeStatusCmd ¶
type LibvirtGuestFsfreezeStatusCmd struct {
Vm string `arg:"" help:"VM name"`
// contains filtered or unexported fields
}
func (*LibvirtGuestFsfreezeStatusCmd) Run ¶
func (c *LibvirtGuestFsfreezeStatusCmd) Run() error
type LibvirtGuestFsfreezeThawCmd ¶
type LibvirtGuestFsfreezeThawCmd struct {
Vm string `arg:"" help:"VM name"`
// contains filtered or unexported fields
}
func (*LibvirtGuestFsfreezeThawCmd) Run ¶
func (c *LibvirtGuestFsfreezeThawCmd) Run() error
type LibvirtGuestFsinfoCmd ¶
type LibvirtGuestFsinfoCmd struct {
Vm string `arg:"" help:"VM name"`
// contains filtered or unexported fields
}
func (*LibvirtGuestFsinfoCmd) Run ¶
func (c *LibvirtGuestFsinfoCmd) Run() error
type LibvirtGuestFstrimCmd ¶
type LibvirtGuestFstrimCmd struct {
Vm string `arg:"" help:"VM name"`
Minimum int `long:"minimum" default:"0" help:"Minimum extent size in bytes"`
// contains filtered or unexported fields
}
func (*LibvirtGuestFstrimCmd) Run ¶
func (c *LibvirtGuestFstrimCmd) Run() error
type LibvirtGuestGroup ¶
type LibvirtGuestGroup struct {
Ping LibvirtGuestPingCmd `cmd:"" help:"Ping qemu-guest-agent"`
Info LibvirtGuestInfoCmd `cmd:"" help:"Show agent capabilities"`
OsInfo LibvirtGuestOsInfoCmd `cmd:"" name:"os-info" help:"Guest OS information"`
Time LibvirtGuestTimeCmd `cmd:"" help:"Guest clock time"`
Hostname LibvirtGuestHostnameCmd `cmd:"" help:"Guest hostname"`
Users LibvirtGuestUsersCmd `cmd:"" help:"Logged-in users"`
Interfaces LibvirtGuestInterfacesCmd `cmd:"" help:"Network interfaces + IPs"`
Disks LibvirtGuestDisksCmd `cmd:"" help:"Guest-visible disks"`
Fsinfo LibvirtGuestFsinfoCmd `cmd:"" name:"fsinfo" help:"Mounted filesystems"`
Vcpus LibvirtGuestVcpusCmd `cmd:"" help:"Guest-side vCPU state"`
Exec LibvirtGuestExecCmd `cmd:"" help:"Run a command via guest-exec"`
File LibvirtGuestFileGroup `cmd:"" help:"Read/write guest files"`
Fsfreeze LibvirtGuestFsfreezeGroup `cmd:"" help:"Filesystem freeze control"`
Fstrim LibvirtGuestFstrimCmd `cmd:"" help:"Run TRIM on guest filesystems"`
}
type LibvirtGuestHostnameCmd ¶
type LibvirtGuestHostnameCmd struct {
Vm string `arg:"" help:"VM name"`
// contains filtered or unexported fields
}
func (*LibvirtGuestHostnameCmd) Run ¶
func (c *LibvirtGuestHostnameCmd) Run() error
type LibvirtGuestInfoCmd ¶
type LibvirtGuestInfoCmd struct {
Vm string `arg:"" help:"VM name"`
// contains filtered or unexported fields
}
func (*LibvirtGuestInfoCmd) Run ¶
func (c *LibvirtGuestInfoCmd) Run() error
type LibvirtGuestInterfacesCmd ¶
type LibvirtGuestInterfacesCmd struct {
Vm string `arg:"" help:"VM name"`
// contains filtered or unexported fields
}
func (*LibvirtGuestInterfacesCmd) Run ¶
func (c *LibvirtGuestInterfacesCmd) Run() error
type LibvirtGuestOsInfoCmd ¶
type LibvirtGuestOsInfoCmd struct {
Vm string `arg:"" help:"VM name"`
// contains filtered or unexported fields
}
func (*LibvirtGuestOsInfoCmd) Run ¶
func (c *LibvirtGuestOsInfoCmd) Run() error
type LibvirtGuestPingCmd ¶
type LibvirtGuestPingCmd struct {
Vm string `arg:"" help:"VM name"`
Timeout time.Duration `long:"timeout" default:"5s" help:"Max wait"`
// contains filtered or unexported fields
}
func (*LibvirtGuestPingCmd) Run ¶
func (c *LibvirtGuestPingCmd) Run() error
type LibvirtGuestTimeCmd ¶
type LibvirtGuestTimeCmd struct {
Vm string `arg:"" help:"VM name"`
// contains filtered or unexported fields
}
func (*LibvirtGuestTimeCmd) Run ¶
func (c *LibvirtGuestTimeCmd) Run() error
type LibvirtGuestUsersCmd ¶
type LibvirtGuestUsersCmd struct {
Vm string `arg:"" help:"VM name"`
// contains filtered or unexported fields
}
func (*LibvirtGuestUsersCmd) Run ¶
func (c *LibvirtGuestUsersCmd) Run() error
type LibvirtGuestVcpusCmd ¶
type LibvirtGuestVcpusCmd struct {
Vm string `arg:"" help:"VM name"`
// contains filtered or unexported fields
}
func (*LibvirtGuestVcpusCmd) Run ¶
func (c *LibvirtGuestVcpusCmd) Run() error
type LibvirtHostdev ¶
type LibvirtHostdev = vmshared.LibvirtHostdev
type LibvirtHyperV ¶
type LibvirtHyperV = vmshared.LibvirtHyperV
type LibvirtIOMMU ¶
type LibvirtIOMMU = vmshared.LibvirtIOMMU
type LibvirtInfoCmd ¶
type LibvirtInfoCmd struct {
Vm string `arg:"" help:"VM name (vm.yml entity)"`
Format string `long:"format" default:"text" help:"Output format: text, json"`
// contains filtered or unexported fields
}
func (*LibvirtInfoCmd) Run ¶
func (c *LibvirtInfoCmd) Run() error
type LibvirtInterface ¶
type LibvirtInterface = vmshared.LibvirtInterface
type LibvirtKVM ¶
type LibvirtKVM = vmshared.LibvirtKVM
type LibvirtLaunchSecurity ¶
type LibvirtLaunchSecurity = vmshared.LibvirtLaunchSecurity
type LibvirtListCmd ¶
type LibvirtListCmd struct {
Format string `long:"format" default:"text" help:"Output format: text, json"`
// contains filtered or unexported fields
}
func (*LibvirtListCmd) Run ¶
func (c *LibvirtListCmd) Run() error
type LibvirtMemBalloon ¶
type LibvirtMemBalloon = vmshared.LibvirtMemBalloon
type LibvirtMemTune ¶
type LibvirtMemTune = vmshared.LibvirtMemTune
type LibvirtMemoryBacking ¶
type LibvirtMemoryBacking = vmshared.LibvirtMemoryBacking
type LibvirtNUMATune ¶
type LibvirtNUMATune = vmshared.LibvirtNUMATune
type LibvirtParallel ¶
type LibvirtParallel = vmshared.LibvirtParallel
type LibvirtPasswdCmd ¶
type LibvirtPasswdCmd struct {
Vm string `arg:"" help:"VM name"`
Password string `arg:"" optional:"" help:"Password (empty = prompt or stdin)"`
Type string `long:"type" default:"spice" help:"Graphics type: spice or vnc"`
Persist bool `long:"persistent" help:"Also persist to inactive config (default: live only)"`
// contains filtered or unexported fields
}
func (*LibvirtPasswdCmd) Run ¶
func (c *LibvirtPasswdCmd) Run() error
type LibvirtQmpCmd ¶
type LibvirtQmpCmd struct {
Vm string `arg:"" help:"VM name"`
Command string `arg:"" help:"QMP command name (e.g. query-status)"`
Args string `arg:"" optional:"" help:"JSON args (optional)"`
// contains filtered or unexported fields
}
func (*LibvirtQmpCmd) Run ¶
func (c *LibvirtQmpCmd) Run() error
type LibvirtRNG ¶
type LibvirtRNG = vmshared.LibvirtRNG
type LibvirtRedirDev ¶
type LibvirtRedirDev = vmshared.LibvirtRedirDev
type LibvirtResource ¶
type LibvirtResource = vmshared.LibvirtResource
type LibvirtScreenshotCmd ¶
type LibvirtScreenshotCmd struct {
Vm string `arg:"" help:"VM name"`
File string `arg:"" optional:"" default:"screenshot.png" help:"Output file path (use '-' for stdout)"`
Screen int `long:"screen" default:"0" help:"Display index for multi-head VMs"`
// contains filtered or unexported fields
}
func (*LibvirtScreenshotCmd) Run ¶
func (c *LibvirtScreenshotCmd) Run() error
type LibvirtSecLabel ¶
type LibvirtSecLabel = vmshared.LibvirtSecLabel
type LibvirtSendKeyCmd ¶
type LibvirtSendKeyCmd struct {
Vm string `arg:"" help:"VM name"`
Keys []string `arg:"" help:"Key names (space-separated, e.g. 'ctrl alt F2')"`
Hold int `long:"hold" default:"50" help:"Hold duration in ms"`
// contains filtered or unexported fields
}
func (*LibvirtSendKeyCmd) Run ¶
func (c *LibvirtSendKeyCmd) Run() error
type LibvirtSerial ¶
type LibvirtSerial = vmshared.LibvirtSerial
type LibvirtShmem ¶
type LibvirtShmem = vmshared.LibvirtShmem
type LibvirtSmartcard ¶
type LibvirtSmartcard = vmshared.LibvirtSmartcard
type LibvirtSnapshotCreateCmd ¶
type LibvirtSnapshotCreateCmd struct {
Vm string `arg:"" help:"VM name"`
Name string `arg:"" help:"Snapshot name"`
Desc string `long:"desc" help:"Description"`
DiskOnly bool `long:"disk-only" help:"Disk-only snapshot (skip memory)"`
// contains filtered or unexported fields
}
func (*LibvirtSnapshotCreateCmd) Run ¶
func (c *LibvirtSnapshotCreateCmd) Run() error
type LibvirtSnapshotDeleteCmd ¶
type LibvirtSnapshotDeleteCmd struct {
Vm string `arg:"" help:"VM name"`
Name string `arg:"" help:"Snapshot name"`
// contains filtered or unexported fields
}
func (*LibvirtSnapshotDeleteCmd) Run ¶
func (c *LibvirtSnapshotDeleteCmd) Run() error
type LibvirtSnapshotGroup ¶
type LibvirtSnapshotGroup struct {
List LibvirtSnapshotListCmd `cmd:"" help:"List snapshots"`
Create LibvirtSnapshotCreateCmd `cmd:"" help:"Create a snapshot"`
Info LibvirtSnapshotInfoCmd `cmd:"" help:"Show snapshot XML"`
Revert LibvirtSnapshotRevertCmd `cmd:"" help:"Revert to a snapshot"`
Delete LibvirtSnapshotDeleteCmd `cmd:"" help:"Delete a snapshot"`
}
type LibvirtSnapshotInfoCmd ¶
type LibvirtSnapshotInfoCmd struct {
Vm string `arg:"" help:"VM name"`
Name string `arg:"" help:"Snapshot name"`
// contains filtered or unexported fields
}
func (*LibvirtSnapshotInfoCmd) Run ¶
func (c *LibvirtSnapshotInfoCmd) Run() error
type LibvirtSnapshotListCmd ¶
type LibvirtSnapshotListCmd struct {
Vm string `arg:"" help:"VM name"`
// contains filtered or unexported fields
}
func (*LibvirtSnapshotListCmd) Run ¶
func (c *LibvirtSnapshotListCmd) Run() error
type LibvirtSnapshotRevertCmd ¶
type LibvirtSnapshotRevertCmd struct {
Vm string `arg:"" help:"VM name"`
Name string `arg:"" help:"Snapshot name"`
// contains filtered or unexported fields
}
func (*LibvirtSnapshotRevertCmd) Run ¶
func (c *LibvirtSnapshotRevertCmd) Run() error
type LibvirtSysInfo ¶
type LibvirtSysInfo = vmshared.LibvirtSysInfo
type LibvirtTPM ¶
type LibvirtTPM = vmshared.LibvirtTPM
type LibvirtURI ¶
type LibvirtURI = vmshared.LibvirtURI
type LibvirtVendorID ¶
type LibvirtVendorID = vmshared.LibvirtVendorID
type LibvirtVideo ¶
type LibvirtVideo = vmshared.LibvirtVideo
type LibvirtVsock ¶
type LibvirtVsock = vmshared.LibvirtVsock
type QemuRuntimePaths ¶
type QemuRuntimePaths = vmshared.QemuRuntimePaths
type ReadinessConfig ¶
type ReadinessConfig = vmshared.ReadinessConfig
type ResolvedBox ¶
type ResolvedBox = buildkit.ResolvedBox
vm_move_aliases.go — package-vm bindings for the shared types the VM CLI handlers (moved out of charly core, P10) reference by their core short names. charly core reaches the same identities directly as vmshared.X/buildkit.X now (K3 ZERO-ALIASES dissolved charly/buildkit_aliases.go; only charly/vmshared_aliases.go remains, itself K4/K5 dissolving inventory): the shared model lives ONCE in sdk/vmshared + sdk/buildkit; these keep the moved handlers compiling unchanged.
type ResolvedGpuSelector ¶
type ResolvedGpuSelector = spec.ResolvedGpuSelector
Spec-type aliases the moved handlers reference by their core (package main) short names. All are canonical sdk/spec wire types (the same identity core used via its own alias surface).
type ResolvedReadiness ¶
type ResolvedReadiness = vmshared.ResolvedReadiness
type ResolvedResource ¶
type ResolvedResource = spec.ResolvedResource
Spec-type aliases the moved handlers reference by their core (package main) short names. All are canonical sdk/spec wire types (the same identity core used via its own alias surface).
type ResolvedRuntime ¶
type ResolvedRuntime = kit.ResolvedRuntime
vm_move_aliases.go — package-vm bindings for the shared types the VM CLI handlers (moved out of charly core, P10) reference by their core short names. charly core reaches the same identities directly as vmshared.X/buildkit.X now (K3 ZERO-ALIASES dissolved charly/buildkit_aliases.go; only charly/vmshared_aliases.go remains, itself K4/K5 dissolving inventory): the shared model lives ONCE in sdk/vmshared + sdk/buildkit; these keep the moved handlers compiling unchanged.
type SSHExecutor ¶
type SSHExecutor = kit.SSHExecutor
vm_move_aliases.go — package-vm bindings for the shared types the VM CLI handlers (moved out of charly core, P10) reference by their core short names. charly core reaches the same identities directly as vmshared.X/buildkit.X now (K3 ZERO-ALIASES dissolved charly/buildkit_aliases.go; only charly/vmshared_aliases.go remains, itself K4/K5 dissolving inventory): the shared model lives ONCE in sdk/vmshared + sdk/buildkit; these keep the moved handlers compiling unchanged.
type SnapshotCreateOpts ¶
type SnapshotCreateOpts = vmshared.SnapshotCreateOpts
type SnapshotDeleteOpts ¶
type SnapshotDeleteOpts = vmshared.SnapshotDeleteOpts
vm_move_aliases.go — package-vm bindings for the shared types the VM CLI handlers (moved out of charly core, P10) reference by their core short names. charly core reaches the same identities directly as vmshared.X/buildkit.X now (K3 ZERO-ALIASES dissolved charly/buildkit_aliases.go; only charly/vmshared_aliases.go remains, itself K4/K5 dissolving inventory): the shared model lives ONCE in sdk/vmshared + sdk/buildkit; these keep the moved handlers compiling unchanged.
type SnapshotEntry ¶
type SnapshotEntry = vmshared.SnapshotEntry
type VFIOGpu ¶
vm_move_aliases.go — package-vm bindings for the shared types the VM CLI handlers (moved out of charly core, P10) reference by their core short names. charly core reaches the same identities directly as vmshared.X/buildkit.X now (K3 ZERO-ALIASES dissolved charly/buildkit_aliases.go; only charly/vmshared_aliases.go remains, itself K4/K5 dissolving inventory): the shared model lives ONCE in sdk/vmshared + sdk/buildkit; these keep the moved handlers compiling unchanged.
type VFIOPCIDevice ¶
type VFIOPCIDevice = spec.VFIOPCIDevice
Spec-type aliases the moved handlers reference by their core (package main) short names. All are canonical sdk/spec wire types (the same identity core used via its own alias surface).
type VFIOReport ¶
type VFIOReport = spec.VFIOReport
Spec-type aliases the moved handlers reference by their core (package main) short names. All are canonical sdk/spec wire types (the same identity core used via its own alias surface).
type VmBuildCmd ¶
type VmBuildCmd struct {
Box string `arg:"" help:"Bootc image name"`
Size string `long:"size" help:"Override disk size (e.g. 20G, '20 GiB')"`
RootSize string `long:"root-size" help:"Override root partition size (e.g. 10G)"`
Tag string `long:"tag" help:"Image tag override"`
Type string `long:"type" default:"qcow2" help:"Output format: qcow2, raw"`
Transport string `long:"transport" help:"Image transport: registry, containers-storage, oci, oci-archive"`
Console bool `long:"console" help:"Enable console output for debugging"`
Force bool `` /* 308-byte string literal not displayed */
}
vm_build.go — the command:vm `charly vm build` DRIVE (P8b-rest: the disk-build ENGINE moved HERE from charly core — the same inversion candy/plugin-build's podman DRIVE already went through behind HostBuild("build-prep") in P8b). The host resolves the kind:vm entity + the build vocabulary + the per-source-kind image refs into the spec.VmBuildReply envelope (HostBuild("vm-build") — LoadUnified, LoadBuildConfigForBox, resolveBootcImageRef, ensureBuilderImageBuilt are loader + box-store Mechanisms a sdk-only candy cannot run); this command runs the actual privileged-container / qemu-img / bootc-install / cloud-init exec itself and prints its own progress to the shared stdio (compiled-in, so os.Stderr is the operator's terminal).
func (*VmBuildCmd) Run ¶
func (c *VmBuildCmd) Run() error
type VmCloneCmd ¶
type VmCloneCmd struct {
// Name is the new VM name (kind:vm entity key).
Name string `arg:"" help:"New VM name"`
// From is the source VM, optionally with @snapshot. Forms:
// --from arch → clone from arch's current state (auto-snapshot)
// --from arch@baseline → clone from arch's "baseline" snapshot
From string `long:"from" required:"" help:"Source VM, optionally @snapshot (e.g. arch@baseline)"`
// CloudInitClean injects cloud-init clean --machine-id into the
// clone's user-data. Default true for ad-hoc clones (so two clones
// don't collide on machine-id).
CloudInitClean bool `long:"cloud-init-clean" default:"true" help:"Regenerate machine-id and SSH host keys on first boot"`
// Build, when true, also runs `charly vm build` after writing vm.yml.
Build bool `long:"build" default:"true" help:"After writing vm.yml, run charly vm build to materialize the clone disk"`
}
VmCloneCmd implements `charly vm clone <new> --from <src>[@<snap>]`.
type VmCloudInit ¶
type VmCloudInit = vmshared.VmCloudInit
vm_move_aliases.go — package-vm bindings for the shared types the VM CLI handlers (moved out of charly core, P10) reference by their core short names. charly core reaches the same identities directly as vmshared.X/buildkit.X now (K3 ZERO-ALIASES dissolved charly/buildkit_aliases.go; only charly/vmshared_aliases.go remains, itself K4/K5 dissolving inventory): the shared model lives ONCE in sdk/vmshared + sdk/buildkit; these keep the moved handlers compiling unchanged.
type VmCmd ¶
type VmCmd struct {
Build VmBuildCmd `cmd:"" help:"Build QCOW2/RAW disk image from bootc container"`
Clone VmCloneCmd `cmd:"" help:"Clone a new VM from another VM's snapshot (writes a kind:vm declaration)"`
Console VmConsoleCmd `cmd:"" help:"Attach to VM serial console"`
CpImage VmCpBoxCmd `cmd:"" name:"cp-box" help:"Load a host image into a running VM guest's podman storage"`
Create VmCreateCmd `cmd:"" help:"Create a VM from a disk image"`
Destroy VmDestroyCmd `cmd:"" help:"Remove VM definition and optionally delete disk"`
Gpu VmGpuCmd `cmd:"" help:"Inspect host VFIO/GPU-passthrough readiness (status, list)"`
Import VmImportCmd `cmd:"" help:"Adopt an existing libvirt-managed VM into charly configuration"`
List VmListCmd `cmd:"" help:"List VMs and their status"`
Scp VmScpCmd `cmd:"" help:"Copy a local file into a running VM guest over SSH"`
Snapshot VmSnapshotCmd `cmd:"" help:"Manage VM snapshots (create, list, delete, revert, promote)"`
Ssh VmSshCmd `cmd:"" help:"SSH into a VM"`
Start VmStartCmd `cmd:"" help:"Start a VM"`
Stop VmStopCmd `cmd:"" help:"Stop a VM (graceful shutdown)"`
}
VmCmd groups VM management subcommands.
type VmConsoleCmd ¶
type VmConsoleCmd struct {
Box string `arg:"" help:"Box name"`
Instance string `short:"i" long:"instance" help:"Instance name"`
Domain string `` /* 157-byte string literal not displayed */
}
func (*VmConsoleCmd) Run ¶
func (c *VmConsoleCmd) Run() error
type VmCpBoxCmd ¶
type VmCpBoxCmd struct {
VM string `arg:"" help:"kind:vm entity name (uses its managed charly-<name> ssh alias)"`
Image string `arg:"" help:"image ref (short name or full ref) present in host podman storage"`
As string `long:"as" help:"after load, tag the image in the guest under this stable ref (e.g. localhost/charly-selkies-kde:latest)"`
Rootless bool `` /* 168-byte string literal not displayed */
}
VmCpBoxCmd loads a locally-built container image into a running VM guest's podman storage via `podman save | scp | podman load`. This is the host→guest delivery path for images that are NOT on a registry — the case the nested-pod-in-VM capability hits: plugin-deploy-vm's PostApply host-builds a nested pod's image (e.g. `cachyos.selkies-kde-nvidia`), cp-boxes it in as `localhost/charly-<child>:latest`, then the guest's own `charly bundle from-box` brings it up as a persistent quadlet — all offline, no registry.
Idempotent: skips the transfer when the guest already has the image.
func (*VmCpBoxCmd) Run ¶
func (c *VmCpBoxCmd) Run() error
type VmCreateCmd ¶
type VmCreateCmd struct {
Box string `arg:"" help:"Box name"`
Ram string `long:"ram" help:"Override RAM size (e.g. 4G, 8192M)"`
Cpus int `long:"cpus" help:"Override CPU count"`
Instance string `short:"i" long:"instance" help:"Instance name"`
Domain string `` /* 304-byte string literal not displayed */
SshKey string `long:"ssh-key" default:"auto" help:"SSH public key: path to .pub file, 'auto' (default ~/.ssh key), 'generate', or 'none'"`
AutoDetectFlags `embed:""`
}
VmCreateCmd creates a VM from a QCOW2 disk image.
func (*VmCreateCmd) Run ¶
func (c *VmCreateCmd) Run() error
type VmDeployState ¶
type VmDeployState = vmshared.VmDeployState
vm_move_aliases.go — package-vm bindings for the shared types the VM CLI handlers (moved out of charly core, P10) reference by their core short names. charly core reaches the same identities directly as vmshared.X/buildkit.X now (K3 ZERO-ALIASES dissolved charly/buildkit_aliases.go; only charly/vmshared_aliases.go remains, itself K4/K5 dissolving inventory): the shared model lives ONCE in sdk/vmshared + sdk/buildkit; these keep the moved handlers compiling unchanged.
type VmDestroyCmd ¶
type VmDestroyCmd struct {
Box string `arg:"" help:"Box name"`
Instance string `short:"i" long:"instance" help:"Instance name"`
Domain string `` /* 157-byte string literal not displayed */
Disk bool `long:"disk" help:"Also delete the QCOW2 disk image"`
KeepDeploy bool `long:"keep-deploy" help:"Keep the charly.yml vm:<name> entry (default: remove it, like 'charly remove' for pods)"`
IfExists bool `long:"if-exists" help:"Succeed silently when the domain is already absent, while still cleaning managed metadata"`
}
func (*VmDestroyCmd) Run ¶
func (c *VmDestroyCmd) Run() error
type VmGpuCmd ¶
type VmGpuCmd struct {
Status VmGpuStatusCmd `cmd:"" help:"Report host IOMMU readiness for GPU passthrough"`
List VmGpuListCmd `cmd:"" help:"List passthrough-capable GPUs and emit a ready-to-paste hostdevs block"`
Mode VmGpuModeCmd `cmd:"" help:"Show or set the GPU driver mode: vfio (VM passthrough) | nvidia (shared CDI pods)"`
Plan VmGpuPlanCmd `cmd:"" help:"DRY-RUN: print the exact host commands a mode flip WOULD run, without touching sysfs"`
Recover VmGpuRecoverCmd `` /* 136-byte string literal not displayed */
}
VmGpuCmd groups the host-side VFIO/GPU-passthrough inspection + mode verbs.
type VmGpuListCmd ¶
type VmGpuListCmd struct{}
VmGpuListCmd lists each GPU plus a ready-to-paste hostdevs YAML block.
func (*VmGpuListCmd) Run ¶
func (c *VmGpuListCmd) Run() error
type VmGpuModeCmd ¶
type VmGpuModeCmd struct {
Mode string `arg:"" optional:"" help:"Target mode: vfio (passthrough) | nvidia (CDI pods). Omit to SHOW the current mode."`
Vendor string `long:"vendor" default:"0x10de" help:"PCI vendor of the GPU to switch (default 0x10de = NVIDIA)."`
}
VmGpuModeCmd shows or sets the host GPU driver mode for a vendor-matched card. This is the manual operator interface for the vfio<->nvidia switch (the charly-CLI way, vs ad-hoc sysfs). The arbiter (charly/preempt.go) flips automatically for requires_exclusive (vfio) / requires_shared (nvidia) claims; this verb is the explicit override + inspector. It does NOT consult the arbiter ledger — a manual flip while an exclusive lease is active is the operator's call. The flip switches the WHOLE IOMMU group (display + audio), never just the display function (see candy/plugin-gpu/switch.go).
func (*VmGpuModeCmd) Run ¶
func (c *VmGpuModeCmd) Run() error
type VmGpuPlanCmd ¶
type VmGpuPlanCmd struct {
Mode string `arg:"" optional:"" default:"vfio" help:"Mode to preview: vfio (passthrough) | nvidia (CDI pods). Default vfio."`
Vendor string `` /* 143-byte string literal not displayed */
}
VmGpuPlanCmd is the DRY-RUN preview of the vfio<->nvidia driver switch: it prints the EXACT host rebind commands `charly vm gpu mode <mode>` would run, WITHOUT touching sysfs (cutover C9, the driver-switch dispatch proof). It uses the vendor-matched card when one is present, else a documented synthetic example card — so it is completely cred/hardware-free and works on a GPU-less host (the check-step assertion the R10 bed makes).
func (*VmGpuPlanCmd) Run ¶
func (c *VmGpuPlanCmd) Run() error
type VmGpuRecoverCmd ¶
type VmGpuRecoverCmd struct {
Vendor string `long:"vendor" default:"0x10de" help:"PCI vendor of the GPU to recover (default 0x10de = NVIDIA)."`
}
VmGpuRecoverCmd recovers a card left UNBOUND or half-switched (e.g. an interrupted flip) back to the clean vfio-pci default — but ONLY when the card is NOT wedged. A read-only probe detects a true device_lock wedge (an nvidia `.remove` stuck in D-state) FIRST; on a wedge it reports reboot-required and attempts NOTHING (a bind on a wedged device would add a second permanent D-state). On a healthy/unbound card it rebinds the whole IOMMU group to vfio-pci and clears any stale poison marker.
func (*VmGpuRecoverCmd) Run ¶
func (c *VmGpuRecoverCmd) Run() error
type VmGpuStatusCmd ¶
type VmGpuStatusCmd struct{}
VmGpuStatusCmd reports whether the host is configured for VFIO passthrough.
func (*VmGpuStatusCmd) Run ¶
func (c *VmGpuStatusCmd) Run() error
type VmImportCmd ¶
type VmImportCmd struct {
// Domain is the libvirt domain name to import. Empty when --all
// or --list is set.
Domain string `` /* 146-byte string literal not displayed */
// TargetName overrides the vm.yml entry key. Default: domain name
// with any "charly-" prefix stripped.
TargetName string `long:"target-name" help:"Override the kind:vm entry name in vm.yml"`
// All adopts every libvirt domain not already in vm.yml.
All bool `long:"all" help:"Adopt every unmanaged libvirt domain"`
// List shows libvirt domains absent from vm.yml without writing
// anything. Diagnostic mode.
List bool `long:"list" help:"Show libvirt domains absent from vm.yml; do not write"`
// ShowDrift, used with --list, marks entries whose libvirt XML
// has diverged from the on-disk vm.yml entry.
ShowDrift bool `long:"show-drift" help:"With --list: mark entries whose libvirt XML diverges from vm.yml"`
// Update re-reads libvirt XML for an existing entry and overwrites
// only source-derived fields, preserving operator-authored
// sub-mappings (snapshots, cloud_init, ssh, libvirt). Compatible
// with --diff (preview without writing).
Update bool `long:"update" help:"Re-read libvirt XML and update an existing kind:vm entry in place"`
// Diff prints the field-level differences between libvirt XML and
// the on-disk vm.yml entry, without writing.
Diff bool `long:"diff" help:"Print drift between libvirt XML and vm.yml without writing"`
// ReplaceLibvirt, used with --update, drops the operator-authored
// libvirt: block (defaults preserve it).
ReplaceLibvirt bool `long:"replace-libvirt" help:"With --update: also overwrite the operator-authored libvirt: block"`
}
VmImportCmd implements `charly vm import {<domain>, --all, --list}` plus the reverse-sync surface (`--update`, `--diff`, `--show-drift`).
type VmInstanceOverride ¶
type VmInstanceOverride struct {
// Disposable, when non-nil, overrides the upstream classification
// for the libvirt domain at this path. Pointer-typed to
// distinguish "absent" from "explicit false".
Disposable *bool `yaml:"disposable,omitempty" json:"disposable,omitempty"`
// Lifecycle, when non-empty, overrides the upstream lifecycle tag.
Lifecycle string `yaml:"lifecycle,omitempty" json:"lifecycle,omitempty"`
// Libvirt, when non-nil, is a per-host device overlay merged into the
// VmSpec at create time (ApplyToVmSpec). Uses the SAME schema as a
// `kind: vm` entity's `libvirt:` block, but only the host-specific
// device categories are merged: `devices.hostdevs` (PCI passthrough —
// the address is host-specific) and `devices.filesystems` (virtiofs
// shares rooted at an absolute host path). Both APPEND to whatever the
// portable repo `vm.yml` already declares, so the committed entity
// carries no host-specific identity.
Libvirt *LibvirtDomain `yaml:"libvirt,omitempty" json:"libvirt,omitempty"`
}
VmInstanceOverride is the operator-side per-libvirt-domain override file. Lives at ~/.local/share/charly/vm/<domain-name>/instance.yml — a sibling to the SSH key, NVRAM, and console socket already kept there. The presence of this file lets an operator override the project-level VM classification for their specific instance without modifying the project's charly.yml or vm.yml.
The override carries `disposable:` / `lifecycle:` (the two fields that gate `charly update <vm-entity>`) AND a `libvirt:` block — a per-host libvirt device overlay, using the SAME schema as a `kind: vm` entity's `libvirt:` block, merged into the VmSpec at `charly vm create`. This is where HOST-SPECIFIC device config lives: a PCI `<hostdev>` (the GPU's bus/slot address is host-specific) and a virtiofs `<filesystem>` share rooted at an absolute host path (e.g. /home/<operator>). Keeping these in the home overlay — never the committed `vm.yml` — lets the project's VM entities stay PORTABLE (no PCI address, no operator-home path baked into version control) while this host attaches its real GPU + shares for a live run. Future fields (per-instance ports, env, add_candy) can be added without breaking the on-disk format because yaml.v3 unknown-keys defaults to forgiving.
Pointer to bool for Disposable lets the loader distinguish "field absent → use upstream classification" from "field set to false → override-explicit no". A bare bool would conflate the two.
Use case: project charly.yml's arch-vm has disposable: true. An operator who wants to use the arch-vm bed for a long-running experiment can write
~/.local/share/charly/vm/charly-arch/instance.yml: disposable: false lifecycle: long-running
and the AUTONOMOUS rebuild path (the check-runner / R10 discipline) then treats the domain as non-disposable and skips it — protecting the experiment from an unattended destroy, with no need to edit the project's charly.yml or stash a different lifecycle tag in version control. (An explicit `charly update arch` still obeys, printing a transparency note: the disposable flag gates autonomy, not the verb.)
func LoadVmInstanceOverride ¶
func LoadVmInstanceOverride(domainName string) (*VmInstanceOverride, error)
LoadVmInstanceOverride reads the per-domain override file and returns a parsed VmInstanceOverride. Returns (nil, nil) when the file doesn't exist (the common case — most operators don't override). Returns (nil, error) when the file exists but is unreadable or contains invalid YAML — silent fall-through there would mask real config problems.
func (*VmInstanceOverride) ApplyToVmClassification ¶
func (o *VmInstanceOverride) ApplyToVmClassification(disposable bool, lifecycle string) (bool, string)
ApplyToVmClassification merges an override on top of an upstream (disposable, lifecycle) pair. When the override is nil or empty, returns the upstream pair unchanged. When set, the override wins.
Centralised here so every caller (the `charly update` VM-entity path, future commands that want per-instance classification) gets the same semantics.
func (*VmInstanceOverride) ApplyToVmSpec ¶
func (o *VmInstanceOverride) ApplyToVmSpec(spec *VmSpec)
ApplyToVmSpec merges the override's per-host `libvirt:` device overlay onto spec IN PLACE, called by runVmSpecCreate before the domain XML is rendered. Only the HOST-SPECIFIC device categories are merged — `devices.hostdevs` (PCI passthrough, a host-specific bus/slot address) and `devices.filesystems` (virtiofs shares rooted at an absolute host path) — and they APPEND to whatever the portable repo vm.yml already declares. This is what lets the committed `kind: vm` entity stay free of any PCI address or operator-home path: the project ships the portable shape, the operator's home overlay supplies this host's GPU + shares.
Nil override or nil overlay → no-op (the common case). spec.Libvirt / spec.Libvirt.Devices are created on demand so an entity that declares no libvirt block at all still receives the overlay. Other libvirt fields in the overlay are intentionally ignored — host-specific config is exactly the passthrough device + the host-path share, nothing else.
type VmListCmd ¶
type VmRuntimeParams ¶
type VmRuntimeParams = vmshared.VmRuntimeParams
type VmScpCmd ¶
type VmScpCmd struct {
VM string `arg:"" help:"kind:vm entity name (uses its managed charly-<name> ssh alias)"`
Src string `arg:"" help:"local source file to copy into the guest (a leading ~ resolves against the host $HOME)"`
Dst string `arg:"" help:"destination path in the guest (a leading ~ resolves against the guest user's $HOME)"`
}
VmScpCmd copies a single LOCAL file into a running VM guest over SSH — the arbitrary-file analogue of `charly vm cp-box` (cp-box streams a whole container image; scp copies one file). It resolves the guest SSH endpoint the SAME way `charly vm ssh` / `charly vm cp-box` do (the managed charly-<name> ssh_config alias, via sshParamsForVm), so no host/port/key plumbing is needed, and a leading `~` in the destination resolves against the guest user's $HOME (faithful scp semantics).
type VmSnapshotCmd ¶
type VmSnapshotCmd struct {
Create VmSnapshotCreateCmd `cmd:"" help:"Create a snapshot of a VM (external by default; internal with --mode internal)"`
List VmSnapshotListCmd `cmd:"" help:"List snapshots for a VM"`
Delete VmSnapshotDeleteCmd `cmd:"" help:"Delete a snapshot (refuses while clones/ephemerals reference it)"`
Revert VmSnapshotRevertCmd `cmd:"" help:"Revert a VM to a snapshot"`
Promote VmSnapshotPromoteCmd `cmd:"" help:"Convert an internal snapshot to external mode (extracts via qemu-img convert)"`
}
VmSnapshotCmd is the parent of `charly vm snapshot`.
type VmSnapshotCreateCmd ¶
type VmSnapshotCreateCmd struct {
Vm string `arg:"" help:"VM name (kind:vm entity)"`
Name string `arg:"" help:"Snapshot name"`
Mode string `` /* 157-byte string literal not displayed */
Description string `long:"description" help:"Human-facing description of the snapshot"`
Quiesce bool `long:"quiesce" help:"Flush guest state via guest-agent fsfreeze before snapshotting (falls back to libvirt's plain freeze)"`
}
VmSnapshotCreateCmd implements `charly vm snapshot create <vm> <name>`.
func (*VmSnapshotCreateCmd) Run ¶
func (c *VmSnapshotCreateCmd) Run() error
Run executes `charly vm snapshot create`.
type VmSnapshotDeleteCmd ¶
type VmSnapshotDeleteCmd struct {
Vm string `arg:"" help:"VM name"`
Name string `arg:"" help:"Snapshot name"`
Force bool `long:"force" help:"Delete even when refcount > 0 (only safe after destroying consumers)"`
}
VmSnapshotDeleteCmd implements `charly vm snapshot delete <vm> <name>`.
func (*VmSnapshotDeleteCmd) Run ¶
func (c *VmSnapshotDeleteCmd) Run() error
type VmSnapshotListCmd ¶
type VmSnapshotListCmd struct {
Vm string `arg:"" help:"VM name"`
JSON bool `long:"json" help:"Emit JSON instead of a table"`
}
VmSnapshotListCmd implements `charly vm snapshot list <vm>`.
func (*VmSnapshotListCmd) Run ¶
func (c *VmSnapshotListCmd) Run() error
type VmSnapshotPromoteCmd ¶
type VmSnapshotPromoteCmd struct {
Vm string `arg:"" help:"VM name"`
Name string `arg:"" help:"Snapshot name (must be mode=internal)"`
}
VmSnapshotPromoteCmd implements `charly vm snapshot promote <vm> <name>`.
func (*VmSnapshotPromoteCmd) Run ¶
func (c *VmSnapshotPromoteCmd) Run() error
type VmSnapshotRevertCmd ¶
type VmSnapshotRevertCmd struct {
Vm string `arg:"" help:"VM name"`
Name string `arg:"" help:"Snapshot name"`
}
VmSnapshotRevertCmd implements `charly vm snapshot revert <vm> <name>`.
func (*VmSnapshotRevertCmd) Run ¶
func (c *VmSnapshotRevertCmd) Run() error
type VmSpec ¶
func ImportFromLibvirt ¶
ImportFromLibvirt reads the domain XML for `domainName`, maps it onto a VmSpec, and returns the (name, spec) pair ready to be written into vm.yml. The targetName argument lets the caller override the vm.yml entry key (default: domain name).
func UpdateImportedVm ¶
UpdateImportedVm re-reads the libvirt XML for the named domain and overwrites only the source-derived fields on the matching vm.yml entry, preserving operator-authored sub-mappings (snapshots:, cloud_init:, ssh:, libvirt: by default — pass --replace-libvirt to overwrite). Returns the updated spec for caller-side reporting.
Field-merge semantics (see /charly-internals:libvirt-renderer "VM adoption"):
- source.{libvirt_name,disk_path,disk_format} → replaced from XML
- source.adopted_at → preserved (first-import timestamp)
- source.last_synced_at → set to NOW
- ram, cpus, machine, firmware, network.mode → replaced from XML
- snapshots:, cloud_init:, ssh:, libvirt: → preserved by default
type VmSshCmd ¶
type VmSshCmd struct {
Box string `arg:"" help:"Box name"`
Instance string `short:"i" long:"instance" help:"Instance name"`
Port int `short:"p" long:"port" help:"Override the host SSH port (default: resolved from the managed ssh_config alias)"`
User string `short:"l" long:"user" help:"Override the SSH username (default: resolved from the managed ssh_config alias)"`
Args []string `arg:"" optional:"" help:"Additional SSH arguments or command"`
}
type VmSshStanza ¶
type VmSshStanza = kit.VmSshStanza
vm_move_aliases.go — package-vm bindings for the shared types the VM CLI handlers (moved out of charly core, P10) reference by their core short names. charly core reaches the same identities directly as vmshared.X/buildkit.X now (K3 ZERO-ALIASES dissolved charly/buildkit_aliases.go; only charly/vmshared_aliases.go remains, itself K4/K5 dissolving inventory): the shared model lives ONCE in sdk/vmshared + sdk/buildkit; these keep the moved handlers compiling unchanged.
type VmStartCmd ¶
type VmStartCmd struct {
Box string `arg:"" help:"Box name"`
Instance string `short:"i" long:"instance" help:"Instance name"`
Domain string `` /* 153-byte string literal not displayed */
}
func (*VmStartCmd) Run ¶
func (c *VmStartCmd) Run() error
type VmStopCmd ¶
type VmTarget ¶
type VmTarget struct {
Conn *libvirtConn // shared connection wrapper
Domain libvirt.Domain // libvirt handle
XML *libvirtxml.Domain // parsed live XML
Spec *VmSpec // vm.yml entity
VmName string // vm.yml key
DomName string // libvirt domain name (typically "charly-<vmName>")
Uri string // libvirt URI used to resolve this target (empty = local)
}
VmTarget holds an open libvirt connection to a running VM plus its parsed runtime XML. Callers are responsible for calling Close.
func ResolveVmTarget ¶
ResolveVmTarget opens a libvirt connection (local by default or remote when uri is qemu+ssh://…) and resolves the running domain for a vm.yml entity. Caller must Close() the returned target.
The domain-name convention matches `charly vm start`: "charly-<vmName>". For entity names already prefixed with "charly-" (rare), the prefix is not doubled. Pass uri == "" for the default local qemu:///session. ResolveVmTarget connects to the VM's running libvirt domain and parses its live XML. It does NOT load charly.yml: the old impl loaded the project only to populate VmTarget.Spec, which NO caller ever reads, and the domain lookup below already validates the VM exists. (The plugin is out-of-process and cannot reach core's project loader anyway — host-passes-data principle.)
func (*VmTarget) AgentReachable ¶
AgentReachable probes qemu-guest-agent with a guest-ping command. Returns true if the agent responds within the timeout. Useful as a cheap pre-flight check before `guest exec`/`guest info`/etc.
func (*VmTarget) EnsureRunning ¶
EnsureRunning returns an error if the domain is not running.
func (*VmTarget) SpiceAddress ¶
SpiceAddress returns the TCP form of the SPICE endpoint — provided for existing callers that don't understand socket listeners. Use SpiceEndpoint() for new code. Returns an error if the endpoint is socket-only (no TCP fallback).
func (*VmTarget) SpiceEndpoint ¶
func (t *VmTarget) SpiceEndpoint() (DisplayEndpoint, error)
SpiceEndpoint walks the domain XML and returns the SPICE graphics endpoint (socket or TCP) with tunneling requirements annotated.
Errors:
- no <graphics type='spice'/> in domain
- graphics present but no listener has resolved (port==0 for TCP, or libvirt hasn't populated a socket= attribute yet)
func (*VmTarget) VncAddress ¶
VncAddress is the TCP-only counterpart of SpiceAddress.
func (*VmTarget) VncEndpoint ¶
func (t *VmTarget) VncEndpoint() (DisplayEndpoint, error)
VncEndpoint is the VNC counterpart of SpiceEndpoint.
Source Files
¶
- command.go
- display_gate_sentinel.go
- egress_stub.go
- gpu_allocate.go
- libvirt.go
- libvirt_cmd.go
- libvirt_guest_agent.go
- libvirt_methods.go
- libvirt_ops.go
- libvirt_yaml_bridge.go
- machine.go
- plugin.go
- provider.go
- readiness_config.go
- vm.go
- vm_arbiter_shim.go
- vm_bootc_engine.go
- vm_bootstrap_engine.go
- vm_build.go
- vm_clone.go
- vm_clone_cmd.go
- vm_cloud_image.go
- vm_cp_box.go
- vm_create_orchestrate.go
- vm_create_spec.go
- vm_disk_layout.go
- vm_egress_shim.go
- vm_engine_direct.go
- vm_gpu_cmd.go
- vm_gpu_shim.go
- vm_host_seams.go
- vm_import.go
- vm_import_cmd.go
- vm_instance_override.go
- vm_libvirt.go
- vm_move_aliases.go
- vm_phaseA_shims.go
- vm_qemu.go
- vm_scp.go
- vm_snapshot_command.go
- vm_snapshot_internal.go
- vm_snapshot_libvirt.go
- vm_target.go
- vm_util_copies.go
- vm_util_shims.go
- vmshared_aliases.go