mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-01-05 21:14:56 +00:00
Restore from PodVolumeBackups (#1723)
* Restore from PodVolumeBackups Signed-off-by: Carlisia <carlisiac@vmware.com> * Partially address code reviews Signed-off-by: Carlisia <carlisiac@vmware.com> * Partially address code reviews #2 Signed-off-by: Carlisia <carlisiac@vmware.com> * Clean up struct Signed-off-by: Carlisia <carlisiac@vmware.com> * Fix log messages Signed-off-by: Carlisia <carlisiac@vmware.com> * Fix tests Signed-off-by: Carlisia <carlisiac@vmware.com> * Clean up Signed-off-by: Carlisia <carlisiac@vmware.com> * Add changelog Signed-off-by: Carlisia <carlisiac@vmware.com>
This commit is contained in:
committed by
Adnan Abdulhussein
parent
4e1b1f9457
commit
4accb8512a
@@ -45,10 +45,12 @@ const (
|
||||
volumesToBackupAnnotation = "backup.velero.io/backup-volumes"
|
||||
)
|
||||
|
||||
// GetPodSnapshotAnnotations returns a map, of volume name -> snapshot id,
|
||||
// getPodSnapshotAnnotations returns a map, of volume name -> snapshot id,
|
||||
// of all restic snapshots for this pod.
|
||||
// Deprecated: we will stop using pod annotations to record restic snapshot IDs after they're taken.
|
||||
func GetPodSnapshotAnnotations(obj metav1.Object) map[string]string {
|
||||
// TODO(2.0) to remove
|
||||
// Deprecated: we will stop using pod annotations to record restic snapshot IDs after they're taken,
|
||||
// therefore we won't need to check if these annotations exist.
|
||||
func getPodSnapshotAnnotations(obj metav1.Object) map[string]string {
|
||||
var res map[string]string
|
||||
|
||||
insertSafe := func(k, v string) {
|
||||
@@ -67,6 +69,24 @@ func GetPodSnapshotAnnotations(obj metav1.Object) map[string]string {
|
||||
return res
|
||||
}
|
||||
|
||||
// GetVolumeBackupsForPod returns a map, of volume name -> snapshot id,
|
||||
// of the PodVolumeBackups that exist for the provided pod.
|
||||
func GetVolumeBackupsForPod(podVolumeBackups []*velerov1api.PodVolumeBackup, pod metav1.Object) map[string]string {
|
||||
volumes := make(map[string]string)
|
||||
|
||||
for _, pvb := range podVolumeBackups {
|
||||
if pod.GetName() == pvb.Spec.Pod.Name {
|
||||
volumes[pvb.Spec.Volume] = pvb.Status.SnapshotID
|
||||
}
|
||||
}
|
||||
|
||||
if len(volumes) > 0 {
|
||||
return volumes
|
||||
}
|
||||
|
||||
return getPodSnapshotAnnotations(pod)
|
||||
}
|
||||
|
||||
// GetVolumesToBackup returns a list of volume names to backup for
|
||||
// the provided pod.
|
||||
func GetVolumesToBackup(obj metav1.Object) []string {
|
||||
|
||||
@@ -75,7 +75,7 @@ func TestGetPodSnapshotAnnotations(t *testing.T) {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
pod := &corev1api.Pod{}
|
||||
pod.Annotations = test.annotations
|
||||
assert.Equal(t, test.expected, GetPodSnapshotAnnotations(pod))
|
||||
assert.Equal(t, test.expected, getPodSnapshotAnnotations(pod))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,10 +31,17 @@ import (
|
||||
"github.com/heptio/velero/pkg/util/boolptr"
|
||||
)
|
||||
|
||||
type RestoreData struct {
|
||||
Restore *velerov1api.Restore
|
||||
Pod *corev1api.Pod
|
||||
PodVolumeBackups []*velerov1api.PodVolumeBackup
|
||||
SourceNamespace, BackupLocation string
|
||||
}
|
||||
|
||||
// Restorer can execute restic restores of volumes in a pod.
|
||||
type Restorer interface {
|
||||
// RestorePodVolumes restores all annotated volumes in a pod.
|
||||
RestorePodVolumes(restore *velerov1api.Restore, pod *corev1api.Pod, sourceNamespace, backupLocation string, log logrus.FieldLogger) []error
|
||||
RestorePodVolumes(RestoreData) []error
|
||||
}
|
||||
|
||||
type restorer struct {
|
||||
@@ -84,14 +91,13 @@ func newRestorer(
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *restorer) RestorePodVolumes(restore *velerov1api.Restore, pod *corev1api.Pod, sourceNamespace, backupLocation string, log logrus.FieldLogger) []error {
|
||||
// get volumes to restore from pod's annotations
|
||||
volumesToRestore := GetPodSnapshotAnnotations(pod)
|
||||
func (r *restorer) RestorePodVolumes(data RestoreData) []error {
|
||||
volumesToRestore := GetVolumeBackupsForPod(data.PodVolumeBackups, data.Pod)
|
||||
if len(volumesToRestore) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
repo, err := r.repoEnsurer.EnsureRepo(r.ctx, restore.Namespace, sourceNamespace, backupLocation)
|
||||
repo, err := r.repoEnsurer.EnsureRepo(r.ctx, data.Restore.Namespace, data.SourceNamespace, data.BackupLocation)
|
||||
if err != nil {
|
||||
return []error{err}
|
||||
}
|
||||
@@ -104,7 +110,7 @@ func (r *restorer) RestorePodVolumes(restore *velerov1api.Restore, pod *corev1ap
|
||||
resultsChan := make(chan *velerov1api.PodVolumeRestore)
|
||||
|
||||
r.resultsLock.Lock()
|
||||
r.results[resultsKey(pod.Namespace, pod.Name)] = resultsChan
|
||||
r.results[resultsKey(data.Pod.Namespace, data.Pod.Name)] = resultsChan
|
||||
r.resultsLock.Unlock()
|
||||
|
||||
var (
|
||||
@@ -113,7 +119,7 @@ func (r *restorer) RestorePodVolumes(restore *velerov1api.Restore, pod *corev1ap
|
||||
)
|
||||
|
||||
for volume, snapshot := range volumesToRestore {
|
||||
volumeRestore := newPodVolumeRestore(restore, pod, volume, snapshot, backupLocation, repo.Spec.ResticIdentifier)
|
||||
volumeRestore := newPodVolumeRestore(data.Restore, data.Pod, data.BackupLocation, volume, snapshot, repo.Spec.ResticIdentifier)
|
||||
|
||||
if err := errorOnly(r.repoManager.veleroClient.VeleroV1().PodVolumeRestores(volumeRestore.Namespace).Create(volumeRestore)); err != nil {
|
||||
errs = append(errs, errors.WithStack(err))
|
||||
@@ -136,13 +142,13 @@ ForEachVolume:
|
||||
}
|
||||
|
||||
r.resultsLock.Lock()
|
||||
delete(r.results, resultsKey(pod.Namespace, pod.Name))
|
||||
delete(r.results, resultsKey(data.Pod.Namespace, data.Pod.Name))
|
||||
r.resultsLock.Unlock()
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
func newPodVolumeRestore(restore *velerov1api.Restore, pod *corev1api.Pod, volume, snapshot, backupLocation, repoIdentifier string) *velerov1api.PodVolumeRestore {
|
||||
func newPodVolumeRestore(restore *velerov1api.Restore, pod *corev1api.Pod, backupLocation, volume, snapshot, repoIdentifier string) *velerov1api.PodVolumeRestore {
|
||||
return &velerov1api.PodVolumeRestore{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: restore.Namespace,
|
||||
|
||||
Reference in New Issue
Block a user