You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by mi...@apache.org on 2023/04/13 02:26:52 UTC

[shardingsphere-on-cloud] branch feat-sschaos updated: Rebase sschaos (#308)

This is an automated email from the ASF dual-hosted git repository.

miaoliyao pushed a commit to branch feat-sschaos
in repository https://gitbox.apache.org/repos/asf/shardingsphere-on-cloud.git


The following commit(s) were added to refs/heads/feat-sschaos by this push:
     new 3b23bfc  Rebase sschaos (#308)
3b23bfc is described below

commit 3b23bfcceda890136f5f26dd3c51316ed0a42ee4
Author: moomman <85...@users.noreply.github.com>
AuthorDate: Thu Apr 13 10:26:47 2023 +0800

    Rebase sschaos (#308)
    
    * chore: add ifExists to ast (#304)
    
    Signed-off-by: wangbo <wa...@sphere-ex.com>
    Co-authored-by: wangbo <wa...@sphere-ex.com>
    
    * Common builder (#305)
    
    * refactor container builder to pkg/common
    
    * fix golang-lint check
    
    * add lincense check
    
    ---------
    
    Co-authored-by: moonman <ag...@163.com>
    
    * refactor configmap to common pkg (#306)
    
    Co-authored-by: moonman <ag...@163.com>
    
    * Rebase main
    
    ---------
    
    Signed-off-by: mlycore <ma...@126.com>
    Co-authored-by: Xu-Wentao <cu...@yahoo.com>
    Co-authored-by: liyao <ma...@126.com>
    Co-authored-by: Zhengqiang Duan <du...@apache.org>
    Co-authored-by: moonman <ag...@163.com>
    
    * chore: update go mod
    
    Signed-off-by: mlycore <ma...@126.com>
    
    ---------
    
    Signed-off-by: wangbo <wa...@sphere-ex.com>
    Signed-off-by: mlycore <ma...@126.com>
    Co-authored-by: Jack <87...@qq.com>
    Co-authored-by: wangbo <wa...@sphere-ex.com>
    Co-authored-by: moonman <ag...@163.com>
    Co-authored-by: Xu-Wentao <cu...@yahoo.com>
    Co-authored-by: liyao <ma...@126.com>
    Co-authored-by: Zhengqiang Duan <du...@apache.org>
---
 .../pkg/controllers/compute_node_controller.go     |   2 +-
 .../pkg/distsql/visitor/rdl_visitor.go             |  13 +-
 .../pkg/reconcile/common/configmap.go              |  68 +++++++++
 .../pkg/reconcile/common/container.go              | 160 ++++++++++++++++++++
 .../pkg/reconcile/common/container_test.go         |  70 +++++++++
 .../pkg/reconcile/computenode/configmap.go         |  68 +++------
 .../pkg/reconcile/computenode/configmap_test.go    |   4 +-
 .../pkg/reconcile/computenode/deployment.go        | 164 ++-------------------
 .../pkg/reconcile/computenode/deployment_test.go   |  47 ------
 9 files changed, 344 insertions(+), 252 deletions(-)

diff --git a/shardingsphere-operator/pkg/controllers/compute_node_controller.go b/shardingsphere-operator/pkg/controllers/compute_node_controller.go
index 593e1a2..7dbf64b 100644
--- a/shardingsphere-operator/pkg/controllers/compute_node_controller.go
+++ b/shardingsphere-operator/pkg/controllers/compute_node_controller.go
@@ -253,7 +253,7 @@ func (r *ComputeNodeReconciler) getServiceByNamespacedName(ctx context.Context,
 }
 
 func (r *ComputeNodeReconciler) createConfigMap(ctx context.Context, cn *v1alpha1.ComputeNode) error {
-	cm := reconcile.NewConfigMap(cn)
+	cm := reconcile.NewCNConfigMap(cn)
 	err := r.Create(ctx, cm)
 	if err != nil && apierrors.IsAlreadyExists(err) || err == nil {
 		return nil
diff --git a/shardingsphere-operator/pkg/distsql/visitor/rdl_visitor.go b/shardingsphere-operator/pkg/distsql/visitor/rdl_visitor.go
index b97955a..3adaeaa 100644
--- a/shardingsphere-operator/pkg/distsql/visitor/rdl_visitor.go
+++ b/shardingsphere-operator/pkg/distsql/visitor/rdl_visitor.go
@@ -53,6 +53,12 @@ func (v *Visitor) VisitIfNotExists(ctx *parser.IfNotExistsContext) *ast.IfNotExi
 	}
 }
 
+func (v *Visitor) VisitIfExists(ctx *parser.IfExistsContext) *ast.IfExists {
+	return &ast.IfExists{
+		IfExists: fmt.Sprintf("%s %s", ctx.IF().GetText(), ctx.EXISTS().GetText()),
+	}
+}
+
 func (v *Visitor) VisitAlterEncryptRule(ctx *parser.AlterEncryptRuleContext) *ast.AlterEncryptRule {
 	stmt := &ast.AlterEncryptRule{}
 	if ctx.AllEncryptRuleDefinition() != nil {
@@ -66,10 +72,9 @@ func (v *Visitor) VisitAlterEncryptRule(ctx *parser.AlterEncryptRuleContext) *as
 func (v *Visitor) VisitDropEncryptRule(ctx *parser.DropEncryptRuleContext) *ast.DropEncryptRule {
 	stmt := &ast.DropEncryptRule{}
 
-	// TODO: Add IfExists to AST
-	// if ctx.IfExists() != nil {
-	// 	stmt.IfExists = v.VisitIfExists(ctx.IfExists().(*parser.IfExistsContext))
-	// }
+	if ctx.IfExists() != nil {
+		stmt.IfExists = v.VisitIfExists(ctx.IfExists().(*parser.IfExistsContext))
+	}
 
 	if ctx.AllTableName() != nil {
 		for _, tableName := range ctx.AllTableName() {
diff --git a/shardingsphere-operator/pkg/reconcile/common/configmap.go b/shardingsphere-operator/pkg/reconcile/common/configmap.go
new file mode 100644
index 0000000..354ceeb
--- /dev/null
+++ b/shardingsphere-operator/pkg/reconcile/common/configmap.go
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 common
+
+import v1 "k8s.io/api/core/v1"
+
+// ConfigMapBuilder generic configmap interface
+type ConfigMapBuilder interface {
+	SetName(name string) ConfigMapBuilder
+	SetNamespace(namespace string) ConfigMapBuilder
+	SetLabels(labels map[string]string) ConfigMapBuilder
+	SetAnnotations(annos map[string]string) ConfigMapBuilder
+	Build() *v1.ConfigMap
+}
+
+// commonConfigMapBuilder common configmap implementation
+type commonConfigMapBuilder struct {
+	configmap *v1.ConfigMap
+}
+
+// NewCommonConfigMapBuilder Create a new common configmap builder
+func NewCommonConfigMapBuilder(configmap *v1.ConfigMap) ConfigMapBuilder {
+	return &commonConfigMapBuilder{configmap}
+}
+
+// SetName set the ConfigMap name
+func (c *commonConfigMapBuilder) SetName(name string) ConfigMapBuilder {
+	c.configmap.Name = name
+	return c
+}
+
+// SetNamespace set the ConfigMap namespace
+func (c *commonConfigMapBuilder) SetNamespace(namespace string) ConfigMapBuilder {
+	c.configmap.Namespace = namespace
+	return c
+}
+
+// SetLabels set the ConfigMap labels
+func (c *commonConfigMapBuilder) SetLabels(labels map[string]string) ConfigMapBuilder {
+	c.configmap.Labels = labels
+	return c
+}
+
+// SetAnnotations set the ConfigMap annotations
+func (c *commonConfigMapBuilder) SetAnnotations(annos map[string]string) ConfigMapBuilder {
+	c.configmap.Annotations = annos
+	return c
+}
+
+// Build returns a ConfigMap
+func (c *commonConfigMapBuilder) Build() *v1.ConfigMap {
+	return c.configmap
+}
diff --git a/shardingsphere-operator/pkg/reconcile/common/container.go b/shardingsphere-operator/pkg/reconcile/common/container.go
new file mode 100644
index 0000000..a4fb878
--- /dev/null
+++ b/shardingsphere-operator/pkg/reconcile/common/container.go
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 common
+
+import (
+	v1 "k8s.io/api/core/v1"
+)
+
+// ContainerBuilder is a common builder for Container
+type ContainerBuilder interface {
+	SetName(name string) ContainerBuilder
+	SetImage(image string) ContainerBuilder
+	SetPorts(ports []v1.ContainerPort) ContainerBuilder
+	SetResources(res v1.ResourceRequirements) ContainerBuilder
+	SetLivenessProbe(probe *v1.Probe) ContainerBuilder
+	SetReadinessProbe(probe *v1.Probe) ContainerBuilder
+	SetStartupProbe(probe *v1.Probe) ContainerBuilder
+	SetEnv(envs []v1.EnvVar) ContainerBuilder
+	SetCommand(cmds []string) ContainerBuilder
+	SetVolumeMount(mount *v1.VolumeMount) ContainerBuilder
+	Build() *v1.Container
+}
+
+// NewContainerBuilder return a builder for Container
+func NewContainerBuilder() ContainerBuilder {
+	return &containerBuilder{
+		container: DefaultContainer(),
+	}
+}
+
+type containerBuilder struct {
+	container *v1.Container
+}
+
+// SetName sets the name of the container
+func (c *containerBuilder) SetName(name string) ContainerBuilder {
+	c.container.Name = name
+	return c
+}
+
+// SetImage sets the name of the container
+func (c *containerBuilder) SetImage(image string) ContainerBuilder {
+	c.container.Image = image
+	return c
+}
+
+// SetPorts set the container port of the container
+func (c *containerBuilder) SetPorts(ports []v1.ContainerPort) ContainerBuilder {
+	if ports == nil {
+		c.container.Ports = []v1.ContainerPort{}
+	}
+	if ports != nil {
+		c.container.Ports = ports
+	}
+	return c
+}
+
+// SetResources set the resources of the container
+func (c *containerBuilder) SetResources(res v1.ResourceRequirements) ContainerBuilder {
+	c.container.Resources = res
+	return c
+}
+
+// SetLivenessProbe set the livenessProbe of the container
+func (c *containerBuilder) SetLivenessProbe(probe *v1.Probe) ContainerBuilder {
+	if probe != nil {
+		if c.container.LivenessProbe == nil {
+			c.container.LivenessProbe = &v1.Probe{}
+		}
+		c.container.LivenessProbe = probe
+	}
+	return c
+}
+
+// SetReadinessProbe set the readinessProbe of the container
+func (c *containerBuilder) SetReadinessProbe(probe *v1.Probe) ContainerBuilder {
+	if probe != nil {
+		if c.container.ReadinessProbe == nil {
+			c.container.ReadinessProbe = &v1.Probe{}
+		}
+		c.container.ReadinessProbe = probe
+	}
+	return c
+}
+
+// SetStartupProbe set the startupProbe of the container
+func (c *containerBuilder) SetStartupProbe(probe *v1.Probe) ContainerBuilder {
+	if probe != nil {
+		if c.container.StartupProbe == nil {
+			c.container.StartupProbe = &v1.Probe{}
+		}
+		c.container.StartupProbe = probe
+	}
+	return c
+}
+
+// SetEnv set the env of the container
+func (c *containerBuilder) SetEnv(envs []v1.EnvVar) ContainerBuilder {
+	if envs == nil {
+		c.container.Env = []v1.EnvVar{}
+	}
+	if envs != nil {
+		c.container.Env = envs
+	}
+	return c
+}
+
+// SetCommand set the command of the container
+func (c *containerBuilder) SetCommand(cmds []string) ContainerBuilder {
+	if cmds != nil {
+		c.container.Command = cmds
+	}
+	return c
+}
+
+// SetVolumeMount set the mount point of the container
+func (c *containerBuilder) SetVolumeMount(mount *v1.VolumeMount) ContainerBuilder {
+	if c.container.VolumeMounts == nil {
+		c.container.VolumeMounts = []v1.VolumeMount{*mount}
+	} else {
+		for idx := range c.container.VolumeMounts {
+			if c.container.VolumeMounts[idx].Name == mount.Name {
+				c.container.VolumeMounts[idx] = *mount
+				return c
+			}
+		}
+		c.container.VolumeMounts = append(c.container.VolumeMounts, *mount)
+	}
+
+	return c
+}
+
+// Build returns a Container
+func (c *containerBuilder) Build() *v1.Container {
+	return c.container
+}
+
+// DefaultContainer returns a container with busybox
+func DefaultContainer() *v1.Container {
+	con := &v1.Container{
+		Name:  "default",
+		Image: "busybox:1.35.0",
+	}
+	return con
+}
diff --git a/shardingsphere-operator/pkg/reconcile/common/container_test.go b/shardingsphere-operator/pkg/reconcile/common/container_test.go
new file mode 100644
index 0000000..2fa0308
--- /dev/null
+++ b/shardingsphere-operator/pkg/reconcile/common/container_test.go
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 common
+
+import (
+	corev1 "k8s.io/api/core/v1"
+	"testing"
+)
+
+func TestContainerBuilder_SetVolumeMount(t *testing.T) {
+	var found bool
+
+	// create a new container builder
+	c := &containerBuilder{
+		container: &corev1.Container{
+			VolumeMounts: []corev1.VolumeMount{},
+		},
+	}
+
+	// add a new volume mount
+	mount := &corev1.VolumeMount{
+		Name:      "test-mount",
+		MountPath: "/test",
+	}
+	c.SetVolumeMount(mount)
+
+	// check if the volume mount has been added
+	for _, v := range c.container.VolumeMounts {
+		if v.Name == mount.Name {
+			found = true
+			break
+		}
+	}
+	if !found {
+		t.Errorf("SetVolumeMount() failed to add the VolumeMount")
+	}
+
+	// update an existing volume mount
+	updatedMount := &corev1.VolumeMount{
+		Name:      "test-mount",
+		MountPath: "/new-test",
+	}
+	c.SetVolumeMount(updatedMount)
+
+	// check if the volume mount has been updated
+	for _, v := range c.container.VolumeMounts {
+		if v.MountPath == updatedMount.MountPath {
+			found = true
+			break
+		}
+	}
+	if !found {
+		t.Errorf("SetVolumeMount() failed to update the VolumeMount")
+	}
+}
diff --git a/shardingsphere-operator/pkg/reconcile/computenode/configmap.go b/shardingsphere-operator/pkg/reconcile/computenode/configmap.go
index 3735541..fdc0fc7 100644
--- a/shardingsphere-operator/pkg/reconcile/computenode/configmap.go
+++ b/shardingsphere-operator/pkg/reconcile/computenode/configmap.go
@@ -21,6 +21,8 @@ import (
 	"encoding/json"
 	"reflect"
 
+	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/common"
+
 	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
 	"gopkg.in/yaml.v2"
 	v1 "k8s.io/api/core/v1"
@@ -42,8 +44,8 @@ const (
 	AnnoLogbackConfig = "computenode.shardingsphere.org/logback"
 )
 
-// NewConfigMap returns a new ConfigMap
-func NewConfigMap(cn *v1alpha1.ComputeNode) *v1.ConfigMap {
+// NewCNConfigMap returns a new ConfigMap
+func NewCNConfigMap(cn *v1alpha1.ComputeNode) *v1.ConfigMap {
 	builder := NewConfigMapBuilder(cn.GetObjectMeta(), cn.GetObjectKind().GroupVersionKind())
 	builder.SetName(cn.Name).SetNamespace(cn.Namespace).SetLabels(cn.Labels).SetAnnotations(cn.Annotations)
 
@@ -89,76 +91,46 @@ func updateConfigMapServerConf(cluster string, servconf *v1alpha1.ServerConfig,
 	return string(y), err
 }
 
-// ConfigMapBuilder is a builder for ConfigMap by ComputeNode
-type ConfigMapBuilder interface {
-	SetName(name string) ConfigMapBuilder
-	SetNamespace(namespace string) ConfigMapBuilder
-	SetLabels(labels map[string]string) ConfigMapBuilder
-	SetAnnotations(annos map[string]string) ConfigMapBuilder
-	SetLogback(logback string) ConfigMapBuilder
-	SetServerConfig(serverConfig string) ConfigMapBuilder
-	SetAgentConfig(agentConfig string) ConfigMapBuilder
-	Build() *v1.ConfigMap
+// CNConfigMapBuilder is a builder for ConfigMap by ComputeNode
+type CNConfigMapBuilder interface {
+	common.ConfigMapBuilder
+	SetLogback(logback string) CNConfigMapBuilder
+	SetServerConfig(serverConfig string) CNConfigMapBuilder
+	SetAgentConfig(agentConfig string) CNConfigMapBuilder
 }
 
 type configmapBuilder struct {
+	common.ConfigMapBuilder
 	configmap *v1.ConfigMap
 }
 
-// NewConfigMapBuilder returns a ConfigMapBuilder
-func NewConfigMapBuilder(meta metav1.Object, gvk schema.GroupVersionKind) ConfigMapBuilder {
+// NewConfigMapBuilder returns a CNConfigMapBuilder
+func NewConfigMapBuilder(meta metav1.Object, gvk schema.GroupVersionKind) CNConfigMapBuilder {
+	configmap := DefaultConfigMap(meta, gvk)
 	return &configmapBuilder{
-		configmap: DefaultConfigMap(meta, gvk),
+		common.NewCommonConfigMapBuilder(configmap),
+		configmap,
 	}
 }
 
-// SetName set the ConfigMap name
-func (c *configmapBuilder) SetName(name string) ConfigMapBuilder {
-	c.configmap.Name = name
-	return c
-}
-
-// SetNamespace set the ConfigMap namespace
-func (c *configmapBuilder) SetNamespace(namespace string) ConfigMapBuilder {
-	c.configmap.Namespace = namespace
-	return c
-}
-
-// SetLabels set the ConfigMap labels
-func (c *configmapBuilder) SetLabels(labels map[string]string) ConfigMapBuilder {
-	c.configmap.Labels = labels
-	return c
-}
-
-// SetAnnotations set the ConfigMap annotations
-func (c *configmapBuilder) SetAnnotations(annos map[string]string) ConfigMapBuilder {
-	c.configmap.Annotations = annos
-	return c
-}
-
 // SetLogback set the ConfigMap data logback
-func (c *configmapBuilder) SetLogback(logback string) ConfigMapBuilder {
+func (c *configmapBuilder) SetLogback(logback string) CNConfigMapBuilder {
 	c.configmap.Data[ConfigDataKeyForLogback] = logback
 	return c
 }
 
 // SetServerConfig set the ConfigMap data server config
-func (c *configmapBuilder) SetServerConfig(serviceConfig string) ConfigMapBuilder {
+func (c *configmapBuilder) SetServerConfig(serviceConfig string) CNConfigMapBuilder {
 	c.configmap.Data[ConfigDataKeyForServer] = serviceConfig
 	return c
 }
 
 // SetAgentConfig set the ConfigMap data agent config
-func (c *configmapBuilder) SetAgentConfig(agentConfig string) ConfigMapBuilder {
+func (c *configmapBuilder) SetAgentConfig(agentConfig string) CNConfigMapBuilder {
 	c.configmap.Data[ConfigDataKeyForAgent] = agentConfig
 	return c
 }
 
-// Build returns a ConfigMap
-func (c *configmapBuilder) Build() *v1.ConfigMap {
-	return c.configmap
-}
-
 // DefaultConfigMap returns a ConfigMap filling with default expected values
 func DefaultConfigMap(meta metav1.Object, gvk schema.GroupVersionKind) *v1.ConfigMap {
 	return &v1.ConfigMap{
@@ -181,7 +153,7 @@ func UpdateConfigMap(cn *v1alpha1.ComputeNode, cur *v1.ConfigMap) *v1.ConfigMap
 	exp.ObjectMeta.ResourceVersion = ""
 	exp.Labels = cur.Labels
 	exp.Annotations = cur.Annotations
-	exp.Data = NewConfigMap(cn).Data
+	exp.Data = NewCNConfigMap(cn).Data
 	return exp
 }
 
diff --git a/shardingsphere-operator/pkg/reconcile/computenode/configmap_test.go b/shardingsphere-operator/pkg/reconcile/computenode/configmap_test.go
index 3574a68..d778a77 100644
--- a/shardingsphere-operator/pkg/reconcile/computenode/configmap_test.go
+++ b/shardingsphere-operator/pkg/reconcile/computenode/configmap_test.go
@@ -56,7 +56,7 @@ var _ = Describe("ConfigMap", func() {
 	})
 
 	Context("Assert ObjectMeta", func() {
-		cm := computenode.NewConfigMap(cn)
+		cm := computenode.NewCNConfigMap(cn)
 		It("name should be equal", func() {
 			Expect(expect.Name).To(Equal(cm.Name))
 		})
@@ -69,7 +69,7 @@ var _ = Describe("ConfigMap", func() {
 	})
 
 	Context("Assert Default Spec Data", func() {
-		cm := computenode.NewConfigMap(cn)
+		cm := computenode.NewCNConfigMap(cn)
 		It("default logback should be equal", func() {
 			Expect(expect.Data[computenode.AnnoLogbackConfig]).To(Equal(cm.Data[computenode.AnnoLogbackConfig]))
 		})
diff --git a/shardingsphere-operator/pkg/reconcile/computenode/deployment.go b/shardingsphere-operator/pkg/reconcile/computenode/deployment.go
index fd3e6d9..e62f4c7 100644
--- a/shardingsphere-operator/pkg/reconcile/computenode/deployment.go
+++ b/shardingsphere-operator/pkg/reconcile/computenode/deployment.go
@@ -20,6 +20,8 @@ package computenode
 import (
 	"fmt"
 
+	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/common"
+
 	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
@@ -68,14 +70,14 @@ func absoluteMySQLDriverMountName(p, v string) string {
 // and several different Proxy related attributes
 type ShardingSphereProxyContainerBuilder interface {
 	// A default container builder
-	ContainerBuilder
+	common.ContainerBuilder
 
 	// set the version of ShardingSphere Proxy
 	SetVersion(version string) ShardingSphereProxyContainerBuilder
 }
 
 type shardingSphereProxyContainerBuilder struct {
-	ContainerBuilder
+	common.ContainerBuilder
 }
 
 // SetVersion sets the version of ShardingSphere Proxy
@@ -88,7 +90,7 @@ func (c *shardingSphereProxyContainerBuilder) SetVersion(version string) Shardin
 // This will set default container name
 func NewShardingSphereProxyContainerBuilder() ShardingSphereProxyContainerBuilder {
 	return &shardingSphereProxyContainerBuilder{
-		ContainerBuilder: NewContainerBuilder().
+		ContainerBuilder: common.NewContainerBuilder().
 			SetName(defaultContainerName),
 	}
 }
@@ -96,18 +98,18 @@ func NewShardingSphereProxyContainerBuilder() ShardingSphereProxyContainerBuilde
 // BootstrapContainerBuilder returns a Container for initialization
 // The container will handle initilialization in Pod's InitContainer
 type BootstrapContainerBuilder interface {
-	ContainerBuilder
+	common.ContainerBuilder
 }
 
 type bootstrapContainerBuilder struct {
-	ContainerBuilder
+	common.ContainerBuilder
 }
 
 // NewBootstrapContainerBuilderForMysqlJar will return a builder for MysqlJar download container
 // This will set the default container name, image and commands
 func NewBootstrapContainerBuilderForMysqlJar() BootstrapContainerBuilder {
 	return &bootstrapContainerBuilder{
-		ContainerBuilder: NewContainerBuilder().
+		ContainerBuilder: common.NewContainerBuilder().
 			SetName("download-mysql-jar").
 			SetImage("busybox:1.35.0").
 			SetCommand([]string{"/bin/sh", "-c", downloadMysqlJarScript}),
@@ -118,7 +120,7 @@ func NewBootstrapContainerBuilderForMysqlJar() BootstrapContainerBuilder {
 // This will set the default container name, image and commands
 func NewBootstrapContainerBuilderForAgentBin() BootstrapContainerBuilder {
 	return &bootstrapContainerBuilder{
-		ContainerBuilder: NewContainerBuilder().
+		ContainerBuilder: common.NewContainerBuilder().
 			SetName("download-agent-bin-jar").
 			SetImage("busybox:1.35.0").
 			SetCommand([]string{"/bin/sh", "-c", downloadAgentJarScript}),
@@ -130,144 +132,6 @@ func (b *bootstrapContainerBuilder) Build() *corev1.Container {
 	return b.ContainerBuilder.Build()
 }
 
-// ContainerBuilder is a common builder for Container
-type ContainerBuilder interface {
-	SetName(name string) ContainerBuilder
-	SetImage(image string) ContainerBuilder
-	SetPorts(ports []corev1.ContainerPort) ContainerBuilder
-	SetResources(res corev1.ResourceRequirements) ContainerBuilder
-	SetLivenessProbe(probe *corev1.Probe) ContainerBuilder
-	SetReadinessProbe(probe *corev1.Probe) ContainerBuilder
-	SetStartupProbe(probe *corev1.Probe) ContainerBuilder
-	SetEnv(envs []corev1.EnvVar) ContainerBuilder
-	SetCommand(cmds []string) ContainerBuilder
-	SetVolumeMount(mount *corev1.VolumeMount) ContainerBuilder
-	Build() *corev1.Container
-}
-
-// NewContainerBuilder return a builder for Container
-func NewContainerBuilder() ContainerBuilder {
-	return &containerBuilder{
-		container: DefaultContainer(),
-	}
-}
-
-type containerBuilder struct {
-	container *corev1.Container
-}
-
-// SetName sets the name of the container
-func (c *containerBuilder) SetName(name string) ContainerBuilder {
-	c.container.Name = name
-	return c
-}
-
-// SetImage sets the name of the container
-func (c *containerBuilder) SetImage(image string) ContainerBuilder {
-	c.container.Image = image
-	return c
-}
-
-// SetPorts set the container port of the container
-func (c *containerBuilder) SetPorts(ports []corev1.ContainerPort) ContainerBuilder {
-	if ports == nil {
-		c.container.Ports = []corev1.ContainerPort{}
-	}
-	if ports != nil {
-		c.container.Ports = ports
-	}
-	return c
-}
-
-// SetResources set the resources of the container
-func (c *containerBuilder) SetResources(res corev1.ResourceRequirements) ContainerBuilder {
-	c.container.Resources = res
-	return c
-}
-
-// SetLivenessProbe set the livenessProbe of the container
-func (c *containerBuilder) SetLivenessProbe(probe *corev1.Probe) ContainerBuilder {
-	if probe != nil {
-		if c.container.LivenessProbe == nil {
-			c.container.LivenessProbe = &corev1.Probe{}
-		}
-		c.container.LivenessProbe = probe
-	}
-	return c
-}
-
-// SetReadinessProbe set the readinessProbe of the container
-func (c *containerBuilder) SetReadinessProbe(probe *corev1.Probe) ContainerBuilder {
-	if probe != nil {
-		if c.container.ReadinessProbe == nil {
-			c.container.ReadinessProbe = &corev1.Probe{}
-		}
-		c.container.ReadinessProbe = probe
-	}
-	return c
-}
-
-// SetStartupProbe set the startupProbe of the container
-func (c *containerBuilder) SetStartupProbe(probe *corev1.Probe) ContainerBuilder {
-	if probe != nil {
-		if c.container.StartupProbe == nil {
-			c.container.StartupProbe = &corev1.Probe{}
-		}
-		c.container.StartupProbe = probe
-	}
-	return c
-}
-
-// SetEnv set the env of the container
-func (c *containerBuilder) SetEnv(envs []corev1.EnvVar) ContainerBuilder {
-	if envs == nil {
-		c.container.Env = []corev1.EnvVar{}
-	}
-	if envs != nil {
-		c.container.Env = envs
-	}
-	return c
-}
-
-// SetCommand set the command of the container
-func (c *containerBuilder) SetCommand(cmds []string) ContainerBuilder {
-	if cmds != nil {
-		c.container.Command = cmds
-	}
-	return c
-}
-
-// SetVolumeMount set the mount point of the container
-func (c *containerBuilder) SetVolumeMount(mount *corev1.VolumeMount) ContainerBuilder {
-	if c.container.VolumeMounts == nil {
-		c.container.VolumeMounts = []corev1.VolumeMount{*mount}
-	} else {
-		for idx := range c.container.VolumeMounts {
-			if c.container.VolumeMounts[idx].Name == mount.Name {
-				c.container.VolumeMounts[idx] = *mount
-				return c
-			}
-		}
-		c.container.VolumeMounts = append(c.container.VolumeMounts, *mount)
-	}
-
-	return c
-}
-
-// Build returns a Container
-func (c *containerBuilder) Build() *corev1.Container {
-	return c.container
-}
-
-// DefaultContainer returns a container with busybox
-func DefaultContainer() *corev1.Container {
-	con := &corev1.Container{
-		Name:  "default",
-		Image: "busybox:1.35.0",
-	}
-	return con
-}
-
 // DeploymentBuilder returns a deployment builder
 type DeploymentBuilder interface {
 	SetName(name string) DeploymentBuilder
@@ -275,8 +139,8 @@ type DeploymentBuilder interface {
 	SetLabelsAndSelectors(labels map[string]string, selectors *metav1.LabelSelector) DeploymentBuilder
 	SetAnnotations(annos map[string]string) DeploymentBuilder
 	SetShardingSphereProxyContainer(con *corev1.Container) DeploymentBuilder
-	SetMySQLConnector(scb ContainerBuilder, cn *v1alpha1.ComputeNode) DeploymentBuilder
-	SetAgentBin(scb ContainerBuilder, cn *v1alpha1.ComputeNode) DeploymentBuilder
+	SetMySQLConnector(scb common.ContainerBuilder, cn *v1alpha1.ComputeNode) DeploymentBuilder
+	SetAgentBin(scb common.ContainerBuilder, cn *v1alpha1.ComputeNode) DeploymentBuilder
 	SetInitContainer(con *corev1.Container) DeploymentBuilder
 	SetVolume(volume *corev1.Volume) DeploymentBuilder
 	SetReplicas(r *int32) DeploymentBuilder
@@ -584,7 +448,7 @@ func NewDeployment(cn *v1alpha1.ComputeNode) *appsv1.Deployment {
 	return builder.Build()
 }
 
-func setProbes(scb ContainerBuilder, cn *v1alpha1.ComputeNode) {
+func setProbes(scb common.ContainerBuilder, cn *v1alpha1.ComputeNode) {
 	if cn.Spec.Probes != nil && cn.Spec.Probes.LivenessProbe != nil {
 		scb.SetLivenessProbe(cn.Spec.Probes.LivenessProbe)
 	}
@@ -597,7 +461,7 @@ func setProbes(scb ContainerBuilder, cn *v1alpha1.ComputeNode) {
 }
 
 // SetMySQLConnector will set an init container to download mysql jar and mount files for proxy container.
-func (d *deploymentBuilder) SetMySQLConnector(scb ContainerBuilder, cn *v1alpha1.ComputeNode) DeploymentBuilder {
+func (d *deploymentBuilder) SetMySQLConnector(scb common.ContainerBuilder, cn *v1alpha1.ComputeNode) DeploymentBuilder {
 	scb.SetEnv([]corev1.EnvVar{
 		{
 			Name:  defaultMySQLDriverEnvName,
@@ -633,7 +497,7 @@ func (d *deploymentBuilder) SetMySQLConnector(scb ContainerBuilder, cn *v1alpha1
 }
 
 // SetAgentBin set `agent bin` for ShardingSphereProxy with [observability](https://shardingsphere.apache.org/document/current/en/user-manual/shardingsphere-proxy/observability/)
-func (d *deploymentBuilder) SetAgentBin(scb ContainerBuilder, cn *v1alpha1.ComputeNode) DeploymentBuilder {
+func (d *deploymentBuilder) SetAgentBin(scb common.ContainerBuilder, cn *v1alpha1.ComputeNode) DeploymentBuilder {
 	// set env JAVA_TOOL_OPTIONS to proxy container, make sure proxy will apply agent-bin.jar
 	// agent-bin's version is always equals to shardingsphere proxy image's version
 	scb.SetEnv([]corev1.EnvVar{
diff --git a/shardingsphere-operator/pkg/reconcile/computenode/deployment_test.go b/shardingsphere-operator/pkg/reconcile/computenode/deployment_test.go
index c49e1b1..7270c63 100644
--- a/shardingsphere-operator/pkg/reconcile/computenode/deployment_test.go
+++ b/shardingsphere-operator/pkg/reconcile/computenode/deployment_test.go
@@ -454,53 +454,6 @@ func assertPodSpec(t *testing.T, exp, act corev1.PodSpec) bool {
 		assert.ElementsMatch(t, exp.Volumes, act.Volumes, "volumes should be equal")
 }
 
-func TestContainerBuilder_SetVolumeMount(t *testing.T) {
-	var found bool
-
-	// create a new container builder
-	c := &containerBuilder{
-		container: &corev1.Container{
-			VolumeMounts: []corev1.VolumeMount{},
-		},
-	}
-
-	// add a new volume mount
-	mount := &corev1.VolumeMount{
-		Name:      "test-mount",
-		MountPath: "/test",
-	}
-	c.SetVolumeMount(mount)
-
-	// check if the volume mount has been added
-	for _, v := range c.container.VolumeMounts {
-		if v.Name == mount.Name {
-			found = true
-			break
-		}
-	}
-	if !found {
-		t.Errorf("SetVolumeMount() failed to add the VolumeMount")
-	}
-
-	// update an existing volume mount
-	updatedMount := &corev1.VolumeMount{
-		Name:      "test-mount",
-		MountPath: "/new-test",
-	}
-	c.SetVolumeMount(updatedMount)
-
-	// check if the volume mount has been updated
-	for _, v := range c.container.VolumeMounts {
-		if v.MountPath == updatedMount.MountPath {
-			found = true
-			break
-		}
-	}
-	if !found {
-		t.Errorf("SetVolumeMount() failed to update the VolumeMount")
-	}
-}
-
 func TestDeploymentBuilder_SetShardingSphereProxyContainer(t *testing.T) {
 	// 1. create a new deploymentBuilder object
 	builder := &deploymentBuilder{