diff --git a/charts/mantle/templates/deployment.yaml b/charts/mantle/templates/deployment.yaml index 4836aade..ef7e0922 100644 --- a/charts/mantle/templates/deployment.yaml +++ b/charts/mantle/templates/deployment.yaml @@ -64,9 +64,6 @@ spec: {{- with .Values.controller.mantleServiceEndpoint }} - --mantle-service-endpoint={{ . }} {{- end }} - {{- with .Values.controller.expireOffset }} - - --expire-offset={{ . }} - {{- end }} {{- with .Values.controller.overwriteMBCSchedule }} - --overwrite-mbc-schedule={{ . }} {{- end }} diff --git a/cmd/backupandrotate/main.go b/cmd/backup/main.go similarity index 63% rename from cmd/backupandrotate/main.go rename to cmd/backup/main.go index 7aeca507..83a32127 100644 --- a/cmd/backupandrotate/main.go +++ b/cmd/backup/main.go @@ -8,16 +8,13 @@ import ( "fmt" "io" "os" - "time" "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" - "k8s.io/kube-openapi/pkg/validation/strfmt" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/config" @@ -29,16 +26,14 @@ import ( var ( mbcName, mbcNamespace string - expireOffset string zapOpts zap.Options scheme = runtime.NewScheme() MantleBackupConfigUID = "mantle.cybozu.io/mbc-uid" - MantleRetainIfExpired = "mantle.cybozu.io/retainIfExpired" - logger = ctrl.Log.WithName("backup-and-rotate") + logger = ctrl.Log.WithName("backup") BackupAndRotateCmd = &cobra.Command{ - Use: "backup-and-rotate", + Use: "backup", RunE: func(cmd *cobra.Command, args []string) error { return subMain(cmd.Context()) }, @@ -49,9 +44,6 @@ func init() { flags := BackupAndRotateCmd.Flags() flags.StringVar(&mbcName, "name", "", "MantleBackupConfig resource's name") flags.StringVar(&mbcNamespace, "namespace", "", "MantleBackupConfig resource's namespace") - flags.StringVar(&expireOffset, "expire-offset", "0s", - "An offset for MantleBackupConfig's .spec.expire field. A MantleBackup will expire after "+ - "it has been active for (.spec.expire - expire-offset) time. This option is intended for testing purposes only.") goflags := flag.NewFlagSet("goflags", flag.ExitOnError) zapOpts.Development = true @@ -91,11 +83,6 @@ func fetchJobID() (string, error) { func subMain(ctx context.Context) error { ctrl.SetLogger(zap.New(zap.UseFlagOptions(&zapOpts))) - parsedExpireOffset, err := strfmt.ParseDuration(expireOffset) - if err != nil { - return fmt.Errorf("couldn't parse the expire offset: %w", err) - } - cli, err := client.New(config.GetConfigOrDie(), client.Options{Scheme: scheme}) if err != nil { return fmt.Errorf("couldn't create a new client: %w", err) @@ -111,10 +98,6 @@ func subMain(ctx context.Context) error { return fmt.Errorf("backup failed: %s: %s: %w", mbcName, mbcNamespace, err) } - if err := rotateMantleBackup(ctx, cli, &mbc, parsedExpireOffset); err != nil { - return fmt.Errorf("rotation failed: %s: %s: %w", mbcName, mbcNamespace, err) - } - return nil } @@ -170,62 +153,3 @@ func createMantleBackup(ctx context.Context, cli client.Client, mbc *mantlev1.Ma "mbcName", mbcName, "mbcNamespace", mbcNamespace) return nil } - -func rotateMantleBackup( - ctx context.Context, - cli client.Client, - mbc *mantlev1.MantleBackupConfig, - expireOffset time.Duration, -) error { - // List all MantleBackup objects associated with the mbc. - var mbList mantlev1.MantleBackupList - if err := cli.List(ctx, &mbList, &client.ListOptions{ - LabelSelector: labels.SelectorFromSet(map[string]string{MantleBackupConfigUID: string(mbc.GetUID())}), - }); err != nil { - return fmt.Errorf("couldn't list MantleBackups: %s: %w", string(mbc.UID), err) - } - - // Delete the MantleBackup objects that are already expired and don't have the retainIfExpired label. - expire, err := strfmt.ParseDuration(mbc.Spec.Expire) - if err != nil { - return fmt.Errorf("couldn't parse spec.expire: %s: %w", mbc.Spec.Expire, err) - } - if expire >= expireOffset { - expire -= expireOffset - } else { - expire = 0 - } - for _, mb := range mbList.Items { - if mb.Status.CreatedAt == (metav1.Time{}) { - // mb is not created yet (at least from the cache's perspective), so let's ignore it. - continue - } - elapsed := time.Since(mb.Status.CreatedAt.Time) - if elapsed <= expire { - continue - } - retain, ok := mb.GetAnnotations()[MantleRetainIfExpired] - if ok && retain == "true" { - continue - } - - if err := cli.Delete(ctx, &mb, &client.DeleteOptions{ - Preconditions: &metav1.Preconditions{ - UID: &mb.UID, - ResourceVersion: &mb.ResourceVersion, - }, - }); err == nil || errors.IsNotFound(err) { - logger.Info("MantleBackup deleted", - "mb.Name", mb.Name, "mb.Namespace", mb.Namespace, - "mb.UID", mb.UID, "mb.ResourceVersion", mb.ResourceVersion, - "mbcName", mbcName, "mbcNamespace", mbcNamespace, - "elapsed", elapsed, "expire", expire, - ) - } else { - return fmt.Errorf("couldn't delete MantleBackup: %s: %s: %s: %s: %w", - mb.Name, mb.Namespace, mb.UID, mb.ResourceVersion, err) - } - } - - return nil -} diff --git a/cmd/controller/main.go b/cmd/controller/main.go index c564c48b..096fbd02 100644 --- a/cmd/controller/main.go +++ b/cmd/controller/main.go @@ -46,7 +46,6 @@ var ( enableLeaderElection bool probeAddr string zapOpts zap.Options - expireOffset string overwriteMBCSchedule string role string mantleServiceEndpoint string @@ -62,9 +61,6 @@ func init() { flags.BoolVar(&enableLeaderElection, "leader-elect", false, "Enable leader election for controller manager. "+ "Enabling this will ensure there is only one active controller manager.") - flags.StringVar(&expireOffset, "expire-offset", "", - "An offset for MantleBackupConfig's .spec.expire field. A MantleBackup will expire after "+ - "it has been active for (.spec.expire - expire-offset) time. This option is intended for testing purposes only.") flags.StringVar(&overwriteMBCSchedule, "overwrite-mbc-schedule", "", "By setting this option, every CronJob created by this controller for every MantleBackupConfig "+ "will use its value as .spec.schedule. This option is intended for testing purposes only.") @@ -141,7 +137,6 @@ func setupReconcilers(mgr manager.Manager, primarySettings *controller.PrimarySe mgr.GetClient(), mgr.GetScheme(), managedCephClusterID, - expireOffset, overwriteMBCSchedule, role, ).SetupWithManager(mgr); err != nil { diff --git a/internal/controller/mantlebackupconfig_controller.go b/internal/controller/mantlebackupconfig_controller.go index 3798fef1..2abf2a46 100644 --- a/internal/controller/mantlebackupconfig_controller.go +++ b/internal/controller/mantlebackupconfig_controller.go @@ -33,7 +33,6 @@ type MantleBackupConfigReconciler struct { Client client.Client Scheme *runtime.Scheme managedCephClusterID string - expireOffset string overwriteMBCSchedule string role string } @@ -42,11 +41,10 @@ func NewMantleBackupConfigReconciler( cli client.Client, scheme *runtime.Scheme, managedCephClusterID string, - expireOffset string, overwriteMBCSchedule string, role string, ) *MantleBackupConfigReconciler { - return &MantleBackupConfigReconciler{cli, scheme, managedCephClusterID, expireOffset, overwriteMBCSchedule, role} + return &MantleBackupConfigReconciler{cli, scheme, managedCephClusterID, overwriteMBCSchedule, role} } //+kubebuilder:rbac:groups=mantle.cybozu.io,resources=mantlebackupconfigs,verbs=get;list;watch;create;update;patch;delete @@ -226,14 +224,13 @@ func (r *MantleBackupConfigReconciler) createOrUpdateCronJob(ctx context.Context podSpec.Containers = append(podSpec.Containers, corev1.Container{}) } container := &podSpec.Containers[0] - container.Name = "backup-and-rotate" + container.Name = "backup" container.Image = image container.Command = []string{ "/manager", - "backup-and-rotate", + "backup", "--name", mbc.GetName(), "--namespace", mbc.GetNamespace(), - "--expire-offset", r.expireOffset, } container.ImagePullPolicy = corev1.PullIfNotPresent container.Env = []corev1.EnvVar{ diff --git a/test/e2e/singlek8s/backup_test.go b/test/e2e/singlek8s/backup_test.go index fbf35c50..ec25e53b 100644 --- a/test/e2e/singlek8s/backup_test.go +++ b/test/e2e/singlek8s/backup_test.go @@ -236,7 +236,7 @@ func (test *backupTest) testCase1() { } func (test *backupTest) testCase2() { - It("should create and rotate MantleBackups from MantleBackupConfig", func() { + It("should create MantleBackups from MantleBackupConfig", func() { By("Creating MantleBackupConfig") err := applyMantleBackupConfigTemplate(test.tenantNamespace, test.pvcName1, test.mantleBackupConfigName[2]) Expect(err).NotTo(HaveOccurred()) @@ -251,34 +251,19 @@ func (test *backupTest) testCase2() { }).Should(Succeed()) // Because of the e2e's values-mantle.yaml, the CronJob's .spec.schedule - // is overwritten with "* * * * *", so backup-and-rotate subcommand - // should be triggered every minute. And every MantleBackup created at minute N will be deleted at minute (N+1), - // because of `expire-offset` setting in the e2e's values-mantle.yaml. + // is overwritten with "* * * * *", so backup subcommand + // should be triggered every minute. By("Waiting for a MantleBackup to be created") - var mb mantlev1.MantleBackup Eventually(func() error { mbs, err := listMantleBackupsByMBCUID(test.tenantNamespace, string(mbc.UID)) if err != nil { return err } - if len(mbs) == 1 { - mb = mbs[0] + if len(mbs) > 0 { return nil } return errors.New("MantleBackup not found") }).Should(Succeed()) - - By("Waiting for MantleBackups to be rotated") - Eventually(func() error { - mbs, err := listMantleBackupsByMBCUID(test.tenantNamespace, string(mbc.UID)) - if err != nil { - return err - } - if len(mbs) == 1 && mbs[0].Name != mb.Name { - return nil - } - return errors.New("MantleBackup not rotated") - }).Should(Succeed()) }) It("should not delete the MantleBackups even when the MantleBackupConfig is deleted", func() { @@ -314,72 +299,6 @@ func (test *backupTest) testCase2() { }, "5s", "1s").Should(Succeed()) }) - It("should not delete a MantleBackup if it has an annotation of retainIfExpired", func() { - By("Creating MantleBackupConfig") - err := applyMantleBackupConfigTemplate(test.tenantNamespace, test.pvcName1, test.mantleBackupConfigName[1]) - Expect(err).NotTo(HaveOccurred()) - - By("Waiting for a CronJob to be created") - mbc, err := getMBC(test.tenantNamespace, test.mantleBackupConfigName[1]) - Expect(err).NotTo(HaveOccurred()) - cronJobName := "mbc-" + string(mbc.UID) - Eventually(func() error { - _, err := getCronJob(cephCluster1Namespace, cronJobName) - return err - }).Should(Succeed()) - - By("Attaching an annotation of retainIfExpired to a MantleBackup") - var mb mantlev1.MantleBackup - Eventually(func() error { - mbs, err := listMantleBackupsByMBCUID(test.tenantNamespace, string(mbc.UID)) - if err != nil { - return err - } - if len(mbs) == 0 { - return errors.New("no MantleBackup available") - } - mb = mbs[0] - - _, _, err = kubectl("patch", "mantlebackup", "-n", mb.Namespace, mb.Name, "--type=json", - "-p", "[{\"op\":\"add\",\"path\":\"/metadata/annotations\","+ - "\"value\":{\"mantle.cybozu.io/retainIfExpired\":\"true\"}}]") - return err - }, "120s", "1s").Should(Succeed()) - - By("Checking mb is NOT deleted thanks to retainIfExpired annotation") - Consistently(func() error { - _, _, err := kubectl("get", "mantlebackup", "-n", mb.Namespace, mb.Name) - return err - }, "70s", "10s").Should(Succeed()) - - By("Checking mbs not annotated with retainIfExpired are rotated") - Eventually(func() error { - mbs, err := listMantleBackupsByMBCUID(test.tenantNamespace, string(mbc.UID)) - if err != nil { - return err - } - - for _, mb1 := range mbs { - value, ok := mb1.Annotations["mantle.cybozu.io/retainIfExpired"] - if !ok || value != "true" { - mb = mb1 - return nil - } - } - return errors.New("no MantleBackup available") - }).Should(Succeed()) - Eventually(func() error { - _, stderr, err := kubectl("get", "mantlebackup", "-n", mb.Namespace, mb.Name) - if err != nil { - if strings.Contains(string(stderr), "NotFound") { - return nil - } - return err - } - return errors.New("still exists") - }).Should(Succeed()) - }) - It("should re-create a CronJob associated with a MantleBackup when it's deleted by someone", func() { By("Creating MantleBackupConfig") err := applyMantleBackupConfigTemplate(test.tenantNamespace, test.pvcName1, test.mantleBackupConfigName[3]) diff --git a/test/e2e/testdata/values-mantle1.yaml b/test/e2e/testdata/values-mantle1.yaml index b096ffc2..8ab3f446 100644 --- a/test/e2e/testdata/values-mantle1.yaml +++ b/test/e2e/testdata/values-mantle1.yaml @@ -1,3 +1,2 @@ controller: - expireOffset: 1w6d23h59m50s # 2w - 10s overwriteMBCSchedule: "* * * * *"