Skip to content

Commit

Permalink
Add DataUpload Result and CSI VolumeSnapshot check for restore PV.
Browse files Browse the repository at this point in the history
Signed-off-by: Xun Jiang <[email protected]>
  • Loading branch information
Xun Jiang committed Nov 6, 2023
1 parent d6146ec commit a4b822e
Show file tree
Hide file tree
Showing 8 changed files with 352 additions and 5 deletions.
1 change: 1 addition & 0 deletions changelogs/unreleased/7061-blackpiglet
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add DataUpload Result and CSI VolumeSnapshot check for restore PV.
5 changes: 5 additions & 0 deletions pkg/builder/volume_snapshot_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,8 @@ func (v *VolumeSnapshotBuilder) BoundVolumeSnapshotContentName(vscName string) *
v.object.Status.BoundVolumeSnapshotContentName = &vscName
return v
}

func (v *VolumeSnapshotBuilder) SourcePVC(name string) *VolumeSnapshotBuilder {
v.object.Spec.Source.PersistentVolumeClaimName = &name
return v
}
6 changes: 6 additions & 0 deletions pkg/controller/restore_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,11 @@ func (r *restoreReconciler) runValidatedRestore(restore *api.Restore, info backu
return errors.Wrap(err, "error fetching volume snapshots metadata")
}

csiVolumeSnapshots, err := backupStore.GetCSIVolumeSnapshots(restore.Spec.BackupName)
if err != nil {
return errors.Wrap(err, "fail to fetch CSI VolumeSnapshots metadata")
}

Check warning on line 521 in pkg/controller/restore_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controller/restore_controller.go#L520-L521

Added lines #L520 - L521 were not covered by tests

restoreLog.Info("starting restore")

var podVolumeBackups []*api.PodVolumeBackup
Expand All @@ -531,6 +536,7 @@ func (r *restoreReconciler) runValidatedRestore(restore *api.Restore, info backu
BackupReader: backupFile,
ResourceModifiers: resourceModifiers,
DisableInformerCache: r.disableInformerCache,
CSIVolumeSnapshots: csiVolumeSnapshots,
}
restoreWarnings, restoreErrors := r.restorer.RestoreWithResolvers(restoreReq, actionsResolver, pluginManager)

Expand Down
2 changes: 2 additions & 0 deletions pkg/controller/restore_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"testing"
"time"

snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -471,6 +472,7 @@ func TestRestoreReconcile(t *testing.T) {
}
if test.expectedRestorerCall != nil {
backupStore.On("GetBackupContents", test.backup.Name).Return(io.NopCloser(bytes.NewReader([]byte("hello world"))), nil)
backupStore.On("GetCSIVolumeSnapshots", test.backup.Name).Return([]*snapshotv1api.VolumeSnapshot{}, nil)

restorer.On("RestoreWithResolvers", mock.Anything, mock.Anything, mock.Anything, mock.Anything,
mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(warnings, errors)
Expand Down
2 changes: 2 additions & 0 deletions pkg/restore/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"io"
"sort"

snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1"
"github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/runtime"

Expand Down Expand Up @@ -60,6 +61,7 @@ type Request struct {
itemOperationsList *[]*itemoperation.RestoreOperation
ResourceModifiers *resourcemodifiers.ResourceModifiers
DisableInformerCache bool
CSIVolumeSnapshots []*snapshotv1api.VolumeSnapshot
}

type restoredItemStatus struct {
Expand Down
68 changes: 68 additions & 0 deletions pkg/restore/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"time"

"github.com/google/uuid"
snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
v1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -299,6 +300,7 @@ func (kr *kubernetesRestorer) RestoreWithResolvers(
pvsToProvision: sets.NewString(),
pvRestorer: pvRestorer,
volumeSnapshots: req.VolumeSnapshots,
csiVolumeSnapshots: req.CSIVolumeSnapshots,
podVolumeBackups: req.PodVolumeBackups,
resourceTerminatingTimeout: kr.resourceTerminatingTimeout,
resourceTimeout: kr.resourceTimeout,
Expand Down Expand Up @@ -348,6 +350,7 @@ type restoreContext struct {
pvsToProvision sets.String
pvRestorer PVRestorer
volumeSnapshots []*volume.Snapshot
csiVolumeSnapshots []*snapshotv1api.VolumeSnapshot
podVolumeBackups []*velerov1api.PodVolumeBackup
resourceTerminatingTimeout time.Duration
resourceTimeout time.Duration
Expand Down Expand Up @@ -1295,6 +1298,22 @@ func (ctx *restoreContext) restoreItem(obj *unstructured.Unstructured, groupReso
// want to dynamically re-provision it.
return warnings, errs, itemExists

case hasCSIVolumeSnapshot(ctx, obj):
ctx.log.Infof("Dynamically re-provisioning persistent volume because it has a related CSI VolumeSnapshot.")
ctx.pvsToProvision.Insert(name)

// Return early because we don't want to restore the PV itself, we
// want to dynamically re-provision it.
return warnings, errs, itemExists

case hasSnapshotDataUpload(ctx, obj):
ctx.log.Infof("Dynamically re-provisioning persistent volume because it has a related snapshot DataUpload.")
ctx.pvsToProvision.Insert(name)

// Return early because we don't want to restore the PV itself, we
// want to dynamically re-provision it.
return warnings, errs, itemExists

Check warning on line 1315 in pkg/restore/restore.go

View check run for this annotation

Codecov / codecov/patch

pkg/restore/restore.go#L1309-L1315

Added lines #L1309 - L1315 were not covered by tests

case hasDeleteReclaimPolicy(obj.Object):
ctx.log.Infof("Dynamically re-provisioning persistent volume because it doesn't have a snapshot and its reclaim policy is Delete.")
ctx.pvsToProvision.Insert(name)
Expand Down Expand Up @@ -1937,6 +1956,55 @@ func hasSnapshot(pvName string, snapshots []*volume.Snapshot) bool {
return false
}

func hasCSIVolumeSnapshot(ctx *restoreContext, unstructuredPV *unstructured.Unstructured) bool {
pv := new(v1.PersistentVolume)
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructuredPV.Object, pv); err != nil {
ctx.log.WithError(err).Warnf("Unable to convert PV from unstructured to structured")
return false
}

for _, vs := range ctx.csiVolumeSnapshots {
if pv.Spec.ClaimRef.Name == *vs.Spec.Source.PersistentVolumeClaimName &&
pv.Spec.ClaimRef.Namespace == vs.Namespace {
return true
}
}
return false
}

func hasSnapshotDataUpload(ctx *restoreContext, unstructuredPV *unstructured.Unstructured) bool {
pv := new(v1.PersistentVolume)
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructuredPV.Object, pv); err != nil {
ctx.log.WithError(err).Warnf("Unable to convert PV from unstructured to structured")
return false
}

if pv.Spec.ClaimRef == nil {
return false
}

dataUploadResultList := new(v1.ConfigMapList)
err := ctx.kbClient.List(go_context.TODO(), dataUploadResultList, &crclient.ListOptions{
LabelSelector: labels.SelectorFromSet(map[string]string{
velerov1api.RestoreUIDLabel: label.GetValidName(string(ctx.restore.GetUID())),
velerov1api.PVCNamespaceNameLabel: label.GetValidName(pv.Spec.ClaimRef.Namespace + "." + pv.Spec.ClaimRef.Name),
velerov1api.ResourceUsageLabel: label.GetValidName(string(velerov1api.VeleroResourceUsageDataUploadResult)),
}),
})
if err != nil {
ctx.log.WithError(err).Warnf("Fail to list DataUpload result CM.")
return false
}

Check warning on line 1998 in pkg/restore/restore.go

View check run for this annotation

Codecov / codecov/patch

pkg/restore/restore.go#L1996-L1998

Added lines #L1996 - L1998 were not covered by tests
if len(dataUploadResultList.Items) != 1 {
ctx.log.WithError(fmt.Errorf("dataupload result number is not expected")).
Warnf("Got %d DataUpload result. Expect one.", len(dataUploadResultList.Items))
return false
}

return true
}

Check warning on line 2006 in pkg/restore/restore.go

View check run for this annotation

Codecov / codecov/patch

pkg/restore/restore.go#L2006

Added line #L2006 was not covered by tests

func hasPodVolumeBackup(unstructuredPV *unstructured.Unstructured, ctx *restoreContext) bool {
if len(ctx.podVolumeBackups) == 0 {
return false
Expand Down
Loading

0 comments on commit a4b822e

Please sign in to comment.