Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,6 @@ replace github.com/vmware-tanzu/velero => github.com/openshift/velero v0.10.2-0.

exclude github.com/kcp-dev/kcp/sdk v0.0.0-00010101000000-000000000000

replace github.com/migtools/kubevirt-datamover-controller => github.com/migtools/kubevirt-datamover-controller v0.0.0-20260729163752-37185892c605
replace github.com/migtools/kubevirt-datamover-controller => github.com/migtools/kubevirt-datamover-controller v0.0.0-20260904191729-4f588ce7dc71

replace github.com/vmware-tanzu/velero/pkg/apis => github.com/openshift/velero/pkg/apis v0.0.0-20260805134104-2091b09b93bb
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,8 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.21 h1:xYae+lCNBP7QuW4PUnNG61ffM4hVIfm+zUzDuSzYLGs=
github.com/mattn/go-isatty v0.0.21/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
github.com/migtools/kubevirt-datamover-controller v0.0.0-20260729163752-37185892c605 h1:6+jbDzfKRShcU1cp7TVrw8ZY/Ub9cAa7n5Geh6q55rk=
github.com/migtools/kubevirt-datamover-controller v0.0.0-20260729163752-37185892c605/go.mod h1:zOlAYRuAi5zbxJEfB/RPJaS//T3UdxPi86o6uWJwDds=
github.com/migtools/kubevirt-datamover-controller v0.0.0-20260904191729-4f588ce7dc71 h1:qmD1V7wBfZJWx4F9XXps5wmEsxTKFN3ZDXwLlCt/IDA=
github.com/migtools/kubevirt-datamover-controller v0.0.0-20260904191729-4f588ce7dc71/go.mod h1:iSmvYsXVwyOvelmwFM7kr9WZzlbycW6IbG57pJdioqo=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
Expand Down
30 changes: 28 additions & 2 deletions kubevirt-datamover-plugin/vm/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ func (p *BackupPlugin) createDataUpload(vm *kvcore.VirtualMachine, backup *veler
Labels: map[string]string{
velerov1.BackupNameLabel: controllercommon.SafeLabelValue(backup.Name),
},
Annotations: buildDataUploadAnnotations(vm, operationID),
Annotations: buildDataUploadAnnotations(vm, backup, operationID),
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: "velero.io/v1",
Expand Down Expand Up @@ -894,7 +894,7 @@ func (p *BackupPlugin) patchDataUploadCancel(namespace, name string, cancel bool
// buildDataUploadAnnotations constructs the annotation map for a DataUpload CR.
// It includes required controller annotations and propagates optional per-VM
// annotations (like backup-pvc-size) from the VM to the DataUpload.
func buildDataUploadAnnotations(vm *kvcore.VirtualMachine, operationID string) map[string]string {
func buildDataUploadAnnotations(vm *kvcore.VirtualMachine, backup *velerov1.Backup, operationID string) map[string]string {
annotations := map[string]string{
controllercommon.AnnotationVMName: vm.Name,
controllercommon.AnnotationVMNamespace: vm.Namespace,
Expand All @@ -909,6 +909,32 @@ func buildDataUploadAnnotations(vm *kvcore.VirtualMachine, operationID string) m
}
}

// Handle SkipQuiesce annotation
effectiveSkipVal := ""

// Check VM annotation first
if vm.Annotations != nil {
if val, ok := vm.Annotations[controllercommon.AnnotationSkipQuiesce]; ok {
if val == "true" || val == "false" || val == "auto" {
effectiveSkipVal = val
}
}
}

// Fallback to Backup annotation if VM annotation is absent or invalid
if effectiveSkipVal == "" && backup.Annotations != nil {
if val, ok := backup.Annotations[controllercommon.AnnotationSkipQuiesce]; ok {
if val == "true" || val == "false" || val == "auto" {
effectiveSkipVal = val
}
}
}

// Only set on DataUpload if the effective value is "true" or "false"
if effectiveSkipVal == "true" || effectiveSkipVal == "false" {
annotations[controllercommon.AnnotationSkipQuiesce] = effectiveSkipVal
}

return annotations
}

Expand Down
121 changes: 118 additions & 3 deletions kubevirt-datamover-plugin/vm/backup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1627,6 +1627,7 @@ func vmToUnstructured(t *testing.T, vm *kvcore.VirtualMachine) runtime.Unstructu

func TestBuildDataUploadAnnotations(t *testing.T) {
operationID := "test-op-123"
dummyBackup := &velerov1.Backup{}

t.Run("includes required annotations", func(t *testing.T) {
vm := &kvcore.VirtualMachine{
Expand All @@ -1636,7 +1637,7 @@ func TestBuildDataUploadAnnotations(t *testing.T) {
},
}

annotations := buildDataUploadAnnotations(vm, operationID)
annotations := buildDataUploadAnnotations(vm, dummyBackup, operationID)

assert.Equal(t, "my-vm", annotations[controllercommon.AnnotationVMName])
assert.Equal(t, "my-ns", annotations[controllercommon.AnnotationVMNamespace])
Expand All @@ -1655,7 +1656,7 @@ func TestBuildDataUploadAnnotations(t *testing.T) {
},
}

annotations := buildDataUploadAnnotations(vm, operationID)
annotations := buildDataUploadAnnotations(vm, dummyBackup, operationID)

assert.Equal(t, "50Gi", annotations["kubevirt-datamover.io/backup-pvc-size"])
assert.Equal(t, "my-vm", annotations[controllercommon.AnnotationVMName])
Expand All @@ -1672,8 +1673,122 @@ func TestBuildDataUploadAnnotations(t *testing.T) {
},
}

annotations := buildDataUploadAnnotations(vm, operationID)
annotations := buildDataUploadAnnotations(vm, dummyBackup, operationID)

assert.NotContains(t, annotations, "kubevirt-datamover.io/backup-pvc-size")
})

t.Run("sets SkipQuiesce from VM when true", func(t *testing.T) {
vm := &kvcore.VirtualMachine{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
controllercommon.AnnotationSkipQuiesce: "true",
},
},
}
annotations := buildDataUploadAnnotations(vm, dummyBackup, operationID)
assert.Equal(t, "true", annotations[controllercommon.AnnotationSkipQuiesce])
})

