From 45de8a782fd85d6042cf5aa7057f1972f49131aa Mon Sep 17 00:00:00 2001 From: Scott Seago Date: Wed, 12 Oct 2022 12:41:50 -0400 Subject: [PATCH 1/3] moved RIA execute input/output structs back to velero package The RIA refactoring moved velero.RestoreItemAction into a separate (restoreitemaction) v1 package. Unfortunately, this change would require plugins to make code changes to locate the RestoreItemActionExecuteInput and RestoreItemActionExecuteOutput structs. This commit restores those structs to the original velero package, leaving just the RestoreItemAction interface in the new v1 package. Signed-off-by: Scott Seago --- changelogs/unreleased/5441-sseago | 1 + .../v1/restartable_restore_item_action.go | 2 +- .../restartable_restore_item_action_test.go | 5 +- .../framework/restore_item_action_client.go | 4 +- .../framework/restore_item_action_server.go | 2 +- .../restoreitemaction/v1/RestoreItemAction.go | 11 ++-- .../velero/restore_item_action_shared.go | 62 +++++++++++++++++++ .../v1/restore_item_action.go | 44 +------------ pkg/restore/add_pv_from_pvc_action.go | 7 +-- pkg/restore/add_pv_from_pvc_action_test.go | 3 +- pkg/restore/add_pvc_from_pod_action.go | 5 +- pkg/restore/add_pvc_from_pod_action_test.go | 3 +- pkg/restore/admissionwebhook_config_action.go | 9 ++- .../admissionwebhook_config_action_test.go | 4 +- pkg/restore/apiservice_action.go | 5 +- pkg/restore/apiservice_action_test.go | 4 +- pkg/restore/change_pvc_node_selector.go | 15 +++-- pkg/restore/change_pvc_node_selector_test.go | 4 +- pkg/restore/change_storageclass_action.go | 9 ++- .../change_storageclass_action_test.go | 4 +- pkg/restore/clusterrolebinding_action.go | 7 +-- pkg/restore/clusterrolebinding_action_test.go | 3 +- .../crd_v1_preserve_unknown_fields_action.go | 7 +-- ..._v1_preserve_unknown_fields_action_test.go | 4 +- pkg/restore/init_restorehook_pod_action.go | 5 +- .../init_restorehook_pod_action_test.go | 4 +- pkg/restore/job_action.go | 5 +- pkg/restore/job_action_test.go | 4 +- pkg/restore/pod_action.go | 5 +- pkg/restore/pod_action_test.go | 3 +- pkg/restore/restic_restore_action.go | 7 +-- pkg/restore/restic_restore_action_test.go | 4 +- pkg/restore/restore.go | 2 +- pkg/restore/restore_test.go | 36 +++++------ pkg/restore/rolebinding_action.go | 7 +-- pkg/restore/rolebinding_action_test.go | 3 +- pkg/restore/service_account_action.go | 5 +- pkg/restore/service_account_action_test.go | 3 +- pkg/restore/service_action.go | 5 +- pkg/restore/service_action_test.go | 4 +- 40 files changed, 162 insertions(+), 164 deletions(-) create mode 100644 changelogs/unreleased/5441-sseago create mode 100644 pkg/plugin/velero/restore_item_action_shared.go diff --git a/changelogs/unreleased/5441-sseago b/changelogs/unreleased/5441-sseago new file mode 100644 index 0000000000..fd8f7b7d21 --- /dev/null +++ b/changelogs/unreleased/5441-sseago @@ -0,0 +1 @@ +moved RIA execute input/output structs back to velero package diff --git a/pkg/plugin/clientmgmt/restoreitemaction/v1/restartable_restore_item_action.go b/pkg/plugin/clientmgmt/restoreitemaction/v1/restartable_restore_item_action.go index a6b595544d..28b319eca1 100644 --- a/pkg/plugin/clientmgmt/restoreitemaction/v1/restartable_restore_item_action.go +++ b/pkg/plugin/clientmgmt/restoreitemaction/v1/restartable_restore_item_action.go @@ -99,7 +99,7 @@ func (r RestartableRestoreItemAction) AppliesTo() (velero.ResourceSelector, erro } // Execute restarts the plugin's process if needed, then delegates the call. -func (r *RestartableRestoreItemAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (r *RestartableRestoreItemAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { delegate, err := r.getDelegate() if err != nil { return nil, err diff --git a/pkg/plugin/clientmgmt/restoreitemaction/v1/restartable_restore_item_action_test.go b/pkg/plugin/clientmgmt/restoreitemaction/v1/restartable_restore_item_action_test.go index 55a0db2781..d16e3bb1fe 100644 --- a/pkg/plugin/clientmgmt/restoreitemaction/v1/restartable_restore_item_action_test.go +++ b/pkg/plugin/clientmgmt/restoreitemaction/v1/restartable_restore_item_action_test.go @@ -30,7 +30,6 @@ import ( "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/plugin/velero" mocks "github.com/vmware-tanzu/velero/pkg/plugin/velero/mocks/restoreitemaction/v1" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" ) func TestRestartableGetRestoreItemAction(t *testing.T) { @@ -108,13 +107,13 @@ func TestRestartableRestoreItemActionDelegatedFunctions(t *testing.T) { }, } - input := &riav1.RestoreItemActionExecuteInput{ + input := &velero.RestoreItemActionExecuteInput{ Item: pv, ItemFromBackup: pv, Restore: new(v1.Restore), } - output := &riav1.RestoreItemActionExecuteOutput{ + output := &velero.RestoreItemActionExecuteOutput{ UpdatedItem: &unstructured.Unstructured{ Object: map[string]interface{}{ "color": "green", diff --git a/pkg/plugin/framework/restore_item_action_client.go b/pkg/plugin/framework/restore_item_action_client.go index 35bafa0893..75490d4c2f 100644 --- a/pkg/plugin/framework/restore_item_action_client.go +++ b/pkg/plugin/framework/restore_item_action_client.go @@ -73,7 +73,7 @@ func (c *RestoreItemActionGRPCClient) AppliesTo() (velero.ResourceSelector, erro }, nil } -func (c *RestoreItemActionGRPCClient) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (c *RestoreItemActionGRPCClient) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { itemJSON, err := json.Marshal(input.Item.UnstructuredContent()) if err != nil { return nil, errors.WithStack(err) @@ -120,7 +120,7 @@ func (c *RestoreItemActionGRPCClient) Execute(input *riav1.RestoreItemActionExec additionalItems = append(additionalItems, newItem) } - return &riav1.RestoreItemActionExecuteOutput{ + return &velero.RestoreItemActionExecuteOutput{ UpdatedItem: &updatedItem, AdditionalItems: additionalItems, SkipRestore: res.SkipRestore, diff --git a/pkg/plugin/framework/restore_item_action_server.go b/pkg/plugin/framework/restore_item_action_server.go index 924929c975..bdc149c480 100644 --- a/pkg/plugin/framework/restore_item_action_server.go +++ b/pkg/plugin/framework/restore_item_action_server.go @@ -108,7 +108,7 @@ func (s *RestoreItemActionGRPCServer) Execute(ctx context.Context, req *proto.Re return nil, common.NewGRPCError(errors.WithStack(err)) } - executeOutput, err := impl.Execute(&riav1.RestoreItemActionExecuteInput{ + executeOutput, err := impl.Execute(&velero.RestoreItemActionExecuteInput{ Item: &item, ItemFromBackup: &itemFromBackup, Restore: &restoreObj, diff --git a/pkg/plugin/velero/mocks/restoreitemaction/v1/RestoreItemAction.go b/pkg/plugin/velero/mocks/restoreitemaction/v1/RestoreItemAction.go index 5bf33ed851..1bacf7b161 100644 --- a/pkg/plugin/velero/mocks/restoreitemaction/v1/RestoreItemAction.go +++ b/pkg/plugin/velero/mocks/restoreitemaction/v1/RestoreItemAction.go @@ -20,7 +20,6 @@ package v1 import ( mock "github.com/stretchr/testify/mock" velero "github.com/vmware-tanzu/velero/pkg/plugin/velero" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" ) // RestoreItemAction is an autogenerated mock type for the RestoreItemAction type @@ -50,20 +49,20 @@ func (_m *RestoreItemAction) AppliesTo() (velero.ResourceSelector, error) { } // Execute provides a mock function with given fields: input -func (_m *RestoreItemAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (_m *RestoreItemAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { ret := _m.Called(input) - var r0 *riav1.RestoreItemActionExecuteOutput - if rf, ok := ret.Get(0).(func(*riav1.RestoreItemActionExecuteInput) *riav1.RestoreItemActionExecuteOutput); ok { + var r0 *velero.RestoreItemActionExecuteOutput + if rf, ok := ret.Get(0).(func(*velero.RestoreItemActionExecuteInput) *velero.RestoreItemActionExecuteOutput); ok { r0 = rf(input) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*riav1.RestoreItemActionExecuteOutput) + r0 = ret.Get(0).(*velero.RestoreItemActionExecuteOutput) } } var r1 error - if rf, ok := ret.Get(1).(func(*riav1.RestoreItemActionExecuteInput) error); ok { + if rf, ok := ret.Get(1).(func(*velero.RestoreItemActionExecuteInput) error); ok { r1 = rf(input) } else { r1 = ret.Error(1) diff --git a/pkg/plugin/velero/restore_item_action_shared.go b/pkg/plugin/velero/restore_item_action_shared.go new file mode 100644 index 0000000000..2714d69ab6 --- /dev/null +++ b/pkg/plugin/velero/restore_item_action_shared.go @@ -0,0 +1,62 @@ +/* +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 velero + +import ( + "k8s.io/apimachinery/pkg/runtime" + + api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" +) + +// RestoreItemActionExecuteInput contains the input parameters for the ItemAction's Execute function. +type RestoreItemActionExecuteInput struct { + // Item is the item being restored. It is likely different from the pristine backed up version + // (metadata reset, changed by various restore item action plugins, etc.). + Item runtime.Unstructured + // ItemFromBackup is the item taken from the pristine backed up version of resource. + ItemFromBackup runtime.Unstructured + // Restore is the representation of the restore resource processed by Velero. + Restore *api.Restore +} + +// RestoreItemActionExecuteOutput contains the output variables for the ItemAction's Execution function. +type RestoreItemActionExecuteOutput struct { + // UpdatedItem is the item being restored mutated by ItemAction. + UpdatedItem runtime.Unstructured + + // AdditionalItems is a list of additional related items that should + // be restored. + AdditionalItems []ResourceIdentifier + + // SkipRestore tells velero to stop executing further actions + // on this item, and skip the restore step. When this field's + // value is true, AdditionalItems will be ignored. + SkipRestore bool +} + +// NewRestoreItemActionExecuteOutput creates a new RestoreItemActionExecuteOutput +func NewRestoreItemActionExecuteOutput(item runtime.Unstructured) *RestoreItemActionExecuteOutput { + return &RestoreItemActionExecuteOutput{ + UpdatedItem: item, + } +} + +// WithoutRestore returns SkipRestore for RestoreItemActionExecuteOutput +func (r *RestoreItemActionExecuteOutput) WithoutRestore() *RestoreItemActionExecuteOutput { + r.SkipRestore = true + return r +} diff --git a/pkg/plugin/velero/restoreitemaction/v1/restore_item_action.go b/pkg/plugin/velero/restoreitemaction/v1/restore_item_action.go index a50f3021f0..3398af9e1e 100644 --- a/pkg/plugin/velero/restoreitemaction/v1/restore_item_action.go +++ b/pkg/plugin/velero/restoreitemaction/v1/restore_item_action.go @@ -17,9 +17,6 @@ limitations under the License. package v1 import ( - "k8s.io/apimachinery/pkg/runtime" - - api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/plugin/velero" ) @@ -36,44 +33,5 @@ type RestoreItemAction interface { // related items that should be restored, a warning (which will be logged but will not prevent // the item from being restored) or error (which will be logged and will prevent the item // from being restored) if applicable. - Execute(input *RestoreItemActionExecuteInput) (*RestoreItemActionExecuteOutput, error) -} - -// RestoreItemActionExecuteInput contains the input parameters for the ItemAction's Execute function. -type RestoreItemActionExecuteInput struct { - // Item is the item being restored. It is likely different from the pristine backed up version - // (metadata reset, changed by various restore item action plugins, etc.). - Item runtime.Unstructured - // ItemFromBackup is the item taken from the pristine backed up version of resource. - ItemFromBackup runtime.Unstructured - // Restore is the representation of the restore resource processed by Velero. - Restore *api.Restore -} - -// RestoreItemActionExecuteOutput contains the output variables for the ItemAction's Execution function. -type RestoreItemActionExecuteOutput struct { - // UpdatedItem is the item being restored mutated by ItemAction. - UpdatedItem runtime.Unstructured - - // AdditionalItems is a list of additional related items that should - // be restored. - AdditionalItems []velero.ResourceIdentifier - - // SkipRestore tells velero to stop executing further actions - // on this item, and skip the restore step. When this field's - // value is true, AdditionalItems will be ignored. - SkipRestore bool -} - -// NewRestoreItemActionExecuteOutput creates a new RestoreItemActionExecuteOutput -func NewRestoreItemActionExecuteOutput(item runtime.Unstructured) *RestoreItemActionExecuteOutput { - return &RestoreItemActionExecuteOutput{ - UpdatedItem: item, - } -} - -// WithoutRestore returns SkipRestore for RestoreItemActionExecuteOutput -func (r *RestoreItemActionExecuteOutput) WithoutRestore() *RestoreItemActionExecuteOutput { - r.SkipRestore = true - return r + Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) } diff --git a/pkg/restore/add_pv_from_pvc_action.go b/pkg/restore/add_pv_from_pvc_action.go index 147ad553f4..04c992357f 100644 --- a/pkg/restore/add_pv_from_pvc_action.go +++ b/pkg/restore/add_pv_from_pvc_action.go @@ -24,7 +24,6 @@ import ( "github.com/vmware-tanzu/velero/pkg/kuberesource" "github.com/vmware-tanzu/velero/pkg/plugin/velero" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" ) type AddPVFromPVCAction struct { @@ -41,7 +40,7 @@ func (a *AddPVFromPVCAction) AppliesTo() (velero.ResourceSelector, error) { }, nil } -func (a *AddPVFromPVCAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (a *AddPVFromPVCAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { a.logger.Info("Executing AddPVFromPVCAction") // use input.ItemFromBackup because we need to look at status fields, which have already been @@ -54,7 +53,7 @@ func (a *AddPVFromPVCAction) Execute(input *riav1.RestoreItemActionExecuteInput) // TODO: consolidate this logic in a helper function to share with backup_pv_action.go if pvc.Status.Phase != corev1api.ClaimBound || pvc.Spec.VolumeName == "" { a.logger.Info("PVC is not bound or its volume name is empty") - return &riav1.RestoreItemActionExecuteOutput{ + return &velero.RestoreItemActionExecuteOutput{ UpdatedItem: input.Item, }, nil } @@ -65,7 +64,7 @@ func (a *AddPVFromPVCAction) Execute(input *riav1.RestoreItemActionExecuteInput) } a.logger.Infof("Adding PV %s as an additional item to restore", pvc.Spec.VolumeName) - return &riav1.RestoreItemActionExecuteOutput{ + return &velero.RestoreItemActionExecuteOutput{ UpdatedItem: input.Item, AdditionalItems: []velero.ResourceIdentifier{pv}, }, nil diff --git a/pkg/restore/add_pv_from_pvc_action_test.go b/pkg/restore/add_pv_from_pvc_action_test.go index f8b5b5aaba..b4ceb90a43 100644 --- a/pkg/restore/add_pv_from_pvc_action_test.go +++ b/pkg/restore/add_pv_from_pvc_action_test.go @@ -27,7 +27,6 @@ import ( "github.com/vmware-tanzu/velero/pkg/kuberesource" "github.com/vmware-tanzu/velero/pkg/plugin/velero" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" velerotest "github.com/vmware-tanzu/velero/pkg/test" ) @@ -90,7 +89,7 @@ func TestAddPVFromPVCActionExecute(t *testing.T) { action := &AddPVFromPVCAction{logger: velerotest.NewLogger()} - input := &riav1.RestoreItemActionExecuteInput{ + input := &velero.RestoreItemActionExecuteInput{ Item: &unstructured.Unstructured{Object: itemData}, ItemFromBackup: &unstructured.Unstructured{Object: itemFromBackupData}, } diff --git a/pkg/restore/add_pvc_from_pod_action.go b/pkg/restore/add_pvc_from_pod_action.go index b7bd60a34c..70f33d985d 100644 --- a/pkg/restore/add_pvc_from_pod_action.go +++ b/pkg/restore/add_pvc_from_pod_action.go @@ -24,7 +24,6 @@ import ( "github.com/vmware-tanzu/velero/pkg/kuberesource" "github.com/vmware-tanzu/velero/pkg/plugin/velero" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" ) type AddPVCFromPodAction struct { @@ -41,7 +40,7 @@ func (a *AddPVCFromPodAction) AppliesTo() (velero.ResourceSelector, error) { }, nil } -func (a *AddPVCFromPodAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (a *AddPVCFromPodAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { a.logger.Info("Executing AddPVCFromPodAction") var pod corev1api.Pod @@ -64,7 +63,7 @@ func (a *AddPVCFromPodAction) Execute(input *riav1.RestoreItemActionExecuteInput }) } - return &riav1.RestoreItemActionExecuteOutput{ + return &velero.RestoreItemActionExecuteOutput{ UpdatedItem: input.Item, AdditionalItems: additionalItems, }, nil diff --git a/pkg/restore/add_pvc_from_pod_action_test.go b/pkg/restore/add_pvc_from_pod_action_test.go index 529751b379..b409e5d6ef 100644 --- a/pkg/restore/add_pvc_from_pod_action_test.go +++ b/pkg/restore/add_pvc_from_pod_action_test.go @@ -28,7 +28,6 @@ import ( "github.com/vmware-tanzu/velero/pkg/kuberesource" "github.com/vmware-tanzu/velero/pkg/plugin/velero" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" velerotest "github.com/vmware-tanzu/velero/pkg/test" ) @@ -101,7 +100,7 @@ func TestAddPVCFromPodActionExecute(t *testing.T) { action := &AddPVCFromPodAction{logger: velerotest.NewLogger()} - input := &riav1.RestoreItemActionExecuteInput{ + input := &velero.RestoreItemActionExecuteInput{ Item: &unstructured.Unstructured{Object: itemData}, } diff --git a/pkg/restore/admissionwebhook_config_action.go b/pkg/restore/admissionwebhook_config_action.go index 68fa089888..8fd5c1693e 100644 --- a/pkg/restore/admissionwebhook_config_action.go +++ b/pkg/restore/admissionwebhook_config_action.go @@ -23,7 +23,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "github.com/vmware-tanzu/velero/pkg/plugin/velero" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" ) // AdmissionWebhookConfigurationAction is a RestoreItemAction plugin applicable to mutatingwebhookconfiguration and @@ -47,7 +46,7 @@ func (a *AdmissionWebhookConfigurationAction) AppliesTo() (velero.ResourceSelect // Execute will reset the value of "sideEffects" attribute of each item in the "webhooks" list to "None" if they are invalid values for // v1, such as "Unknown" or "Some" -func (a *AdmissionWebhookConfigurationAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (a *AdmissionWebhookConfigurationAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { a.logger.Info("Executing ChangeStorageClassAction") defer a.logger.Info("Done executing ChangeStorageClassAction") @@ -60,7 +59,7 @@ func (a *AdmissionWebhookConfigurationAction) Execute(input *riav1.RestoreItemAc logger := a.logger.WithField("resource_name", name) if apiVersion != "admissionregistration.k8s.io/v1" { logger.Infof("unable to handle api version: %s, skip", apiVersion) - return riav1.NewRestoreItemActionExecuteOutput(input.Item), nil + return velero.NewRestoreItemActionExecuteOutput(input.Item), nil } webhooks, ok, err := unstructured.NestedSlice(item.UnstructuredContent(), "webhooks") if err != nil { @@ -68,7 +67,7 @@ func (a *AdmissionWebhookConfigurationAction) Execute(input *riav1.RestoreItemAc } if !ok { logger.Info("webhooks is not set, skip") - return riav1.NewRestoreItemActionExecuteOutput(input.Item), nil + return velero.NewRestoreItemActionExecuteOutput(input.Item), nil } newWebhooks := make([]interface{}, 0) for i, entry := range webhooks { @@ -86,5 +85,5 @@ func (a *AdmissionWebhookConfigurationAction) Execute(input *riav1.RestoreItemAc newWebhooks = append(newWebhooks, obj) } item.UnstructuredContent()["webhooks"] = newWebhooks - return riav1.NewRestoreItemActionExecuteOutput(item), nil + return velero.NewRestoreItemActionExecuteOutput(item), nil } diff --git a/pkg/restore/admissionwebhook_config_action_test.go b/pkg/restore/admissionwebhook_config_action_test.go index a6548ae586..c6c31d2219 100644 --- a/pkg/restore/admissionwebhook_config_action_test.go +++ b/pkg/restore/admissionwebhook_config_action_test.go @@ -8,7 +8,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" + "github.com/vmware-tanzu/velero/pkg/plugin/velero" velerotest "github.com/vmware-tanzu/velero/pkg/test" ) @@ -163,7 +163,7 @@ func TestNewAdmissionWebhookConfigurationActionExecute(t *testing.T) { t.Run(tt.name, func(t *testing.T) { o := map[string]interface{}{} json.Unmarshal([]byte(tt.itemJSON), &o) - input := &riav1.RestoreItemActionExecuteInput{ + input := &velero.RestoreItemActionExecuteInput{ Item: &unstructured.Unstructured{ Object: o, }, diff --git a/pkg/restore/apiservice_action.go b/pkg/restore/apiservice_action.go index 0d9568c0b8..7f817a59e0 100644 --- a/pkg/restore/apiservice_action.go +++ b/pkg/restore/apiservice_action.go @@ -21,7 +21,6 @@ import ( "k8s.io/kube-aggregator/pkg/controllers/autoregister" "github.com/vmware-tanzu/velero/pkg/plugin/velero" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" ) type APIServiceAction struct { @@ -43,10 +42,10 @@ func (a *APIServiceAction) AppliesTo() (velero.ResourceSelector, error) { }, nil } -func (a *APIServiceAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (a *APIServiceAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { a.logger.Info("Executing APIServiceAction") defer a.logger.Info("Done executing APIServiceAction") a.logger.Infof("Skipping restore of APIService as it is managed by Kubernetes") - return riav1.NewRestoreItemActionExecuteOutput(input.Item).WithoutRestore(), nil + return velero.NewRestoreItemActionExecuteOutput(input.Item).WithoutRestore(), nil } diff --git a/pkg/restore/apiservice_action_test.go b/pkg/restore/apiservice_action_test.go index 1f9baeae92..81f4a6171c 100644 --- a/pkg/restore/apiservice_action_test.go +++ b/pkg/restore/apiservice_action_test.go @@ -25,7 +25,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" + "github.com/vmware-tanzu/velero/pkg/plugin/velero" velerotest "github.com/vmware-tanzu/velero/pkg/test" ) @@ -40,7 +40,7 @@ func TestAPIServiceActionExecuteSkipsRestore(t *testing.T) { require.NoError(t, err) action := NewAPIServiceAction(velerotest.NewLogger()) - res, err := action.Execute(&riav1.RestoreItemActionExecuteInput{ + res, err := action.Execute(&velero.RestoreItemActionExecuteInput{ Item: &unstructured.Unstructured{Object: unstructuredAPIService}, ItemFromBackup: &unstructured.Unstructured{Object: unstructuredAPIService}, }) diff --git a/pkg/restore/change_pvc_node_selector.go b/pkg/restore/change_pvc_node_selector.go index 23a3c20c90..d281d318f7 100644 --- a/pkg/restore/change_pvc_node_selector.go +++ b/pkg/restore/change_pvc_node_selector.go @@ -28,7 +28,6 @@ import ( "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/plugin/velero" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" ) // ChangePVCNodeSelectorAction updates/reset PVC's node selector @@ -62,23 +61,23 @@ func (p *ChangePVCNodeSelectorAction) AppliesTo() (velero.ResourceSelector, erro // Execute updates the pvc's selected-node annotation: // a) if node mapping found in the config map for the plugin // b) if node mentioned in annotation doesn't exist -func (p *ChangePVCNodeSelectorAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (p *ChangePVCNodeSelectorAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { p.logger.Info("Executing ChangePVCNodeSelectorAction") defer p.logger.Info("Done executing ChangePVCNodeSelectorAction") typeAcc, err := meta.TypeAccessor(input.Item) if err != nil { - return &riav1.RestoreItemActionExecuteOutput{}, err + return &velero.RestoreItemActionExecuteOutput{}, err } metadata, err := meta.Accessor(input.Item) if err != nil { - return &riav1.RestoreItemActionExecuteOutput{}, err + return &velero.RestoreItemActionExecuteOutput{}, err } annotations := metadata.GetAnnotations() if annotations == nil { - return riav1.NewRestoreItemActionExecuteOutput(input.Item), nil + return velero.NewRestoreItemActionExecuteOutput(input.Item), nil } log := p.logger.WithFields(map[string]interface{}{ @@ -91,7 +90,7 @@ func (p *ChangePVCNodeSelectorAction) Execute(input *riav1.RestoreItemActionExec node, ok := annotations["volume.kubernetes.io/selected-node"] if !ok { log.Debug("PVC doesn't have node selector") - return riav1.NewRestoreItemActionExecuteOutput(input.Item), nil + return velero.NewRestoreItemActionExecuteOutput(input.Item), nil } // fetch node mapping from configMap @@ -106,7 +105,7 @@ func (p *ChangePVCNodeSelectorAction) Execute(input *riav1.RestoreItemActionExec annotations["volume.kubernetes.io/selected-node"] = newNode metadata.SetAnnotations(annotations) log.Infof("Updating selected-node to %s from %s", newNode, node) - return riav1.NewRestoreItemActionExecuteOutput(input.Item), nil + return velero.NewRestoreItemActionExecuteOutput(input.Item), nil } // configMap doesn't have node-mapping @@ -126,7 +125,7 @@ func (p *ChangePVCNodeSelectorAction) Execute(input *riav1.RestoreItemActionExec } } - return riav1.NewRestoreItemActionExecuteOutput(input.Item), nil + return velero.NewRestoreItemActionExecuteOutput(input.Item), nil } func getNewNodeFromConfigMap(client corev1client.ConfigMapInterface, node string) (string, error) { diff --git a/pkg/restore/change_pvc_node_selector_test.go b/pkg/restore/change_pvc_node_selector_test.go index 92a6f4b311..8be3051bac 100644 --- a/pkg/restore/change_pvc_node_selector_test.go +++ b/pkg/restore/change_pvc_node_selector_test.go @@ -31,7 +31,7 @@ import ( "k8s.io/client-go/kubernetes/fake" "github.com/vmware-tanzu/velero/pkg/builder" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" + "github.com/vmware-tanzu/velero/pkg/plugin/velero" ) // TestChangePVCNodeSelectorActionExecute runs the ChangePVCNodeSelectorAction's Execute @@ -146,7 +146,7 @@ func TestChangePVCNodeSelectorActionExecute(t *testing.T) { unstructuredMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(tc.pvc) require.NoError(t, err) - input := &riav1.RestoreItemActionExecuteInput{ + input := &velero.RestoreItemActionExecuteInput{ Item: &unstructured.Unstructured{ Object: unstructuredMap, }, diff --git a/pkg/restore/change_storageclass_action.go b/pkg/restore/change_storageclass_action.go index 3349cc7925..a02b7c484e 100644 --- a/pkg/restore/change_storageclass_action.go +++ b/pkg/restore/change_storageclass_action.go @@ -31,7 +31,6 @@ import ( "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/plugin/velero" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" ) // ChangeStorageClassAction updates a PV or PVC's storage class name @@ -65,7 +64,7 @@ func (a *ChangeStorageClassAction) AppliesTo() (velero.ResourceSelector, error) // Execute updates the item's spec.storageClassName if a mapping is found // in the config map for the plugin. -func (a *ChangeStorageClassAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (a *ChangeStorageClassAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { a.logger.Info("Executing ChangeStorageClassAction") defer a.logger.Info("Done executing ChangeStorageClassAction") @@ -77,7 +76,7 @@ func (a *ChangeStorageClassAction) Execute(input *riav1.RestoreItemActionExecute if config == nil || len(config.Data) == 0 { a.logger.Debug("No storage class mappings found") - return riav1.NewRestoreItemActionExecuteOutput(input.Item), nil + return velero.NewRestoreItemActionExecuteOutput(input.Item), nil } obj, ok := input.Item.(*unstructured.Unstructured) @@ -129,7 +128,7 @@ func (a *ChangeStorageClassAction) Execute(input *riav1.RestoreItemActionExecute if err != nil { return nil, err } else if !exists { - return riav1.NewRestoreItemActionExecuteOutput(input.Item), nil + return velero.NewRestoreItemActionExecuteOutput(input.Item), nil } log.Infof("Updating item's storage class name to %s", newStorageClass) @@ -138,7 +137,7 @@ func (a *ChangeStorageClassAction) Execute(input *riav1.RestoreItemActionExecute return nil, errors.Wrap(err, "unable to set item's spec.storageClassName") } } - return riav1.NewRestoreItemActionExecuteOutput(obj), nil + return velero.NewRestoreItemActionExecuteOutput(obj), nil } func (a *ChangeStorageClassAction) isStorageClassExist(log *logrus.Entry, storageClass *string, cm *corev1.ConfigMap) (exists bool, newStorageClass string, err error) { diff --git a/pkg/restore/change_storageclass_action_test.go b/pkg/restore/change_storageclass_action_test.go index 12a663075f..65de052db2 100644 --- a/pkg/restore/change_storageclass_action_test.go +++ b/pkg/restore/change_storageclass_action_test.go @@ -32,7 +32,7 @@ import ( "k8s.io/client-go/kubernetes/fake" "github.com/vmware-tanzu/velero/pkg/builder" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" + "github.com/vmware-tanzu/velero/pkg/plugin/velero" ) // TestChangeStorageClassActionExecute runs the ChangeStorageClassAction's Execute @@ -245,7 +245,7 @@ func TestChangeStorageClassActionExecute(t *testing.T) { unstructuredMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(tc.pvOrPvcOrSTS) require.NoError(t, err) - input := &riav1.RestoreItemActionExecuteInput{ + input := &velero.RestoreItemActionExecuteInput{ Item: &unstructured.Unstructured{ Object: unstructuredMap, }, diff --git a/pkg/restore/clusterrolebinding_action.go b/pkg/restore/clusterrolebinding_action.go index eed52ba89c..851b13f098 100644 --- a/pkg/restore/clusterrolebinding_action.go +++ b/pkg/restore/clusterrolebinding_action.go @@ -24,7 +24,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "github.com/vmware-tanzu/velero/pkg/plugin/velero" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" ) // ClusterRoleBindingAction handle namespace remappings for role bindings @@ -42,10 +41,10 @@ func (a *ClusterRoleBindingAction) AppliesTo() (velero.ResourceSelector, error) }, nil } -func (a *ClusterRoleBindingAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (a *ClusterRoleBindingAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { namespaceMapping := input.Restore.Spec.NamespaceMapping if len(namespaceMapping) == 0 { - return riav1.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: input.Item.UnstructuredContent()}), nil + return velero.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: input.Item.UnstructuredContent()}), nil } clusterRoleBinding := new(rbac.ClusterRoleBinding) @@ -64,5 +63,5 @@ func (a *ClusterRoleBindingAction) Execute(input *riav1.RestoreItemActionExecute return nil, errors.WithStack(err) } - return riav1.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil + return velero.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil } diff --git a/pkg/restore/clusterrolebinding_action_test.go b/pkg/restore/clusterrolebinding_action_test.go index a68334565a..cea1c57871 100644 --- a/pkg/restore/clusterrolebinding_action_test.go +++ b/pkg/restore/clusterrolebinding_action_test.go @@ -28,7 +28,6 @@ import ( api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "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/test" ) @@ -90,7 +89,7 @@ func TestClusterRoleBindingActionExecute(t *testing.T) { require.NoError(t, err) action := NewClusterRoleBindingAction(test.NewLogger()) - res, err := action.Execute(&riav1.RestoreItemActionExecuteInput{ + res, err := action.Execute(&velero.RestoreItemActionExecuteInput{ Item: &unstructured.Unstructured{Object: roleBindingUnstructured}, ItemFromBackup: &unstructured.Unstructured{Object: roleBindingUnstructured}, Restore: &api.Restore{ diff --git a/pkg/restore/crd_v1_preserve_unknown_fields_action.go b/pkg/restore/crd_v1_preserve_unknown_fields_action.go index a9d8768056..f67d47910d 100644 --- a/pkg/restore/crd_v1_preserve_unknown_fields_action.go +++ b/pkg/restore/crd_v1_preserve_unknown_fields_action.go @@ -26,7 +26,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "github.com/vmware-tanzu/velero/pkg/plugin/velero" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" ) // CRDV1PreserveUnknownFieldsAction will take a CRD and inspect it for the API version and the PreserveUnknownFields value. @@ -46,7 +45,7 @@ func (c *CRDV1PreserveUnknownFieldsAction) AppliesTo() (velero.ResourceSelector, }, nil } -func (c *CRDV1PreserveUnknownFieldsAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (c *CRDV1PreserveUnknownFieldsAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { c.logger.Info("Executing CRDV1PreserveUnknownFieldsAction") name, _, err := unstructured.NestedString(input.Item.UnstructuredContent(), "name") @@ -63,7 +62,7 @@ func (c *CRDV1PreserveUnknownFieldsAction) Execute(input *riav1.RestoreItemActio // We don't want to "fix" anything in beta CRDs at the moment, just v1 versions with preserveunknownfields = true if version != "apiextensions.k8s.io/v1" { - return &riav1.RestoreItemActionExecuteOutput{ + return &velero.RestoreItemActionExecuteOutput{ UpdatedItem: input.Item, }, nil } @@ -103,7 +102,7 @@ func (c *CRDV1PreserveUnknownFieldsAction) Execute(input *riav1.RestoreItemActio return nil, errors.Wrap(err, "unable to convert crd to runtime.Unstructured") } - return &riav1.RestoreItemActionExecuteOutput{ + return &velero.RestoreItemActionExecuteOutput{ UpdatedItem: &unstructured.Unstructured{Object: res}, }, nil } diff --git a/pkg/restore/crd_v1_preserve_unknown_fields_action_test.go b/pkg/restore/crd_v1_preserve_unknown_fields_action_test.go index 3840918ad5..77045b596d 100644 --- a/pkg/restore/crd_v1_preserve_unknown_fields_action_test.go +++ b/pkg/restore/crd_v1_preserve_unknown_fields_action_test.go @@ -24,7 +24,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "github.com/vmware-tanzu/velero/pkg/builder" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" + "github.com/vmware-tanzu/velero/pkg/plugin/velero" "github.com/vmware-tanzu/velero/pkg/test" ) @@ -48,6 +48,6 @@ func TestExecuteForACRDWithAnIntOnAFloat64FieldShouldWork(t *testing.T) { a := NewCRDV1PreserveUnknownFieldsAction(test.NewLogger()) - _, err = a.Execute(&riav1.RestoreItemActionExecuteInput{Item: &u}) + _, err = a.Execute(&velero.RestoreItemActionExecuteInput{Item: &u}) require.NoError(t, err) } diff --git a/pkg/restore/init_restorehook_pod_action.go b/pkg/restore/init_restorehook_pod_action.go index cb72e14d4f..f994d811de 100644 --- a/pkg/restore/init_restorehook_pod_action.go +++ b/pkg/restore/init_restorehook_pod_action.go @@ -24,7 +24,6 @@ import ( "github.com/vmware-tanzu/velero/internal/hook" "github.com/vmware-tanzu/velero/pkg/kuberesource" "github.com/vmware-tanzu/velero/pkg/plugin/velero" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" ) // InitRestoreHookPodAction is a RestoreItemAction plugin applicable to pods that runs @@ -46,7 +45,7 @@ func (a *InitRestoreHookPodAction) AppliesTo() (velero.ResourceSelector, error) } // Execute implements the RestoreItemAction plugin interface method. -func (a *InitRestoreHookPodAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (a *InitRestoreHookPodAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { a.logger.Infof("Executing InitRestoreHookPodAction") // handle any init container restore hooks for the pod restoreHooks, err := hook.GetRestoreHooksFromSpec(&input.Restore.Spec.Hooks) @@ -61,5 +60,5 @@ func (a *InitRestoreHookPodAction) Execute(input *riav1.RestoreItemActionExecute } a.logger.Infof("Returning from InitRestoreHookPodAction") - return riav1.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: postHooksItem.UnstructuredContent()}), nil + return velero.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: postHooksItem.UnstructuredContent()}), nil } diff --git a/pkg/restore/init_restorehook_pod_action_test.go b/pkg/restore/init_restorehook_pod_action_test.go index 058865660a..c69d3c23f9 100644 --- a/pkg/restore/init_restorehook_pod_action_test.go +++ b/pkg/restore/init_restorehook_pod_action_test.go @@ -29,7 +29,7 @@ import ( velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/builder" "github.com/vmware-tanzu/velero/pkg/kuberesource" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" + "github.com/vmware-tanzu/velero/pkg/plugin/velero" velerotest "github.com/vmware-tanzu/velero/pkg/test" ) @@ -125,7 +125,7 @@ func TestInitContainerRestoreHookPodActionExecute(t *testing.T) { unstructuredPod, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&tc.obj) require.NoError(t, err) - res, err := action.Execute(&riav1.RestoreItemActionExecuteInput{ + res, err := action.Execute(&velero.RestoreItemActionExecuteInput{ Item: &unstructured.Unstructured{Object: unstructuredPod}, ItemFromBackup: &unstructured.Unstructured{Object: unstructuredPod}, Restore: tc.restore, diff --git a/pkg/restore/job_action.go b/pkg/restore/job_action.go index 4e20f9cc92..fbaf30b249 100644 --- a/pkg/restore/job_action.go +++ b/pkg/restore/job_action.go @@ -24,7 +24,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "github.com/vmware-tanzu/velero/pkg/plugin/velero" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" ) type JobAction struct { @@ -41,7 +40,7 @@ func (a *JobAction) AppliesTo() (velero.ResourceSelector, error) { }, nil } -func (a *JobAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (a *JobAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { job := new(batchv1api.Job) if err := runtime.DefaultUnstructuredConverter.FromUnstructured(input.Item.UnstructuredContent(), job); err != nil { return nil, errors.WithStack(err) @@ -57,5 +56,5 @@ func (a *JobAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1. return nil, errors.WithStack(err) } - return riav1.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil + return velero.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil } diff --git a/pkg/restore/job_action_test.go b/pkg/restore/job_action_test.go index 0b15bc47f0..606dd089d8 100644 --- a/pkg/restore/job_action_test.go +++ b/pkg/restore/job_action_test.go @@ -27,7 +27,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" + "github.com/vmware-tanzu/velero/pkg/plugin/velero" velerotest "github.com/vmware-tanzu/velero/pkg/test" ) @@ -138,7 +138,7 @@ func TestJobActionExecute(t *testing.T) { unstructuredJob, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&test.obj) require.NoError(t, err) - res, err := action.Execute(&riav1.RestoreItemActionExecuteInput{ + res, err := action.Execute(&velero.RestoreItemActionExecuteInput{ Item: &unstructured.Unstructured{Object: unstructuredJob}, ItemFromBackup: &unstructured.Unstructured{Object: unstructuredJob}, Restore: nil, diff --git a/pkg/restore/pod_action.go b/pkg/restore/pod_action.go index 35d9d75220..d4bdc13847 100644 --- a/pkg/restore/pod_action.go +++ b/pkg/restore/pod_action.go @@ -27,7 +27,6 @@ import ( "github.com/vmware-tanzu/velero/pkg/kuberesource" "github.com/vmware-tanzu/velero/pkg/plugin/velero" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" ) type PodAction struct { @@ -44,7 +43,7 @@ func (a *PodAction) AppliesTo() (velero.ResourceSelector, error) { }, nil } -func (a *PodAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (a *PodAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { pod := new(v1.Pod) if err := runtime.DefaultUnstructuredConverter.FromUnstructured(input.Item.UnstructuredContent(), pod); err != nil { return nil, errors.WithStack(err) @@ -87,7 +86,7 @@ func (a *PodAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1. if err != nil { return nil, errors.WithStack(err) } - restoreExecuteOutput := riav1.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}) + restoreExecuteOutput := velero.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}) if pod.Spec.PriorityClassName != "" { a.logger.Infof("Adding priorityclass %s to AdditionalItems", pod.Spec.PriorityClassName) restoreExecuteOutput.AdditionalItems = []velero.ResourceIdentifier{ diff --git a/pkg/restore/pod_action_test.go b/pkg/restore/pod_action_test.go index c8121df673..f1aa83c1a3 100644 --- a/pkg/restore/pod_action_test.go +++ b/pkg/restore/pod_action_test.go @@ -28,7 +28,6 @@ import ( "github.com/vmware-tanzu/velero/pkg/kuberesource" "github.com/vmware-tanzu/velero/pkg/plugin/velero" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" velerotest "github.com/vmware-tanzu/velero/pkg/test" ) @@ -230,7 +229,7 @@ func TestPodActionExecute(t *testing.T) { unstructuredPod, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&test.obj) require.NoError(t, err) - res, err := action.Execute(&riav1.RestoreItemActionExecuteInput{ + res, err := action.Execute(&velero.RestoreItemActionExecuteInput{ Item: &unstructured.Unstructured{Object: unstructuredPod}, ItemFromBackup: &unstructured.Unstructured{Object: unstructuredPod}, Restore: nil, diff --git a/pkg/restore/restic_restore_action.go b/pkg/restore/restic_restore_action.go index bf7116b8b9..f2d8df9a1d 100644 --- a/pkg/restore/restic_restore_action.go +++ b/pkg/restore/restic_restore_action.go @@ -36,7 +36,6 @@ import ( "github.com/vmware-tanzu/velero/pkg/label" "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "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/util/kube" ) @@ -67,7 +66,7 @@ func (a *ResticRestoreAction) AppliesTo() (velero.ResourceSelector, error) { }, nil } -func (a *ResticRestoreAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (a *ResticRestoreAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { a.logger.Info("Executing ResticRestoreAction") defer a.logger.Info("Done executing ResticRestoreAction") @@ -100,7 +99,7 @@ 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") - return riav1.NewRestoreItemActionExecuteOutput(input.Item), nil + return velero.NewRestoreItemActionExecuteOutput(input.Item), nil } log.Info("Restic backups for pod found") @@ -172,7 +171,7 @@ func (a *ResticRestoreAction) Execute(input *riav1.RestoreItemActionExecuteInput return nil, errors.Wrap(err, "unable to convert pod to runtime.Unstructured") } - return riav1.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil + return velero.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil } func getCommand(log logrus.FieldLogger, config *corev1.ConfigMap) []string { diff --git a/pkg/restore/restic_restore_action_test.go b/pkg/restore/restic_restore_action_test.go index 660c1fc66c..b218f4b88d 100644 --- a/pkg/restore/restic_restore_action_test.go +++ b/pkg/restore/restic_restore_action_test.go @@ -35,7 +35,7 @@ import ( "github.com/vmware-tanzu/velero/pkg/builder" "github.com/vmware-tanzu/velero/pkg/buildinfo" velerofake "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/fake" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" + "github.com/vmware-tanzu/velero/pkg/plugin/velero" velerotest "github.com/vmware-tanzu/velero/pkg/test" "github.com/vmware-tanzu/velero/pkg/util/kube" ) @@ -278,7 +278,7 @@ func TestResticRestoreActionExecute(t *testing.T) { unstructuredPodFromBackup = unstructuredPod } - input := &riav1.RestoreItemActionExecuteInput{ + input := &velero.RestoreItemActionExecuteInput{ Item: &unstructured.Unstructured{ Object: unstructuredPod, }, diff --git a/pkg/restore/restore.go b/pkg/restore/restore.go index 8705ae2127..02d882d955 100644 --- a/pkg/restore/restore.go +++ b/pkg/restore/restore.go @@ -1152,7 +1152,7 @@ func (ctx *restoreContext) restoreItem(obj *unstructured.Unstructured, groupReso } ctx.log.Infof("Executing item action for %v", &groupResource) - executeOutput, err := action.RestoreItemAction.Execute(&riav1.RestoreItemActionExecuteInput{ + executeOutput, err := action.RestoreItemAction.Execute(&velero.RestoreItemActionExecuteInput{ Item: obj, ItemFromBackup: itemFromBackup, Restore: ctx.restore, diff --git a/pkg/restore/restore_test.go b/pkg/restore/restore_test.go index f1575bc185..46ef8cdede 100644 --- a/pkg/restore/restore_test.go +++ b/pkg/restore/restore_test.go @@ -1149,17 +1149,17 @@ func (a *recordResourcesAction) AppliesTo() (velero.ResourceSelector, error) { return a.selector, nil } -func (a *recordResourcesAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (a *recordResourcesAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { metadata, err := meta.Accessor(input.Item) if err != nil { - return &riav1.RestoreItemActionExecuteOutput{ + return &velero.RestoreItemActionExecuteOutput{ UpdatedItem: input.Item, AdditionalItems: a.additionalItems, }, err } a.ids = append(a.ids, kubeutil.NamespaceAndName(metadata)) - return &riav1.RestoreItemActionExecuteOutput{ + return &velero.RestoreItemActionExecuteOutput{ UpdatedItem: input.Item, AdditionalItems: a.additionalItems, }, nil @@ -1355,12 +1355,12 @@ func TestRestoreActionsRunForCorrectItems(t *testing.T) { // function body at runtime. type pluggableAction struct { selector velero.ResourceSelector - executeFunc func(*riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) + executeFunc func(*velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) } -func (a *pluggableAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (a *pluggableAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { if a.executeFunc == nil { - return &riav1.RestoreItemActionExecuteOutput{ + return &velero.RestoreItemActionExecuteOutput{ UpdatedItem: input.Item, }, nil } @@ -1385,7 +1385,7 @@ func TestRestoreActionModifications(t *testing.T) { // method modifies the item being passed in by calling the 'modify' function on it. modifyingActionGetter := func(modify func(*unstructured.Unstructured)) *pluggableAction { return &pluggableAction{ - executeFunc: func(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { + executeFunc: func(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { obj, ok := input.Item.(*unstructured.Unstructured) if !ok { return nil, errors.Errorf("unexpected type %T", input.Item) @@ -1394,7 +1394,7 @@ func TestRestoreActionModifications(t *testing.T) { res := obj.DeepCopy() modify(res) - return &riav1.RestoreItemActionExecuteOutput{ + return &velero.RestoreItemActionExecuteOutput{ UpdatedItem: res, }, nil }, @@ -1532,8 +1532,8 @@ func TestRestoreActionAdditionalItems(t *testing.T) { actions: []riav1.RestoreItemAction{ &pluggableAction{ selector: velero.ResourceSelector{IncludedNamespaces: []string{"ns-1"}}, - executeFunc: func(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { - return &riav1.RestoreItemActionExecuteOutput{ + executeFunc: func(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { + return &velero.RestoreItemActionExecuteOutput{ UpdatedItem: input.Item, AdditionalItems: []velero.ResourceIdentifier{ {GroupResource: kuberesource.Pods, Namespace: "ns-2", Name: "pod-2"}, @@ -1554,8 +1554,8 @@ func TestRestoreActionAdditionalItems(t *testing.T) { apiResources: []*test.APIResource{test.Pods()}, actions: []riav1.RestoreItemAction{ &pluggableAction{ - executeFunc: func(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { - return &riav1.RestoreItemActionExecuteOutput{ + executeFunc: func(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { + return &velero.RestoreItemActionExecuteOutput{ UpdatedItem: input.Item, AdditionalItems: []velero.ResourceIdentifier{ {GroupResource: kuberesource.Pods, Namespace: "ns-2", Name: "pod-2"}, @@ -1579,8 +1579,8 @@ func TestRestoreActionAdditionalItems(t *testing.T) { apiResources: []*test.APIResource{test.Pods(), test.PVs()}, actions: []riav1.RestoreItemAction{ &pluggableAction{ - executeFunc: func(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { - return &riav1.RestoreItemActionExecuteOutput{ + executeFunc: func(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { + return &velero.RestoreItemActionExecuteOutput{ UpdatedItem: input.Item, AdditionalItems: []velero.ResourceIdentifier{ {GroupResource: kuberesource.PersistentVolumes, Name: "pv-1"}, @@ -1605,8 +1605,8 @@ func TestRestoreActionAdditionalItems(t *testing.T) { apiResources: []*test.APIResource{test.Pods(), test.PVs()}, actions: []riav1.RestoreItemAction{ &pluggableAction{ - executeFunc: func(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { - return &riav1.RestoreItemActionExecuteOutput{ + executeFunc: func(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { + return &velero.RestoreItemActionExecuteOutput{ UpdatedItem: input.Item, AdditionalItems: []velero.ResourceIdentifier{ {GroupResource: kuberesource.PersistentVolumes, Name: "pv-1"}, @@ -1631,8 +1631,8 @@ func TestRestoreActionAdditionalItems(t *testing.T) { apiResources: []*test.APIResource{test.Pods(), test.PVs()}, actions: []riav1.RestoreItemAction{ &pluggableAction{ - executeFunc: func(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { - return &riav1.RestoreItemActionExecuteOutput{ + executeFunc: func(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { + return &velero.RestoreItemActionExecuteOutput{ UpdatedItem: input.Item, AdditionalItems: []velero.ResourceIdentifier{ {GroupResource: kuberesource.PersistentVolumes, Name: "pv-1"}, diff --git a/pkg/restore/rolebinding_action.go b/pkg/restore/rolebinding_action.go index 55820c21f9..c402075a61 100644 --- a/pkg/restore/rolebinding_action.go +++ b/pkg/restore/rolebinding_action.go @@ -24,7 +24,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "github.com/vmware-tanzu/velero/pkg/plugin/velero" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" ) // RoleBindingAction handle namespace remappings for role bindings @@ -42,10 +41,10 @@ func (a *RoleBindingAction) AppliesTo() (velero.ResourceSelector, error) { }, nil } -func (a *RoleBindingAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (a *RoleBindingAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { namespaceMapping := input.Restore.Spec.NamespaceMapping if len(namespaceMapping) == 0 { - return riav1.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: input.Item.UnstructuredContent()}), nil + return velero.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: input.Item.UnstructuredContent()}), nil } roleBinding := new(rbac.RoleBinding) @@ -64,5 +63,5 @@ func (a *RoleBindingAction) Execute(input *riav1.RestoreItemActionExecuteInput) return nil, errors.WithStack(err) } - return riav1.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil + return velero.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil } diff --git a/pkg/restore/rolebinding_action_test.go b/pkg/restore/rolebinding_action_test.go index 2a62cf6d0d..8995df8c6d 100644 --- a/pkg/restore/rolebinding_action_test.go +++ b/pkg/restore/rolebinding_action_test.go @@ -28,7 +28,6 @@ import ( api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "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/test" ) @@ -90,7 +89,7 @@ func TestRoleBindingActionExecute(t *testing.T) { require.NoError(t, err) action := NewRoleBindingAction(test.NewLogger()) - res, err := action.Execute(&riav1.RestoreItemActionExecuteInput{ + res, err := action.Execute(&velero.RestoreItemActionExecuteInput{ Item: &unstructured.Unstructured{Object: roleBindingUnstructured}, ItemFromBackup: &unstructured.Unstructured{Object: roleBindingUnstructured}, Restore: &api.Restore{ diff --git a/pkg/restore/service_account_action.go b/pkg/restore/service_account_action.go index 424985a26e..252d9fc576 100644 --- a/pkg/restore/service_account_action.go +++ b/pkg/restore/service_account_action.go @@ -26,7 +26,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "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/util/kube" ) @@ -44,7 +43,7 @@ func (a *ServiceAccountAction) AppliesTo() (velero.ResourceSelector, error) { }, nil } -func (a *ServiceAccountAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (a *ServiceAccountAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { a.logger.Info("Executing ServiceAccountAction") defer a.logger.Info("Done executing ServiceAccountAction") @@ -76,5 +75,5 @@ func (a *ServiceAccountAction) Execute(input *riav1.RestoreItemActionExecuteInpu return nil, errors.Wrap(err, "unable to convert serviceaccount to runtime.Unstructured") } - return riav1.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil + return velero.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil } diff --git a/pkg/restore/service_account_action_test.go b/pkg/restore/service_account_action_test.go index f8bc76fcc8..0bc976a0fa 100644 --- a/pkg/restore/service_account_action_test.go +++ b/pkg/restore/service_account_action_test.go @@ -28,7 +28,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "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/test" ) @@ -91,7 +90,7 @@ func TestServiceAccountActionExecute(t *testing.T) { require.NoError(t, err) action := NewServiceAccountAction(test.NewLogger()) - res, err := action.Execute(&riav1.RestoreItemActionExecuteInput{ + res, err := action.Execute(&velero.RestoreItemActionExecuteInput{ Item: &unstructured.Unstructured{Object: saUnstructured}, ItemFromBackup: &unstructured.Unstructured{Object: saUnstructured}, Restore: nil, diff --git a/pkg/restore/service_action.go b/pkg/restore/service_action.go index d21690182e..0b22cf0959 100644 --- a/pkg/restore/service_action.go +++ b/pkg/restore/service_action.go @@ -28,7 +28,6 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "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/util/boolptr" ) @@ -48,7 +47,7 @@ func (a *ServiceAction) AppliesTo() (velero.ResourceSelector, error) { }, nil } -func (a *ServiceAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) { +func (a *ServiceAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { service := new(corev1api.Service) if err := runtime.DefaultUnstructuredConverter.FromUnstructured(input.Item.UnstructuredContent(), service); err != nil { return nil, errors.WithStack(err) @@ -73,7 +72,7 @@ func (a *ServiceAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*ri return nil, errors.WithStack(err) } - return riav1.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil + return velero.NewRestoreItemActionExecuteOutput(&unstructured.Unstructured{Object: res}), nil } func deleteNodePorts(service *corev1api.Service) error { diff --git a/pkg/restore/service_action_test.go b/pkg/restore/service_action_test.go index ccdef0729a..59fef00a15 100644 --- a/pkg/restore/service_action_test.go +++ b/pkg/restore/service_action_test.go @@ -29,7 +29,7 @@ import ( api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/builder" - riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1" + "github.com/vmware-tanzu/velero/pkg/plugin/velero" velerotest "github.com/vmware-tanzu/velero/pkg/test" ) @@ -377,7 +377,7 @@ func TestServiceActionExecute(t *testing.T) { unstructuredSvc, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&test.obj) require.NoError(t, err) - res, err := action.Execute(&riav1.RestoreItemActionExecuteInput{ + res, err := action.Execute(&velero.RestoreItemActionExecuteInput{ Item: &unstructured.Unstructured{Object: unstructuredSvc}, ItemFromBackup: &unstructured.Unstructured{Object: unstructuredSvc}, Restore: test.restore, From cf32cabddd181c71434f679f2b7e23b4a9fdb570 Mon Sep 17 00:00:00 2001 From: danfengl Date: Sat, 1 Oct 2022 02:28:59 +0000 Subject: [PATCH 2/3] fix-ctx-issue 1. Fix issue of kubectl client and server mismatch version in GitAction E2E job, refer to https://github.com/elastic/cloud-on-k8s/issues/4737; 2. Adapt to the changing of keyword for involing Kpoia as fs backupper, new installtion breaked upgrade and migration tests; 3. Accept multi-labels of Ginkgo focus as input of E2E make command; 4. Distinguish workload namespace from each tests; 5. Fix issues of not using Velero util to perform Velero commands; 6. Add snapshot test case for NamespaceMapping E2E test; 7. Collect debug bundle after catching error of Velero backup or restore command; Signed-off-by: danfengl --- .github/workflows/e2e-test-kind.yaml | 7 ++- pkg/cmd/cli/install/install.go | 48 ++++++++++---------- test/e2e/Makefile | 3 +- test/e2e/backups/schedule.go | 8 ++-- test/e2e/basic/namespace-mapping.go | 32 +++++++++---- test/e2e/basic/resources-check/namespaces.go | 1 + test/e2e/e2e_suite_test.go | 7 ++- test/e2e/migration/migration.go | 12 +++-- test/e2e/privilegesmgmt/ssr.go | 18 ++++---- test/e2e/pv-backup/pv-backup-filter.go | 6 +-- test/e2e/test/test.go | 47 ++++++++++++------- test/e2e/types.go | 4 +- test/e2e/upgrade/upgrade.go | 8 +++- test/e2e/util/kibishii/kibishii_utils.go | 7 +-- test/e2e/util/providers/azure_utils.go | 4 +- test/e2e/util/providers/common.go | 10 ++-- test/e2e/util/velero/install.go | 10 +++- test/e2e/util/velero/velero_utils.go | 38 +++++++++------- 18 files changed, 164 insertions(+), 106 deletions(-) diff --git a/.github/workflows/e2e-test-kind.yaml b/.github/workflows/e2e-test-kind.yaml index 3f079d3339..1a260c1b0b 100644 --- a/.github/workflows/e2e-test-kind.yaml +++ b/.github/workflows/e2e-test-kind.yaml @@ -117,12 +117,17 @@ jobs: aws_access_key_id=minio aws_secret_access_key=minio123 EOF + + # Match kubectl version to k8s server version + curl -LO https://dl.k8s.io/release/v${{ matrix.k8s }}/bin/linux/amd64/kubectl + sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl + GOPATH=~/go CLOUD_PROVIDER=kind \ OBJECT_STORE_PROVIDER=aws BSL_CONFIG=region=minio,s3ForcePathStyle="true",s3Url=http://$(hostname -i):9000 \ CREDS_FILE=/tmp/credential BSL_BUCKET=bucket \ ADDITIONAL_OBJECT_STORE_PROVIDER=aws ADDITIONAL_BSL_CONFIG=region=minio,s3ForcePathStyle="true",s3Url=http://$(hostname -i):9000 \ ADDITIONAL_CREDS_FILE=/tmp/credential ADDITIONAL_BSL_BUCKET=additional-bucket \ - GINKGO_FOCUS='Basic\].+\[ClusterResource' VELERO_IMAGE=velero:pr-test \ + GINKGO_FOCUS='Basic\]\[ClusterResource' VELERO_IMAGE=velero:pr-test \ make -C test/e2e run timeout-minutes: 30 - name: Upload debug bundle diff --git a/pkg/cmd/cli/install/install.go b/pkg/cmd/cli/install/install.go index f9cffa48fb..a7782aa1e4 100644 --- a/pkg/cmd/cli/install/install.go +++ b/pkg/cmd/cli/install/install.go @@ -43,29 +43,31 @@ import ( // InstallOptions collects all the options for installing Velero into a Kubernetes cluster. type InstallOptions struct { - Namespace string - Image string - BucketName string - Prefix string - ProviderName string - PodAnnotations flag.Map - PodLabels flag.Map - ServiceAccountAnnotations flag.Map - VeleroPodCPURequest string - VeleroPodMemRequest string - VeleroPodCPULimit string - VeleroPodMemLimit string - NodeAgentPodCPURequest string - NodeAgentPodMemRequest string - NodeAgentPodCPULimit string - NodeAgentPodMemLimit string - RestoreOnly bool - SecretFile string - NoSecret bool - DryRun bool - BackupStorageConfig flag.Map - VolumeSnapshotConfig flag.Map - UseNodeAgent bool + Namespace string + Image string + BucketName string + Prefix string + ProviderName string + PodAnnotations flag.Map + PodLabels flag.Map + ServiceAccountAnnotations flag.Map + VeleroPodCPURequest string + VeleroPodMemRequest string + VeleroPodCPULimit string + VeleroPodMemLimit string + NodeAgentPodCPURequest string + NodeAgentPodMemRequest string + NodeAgentPodCPULimit string + NodeAgentPodMemLimit string + RestoreOnly bool + SecretFile string + NoSecret bool + DryRun bool + BackupStorageConfig flag.Map + VolumeSnapshotConfig flag.Map + UseNodeAgent bool + //TODO remove UseRestic when migration test out of using it + UseRestic bool Wait bool UseVolumeSnapshots bool DefaultRepoMaintenanceFrequency time.Duration diff --git a/test/e2e/Makefile b/test/e2e/Makefile index 8f703cc003..6b76b8ad15 100644 --- a/test/e2e/Makefile +++ b/test/e2e/Makefile @@ -48,6 +48,7 @@ OUTPUT_DIR := _output/$(GOOS)/$(GOARCH)/bin GINKGO_FOCUS ?= GINKGO_SKIP ?= SKIP_STR := $(foreach var, $(subst ., ,$(GINKGO_SKIP)),-skip "$(var)") +FOCUS_STR := $(foreach var, $(subst ., ,$(GINKGO_FOCUS)),-focus "$(var)") VELERO_CLI ?=$$(pwd)/../../_output/bin/$(GOOS)/$(GOARCH)/velero VELERO_IMAGE ?= velero/velero:main VELERO_VERSION ?= $(VERSION) @@ -110,7 +111,7 @@ run: ginkgo (echo "Bucket to store the backups from E2E tests is required, please re-run with BSL_BUCKET="; exit 1 ) @[ "${CLOUD_PROVIDER}" ] && echo "Using cloud provider ${CLOUD_PROVIDER}" || \ (echo "Cloud provider for target cloud/plug-in provider is required, please rerun with CLOUD_PROVIDER="; exit 1) - @$(GINKGO) -v -focus="$(GINKGO_FOCUS)" $(SKIP_STR) . -- -velerocli=$(VELERO_CLI) \ + @$(GINKGO) -v $(FOCUS_STR) $(SKIP_STR) . -- -velerocli=$(VELERO_CLI) \ -velero-image=$(VELERO_IMAGE) \ -plugins=$(PLUGINS) \ -velero-version=$(VELERO_VERSION) \ diff --git a/test/e2e/backups/schedule.go b/test/e2e/backups/schedule.go index 8cabe529c6..a30ba761e6 100644 --- a/test/e2e/backups/schedule.go +++ b/test/e2e/backups/schedule.go @@ -25,7 +25,7 @@ type ScheduleBackup struct { verifyTimes int } -var ScheduleBackupTest func() = TestFunc(&ScheduleBackup{TestCase: TestCase{NSBaseName: "ns", NSIncluded: &[]string{"ns1"}}}) +var ScheduleBackupTest func() = TestFunc(&ScheduleBackup{TestCase: TestCase{NSBaseName: "schedule-test-ns", NSIncluded: &[]string{"ns1"}}}) func (n *ScheduleBackup) Init() error { n.Client = TestClientInstance @@ -45,7 +45,6 @@ func (n *ScheduleBackup) StartRun() error { n.RestoreName = n.RestoreName + "restore-ns-mapping-" + UUIDgen.String() n.ScheduleArgs = []string{ - "schedule", "create", "--namespace", VeleroCfg.VeleroNamespace, n.ScheduleName, "--include-namespaces", strings.Join(*n.NSIncluded, ","), "--schedule=*/" + fmt.Sprintf("%v", n.Period) + " * * * *", } @@ -78,7 +77,10 @@ func (n *ScheduleBackup) Backup() error { now := time.Now().Minute() triggerNow := now % n.Period if triggerNow == 0 { - Expect(VeleroCmdExec(n.Ctx, VeleroCfg.VeleroCLI, n.ScheduleArgs)).To(Succeed()) + Expect(VeleroScheduleCreate(n.Ctx, VeleroCfg.VeleroCLI, VeleroCfg.VeleroNamespace, n.ScheduleName, n.ScheduleArgs)).To(Succeed(), func() string { + RunDebug(context.Background(), VeleroCfg.VeleroCLI, VeleroCfg.VeleroNamespace, "", "") + return "Fail to restore workload" + }) break } } diff --git a/test/e2e/basic/namespace-mapping.go b/test/e2e/basic/namespace-mapping.go index 3a8d56ccef..e0b61fcf13 100644 --- a/test/e2e/basic/namespace-mapping.go +++ b/test/e2e/basic/namespace-mapping.go @@ -21,17 +21,24 @@ type NamespaceMapping struct { kibishiiData *KibishiiData } -var OneNamespaceMappingTest func() = TestFunc(&NamespaceMapping{TestCase: TestCase{NSBaseName: "ns", NSIncluded: &[]string{"ns1"}}}) -var MultiNamespacesMappingTest func() = TestFunc(&NamespaceMapping{TestCase: TestCase{NSBaseName: "ns", NSIncluded: &[]string{"ns1", "ns2"}}}) +const NamespaceBaseName string = "ns-mp-" + +var OneNamespaceMappingResticTest func() = TestFunc(&NamespaceMapping{TestCase: TestCase{NSBaseName: NamespaceBaseName, NSIncluded: &[]string{NamespaceBaseName + "1"}, UseVolumeSnapshots: false}}) +var MultiNamespacesMappingResticTest func() = TestFunc(&NamespaceMapping{TestCase: TestCase{NSBaseName: NamespaceBaseName, NSIncluded: &[]string{NamespaceBaseName + "1", NamespaceBaseName + "2"}, UseVolumeSnapshots: false}}) +var OneNamespaceMappingSnapshotTest func() = TestFunc(&NamespaceMapping{TestCase: TestCase{NSBaseName: NamespaceBaseName, NSIncluded: &[]string{NamespaceBaseName + "1"}, UseVolumeSnapshots: true}}) +var MultiNamespacesMappingSnapshotTest func() = TestFunc(&NamespaceMapping{TestCase: TestCase{NSBaseName: NamespaceBaseName, NSIncluded: &[]string{NamespaceBaseName + "1", NamespaceBaseName + "2"}, UseVolumeSnapshots: true}}) func (n *NamespaceMapping) Init() error { n.Client = TestClientInstance n.kibishiiData = &KibishiiData{2, 10, 10, 1024, 1024, 0, 2} - + backupType := "restic" + if n.UseVolumeSnapshots { + backupType = "snapshot" + } n.TestMsg = &TestMSG{ - Desc: "Backup resources with include namespace test", - FailedMSG: "Failed to backup with namespace include", - Text: fmt.Sprintf("should backup namespaces %s", *n.NSIncluded), + Desc: fmt.Sprintf("Restore namespace %s with namespace mapping by %s test", *n.NSIncluded, backupType), + FailedMSG: "Failed to restore with namespace mapping", + Text: fmt.Sprintf("should restore namespace %s with namespace mapping by %s", *n.NSIncluded, backupType), } return nil } @@ -49,15 +56,20 @@ func (n *NamespaceMapping) StartRun() error { n.BackupName = n.BackupName + ns n.RestoreName = n.RestoreName + ns } - n.BackupName = n.BackupName + "backup-ns-mapping-" + UUIDgen.String() - n.RestoreName = n.RestoreName + "restore-ns-mapping-" + UUIDgen.String() + n.BackupName = n.BackupName + UUIDgen.String() + n.RestoreName = n.RestoreName + UUIDgen.String() n.MappedNamespaceList = mappedNSList fmt.Println(mappedNSList) n.BackupArgs = []string{ "create", "--namespace", VeleroCfg.VeleroNamespace, "backup", n.BackupName, - "--include-namespaces", strings.Join(*n.NSIncluded, ","), - "--default-volumes-to-fs-backup", "--wait", + "--include-namespaces", strings.Join(*n.NSIncluded, ","), "--wait", + } + if n.UseVolumeSnapshots { + n.BackupArgs = append(n.BackupArgs, "--snapshot-volumes") + } else { + n.BackupArgs = append(n.BackupArgs, "--snapshot-volumes=false") + n.BackupArgs = append(n.BackupArgs, "--default-volumes-to-fs-backup") } n.RestoreArgs = []string{ "create", "--namespace", VeleroCfg.VeleroNamespace, "restore", n.RestoreName, diff --git a/test/e2e/basic/resources-check/namespaces.go b/test/e2e/basic/resources-check/namespaces.go index 7c1d6ad4f6..67da3481bd 100644 --- a/test/e2e/basic/resources-check/namespaces.go +++ b/test/e2e/basic/resources-check/namespaces.go @@ -121,6 +121,7 @@ func (m *MultiNSBackup) Verify() error { } func (m *MultiNSBackup) Destroy() error { + m.Ctx, _ = context.WithTimeout(context.Background(), 60*time.Minute) err := CleanupNamespaces(m.Ctx, m.Client, m.NSBaseName) if err != nil { return errors.Wrap(err, "Could cleanup retrieve namespaces") diff --git a/test/e2e/e2e_suite_test.go b/test/e2e/e2e_suite_test.go index 1025d02166..ef35b7f5da 100644 --- a/test/e2e/e2e_suite_test.go +++ b/test/e2e/e2e_suite_test.go @@ -37,6 +37,7 @@ import ( . "github.com/vmware-tanzu/velero/test/e2e/privilegesmgmt" . "github.com/vmware-tanzu/velero/test/e2e/pv-backup" . "github.com/vmware-tanzu/velero/test/e2e/resource-filtering" + . "github.com/vmware-tanzu/velero/test/e2e/scale" . "github.com/vmware-tanzu/velero/test/e2e/upgrade" @@ -126,8 +127,10 @@ var _ = Describe("[Migration][Snapshot]", MigrationWithSnapshots) var _ = Describe("[Schedule][OrederedResources] Backup resources should follow the specific order in schedule", ScheduleOrderedResources) -var _ = Describe("[NamespaceMapping][Single] Backup resources should follow the specific order in schedule", OneNamespaceMappingTest) -var _ = Describe("[NamespaceMapping][Multiple] Backup resources should follow the specific order in schedule", MultiNamespacesMappingTest) +var _ = Describe("[NamespaceMapping][Single][Restic] Backup resources should follow the specific order in schedule", OneNamespaceMappingResticTest) +var _ = Describe("[NamespaceMapping][Multiple][Restic] Backup resources should follow the specific order in schedule", MultiNamespacesMappingResticTest) +var _ = Describe("[NamespaceMapping][Single][Snapshot] Backup resources should follow the specific order in schedule", OneNamespaceMappingSnapshotTest) +var _ = Describe("[NamespaceMapping][Multiple][Snapshot] Backup resources should follow the specific order in schedule", MultiNamespacesMappingSnapshotTest) var _ = Describe("[pv-backup][Opt-In] Backup resources should follow the specific order in schedule", OptInPVBackupTest) var _ = Describe("[pv-backup][Opt-Out] Backup resources should follow the specific order in schedule", OptOutPVBackupTest) diff --git a/test/e2e/migration/migration.go b/test/e2e/migration/migration.go index 3e81d8dd15..e957ace265 100644 --- a/test/e2e/migration/migration.go +++ b/test/e2e/migration/migration.go @@ -126,6 +126,8 @@ func MigrationTest(useVolumeSnapshots bool, veleroCLI2Version VeleroCLI2Version) OriginVeleroCfg.Plugins = "" //TODO: Remove this once origin Velero version is 1.10 and upper OriginVeleroCfg.UploaderType = "" + OriginVeleroCfg.UseNodeAgent = false + OriginVeleroCfg.UseRestic = !useVolumeSnapshots } fmt.Println(OriginVeleroCfg) Expect(VeleroInstall(context.Background(), &OriginVeleroCfg, useVolumeSnapshots)).To(Succeed()) @@ -157,9 +159,9 @@ func MigrationTest(useVolumeSnapshots bool, veleroCLI2Version VeleroCLI2Version) BackupStorageClassCfg.IncludeResources = "StorageClass" BackupStorageClassCfg.IncludeClusterResources = true //TODO Remove UseRestic parameter once minor version is 1.10 or upper - BackupStorageClassCfg.UseRestic = true + BackupStorageClassCfg.UseResticIfFSBackup = true if veleroCLI2Version.VeleroVersion == "self" { - BackupStorageClassCfg.UseRestic = false + BackupStorageClassCfg.UseResticIfFSBackup = false } Expect(VeleroBackupNamespace(context.Background(), OriginVeleroCfg.VeleroCLI, @@ -175,9 +177,9 @@ func MigrationTest(useVolumeSnapshots bool, veleroCLI2Version VeleroCLI2Version) BackupCfg.BackupLocation = "" BackupCfg.Selector = "" //TODO Remove UseRestic parameter once minor version is 1.10 or upper - BackupCfg.UseRestic = true + BackupCfg.UseResticIfFSBackup = true if veleroCLI2Version.VeleroVersion == "self" { - BackupCfg.UseRestic = false + BackupCfg.UseResticIfFSBackup = false } Expect(VeleroBackupNamespace(context.Background(), OriginVeleroCfg.VeleroCLI, OriginVeleroCfg.VeleroNamespace, BackupCfg)).To(Succeed(), func() string { @@ -235,6 +237,8 @@ func MigrationTest(useVolumeSnapshots bool, veleroCLI2Version VeleroCLI2Version) VeleroCfg.ObjectStoreProvider = "" VeleroCfg.ClientToInstallVelero = VeleroCfg.StandbyClient + VeleroCfg.UseNodeAgent = !useVolumeSnapshots + VeleroCfg.UseRestic = false Expect(VeleroInstall(context.Background(), &VeleroCfg, useVolumeSnapshots)).To(Succeed()) }) diff --git a/test/e2e/privilegesmgmt/ssr.go b/test/e2e/privilegesmgmt/ssr.go index 526efb1e84..428cacc815 100644 --- a/test/e2e/privilegesmgmt/ssr.go +++ b/test/e2e/privilegesmgmt/ssr.go @@ -62,16 +62,14 @@ func SSRTest() { Expect(CreateNamespace(ctx, *VeleroCfg.ClientToInstallVelero, testNS)).To(Succeed(), fmt.Sprintf("Failed to create %s namespace", testNS)) - By(fmt.Sprintf("Get version in %s namespace", testNS)) - cmd := []string{"version", "-n", testNS} - Expect(VeleroCmdExec(context.Background(), VeleroCfg.VeleroCLI, cmd)).To(Succeed(), - fmt.Sprintf("Failed to create an ssr object in the %s namespace", testNS)) - - By(fmt.Sprintf("Get version in %s namespace", VeleroCfg.VeleroNamespace)) - cmd = []string{"version", "-n", VeleroCfg.VeleroNamespace} - Expect(VeleroCmdExec(context.Background(), VeleroCfg.VeleroCLI, cmd)).To(Succeed(), - fmt.Sprintf("Failed to create an ssr object in %s namespace", VeleroCfg.VeleroNamespace)) - + By(fmt.Sprintf("Get version in %s namespace", testNS), func() { + Expect(VeleroVersion(context.Background(), VeleroCfg.VeleroCLI, testNS)).To(Succeed(), + fmt.Sprintf("Failed to create an ssr object in the %s namespace", testNS)) + }) + By(fmt.Sprintf("Get version in %s namespace", VeleroCfg.VeleroNamespace), func() { + Expect(VeleroVersion(context.Background(), VeleroCfg.VeleroCLI, VeleroCfg.VeleroNamespace)).To(Succeed(), + fmt.Sprintf("Failed to create an ssr object in %s namespace", VeleroCfg.VeleroNamespace)) + }) ssrListResp := new(v1.ServerStatusRequestList) By(fmt.Sprintf("Check ssr object in %s namespace", VeleroCfg.VeleroNamespace)) err = waitutil.PollImmediate(5*time.Second, time.Minute, diff --git a/test/e2e/pv-backup/pv-backup-filter.go b/test/e2e/pv-backup/pv-backup-filter.go index 3de103894b..4cef609d3a 100644 --- a/test/e2e/pv-backup/pv-backup-filter.go +++ b/test/e2e/pv-backup/pv-backup-filter.go @@ -49,8 +49,8 @@ func (p *PVBackupFiltering) StartRun() error { if err != nil { return err } - p.BackupName = p.BackupName + "backup-opt-in-" + UUIDgen.String() - p.RestoreName = p.RestoreName + "restore-opt-in-" + UUIDgen.String() + p.BackupName = p.BackupName + "backup-" + p.id + "-" + UUIDgen.String() + p.RestoreName = p.RestoreName + "restore-" + p.id + "-" + UUIDgen.String() p.BackupArgs = []string{ "create", "--namespace", VeleroCfg.VeleroNamespace, "backup", p.BackupName, "--include-namespaces", strings.Join(*p.NSIncluded, ","), @@ -84,7 +84,7 @@ func (p *PVBackupFiltering) CreateResources() error { for j := 0; j <= VOLUME_COUNT_PER_POD-1; j++ { volume := fmt.Sprintf("volume-%s-%d-%d", p.id, i, j) volumes = append(volumes, volume) - //Volumes cherry pick policy for opt-in/out annotation to pods + //Volumes cherry-pick policy for opt-in/out annotation to apply if j%2 == 0 { volumeToAnnotationList = append(volumeToAnnotationList, volume) } diff --git a/test/e2e/test/test.go b/test/e2e/test/test.go index ee9218a0c1..4a754efb88 100644 --- a/test/e2e/test/test.go +++ b/test/e2e/test/test.go @@ -20,6 +20,7 @@ import ( "context" "flag" "fmt" + "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -47,6 +48,7 @@ type VeleroBackupRestoreTest interface { Verify() error Clean() error GetTestMsg() *TestMSG + GetTestCase() *TestCase } type TestMSG struct { @@ -56,16 +58,17 @@ type TestMSG struct { } type TestCase struct { - BackupName string - RestoreName string - NSBaseName string - BackupArgs []string - RestoreArgs []string - NamespacesTotal int - TestMsg *TestMSG - Client TestClient - Ctx context.Context - NSIncluded *[]string + BackupName string + RestoreName string + NSBaseName string + BackupArgs []string + RestoreArgs []string + NamespacesTotal int + TestMsg *TestMSG + Client TestClient + Ctx context.Context + NSIncluded *[]string + UseVolumeSnapshots bool } var TestClientInstance TestClient @@ -79,7 +82,7 @@ func TestFunc(test VeleroBackupRestoreTest) func() { BeforeEach(func() { flag.Parse() if VeleroCfg.InstallVelero { - Expect(VeleroInstall(context.Background(), &VeleroCfg, false)).To(Succeed()) + Expect(VeleroInstall(context.Background(), &VeleroCfg, test.GetTestCase().UseVolumeSnapshots)).To(Succeed()) } }) AfterEach(func() { @@ -101,16 +104,17 @@ func TestFuncWithMultiIt(tests []VeleroBackupRestoreTest) func() { By("Create test client instance", func() { TestClientInstance = *VeleroCfg.ClientToInstallVelero }) - + var useVolumeSnapshots bool for k := range tests { Expect(tests[k].Init()).To(Succeed(), fmt.Sprintf("Failed to instantiate test %s case", tests[k].GetTestMsg().Desc)) + useVolumeSnapshots = tests[k].GetTestCase().UseVolumeSnapshots } BeforeEach(func() { flag.Parse() if VeleroCfg.InstallVelero { if countIt == 0 { - Expect(VeleroInstall(context.Background(), &VeleroCfg, false)).To(Succeed()) + Expect(VeleroInstall(context.Background(), &VeleroCfg, useVolumeSnapshots)).To(Succeed()) } countIt++ } @@ -148,7 +152,7 @@ func (t *TestCase) StartRun() error { } func (t *TestCase) Backup() error { - if err := VeleroCmdExec(t.Ctx, VeleroCfg.VeleroCLI, t.BackupArgs); err != nil { + if err := VeleroBackupExec(t.Ctx, VeleroCfg.VeleroCLI, VeleroCfg.VeleroNamespace, t.BackupName, t.BackupArgs); err != nil { RunDebug(context.Background(), VeleroCfg.VeleroCLI, VeleroCfg.VeleroNamespace, t.BackupName, "") return errors.Wrapf(err, "Failed to backup resources") } @@ -164,9 +168,17 @@ func (t *TestCase) Destroy() error { } func (t *TestCase) Restore() error { + // the snapshots of AWS may be still in pending status when do the restore, wait for a while + // to avoid this https://github.com/vmware-tanzu/velero/issues/1799 + // TODO remove this after https://github.com/vmware-tanzu/velero/issues/3533 is fixed + if t.UseVolumeSnapshots { + fmt.Println("Waiting 5 minutes to make sure the snapshots are ready...") + time.Sleep(5 * time.Minute) + } + By("Start to restore ......", func() { - Expect(VeleroCmdExec(t.Ctx, VeleroCfg.VeleroCLI, t.RestoreArgs)).To(Succeed(), func() string { - RunDebug(context.Background(), VeleroCfg.VeleroCLI, VeleroCfg.VeleroNamespace, t.BackupName, "") + Expect(VeleroRestoreExec(t.Ctx, VeleroCfg.VeleroCLI, VeleroCfg.VeleroNamespace, t.RestoreName, t.RestoreArgs)).To(Succeed(), func() string { + RunDebug(context.Background(), VeleroCfg.VeleroCLI, VeleroCfg.VeleroNamespace, "", t.RestoreName) return "Fail to restore workload" }) }) @@ -193,6 +205,9 @@ func (t *TestCase) GetTestMsg() *TestMSG { return t.TestMsg } +func (t *TestCase) GetTestCase() *TestCase { + return t +} func RunTestCase(test VeleroBackupRestoreTest) error { fmt.Printf("Running test case %s\n", test.GetTestMsg().Desc) if test == nil { diff --git a/test/e2e/types.go b/test/e2e/types.go index 068d957ebb..5215170706 100644 --- a/test/e2e/types.go +++ b/test/e2e/types.go @@ -64,6 +64,8 @@ type VerleroConfig struct { DefaultClient *TestClient StandbyClient *TestClient UploaderType string + UseNodeAgent bool + UseRestic bool } type SnapshotCheckPoint struct { @@ -87,7 +89,7 @@ type BackupConfig struct { ExcludeResources string IncludeClusterResources bool OrderedResources string - UseRestic bool + UseResticIfFSBackup bool } type VeleroCLI2Version struct { diff --git a/test/e2e/upgrade/upgrade.go b/test/e2e/upgrade/upgrade.go index a46231b464..120deb9787 100644 --- a/test/e2e/upgrade/upgrade.go +++ b/test/e2e/upgrade/upgrade.go @@ -113,6 +113,8 @@ func BackupUpgradeRestoreTest(useVolumeSnapshots bool, veleroCLI2Version VeleroC tmpCfgForOldVeleroInstall.ResticHelperImage = "" tmpCfgForOldVeleroInstall.Plugins = "" tmpCfgForOldVeleroInstall.UploaderType = "" + tmpCfgForOldVeleroInstall.UseNodeAgent = false + tmpCfgForOldVeleroInstall.UseRestic = !useVolumeSnapshots Expect(VeleroInstall(context.Background(), &tmpCfgForOldVeleroInstall, useVolumeSnapshots)).To(Succeed()) @@ -144,8 +146,8 @@ func BackupUpgradeRestoreTest(useVolumeSnapshots bool, veleroCLI2Version VeleroC BackupCfg.BackupLocation = "" BackupCfg.UseVolumeSnapshots = useVolumeSnapshots BackupCfg.Selector = "" - //TODO: pay attention to this param - BackupCfg.UseRestic = true + //TODO: pay attention to this param, remove it when restic is not the default backup tool any more. + BackupCfg.UseResticIfFSBackup = true Expect(VeleroBackupNamespace(oneHourTimeout, tmpCfg.UpgradeFromVeleroCLI, tmpCfg.VeleroNamespace, BackupCfg)).To(Succeed(), func() string { RunDebug(context.Background(), tmpCfg.UpgradeFromVeleroCLI, tmpCfg.VeleroNamespace, @@ -196,6 +198,8 @@ func BackupUpgradeRestoreTest(useVolumeSnapshots bool, veleroCLI2Version VeleroC By(fmt.Sprintf("Upgrade Velero by CLI %s", tmpCfg.VeleroCLI), func() { tmpCfg.GCFrequency = "" + tmpCfg.UseNodeAgent = !useVolumeSnapshots + tmpCfg.UseRestic = false Expect(VeleroInstall(context.Background(), &tmpCfg, useVolumeSnapshots)).To(Succeed()) Expect(CheckVeleroVersion(context.Background(), tmpCfg.VeleroCLI, tmpCfg.VeleroVersion)).To(Succeed()) diff --git a/test/e2e/util/kibishii/kibishii_utils.go b/test/e2e/util/kibishii/kibishii_utils.go index b87f3e03bf..016fa072de 100644 --- a/test/e2e/util/kibishii/kibishii_utils.go +++ b/test/e2e/util/kibishii/kibishii_utils.go @@ -120,12 +120,11 @@ func RunKibishiiTests(client TestClient, veleroCfg VerleroConfig, backupName, re if err := DeleteNamespace(oneHourTimeout, client, kibishiiNamespace, true); err != nil { return errors.Wrapf(err, "failed to delete namespace %s", kibishiiNamespace) } - time.Sleep(5 * time.Minute) // the snapshots of AWS may be still in pending status when do the restore, wait for a while // to avoid this https://github.com/vmware-tanzu/velero/issues/1799 // TODO remove this after https://github.com/vmware-tanzu/velero/issues/3533 is fixed - if providerName == "aws" && useVolumeSnapshots { + if useVolumeSnapshots { fmt.Println("Waiting 5 minutes to make sure the snapshots are ready...") time.Sleep(5 * time.Minute) } @@ -138,7 +137,6 @@ func RunKibishiiTests(client TestClient, veleroCfg VerleroConfig, backupName, re if err := KibishiiVerifyAfterRestore(client, kibishiiNamespace, oneHourTimeout, DefaultKibishiiData); err != nil { return errors.Wrapf(err, "Error verifying kibishii after restore") } - fmt.Printf("kibishii test completed successfully\n") return nil } @@ -151,8 +149,7 @@ func installKibishii(ctx context.Context, namespace string, cloudPlatform, veler } // We use kustomize to generate YAML for Kibishii from the checked-in yaml directories kibishiiInstallCmd := exec.CommandContext(ctx, "kubectl", "apply", "-n", namespace, "-k", - kibishiiDirectory+cloudPlatform) - + kibishiiDirectory+cloudPlatform, "--timeout=90s") _, stderr, err := veleroexec.RunCommand(kibishiiInstallCmd) fmt.Printf("Install Kibishii cmd: %s\n", kibishiiInstallCmd) if err != nil { diff --git a/test/e2e/util/providers/azure_utils.go b/test/e2e/util/providers/azure_utils.go index 8c579c74fb..1dce4cb5b9 100644 --- a/test/e2e/util/providers/azure_utils.go +++ b/test/e2e/util/providers/azure_utils.go @@ -364,10 +364,10 @@ func (s AzureStorage) IsSnapshotExisted(cloudCredentialsFile, bslConfig, backupN snapshotCountFound := 0 backupNameInSnapshot := "" if err != nil { - errors.Wrap(err, fmt.Sprintf("Fail to list snapshots %s\n", envVars[resourceGroupEnvVar])) + return errors.Wrap(err, fmt.Sprintf("Fail to list snapshots %s\n", envVars[resourceGroupEnvVar])) } if result.Value == nil { - errors.New(fmt.Sprintf("No snapshots in Azure resource group %s\n", envVars[resourceGroupEnvVar])) + return errors.New(fmt.Sprintf("No snapshots in Azure resource group %s\n", envVars[resourceGroupEnvVar])) } for _, v := range *result.Value { if snapshotCheck.EnableCSI { diff --git a/test/e2e/util/providers/common.go b/test/e2e/util/providers/common.go index 61ffd1bf97..8c37d79d9e 100644 --- a/test/e2e/util/providers/common.go +++ b/test/e2e/util/providers/common.go @@ -46,7 +46,7 @@ func ObjectsShouldBeInBucket(cloudProvider, cloudCredentialsFile, bslBucket, bsl func ObjectsShouldNotBeInBucket(cloudProvider, cloudCredentialsFile, bslBucket, bslPrefix, bslConfig, backupName, subPrefix string, retryTimes int) error { var err error var exist bool - fmt.Printf("|| VERIFICATION || - %s %s should not exist in storage %s\n", subPrefix, backupName, bslPrefix) + fmt.Printf("|| VERIFICATION || - %s %s should not exist in object store %s\n", subPrefix, backupName, bslPrefix) for i := 0; i < retryTimes; i++ { exist, err = IsObjectsInBucket(cloudProvider, cloudCredentialsFile, bslBucket, bslPrefix, bslConfig, backupName, subPrefix) if err != nil { @@ -114,9 +114,9 @@ func SnapshotsShouldNotExistInCloud(cloudProvider, cloudCredentialsFile, bslBuck snapshotCheckPoint.ExpectCount = 0 err := IsSnapshotExisted(cloudProvider, cloudCredentialsFile, bslBucket, bslConfig, backupName, snapshotCheckPoint) if err != nil { - return errors.Wrapf(err, fmt.Sprintf("|| UNEXPECTED ||Snapshots %s is existed in cloud after backup as expected", backupName)) + return errors.Wrapf(err, fmt.Sprintf("|| UNEXPECTED ||Snapshots %s exist in cloud after backup as expected", backupName)) } - fmt.Printf("|| EXPECTED || - Snapshots are not existed in cloud, backup %s\n", backupName) + fmt.Printf("|| EXPECTED || - Snapshots do not exist in cloud, backup %s\n", backupName) return nil } @@ -124,9 +124,9 @@ func SnapshotsShouldBeCreatedInCloud(cloudProvider, cloudCredentialsFile, bslBuc fmt.Printf("|| VERIFICATION || - Snapshots should exist in cloud, backup %s\n", backupName) err := IsSnapshotExisted(cloudProvider, cloudCredentialsFile, bslBucket, bslConfig, backupName, snapshotCheckPoint) if err != nil { - return errors.Wrapf(err, fmt.Sprintf("|| UNEXPECTED ||Snapshots %s are not existed in cloud after backup as expected", backupName)) + return errors.Wrapf(err, fmt.Sprintf("|| UNEXPECTED ||Snapshots %s do not exist in cloud after backup as expected", backupName)) } - fmt.Printf("|| EXPECTED || - Snapshots are existed in cloud, backup %s\n", backupName) + fmt.Printf("|| EXPECTED || - Snapshots exist in cloud, backup %s\n", backupName) return nil } diff --git a/test/e2e/util/velero/install.go b/test/e2e/util/velero/install.go index fc0389bc55..d3730b0bb8 100644 --- a/test/e2e/util/velero/install.go +++ b/test/e2e/util/velero/install.go @@ -87,7 +87,10 @@ func VeleroInstall(ctx context.Context, veleroCfg *VerleroConfig, useVolumeSnaps return errors.WithMessagef(err, "Failed to get Velero InstallOptions for plugin provider %s", veleroCfg.ObjectStoreProvider) } veleroInstallOptions.UseVolumeSnapshots = useVolumeSnapshots - veleroInstallOptions.UseNodeAgent = !useVolumeSnapshots + if !veleroCfg.UseRestic { + veleroInstallOptions.UseNodeAgent = !useVolumeSnapshots + } + veleroInstallOptions.UseRestic = veleroCfg.UseRestic veleroInstallOptions.Image = veleroCfg.VeleroImage veleroInstallOptions.Namespace = veleroCfg.VeleroNamespace veleroInstallOptions.UploaderType = veleroCfg.UploaderType @@ -175,6 +178,9 @@ func installVeleroServer(ctx context.Context, cli string, options *installOption if options.UseNodeAgent { args = append(args, "--use-node-agent") } + if options.UseRestic { + args = append(args, "--use-restic") + } if options.UseVolumeSnapshots { args = append(args, "--use-volume-snapshots") } @@ -285,7 +291,7 @@ func createVelereResources(ctx context.Context, cli, namespace string, args []st cmd.Stderr = os.Stderr fmt.Printf("Running cmd %q \n", cmd.String()) if err = cmd.Run(); err != nil { - return errors.Wrapf(err, "failed to apply velere resources") + return errors.Wrapf(err, "failed to apply Velero resources") } return nil diff --git a/test/e2e/util/velero/velero_utils.go b/test/e2e/util/velero/velero_utils.go index f8495865c1..ded37dd46c 100644 --- a/test/e2e/util/velero/velero_utils.go +++ b/test/e2e/util/velero/velero_utils.go @@ -323,7 +323,7 @@ func VeleroBackupNamespace(ctx context.Context, veleroCLI, veleroNamespace strin if backupCfg.UseVolumeSnapshots { args = append(args, "--snapshot-volumes") } else { - if backupCfg.UseRestic { + if backupCfg.UseResticIfFSBackup { args = append(args, "--default-volumes-to-restic") } else { args = append(args, "--default-volumes-to-fs-backup") @@ -399,6 +399,7 @@ func VeleroRestoreExec(ctx context.Context, veleroCLI, veleroNamespace, restoreN if err := VeleroCmdExec(ctx, veleroCLI, args); err != nil { return err } + return checkRestorePhase(ctx, veleroCLI, veleroNamespace, restoreName, velerov1api.RestorePhaseCompleted) } @@ -436,19 +437,14 @@ func VeleroScheduleCreate(ctx context.Context, veleroCLI string, veleroNamespace func VeleroCmdExec(ctx context.Context, veleroCLI string, args []string) error { cmd := exec.CommandContext(ctx, veleroCLI, args...) - var errBuf, outBuf bytes.Buffer - cmd.Stderr = io.MultiWriter(os.Stderr, &errBuf) - cmd.Stdout = io.MultiWriter(os.Stdout, &outBuf) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr fmt.Printf("velero cmd =%v\n", cmd) err := cmd.Run() - retAll := outBuf.String() + " " + errBuf.String() - if strings.Contains(strings.ToLower(retAll), "failed") { - return errors.Wrap(err, fmt.Sprintf("velero cmd =%v return with failure\n", cmd)) + if strings.Contains(fmt.Sprint(cmd.Stdout), "Failed") { + return errors.New(fmt.Sprintf("velero cmd =%v return with failure\n", cmd)) } - if err != nil { - return err - } - return nil + return err } func VeleroBackupLogs(ctx context.Context, veleroCLI string, veleroNamespace string, backupName string) error { @@ -511,6 +507,16 @@ func VeleroCreateBackupLocation(ctx context.Context, return VeleroCmdExec(ctx, veleroCLI, args) } +func VeleroVersion(ctx context.Context, veleroCLI, veleroNamespace string) error { + args := []string{ + "version", "--namespace", veleroNamespace, + } + if err := VeleroCmdExec(ctx, veleroCLI, args); err != nil { + return err + } + return nil +} + func getProviderPlugins(ctx context.Context, veleroCLI, objectStoreProvider, providerPlugins, feature string) ([]string, error) { // Fetch the plugins for the provider before checking for the object store provider below. var plugins []string @@ -788,12 +794,11 @@ func GetBackup(ctx context.Context, veleroCLI string, backupName string) (string func IsBackupExist(ctx context.Context, veleroCLI string, backupName string) (bool, error) { out, outerr, err := GetBackup(ctx, veleroCLI, backupName) if err != nil { - if err != nil { - if strings.Contains(outerr, "not found") { - return false, nil - } - return false, err + if strings.Contains(outerr, "not found") { + fmt.Printf("Backup CR %s was not found\n", backupName) + return false, nil } + return false, err } fmt.Printf("Backup <%s> exist locally according to output \n[%s]\n", backupName, out) return true, nil @@ -807,6 +812,7 @@ func WaitBackupDeleted(ctx context.Context, veleroCLI string, backupName string, if exist { return false, nil } else { + fmt.Printf("Backup %s does not exist\n", backupName) return true, nil } } From d52ec8c079b731acf924402c4fe0ad61165151f9 Mon Sep 17 00:00:00 2001 From: lyndon <98304688+Lyndon-Li@users.noreply.github.com> Date: Mon, 17 Oct 2022 13:42:09 +0800 Subject: [PATCH 3/3] Pod Volume Backup/Restore Refactor: Rename Init Helper (#5432) * restore helper refactor Signed-off-by: Lyndon-Li * resolve codespell Signed-off-by: Lyndon-Li Signed-off-by: Lyndon-Li --- .github/workflows/pr-codespell.yml | 2 +- Makefile | 6 +- changelogs/unreleased/5432-lyndon | 1 + .../velero-restore-helper.go} | 0 design/Implemented/backup-resources-order.md | 6 +- ...ting-velero-crds-with-structural-schema.md | 2 +- internal/hook/item_hook_handler.go | 8 +-- internal/hook/item_hook_handler_test.go | 20 +++--- internal/velero/images.go | 6 +- internal/velero/images_test.go | 4 +- pkg/cmd/server/plugin/plugin.go | 6 +- .../pod_volume_restore_controller.go | 25 ++++---- .../pod_volume_restore_controller_test.go | 62 +++++++++---------- pkg/podvolume/util.go | 14 ++--- ...action.go => pod_volume_restore_action.go} | 39 ++++++------ ...t.go => pod_volume_restore_action_test.go} | 34 +++++----- pkg/restorehelper/util.go | 33 ++++++++++ pkg/uploader/provider/provider.go | 6 +- test/e2e/Makefile | 4 +- test/e2e/e2e_suite_test.go | 2 +- test/e2e/migration/migration.go | 2 +- test/e2e/types.go | 2 +- test/e2e/upgrade/upgrade.go | 6 +- test/e2e/util/velero/install.go | 16 ++--- 24 files changed, 169 insertions(+), 137 deletions(-) create mode 100644 changelogs/unreleased/5432-lyndon rename cmd/{velero-restic-restore-helper/velero-restic-restore-helper.go => velero-restore-helper/velero-restore-helper.go} (100%) rename pkg/restore/{restic_restore_action.go => pod_volume_restore_action.go} (86%) rename pkg/restore/{restic_restore_action_test.go => pod_volume_restore_action_test.go} (89%) create mode 100644 pkg/restorehelper/util.go diff --git a/.github/workflows/pr-codespell.yml b/.github/workflows/pr-codespell.yml index 0305b84acb..36cb779f45 100644 --- a/.github/workflows/pr-codespell.yml +++ b/.github/workflows/pr-codespell.yml @@ -15,6 +15,6 @@ jobs: with: # ignore the config/.../crd.go file as it's generated binary data that is edited elswhere. skip: .git,*.png,*.jpg,*.woff,*.ttf,*.gif,*.ico,./config/crd/v1beta1/crds/crds.go,./config/crd/v1/crds/crds.go,./go.sum,./LICENSE - ignore_words_list: iam,aks,ist,bridget,ue + ignore_words_list: iam,aks,ist,bridget,ue,shouldnot check_filenames: true check_hidden: true diff --git a/Makefile b/Makefile index b3a6a32f21..4e8e728659 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/changelogs/unreleased/5432-lyndon b/changelogs/unreleased/5432-lyndon new file mode 100644 index 0000000000..f6eb6708e7 --- /dev/null +++ b/changelogs/unreleased/5432-lyndon @@ -0,0 +1 @@ +Rename Velero pod volume restore init helper from "velero-restic-restore-helper" to "velero-restore-helper" \ No newline at end of file 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/design/Implemented/backup-resources-order.md b/design/Implemented/backup-resources-order.md index 46521b76a1..d888ad2371 100644 --- a/design/Implemented/backup-resources-order.md +++ b/design/Implemented/backup-resources-order.md @@ -2,7 +2,7 @@ This document proposes a solution that allows user to specify a backup order for resources of specific resource type. ## Background -During backup process, user may need to back up resources of specific type in some specific order to ensure the resources were backup properly because these resources are related and ordering might be required to preserve the consistency for the apps to recover itself  from the backup image +During backup process, user may need to back up resources of specific type in some specific order to ensure the resources were backup properly because these resources are related and ordering might be required to preserve the consistency for the apps to recover itself �from the backup image (Ex: primary-secondary database pods in a cluster). ## Goals @@ -12,7 +12,7 @@ During backup process, user may need to back up resources of specific type in so - Use a plugin to backup an resources and all the sub resources. For example use a plugin for StatefulSet and backup pods belong to the StatefulSet in specific order. This plugin solution is not generic and requires plugin for each resource type. ## High-Level Design -User will specify a map of resource type to list resource names (separate by semicolons). Each name will be in the format "namespaceName/resourceName" to enable ordering accross namespaces. Based on this map, the resources of each resource type will be sorted by the order specified in the list of resources. If a resource instance belong to that specific type but its name is not in the order list, then it will be put behind other resources that are in the list. +User will specify a map of resource type to list resource names (separate by semicolons). Each name will be in the format "namespaceName/resourceName" to enable ordering across namespaces. Based on this map, the resources of each resource type will be sorted by the order specified in the list of resources. If a resource instance belong to that specific type but its name is not in the order list, then it will be put behind other resources that are in the list. ### Changes to BackupSpec Add new field to BackupSpec @@ -36,5 +36,5 @@ Example: >velero backup create mybackup --ordered-resources "pod=ns1/pod1,ns1/pod2;persistentvolumeclaim=n2/slavepod,ns2/primarypod" ## Open Issues -- In the CLI, the design proposes to use commas to separate items of a resource type and semicolon to separate key-value pairs. This follows the convention of using commas to separate items in a list (For example: --include-namespaces ns1,ns2). However, the syntax for map in labels and annotations use commas to seperate key-value pairs. So it introduces some inconsistency. +- In the CLI, the design proposes to use commas to separate items of a resource type and semicolon to separate key-value pairs. This follows the convention of using commas to separate items in a list (For example: --include-namespaces ns1,ns2). However, the syntax for map in labels and annotations use commas to separate key-value pairs. So it introduces some inconsistency. - For pods that managed by Deployment or DaemonSet, this design may not work because the pods' name is randomly generated and if pods are restarted, they would have different names so the Backup operation may not consider the restarted pods in the sorting algorithm. This problem will be addressed when we enhance the design to use regular expression to specify the OrderResources instead of exact match. diff --git a/design/Implemented/generating-velero-crds-with-structural-schema.md b/design/Implemented/generating-velero-crds-with-structural-schema.md index 7c8c5a127e..fe4e820de3 100644 --- a/design/Implemented/generating-velero-crds-with-structural-schema.md +++ b/design/Implemented/generating-velero-crds-with-structural-schema.md @@ -28,7 +28,7 @@ This document proposes adding _controller-tools_ to the project to automatically _controller-tools_ works by reading the Go files that contain the API type definitions. It uses a combination of the struct fields, types, tags and comments to build the OpenAPIv3 schema for the CRDs. The tooling makes some assumptions based on conventions followed in upstream Kubernetes and the ecosystem, which involves some changes to the Velero API type definitions, especially around optional fields. -In order for _controller-tools_ to read the Go files containing Velero API type defintiions, the CRDs need to be generated at build time, as these files are not available at runtime (i.e. the Go files are not accessible by the compiled binary). +In order for _controller-tools_ to read the Go files containing Velero API type definitions, the CRDs need to be generated at build time, as these files are not available at runtime (i.e. the Go files are not accessible by the compiled binary). These generated CRD manifests (YAML) will then need to be available to the `pkg/install` package for it to include when installing Velero resources. ## Detailed Design diff --git a/internal/hook/item_hook_handler.go b/internal/hook/item_hook_handler.go index 062922a056..0bced9484a 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 9f8267808c..ea2c518897 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 c6319aaddd..b21d4aff8c 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 d04c66b9dc..7d6bdf8cd9 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 64dbe4572a..bb2c1c6004 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 5292e0a01f..9c78171ae9 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 d9cdc5d264..eeec55b544 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 d75b393153..e8c1d202c4 100644 --- a/pkg/podvolume/util.go +++ b/pkg/podvolume/util.go @@ -38,17 +38,13 @@ const ( podAnnotationPrefix = "snapshot.velero.io/" // VolumesToBackupAnnotation is the annotation on a pod whose mounted volumes - // need to be backed up using restic. + // need to be backed up using pod volume backup. VolumesToBackupAnnotation = "backup.velero.io/backup-volumes" // VolumesToExcludeAnnotation is the annotation on a pod whose mounted volumes - // should be excluded from restic backup. + // should be excluded from pod volume 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 @@ -201,7 +197,7 @@ func volumeHasNonRestorableSource(volumeName string, podVolumes []corev1api.Volu // getPodSnapshotAnnotations returns a map, of volume name -> snapshot id, // of all snapshots for this pod. // TODO(2.0) to remove -// Deprecated: we will stop using pod annotations to record restic snapshot IDs after they're taken, +// Deprecated: we will stop using pod annotations to record pod volume 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 @@ -224,7 +220,7 @@ func getPodSnapshotAnnotations(obj metav1.Object) map[string]string { // GetVolumesToBackup returns a list of volume names to backup for // the provided pod. -// Deprecated: Use GetPodVolumesUsingRestic instead. +// Deprecated: Use GetVolumesByPod instead. func GetVolumesToBackup(obj metav1.Object) []string { annotations := obj.GetAnnotations() if annotations == nil { @@ -267,7 +263,7 @@ func GetVolumesByPod(pod *corev1api.Pod, defaultVolumesToFsBackup bool) []string podVolumes := []string{} for _, pv := range pod.Spec.Volumes { // cannot backup hostpath volumes as they are not mounted into /var/lib/kubelet/pods - // and therefore not accessible to the restic daemon set. + // and therefore not accessible to the node agent daemon set. if pv.HostPath != nil { continue } diff --git a/pkg/restore/restic_restore_action.go b/pkg/restore/pod_volume_restore_action.go similarity index 86% rename from pkg/restore/restic_restore_action.go rename to pkg/restore/pod_volume_restore_action.go index f2d8df9a1d..3f419c0aca 100644 --- a/pkg/restore/restic_restore_action.go +++ b/pkg/restore/pod_volume_restore_action.go @@ -37,38 +37,39 @@ import ( "github.com/vmware-tanzu/velero/pkg/plugin/framework/common" "github.com/vmware-tanzu/velero/pkg/plugin/velero" "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 *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) { - a.logger.Info("Executing ResticRestoreAction") - defer a.logger.Info("Done executing ResticRestoreAction") +func (a *PodVolumeRestoreAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.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 { @@ -98,16 +99,16 @@ func (a *ResticRestoreAction) Execute(input *velero.RestoreItemActionExecuteInpu } 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 velero.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 } @@ -146,7 +147,7 @@ func (a *ResticRestoreAction) Execute(input *velero.RestoreItemActionExecuteInpu 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) @@ -160,7 +161,7 @@ func (a *ResticRestoreAction) Execute(input *velero.RestoreItemActionExecuteInpu 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 @@ -192,13 +193,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) @@ -206,7 +207,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 @@ -264,7 +265,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), } @@ -288,8 +289,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/pod_volume_restore_action_test.go similarity index 89% rename from pkg/restore/restic_restore_action_test.go rename to pkg/restore/pod_volume_restore_action_test.go index b218f4b88d..f57ffdc69f 100644 --- a/pkg/restore/restic_restore_action_test.go +++ b/pkg/restore/pod_volume_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 pod volume 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 0000000000..f42d520085 --- /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/pkg/uploader/provider/provider.go b/pkg/uploader/provider/provider.go index 08dbb0ee52..3d0c452dc9 100644 --- a/pkg/uploader/provider/provider.go +++ b/pkg/uploader/provider/provider.go @@ -37,9 +37,9 @@ import ( const restoreProgressCheckInterval = 10 * time.Second const backupProgressCheckInterval = 10 * time.Second -// Provider which is designed for one pod volumn to do the backup or restore +// Provider which is designed for one pod volume to do the backup or restore type Provider interface { - // RunBackup which will do backup for one specific volumn and return snapshotID, isSnapshotEmpty, error + // RunBackup which will do backup for one specific volume and return snapshotID, isSnapshotEmpty, error // updater is used for updating backup progress which implement by third-party RunBackup( ctx context.Context, @@ -47,7 +47,7 @@ type Provider interface { tags map[string]string, parentSnapshot string, updater uploader.ProgressUpdater) (string, bool, error) - // RunRestore which will do restore for one specific volumn with given snapshot id and return error + // RunRestore which will do restore for one specific volume with given snapshot id and return error // updater is used for updating backup progress which implement by third-party RunRestore( ctx context.Context, diff --git a/test/e2e/Makefile b/test/e2e/Makefile index 6b76b8ad15..f33d330676 100644 --- a/test/e2e/Makefile +++ b/test/e2e/Makefile @@ -53,7 +53,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 @@ -115,7 +115,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 ef35b7f5da..0eb3697145 100644 --- a/test/e2e/e2e_suite_test.go +++ b/test/e2e/e2e_suite_test.go @@ -55,7 +55,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 e957ace265..8b163b111a 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 5215170706..95376e04a0 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 120deb9787..d91cae4395 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 = "" tmpCfgForOldVeleroInstall.UseNodeAgent = false diff --git a/test/e2e/util/velero/install.go b/test/e2e/util/velero/install.go index d3730b0bb8..7f50d780cc 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 { @@ -100,7 +100,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") @@ -224,14 +224,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 @@ -276,7 +276,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") } @@ -298,7 +298,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) @@ -342,7 +342,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", @@ -357,7 +357,7 @@ func patchResources(ctx context.Context, resources *unstructured.UnstructuredLis }, }, Data: map[string]string{ - "image": VeleroCfg.ResticHelperImage, + "image": VeleroCfg.RestoreHelperImage, }, }