Skip to content

Instantly share code, notes, and snippets.

@weshayutin
Last active June 9, 2026 14:54
Show Gist options
  • Select an option

  • Save weshayutin/6a17fd71341309c5ef9fd4c656872d69 to your computer and use it in GitHub Desktop.

Select an option

Save weshayutin/6a17fd71341309c5ef9fd4c656872d69 to your computer and use it in GitHub Desktop.
kubevirt velero plugin dependency info

KubeVirt Velero Plugin - BackupItemAction and Additional Items

Searching the codebase for BackupItemAction implementations, additional-items logic, and KubeVirt GVR definitions.

Overview

Here is how the kubevirt-velero-plugin wires VM-related "additional items" for Velero backup. The design is BackupItemAction → dependency graph (kvgraph) → velero.ResourceIdentifier list, not a separate CRD/GVR registration API.


1. Plugin Registration (where BIAs are wired in)

All backup item actions are registered in main.go:

main.go (Lines 39-43):

RegisterBackupItemAction("kubevirt-velero-plugin/backup-datavolume-action", newDVBackupItemAction).
RegisterBackupItemAction("kubevirt-velero-plugin/backup-pvc-action", newPVCBackupItemAction).
RegisterBackupItemAction("kubevirt-velero-plugin/backup-volumesnapshot-action", newVolumeSnapshotBackupItemAction).
RegisterBackupItemAction("kubevirt-velero-plugin/backup-virtualmachine-action", newVMBackupItemAction).
RegisterBackupItemAction("kubevirt-velero-plugin/backup-virtualmachineinstance-action", newVMIBackupItemAction).

There is no central "register these GVRs with Velero" list beyond these BIAs and their AppliesTo() selectors.


2. GVR / GroupResource Definitions (KVObjectGraph)

Related resource types are defined as schema.GroupResource (group + resource, no version) in pkg/util/kvgraph/util.go:

util.go (Lines 36-46):

// KVObjectGraph represents the graph of objects that can be potentially related to a KubeVirt resource
var KVObjectGraph = map[string]schema.GroupResource{
    "virtualmachineinstances": {Group: "kubevirt.io", Resource: "virtualmachineinstances"},
    "datavolumes":             {Group: "cdi.kubevirt.io", Resource: "datavolumes"},
    "controllerrevisions":     {Group: "apps", Resource: "controllerrevisions"},
    "configmaps":              {Group: "", Resource: "configmaps"},
    "persistentvolumeclaims":  kuberesource.PersistentVolumeClaims,
    "serviceaccounts":         kuberesource.ServiceAccounts,
    "secrets":                 kuberesource.Secrets,
    "pods":                    kuberesource.Pods,
}

Lookup and construction of additional items happens in addVeleroResource():

util.go (Lines 48-56):

func addVeleroResource(name, namespace, resource string, resources []velero.ResourceIdentifier) []velero.ResourceIdentifier {
    if groupResource, ok := KVObjectGraph[resource]; ok {
        resources = append(resources, velero.ResourceIdentifier{
            GroupResource: groupResource,
            Namespace:     namespace,
            Name:          name,
        })
    }
    return resources
}

Note: Not in KVObjectGraph: VirtualMachineInstancePreset, VirtualMachineInstancetype, VirtualMachinePreference, VirtualMachineInstanceMigration, etc. There are zero references to "preset" under pkg/.


3. Dependency / Backup Graph Logic

Entry Points - pkg/util/kvgraph/backup_graph.go

Function Lines Purpose
NewObjectBackupGraph 32–58 Dispatches by kind (VirtualMachine, VirtualMachineInstance, DataVolume)
NewVirtualMachineBackupGraph 61–88 VM backup graph
NewVirtualMachineInstanceBackupGraph 91–110 VMI backup graph
NewDataVolumeBackupGraph 113–119 DV → PVC when phase is Succeeded

VM Graph (NewVirtualMachineBackupGraph, lines 61–88)

  • addInstanceType / addPreference → controllerrevisions
  • If vm.Status.Created: virtualmachineinstances + launcher pod
  • addCommonVMIObjectGraph on vm.Spec.Template.Spec

VMI Graph (NewVirtualMachineInstanceBackupGraph, lines 91–110)

  • Launcher pod
  • addCommonVMIObjectGraph on vmi.Spec

DataVolume Graph (NewDataVolumeBackupGraph, lines 113–119)

  • If succeeded: related persistentvolumeclaims

Shared Graph Builders - pkg/util/kvgraph/util.go

Function Lines Adds
addCommonVMIObjectGraph 59–62 Volumes + access credentials
addVolumeGraph 65–103 DVs, PVCs, memory-dump PVCs, ConfigMaps, Secrets, ServiceAccounts, cloud-init Secrets
addAccessCredentials 106–114 SSH/password Secrets
addLauncherPod 117–123 virt-launcher pod
addInstanceType 126–130 Instancetype controllerrevisions
addPreference 133–137 Preference controllerrevisions
addInstanceTypeMatcherResource 140–148 controllerrevisions from status or spec RevisionName
addBackendPVC 151–170 Persistent TPM/EFI backend PVCs
IsBackendStorageNeededForVMI 173–174 Triggers backend PVC lookup
HasPersistentTPMDevice 177–180
HasPersistentEFI 183–188

Volume-type Handling in addVolumeGraph (lines 66–95)

util.go (Lines 65-95):

