diff --git a/clustering/process.go b/clustering/process.go index 845d6d741..2f419daf8 100644 --- a/clustering/process.go +++ b/clustering/process.go @@ -276,7 +276,6 @@ func (p *managerProcess) updateStatus(ctx context.Context, ss *StatusSet) error meta.SetStatusCondition(&cluster.Status.Conditions, updateCond(mocov1beta2.ConditionAvailable, available, cluster.Status.Conditions)) meta.SetStatusCondition(&cluster.Status.Conditions, updateCond(mocov1beta2.ConditionHealthy, healthy, cluster.Status.Conditions)) - // cluster.Status.Conditions = conditions if available == metav1.ConditionTrue { p.metrics.available.Set(1) } else { diff --git a/controllers/mysqlcluster_controller.go b/controllers/mysqlcluster_controller.go index f30c8f2f6..8f947cffb 100644 --- a/controllers/mysqlcluster_controller.go +++ b/controllers/mysqlcluster_controller.go @@ -168,7 +168,8 @@ func (r *MySQLClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request } result, err := reconciler(ctx, req, cluster) if err2 := r.updateReconcileStatus(ctx, cluster, err); err2 != nil { - log.Error(err2, "failed to update reconcile status") + log.Error(err2, "failed to exec updateReconcileStatus()") + err = err2 } return result, err } @@ -177,7 +178,7 @@ func (r *MySQLClusterReconciler) reconcileV1(ctx context.Context, req ctrl.Reque log := crlog.FromContext(ctx) defer func(ctx2 context.Context, cluster2 *mocov1beta2.MySQLCluster) { - if err2 := r.updateStatusByStatefulSet(ctx2, cluster2); err != nil { + if err2 := r.updateStatusByStatefulSet(ctx2, cluster2); err2 != nil { err = err2 log.Error(err2, "failed to update status") } @@ -1905,10 +1906,10 @@ func (r *MySQLClusterReconciler) updateStatusByStatefulSet(ctx context.Context, } meta.SetStatusCondition(&cluster.Status.Conditions, cond) if err := r.Status().Update(ctx, cluster); err != nil { - log.Error(err, "failed to update reconciliation info") + log.Error(err, "failed to update ConditionStatefulSetReady") return err } - log.Info("update status successfully") + log.Info("update ConditionStatefulSetReady successfully") } return nil } @@ -1923,22 +1924,19 @@ func (r *MySQLClusterReconciler) updateReconcileStatus(ctx context.Context, clus message = "reconcile successfully" success = metav1.ConditionTrue } - currentConditionReconcileSuccess := meta.FindStatusCondition(cluster.Status.Conditions, mocov1beta2.ConditionReconcileSuccess) - if currentConditionReconcileSuccess == nil || currentConditionReconcileSuccess.Status != success || currentConditionReconcileSuccess.ObservedGeneration != cluster.Generation { - cond := metav1.Condition{ - Type: mocov1beta2.ConditionReconcileSuccess, - Status: success, - ObservedGeneration: cluster.Generation, - Reason: reason, - Message: message, - } - meta.SetStatusCondition(&cluster.Status.Conditions, cond) - if err := r.Status().Update(ctx, cluster); err != nil { - log.Error(err, "failed to update reconciliation info") - return err - } - log.Info("update status successfully") + cond := metav1.Condition{ + Type: mocov1beta2.ConditionReconcileSuccess, + Status: success, + ObservedGeneration: cluster.Generation, + Reason: reason, + Message: message, + } + meta.SetStatusCondition(&cluster.Status.Conditions, cond) + if err := r.Status().Update(ctx, cluster); err != nil { + log.Error(err, "failed to update reconcile status") + return err } + log.Info("update reconcile status successfully") return nil } diff --git a/controllers/mysqlcluster_controller_test.go b/controllers/mysqlcluster_controller_test.go index 1c0a3f1f5..0444ceb0d 100644 --- a/controllers/mysqlcluster_controller_test.go +++ b/controllers/mysqlcluster_controller_test.go @@ -330,12 +330,17 @@ var _ = Describe("MySQLCluster reconciler", func() { return nil }).Should(Succeed()) - cluster = &mocov1beta2.MySQLCluster{} - err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster) - Expect(err).NotTo(HaveOccurred()) - cluster.Spec.DisableSlowQueryLogContainer = true - err = k8sClient.Update(ctx, cluster) - Expect(err).NotTo(HaveOccurred()) + Eventually(func() error { + cluster := &mocov1beta2.MySQLCluster{} + if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster); err != nil { + return err + } + cluster.Spec.DisableSlowQueryLogContainer = true + if err = k8sClient.Update(ctx, cluster); err != nil { + return err + } + return nil + }).Should(Succeed()) Eventually(func() bool { slowCM = &corev1.ConfigMap{} @@ -402,15 +407,20 @@ var _ = Describe("MySQLCluster reconciler", func() { err = k8sClient.Create(ctx, userCM) Expect(err).NotTo(HaveOccurred()) - cluster = &mocov1beta2.MySQLCluster{} - err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster) - Expect(err).NotTo(HaveOccurred()) - cluster.Spec.MySQLConfigMapName = pointer.String(userCM.Name) - cluster.Spec.PodTemplate.Spec.Containers[0].Resources.WithRequests(corev1.ResourceList{ - corev1.ResourceMemory: resource.MustParse("500Mi"), - }) - err = k8sClient.Update(ctx, cluster) - Expect(err).NotTo(HaveOccurred()) + Eventually(func() error { + cluster := &mocov1beta2.MySQLCluster{} + if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster); err != nil { + return err + } + cluster.Spec.MySQLConfigMapName = pointer.String(userCM.Name) + cluster.Spec.PodTemplate.Spec.Containers[0].Resources.WithRequests(corev1.ResourceList{ + corev1.ResourceMemory: resource.MustParse("500Mi"), + }) + if err = k8sClient.Update(ctx, cluster); err != nil { + return err + } + return nil + }).Should(Succeed()) oldName := cm.Name Eventually(func() error { @@ -830,98 +840,103 @@ var _ = Describe("MySQLCluster reconciler", func() { } By("updating MySQLCluster") - cluster = &mocov1beta2.MySQLCluster{} - err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster) - Expect(err).NotTo(HaveOccurred()) + Eventually(func() error { + cluster = &mocov1beta2.MySQLCluster{} + if err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster); err != nil { + return err + } - cluster.Spec.Replicas = 5 - cluster.Spec.ReplicationSourceSecretName = nil - cluster.Spec.Collectors = []string{"engine_innodb_status", "info_schema.innodb_metrics"} - cluster.Spec.MaxDelaySeconds = pointer.Int(20) - cluster.Spec.StartupWaitSeconds = 3 - cluster.Spec.LogRotationSchedule = "0 * * * *" - cluster.Spec.DisableSlowQueryLogContainer = true - cluster.Spec.PodTemplate.OverwriteContainers = []mocov1beta2.OverwriteContainer{ - { - Name: mocov1beta2.AgentContainerName, - Resources: (*mocov1beta2.ResourceRequirementsApplyConfiguration)(corev1ac.ResourceRequirements(). - WithLimits(corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("100m")}). - WithRequests(corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("100m")}), - ), - }, - { - Name: mocov1beta2.ExporterContainerName, - Resources: (*mocov1beta2.ResourceRequirementsApplyConfiguration)(corev1ac.ResourceRequirements(). - WithLimits(corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("200m")}). - WithRequests(corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("200m")}), - ), - }, - { - Name: mocov1beta2.InitContainerName, - Resources: (*mocov1beta2.ResourceRequirementsApplyConfiguration)(corev1ac.ResourceRequirements(). - WithLimits(corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("300m")}). - WithRequests(corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("300m")}), - ), - }, - } + cluster.Spec.Replicas = 5 + cluster.Spec.ReplicationSourceSecretName = nil + cluster.Spec.Collectors = []string{"engine_innodb_status", "info_schema.innodb_metrics"} + cluster.Spec.MaxDelaySeconds = pointer.Int(20) + cluster.Spec.StartupWaitSeconds = 3 + cluster.Spec.LogRotationSchedule = "0 * * * *" + cluster.Spec.DisableSlowQueryLogContainer = true + cluster.Spec.PodTemplate.OverwriteContainers = []mocov1beta2.OverwriteContainer{ + { + Name: mocov1beta2.AgentContainerName, + Resources: (*mocov1beta2.ResourceRequirementsApplyConfiguration)(corev1ac.ResourceRequirements(). + WithLimits(corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("100m")}). + WithRequests(corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("100m")}), + ), + }, + { + Name: mocov1beta2.ExporterContainerName, + Resources: (*mocov1beta2.ResourceRequirementsApplyConfiguration)(corev1ac.ResourceRequirements(). + WithLimits(corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("200m")}). + WithRequests(corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("200m")}), + ), + }, + { + Name: mocov1beta2.InitContainerName, + Resources: (*mocov1beta2.ResourceRequirementsApplyConfiguration)(corev1ac.ResourceRequirements(). + WithLimits(corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("300m")}). + WithRequests(corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("300m")}), + ), + }, + } - podSpec := corev1ac.PodSpec(). - WithTerminationGracePeriodSeconds(512). - WithPriorityClassName("hoge"). - WithContainers(corev1ac.Container().WithName("dummy").WithImage("dummy:latest")). - WithInitContainers(corev1ac.Container().WithName("init-dummy").WithImage("init-dummy:latest"). - WithSecurityContext(corev1ac.SecurityContext().WithReadOnlyRootFilesystem(true))). - WithVolumes(corev1ac.Volume().WithName("dummy-vol").WithEmptyDir(corev1ac.EmptyDirVolumeSource())). - WithSecurityContext(corev1ac.PodSecurityContext().WithFSGroup(123)). - WithAffinity(corev1ac.Affinity(). - WithPodAntiAffinity(corev1ac.PodAntiAffinity(). - WithRequiredDuringSchedulingIgnoredDuringExecution(corev1ac.PodAffinityTerm(). - WithLabelSelector(metav1ac.LabelSelector(). - WithMatchExpressions(metav1ac.LabelSelectorRequirement(). - WithKey(constants.LabelAppName). - WithOperator(metav1.LabelSelectorOpIn). - WithValues(constants.AppNameMySQL), - ). - WithMatchExpressions(metav1ac.LabelSelectorRequirement(). - WithKey(constants.LabelAppInstance). - WithOperator(metav1.LabelSelectorOpIn). - WithValues(cluster.Name), + podSpec := corev1ac.PodSpec(). + WithTerminationGracePeriodSeconds(512). + WithPriorityClassName("hoge"). + WithContainers(corev1ac.Container().WithName("dummy").WithImage("dummy:latest")). + WithInitContainers(corev1ac.Container().WithName("init-dummy").WithImage("init-dummy:latest"). + WithSecurityContext(corev1ac.SecurityContext().WithReadOnlyRootFilesystem(true))). + WithVolumes(corev1ac.Volume().WithName("dummy-vol").WithEmptyDir(corev1ac.EmptyDirVolumeSource())). + WithSecurityContext(corev1ac.PodSecurityContext().WithFSGroup(123)). + WithAffinity(corev1ac.Affinity(). + WithPodAntiAffinity(corev1ac.PodAntiAffinity(). + WithRequiredDuringSchedulingIgnoredDuringExecution(corev1ac.PodAffinityTerm(). + WithLabelSelector(metav1ac.LabelSelector(). + WithMatchExpressions(metav1ac.LabelSelectorRequirement(). + WithKey(constants.LabelAppName). + WithOperator(metav1.LabelSelectorOpIn). + WithValues(constants.AppNameMySQL), + ). + WithMatchExpressions(metav1ac.LabelSelectorRequirement(). + WithKey(constants.LabelAppInstance). + WithOperator(metav1.LabelSelectorOpIn). + WithValues(cluster.Name), + ), ), ), - ), - )) - - for _, c := range cluster.Spec.PodTemplate.Spec.Containers { - switch *c.Name { - case constants.MysqldContainerName: - c.WithSecurityContext(corev1ac.SecurityContext().WithReadOnlyRootFilesystem(true)). - WithLivenessProbe(corev1ac.Probe(). - WithTerminationGracePeriodSeconds(int64(200)). - WithHTTPGet(corev1ac.HTTPGetAction(). - WithPath("/healthz"). - WithPort(intstr.FromString(constants.MySQLHealthPortName)). - WithScheme(corev1.URISchemeHTTP))) - } - podSpec.WithContainers(&c) - } + )) + + for _, c := range cluster.Spec.PodTemplate.Spec.Containers { + switch *c.Name { + case constants.MysqldContainerName: + c.WithSecurityContext(corev1ac.SecurityContext().WithReadOnlyRootFilesystem(true)). + WithLivenessProbe(corev1ac.Probe(). + WithTerminationGracePeriodSeconds(int64(200)). + WithHTTPGet(corev1ac.HTTPGetAction(). + WithPath("/healthz"). + WithPort(intstr.FromString(constants.MySQLHealthPortName)). + WithScheme(corev1.URISchemeHTTP))) + } + podSpec.WithContainers(&c) + } - cluster.Spec.PodTemplate.Spec = mocov1beta2.PodSpecApplyConfiguration(*podSpec) + cluster.Spec.PodTemplate.Spec = mocov1beta2.PodSpecApplyConfiguration(*podSpec) - userCM := &corev1.ConfigMap{} - userCM.Namespace = "test" - userCM.Name = "user-conf" - userCM.Data = map[string]string{ - constants.LowerCaseTableNamesConfKey: "1", - } - - err = k8sClient.Create(ctx, userCM) - Expect(err).NotTo(HaveOccurred()) + userCM := &corev1.ConfigMap{} + userCM.Namespace = "test" + userCM.Name = "user-conf" + userCM.Data = map[string]string{ + constants.LowerCaseTableNamesConfKey: "1", + } - cluster.Spec.MySQLConfigMapName = pointer.String(userCM.Name) + if err = k8sClient.Create(ctx, userCM); err != nil { + return err + } - err = k8sClient.Update(ctx, cluster) - Expect(err).NotTo(HaveOccurred()) + cluster.Spec.MySQLConfigMapName = pointer.String(userCM.Name) + if err = k8sClient.Update(ctx, cluster); err != nil { + return err + } + return nil + }).Should(Succeed()) Eventually(func() error { c := &mocov1beta2.MySQLCluster{} if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, c); err != nil { @@ -1015,14 +1030,18 @@ var _ = Describe("MySQLCluster reconciler", func() { Expect(foundDummyVolume).To(BeTrue()) By("updating MySQLCluster (MaxDelaySeconds=0)") - cluster = &mocov1beta2.MySQLCluster{} - err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster) - Expect(err).NotTo(HaveOccurred()) - cluster.Spec.MaxDelaySeconds = pointer.Int(0) - - err = k8sClient.Update(ctx, cluster) - Expect(err).NotTo(HaveOccurred()) + Eventually(func() error { + cluster := &mocov1beta2.MySQLCluster{} + if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster); err != nil { + return err + } + cluster.Spec.MaxDelaySeconds = pointer.Int(0) + if err = k8sClient.Update(ctx, cluster); err != nil { + return err + } + return nil + }).Should(Succeed()) Eventually(func() error { c := &mocov1beta2.MySQLCluster{} @@ -1082,10 +1101,17 @@ var _ = Describe("MySQLCluster reconciler", func() { } return nil }).Should(Succeed()) - cluster.Spec.Replicas = 1 - err = k8sClient.Update(ctx, cluster) - Expect(err).NotTo(HaveOccurred()) - + Eventually(func() error { + cluster = &mocov1beta2.MySQLCluster{} + if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster); err != nil { + return err + } + cluster.Spec.Replicas = 1 + if err := k8sClient.Update(ctx, cluster); err != nil { + return err + } + return nil + }).Should(Succeed()) Eventually(func() bool { pdb = &policyv1.PodDisruptionBudget{} err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: cluster.PrefixedName()}, pdb) @@ -1305,13 +1331,18 @@ var _ = Describe("MySQLCluster reconciler", func() { }).Should(Succeed()) By("disabling backup") - cluster = &mocov1beta2.MySQLCluster{} - err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster) - Expect(err).NotTo(HaveOccurred()) - cluster.Spec.BackupPolicyName = nil - err = k8sClient.Update(ctx, cluster) - Expect(err).NotTo(HaveOccurred()) + Eventually(func() error { + cluster = &mocov1beta2.MySQLCluster{} + if err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster); err != nil { + return err + } + cluster.Spec.BackupPolicyName = nil + if err = k8sClient.Update(ctx, cluster); err != nil { + return err + } + return nil + }).Should(Succeed()) Eventually(func() bool { cj = &batchv1.CronJob{} err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test-policy"}, cj) @@ -1506,15 +1537,17 @@ var _ = Describe("MySQLCluster reconciler", func() { } return nil }).Should(Succeed()) - - cluster = &mocov1beta2.MySQLCluster{} - err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster) - Expect(err).NotTo(HaveOccurred()) - - cluster.Annotations = map[string]string{"foo": "bar"} - err = k8sClient.Update(ctx, cluster) - Expect(err).NotTo(HaveOccurred()) - + Eventually(func() error { + cluster = &mocov1beta2.MySQLCluster{} + if err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster); err != nil { + return err + } + cluster.Annotations = map[string]string{"foo": "bar"} + if err = k8sClient.Update(ctx, cluster); err != nil { + return err + } + return nil + }).Should(Succeed()) Consistently(func() error { cluster2 := &mocov1beta2.MySQLCluster{} if err := k8sClient.Get(ctx, client.ObjectKeyFromObject(cluster), cluster2); err != nil { @@ -1528,15 +1561,17 @@ var _ = Describe("MySQLCluster reconciler", func() { } return nil }).Should(Succeed()) - - cluster = &mocov1beta2.MySQLCluster{} - err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster) - Expect(err).NotTo(HaveOccurred()) - - cluster.Spec.Replicas = 5 - err = k8sClient.Update(ctx, cluster) - Expect(err).NotTo(HaveOccurred()) - + Eventually(func() error { + cluster = &mocov1beta2.MySQLCluster{} + if err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster); err != nil { + return err + } + cluster.Spec.Replicas = 5 + if err = k8sClient.Update(ctx, cluster); err != nil { + return err + } + return nil + }).Should(Succeed()) Eventually(func() error { cluster2 := &mocov1beta2.MySQLCluster{} if err := k8sClient.Get(ctx, client.ObjectKeyFromObject(cluster), cluster2); err != nil { @@ -1846,38 +1881,62 @@ var _ = Describe("MySQLCluster reconciler", func() { return nil }).Should(Succeed()) }) - // It("should sets reconcile status condition true when success", func() { - // cluster := testNewMySQLCluster("test") - // err := k8sClient.Create(ctx, cluster) - // Expect(err).NotTo(HaveOccurred()) - - // var sts *appsv1.StatefulSet - // Eventually(func() error { - // sts = &appsv1.StatefulSet{} - // if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "moco-test"}, sts); err != nil { - // return err - // } - // return nil - // }).Should(Succeed()) - // cluster = &mocov1beta2.MySQLCluster{} - // err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster) - // Expect(err).NotTo(HaveOccurred()) - // conditionReconcileSuccess := meta.FindStatusCondition(cluster.Status.Conditions, mocov1beta2.ConditionReconcileSuccess) - // Expect(conditionReconcileSuccess.Status).To(Equal(metav1.ConditionTrue)) - // }) - // It("should sets reconcile status condition false when success", func() { - // cluster := testNewMySQLCluster("test") - // err := k8sClient.Create(ctx, cluster) - // Expect(err).NotTo(HaveOccurred()) - - // cluster.Spec.MySQLConfigMapName = pointer.String("foo") - // err = k8sClient.Update(ctx, cluster) - // Expect(err).NotTo(HaveOccurred()) - - // cluster = &mocov1beta2.MySQLCluster{} - // err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster) - // Expect(err).NotTo(HaveOccurred()) - // conditionReconcileSuccess := meta.FindStatusCondition(cluster.Status.Conditions, mocov1beta2.ConditionReconcileSuccess) - // Expect(conditionReconcileSuccess.Status).To(Equal(metav1.ConditionFalse)) - // }) + + It("should sets reconcile status condition true when success", func() { + cluster := testNewMySQLCluster("test") + err := k8sClient.Create(ctx, cluster) + Expect(err).NotTo(HaveOccurred()) + + By("checking condition is true") + Eventually(func() error { + cluster = &mocov1beta2.MySQLCluster{} + if err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster); err != nil { + return err + } + conditionReconcileSuccess := meta.FindStatusCondition(cluster.Status.Conditions, mocov1beta2.ConditionReconcileSuccess) + if conditionReconcileSuccess == nil { + return fmt.Errorf("not reconciled yet") + + } + if conditionReconcileSuccess.Status != metav1.ConditionTrue { + return fmt.Errorf("status is not true") + } + return nil + }).Should(Succeed()) + }) + + It("should sets reconcile status condition false when faild", func() { + cluster := testNewMySQLCluster("test") + err := k8sClient.Create(ctx, cluster) + Expect(err).NotTo(HaveOccurred()) + + By("setting mysql configmap name to be invalid") + Eventually(func() error { + cluster := &mocov1beta2.MySQLCluster{} + if err := k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster); err != nil { + return err + } + cluster.Spec.MySQLConfigMapName = pointer.String("foobarhoge") + if err = k8sClient.Update(ctx, cluster); err != nil { + return err + } + return nil + }).Should(Succeed()) + By("checking condition is false") + Eventually(func() error { + cluster = &mocov1beta2.MySQLCluster{} + if err = k8sClient.Get(ctx, client.ObjectKey{Namespace: "test", Name: "test"}, cluster); err != nil { + return err + } + conditionReconcileSuccess := meta.FindStatusCondition(cluster.Status.Conditions, mocov1beta2.ConditionReconcileSuccess) + if conditionReconcileSuccess == nil { + return fmt.Errorf("not reconciled yet") + + } + if conditionReconcileSuccess.Status != metav1.ConditionFalse { + return fmt.Errorf("status is not false") + } + return nil + }).Should(Succeed()) + }) }) diff --git a/docs/reconcile.md b/docs/reconcile.md index a82bec7af..92671c55e 100644 --- a/docs/reconcile.md +++ b/docs/reconcile.md @@ -63,7 +63,7 @@ The StatefulSet will be updated when: The fluent-bit sidecar container is updated only when some fields under `spec` of MySQLCluster are modified. ### Status about StatefulSet -- In `MySQLCluster.Status.Condition`, there is a condition named `UpToDate`. +- In `MySQLCluster.Status.Condition`, there is a condition named `StatefulSetReady`. - This indicates the readieness of StatefulSet. - The condition will be `True` when the rolling update of StatefulSet completely finishes. ### Secrets @@ -139,3 +139,8 @@ To restore data from a backup, MOCO creates a Job. MOCO deletes the Job after the Job finishes successfully. If the Job fails, MOCO leaves the Job. + +## Status of Reconcliation +- In `MySQLCluster.Status.Condition`, there is a condition named `ReconcileSuccess`. +- This indicates the status of reconcilation. +- The condition will be `True` when the reconcile function successfully finishes. diff --git a/e2e/upgrade_test.go b/e2e/upgrade_test.go index 1941ee496..37fe5e6a9 100644 --- a/e2e/upgrade_test.go +++ b/e2e/upgrade_test.go @@ -10,7 +10,6 @@ import ( mocov1beta2 "github.com/cybozu-go/moco/api/v1beta2" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -142,31 +141,19 @@ var _ = Context("upgrade", func() { if cluster.Generation != cluster.Status.ReconcileInfo.Generation { return fmt.Errorf("cluster is not reconciled yet") } - conditionHealthy := meta.FindStatusCondition(cluster.Status.Conditions, mocov1beta2.ConditionHealthy) conditionStatefulSetReady := meta.FindStatusCondition(cluster.Status.Conditions, mocov1beta2.ConditionStatefulSetReady) + conditionHealthy := meta.FindStatusCondition(cluster.Status.Conditions, mocov1beta2.ConditionHealthy) if conditionStatefulSetReady == nil { return fmt.Errorf("statefulset is not ready") } if conditionHealthy == nil { return fmt.Errorf("cluster is not healthy") } - if conditionHealthy.Status != metav1.ConditionTrue { - // Expect(conditionStatefulSetReady.Status).To(Equal(metav1.ConditionFalse)) - return fmt.Errorf("cluster is not healthy") - } - if conditionStatefulSetReady.Status != metav1.ConditionTrue { - return fmt.Errorf("statefulset is not ready") + if conditionStatefulSetReady.Status != metav1.ConditionTrue && conditionHealthy.Status != metav1.ConditionTrue { + return fmt.Errorf("cluster is not ready") } return nil }).Should(Succeed()) - - sts := &appsv1.StatefulSet{} - out, err := kubectl(nil, "get", "-n", "upgrade", "sts", "moco-test", "-o", "json") - Expect(err).NotTo(HaveOccurred()) - err = json.Unmarshal(out, sts) - Expect(err).NotTo(HaveOccurred()) - Expect(sts.Status.CurrentRevision).Should(Equal(sts.Status.UpdateRevision)) - Expect(sts.Generation).Should(Equal(sts.Status.ObservedGeneration)) }) It("should delete clusters", func() {