diff --git a/Makefile b/Makefile index b3a6a32f216..4e8e728659e 100644 --- a/Makefile +++ b/Makefile @@ -112,17 +112,17 @@ GOPROXY ?= https://proxy.golang.org # If you want to build all containers, see the 'all-containers' rule. all: @$(MAKE) build - @$(MAKE) build BIN=velero-restic-restore-helper + @$(MAKE) build BIN=velero-restore-helper build-%: @$(MAKE) --no-print-directory ARCH=$* build - @$(MAKE) --no-print-directory ARCH=$* build BIN=velero-restic-restore-helper + @$(MAKE) --no-print-directory ARCH=$* build BIN=velero-restore-helper all-build: $(addprefix build-, $(CLI_PLATFORMS)) all-containers: container-builder-env @$(MAKE) --no-print-directory container - @$(MAKE) --no-print-directory container BIN=velero-restic-restore-helper + @$(MAKE) --no-print-directory container BIN=velero-restore-helper local: build-dirs # Add DEBUG=1 to enable debug locally diff --git a/cmd/velero-restic-restore-helper/velero-restic-restore-helper.go b/cmd/velero-restore-helper/velero-restore-helper.go similarity index 100% rename from cmd/velero-restic-restore-helper/velero-restic-restore-helper.go rename to cmd/velero-restore-helper/velero-restore-helper.go diff --git a/internal/hook/item_hook_handler.go b/internal/hook/item_hook_handler.go index 062922a0566..0bced9484a0 100644 --- a/internal/hook/item_hook_handler.go +++ b/internal/hook/item_hook_handler.go @@ -36,7 +36,7 @@ import ( velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/kuberesource" "github.com/vmware-tanzu/velero/pkg/podexec" - "github.com/vmware-tanzu/velero/pkg/podvolume" + "github.com/vmware-tanzu/velero/pkg/restorehelper" "github.com/vmware-tanzu/velero/pkg/util/collections" "github.com/vmware-tanzu/velero/pkg/util/kube" ) @@ -121,12 +121,12 @@ func (i *InitContainerRestoreHookHandler) HandleRestoreHooks( } initContainers := []corev1api.Container{} - // If this pod had pod volumes backed up using restic, then we want to the pod volumes restored prior to + // If this pod is backed up with data movement, then we want to the pod volumes restored prior to // running the restore hook init containers. This allows the restore hook init containers to prepare the // restored data to be consumed by the application container(s). - // So if there is a "restic-wait" init container already on the pod at index 0, we'll preserve that and run + // So if there is a "restore-wait" init container already on the pod at index 0, we'll preserve that and run // it before running any other init container. - if len(pod.Spec.InitContainers) > 0 && pod.Spec.InitContainers[0].Name == podvolume.InitContainer { + if len(pod.Spec.InitContainers) > 0 && pod.Spec.InitContainers[0].Name == restorehelper.WaitInitContainer { initContainers = append(initContainers, pod.Spec.InitContainers[0]) pod.Spec.InitContainers = pod.Spec.InitContainers[1:] } diff --git a/internal/hook/item_hook_handler_test.go b/internal/hook/item_hook_handler_test.go index 9f8267808ca..ea2c518897b 100644 --- a/internal/hook/item_hook_handler_test.go +++ b/internal/hook/item_hook_handler_test.go @@ -1675,7 +1675,7 @@ func TestHandleRestoreHooks(t *testing.T) { }, }, { - name: "should preserve restic-wait init container when it is the only existing init container", + name: "should preserve restore-wait init container when it is the only existing init container", podInput: corev1api.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: "app1", @@ -1683,8 +1683,8 @@ func TestHandleRestoreHooks(t *testing.T) { }, Spec: corev1api.PodSpec{ InitContainers: []corev1api.Container{ - *builder.ForContainer("restic-wait", "bus-box"). - Command([]string{"restic-restore"}).Result(), + *builder.ForContainer("restore-wait", "bus-box"). + Command([]string{"pod-volume-restore"}).Result(), }, }, }, @@ -1696,8 +1696,8 @@ func TestHandleRestoreHooks(t *testing.T) { }, Spec: corev1api.PodSpec{ InitContainers: []corev1api.Container{ - *builder.ForContainer("restic-wait", "bus-box"). - Command([]string{"restic-restore"}).Result(), + *builder.ForContainer("restore-wait", "bus-box"). + Command([]string{"pod-volume-restore"}).Result(), *builder.ForContainer("restore-init-container-1", "nginx"). Command([]string{"a", "b", "c"}).Result(), *builder.ForContainer("restore-init-container-2", "nginx"). @@ -1729,7 +1729,7 @@ func TestHandleRestoreHooks(t *testing.T) { }, { - name: "should preserve restic-wait init container when it exits with other init containers", + name: "should preserve restore-wait init container when it exits with other init containers", podInput: corev1api.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: "app1", @@ -1737,8 +1737,8 @@ func TestHandleRestoreHooks(t *testing.T) { }, Spec: corev1api.PodSpec{ InitContainers: []corev1api.Container{ - *builder.ForContainer("restic-wait", "bus-box"). - Command([]string{"restic-restore"}).Result(), + *builder.ForContainer("restore-wait", "bus-box"). + Command([]string{"pod-volume-restore"}).Result(), *builder.ForContainer("init-app-step1", "busy-box"). Command([]string{"init-step1"}).Result(), *builder.ForContainer("init-app-step2", "busy-box"). @@ -1754,8 +1754,8 @@ func TestHandleRestoreHooks(t *testing.T) { }, Spec: corev1api.PodSpec{ InitContainers: []corev1api.Container{ - *builder.ForContainer("restic-wait", "bus-box"). - Command([]string{"restic-restore"}).Result(), + *builder.ForContainer("restore-wait", "bus-box"). + Command([]string{"pod-volume-restore"}).Result(), *builder.ForContainer("restore-init-container-1", "nginx"). Command([]string{"a", "b", "c"}).Result(), *builder.ForContainer("restore-init-container-2", "nginx"). diff --git a/internal/velero/images.go b/internal/velero/images.go index c6319aaddd4..b21d4aff8cb 100644 --- a/internal/velero/images.go +++ b/internal/velero/images.go @@ -44,8 +44,8 @@ func DefaultVeleroImage() string { return fmt.Sprintf("%s/%s:%s", imageRegistry(), "velero", ImageTag()) } -// DefaultResticRestoreHelperImage returns the default container image to use for the restic restore helper +// DefaultRestoreHelperImage returns the default container image to use for the restore helper // for this version of Velero. -func DefaultResticRestoreHelperImage() string { - return fmt.Sprintf("%s/%s:%s", imageRegistry(), "velero-restic-restore-helper", ImageTag()) +func DefaultRestoreHelperImage() string { + return fmt.Sprintf("%s/%s:%s", imageRegistry(), "velero-restore-helper", ImageTag()) } diff --git a/internal/velero/images_test.go b/internal/velero/images_test.go index d04c66b9dcc..7d6bdf8cd92 100644 --- a/internal/velero/images_test.go +++ b/internal/velero/images_test.go @@ -135,6 +135,6 @@ func TestDefaultVeleroImage(t *testing.T) { testDefaultImage(t, DefaultVeleroImage, "velero") } -func TestDefaultResticRestoreHelperImage(t *testing.T) { - testDefaultImage(t, DefaultResticRestoreHelperImage, "velero-restic-restore-helper") +func TestDefaultRestoreHelperImage(t *testing.T) { + testDefaultImage(t, DefaultRestoreHelperImage, "velero-restore-helper") } diff --git a/pkg/cmd/server/plugin/plugin.go b/pkg/cmd/server/plugin/plugin.go index 64dbe4572a5..bb2c1c60048 100644 --- a/pkg/cmd/server/plugin/plugin.go +++ b/pkg/cmd/server/plugin/plugin.go @@ -45,7 +45,7 @@ func NewCommand(f client.Factory) *cobra.Command { RegisterBackupItemAction("velero.io/service-account", newServiceAccountBackupItemAction(f)). RegisterRestoreItemAction("velero.io/job", newJobRestoreItemAction). RegisterRestoreItemAction("velero.io/pod", newPodRestoreItemAction). - RegisterRestoreItemAction("velero.io/restic", newResticRestoreItemAction(f)). + RegisterRestoreItemAction("velero.io/pod-volume-restore", newPodVolumeRestoreItemAction(f)). RegisterRestoreItemAction("velero.io/init-restore-hook", newInitRestoreHookPodAction). RegisterRestoreItemAction("velero.io/service", newServiceRestoreItemAction). RegisterRestoreItemAction("velero.io/service-account", newServiceAccountRestoreItemAction). @@ -139,7 +139,7 @@ func newInitRestoreHookPodAction(logger logrus.FieldLogger) (interface{}, error) return restore.NewInitRestoreHookPodAction(logger), nil } -func newResticRestoreItemAction(f client.Factory) plugincommon.HandlerInitializer { +func newPodVolumeRestoreItemAction(f client.Factory) plugincommon.HandlerInitializer { return func(logger logrus.FieldLogger) (interface{}, error) { client, err := f.KubeClient() if err != nil { @@ -151,7 +151,7 @@ func newResticRestoreItemAction(f client.Factory) plugincommon.HandlerInitialize return nil, err } - return restore.NewResticRestoreAction(logger, client.CoreV1().ConfigMaps(f.Namespace()), veleroClient.VeleroV1().PodVolumeBackups(f.Namespace())), nil + return restore.NewPodVolumeRestoreAction(logger, client.CoreV1().ConfigMaps(f.Namespace()), veleroClient.VeleroV1().PodVolumeBackups(f.Namespace())), nil } } diff --git a/pkg/controller/pod_volume_restore_controller.go b/pkg/controller/pod_volume_restore_controller.go index 5292e0a01f2..9c78171ae9a 100644 --- a/pkg/controller/pod_volume_restore_controller.go +++ b/pkg/controller/pod_volume_restore_controller.go @@ -42,6 +42,7 @@ import ( "github.com/vmware-tanzu/velero/pkg/podvolume" "github.com/vmware-tanzu/velero/pkg/repository" repokey "github.com/vmware-tanzu/velero/pkg/repository/keys" + "github.com/vmware-tanzu/velero/pkg/restorehelper" "github.com/vmware-tanzu/velero/pkg/uploader" "github.com/vmware-tanzu/velero/pkg/uploader/provider" "github.com/vmware-tanzu/velero/pkg/util/boolptr" @@ -105,10 +106,10 @@ func (c *PodVolumeRestoreReconciler) Reconcile(ctx context.Context, req ctrl.Req return ctrl.Result{}, nil } - resticInitContainerIndex := getResticInitContainerIndex(pod) - if resticInitContainerIndex > 0 { + initContainerIndex := getInitContainerIndex(pod) + if initContainerIndex > 0 { log.Warnf(`Init containers before the %s container may cause issues - if they interfere with volumes being restored: %s index %d`, podvolume.InitContainer, podvolume.InitContainer, resticInitContainerIndex) + if they interfere with volumes being restored: %s index %d`, restorehelper.WaitInitContainer, restorehelper.WaitInitContainer, initContainerIndex) } log.Info("Restore starting") @@ -162,8 +163,8 @@ func (c *PodVolumeRestoreReconciler) shouldProcess(ctx context.Context, log logr return false, nil, err } - if !isResticInitContainerRunning(pod) { - log.Debug("Pod is not running restic-wait init container, skip") + if !isInitContainerRunning(pod) { + log.Debug("Pod is not running restore-wait init container, skip") return false, nil, nil } @@ -207,18 +208,18 @@ func isPVRNew(pvr *velerov1api.PodVolumeRestore) bool { return pvr.Status.Phase == "" || pvr.Status.Phase == velerov1api.PodVolumeRestorePhaseNew } -func isResticInitContainerRunning(pod *corev1api.Pod) bool { - // Restic wait container can be anywhere in the list of init containers, but must be running. - i := getResticInitContainerIndex(pod) +func isInitContainerRunning(pod *corev1api.Pod) bool { + // Pod volume wait container can be anywhere in the list of init containers, but must be running. + i := getInitContainerIndex(pod) return i >= 0 && len(pod.Status.InitContainerStatuses)-1 >= i && pod.Status.InitContainerStatuses[i].State.Running != nil } -func getResticInitContainerIndex(pod *corev1api.Pod) int { - // Restic wait container can be anywhere in the list of init containers so locate it. +func getInitContainerIndex(pod *corev1api.Pod) int { + // Pod volume wait container can be anywhere in the list of init containers so locate it. for i, initContainer := range pod.Spec.InitContainers { - if initContainer.Name == podvolume.InitContainer { + if initContainer.Name == restorehelper.WaitInitContainer { return i } } @@ -299,7 +300,7 @@ func (c *PodVolumeRestoreReconciler) processRestore(ctx context.Context, req *ve } // Write a done file with name= into the just-created .velero dir - // within the volume. The velero restic init container on the pod is waiting + // within the volume. The velero init container on the pod is waiting // for this file to exist in each restored volume before completing. if err := ioutil.WriteFile(filepath.Join(volumePath, ".velero", string(restoreUID)), nil, 0644); err != nil { return errors.Wrap(err, "error writing done file") diff --git a/pkg/controller/pod_volume_restore_controller_test.go b/pkg/controller/pod_volume_restore_controller_test.go index d9cdc5d264e..eeec55b5446 100644 --- a/pkg/controller/pod_volume_restore_controller_test.go +++ b/pkg/controller/pod_volume_restore_controller_test.go @@ -31,7 +31,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" - "github.com/vmware-tanzu/velero/pkg/podvolume" + "github.com/vmware-tanzu/velero/pkg/restorehelper" "github.com/vmware-tanzu/velero/pkg/test" ) @@ -120,7 +120,7 @@ func TestShouldProcess(t *testing.T) { NodeName: controllerNode, InitContainers: []corev1api.Container{ { - Name: podvolume.InitContainer, + Name: restorehelper.WaitInitContainer, }, }, }, @@ -160,7 +160,7 @@ func TestShouldProcess(t *testing.T) { NodeName: controllerNode, InitContainers: []corev1api.Container{ { - Name: podvolume.InitContainer, + Name: restorehelper.WaitInitContainer, }, }, }, @@ -205,7 +205,7 @@ func TestShouldProcess(t *testing.T) { } } -func TestIsResticContainerRunning(t *testing.T) { +func TestIsInitContainerRunning(t *testing.T) { tests := []struct { name string pod *corev1api.Pod @@ -222,7 +222,7 @@ func TestIsResticContainerRunning(t *testing.T) { expected: false, }, { - name: "pod with running init container that's not restic should return false", + name: "pod with running init container that's not restore init should return false", pod: &corev1api.Pod{ ObjectMeta: metav1.ObjectMeta{ Namespace: "ns-1", @@ -231,7 +231,7 @@ func TestIsResticContainerRunning(t *testing.T) { Spec: corev1api.PodSpec{ InitContainers: []corev1api.Container{ { - Name: "non-restic-init", + Name: "non-restore-init", }, }, }, @@ -248,7 +248,7 @@ func TestIsResticContainerRunning(t *testing.T) { expected: false, }, { - name: "pod with running restic init container that's not first should still work", + name: "pod with running init container that's not first should still work", pod: &corev1api.Pod{ ObjectMeta: metav1.ObjectMeta{ Namespace: "ns-1", @@ -257,10 +257,10 @@ func TestIsResticContainerRunning(t *testing.T) { Spec: corev1api.PodSpec{ InitContainers: []corev1api.Container{ { - Name: "non-restic-init", + Name: "non-restore-init", }, { - Name: podvolume.InitContainer, + Name: restorehelper.WaitInitContainer, }, }, }, @@ -282,7 +282,7 @@ func TestIsResticContainerRunning(t *testing.T) { expected: true, }, { - name: "pod with restic init container as first initContainer that's not running should return false", + name: "pod with init container as first initContainer that's not running should return false", pod: &corev1api.Pod{ ObjectMeta: metav1.ObjectMeta{ Namespace: "ns-1", @@ -291,10 +291,10 @@ func TestIsResticContainerRunning(t *testing.T) { Spec: corev1api.PodSpec{ InitContainers: []corev1api.Container{ { - Name: podvolume.InitContainer, + Name: restorehelper.WaitInitContainer, }, { - Name: "non-restic-init", + Name: "non-restore-init", }, }, }, @@ -314,7 +314,7 @@ func TestIsResticContainerRunning(t *testing.T) { expected: false, }, { - name: "pod with running restic init container as first initContainer should return true", + name: "pod with running init container as first initContainer should return true", pod: &corev1api.Pod{ ObjectMeta: metav1.ObjectMeta{ Namespace: "ns-1", @@ -323,10 +323,10 @@ func TestIsResticContainerRunning(t *testing.T) { Spec: corev1api.PodSpec{ InitContainers: []corev1api.Container{ { - Name: podvolume.InitContainer, + Name: restorehelper.WaitInitContainer, }, { - Name: "non-restic-init", + Name: "non-restore-init", }, }, }, @@ -348,7 +348,7 @@ func TestIsResticContainerRunning(t *testing.T) { expected: true, }, { - name: "pod with restic init container with empty InitContainerStatuses should return 0", + name: "pod with init container with empty InitContainerStatuses should return 0", pod: &corev1api.Pod{ ObjectMeta: metav1.ObjectMeta{ Namespace: "ns-1", @@ -357,7 +357,7 @@ func TestIsResticContainerRunning(t *testing.T) { Spec: corev1api.PodSpec{ InitContainers: []corev1api.Container{ { - Name: podvolume.InitContainer, + Name: restorehelper.WaitInitContainer, }, }, }, @@ -371,12 +371,12 @@ func TestIsResticContainerRunning(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - assert.Equal(t, test.expected, isResticInitContainerRunning(test.pod)) + assert.Equal(t, test.expected, isInitContainerRunning(test.pod)) }) } } -func TestGetResticInitContainerIndex(t *testing.T) { +func TestGetInitContainerIndex(t *testing.T) { tests := []struct { name string pod *corev1api.Pod @@ -393,7 +393,7 @@ func TestGetResticInitContainerIndex(t *testing.T) { expected: -1, }, { - name: "pod with no restic init container return -1", + name: "pod with no init container return -1", pod: &corev1api.Pod{ ObjectMeta: metav1.ObjectMeta{ Namespace: "ns-1", @@ -402,7 +402,7 @@ func TestGetResticInitContainerIndex(t *testing.T) { Spec: corev1api.PodSpec{ InitContainers: []corev1api.Container{ { - Name: "non-restic-init", + Name: "non-restore-init", }, }, }, @@ -410,7 +410,7 @@ func TestGetResticInitContainerIndex(t *testing.T) { expected: -1, }, { - name: "pod with restic container as second initContainern should return 1", + name: "pod with container as second initContainern should return 1", pod: &corev1api.Pod{ ObjectMeta: metav1.ObjectMeta{ Namespace: "ns-1", @@ -419,10 +419,10 @@ func TestGetResticInitContainerIndex(t *testing.T) { Spec: corev1api.PodSpec{ InitContainers: []corev1api.Container{ { - Name: "non-restic-init", + Name: "non-restore-init", }, { - Name: podvolume.InitContainer, + Name: restorehelper.WaitInitContainer, }, }, }, @@ -430,7 +430,7 @@ func TestGetResticInitContainerIndex(t *testing.T) { expected: 1, }, { - name: "pod with restic init container as first initContainer should return 0", + name: "pod with init container as first initContainer should return 0", pod: &corev1api.Pod{ ObjectMeta: metav1.ObjectMeta{ Namespace: "ns-1", @@ -439,10 +439,10 @@ func TestGetResticInitContainerIndex(t *testing.T) { Spec: corev1api.PodSpec{ InitContainers: []corev1api.Container{ { - Name: podvolume.InitContainer, + Name: restorehelper.WaitInitContainer, }, { - Name: "non-restic-init", + Name: "non-restore-init", }, }, }, @@ -450,7 +450,7 @@ func TestGetResticInitContainerIndex(t *testing.T) { expected: 0, }, { - name: "pod with restic init container as first initContainer should return 0", + name: "pod with init container as first initContainer should return 0", pod: &corev1api.Pod{ ObjectMeta: metav1.ObjectMeta{ Namespace: "ns-1", @@ -459,10 +459,10 @@ func TestGetResticInitContainerIndex(t *testing.T) { Spec: corev1api.PodSpec{ InitContainers: []corev1api.Container{ { - Name: podvolume.InitContainer, + Name: restorehelper.WaitInitContainer, }, { - Name: "non-restic-init", + Name: "non-restore-init", }, }, }, @@ -473,7 +473,7 @@ func TestGetResticInitContainerIndex(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - assert.Equal(t, test.expected, getResticInitContainerIndex(test.pod)) + assert.Equal(t, test.expected, getInitContainerIndex(test.pod)) }) } } diff --git a/pkg/podvolume/util.go b/pkg/podvolume/util.go index d75b3931535..9704af468de 100644 --- a/pkg/podvolume/util.go +++ b/pkg/podvolume/util.go @@ -45,10 +45,6 @@ const ( // should be excluded from restic backup. VolumesToExcludeAnnotation = "backup.velero.io/backup-volumes-excludes" - // InitContainer is the name of the init container added - // to workload pods to help with restores. - InitContainer = "restic-wait" - // DefaultVolumesToFsBackup specifies whether pod volume backup should be used, by default, to // take backup of all pod volumes. DefaultVolumesToFsBackup = false diff --git a/pkg/restore/restic_restore_action.go b/pkg/restore/restic_restore_action.go index bf7116b8b92..48743fe750e 100644 --- a/pkg/restore/restic_restore_action.go +++ b/pkg/restore/restic_restore_action.go @@ -38,38 +38,39 @@ import ( "github.com/vmware-tanzu/velero/pkg/plugin/velero" riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" "github.com/vmware-tanzu/velero/pkg/podvolume" + "github.com/vmware-tanzu/velero/pkg/restorehelper" "github.com/vmware-tanzu/velero/pkg/util/kube" ) const ( defaultCPURequestLimit = "100m" defaultMemRequestLimit = "128Mi" - defaultCommand = "/velero-restic-restore-helper" + defaultCommand = "/velero-restore-helper" ) -type ResticRestoreAction struct { +type PodVolumeRestoreAction struct { logger logrus.FieldLogger client corev1client.ConfigMapInterface podVolumeBackupClient velerov1client.PodVolumeBackupInterface } -func NewResticRestoreAction(logger logrus.FieldLogger, client corev1client.ConfigMapInterface, podVolumeBackupClient velerov1client.PodVolumeBackupInterface) *ResticRestoreAction { - return &ResticRestoreAction{ +func NewPodVolumeRestoreAction(logger logrus.FieldLogger, client corev1client.ConfigMapInterface, podVolumeBackupClient velerov1client.PodVolumeBackupInterface) *PodVolumeRestoreAction { + return &PodVolumeRestoreAction{ logger: logger, client: client, podVolumeBackupClient: podVolumeBackupClient, } } -func (a *ResticRestoreAction) AppliesTo() (velero.ResourceSelector, error) { +func (a *PodVolumeRestoreAction) AppliesTo() (velero.ResourceSelector, error) { return velero.ResourceSelector{ IncludedResources: []string{"pods"}, }, nil } -func (a *ResticRestoreAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { - a.logger.Info("Executing ResticRestoreAction") - defer a.logger.Info("Done executing ResticRestoreAction") +func (a *PodVolumeRestoreAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { + a.logger.Info("Executing PodVolumeRestoreAction") + defer a.logger.Info("Done executing PodVolumeRestoreAction") var pod corev1.Pod if err := runtime.DefaultUnstructuredConverter.FromUnstructured(input.Item.UnstructuredContent(), &pod); err != nil { @@ -99,16 +100,16 @@ func (a *ResticRestoreAction) Execute(input *riav1.RestoreItemActionExecuteInput } volumeSnapshots := podvolume.GetVolumeBackupsForPod(podVolumeBackups, &pod, podFromBackup.Namespace) if len(volumeSnapshots) == 0 { - log.Debug("No restic backups found for pod") + log.Debug("No pod volume backups found for pod") return riav1.NewRestoreItemActionExecuteOutput(input.Item), nil } - log.Info("Restic backups for pod found") + log.Info("Pod volume backups for pod found") // TODO we might want/need to get plugin config at the top of this method at some point; for now, wait // until we know we're doing a restore before getting config. log.Debugf("Getting plugin config") - config, err := getPluginConfig(common.PluginKindRestoreItemAction, "velero.io/restic", a.client) + config, err := getPluginConfig(common.PluginKindRestoreItemAction, "velero.io/pod-volume-restore", a.client) if err != nil { return nil, err } @@ -147,7 +148,7 @@ func (a *ResticRestoreAction) Execute(input *riav1.RestoreItemActionExecuteInput log.Errorf("Using default securityContext values, couldn't parse securityContext requirements: %s.", err) } - initContainerBuilder := newResticInitContainerBuilder(image, string(input.Restore.UID)) + initContainerBuilder := newRestoreInitContainerBuilder(image, string(input.Restore.UID)) initContainerBuilder.Resources(&resourceReqs) initContainerBuilder.SecurityContext(&securityContext) @@ -161,7 +162,7 @@ func (a *ResticRestoreAction) Execute(input *riav1.RestoreItemActionExecuteInput initContainerBuilder.Command(getCommand(log, config)) initContainer := *initContainerBuilder.Result() - if len(pod.Spec.InitContainers) == 0 || pod.Spec.InitContainers[0].Name != podvolume.InitContainer { + if len(pod.Spec.InitContainers) == 0 || (pod.Spec.InitContainers[0].Name != restorehelper.WaitInitContainer && pod.Spec.InitContainers[0].Name != restorehelper.WaitInitContainerLegacy) { pod.Spec.InitContainers = append([]corev1.Container{initContainer}, pod.Spec.InitContainers...) } else { pod.Spec.InitContainers[0] = initContainer @@ -193,13 +194,13 @@ func getCommand(log logrus.FieldLogger, config *corev1.ConfigMap) []string { func getImage(log logrus.FieldLogger, config *corev1.ConfigMap) string { if config == nil { log.Debug("No config found for plugin") - return veleroimage.DefaultResticRestoreHelperImage() + return veleroimage.DefaultRestoreHelperImage() } image := config.Data["image"] if image == "" { log.Debugf("No custom image configured") - return veleroimage.DefaultResticRestoreHelperImage() + return veleroimage.DefaultRestoreHelperImage() } log = log.WithField("image", image) @@ -207,7 +208,7 @@ func getImage(log logrus.FieldLogger, config *corev1.ConfigMap) string { parts := strings.Split(image, "/") if len(parts) == 1 { - defaultImage := veleroimage.DefaultResticRestoreHelperImage() + defaultImage := veleroimage.DefaultRestoreHelperImage() // Image supplied without registry part log.Infof("Plugin config contains image name without registry name. Using default init container image: %q", defaultImage) return defaultImage @@ -265,7 +266,7 @@ func getSecurityContext(log logrus.FieldLogger, config *corev1.ConfigMap) (strin func getPluginConfig(kind common.PluginKind, name string, client corev1client.ConfigMapInterface) (*corev1.ConfigMap, error) { opts := metav1.ListOptions{ // velero.io/plugin-config: true - // velero.io/restic: RestoreItemAction + // velero.io/pod-volume-restore: RestoreItemAction LabelSelector: fmt.Sprintf("velero.io/plugin-config,%s=%s", name, kind), } @@ -289,8 +290,8 @@ func getPluginConfig(kind common.PluginKind, name string, client corev1client.Co return &list.Items[0], nil } -func newResticInitContainerBuilder(image, restoreUID string) *builder.ContainerBuilder { - return builder.ForContainer(podvolume.InitContainer, image). +func newRestoreInitContainerBuilder(image, restoreUID string) *builder.ContainerBuilder { + return builder.ForContainer(restorehelper.WaitInitContainer, image). Args(restoreUID). Env([]*corev1.EnvVar{ { diff --git a/pkg/restore/restic_restore_action_test.go b/pkg/restore/restic_restore_action_test.go index 660c1fc66c8..18f21cf52bc 100644 --- a/pkg/restore/restic_restore_action_test.go +++ b/pkg/restore/restic_restore_action_test.go @@ -49,7 +49,7 @@ func TestGetImage(t *testing.T) { } } - defaultImage := veleroimage.DefaultResticRestoreHelperImage() + defaultImage := veleroimage.DefaultRestoreHelperImage() tests := []struct { name string @@ -110,8 +110,8 @@ func TestGetImage(t *testing.T) { } } -// TestResticRestoreActionExecute tests the restic restore item action plugin's Execute method. -func TestResticRestoreActionExecute(t *testing.T) { +// TestPodVolumeRestoreActionExecute tests the restic restore item action plugin's Execute method. +func TestPodVolumeRestoreActionExecute(t *testing.T) { resourceReqs, _ := kube.ParseResourceRequirements( defaultCPURequestLimit, defaultMemRequestLimit, // requests defaultCPURequestLimit, defaultMemRequestLimit, // limits @@ -125,7 +125,7 @@ func TestResticRestoreActionExecute(t *testing.T) { veleroNs = "velero" ) - defaultResticRestoreHelperImage := veleroimage.DefaultResticRestoreHelperImage() + defaultRestoreHelperImage := veleroimage.DefaultRestoreHelperImage() tests := []struct { name string @@ -135,7 +135,7 @@ func TestResticRestoreActionExecute(t *testing.T) { want *corev1api.Pod }{ { - name: "Restoring pod with no other initContainers adds the restic initContainer", + name: "Restoring pod with no other initContainers adds the restore initContainer", pod: builder.ForPod("ns-1", "my-pod").ObjectMeta( builder.WithAnnotations("snapshot.velero.io/myvol", "")). Result(), @@ -143,14 +143,14 @@ func TestResticRestoreActionExecute(t *testing.T) { ObjectMeta( builder.WithAnnotations("snapshot.velero.io/myvol", "")). InitContainers( - newResticInitContainerBuilder(defaultResticRestoreHelperImage, ""). + newRestoreInitContainerBuilder(defaultRestoreHelperImage, ""). Resources(&resourceReqs). SecurityContext(&securityContext). VolumeMounts(builder.ForVolumeMount("myvol", "/restores/myvol").Result()). - Command([]string{"/velero-restic-restore-helper"}).Result()).Result(), + Command([]string{"/velero-restore-helper"}).Result()).Result(), }, { - name: "Restoring pod with other initContainers adds the restic initContainer as the first one", + name: "Restoring pod with other initContainers adds the restore initContainer as the first one", pod: builder.ForPod("ns-1", "my-pod"). ObjectMeta( builder.WithAnnotations("snapshot.velero.io/myvol", "")). @@ -160,16 +160,16 @@ func TestResticRestoreActionExecute(t *testing.T) { ObjectMeta( builder.WithAnnotations("snapshot.velero.io/myvol", "")). InitContainers( - newResticInitContainerBuilder(defaultResticRestoreHelperImage, ""). + newRestoreInitContainerBuilder(defaultRestoreHelperImage, ""). Resources(&resourceReqs). SecurityContext(&securityContext). VolumeMounts(builder.ForVolumeMount("myvol", "/restores/myvol").Result()). - Command([]string{"/velero-restic-restore-helper"}).Result(), + Command([]string{"/velero-restore-helper"}).Result(), builder.ForContainer("first-container", "").Result()). Result(), }, { - name: "Restoring pod with other initContainers adds the restic initContainer as the first one using PVB to identify the volumes and not annotations", + name: "Restoring pod with other initContainers adds the restore initContainer as the first one using PVB to identify the volumes and not annotations", pod: builder.ForPod("ns-1", "my-pod"). Volumes( builder.ForVolume("vol-1").PersistentVolumeClaimSource("pvc-1").Result(), @@ -203,16 +203,16 @@ func TestResticRestoreActionExecute(t *testing.T) { ObjectMeta( builder.WithAnnotations("snapshot.velero.io/not-used", "")). InitContainers( - newResticInitContainerBuilder(defaultResticRestoreHelperImage, ""). + newRestoreInitContainerBuilder(defaultRestoreHelperImage, ""). Resources(&resourceReqs). SecurityContext(&securityContext). VolumeMounts(builder.ForVolumeMount("vol-1", "/restores/vol-1").Result(), builder.ForVolumeMount("vol-2", "/restores/vol-2").Result()). - Command([]string{"/velero-restic-restore-helper"}).Result(), + Command([]string{"/velero-restore-helper"}).Result(), builder.ForContainer("first-container", "").Result()). Result(), }, { - name: "Restoring pod in another namespace adds the restic initContainer and uses the namespace of the backup pod for matching PVBs", + name: "Restoring pod in another namespace adds the restore initContainer and uses the namespace of the backup pod for matching PVBs", pod: builder.ForPod("new-ns", "my-pod"). Volumes( builder.ForVolume("vol-1").PersistentVolumeClaimSource("pvc-1").Result(), @@ -247,11 +247,11 @@ func TestResticRestoreActionExecute(t *testing.T) { builder.ForVolume("vol-2").PersistentVolumeClaimSource("pvc-2").Result(), ). InitContainers( - newResticInitContainerBuilder(defaultResticRestoreHelperImage, ""). + newRestoreInitContainerBuilder(defaultRestoreHelperImage, ""). Resources(&resourceReqs). SecurityContext(&securityContext). VolumeMounts(builder.ForVolumeMount("vol-1", "/restores/vol-1").Result(), builder.ForVolumeMount("vol-2", "/restores/vol-2").Result()). - Command([]string{"/velero-restic-restore-helper"}).Result()). + Command([]string{"/velero-restore-helper"}).Result()). Result(), }, } @@ -291,7 +291,7 @@ func TestResticRestoreActionExecute(t *testing.T) { Result(), } - a := NewResticRestoreAction( + a := NewPodVolumeRestoreAction( logrus.StandardLogger(), clientset.CoreV1().ConfigMaps(veleroNs), clientsetVelero.VeleroV1().PodVolumeBackups(veleroNs), diff --git a/pkg/restorehelper/util.go b/pkg/restorehelper/util.go new file mode 100644 index 00000000000..f42d5200855 --- /dev/null +++ b/pkg/restorehelper/util.go @@ -0,0 +1,33 @@ +/* +Copyright The Velero Contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package restorehelper + +const ( + // WaitInitContainer is the name of the init container added + // to workload pods to help with restores. + // If Velero needs to further process the volume data after PVC is + // provisioned, this init container is used to block Pod from running + // until the volume data is ready + WaitInitContainer = "restore-wait" + + // This is the name of the init container added by pre-v1.10 for the same + // purpose with WaitInitContainer. + // For compatibility, we need to check it when restoring backups created by + // old releases. The pods backed up by old releases may contain this init container + // since the init container is not deleted after pod is restored. + WaitInitContainerLegacy = "restic-wait" +) diff --git a/test/e2e/Makefile b/test/e2e/Makefile index 8f703cc003f..181589f686c 100644 --- a/test/e2e/Makefile +++ b/test/e2e/Makefile @@ -52,7 +52,7 @@ VELERO_CLI ?=$$(pwd)/../../_output/bin/$(GOOS)/$(GOARCH)/velero VELERO_IMAGE ?= velero/velero:main VELERO_VERSION ?= $(VERSION) PLUGINS ?= -RESTIC_HELPER_IMAGE ?= +RESTORE_HELPER_IMAGE ?= #Released version only UPGRADE_FROM_VELERO_VERSION ?= v1.7.1,v1.8.1 # UPGRADE_FROM_VELERO_CLI can has the same format(a list divided by comma) with UPGRADE_FROM_VELERO_VERSION @@ -114,7 +114,7 @@ run: ginkgo -velero-image=$(VELERO_IMAGE) \ -plugins=$(PLUGINS) \ -velero-version=$(VELERO_VERSION) \ - -restic-helper-image=$(RESTIC_HELPER_IMAGE) \ + -restore-helper-image=$(RESTORE_HELPER_IMAGE) \ -upgrade-from-velero-cli=$(UPGRADE_FROM_VELERO_CLI) \ -upgrade-from-velero-version=$(UPGRADE_FROM_VELERO_VERSION) \ -migrate-from-velero-cli=$(MIGRATE_FROM_VELERO_CLI) \ diff --git a/test/e2e/e2e_suite_test.go b/test/e2e/e2e_suite_test.go index 1025d021668..f44a89b35ba 100644 --- a/test/e2e/e2e_suite_test.go +++ b/test/e2e/e2e_suite_test.go @@ -54,7 +54,7 @@ func init() { flag.StringVar(&VeleroCfg.Plugins, "plugins", "", "provider plugins to be tested.") flag.StringVar(&VeleroCfg.AddBSLPlugins, "additional-bsl-plugins", "", "additional plugins to be tested.") flag.StringVar(&VeleroCfg.VeleroVersion, "velero-version", "main", "image version for the velero server to be tested with.") - flag.StringVar(&VeleroCfg.ResticHelperImage, "restic-helper-image", "", "image for the velero restic restore helper to be tested.") + flag.StringVar(&VeleroCfg.RestoreHelperImage, "restore-helper-image", "", "image for the velero restore helper to be tested.") flag.StringVar(&VeleroCfg.UpgradeFromVeleroCLI, "upgrade-from-velero-cli", "", "path to the pre-upgrade velero application to use.") flag.StringVar(&VeleroCfg.UpgradeFromVeleroVersion, "upgrade-from-velero-version", "v1.7.1", "image for the pre-upgrade velero server to be tested.") flag.StringVar(&VeleroCfg.MigrateFromVeleroCLI, "migrate-from-velero-cli", "", "path to the origin velero application to use.") diff --git a/test/e2e/migration/migration.go b/test/e2e/migration/migration.go index 3e81d8dd153..d1bf65e0cc3 100644 --- a/test/e2e/migration/migration.go +++ b/test/e2e/migration/migration.go @@ -122,7 +122,7 @@ func MigrationTest(useVolumeSnapshots bool, veleroCLI2Version VeleroCLI2Version) if veleroCLI2Version.VeleroVersion != "self" { fmt.Printf("Using default images address of Velero CLI %s\n", veleroCLI2Version.VeleroVersion) OriginVeleroCfg.VeleroImage = "" - OriginVeleroCfg.ResticHelperImage = "" + OriginVeleroCfg.RestoreHelperImage = "" OriginVeleroCfg.Plugins = "" //TODO: Remove this once origin Velero version is 1.10 and upper OriginVeleroCfg.UploaderType = "" diff --git a/test/e2e/types.go b/test/e2e/types.go index 068d957ebb0..9835f77e3e6 100644 --- a/test/e2e/types.go +++ b/test/e2e/types.go @@ -46,7 +46,7 @@ type VerleroConfig struct { AdditionalBSLConfig string AdditionalBSLCredentials string RegistryCredentialFile string - ResticHelperImage string + RestoreHelperImage string UpgradeFromVeleroVersion string UpgradeFromVeleroCLI string MigrateFromVeleroVersion string diff --git a/test/e2e/upgrade/upgrade.go b/test/e2e/upgrade/upgrade.go index a46231b4640..b3571b5588d 100644 --- a/test/e2e/upgrade/upgrade.go +++ b/test/e2e/upgrade/upgrade.go @@ -104,13 +104,13 @@ func BackupUpgradeRestoreTest(useVolumeSnapshots bool, veleroCLI2Version VeleroC VeleroCfg.GCFrequency = "" By(fmt.Sprintf("Install the expected old version Velero (%s) for upgrade", veleroCLI2Version.VeleroVersion), func() { - //Set VeleroImage and ResticHelperImage to blank - //VeleroImage and ResticHelperImage should be the default value in originalCli + //Set VeleroImage and RestoreHelperImage to blank + //VeleroImage and RestoreHelperImage should be the default value in originalCli tmpCfgForOldVeleroInstall := VeleroCfg tmpCfgForOldVeleroInstall.UpgradeFromVeleroVersion = veleroCLI2Version.VeleroVersion tmpCfgForOldVeleroInstall.VeleroCLI = veleroCLI2Version.VeleroCLI tmpCfgForOldVeleroInstall.VeleroImage = "" - tmpCfgForOldVeleroInstall.ResticHelperImage = "" + tmpCfgForOldVeleroInstall.RestoreHelperImage = "" tmpCfgForOldVeleroInstall.Plugins = "" tmpCfgForOldVeleroInstall.UploaderType = "" diff --git a/test/e2e/util/velero/install.go b/test/e2e/util/velero/install.go index fc0389bc55a..a5611418379 100644 --- a/test/e2e/util/velero/install.go +++ b/test/e2e/util/velero/install.go @@ -46,7 +46,7 @@ import ( type installOptions struct { *install.InstallOptions RegistryCredentialFile string - ResticHelperImage string + RestoreHelperImage string } func VeleroInstall(ctx context.Context, veleroCfg *VerleroConfig, useVolumeSnapshots bool) error { @@ -97,7 +97,7 @@ func VeleroInstall(ctx context.Context, veleroCfg *VerleroConfig, useVolumeSnaps err = installVeleroServer(ctx, veleroCfg.VeleroCLI, &installOptions{ InstallOptions: veleroInstallOptions, RegistryCredentialFile: veleroCfg.RegistryCredentialFile, - ResticHelperImage: veleroCfg.ResticHelperImage, + RestoreHelperImage: veleroCfg.RestoreHelperImage, }) if err != nil { return errors.WithMessagef(err, "Failed to install Velero in the cluster") @@ -218,14 +218,14 @@ func installVeleroServer(ctx context.Context, cli string, options *installOption args = append(args, fmt.Sprintf("--uploader-type=%v", options.UploaderType)) } - if err := createVelereResources(ctx, cli, namespace, args, options.RegistryCredentialFile, options.ResticHelperImage); err != nil { + if err := createVelereResources(ctx, cli, namespace, args, options.RegistryCredentialFile, options.RestoreHelperImage); err != nil { return err } return waitVeleroReady(ctx, namespace, options.UseNodeAgent) } -func createVelereResources(ctx context.Context, cli, namespace string, args []string, registryCredentialFile, resticHelperImage string) error { +func createVelereResources(ctx context.Context, cli, namespace string, args []string, registryCredentialFile, RestoreHelperImage string) error { args = append(args, "--dry-run", "--output", "json", "--crds-only") // get the CRD definitions @@ -270,7 +270,7 @@ func createVelereResources(ctx context.Context, cli, namespace string, args []st return errors.Wrapf(err, "failed to unmarshal the resources: %s", string(stdout)) } - if err = patchResources(ctx, resources, namespace, registryCredentialFile, VeleroCfg.ResticHelperImage); err != nil { + if err = patchResources(ctx, resources, namespace, registryCredentialFile, VeleroCfg.RestoreHelperImage); err != nil { return errors.Wrapf(err, "failed to patch resources") } @@ -292,7 +292,7 @@ func createVelereResources(ctx context.Context, cli, namespace string, args []st } // patch the velero resources -func patchResources(ctx context.Context, resources *unstructured.UnstructuredList, namespace, registryCredentialFile, resticHelperImage string) error { +func patchResources(ctx context.Context, resources *unstructured.UnstructuredList, namespace, registryCredentialFile, RestoreHelperImage string) error { // apply the image pull secret to avoid the image pull limit of Docker Hub if len(registryCredentialFile) > 0 { credential, err := ioutil.ReadFile(registryCredentialFile) @@ -336,7 +336,7 @@ func patchResources(ctx context.Context, resources *unstructured.UnstructuredLis } // customize the restic restore helper image - if len(VeleroCfg.ResticHelperImage) > 0 { + if len(VeleroCfg.RestoreHelperImage) > 0 { restoreActionConfig := corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{ Kind: "ConfigMap", @@ -351,7 +351,7 @@ func patchResources(ctx context.Context, resources *unstructured.UnstructuredLis }, }, Data: map[string]string{ - "image": VeleroCfg.ResticHelperImage, + "image": VeleroCfg.RestoreHelperImage, }, }