diff --git a/pkg/controller/backup_configuration.go b/pkg/controller/backup_configuration.go index 9049bac9f..7b603a014 100644 --- a/pkg/controller/backup_configuration.go +++ b/pkg/controller/backup_configuration.go @@ -34,7 +34,7 @@ import ( "stash.appscode.dev/stash/pkg/util" "gomodules.xyz/pointer" - batchv1 "k8s.io/api/batch/v1" + batchv1beta1 "k8s.io/api/batch/v1beta1" core "k8s.io/api/core/v1" kerr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -44,7 +44,7 @@ import ( "k8s.io/apimachinery/pkg/util/errors" "k8s.io/client-go/tools/cache" "k8s.io/klog/v2" - batch_util "kmodules.xyz/client-go/batch/v1" + batch_v1beta1_util "kmodules.xyz/client-go/batch/v1beta1" core_util "kmodules.xyz/client-go/core/v1" meta2 "kmodules.xyz/client-go/meta" meta_util "kmodules.xyz/client-go/meta" @@ -468,12 +468,12 @@ func (c *StashController) EnsureBackupTriggeringCronJob(inv invoker.BackupInvoke return err } } - _, _, err = batch_util.CreateOrPatchCronJob( + _, _, err = batch_v1beta1_util.CreateOrPatchCronJob( context.TODO(), c.kubeClient, meta, - func(in *batchv1.CronJob) *batchv1.CronJob { - //set backup invoker object as cron-job owner + func(in *batchv1beta1.CronJob) *batchv1beta1.CronJob { + // set backup invoker object as cron-job owner core_util.EnsureOwnerReference(&in.ObjectMeta, ownerRef) in.Spec.Schedule = inv.GetSchedule() @@ -525,18 +525,18 @@ func (c *StashController) EnsureBackupTriggeringCronJob(inv invoker.BackupInvoke // Kuebernetes garbage collector will take care of removing the CronJob func (c *StashController) EnsureBackupTriggeringCronJobDeleted(inv invoker.BackupInvoker) error { invMeta := inv.GetObjectMeta() - cur, err := c.kubeClient.BatchV1().CronJobs(invMeta.Namespace).Get(context.TODO(), getBackupCronJobName(invMeta.Name), metav1.GetOptions{}) + cur, err := c.kubeClient.BatchV1beta1().CronJobs(invMeta.Namespace).Get(context.TODO(), getBackupCronJobName(invMeta.Name), metav1.GetOptions{}) if err != nil { if kerr.IsNotFound(err) { return nil } return err } - _, _, err = batch_util.PatchCronJob( + _, _, err = batch_v1beta1_util.PatchCronJob( context.TODO(), c.kubeClient, cur, - func(in *batchv1.CronJob) *batchv1.CronJob { + func(in *batchv1beta1.CronJob) *batchv1beta1.CronJob { core_util.EnsureOwnerReference(&in.ObjectMeta, inv.GetOwnerRef()) return in }, diff --git a/test/e2e/framework/backup_configuration.go b/test/e2e/framework/backup_configuration.go index d9bd3b313..5b4b7d1e1 100644 --- a/test/e2e/framework/backup_configuration.go +++ b/test/e2e/framework/backup_configuration.go @@ -29,6 +29,7 @@ import ( . "github.com/onsi/gomega" "gomodules.xyz/x/crypto/rand" batchv1 "k8s.io/api/batch/v1" + batchv1beta1 "k8s.io/api/batch/v1beta1" kerr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kmapi "kmodules.xyz/client-go/api/v1" @@ -93,8 +94,8 @@ func (f *Framework) EventuallyCronJobCreated(meta metav1.ObjectMeta) GomegaAsync ) } -func (f *Framework) GetCronJob(meta metav1.ObjectMeta) (*batchv1.CronJob, error) { - return f.KubeClient.BatchV1().CronJobs(meta.Namespace).Get(context.TODO(), getBackupCronJobName(meta), metav1.GetOptions{}) +func (f *Framework) GetCronJob(meta metav1.ObjectMeta) (*batchv1beta1.CronJob, error) { + return f.KubeClient.BatchV1beta1().CronJobs(meta.Namespace).Get(context.TODO(), getBackupCronJobName(meta), metav1.GetOptions{}) } func (f *Framework) EventuallyCronJobSuspended(meta metav1.ObjectMeta) GomegaAsyncAssertion { diff --git a/vendor/kmodules.xyz/client-go/batch/v1beta1/cronjob.go b/vendor/kmodules.xyz/client-go/batch/v1beta1/cronjob.go new file mode 100644 index 000000000..a9ceae0f2 --- /dev/null +++ b/vendor/kmodules.xyz/client-go/batch/v1beta1/cronjob.go @@ -0,0 +1,101 @@ +/* +Copyright AppsCode Inc. and 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 v1beta1 + +import ( + "context" + + "github.com/pkg/errors" + batch "k8s.io/api/batch/v1beta1" + kerr "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/strategicpatch" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/kubernetes" + "k8s.io/klog/v2" + kutil "kmodules.xyz/client-go" +) + +func CreateOrPatchCronJob(ctx context.Context, c kubernetes.Interface, meta metav1.ObjectMeta, transform func(*batch.CronJob) *batch.CronJob, opts metav1.PatchOptions) (*batch.CronJob, kutil.VerbType, error) { + cur, err := c.BatchV1beta1().CronJobs(meta.Namespace).Get(ctx, meta.Name, metav1.GetOptions{}) + if kerr.IsNotFound(err) { + klog.V(3).Infof("Creating CronJob %s/%s.", meta.Namespace, meta.Name) + out, err := c.BatchV1beta1().CronJobs(meta.Namespace).Create(ctx, transform(&batch.CronJob{ + TypeMeta: metav1.TypeMeta{ + Kind: "CronJob", + APIVersion: batch.SchemeGroupVersion.String(), + }, + ObjectMeta: meta, + }), metav1.CreateOptions{ + DryRun: opts.DryRun, + FieldManager: opts.FieldManager, + }) + return out, kutil.VerbCreated, err + } else if err != nil { + return nil, kutil.VerbUnchanged, err + } + return PatchCronJob(ctx, c, cur, transform, opts) +} + +func PatchCronJob(ctx context.Context, c kubernetes.Interface, cur *batch.CronJob, transform func(*batch.CronJob) *batch.CronJob, opts metav1.PatchOptions) (*batch.CronJob, kutil.VerbType, error) { + return PatchCronJobObject(ctx, c, cur, transform(cur.DeepCopy()), opts) +} + +func PatchCronJobObject(ctx context.Context, c kubernetes.Interface, cur, mod *batch.CronJob, opts metav1.PatchOptions) (*batch.CronJob, kutil.VerbType, error) { + curJson, err := json.Marshal(cur) + if err != nil { + return nil, kutil.VerbUnchanged, err + } + + modJson, err := json.Marshal(mod) + if err != nil { + return nil, kutil.VerbUnchanged, err + } + + patch, err := strategicpatch.CreateTwoWayMergePatch(curJson, modJson, batch.CronJob{}) + if err != nil { + return nil, kutil.VerbUnchanged, err + } + if len(patch) == 0 || string(patch) == "{}" { + return cur, kutil.VerbUnchanged, nil + } + klog.V(3).Infof("Patching CronJob %s/%s with %s.", cur.Namespace, cur.Name, string(patch)) + out, err := c.BatchV1beta1().CronJobs(cur.Namespace).Patch(ctx, cur.Name, types.StrategicMergePatchType, patch, opts) + return out, kutil.VerbPatched, err +} + +func TryUpdateCronJob(ctx context.Context, c kubernetes.Interface, meta metav1.ObjectMeta, transform func(*batch.CronJob) *batch.CronJob, opts metav1.UpdateOptions) (result *batch.CronJob, err error) { + attempt := 0 + err = wait.PollImmediate(kutil.RetryInterval, kutil.RetryTimeout, func() (bool, error) { + attempt++ + cur, e2 := c.BatchV1beta1().CronJobs(meta.Namespace).Get(ctx, meta.Name, metav1.GetOptions{}) + if kerr.IsNotFound(e2) { + return false, e2 + } else if e2 == nil { + result, e2 = c.BatchV1beta1().CronJobs(cur.Namespace).Update(ctx, transform(cur.DeepCopy()), opts) + return e2 == nil, nil + } + klog.Errorf("Attempt %d failed to update CronJob %s/%s due to %v.", attempt, cur.Namespace, cur.Name, e2) + return false, nil + }) + + if err != nil { + err = errors.Errorf("failed to update CronJob %s/%s after %d attempts due to %v", meta.Namespace, meta.Name, attempt, err) + } + return +} diff --git a/vendor/kmodules.xyz/client-go/batch/v1beta1/kubernetes.go b/vendor/kmodules.xyz/client-go/batch/v1beta1/kubernetes.go new file mode 100644 index 000000000..71bef9bee --- /dev/null +++ b/vendor/kmodules.xyz/client-go/batch/v1beta1/kubernetes.go @@ -0,0 +1,23 @@ +/* +Copyright AppsCode Inc. and 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 v1beta1 + +import ( + jsoniter "github.com/json-iterator/go" +) + +var json = jsoniter.ConfigFastest diff --git a/vendor/modules.txt b/vendor/modules.txt index 2b390a883..4c3c451d1 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1378,6 +1378,7 @@ kmodules.xyz/client-go/apiextensions/v1 kmodules.xyz/client-go/apiregistration/v1 kmodules.xyz/client-go/apps/v1 kmodules.xyz/client-go/batch/v1 +kmodules.xyz/client-go/batch/v1beta1 kmodules.xyz/client-go/core/v1 kmodules.xyz/client-go/discovery kmodules.xyz/client-go/dynamic