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

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


The following commit(s) were added to refs/heads/main by this push:
     new adb5248  feat(agent): support metric agent to operator (#260)
adb5248 is described below

commit adb5248bd182bab35e3ad1d10de188e74f76b4a5
Author: Xu-Wentao <[email protected]>
AuthorDate: Mon Mar 13 12:23:19 2023 +0800

    feat(agent): support metric agent to operator (#260)
---
 .../shardingsphere.apache.org_computenodes.yaml    |  89 +++++----
 .../templates/operator_deployment.yaml             |   2 +-
 .../shardingsphere_v1alpha1_computenode.yaml       |  32 ++--
 .../values.yaml                                    |  63 ++++---
 .../api/v1alpha1/compute_node_types.go             |  16 +-
 .../api/v1alpha1/zz_generated.deepcopy.go          |  42 ++---
 .../pkg/reconcile/computenode/configmap.go         |  15 ++
 .../pkg/reconcile/computenode/deployment.go        | 155 ++++++++++++----
 .../pkg/reconcile/computenode/deployment_test.go   | 205 ++++++++++++++++++++-
 9 files changed, 470 insertions(+), 149 deletions(-)

diff --git 
a/charts/apache-shardingsphere-operator-charts/crds/shardingsphere.apache.org_computenodes.yaml
 
b/charts/apache-shardingsphere-operator-charts/crds/shardingsphere.apache.org_computenodes.yaml
index 1d49fbc..aee16b2 100644
--- 
a/charts/apache-shardingsphere-operator-charts/crds/shardingsphere.apache.org_computenodes.yaml
+++ 
b/charts/apache-shardingsphere-operator-charts/crds/shardingsphere.apache.org_computenodes.yaml
@@ -101,7 +101,7 @@ spec:
                                   port:
                                     format: int32
                                     type: integer
-                                  properties:
+                                  props:
                                     additionalProperties:
                                       type: string
                                     type: object
@@ -114,56 +114,53 @@ spec:
                           tracing:
                             description: PluginTracing defines the plugin for 
tracing
                             properties:
-                              tracing:
+                              jaeger:
                                 properties:
-                                  jaeger:
-                                    properties:
-                                      host:
-                                        type: string
-                                      port:
-                                        format: int32
-                                        type: integer
-                                      props:
-                                        additionalProperties:
-                                          type: string
-                                        type: object
-                                        x-kubernetes-preserve-unknown-fields: 
true
-                                    required:
-                                    - host
-                                    - port
+                                  host:
+                                    type: string
+                                  port:
+                                    format: int32
+                                    type: integer
+                                  props:
+                                    additionalProperties:
+                                      type: string
                                     type: object
-                                  openTelemetry:
-                                    properties:
-                                      props:
-                                        additionalProperties:
-                                          type: string
-                                        type: object
-                                        x-kubernetes-preserve-unknown-fields: 
true
+                                    x-kubernetes-preserve-unknown-fields: true
+                                required:
+                                  - host
+                                  - port
+                                type: object
+                              openTelemetry:
+                                properties:
+                                  props:
+                                    additionalProperties:
+                                      type: string
                                     type: object
-                                  skyWalking:
-                                    properties:
-                                      props:
-                                        additionalProperties:
-                                          type: string
-                                        type: object
-                                        x-kubernetes-preserve-unknown-fields: 
true
+                                    x-kubernetes-preserve-unknown-fields: true
+                                type: object
+                              skyWalking:
+                                properties:
+                                  props:
+                                    additionalProperties:
+                                      type: string
                                     type: object
-                                  zipkin:
-                                    properties:
-                                      host:
-                                        type: string
-                                      port:
-                                        format: int32
-                                        type: integer
-                                      props:
-                                        additionalProperties:
-                                          type: string
-                                        type: object
-                                        x-kubernetes-preserve-unknown-fields: 
true
-                                    required:
-                                    - host
-                                    - port
+                                    x-kubernetes-preserve-unknown-fields: true
+                                type: object
+                              zipkin:
+                                properties:
+                                  host:
+                                    type: string
+                                  port:
+                                    format: int32
+                                    type: integer
+                                  props:
+                                    additionalProperties:
+                                      type: string
                                     type: object
+                                    x-kubernetes-preserve-unknown-fields: true
+                                required:
+                                  - host
+                                  - port
                                 type: object
                             type: object
                         type: object
diff --git 
a/charts/apache-shardingsphere-operator-charts/templates/operator_deployment.yaml
 
b/charts/apache-shardingsphere-operator-charts/templates/operator_deployment.yaml
index 150d9d2..06d4755 100644
--- 
a/charts/apache-shardingsphere-operator-charts/templates/operator_deployment.yaml
+++ 
b/charts/apache-shardingsphere-operator-charts/templates/operator_deployment.yaml
@@ -38,7 +38,7 @@ spec:
             - --leader-elect
               {{- if eq .Values.operator.featureGates.computeNode true }}
             - --feature-gates=ComputeNode={{ 
.Values.operator.featureGates.computeNode }}
-              {{- end}}
+              {{- end }}
           command:
             - /operator
           ports:
diff --git 
a/charts/apache-shardingsphere-operator-charts/templates/shardingsphere_v1alpha1_computenode.yaml
 
b/charts/apache-shardingsphere-operator-charts/templates/shardingsphere_v1alpha1_computenode.yaml
index 25576a4..813b282 100644
--- 
a/charts/apache-shardingsphere-operator-charts/templates/shardingsphere_v1alpha1_computenode.yaml
+++ 
b/charts/apache-shardingsphere-operator-charts/templates/shardingsphere_v1alpha1_computenode.yaml
@@ -17,15 +17,15 @@
 
 {{- if .Values.operator.featureGates.computeNode }}
 apiVersion: shardingsphere.apache.org/v1alpha1
-kind: ComputeNode 
+kind: ComputeNode
 metadata:
   name: {{ template "common.names.fullname" . }}
   namespace: {{ .Release.Namespace }}
   labels:
-    "app": {{ template "common.names.fullname" .}} 
+    "app": {{ template "common.names.fullname" .}}
 spec:
   storageNodeConnector:
-    type: {{ .Values.computeNode.storageNodeConnector.type }} 
+    type: {{ .Values.computeNode.storageNodeConnector.type }}
     version: {{ .Values.computeNode.storageNodeConnector.version| quote}}
   serverVersion: {{ .Values.computeNode.serverVersion | default 
.Chart.AppVersion }}
   replicas: {{ .Values.computeNode.replicas }}
@@ -34,10 +34,10 @@ spec:
       "app": {{ template "common.names.fullname" . }}
   portBindings:
   {{- range $.Values.computeNode.portBindings }}
-  - name: {{ .name }}
-    containerPort: {{ .containerPort }} 
-    servicePort: {{ .servicePort }}
-    protocol: {{ .protocol }}
+    - name: {{ .name }}
+      containerPort: {{ .containerPort }}
+      servicePort: {{ .servicePort }}
+      protocol: {{ .protocol }}
   {{- end }}{{/* $.Values.computeNode.portBindings */}}
   serviceType: {{ .Values.computeNode.serviceType }}
   {{- if .Values.computeNode.bootstrap }}
@@ -46,11 +46,11 @@ spec:
     serverConfig:
       authority:
         privilege:
-          type: {{ 
.Values.computeNode.bootstrap.serverConfig.authority.privilege.type }} 
+          type: {{ 
.Values.computeNode.bootstrap.serverConfig.authority.privilege.type }}
         users:
         {{- range $.Values.computeNode.bootstrap.serverConfig.authority.users 
}}
-        - user: {{ .user }}
-          password: {{ .password }}
+          - user: {{ .user }}
+            password: {{ .password }}
         {{- end }}{{/* 
.Values.computeNode.bootstrap.serverConfig.authority.users */}}
       mode:
         type: {{ .Values.computeNode.bootstrap.serverConfig.mode.type }}
@@ -66,5 +66,15 @@ spec:
       props:
         proxy-frontend-database-protocol-type: {{ 
.Values.computeNode.bootstrap.serverConfig.props.proxyFrontendDatabaseProtocolType
 }}
     {{- end }}{{/* .Values.computeNode.bootstrap.serverConfig */}}
+    {{- if .Values.computeNode.bootstrap.agentConfig }}
+    agentConfig:
+      plugins:
+        metrics:
+          prometheus:
+            host: {{ 
.Values.computeNode.bootstrap.agentConfig.plugins.metrics.prometheus.host }}
+            port: {{ 
.Values.computeNode.bootstrap.agentConfig.plugins.metrics.prometheus.port }}
+            props:
+              jvm-information-collector-enabled: 
{{.Values.computeNode.bootstrap.agentConfig.plugins.metrics.prometheus.props.jvmInformationCollectorEnabled
 | quote }}
+    {{- end }}
   {{- end }}{{/* .Values.computeNode.bootstrap */}}
-{{- end }}{{/* .Values.computeNode.enabled */}}
\ No newline at end of file
+{{- end }}{{/* .Values.computeNode.enabled */}}
diff --git a/charts/apache-shardingsphere-operator-charts/values.yaml 
b/charts/apache-shardingsphere-operator-charts/values.yaml
index 38e6ba4..defbc0e 100644
--- a/charts/apache-shardingsphere-operator-charts/values.yaml
+++ b/charts/apache-shardingsphere-operator-charts/values.yaml
@@ -22,8 +22,8 @@ nameOverride: shardingsphere-proxy
 
 ## @section ShardingSphere operator parameters
 operator:
-## @param replicaCount operator replica count
-##
+  ## @param replicaCount operator replica count
+  ##
   replicaCount: 1
   image:
     ## @param image.repository operator image name
@@ -40,7 +40,7 @@ operator:
   ## imagePullSecrets:
   ##   - name: mysecret
   ##
-  imagePullSecrets: {}
+  imagePullSecrets: { }
   ## @param resources operator Resources required by the operator
   ## e.g:
   ## resources:
@@ -49,7 +49,7 @@ operator:
   ##   limits:
   ##     cpu: 2
   ##
-  resources: {}
+  resources: { }
   ## @param health.healthProbePort operator health check port
   ##
   health:
@@ -57,7 +57,7 @@ operator:
   ## @param featureGates.computeNode operator health check port
   ##
   featureGates:
-    computeNode: false 
+    computeNode: false
 
 
 ## @section ShardingSphere-Proxy cluster parameters
@@ -92,7 +92,7 @@ proxyCluster:
   ##     cpu: 2
   ##     memory: 2Gi
   ##
-  resources: {}
+  resources: { }
   ## @param service.type ShardingSphere-Proxy external exposure mode
   ## @param service.port ShardingSphere-Proxy exposes  port
   ##
@@ -111,7 +111,7 @@ proxyCluster:
   ## imagePullSecrets:
   ##   - name: mysecret
   ##
-  imagePullSecrets: []
+  imagePullSecrets: [ ]
   ## @section  ShardingSphere-Proxy ServerConfiguration parameters
   ## NOTE: If you use the sub-charts to deploy Zookeeper, the server-lists 
field must be "{{ printf \"%s-zookeeper.%s:2181\" .Release.Name 
.Release.Namespace }}",
   ## otherwise please fill in the correct zookeeper address
