Skip to content

Commit 68d361e

Browse files
authored
Merge pull request #264 from runkecheng/add_state
*: Make the cluster state cover more scenarios. #253
2 parents 502994f + 36e7a4d commit 68d361e

File tree

3 files changed

+69
-19
lines changed

3 files changed

+69
-19
lines changed

api/v1alpha1/mysqlcluster_types.go

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -242,16 +242,34 @@ type Persistence struct {
242242
Size string `json:"size,omitempty"`
243243
}
244244

245+
// ClusterState defines cluster state.
246+
type ClusterState string
247+
248+
const (
249+
// ClusterInitState indicates whether the cluster is initializing.
250+
ClusterInitState ClusterState = "Initializing"
251+
// ClusterUpdateState indicates whether the cluster is being updated.
252+
ClusterUpdateState ClusterState = "Updating"
253+
// ClusterReadyState indicates whether all containers in the pod are ready.
254+
ClusterReadyState ClusterState = "Ready"
255+
// ClusterCloseState indicates whether the cluster is closed.
256+
ClusterCloseState ClusterState = "Closed"
257+
)
258+
245259
// ClusterConditionType defines type for cluster condition type.
246260
type ClusterConditionType string
247261

248262
const (
249-
// ClusterInit indicates whether the cluster is initializing.
250-
ClusterInit ClusterConditionType = "Initializing"
251-
// ClusterReady indicates whether all containers in the pod are ready.
252-
ClusterReady ClusterConditionType = "Ready"
253-
// ClusterError indicates whether the cluster encountered an error.
254-
ClusterError ClusterConditionType = "Error"
263+
// ConditionInit indicates whether the cluster is initializing.
264+
ConditionInit ClusterConditionType = "Initializing"
265+
// ConditionUpdate indicates whether the cluster is being updated.
266+
ConditionUpdate ClusterConditionType = "Updating"
267+
// ConditionReady indicates whether all containers in the pod are ready.
268+
ConditionReady ClusterConditionType = "Ready"
269+
// ConditionClose indicates whether the cluster is closed.
270+
ConditionClose ClusterConditionType = "Closed"
271+
// ConditionError indicates whether there is an error in the cluster.
272+
ConditionError ClusterConditionType = "Error"
255273
)
256274