t.Run("sets SkipQuiesce from VM when false", func(t *testing.T) {
vm := &kvcore.VirtualMachine{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
controllercommon.AnnotationSkipQuiesce: "false",
},
},
}
backup := &velerov1.Backup{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
controllercommon.AnnotationSkipQuiesce: "true", // Should be ignored because VM explicitly set it to false
},
},
}
annotations := buildDataUploadAnnotations(vm, backup, operationID)
assert.Equal(t, "false", annotations[controllercommon.AnnotationSkipQuiesce])
})

t.Run("does not set SkipQuiesce when VM is auto", func(t *testing.T) {
vm := &kvcore.VirtualMachine{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
controllercommon.AnnotationSkipQuiesce: "auto",
},
},
}
backup := &velerov1.Backup{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
controllercommon.AnnotationSkipQuiesce: "true", // Should be ignored because VM explicitly set it to auto
},
},
}
annotations := buildDataUploadAnnotations(vm, backup, operationID)
assert.NotContains(t, annotations, controllercommon.AnnotationSkipQuiesce)
})

t.Run("falls back to Backup when VM annotation is invalid", func(t *testing.T) {
vm := &kvcore.VirtualMachine{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
controllercommon.AnnotationSkipQuiesce: "invalid-value",
},
},
}
backup := &velerov1.Backup{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
controllercommon.AnnotationSkipQuiesce: "true",
},
},
}
annotations := buildDataUploadAnnotations(vm, backup, operationID)
assert.Equal(t, "true", annotations[controllercommon.AnnotationSkipQuiesce])
})

t.Run("sets SkipQuiesce from Backup when VM annotation is absent", func(t *testing.T) {
vm := &kvcore.VirtualMachine{}
backup := &velerov1.Backup{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
controllercommon.AnnotationSkipQuiesce: "false",
},
},
}
annotations := buildDataUploadAnnotations(vm, backup, operationID)
assert.Equal(t, "false", annotations[controllercommon.AnnotationSkipQuiesce])
})

t.Run("does not set SkipQuiesce when Backup is auto and VM is absent", func(t *testing.T) {
vm := &kvcore.VirtualMachine{}
backup := &velerov1.Backup{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
controllercommon.AnnotationSkipQuiesce: "auto",
},
},
}
annotations := buildDataUploadAnnotations(vm, backup, operationID)
assert.NotContains(t, annotations, controllercommon.AnnotationSkipQuiesce)
})

t.Run("does not set SkipQuiesce when both are invalid", func(t *testing.T) {
vm := &kvcore.VirtualMachine{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
controllercommon.AnnotationSkipQuiesce: "invalid-vm",
},
},
}
backup := &velerov1.Backup{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
controllercommon.AnnotationSkipQuiesce: "invalid-backup",
},
},
}
annotations := buildDataUploadAnnotations(vm, backup, operationID)
assert.NotContains(t, annotations, controllercommon.AnnotationSkipQuiesce)
})
}