@@ -200,15 +200,15 @@ computeNode:
   ## @param computeNode.portBindings the port binding
   ##
   portBindings:
-  ## @param computeNode.portBindings[0].name the port binding
-  ## @param computeNode.portBindings[0].containerPort the container port
-  ## @param computeNode.portBindings[0].servicePort the service port
-  ## @param computeNode.portBindings[0].protocol the protocol
-  #
-  - name: server
-    containerPort: 3307
-    servicePort: 3307
-    protocol: TCP
+    ## @param computeNode.portBindings[0].name the port binding
+    ## @param computeNode.portBindings[0].containerPort the container port
+    ## @param computeNode.portBindings[0].servicePort the service port
+    ## @param computeNode.portBindings[0].protocol the protocol
+    #
+    - name: server
+      containerPort: 3307
+      servicePort: 3307
+      protocol: TCP
   ## @param computeNode.serviceType the service type 
   ##
   serviceType: ClusterIP
@@ -220,7 +220,7 @@ computeNode:
     serverConfig:
       ## @param computeNode.bootstrap.serverConfig.authority the authorization
       ##
-      authority: 
+      authority:
         ## @param computeNode.bootstrap.serverConfig.authority.privilege 
authorized privilege 
         ##
         privilege:
@@ -232,14 +232,14 @@ computeNode:
         ## @param computeNode.users[0].password the password 
         ##
         users:
