Skip to content

Commit

Permalink
Merge branch 'feature/component-definition' of github.com:apecloud/ku…
Browse files Browse the repository at this point in the history
…beblocks into feature/component-definition
  • Loading branch information
Y-Rookie committed Oct 23, 2023
2 parents b95b1da + bb5eade commit 26b4020
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 118 deletions.
13 changes: 5 additions & 8 deletions apis/apps/v1alpha1/cluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ type ClusterStatus struct {
}

// ClusterComponentSpec defines the cluster component spec.
// +kubebuilder:validation:XValidation:rule="has(self.componentDefRef) || has(self.componentDef)",message="either componentDefRef or componentDef should be provided"
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.componentDefRef) || has(self.componentDefRef)", message="componentDefRef is required once set"
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.componentDef) || has(self.componentDef)", message="componentDef is required once set"
type ClusterComponentSpec struct {
// name defines cluster's component name, this name is also part of Service DNS name, so this name will
// comply with IANA Service Naming rule.
Expand All @@ -233,17 +236,11 @@ type ClusterComponentSpec struct {
// +optional
ComponentDefRef string `json:"componentDefRef"`

// enableComponentDefinition is the switch to control whether to enable the new ComponentDefinition API.
// ComponentDefinition and ClusterDefinition are mutually exclusive. When the switch is enabled, ComponentDefRef will be ignored.
// +kubebuilder:default=false
// +optional
EnableComponentDefinition bool `json:"enableComponentDefinition,omitempty"`

// componentDef references the name of the ComponentDefinition.
// When the enableComponentDefinition is true, ComponentDef must be provided. In this case, ComponentDef takes precedence over ComponentDefRef, and ComponentDefRef will be ignored.
// +kubebuilder:validation:Required
// If both componentDefRef and componentDef are provided, the componentDef will take precedence over componentDefRef.
// +kubebuilder:validation:MaxLength=22
// +kubebuilder:validation:Pattern:=`^[a-z]([a-z0-9\-]*[a-z0-9])?$`
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="componentDef is immutable"
// +optional
ComponentDef string `json:"componentDef"`

Expand Down
22 changes: 12 additions & 10 deletions config/crd/bases/apps.kubeblocks.io_clusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,14 @@ spec:
type: object
componentDef:
description: componentDef references the name of the ComponentDefinition.
When the enableComponentDefinition is true, ComponentDef must
be provided. In this case, ComponentDef takes precedence over
ComponentDefRef, and ComponentDefRef will be ignored.
If both componentDefRef and componentDef are provided, the
componentDef will take precedence over componentDefRef.
maxLength: 22
pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$
type: string
x-kubernetes-validations:
- message: componentDef is immutable
rule: self == oldSelf
componentDefRef:
description: componentDefRef references componentDef defined
in ClusterDefinition spec. Need to comply with IANA Service
Expand All @@ -245,13 +247,6 @@ spec:
x-kubernetes-validations:
- message: componentDefRef is immutable
rule: self == oldSelf
enableComponentDefinition:
default: false
description: enableComponentDefinition is the switch to control
whether to enable the new ComponentDefinition API. ComponentDefinition
and ClusterDefinition are mutually exclusive. When the switch
is enabled, ComponentDefRef will be ignored.
type: boolean
enabledLogs:
description: enabledLogs indicates which log file takes effect
in the database cluster. element is the log type which is
Expand Down Expand Up @@ -665,6 +660,13 @@ spec:
- name
- replicas
type: object
x-kubernetes-validations:
- message: either componentDefRef or componentDef should be provided
rule: has(self.componentDefRef) || has(self.componentDef)
- message: componentDefRef is required once set
rule: '!has(oldSelf.componentDefRef) || has(self.componentDefRef)'
- message: componentDef is required once set
rule: '!has(oldSelf.componentDef) || has(self.componentDef)'
maxItems: 128
minItems: 1
type: array
Expand Down
5 changes: 0 additions & 5 deletions controllers/apps/cluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,19 +164,14 @@ func (r *ClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
// TODO: transformers are vertices, theirs' dependencies are edges, make plan Build stage a DAG.
plan, errBuild := planBuilder.
AddTransformer(
// handle deletion
// handle cluster deletion first
&ClusterDeletionTransformer{},
// check is recovering from halted cluster
&HaltRecoveryTransformer{},
// assure meta-data info
// update finalizer and cd&cv labels
&AssureMetaTransformer{},
// validate ref objects
// validate cd & cv's existence and availability
&ValidateAndLoadRefResourcesTransformer{},
// validate config
&ValidateEnableLogsTransformer{},
// create cluster connection credential secret object
&ClusterCredentialTransformer{Client: r.Client},
// handle restore before ClusterComponentTransformer
Expand Down
15 changes: 0 additions & 15 deletions controllers/apps/components/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,21 +75,6 @@ func ListPodOwnedByComponent(ctx context.Context, cli client.Client, namespace s
return ListObjWithLabelsInNamespace(ctx, cli, generics.PodSignature, namespace, labels)
}

// RestartPod restarts a Pod through updating the pod's annotation
func RestartPod(podTemplate *corev1.PodTemplateSpec) error {
if podTemplate.Annotations == nil {
podTemplate.Annotations = map[string]string{}
}

startTimestamp := time.Now() // TODO(impl): opsRes.OpsRequest.Status.StartTimestamp
restartTimestamp := podTemplate.Annotations[constant.RestartAnnotationKey]
// if res, _ := time.Parse(time.RFC3339, restartTimestamp); startTimestamp.After(res) {
if res, _ := time.Parse(time.RFC3339, restartTimestamp); startTimestamp.Before(res) {
podTemplate.Annotations[constant.RestartAnnotationKey] = startTimestamp.Format(time.RFC3339)
}
return nil
}

// mergeAnnotations keeps the original annotations.
// if annotations exist and are replaced, the Deployment/StatefulSet will be updated.
func mergeAnnotations(originalAnnotations map[string]string, targetAnnotations *map[string]string) {
Expand Down
10 changes: 0 additions & 10 deletions controllers/apps/transformer_component_workload.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,6 @@ func (t *ComponentWorkloadTransformer) handleWorkloadUpdate(reqCtx intctrlutil.R
cluster *appsv1alpha1.Cluster, synthesizeComp *component.SynthesizedComponent, obj, rsm *workloads.ReplicatedStateMachine) error {
cwo := newComponentWorkloadOps(reqCtx, t.Client, cluster, synthesizeComp, obj, rsm, dag)

// handle rsm workload restart
if err := cwo.restart(); err != nil {
return err
}

// handle rsm expand volume
if err := cwo.expandVolume(); err != nil {
return err
Expand Down Expand Up @@ -295,11 +290,6 @@ func copyAndMerge(oldObj, newObj client.Object, cluster *appsv1alpha1.Cluster) c
}
}

// restart handles rsm workload restart by patch pod template annotation
func (r *componentWorkloadOps) restart() error {
return components.RestartPod(&r.runningRSM.Spec.Template)
}

// expandVolume handles rsm workload expand volume
func (r *componentWorkloadOps) expandVolume() error {
for _, vct := range r.runningRSM.Spec.VolumeClaimTemplates {
Expand Down
43 changes: 0 additions & 43 deletions controllers/apps/transformer_validate_enable_logs.go

This file was deleted.

22 changes: 12 additions & 10 deletions deploy/helm/crds/apps.kubeblocks.io_clusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,14 @@ spec:
type: object
componentDef:
description: componentDef references the name of the ComponentDefinition.
When the enableComponentDefinition is true, ComponentDef must
be provided. In this case, ComponentDef takes precedence over
ComponentDefRef, and ComponentDefRef will be ignored.
If both componentDefRef and componentDef are provided, the
componentDef will take precedence over componentDefRef.
maxLength: 22
pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$
type: string
x-kubernetes-validations:
- message: componentDef is immutable
rule: self == oldSelf
componentDefRef:
description: componentDefRef references componentDef defined
in ClusterDefinition spec. Need to comply with IANA Service
Expand All @@ -245,13 +247,6 @@ spec:
x-kubernetes-validations:
- message: componentDefRef is immutable
rule: self == oldSelf
enableComponentDefinition:
default: false
description: enableComponentDefinition is the switch to control
whether to enable the new ComponentDefinition API. ComponentDefinition
and ClusterDefinition are mutually exclusive. When the switch
is enabled, ComponentDefRef will be ignored.
type: boolean
enabledLogs:
description: enabledLogs indicates which log file takes effect
in the database cluster. element is the log type which is
Expand Down Expand Up @@ -665,6 +660,13 @@ spec:
- name
- replicas
type: object
x-kubernetes-validations:
- message: either componentDefRef or componentDef should be provided
rule: has(self.componentDefRef) || has(self.componentDef)
- message: componentDefRef is required once set
rule: '!has(oldSelf.componentDefRef) || has(self.componentDefRef)'
- message: componentDef is required once set
rule: '!has(oldSelf.componentDef) || has(self.componentDef)'
maxItems: 128
minItems: 1
type: array
Expand Down
36 changes: 19 additions & 17 deletions pkg/controller/component/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,18 @@ func BuildProtoComponent(reqCtx ictrlutil.RequestCtx,
cli client.Client,
cluster *appsv1alpha1.Cluster,
clusterCompSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1alpha1.Component, error) {
// check if clusterCompSpec enable the ComponentDefinition API feature gate.
if clusterCompSpec.EnableComponentDefinition && clusterCompSpec.ComponentDef != "" {
return buildProtoCompFromCompDef(reqCtx, cli, cluster, clusterCompSpec)
}
if !clusterCompSpec.EnableComponentDefinition && clusterCompSpec.ComponentDefRef != "" {
if clusterCompSpec.ComponentDef == "" {
if clusterCompSpec.ComponentDefRef == "" {
return nil, errors.New("invalid component spec")
}
if cluster.Spec.ClusterDefRef == "" {
return nil, errors.New("clusterDefRef is required when enableComponentDefinition is false")
return nil, errors.New("clusterDefRef is required when component def is not provided")
}
return buildProtoCompFromConvertor(reqCtx, cli, cluster, clusterCompSpec)
}
return nil, errors.New("invalid component spec")
if clusterCompSpec.ComponentDef != "" {
return buildProtoCompFromCompDef(reqCtx, cli, cluster, clusterCompSpec)
}
return buildProtoCompFromConvertor(reqCtx, cli, cluster, clusterCompSpec)
}

// BuildComponentDefinition constructs a ComponentDefinition object based on the following rules:
Expand All @@ -56,21 +57,22 @@ func BuildComponentDefinition(reqCtx ictrlutil.RequestCtx,
cli client.Client,
cluster *appsv1alpha1.Cluster,
clusterCompSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1alpha1.ComponentDefinition, error) {
// check if clusterCompSpec enable the ComponentDefinition API feature gate.
if clusterCompSpec.EnableComponentDefinition && clusterCompSpec.ComponentDef != "" {
if clusterCompSpec.ComponentDef == "" {
if clusterCompSpec.ComponentDefRef == "" {
return nil, errors.New("invalid component spec")
}
if cluster.Spec.ClusterDefRef == "" {
return nil, errors.New("clusterDefRef is required when component def is not provided")
}
}
if clusterCompSpec.ComponentDef != "" {
cmpd := &appsv1alpha1.ComponentDefinition{}
if err := ictrlutil.ValidateExistence(reqCtx.Ctx, cli, types.NamespacedName{Name: clusterCompSpec.ComponentDef}, cmpd, false); err != nil {
return nil, err
}
return cmpd, nil
}
if !clusterCompSpec.EnableComponentDefinition && clusterCompSpec.ComponentDefRef != "" {
if cluster.Spec.ClusterDefRef == "" {
return nil, errors.New("clusterDefRef is required when enableComponentDefinition is false")
}
return buildCompDefFromConvertor(reqCtx, cli, cluster, clusterCompSpec)
}
return nil, errors.New("invalid component spec")
return buildCompDefFromConvertor(reqCtx, cli, cluster, clusterCompSpec)
}

// buildCompDefFromConvertor builds a new ComponentDefinition object based on converting clusterComponentDefinition to ComponentDefinition.
Expand Down

0 comments on commit 26b4020

Please sign in to comment.