func addVolumeGraph(vmiSpec v1.VirtualMachineInstanceSpec, vmName, namespace string, resources []velero.ResourceIdentifier) ([]velero.ResourceIdentifier, error) {
    for _, volume := range vmiSpec.Volumes {
        switch {
        case volume.DataVolume != nil:
            resources = addVeleroResource(volume.DataVolume.Name, namespace, "datavolumes", resources)
            resources = addVeleroResource(volume.DataVolume.Name, namespace, "persistentvolumeclaims", resources)
        case volume.PersistentVolumeClaim != nil:
            resources = addVeleroResource(volume.PersistentVolumeClaim.ClaimName, namespace, "persistentvolumeclaims", resources)
        case volume.MemoryDump != nil:
            resources = addVeleroResource(volume.MemoryDump.ClaimName, namespace, "persistentvolumeclaims", resources)
        case volume.ConfigMap != nil:
            resources = addVeleroResource(volume.ConfigMap.Name, namespace, "configmaps", resources)
        case volume.Secret != nil:
            resources = addVeleroResource(volume.Secret.SecretName, namespace, "secrets", resources)
        case volume.ServiceAccount != nil:
            resources = addVeleroResource(volume.ServiceAccount.ServiceAccountName, namespace, "serviceaccounts", resources)
        case volume.CloudInitNoCloud != nil:
            // ... userData/networkData secrets ...
        case volume.CloudInitConfigDrive != nil:
            // ... userData/networkData secrets ...
        }
    }
    // ...
}

Note: NewObjectBackupGraph exists but is only used in tests (backup_graph_test.go); production code calls the specific NewVirtualMachineBackupGraph / NewVirtualMachineInstanceBackupGraph functions directly from BIAs.


4. BackupItemAction Implementations that Return Additional Items

Velero's BIA contract: Execute(...) (runtime.Unstructured, []velero.ResourceIdentifier, error) — the second return value is the additional-items list.

A. VMBackupItemAction - pkg/plugin/vm_backup_item_action.go

Method Lines Notes
AppliesTo 55–61 IncludedResources: ["VirtualMachine"]
Execute 65–128 Calls kvgraph.NewVirtualMachineBackupGraph(vm) at 101–104, returns extra at 128
canBeSafelyBackedUp 132–158 Validates backup scope (VMI/pods/PVCs in backup spec) via util.IsResourceInBackup

B. VMIBackupItemAction - pkg/plugin/vmi_backup_item_action.go

Method Lines Notes
AppliesTo 60–66 IncludedResources: ["VirtualMachineInstance"]
Execute 70–122 Calls kvgraph.NewVirtualMachineInstanceBackupGraph(vmi) at 118, returns extra at 122

C. DVBackupItemAction - pkg/plugin/dv_backup_item_action.go

Method Lines Notes
AppliesTo 61–68 PersistentVolumeClaim, DataVolume
Execute 73–90 Dispatches by kind
handlePVC 93–121 Returns empty extra
handleDataVolume 124–148 Returns kvgraph.NewDataVolumeBackupGraph(&dv) at 146

D. BIAs that Do Not Return Additional Items

File Execute Lines Returns
pkg/plugin/pvc_backup_item_action.go 55–91 Empty extra (UID labeling only)
pkg/plugin/volumesnapshot_backup_item_action.go 79–136 Empty extra (PVC UID labeling only)

5. Backup Scope Checks (not additional items, but related)

pkg/util/util.go checks whether a resource kind is in the backup's include/exclude lists:

  • IsResourceIncluded — lines 99–112
  • IsResourceExcluded — lines 115–128
  • IsResourceInBackup — lines 145–146

Used by VM/VMI BIAs to fail or warn when, e.g., a running VM backup includes PVCs but not pods/VMI. The plugin still returns additional items even when excluded; Velero filters them (see comment in vm_backup_item_action_test.go around lines 369–370).


6. Restore-Side Graph (for completeness)

Restore uses the same kvgraph helpers but via RestoreItemAction, not backup BIAs:

  • pkg/plugin/vm_restore_item_action.go line 90: kvgraph.NewVirtualMachineRestoreGraph(vm)
  • pkg/plugin/vmi_restore_item_action.go line 105: kvgraph.NewVirtualMachineInstanceRestoreGraph(vmi)
  • Graph definitions: pkg/util/kvgraph/restore_graph.go lines 30–64

Summary: What Gets Pulled in When Backing Up a VM

When Velero backs up a VirtualMachine, VMBackupItemAction.Execute builds this transitive set (Velero then honors backup include/exclude filters):

Related Resource Group Resource How Added
VirtualMachineInstance kubevirt.io virtualmachineinstances VM graph, if status.created
virt-launcher Pod "" pods VM/VMI graph, if running
DataVolume cdi.kubevirt.io datavolumes Volume refs
PVC "" persistentvolumeclaims DV/PVC/memory-dump/backend storage
ConfigMap "" configmaps Volume refs
Secret "" secrets Volume + cloud-init + access credentials
ServiceAccount "" serviceaccounts Volume refs
ControllerRevision apps controllerrevisions Instancetype/preference matchers

Not handled by this plugin: VirtualMachineInstancePreset, instancetype/preference CRs themselves (only their controller revisions), migrations, snapshots, exports, pools, clones, etc.

If you need preset or instancetype CRs included, that would require extending KVObjectGraph and adding graph-walking logic — it does not exist today.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment