Disable status as sub resource in CRDs

When enabling the status as sub resource in CRD, the status will be ignored when creating the CR with status, this will cause issues when syncing backups/pvbs

Fixes #4950

Signed-off-by: Wenkai Yin(尹文开) <yinw@vmware.com>
This commit is contained in:
Wenkai Yin(尹文开)
2022-06-09 07:52:08 +08:00
parent de9ee22e26
commit 34087fe5f4
34 changed files with 82 additions and 272 deletions
+3 -21
View File
@@ -70,7 +70,6 @@ import (
"github.com/vmware-tanzu/velero/pkg/util/logging"
"github.com/vmware-tanzu/velero/pkg/volume"
"sigs.k8s.io/cluster-api/util/patch"
kbclient "sigs.k8s.io/controller-runtime/pkg/client"
)
@@ -943,10 +942,9 @@ func (c *backupController) deleteVolumeSnapshot(volumeSnapshots []*snapshotv1api
// in backup deletion.
if modifyVSCFlag {
logger.Debugf("Patching VolumeSnapshotContent %s", vsc.Name)
_, err := c.patchVolumeSnapshotContent(vsc, func(req *snapshotv1api.VolumeSnapshotContent) {
req.Spec.DeletionPolicy = snapshotv1api.VolumeSnapshotContentRetain
})
if err != nil {
original := vsc.DeepCopy()
vsc.Spec.DeletionPolicy = snapshotv1api.VolumeSnapshotContentRetain
if err := c.kbClient.Patch(context.Background(), vsc, kbclient.MergeFrom(original)); err != nil {
logger.Errorf("fail to modify VolumeSnapshotContent %s DeletionPolicy to Retain: %s", vsc.Name, err.Error())
return
}
@@ -972,22 +970,6 @@ func (c *backupController) deleteVolumeSnapshot(volumeSnapshots []*snapshotv1api
wg.Wait()
}
func (c *backupController) patchVolumeSnapshotContent(req *snapshotv1api.VolumeSnapshotContent, mutate func(*snapshotv1api.VolumeSnapshotContent)) (*snapshotv1api.VolumeSnapshotContent, error) {
patchHelper, err := patch.NewHelper(req, c.kbClient)
if err != nil {
return nil, errors.Wrap(err, "fail to get patch helper.")
}
// Mutate
mutate(req)
if err := patchHelper.Patch(context.TODO(), req); err != nil {
return nil, errors.Wrapf(err, "fail to patch VolumeSnapshotContent %s", req.Name)
}
return req, nil
}
// recreateVolumeSnapshotContent will delete then re-create VolumeSnapshotContent,
// because some parameter in VolumeSnapshotContent Spec is immutable, e.g. VolumeSnapshotRef
// and Source. Source is updated to let csi-controller thinks the VSC is statically provsisioned with VS.
+2 -7
View File
@@ -30,7 +30,6 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/clock"
kubeerrs "k8s.io/apimachinery/pkg/util/errors"
"sigs.k8s.io/cluster-api/util/patch"
ctrl "sigs.k8s.io/controller-runtime"
"github.com/vmware-tanzu/velero/internal/delete"
@@ -458,13 +457,9 @@ func (r *backupDeletionReconciler) deleteResticSnapshots(ctx context.Context, ba
}
func (r *backupDeletionReconciler) patchDeleteBackupRequest(ctx context.Context, req *velerov1api.DeleteBackupRequest, mutate func(*velerov1api.DeleteBackupRequest)) (*velerov1api.DeleteBackupRequest, error) {
patchHelper, err := patch.NewHelper(req, r.Client)
if err != nil {
return nil, errors.Wrap(err, "unable to get the patch helper")
}
// Mutate
original := req.DeepCopy()
mutate(req)
if err := patchHelper.Patch(ctx, req); err != nil {
if err := r.Patch(ctx, req, client.MergeFrom(original)); err != nil {
return nil, errors.Wrap(err, "error patching the deletebackuprquest")
}
return req, nil
@@ -26,7 +26,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/cluster-api/util/patch"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/event"
@@ -102,12 +101,8 @@ func (r *BackupStorageLocationReconciler) Reconcile(ctx context.Context, req ctr
}
func() {
// Initialize the patch helper.
patchHelper, err := patch.NewHelper(&location, r.Client)
if err != nil {
log.WithError(err).Error("Error getting a patch helper to update BackupStorageLocation")
return
}
var err error
original := location.DeepCopy()
defer func() {
location.Status.LastValidationTime = &metav1.Time{Time: time.Now().UTC()}
if err != nil {
@@ -121,7 +116,7 @@ func (r *BackupStorageLocationReconciler) Reconcile(ctx context.Context, req ctr
location.Status.Phase = velerov1api.BackupStorageLocationPhaseAvailable
location.Status.Message = ""
}
if err := patchHelper.Patch(r.Ctx, &location); err != nil {
if err := r.Client.Patch(r.Ctx, &location, client.MergeFrom(original)); err != nil {
log.WithError(err).Error("Error updating BackupStorageLocation phase")
}
}()
@@ -25,7 +25,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/clock"
"sigs.k8s.io/cluster-api/util/patch"
ctrl "sigs.k8s.io/controller-runtime"
kbclient "sigs.k8s.io/controller-runtime/pkg/client"
@@ -68,16 +67,10 @@ func (r *DownloadRequestReconciler) Reconcile(ctx context.Context, req ctrl.Requ
return ctrl.Result{}, errors.WithStack(err)
}
// Initialize the patch helper.
patchHelper, err := patch.NewHelper(downloadRequest, r.Client)
if err != nil {
log.WithError(err).Error("Error getting a patch helper to update this resource")
return ctrl.Result{}, errors.WithStack(err)
}
original := downloadRequest.DeepCopy()
defer func() {
// Always attempt to Patch the downloadRequest object and status after each reconciliation.
if err := patchHelper.Patch(ctx, downloadRequest); err != nil {
if err := r.Client.Patch(ctx, downloadRequest, kbclient.MergeFrom(original)); err != nil {
log.WithError(err).Error("Error updating download request")
return
}
@@ -143,9 +143,9 @@ var _ = Describe("Download Request Reconciler", func() {
Expect(apierrors.IsNotFound(err)).To(BeTrue())
} else {
if test.downloadRequest.Status.Phase == velerov1api.DownloadRequestPhaseProcessed {
Expect(instance).To(Equal(test.downloadRequest))
Expect(instance.Status).To(Equal(test.downloadRequest.Status))
} else {
Expect(instance).ToNot(Equal(test.downloadRequest))
Expect(instance.Status).ToNot(Equal(test.downloadRequest.Status))
}
Expect(err).To(BeNil())
}
@@ -105,7 +105,7 @@ func (r *PodVolumeBackupReconciler) Reconcile(ctx context.Context, req ctrl.Requ
original := pvb.DeepCopy()
pvb.Status.Phase = velerov1api.PodVolumeBackupPhaseInProgress
pvb.Status.StartTimestamp = &metav1.Time{Time: r.Clock.Now()}
if err := kube.Patch(ctx, original, &pvb, r.Client); err != nil {
if err := r.Client.Patch(ctx, &pvb, client.MergeFrom(original)); err != nil {
log.WithError(err).Error("error updating PodVolumeBackup status")
return ctrl.Result{}, err
}
@@ -181,7 +181,7 @@ func (r *PodVolumeBackupReconciler) Reconcile(ctx context.Context, req ctrl.Requ
if emptySnapshot {
pvb.Status.Message = "volume was empty so no snapshot was taken"
}
if err = kube.Patch(ctx, original, &pvb, r.Client); err != nil {
if err = r.Client.Patch(ctx, &pvb, client.MergeFrom(original)); err != nil {
log.WithError(err).Error("error updating PodVolumeBackup status")
return ctrl.Result{}, err
}
@@ -278,7 +278,7 @@ func (r *PodVolumeBackupReconciler) updateBackupProgressFunc(pvb *velerov1api.Po
return func(progress velerov1api.PodVolumeOperationProgress) {
original := pvb.DeepCopy()
pvb.Status.Progress = progress
if err := kube.Patch(context.Background(), original, pvb, r.Client); err != nil {
if err := r.Client.Patch(context.Background(), pvb, client.MergeFrom(original)); err != nil {
log.WithError(err).Error("error update progress")
}
}
@@ -290,7 +290,7 @@ func (r *PodVolumeBackupReconciler) updateStatusToFailed(ctx context.Context, pv
pvb.Status.Message = errors.WithMessage(err, msg).Error()
pvb.Status.CompletionTimestamp = &metav1.Time{Time: r.Clock.Now()}
if err = kube.Patch(ctx, original, pvb, r.Client); err != nil {
if err = r.Client.Patch(ctx, pvb, client.MergeFrom(original)); err != nil {
log.WithError(err).Error("error updating PodVolumeBackup status")
return ctrl.Result{}, err
}
@@ -104,7 +104,7 @@ func (c *PodVolumeRestoreReconciler) Reconcile(ctx context.Context, req ctrl.Req
original := pvr.DeepCopy()
pvr.Status.Phase = velerov1api.PodVolumeRestorePhaseInProgress
pvr.Status.StartTimestamp = &metav1.Time{Time: c.clock.Now()}
if err = kube.Patch(ctx, original, pvr, c.Client); err != nil {
if err = c.Patch(ctx, pvr, client.MergeFrom(original)); err != nil {
log.WithError(err).Error("Unable to update status to in progress")
return ctrl.Result{}, err
}
@@ -114,7 +114,7 @@ func (c *PodVolumeRestoreReconciler) Reconcile(ctx context.Context, req ctrl.Req
pvr.Status.Phase = velerov1api.PodVolumeRestorePhaseFailed
pvr.Status.Message = err.Error()
pvr.Status.CompletionTimestamp = &metav1.Time{Time: c.clock.Now()}
if e := kube.Patch(ctx, original, pvr, c.Client); e != nil {
if e := c.Patch(ctx, pvr, client.MergeFrom(original)); e != nil {
log.WithError(err).Error("Unable to update status to failed")
}
@@ -125,7 +125,7 @@ func (c *PodVolumeRestoreReconciler) Reconcile(ctx context.Context, req ctrl.Req
original = pvr.DeepCopy()
pvr.Status.Phase = velerov1api.PodVolumeRestorePhaseCompleted
pvr.Status.CompletionTimestamp = &metav1.Time{Time: c.clock.Now()}
if err = kube.Patch(ctx, original, pvr, c.Client); err != nil {
if err = c.Patch(ctx, pvr, client.MergeFrom(original)); err != nil {
log.WithError(err).Error("Unable to update status to completed")
return ctrl.Result{}, err
}
@@ -334,7 +334,7 @@ func (c *PodVolumeRestoreReconciler) updateRestoreProgressFunc(req *velerov1api.
return func(progress velerov1api.PodVolumeOperationProgress) {
original := req.DeepCopy()
req.Status.Progress = progress
if err := kube.Patch(context.Background(), original, req, c.Client); err != nil {
if err := c.Patch(context.Background(), req, client.MergeFrom(original)); err != nil {
log.WithError(err).Error("Unable to update PodVolumeRestore progress")
}
}
+22 -30
View File
@@ -27,7 +27,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/clock"
"sigs.k8s.io/cluster-api/util/patch"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -88,15 +87,8 @@ func (r *ResticRepoReconciler) Reconcile(ctx context.Context, req ctrl.Request)
return ctrl.Result{}, err
}
// Initialize the patch helper.
patchHelper, err := patch.NewHelper(resticRepo, r.Client)
if err != nil {
log.WithError(err).Error("Error getting a patch helper to update restic repository resource")
return ctrl.Result{}, errors.WithStack(err)
}
if resticRepo.Status.Phase == "" || resticRepo.Status.Phase == velerov1api.ResticRepositoryPhaseNew {
if err = r.initializeRepo(ctx, resticRepo, log, patchHelper); err != nil {
if err := r.initializeRepo(ctx, resticRepo, log); err != nil {
log.WithError(err).Error("error initialize repository")
return ctrl.Result{}, errors.WithStack(err)
}
@@ -114,15 +106,15 @@ func (r *ResticRepoReconciler) Reconcile(ctx context.Context, req ctrl.Request)
switch resticRepo.Status.Phase {
case velerov1api.ResticRepositoryPhaseReady:
return ctrl.Result{}, r.runMaintenanceIfDue(ctx, resticRepo, patchHelper, log)
return ctrl.Result{}, r.runMaintenanceIfDue(ctx, resticRepo, log)
case velerov1api.ResticRepositoryPhaseNotReady:
return ctrl.Result{}, r.checkNotReadyRepo(ctx, resticRepo, patchHelper, log)
return ctrl.Result{}, r.checkNotReadyRepo(ctx, resticRepo, log)
}
return ctrl.Result{}, nil
}
func (r *ResticRepoReconciler) initializeRepo(ctx context.Context, req *velerov1api.ResticRepository, log logrus.FieldLogger, patchHelper *patch.Helper) error {
func (r *ResticRepoReconciler) initializeRepo(ctx context.Context, req *velerov1api.ResticRepository, log logrus.FieldLogger) error {
log.Info("Initializing restic repository")
// confirm the repo's BackupStorageLocation is valid
@@ -132,12 +124,12 @@ func (r *ResticRepoReconciler) initializeRepo(ctx context.Context, req *velerov1
Namespace: req.Namespace,
Name: req.Spec.BackupStorageLocation,
}, loc); err != nil {
return r.patchResticRepository(ctx, req, patchHelper, log, repoNotReady(err.Error()))
return r.patchResticRepository(ctx, req, repoNotReady(err.Error()))
}
repoIdentifier, err := restic.GetRepoIdentifier(loc, req.Spec.VolumeNamespace)
if err != nil {
return r.patchResticRepository(ctx, req, patchHelper, log, func(rr *velerov1api.ResticRepository) {
return r.patchResticRepository(ctx, req, func(rr *velerov1api.ResticRepository) {
rr.Status.Message = err.Error()
rr.Status.Phase = velerov1api.ResticRepositoryPhaseNotReady
@@ -148,7 +140,7 @@ func (r *ResticRepoReconciler) initializeRepo(ctx context.Context, req *velerov1
}
// defaulting - if the patch fails, return an error so the item is returned to the queue
if err := r.patchResticRepository(ctx, req, patchHelper, log, func(rr *velerov1api.ResticRepository) {
if err := r.patchResticRepository(ctx, req, func(rr *velerov1api.ResticRepository) {
rr.Spec.ResticIdentifier = repoIdentifier
if rr.Spec.MaintenanceFrequency.Duration <= 0 {
@@ -159,10 +151,10 @@ func (r *ResticRepoReconciler) initializeRepo(ctx context.Context, req *velerov1
}
if err := ensureRepo(req, r.repositoryManager); err != nil {
return r.patchResticRepository(ctx, req, patchHelper, log, repoNotReady(err.Error()))
return r.patchResticRepository(ctx, req, repoNotReady(err.Error()))
}
return r.patchResticRepository(ctx, req, patchHelper, log, func(rr *velerov1api.ResticRepository) {
return r.patchResticRepository(ctx, req, func(rr *velerov1api.ResticRepository) {
rr.Status.Phase = velerov1api.ResticRepositoryPhaseReady
rr.Status.LastMaintenanceTime = &metav1.Time{Time: time.Now()}
})
@@ -187,7 +179,7 @@ func ensureRepo(repo *velerov1api.ResticRepository, repoManager restic.Repositor
return nil
}
func (r *ResticRepoReconciler) runMaintenanceIfDue(ctx context.Context, req *velerov1api.ResticRepository, patchHelper *patch.Helper, log logrus.FieldLogger) error {
func (r *ResticRepoReconciler) runMaintenanceIfDue(ctx context.Context, req *velerov1api.ResticRepository, log logrus.FieldLogger) error {
log.Debug("resticRepositoryController.runMaintenanceIfDue")
now := r.clock.Now()
@@ -204,12 +196,12 @@ func (r *ResticRepoReconciler) runMaintenanceIfDue(ctx context.Context, req *vel
log.Debug("Pruning repo")
if err := r.repositoryManager.PruneRepo(req); err != nil {
log.WithError(err).Warn("error pruning repository")
if patchErr := patchHelper.Patch(ctx, req); patchErr != nil {
req.Status.Message = err.Error()
return patchErr
}
return r.patchResticRepository(ctx, req, func(rr *velerov1api.ResticRepository) {
rr.Status.Message = err.Error()
})
}
return r.patchResticRepository(ctx, req, patchHelper, log, func(rr *velerov1api.ResticRepository) {
return r.patchResticRepository(ctx, req, func(rr *velerov1api.ResticRepository) {
rr.Status.LastMaintenanceTime = &metav1.Time{Time: now}
})
}
@@ -218,7 +210,7 @@ func dueForMaintenance(req *velerov1api.ResticRepository, now time.Time) bool {
return req.Status.LastMaintenanceTime == nil || req.Status.LastMaintenanceTime.Add(req.Spec.MaintenanceFrequency.Duration).Before(now)
}
func (r *ResticRepoReconciler) checkNotReadyRepo(ctx context.Context, req *velerov1api.ResticRepository, patchHelper *patch.Helper, log logrus.FieldLogger) error {
func (r *ResticRepoReconciler) checkNotReadyRepo(ctx context.Context, req *velerov1api.ResticRepository, log logrus.FieldLogger) error {
// no identifier: can't possibly be ready, so just return
if req.Spec.ResticIdentifier == "" {
return nil
@@ -229,9 +221,9 @@ func (r *ResticRepoReconciler) checkNotReadyRepo(ctx context.Context, req *veler
// we need to ensure it (first check, if check fails, attempt to init)
// because we don't know if it's been successfully initialized yet.
if err := ensureRepo(req, r.repositoryManager); err != nil {
return r.patchResticRepository(ctx, req, patchHelper, log, repoNotReady(err.Error()))
return r.patchResticRepository(ctx, req, repoNotReady(err.Error()))
}
return r.patchResticRepository(ctx, req, patchHelper, log, repoReady())
return r.patchResticRepository(ctx, req, repoReady())
}
func repoNotReady(msg string) func(*velerov1api.ResticRepository) {
@@ -251,11 +243,11 @@ func repoReady() func(*velerov1api.ResticRepository) {
// patchResticRepository mutates req with the provided mutate function, and patches it
// through the Kube API. After executing this function, req will be updated with both
// the mutation and the results of the Patch() API call.
func (r *ResticRepoReconciler) patchResticRepository(ctx context.Context, req *velerov1api.ResticRepository, patchHelper *patch.Helper, log logrus.FieldLogger, mutate func(*velerov1api.ResticRepository)) error {
func (r *ResticRepoReconciler) patchResticRepository(ctx context.Context, req *velerov1api.ResticRepository, mutate func(*velerov1api.ResticRepository)) error {
original := req.DeepCopy()
mutate(req)
if err := patchHelper.Patch(ctx, req); err != nil {
log.WithError(err).Errorf("error updating restic repository resource %s in namespace %s with err %s", req.Name, req.Namespace, err.Error())
return err
if err := r.Patch(ctx, req, client.MergeFrom(original)); err != nil {
return errors.Wrap(err, "error patching ResticRepository")
}
return nil
}
@@ -21,7 +21,6 @@ import (
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/cluster-api/util/patch"
ctrl "sigs.k8s.io/controller-runtime"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
@@ -63,12 +62,10 @@ func TestPatchResticRepository(t *testing.T) {
reconciler := mockResticRepoReconciler(t, rr, "", nil, nil)
err := reconciler.Client.Create(context.TODO(), rr)
assert.NoError(t, err)
patchHelper, err := patch.NewHelper(rr, reconciler.Client)
assert.NoError(t, err)
err = reconciler.patchResticRepository(context.Background(), rr, patchHelper, reconciler.logger, repoReady())
err = reconciler.patchResticRepository(context.Background(), rr, repoReady())
assert.NoError(t, err)
assert.Equal(t, rr.Status.Phase, velerov1api.ResticRepositoryPhaseReady)
err = reconciler.patchResticRepository(context.Background(), rr, patchHelper, reconciler.logger, repoNotReady("not ready"))
err = reconciler.patchResticRepository(context.Background(), rr, repoNotReady("not ready"))
assert.NoError(t, err)
assert.NotEqual(t, rr.Status.Phase, velerov1api.ResticRepositoryPhaseReady)
}
@@ -78,13 +75,11 @@ func TestCheckNotReadyRepo(t *testing.T) {
reconciler := mockResticRepoReconciler(t, rr, "ConnectToRepo", rr, nil)
err := reconciler.Client.Create(context.TODO(), rr)
assert.NoError(t, err)
patchHelper, err := patch.NewHelper(rr, reconciler.Client)
assert.NoError(t, err)
err = reconciler.checkNotReadyRepo(context.TODO(), rr, patchHelper, reconciler.logger)
err = reconciler.checkNotReadyRepo(context.TODO(), rr, reconciler.logger)
assert.NoError(t, err)
assert.Equal(t, rr.Status.Phase, velerov1api.ResticRepositoryPhase(""))
rr.Spec.ResticIdentifier = "s3:test.amazonaws.com/bucket/restic"
err = reconciler.checkNotReadyRepo(context.TODO(), rr, patchHelper, reconciler.logger)
err = reconciler.checkNotReadyRepo(context.TODO(), rr, reconciler.logger)
assert.NoError(t, err)
assert.Equal(t, rr.Status.Phase, velerov1api.ResticRepositoryPhaseReady)
}
@@ -94,16 +89,14 @@ func TestRunMaintenanceIfDue(t *testing.T) {
reconciler := mockResticRepoReconciler(t, rr, "PruneRepo", rr, nil)
err := reconciler.Client.Create(context.TODO(), rr)
assert.NoError(t, err)
patchHelper, err := patch.NewHelper(rr, reconciler.Client)
assert.NoError(t, err)
lastTm := rr.Status.LastMaintenanceTime
err = reconciler.runMaintenanceIfDue(context.TODO(), rr, patchHelper, reconciler.logger)
err = reconciler.runMaintenanceIfDue(context.TODO(), rr, reconciler.logger)
assert.NoError(t, err)
assert.NotEqual(t, rr.Status.LastMaintenanceTime, lastTm)
rr.Status.LastMaintenanceTime = &metav1.Time{Time: time.Now()}
lastTm = rr.Status.LastMaintenanceTime
err = reconciler.runMaintenanceIfDue(context.TODO(), rr, patchHelper, reconciler.logger)
err = reconciler.runMaintenanceIfDue(context.TODO(), rr, reconciler.logger)
assert.NoError(t, err)
assert.Equal(t, rr.Status.LastMaintenanceTime, lastTm)
}
@@ -114,8 +107,6 @@ func TestInitializeRepo(t *testing.T) {
reconciler := mockResticRepoReconciler(t, rr, "ConnectToRepo", rr, nil)
err := reconciler.Client.Create(context.TODO(), rr)
assert.NoError(t, err)
patchHelper, err := patch.NewHelper(rr, reconciler.Client)
assert.NoError(t, err)
locations := &velerov1api.BackupStorageLocation{
Spec: velerov1api.BackupStorageLocationSpec{
Config: map[string]string{"resticRepoPrefix": "s3:test.amazonaws.com/bucket/restic"},
@@ -128,7 +119,7 @@ func TestInitializeRepo(t *testing.T) {
err = reconciler.Client.Create(context.TODO(), locations)
assert.NoError(t, err)
err = reconciler.initializeRepo(context.TODO(), rr, reconciler.logger, patchHelper)
err = reconciler.initializeRepo(context.TODO(), rr, reconciler.logger)
assert.NoError(t, err)
assert.Equal(t, rr.Status.Phase, velerov1api.ResticRepositoryPhaseReady)
}
+4 -11
View File
@@ -27,7 +27,6 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/clock"
"sigs.k8s.io/cluster-api/util/patch"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -99,10 +98,7 @@ func (c *scheduleReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
c.metrics.InitSchedule(schedule.Name)
patchHelper, err := patch.NewHelper(schedule, c.Client)
if err != nil {
return ctrl.Result{}, errors.Wrapf(err, "error new patch helper for schedule %s", req.String())
}
original := schedule.DeepCopy()
// validation - even if the item is Enabled, we can't trust it
// so re-validate
@@ -118,7 +114,7 @@ func (c *scheduleReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
// update status if it's changed
if currentPhase != schedule.Status.Phase {
if err = patchHelper.Patch(ctx, schedule); err != nil {
if err := c.Patch(ctx, schedule, client.MergeFrom(original)); err != nil {
return ctrl.Result{}, errors.Wrapf(err, "error updating phase of schedule %s to %s", req.String(), schedule.Status.Phase)
}
}
@@ -200,13 +196,10 @@ func (c *scheduleReconciler) submitBackupIfDue(ctx context.Context, item *velero
return errors.Wrap(err, "error creating Backup")
}
patchHelper, err := patch.NewHelper(item, c.Client)
if err != nil {
return errors.Wrap(err, "error creating patch helper")
}
original := item.DeepCopy()
item.Status.LastBackup = &metav1.Time{Time: now}
if err := patchHelper.Patch(ctx, item); err != nil {
if err := c.Patch(ctx, item, client.MergeFrom(original)); err != nil {
return errors.Wrapf(err, "error updating Schedule's LastBackup time to %v", item.Status.LastBackup)
}
@@ -26,7 +26,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/clock"
"sigs.k8s.io/cluster-api/util/patch"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
@@ -88,20 +87,13 @@ func (r *ServerStatusRequestReconciler) Reconcile(ctx context.Context, req ctrl.
switch statusRequest.Status.Phase {
case "", velerov1api.ServerStatusRequestPhaseNew:
log.Info("Processing new ServerStatusRequest")
// Initialize the patch helper.
patchHelper, err := patch.NewHelper(statusRequest, r.Client)
if err != nil {
log.WithError(err).Error("Error getting a patch helper to update this resource")
return ctrl.Result{}, err
}
original := statusRequest.DeepCopy()
statusRequest.Status.ServerVersion = buildinfo.Version
statusRequest.Status.Phase = velerov1api.ServerStatusRequestPhaseProcessed
statusRequest.Status.ProcessedTimestamp = &metav1.Time{Time: r.Clock.Now()}
statusRequest.Status.Plugins = velero.GetInstalledPluginInfo(r.PluginRegistry)
if err := patchHelper.Patch(r.Ctx, statusRequest); err != nil {
if err := r.Client.Patch(r.Ctx, statusRequest, client.MergeFrom(original)); err != nil {
log.WithError(err).Error("Error updating ServerStatusRequest status")
return ctrl.Result{RequeueAfter: statusRequestResyncPeriod}, err
}