-        - user: root%
-          password: root
+          - user: root%
+            password: root
       ## @param computeNode.bootstrap.serverConfig.mode the modes for 
ShardingSphere
       ##
-      mode: 
+      mode:
         ## @param computeNode.bootstrap.serverConfig.mode.type the running 
mode for ShardingSphere
         ##
-        type: Cluster 
+        type: Cluster
         ## @param computeNode.bootstrap.serverConfig.mode.repository the 
config for repository
         ##
         repository:
@@ -270,3 +270,24 @@ computeNode:
       ##
       props:
         proxyFrontendDatabaseProtocolType: MySQL
+
+    ## @param computeNode.bootstrap.agentConfig the agent.yaml
+    ##
+    agentConfig:
+      ## @param computeNode.bootstrap.agentConfig.plugins the plugins for agent
+      ##
+      plugins:
+        ## metric plugin
+        metrics:
+          ## prometheus settings
+          prometheus:
+            ## host for prometheus
+            ## e.g.
+            ## host: "localhost"
+            host: "localhost"
+            ## port for prometheus
+            ## e.g.
+            ## port: 9090
+            port: 9090
+            props:
+              jvmInformationCollectorEnabled: "true"
diff --git a/shardingsphere-operator/api/v1alpha1/compute_node_types.go 
b/shardingsphere-operator/api/v1alpha1/compute_node_types.go
index d193734..ec4879a 100644
--- a/shardingsphere-operator/api/v1alpha1/compute_node_types.go
+++ b/shardingsphere-operator/api/v1alpha1/compute_node_types.go
@@ -135,7 +135,7 @@ type PluginLogging struct {
 type Prometheus struct {
        Host  string     `json:"host"`
        Port  int32      `json:"port"`
-       Props Properties `json:"properties,omitempty"`
+       Props Properties `json:"props,omitempty"`
 }
 
 // PluginMetrics defines the plugin for metrics
@@ -163,7 +163,8 @@ type OpenTelemetryTracing struct {
        Props Properties `json:"props,omitempty"`
 }
 
-type Tracing struct {
+// PluginTracing defines the plugin for tracing
+type PluginTracing struct {
        // +optional
        Jaeger JaegerTracing `json:"jaeger,omitempty" yaml:"Jaeger"`
        // +optional
@@ -174,19 +175,14 @@ type Tracing struct {
        OpenTelemetry OpenTelemetryTracing `json:"openTelemetry,omitempty" 
yaml:"OpenTelemetry"`
 }
 
-// PluginTracing defines the plugin for tracing
-type PluginTracing struct {
-       Tracing Tracing `json:"tracing,omitempty"`
-}
-
 // AgentPlugin defines a set of plugins for ShardingSphere Agent
 type AgentPlugin struct {
        // +optional
-       Logging PluginLogging `json:"logging,omitempty"`
+       Logging *PluginLogging `json:"logging,omitempty"`
        // +optional
-       Metrics PluginMetrics `json:"metrics,omitempty"`
+       Metrics *PluginMetrics `json:"metrics,omitempty"`
        // +optional
-       Tracing PluginTracing `json:"tracing,omitempty"`
+       Tracing *PluginTracing `json:"tracing,omitempty"`
 }
 
 // AgentConfig defines the config for ShardingSphere-Agent, renderred as 
agent.yaml
diff --git a/shardingsphere-operator/api/v1alpha1/zz_generated.deepcopy.go 
b/shardingsphere-operator/api/v1alpha1/zz_generated.deepcopy.go
index 0a8a0e2..2bdb71c 100644
--- a/shardingsphere-operator/api/v1alpha1/zz_generated.deepcopy.go
+++ b/shardingsphere-operator/api/v1alpha1/zz_generated.deepcopy.go
@@ -47,9 +47,21 @@ func (in *AgentConfig) DeepCopy() *AgentConfig {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
 func (in *AgentPlugin) DeepCopyInto(out *AgentPlugin) {
        *out = *in
-       in.Logging.DeepCopyInto(&out.Logging)
-       in.Metrics.DeepCopyInto(&out.Metrics)
-       in.Tracing.DeepCopyInto(&out.Tracing)
+       if in.Logging != nil {
+               in, out := &in.Logging, &out.Logging
+               *out = new(PluginLogging)
+               (*in).DeepCopyInto(*out)
+       }
+       if in.Metrics != nil {
+               in, out := &in.Metrics, &out.Metrics
+               *out = new(PluginMetrics)
+               (*in).DeepCopyInto(*out)
+       }
+       if in.Tracing != nil {
+               in, out := &in.Tracing, &out.Tracing
+               *out = new(PluginTracing)
+               (*in).DeepCopyInto(*out)
+       }
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, 
creating a new AgentPlugin.
@@ -567,7 +579,10 @@ func (in *PluginMetrics) DeepCopy() *PluginMetrics {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
 func (in *PluginTracing) DeepCopyInto(out *PluginTracing) {
        *out = *in
-       in.Tracing.DeepCopyInto(&out.Tracing)
+       in.Jaeger.DeepCopyInto(&out.Jaeger)
+       in.Zipkin.DeepCopyInto(&out.Zipkin)
+       in.SkyWalking.DeepCopyInto(&out.SkyWalking)
+       in.OpenTelemetry.DeepCopyInto(&out.OpenTelemetry)
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, 
creating a new PluginTracing.
@@ -1058,25 +1073,6 @@ func (in *StorageNodeConnector) DeepCopy() 
*StorageNodeConnector {
        return out
 }
 
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
-func (in *Tracing) DeepCopyInto(out *Tracing) {
-       *out = *in
-       in.Jaeger.DeepCopyInto(&out.Jaeger)
-       in.Zipkin.DeepCopyInto(&out.Zipkin)
-       in.SkyWalking.DeepCopyInto(&out.SkyWalking)
-       in.OpenTelemetry.DeepCopyInto(&out.OpenTelemetry)
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, 
creating a new Tracing.
-func (in *Tracing) DeepCopy() *Tracing {
-       if in == nil {
-               return nil
-       }
-       out := new(Tracing)
-       in.DeepCopyInto(out)
-       return out
-}
-
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
 func (in *User) DeepCopyInto(out *User) {
        *out = *in
diff --git a/shardingsphere-operator/pkg/reconcile/computenode/configmap.go 
b/shardingsphere-operator/pkg/reconcile/computenode/configmap.go
index 8fe5984..26c6b19 100644
--- a/shardingsphere-operator/pkg/reconcile/computenode/configmap.go
+++ b/shardingsphere-operator/pkg/reconcile/computenode/configmap.go
@@ -31,6 +31,7 @@ import (
 const (
        ConfigDataKeyForLogback = "logback.xml"
        ConfigDataKeyForServer  = "server.yaml"
+       ConfigDataKeyForAgent   = "agent.yaml"
 
        AnnoClusterRepoConfig = 
"computenode.shardingsphere.org/server-config-mode-cluster"
        AnnoLogbackConfig     = "computenode.shardingsphere.org/logback"
@@ -64,6 +65,14 @@ func NewConfigMap(cn *v1alpha1.ComputeNode) *v1.ConfigMap {
                builder.SetServerConfig("# Empty file is needed")
        }
 
+       // load java agent config to configmap if needed
+       if !reflect.DeepEqual(cn.Spec.Bootstrap.AgentConfig, 
v1alpha1.AgentConfig{}) {
+               agentConf := cn.Spec.Bootstrap.AgentConfig.DeepCopy()
+               if y, err := yaml.Marshal(agentConf); err == nil {
+                       builder.SetAgentConfig(string(y))
+               }
+       }
+
        return builder.Build()
 }
 
@@ -74,6 +83,7 @@ type ConfigMapBuilder interface {
        SetAnnotations(annos map[string]string) ConfigMapBuilder
        SetLogback(logback string) ConfigMapBuilder
        SetServerConfig(serverConfig string) ConfigMapBuilder
+       SetAgentConfig(agentConfig string) ConfigMapBuilder
        Build() *v1.ConfigMap
 }
 
@@ -116,6 +126,11 @@ func (c *configmapBuilder) SetServerConfig(serviceConfig 
string) ConfigMapBuilde
        return c
 }
 
+func (c *configmapBuilder) SetAgentConfig(agentConfig string) ConfigMapBuilder 
{
+       c.configmap.Data[ConfigDataKeyForAgent] = agentConfig
+       return c
+}
+
 func (c *configmapBuilder) Build() *v1.ConfigMap {
        return c.configmap
 }
diff --git a/shardingsphere-operator/pkg/reconcile/computenode/deployment.go 
b/shardingsphere-operator/pkg/reconcile/computenode/deployment.go
index cdb05b5..fbcda34 100644
--- a/shardingsphere-operator/pkg/reconcile/computenode/deployment.go
+++ b/shardingsphere-operator/pkg/reconcile/computenode/deployment.go
@@ -39,11 +39,22 @@ const (
        defaultMySQLDriverEnvName    = "MYSQL_CONNECTOR_VERSION"
        defaultMySQLDriverVolumeName = "mysql-connector-java"
 
-       download_script = `wget 
https://repo1.maven.org/maven2/mysql/mysql-connector-java/${MYSQL_CONNECTOR_VERSION}/mysql-connector-java-${MYSQL_CONNECTOR_VERSION}.jar;
+       defaultAnnotationJavaAgentEnabled     = 
"shardingsphere.apache.org/java-agent-enabled"
+       defaultJavaAgentVolumeName            = "java-agent-bin"
+       defaultJavaAgentVolumeMountPath       = 
"/opt/shardingsphere-proxy/agent"
+       defaultJavaAgentConfigVolumeName      = "java-agent-config"
+       defaultJavaAgentConfigVolumeMountPath = 
"/opt/shardingsphere-proxy/agent/conf"
+       defaultJavaToolOptionsName            = "JAVA_TOOL_OPTIONS"
+       defaultJavaAgentEnvValue              = 
"-javaagent:/opt/shardingsphere-proxy/agent/shardingsphere-agent-%s.jar"
+       defaultAgentBinVersionEnvName         = "AGENT_BIN_VERSION"
+
+       downloadMysqlJarScript = `wget 
https://repo1.maven.org/maven2/mysql/mysql-connector-java/${MYSQL_CONNECTOR_VERSION}/mysql-connector-java-${MYSQL_CONNECTOR_VERSION}.jar;
 wget 
https://repo1.maven.org/maven2/mysql/mysql-connector-java/${MYSQL_CONNECTOR_VERSION}/mysql-connector-java-${MYSQL_CONNECTOR_VERSION}.jar.md5;
 if [ $(md5sum /mysql-connector-java-${MYSQL_CONNECTOR_VERSION}.jar | cut -d ' 
' -f1) = $(cat /mysql-connector-java-${MYSQL_CONNECTOR_VERSION}.jar.md5) ];
 then echo success;
 else echo failed;exit 1;fi;mv 
/mysql-connector-java-${MYSQL_CONNECTOR_VERSION}.jar 
/opt/shardingsphere-proxy/ext-lib`
+       downloadAgentJarScript = `wget 
https://archive.apache.org/dist/shardingsphere/${AGENT_BIN_VERSION}/apache-shardingsphere-${AGENT_BIN_VERSION}-shardingsphere-agent-bin.tar.gz;
+tar -zxvf 
apache-shardingsphere-${AGENT_BIN_VERSION}-shardingsphere-agent-bin.tar.gz -C 
/opt/shardingsphere-proxy/agent --strip-component 1;`
 )
 
 func relativeMySQLDriverMountName(v string) string {
@@ -87,12 +98,21 @@ type bootstrapContainerBuilder struct {
        ContainerBuilder
 }
 
-func NewBootstrapContainerBuilder() BootstrapContainerBuilder {
+func NewBootstrapContainerBuilderForMysqlJar() BootstrapContainerBuilder {
        return &bootstrapContainerBuilder{
                ContainerBuilder: NewContainerBuilder().
-                       SetName("boostrap").
+                       SetName("download-mysql-jar").
                        SetImage("busybox:1.35.0").
-                       SetCommand([]string{"/bin/sh", "-c", download_script}),
+                       SetCommand([]string{"/bin/sh", "-c", 
downloadMysqlJarScript}),
+       }
+}
+
+func NewBootstrapContainerBuilderForAgentBin() BootstrapContainerBuilder {
+       return &bootstrapContainerBuilder{
+               ContainerBuilder: NewContainerBuilder().
+                       SetName("download-agent-bin-jar").
+                       SetImage("busybox:1.35.0").
+                       SetCommand([]string{"/bin/sh", "-c", 
downloadAgentJarScript}),
        }
 }
 
@@ -235,6 +255,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
        SetInitContainer(con *corev1.Container) DeploymentBuilder
        SetVolume(volume *corev1.Volume) DeploymentBuilder
        SetReplicas(r *int32) DeploymentBuilder
@@ -325,9 +347,10 @@ type SharedVolumeAndMountBuilder interface {
        SetSubPath(idx int, subpath string) SharedVolumeAndMountBuilder
        SetVolumeMountSize(size int) SharedVolumeAndMountBuilder
        SetVolumeSourceEmptyDir() SharedVolumeAndMountBuilder
-       SetVolumeSourceConfigMap(name string) SharedVolumeAndMountBuilder
+       SetVolumeSourceConfigMap(name string, kps ...corev1.KeyToPath) 
SharedVolumeAndMountBuilder
        Build() (*corev1.Volume, []*corev1.VolumeMount)
 }
+
 type sharedVolumeAndMountBuilder struct {
        volume       *corev1.Volume
        volumeMounts []*corev1.VolumeMount
@@ -388,11 +411,15 @@ func (b *sharedVolumeAndMountBuilder) 
SetVolumeSourceEmptyDir() SharedVolumeAndM
        return b
 }
 
-func (b *sharedVolumeAndMountBuilder) SetVolumeSourceConfigMap(name string) 
SharedVolumeAndMountBuilder {
+func (b *sharedVolumeAndMountBuilder) SetVolumeSourceConfigMap(name string, 
kps ...corev1.KeyToPath) SharedVolumeAndMountBuilder {
        if b.volume.ConfigMap == nil {
                b.volume.ConfigMap = &corev1.ConfigMapVolumeSource{}
        }
        b.volume.ConfigMap.LocalObjectReference.Name = name
+
+       if len(kps) > 0 {
+               b.volume.ConfigMap.Items = kps
+       }
        return b
 }
 
@@ -509,36 +536,12 @@ func NewDeployment(cn *v1alpha1.ComputeNode) 
*v1.Deployment {
 
        if cn.Spec.StorageNodeConnector != nil {
                if cn.Spec.StorageNodeConnector.Type == 
v1alpha1.ConnectorTypeMySQL {
-                       scb.SetEnv([]corev1.EnvVar{
-                               {
-                                       Name:  defaultMySQLDriverEnvName,
-                                       Value: 
cn.Spec.StorageNodeConnector.Version,
-                               },
-                       })
-
-                       vb := NewSharedVolumeAndMountBuilder().
-                               SetVolumeMountSize(2).
-                               SetName(defaultMySQLDriverVolumeName).
-                               SetVolumeSourceEmptyDir().
-                               SetMountPath(0, defaultExtlibPath).
-                               SetMountPath(1, 
absoluteMySQLDriverMountName(defaultExtlibPath, 
cn.Spec.StorageNodeConnector.Version)).
-                               SetSubPath(1, 
relativeMySQLDriverMountName(cn.Spec.StorageNodeConnector.Version))
-
-                       v, vms := vb.Build()
-                       builder.SetVolume(v)
-                       scb.SetVolumeMount(vms[1])
-
-                       cb := 
NewBootstrapContainerBuilder().SetVolumeMount(vms[0]).SetEnv([]corev1.EnvVar{
-                               {
-                                       Name:  defaultMySQLDriverEnvName,
-                                       Value: 
cn.Spec.StorageNodeConnector.Version,
-                               },
-                       })
-                       con := cb.Build()
-                       builder.SetInitContainer(con)
+                       builder.SetMySQLConnector(scb, cn)
+               }
 
-                       sc := scb.Build()
-                       builder.SetShardingSphereProxyContainer(sc)
+               // set agent for proxy
+               if enabled, ok := 
cn.Annotations[defaultAnnotationJavaAgentEnabled]; ok && enabled == "true" {
+                       builder.SetAgentBin(scb, cn)
                }
 
                if cn.Spec.StorageNodeConnector.Type == 
v1alpha1.ConnectorTypePostgreSQL {
@@ -550,6 +553,88 @@ func NewDeployment(cn *v1alpha1.ComputeNode) 
*v1.Deployment {
        return builder.Build()
 }
 
+// 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 {
+       scb.SetEnv([]corev1.EnvVar{
+               {
+                       Name:  defaultMySQLDriverEnvName,
+                       Value: cn.Spec.StorageNodeConnector.Version,
+               },
+       })
+
+       vb := NewSharedVolumeAndMountBuilder().
+               SetVolumeMountSize(2).
+               SetName(defaultMySQLDriverVolumeName).
+               SetVolumeSourceEmptyDir().
+               SetMountPath(0, defaultExtlibPath).
+               SetMountPath(1, absoluteMySQLDriverMountName(defaultExtlibPath, 
cn.Spec.StorageNodeConnector.Version)).
+               SetSubPath(1, 
relativeMySQLDriverMountName(cn.Spec.StorageNodeConnector.Version))
+
+       v, vms := vb.Build()
+       d.SetVolume(v)
+       scb.SetVolumeMount(vms[1])
+
+       cb := 
NewBootstrapContainerBuilderForMysqlJar().SetVolumeMount(vms[0]).SetEnv([]corev1.EnvVar{
+               {
+                       Name:  defaultMySQLDriverEnvName,
+                       Value: cn.Spec.StorageNodeConnector.Version,
+               },
+       })
+       con := cb.Build()
+       d.SetInitContainer(con)
+
+       sc := scb.Build()
+       d.SetShardingSphereProxyContainer(sc)
+
+       return d
+}
+
+// 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 {
+       // 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{
+               {
+                       Name:  defaultJavaToolOptionsName,
+                       Value: fmt.Sprintf(defaultJavaAgentEnvValue, 
cn.Spec.ServerVersion),
+               },
+       })
+
+       // mount agent-bin dir
+       vbAgent := NewSharedVolumeAndMountBuilder().
+               SetVolumeMountSize(1).
+               SetName(defaultJavaAgentVolumeName).
+               SetVolumeSourceEmptyDir().
+               SetMountPath(0, defaultJavaAgentVolumeMountPath)
+       va, vma := vbAgent.Build()
+       d.SetVolume(va)
+       scb.SetVolumeMount(vma[0])
+
+       // mount agent config to overwrite agent-bin's config
+       vbAgentConf := NewSharedVolumeAndMountBuilder().
+               SetVolumeMountSize(1).
+               SetName(defaultJavaAgentConfigVolumeName).
+               SetVolumeSourceConfigMap(cn.Name, corev1.KeyToPath{Key: 
ConfigDataKeyForAgent, Path: ConfigDataKeyForAgent}).
+               SetMountPath(0, defaultJavaAgentConfigVolumeMountPath)
+       vc, vmc := vbAgentConf.Build()
+       d.SetVolume(vc)
+       scb.SetVolumeMount(vmc[0])
+
+       cb := 
NewBootstrapContainerBuilderForAgentBin().SetVolumeMount(vma[0]).SetEnv([]corev1.EnvVar{
+               {
+                       Name:  defaultAgentBinVersionEnvName,
+                       Value: cn.Spec.ServerVersion,
+               },
+       })
+       con := cb.Build()
+       d.SetInitContainer(con)
+
+       sc := scb.Build()
+       d.SetShardingSphereProxyContainer(sc)
+
+       return d
+}
+
 func DefaultDeployment(meta metav1.Object, gvk schema.GroupVersionKind) 
*v1.Deployment {
        defaultMaxUnavailable := intstr.FromInt(0)
        defaultMaxSurge := intstr.FromInt(3)
diff --git 
a/shardingsphere-operator/pkg/reconcile/computenode/deployment_test.go 
b/shardingsphere-operator/pkg/reconcile/computenode/deployment_test.go
index 2f71f6f..7cf2003 100644
--- a/shardingsphere-operator/pkg/reconcile/computenode/deployment_test.go
+++ b/shardingsphere-operator/pkg/reconcile/computenode/deployment_test.go
@@ -143,9 +143,9 @@ func Test_NewDeployment(t *testing.T) {
                                                Spec: corev1.PodSpec{
                                                        InitContainers: 
[]corev1.Container{
                                                                {
-                                                                       Name:   
 "boostrap",
+                                                                       Name:   
 "download-mysql-jar",
                                                                        Image:  
 "busybox:1.35.0",
-                                                                       
Command: []string{"/bin/sh", "-c", download_script},
+                                                                       
Command: []string{"/bin/sh", "-c", downloadMysqlJarScript},
                                                                        Env: 
[]corev1.EnvVar{
                                                                                
{
                                                                                
        Name:  defaultMySQLDriverEnvName,
@@ -215,6 +215,207 @@ func Test_NewDeployment(t *testing.T) {
                        },
                        message: "case 1",
                },
+               {
+                       id: 2,
+                       cn: &v1alpha1.ComputeNode{
+                               ObjectMeta: metav1.ObjectMeta{
+                                       Name:      "test-java-agent",
+                                       Namespace: "test-namespace",
+                                       Labels: map[string]string{
+                                               "k1": "v1",
+                                       },
+                                       Annotations: map[string]string{
+                                               
defaultAnnotationJavaAgentEnabled: "true",
+                                       },
+                               },
+                               Spec: v1alpha1.ComputeNodeSpec{
+                                       StorageNodeConnector: 
&v1alpha1.StorageNodeConnector{
+                                               Type:    
v1alpha1.ConnectorTypeMySQL,
+                                               Version: "5.1.47",
+                                       },
+                                       ServerVersion: "5.3.1",
+                                       Replicas:      2,
+                                       Selector: &metav1.LabelSelector{
+                                               MatchLabels: map[string]string{
+                                                       "k1": "v1",
+                                               },
+                                       },
+                                       PortBindings: []v1alpha1.PortBinding{
+                                               {
+                                                       Name:          "server",
+                                                       ContainerPort: 3307,
+                                                       ServicePort:   3307,
+                                                       Protocol:      
corev1.ProtocolTCP,
+                                               },
+                                       },
+                                       ServiceType: 
corev1.ServiceTypeClusterIP,
+                                       Bootstrap: v1alpha1.BootstrapConfig{
+                                               AgentConfig: 
v1alpha1.AgentConfig{
+                                                       Plugins: 
v1alpha1.AgentPlugin{
+                                                               Metrics: 
&v1alpha1.PluginMetrics{
+                                                                       
Prometheus: v1alpha1.Prometheus{
+                                                                               
Host:  "localhost",
+                                                                               
Port:  9090,
+                                                                               
Props: map[string]string{},
+                                                                       },
+                                                               },
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+                       exp: &v1.Deployment{
+                               ObjectMeta: metav1.ObjectMeta{
+                                       Name:      "test-java-agent",
+                                       Namespace: "test-namespace",
+                                       Labels: map[string]string{
+                                               "k1": "v1",
+                                       },
+                                       Annotations: map[string]string{
+                                               "anno1": "value1",
+                                       },
+                               },
+                               Spec: v1.DeploymentSpec{
+                                       Replicas: &defaultReplicas,
+                                       Strategy: v1.DeploymentStrategy{
+                                               Type: 
v1.RollingUpdateDeploymentStrategyType,
+                                               RollingUpdate: 
&v1.RollingUpdateDeployment{
+                                                       MaxUnavailable: 
&defaultMaxUnavailable,
+                                                       MaxSurge:       
&defaultMaxSurge,
+                                               },
+                                       },
+                                       Selector: &metav1.LabelSelector{
+                                               MatchLabels: map[string]string{
+                                                       "k1": "v1",
+                                               },
+                                       },
+                                       Template: corev1.PodTemplateSpec{
+                                               ObjectMeta: metav1.ObjectMeta{
+                                                       Labels: 
map[string]string{
+                                                               "k1": "v1",
+                                                       },
+                                               },
+                                               Spec: corev1.PodSpec{
+                                                       InitContainers: 
[]corev1.Container{
+                                                               {
+                                                                       Name:   
 "download-mysql-jar",
+                                                                       Image:  
 "busybox:1.35.0",
+                                                                       
Command: []string{"/bin/sh", "-c", downloadMysqlJarScript},
+                                                                       Env: 
[]corev1.EnvVar{
+                                                                               
{
+                                                                               
        Name:  defaultMySQLDriverEnvName,
+                                                                               
        Value: "5.1.47",
+                                                                               
},
+                                                                       },
+                                                                       
VolumeMounts: []corev1.VolumeMount{
+                                                                               
{
+                                                                               
        Name:      defaultMySQLDriverVolumeName,
+                                                                               
        MountPath: defaultExtlibPath,
+                                                                               
},
+                                                                       },
+                                                               },
+                                                               {
+                                                                       Name:   
 "download-agent-bin-jar",
+                                                                       Image:  
 "busybox:1.35.0",
+                                                                       
Command: []string{"/bin/sh", "-c", downloadAgentJarScript},
+                                                                       Env: 
[]corev1.EnvVar{
+                                                                               
{
+                                                                               
        Name:  defaultAgentBinVersionEnvName,
+                                                                               
        Value: "5.3.1",
+                                                                               
},
+                                                                       },
+                                                                       
VolumeMounts: []corev1.VolumeMount{
+                                                                               
{
+                                                                               
        Name:      defaultJavaAgentVolumeName,
+                                                                               
        MountPath: defaultJavaAgentVolumeMountPath,
+                                                                               
},
+                                                                       },
+                                                               },
+                                                       },
+                                                       Containers: 
[]corev1.Container{
+                                                               {
+                                                                       Name:  
defaultContainerName,
+                                                                       Image: 
fmt.Sprintf("%s:%s", defaultImageName, "5.3.1"),
+                                                                       Ports: 
[]corev1.ContainerPort{
+                                                                               
{
+                                                                               
        Name:          "server",
+                                                                               
        ContainerPort: 3307,
+                                                                               
        Protocol:      corev1.ProtocolTCP,
+                                                                               
},
+                                                                       },
+                                                                       Env: 
[]corev1.EnvVar{
+                                                                               
{
+                                                                               
        Name:  defaultJavaToolOptionsName,
+                                                                               
        Value: fmt.Sprintf(defaultJavaAgentEnvValue, "5.3.1"),
+                                                                               
},
+                                                                       },
+                                                                       
VolumeMounts: []corev1.VolumeMount{
+                                                                               
{
+                                                                               
        Name:      defaultConfigVolumeName,
+                                                                               
        MountPath: defaultConfigVolumeMountPath,
+                                                                               
},
+                                                                               
{
+                                                                               
        Name:      defaultMySQLDriverVolumeName,
+                                                                               
        SubPath:   relativeMySQLDriverMountName("5.1.47"),
+                                                                               
        MountPath: absoluteMySQLDriverMountName(defaultExtlibPath, "5.1.47"),
+                                                                               
},
+                                                                               
{
+                                                                               
        Name:      defaultJavaAgentVolumeName,
+                                                                               
        MountPath: defaultJavaAgentVolumeMountPath,
+                                                                               
},
+                                                                               
{
+                                                                               
        Name:      defaultJavaAgentConfigVolumeName,
+                                                                               
        MountPath: defaultJavaAgentConfigVolumeMountPath,
+                                                                               
},
+                                                                       },
+                                                               },
+                                                       },
+                                                       Volumes: 
[]corev1.Volume{
+                                                               {
+                                                                       Name: 
defaultConfigVolumeName,
+                                                                       
VolumeSource: corev1.VolumeSource{
+                                                                               
ConfigMap: &corev1.ConfigMapVolumeSource{
+                                                                               
        LocalObjectReference: corev1.LocalObjectReference{
+                                                                               
                Name: "test-java-agent",
+                                                                               
        },
+                                                                               
},
+                                                                       },
+                                                               },
+                                                               {
+                                                                       Name: 
defaultMySQLDriverVolumeName,
+                                                                       
VolumeSource: corev1.VolumeSource{
+                                                                               
EmptyDir: &corev1.EmptyDirVolumeSource{},
+                                                                       },
+                                                               },
+                                                               {
+                                                                       Name: 
defaultJavaAgentVolumeName,
+                                                                       
VolumeSource: corev1.VolumeSource{
+                                                                               
EmptyDir: &corev1.EmptyDirVolumeSource{},
+                                                                       },
+                                                               },
+                                                               {
+                                                                       Name: 
defaultJavaAgentConfigVolumeName,
+                                                                       
VolumeSource: corev1.VolumeSource{
+                                                                               
ConfigMap: &corev1.ConfigMapVolumeSource{
+                                                                               
        LocalObjectReference: corev1.LocalObjectReference{
+                                                                               
                Name: "test-java-agent",
+                                                                               
        },
+                                                                               
        Items: []corev1.KeyToPath{
+                                                                               
                {
+                                                                               
                        Key:  ConfigDataKeyForAgent,
+                                                                               
                        Path: ConfigDataKeyForAgent,
+                                                                               
                },
+                                                                               
        },
+                                                                               
},
+                                                                       },
+                                                               },
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+                       message: "case 2",
+               },
        }
 
        for _, c := range cases {


Reply via email to