From 0b9d6ae73d5322cd5ed02bdd43879c56c37aa20f Mon Sep 17 00:00:00 2001 From: Rafael Leal Date: Mon, 28 Mar 2022 14:52:01 -0300 Subject: [PATCH] Add restore status mechanism Signed-off-by: Rafael Leal --- pkg/apis/velero/v1/restore.go | 2 +- pkg/restore/restore.go | 36 +++++++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/pkg/apis/velero/v1/restore.go b/pkg/apis/velero/v1/restore.go index 6dfb0a959..251f1a045 100644 --- a/pkg/apis/velero/v1/restore.go +++ b/pkg/apis/velero/v1/restore.go @@ -90,7 +90,7 @@ type RestoreSpec struct { // field. If nil, no objects are included. Optional. // +optional // +nullable - RestoreStatus *RestoreStatusSpec + RestoreStatus *RestoreStatusSpec `json:"restoreStatus,omitempty"` // PreserveNodePorts specifies whether to restore old nodePorts from backup. // +optional diff --git a/pkg/restore/restore.go b/pkg/restore/restore.go index 3761477be..b13e97f4c 100644 --- a/pkg/restore/restore.go +++ b/pkg/restore/restore.go @@ -1127,19 +1127,30 @@ func (ctx *restoreContext) restoreItem(obj *unstructured.Unstructured, groupReso } } - // Clear out non-core metadata fields and status. - if obj, err = resetMetadataAndStatus(obj); err != nil { + // Clear out non-core metadata fields. + if obj, err = resetMetadata(obj); err != nil { errs.Add(namespace, err) return warnings, errs } + shouldRestoreStatus := ctx.resourceStatusIncludesExcludes.ShouldInclude(groupResource.String()) + + ctx.log.Infof("restore status includes excludes: %+v", ctx.resourceStatusIncludesExcludes) + // Clear out status. + if !shouldRestoreStatus { + ctx.log.Infof("Resetting status for obj %s/%s", obj.GetKind(), obj.GetName()) + if obj, err = resetStatus(obj); err != nil { + errs.Add(namespace, err) + return warnings, errs + } + } + for _, action := range ctx.getApplicableActions(groupResource, namespace) { if !action.Selector.Matches(labels.Set(obj.GetLabels())) { continue } ctx.log.Infof("Executing item action for %v", &groupResource) - executeOutput, err := action.RestoreItemAction.Execute(&velero.RestoreItemActionExecuteInput{ Item: obj, ItemFromBackup: itemFromBackup, @@ -1270,12 +1281,18 @@ func (ctx *restoreContext) restoreItem(obj *unstructured.Unstructured, groupReso return warnings, errs } // Remove insubstantial metadata. - fromCluster, err = resetMetadataAndStatus(fromCluster) + fromCluster, err = resetMetadata(fromCluster) if err != nil { ctx.log.Infof("Error trying to reset metadata for %s: %v", kube.NamespaceAndName(obj), err) warnings.Add(namespace, err) return warnings, errs } + fromCluster, err = resetStatus(fromCluster) + if err != nil { + ctx.log.Infof("Error trying to reset status for %s: %v", kube.NamespaceAndName(obj), err) + warnings.Add(namespace, err) + return warnings, errs + } // We know the object from the cluster won't have the backup/restore name // labels, so copy them from the object we attempted to restore. @@ -1373,7 +1390,8 @@ func (ctx *restoreContext) restoreItem(obj *unstructured.Unstructured, groupReso } // if it should restore status, run a UpdateStatus - if ctx.resourceStatusIncludesExcludes.ShouldInclude(groupResource.String()) { + if shouldRestoreStatus { + obj.SetResourceVersion(createdObj.GetResourceVersion()) updated, err := resourceClient.UpdateStatus(obj, metav1.UpdateOptions{}) if err != nil { warnings.Add(namespace, err) @@ -1669,7 +1687,7 @@ func resetVolumeBindingInfo(obj *unstructured.Unstructured) *unstructured.Unstru return obj } -func resetMetadataAndStatus(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) { +func resetMetadata(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) { res, ok := obj.Object["metadata"] if !ok { return nil, errors.New("metadata not found") @@ -1687,9 +1705,11 @@ func resetMetadataAndStatus(obj *unstructured.Unstructured) (*unstructured.Unstr } } - // Never restore status - delete(obj.UnstructuredContent(), "status") + return obj, nil +} +func resetStatus(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) { + delete(obj.UnstructuredContent(), "status") return obj, nil }