257275
// ClusterCondition defines type for cluster conditions.
@@ -321,7 +339,7 @@ type MysqlClusterStatus struct {
321339
// ReadyNodes represents number of the nodes that are in ready state.
322340
ReadyNodes int `json:"readyNodes,omitempty"`
323341
// State
324-
State ClusterConditionType `json:"state,omitempty"`
342+
State ClusterState `json:"state,omitempty"`
325343
// Conditions contains the list of the cluster conditions fulfilled.
326344
Conditions []ClusterCondition `json:"conditions,omitempty"`
327345
// Nodes contains the list of the node status fulfilled.

mysqlcluster/syncer/statefulset.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ func (s *StatefulSetSyncer) applyNWait(ctx context.Context, pod *corev1.Pod) err
470470
if pod.ObjectMeta.Labels["controller-revision-hash"] == s.sfs.Status.UpdateRevision {
471471
log.Info("pod is already updated", "pod name", pod.Name)
472472
} else {
473+
s.Status.State = apiv1alpha1.ClusterUpdateState
473474
log.Info("updating pod", "pod", pod.Name, "key", s.Unwrap())
474475
if pod.DeletionTimestamp != nil {
475476
log.Info("pod is being deleted", "pod", pod.Name, "key", s.Unwrap())

mysqlcluster/syncer/status.go

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,7 @@ func (s *StatusSyncer) GetOwner() runtime.Object { return s.MysqlCluster }
7878

7979
// Sync persists data into the external store.
8080
func (s *StatusSyncer) Sync(ctx context.Context) (syncer.SyncResult, error) {
81-
clusterCondition := apiv1alpha1.ClusterCondition{
82-
Type: apiv1alpha1.ClusterInit,
83-
Status: corev1.ConditionTrue,
84-
LastTransitionTime: metav1.NewTime(time.Now()),
85-
}
86-
s.Status.State = apiv1alpha1.ClusterInit
81+
clusterCondition := s.updateClusterStatus()
8782

8883
list := corev1.PodList{}
8984
err := s.cli.List(
@@ -109,23 +104,24 @@ func (s *StatusSyncer) Sync(ctx context.Context) (syncer.SyncResult, error) {
109104
}
110105
case corev1.PodScheduled:
111106
if cond.Reason == corev1.PodReasonUnschedulable {
107+
// When an error occurs, it is first recorded in the condition,
108+
// but the cluster status is not updated immediately.
112109
clusterCondition = apiv1alpha1.ClusterCondition{
113-
Type: apiv1alpha1.ClusterError,
110+
Type: apiv1alpha1.ConditionError,
114111
Status: corev1.ConditionTrue,
115112
LastTransitionTime: metav1.NewTime(time.Now()),
116113
Reason: corev1.PodReasonUnschedulable,
117114
Message: cond.Message,
118115
}
119-
s.Status.State = apiv1alpha1.ClusterError
120116
}
121117
}
122118
}
123119
}
124120

125121
s.Status.ReadyNodes = len(readyNodes)
126-
if s.Status.ReadyNodes == int(*s.Spec.Replicas) {
127-
s.Status.State = apiv1alpha1.ClusterReady
128-
clusterCondition.Type = apiv1alpha1.ClusterReady
122+
if s.Status.ReadyNodes == int(*s.Spec.Replicas) && int(*s.Spec.Replicas) != 0 {
123+
s.Status.State = apiv1alpha1.ClusterReadyState
124+
clusterCondition.Type = apiv1alpha1.ConditionReady
129125
}
130126

131127
if len(s.Status.Conditions) == 0 {
@@ -140,10 +136,45 @@ func (s *StatusSyncer) Sync(ctx context.Context) (syncer.SyncResult, error) {
140136
s.Status.Conditions = s.Status.Conditions[len(s.Status.Conditions)-maxStatusesQuantity:]
141137
}
142138

143-
// update ready nodes' status.
139+
// Update ready nodes' status.
144140
return syncer.SyncResult{}, s.updateNodeStatus(ctx, s.cli, readyNodes)
145141
}
146142

143+
// updateClusterStatus update the cluster status and returns condition.
144+
func (s *StatusSyncer) updateClusterStatus() apiv1alpha1.ClusterCondition {
145+
clusterCondition := apiv1alpha1.ClusterCondition{
146+
Type: apiv1alpha1.ConditionInit,
147+
Status: corev1.ConditionTrue,
148+
LastTransitionTime: metav1.NewTime(time.Now()),
149+
}
150+
151+
oldState := s.Status.State
152+
// If the state does not exist, the cluster is being initialized.
153+
if oldState == "" {
154+
s.Status.State = apiv1alpha1.ClusterInitState
155+
return clusterCondition
156+
}
157+
// If the expected number of replicas and the actual number
158+
// of replicas are both 0, the cluster has been closed.
159+
if int(*s.Spec.Replicas) == 0 && s.Status.ReadyNodes == 0 {
160+
clusterCondition.Type = apiv1alpha1.ConditionClose
161+
s.Status.State = apiv1alpha1.ClusterCloseState
162+
return clusterCondition
163+
}
164+
// When the cluster is ready or closed, the number of replicas changes,
165+
// indicating that the cluster is updating nodes.
166+
if oldState == apiv1alpha1.ClusterReadyState || oldState == apiv1alpha1.ClusterCloseState {
167+
if int(*s.Spec.Replicas) != s.Status.ReadyNodes {
168+
clusterCondition.Type = apiv1alpha1.ConditionUpdate
169+
s.Status.State = apiv1alpha1.ClusterUpdateState
170+
return clusterCondition
171+
}
172+
}
173+
174+
clusterCondition.Type = apiv1alpha1.ClusterConditionType(oldState)
175+
return clusterCondition
176+
}
177+
147178
// updateNodeStatus update the node status.
148179
func (s *StatusSyncer) updateNodeStatus(ctx context.Context, cli client.Client, pods []corev1.Pod) error {
149180
sctName := s.GetNameForResource(utils.Secret)

0 commit comments

Comments
 (0)