Repository: lf-edge/ekuiper
Pull request #1318 (2022-07-10 04:44:29)

feat: change statefulset to deployment

Rory-Z: Please fix failed check

Patch:
diff --git a/.gitignore b/.gitignore
index 95ab3a0b..141f3277 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,3 +37,5 @@ corss_build_for_rpm.tar
 *.history
 
 */**/*.db
+
+.vscode/
diff --git a/deploy/chart/kuiper/.helmignore b/deploy/chart/ekuiper/.helmignore
similarity index 100%
rename from deploy/chart/kuiper/.helmignore
rename to deploy/chart/ekuiper/.helmignore
diff --git a/deploy/chart/kuiper/Chart.yaml b/deploy/chart/ekuiper/Chart.yaml
similarity index 94%
rename from deploy/chart/kuiper/Chart.yaml
rename to deploy/chart/ekuiper/Chart.yaml
index 1fe487eb..fe5c4e2f 100644
--- a/deploy/chart/kuiper/Chart.yaml
+++ b/deploy/chart/ekuiper/Chart.yaml
@@ -1,5 +1,5 @@
 apiVersion: v2
-name: kuiper
+name: ekuiper
 description: A lightweight IoT edge analytic software
 
 # A chart can be either an 'application' or a 'library' chart.
@@ -14,8 +14,8 @@ type: application
 
 # This is the chart version. This version number should be incremented each time you make changes
 # to the chart and its templates, including the app version.
-version: 1.2.0
+version: 1.3.1
 
 # This is the version number of the application being deployed. This version number should be
 # incremented each time you make changes to the application.
-appVersion: 1.2.0
+appVersion: 1.5.1
diff --git a/deploy/chart/ekuiper/README.md b/deploy/chart/ekuiper/README.md
new file mode 100644
index 00000000..02d3f429
--- /dev/null
+++ b/deploy/chart/ekuiper/README.md
@@ -0,0 +1,56 @@
+# eKuiper
+A lightweight IoT edge analytic software
+
+![Version: 1.3.0](https://img.shields.io/badge/Version-1.3.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.5.0](https://img.shields.io/badge/AppVersion-1.5.0-informational?style=flat-square)
+
+## Install the Chart
+
+- From Github
+```
+git clone https://github.com/lf-edge/ekuiper.git
+cd deploy/chart/ekuiper
+helm install my-ekuiper .
+```
+
+- From Helm repo
+```
+helm repo add emqx https://repos.emqx.io/charts
+helm install my-ekuiper emqx/ekuiper
+```
+
+
+## Uninstall Chart
+```
+helm uninstall my-ekuiper
+```
+
+## Values
+
+| Key | Type | Default | Description |
+|-----|------|---------|-------------|
+| affinity | object | `{}` |  |
+| clusterDomain | string | `"cluster.local"` | clusterDomain Kubernetes Cluster Domain |
+| ekuiperEnv | object | `{"enabled":true,"key":{"mqttDefaultServer":"MQTT_SOURCE__DEFAULT__SERVER"},"value":{"mqttDefaultServer":"tcp://broker.emqx.io:1883"}}` | remove this when the mqtt_source configmap is available |
+| image.pullPolicy | string | `"IfNotPresent"` |  |
+| image.repository | string | `"lfedge/ekuiper"` |  |
+| nodeSelector | object | `{}` |  |
+| persistence.accessMode | string | `"ReadWriteOnce"` |  |
+| persistence.enabled | bool | `false` |  |
+| persistence.existingClaim | string | `""` | Existing PersistentVolumeClaims The value is evaluated as a template So, for example, the name can depend on .Release or .Chart |
+| resources | object | `{}` |  |
+| service.annotations | object | `{}` | Provide any additional annotations which may be required. Evaluated as a template |
+| service.nodePorts | object | `{"ekuiper":null,"restapi":null}` | Specify the nodePort(s) value for the LoadBalancer and NodePort service types. ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport |
+| service.ports | object | `{"ekuiper":{"name":"ekuiper","port":20498},"restapi":{"name":"restapi","port":9081}}` | Service ports |
+| service.ports.ekuiper.name | string | `"ekuiper"` | eKuiper port name |
+| service.ports.ekuiper.port | int | `20498` | eKuiper port |
+| service.ports.restapi.name | string | `"restapi"` | eKuiper restapi port name |
+| service.ports.restapi.port | int | `9081` | eKuiper restapi port |
+| service.type | string | `"ClusterIP"` | service type |
+| serviceAccount.annotations | object | `{}` |  |
+| serviceAccount.create | bool | `true` |  |
+| serviceAccount.name | string | `""` |  |
+| tls | object | `{"autoGenerated":false,"caCertificate":"","enabled":false,"existingSecret":"","existingSecretFullChain":false,"serverCertificate":"","serverKey":""}` | Enable encryption to eKuiper |
+| tls.autoGenerated | bool | `false` | tls.autoGenerated Generate automatically self-signed TLS certificates |
+| tls.caCertificate | string | `""` | tls.caCertificate Certificate Authority (CA) bundle content |
+| tls.enabled | bool | `false` | tls.enabled Enable TLS support on eKuiper |
+| tolerations | list | `[]` |  |
diff --git a/deploy/chart/kuiper/templates/_helpers.tpl b/deploy/chart/ekuiper/templates/_helpers.tpl
similarity index 66%
rename from deploy/chart/kuiper/templates/_helpers.tpl
rename to deploy/chart/ekuiper/templates/_helpers.tpl
index a8da3a91..6263f84f 100644
--- a/deploy/chart/kuiper/templates/_helpers.tpl
+++ b/deploy/chart/ekuiper/templates/_helpers.tpl
@@ -2,7 +2,7 @@
 {{/*
 Expand the name of the chart.
 */}}
-{{- define "kuiper.name" -}}
+{{- define "ekuiper.name" -}}
 {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
 {{- end -}}
 
@@ -11,7 +11,7 @@ Create a default fully qualified app name.
 We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
 If release name contains chart name it will be used as a full name.
 */}}
-{{- define "kuiper.fullname" -}}
+{{- define "ekuiper.fullname" -}}
 {{- if .Values.fullnameOverride -}}
 {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
 {{- else -}}
@@ -27,16 +27,16 @@ If release name contains chart name it will be used as a full name.
 {{/*
 Create chart name and version as used by the chart label.
 */}}
-{{- define "kuiper.chart" -}}
+{{- define "ekuiper.chart" -}}
 {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
 {{- end -}}
 
 {{/*
 Common labels
 */}}
-{{- define "kuiper.labels" -}}
-helm.sh/chart: {{ include "kuiper.chart" . }}
-{{ include "kuiper.selectorLabels" . }}
+{{- define "ekuiper.labels" -}}
+helm.sh/chart: {{ include "ekuiper.chart" . }}
+{{ include "ekuiper.selectorLabels" . }}
 {{- if .Chart.AppVersion }}
 app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
 {{- end }}
@@ -46,18 +46,29 @@ app.kubernetes.io/managed-by: {{ .Release.Service }}
 {{/*
 Selector labels
 */}}
-{{- define "kuiper.selectorLabels" -}}
-app.kubernetes.io/name: {{ include "kuiper.name" . }}
+{{- define "ekuiper.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "ekuiper.name" . }}
 app.kubernetes.io/instance: {{ .Release.Name }}
 {{- end -}}
 
 {{/*
 Create the name of the service account to use
 */}}
-{{- define "kuiper.serviceAccountName" -}}
+{{- define "ekuiper.serviceAccountName" -}}
 {{- if .Values.serviceAccount.create -}}
-    {{ default (include "kuiper.fullname" .) .Values.serviceAccount.name }}
+    {{ default (include "ekuiper.fullname" .) .Values.serviceAccount.name }}
 {{- else -}}
     {{ default "default" .Values.serviceAccount.name }}
 {{- end -}}
 {{- end -}}
+
+{{/*
+Get the TLS secret.
+*/}}
+{{- define "neuron.tlsSecretName" -}}
+    {{- if .Values.tls.existingSecret -}}
+        {{- printf "%s" (tpl .Values.tls.existingSecret $) -}}
+    {{- else -}}
+        {{- printf "%s-certs" (include "neuron.fullname" .) -}}
+    {{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/deploy/chart/ekuiper/templates/configmap.yaml b/deploy/chart/ekuiper/templates/configmap.yaml
new file mode 100644
index 00000000..038be20b
--- /dev/null
+++ b/deploy/chart/ekuiper/templates/configmap.yaml
@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: {{ include "ekuiper.fullname" . }}
+  namespace: {{ .Release.Namespace }}
+  labels:
+    {{- include "ekuiper.labels" . | nindent 4 }}
+data:
+  "kuiper.yaml": |
+    {{ $kuiper := index .Values "kuiperConfig" "kuiper.yaml" }}
+    {{- toYaml $kuiper | nindent 6 }}
\ No newline at end of file
diff --git a/deploy/chart/ekuiper/templates/deployment.yaml b/deploy/chart/ekuiper/templates/deployment.yaml
new file mode 100644
index 00000000..8cba1bce
--- /dev/null
+++ b/deploy/chart/ekuiper/templates/deployment.yaml
@@ -0,0 +1,104 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "ekuiper.fullname" . }}
+  namespace: {{ .Release.Namespace }}
+  labels:
+    {{- include "ekuiper.labels" . | nindent 4 }}
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      {{- include "ekuiper.selectorLabels" . | nindent 6 }}
+  template:
+    metadata:
+      labels:
+        {{- include "ekuiper.selectorLabels" . | nindent 8 }}
+    spec:
+      serviceAccountName: {{ include "ekuiper.serviceAccountName" . }}
+      volumes:
+      - name: ekuiper-data
+        {{- if .Values.persistence.enabled }}
+        persistentVolumeClaim:
+          claimName: {{ (tpl .Values.persistence.existingClaim $) | default (include "ekuiper.fullname" .) }}
+        {{- else }}
+        emptyDir: {}
+        {{- end }}
+      - name: kuiper-config
+        configMap:
+          name: {{ include "ekuiper.fullname" . }}
+          items:
+          - key: kuiper.yaml
+            path: kuiper.yaml
+      {{- if .Values.tls.enabled }}
+      - name: certs
+        secret:
+          secretName: {{ template "neuron.tlsSecretName" . }}
+          items:
+            - key: {{ ternary "tls.crt" "ca.crt" .Values.tls.existingSecretFullChain }}
+              path: xyz-rootca.pem
+            - key: tls.crt
+              path: xyz-certificate.pem
+            - key: tls.key
+              path: xyz-private.pem.key
+        {{- end }}
+      containers:
+        - name: ekuiper
+          image: "{{ .Values.image.repository }}:{{ .Chart.AppVersion }}-alpine"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          {{- if .Values.ekuiperEnv.enabled }}
+          env:
+          - name: {{ .Values.ekuiperEnv.key.mqttDefaultServer }}
+            value: {{ .Values.ekuiperEnv.value.mqttDefaultServer }}
+          {{- end }}
+          command: ["./bin/kuiperd"]
+          readinessProbe:
+            httpGet:
+              {{- $restPort := index .Values "kuiperConfig" "kuiper.yaml" "basic" "restPort" }}
+              port: {{ $restPort | default 9081 }}
+            initialDelaySeconds: 5
+            periodSeconds: 5
+          ports:
+            {{- $restPort := index .Values "kuiperConfig" "kuiper.yaml" "basic" "restPort" }}
+            - name: restapi
+              containerPort: {{ $restPort | default 9081 }}
+            {{- $port := index .Values "kuiperConfig" "kuiper.yaml" "basic" "port" }}
+            - name: ekuiper
+              containerPort: {{ $port | default 20498 }}
+          volumeMounts:
+          - name: ekuiper-data
+            mountPath: "/kuiper/data"
+          {{- if .Values.tls.enabled }}
+          - name: certs
+            mountPath: "/var/kuiper/xyz-rootca.pem"
+            subPath: "xyz-rootca.pem"
+            readOnly: true
+          - name: certs
+            mountPath: "/var/kuiper/xyz-certificate.pem"
+            subPath: "xyz-certificate.pem"
+            readOnly: true
+          - name: certs
+            mountPath: "/var/kuiper/xyz-private.pem.key"
+            subPath: "xyz-private.pem.key"
+            readOnly: true
+          {{- end }}
+          - name: kuiper-config
+            mountPath: "/kuiper/etc/kuiper.yaml"
+            subPath: "kuiper.yaml"
+          resources:
+          {{- toYaml .Values.resources | nindent 12 }}
+    {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+
+
+
diff --git a/deploy/chart/ekuiper/templates/serviceaccount.yaml b/deploy/chart/ekuiper/templates/serviceaccount.yaml
new file mode 100644
index 00000000..8e30a563
--- /dev/null
+++ b/deploy/chart/ekuiper/templates/serviceaccount.yaml
@@ -0,0 +1,12 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ include "ekuiper.serviceAccountName" . }}
+  labels:
+    {{- include "ekuiper.labels" . | nindent 4 }}
+  {{- with .Values.serviceAccount.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+{{- end }}
diff --git a/deploy/chart/kuiper/templates/sevice.yaml b/deploy/chart/ekuiper/templates/svc.yaml
similarity index 59%
rename from deploy/chart/kuiper/templates/sevice.yaml
rename to deploy/chart/ekuiper/templates/svc.yaml
index 9c7f6138..02879465 100644
--- a/deploy/chart/kuiper/templates/sevice.yaml
+++ b/deploy/chart/ekuiper/templates/svc.yaml
@@ -1,10 +1,10 @@
 apiVersion: v1
 kind: Service
 metadata:
-  name: {{ include "kuiper.fullname" . }}
+  name: {{ include "ekuiper.fullname" . }}
   namespace: {{ .Release.Namespace }}
   labels:
-    {{- include "kuiper.labels" . | nindent 4 }}
+    {{- include "ekuiper.labels" . | nindent 4 }}
 spec:
   type: {{ .Values.service.type }}
   {{- if eq .Values.service.type "LoadBalancer" }}
@@ -16,8 +16,8 @@ spec:
   {{- end }}
   {{- end }}
   ports:
-  - name: restapi
-    port:  {{ .Values.service.restapi | default 9081 }}
+  - name: {{ .Values.service.ports.restapi.name }}
+    port:  {{ .Values.service.ports.restapi.port | default 9081 }}
     protocol: TCP
     targetPort:  restapi
     {{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePorts.restapi)) }}
@@ -25,29 +25,14 @@ spec:
     {{- else if eq .Values.service.type "ClusterIP" }}
     nodePort: null
     {{- end }}
-  - name: kuiper
-    port: {{ .Values.service.kuiper | default 20498 }}
+  - name: {{ .Values.service.ports.ekuiper.name }}
+    port: {{ .Values.service.ports.ekuiper.port | default 20498 }}
     protocol: TCP
-    targetPort: kuiper
-    {{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePorts.kuiper)) }}
-    nodePort: {{ .Values.service.nodePorts.kuiper }}
+    targetPort: ekuiper
+    {{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePorts.ekuiper)) }}
+    nodePort: {{ .Values.service.nodePorts.ekuiper }}
     {{- else if eq .Values.service.type "ClusterIP" }}
     nodePort: null
     {{- end }}
   selector:
-    {{- include "kuiper.selectorLabels" . | nindent 4 }}
-
----
-apiVersion: v1
-kind: Service
-metadata:
-  name: {{ include "kuiper.fullname" . }}-headless
-  namespace: {{ .Release.Namespace }}
-  labels:
-    {{- include "kuiper.labels" . | nindent 4 }}
-spec:
-  type: ClusterIP
-  sessionAffinity: None
-  clusterIP: None
-  selector:
-    {{- include "kuiper.selectorLabels" . | nindent 4 }}
\ No newline at end of file
+    {{- include "ekuiper.selectorLabels" . | nindent 4 }}
diff --git a/deploy/chart/ekuiper/templates/tls-secrets.yaml b/deploy/chart/ekuiper/templates/tls-secrets.yaml
new file mode 100644
index 00000000..c6e77187
--- /dev/null
+++ b/deploy/chart/ekuiper/templates/tls-secrets.yaml
@@ -0,0 +1,27 @@
+{{- if .Values.tls.enabled }}
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ include "neuron.fullname" . }}-certs
+  namespace: {{ .Release.Namespace }}
+  labels:
+    {{- include "neuron.labels" . | nindent 4 }}
+type: kubernetes.io/tls
+data:
+  {{- if or (not .Values.tls.autoGenerated ) (and .Values.tls.caCertificate .Values.tls.serverCertificate .Values.tls.serverKey) }}
+  ca.crt: {{ required "A valid .Values.tls.caCertificate entry required!" .Values.tls.caCertificate | b64enc | quote }}
+  tls.crt: {{ required "A valid .Values.tls.serverCertificate entry required!" .Values.tls.serverCertificate| b64enc | quote }}
+  tls.key: {{ required "A valid .Values.tls.serverKey entry required!" .Values.tls.serverKey | b64enc | quote }}
+  {{- else }}
+  {{- $ca := genCA "neuron-ca" 365 }}
+  {{- $fullname := include "neuron.fullname" . }}
+  {{- $releaseNamespace := .Release.Namespace }}
+  {{- $clusterDomain := .Values.clusterDomain }}
+  {{- $serviceName := include "neuron.fullname" . }}
+  {{- $altNames := list (printf "*.%s.%s.svc.%s" $serviceName $releaseNamespace $clusterDomain) (printf "%s.%s.svc.%s" $serviceName $releaseNamespace $clusterDomain) $fullname }}
+  {{- $crt := genSignedCert $fullname nil $altNames 365 $ca }}
+  ca.crt: {{ $ca.Cert | b64enc | quote }}
+  tls.crt: {{ $crt.Cert | b64enc | quote }}
+  tls.key: {{ $crt.Key | b64enc | quote }}
+  {{- end }}
+{{- end }}
diff --git a/deploy/chart/ekuiper/values.yaml b/deploy/chart/ekuiper/values.yaml
new file mode 100644
index 00000000..b5368151
--- /dev/null
+++ b/deploy/chart/ekuiper/values.yaml
@@ -0,0 +1,190 @@
+# Default values for kuiper.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+
+image:
+  repository: lfedge/ekuiper
+  pullPolicy: IfNotPresent
+
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # Annotations to add to the service account
+  annotations: {}
+  # The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template
+  name: ""
+
+service:
+  # -- service type
+  type: ClusterIP
+
+  # -- Service ports
+  ports:
+    ekuiper:
+      # -- eKuiper port name
+      name: "ekuiper"
+      # -- eKuiper port
+      port: 20498
+    restapi:
+      # -- eKuiper restapi port name
+      name: "restapi"
+      # -- eKuiper restapi port
+      port: 9081
+
+
+  # -- Specify the nodePort(s) value for the LoadBalancer and NodePort service types.
+  # ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
+  nodePorts:
+    ekuiper:
+    restapi:
+  ## Set the LoadBalancer service type to internal only.
+  ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer
+  ##
+  # loadBalancerIP:
+  ## Load Balancer sources
+  ## ref: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service
+  ## Example:
+  ## loadBalancerSourceRanges:
+  ## - 10.10.10.0/24
+  ##
+  # @ignored
+  loadBalancerSourceRanges: []
+  # -- Provide any additional annotations which may be required. Evaluated as a template
+  annotations: {}
+
+persistence:
+  enabled: false
+  accessMode: ReadWriteOnce
+  # -- Existing PersistentVolumeClaims
+  # The value is evaluated as a template
+  # So, for example, the name can depend on .Release or .Chart
+  existingClaim: ""
+
+resources: {}
+  # We usually recommend not to specify default resources and to leave this as a conscious
+  # choice for the user. This also increases chances charts run on environments with little
+  # resources, such as Minikube. If you do want to specify resources, uncomment the following
+  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+  # limits:
+  #   cpu: 100m
+  #   memory: 128Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+# -- clusterDomain Kubernetes Cluster Domain
+clusterDomain: cluster.local
+
+# -- Enable encryption to eKuiper
+tls:
+  # -- tls.enabled Enable TLS support on eKuiper
+  enabled: false
+  # -- tls.autoGenerated Generate automatically self-signed TLS certificates
+  autoGenerated: false
+  # -- tls.caCertificate Certificate Authority (CA) bundle content
+  caCertificate: |-
+  # - tls.serverCertificate Server certificate content
+  serverCertificate: |-
+  # - tls.serverKey Server private key content
+  serverKey: |-
+  # - tls.existingSecret Existing secret with certificate content to eKuiper credentials
+  existingSecret: ""
+  # - tls.existingSecretFullChain Whether or not the existing secret contains the full chain in the certificate (`tls.crt`). Will be used in place of `ca.cert` if `true`.
+  existingSecretFullChain: false
+
+# @ignored
+kuiperConfig:
+  "kuiper.yaml":
+    basic:
+      # true|false, with debug level, it prints more debug info
+      debug: false
+      # true|false, if it's set to true, then the log will be print to console
+      consoleLog: false
+      # true|false, if it's set to true, then the log will be print to log file
+      fileLog: true
+      # How many hours to split the file
+      rotateTime: 24
+      # Maximum file storage hours
+      maxAge: 72
+      # CLI ip
+      ip: 0.0.0.0
+      # CLI port
+      port: 20498
+      # REST service ip
+      restIp: 0.0.0.0
+      # REST service port
+      restPort: 9081
+      # true|false, when true, will check the RSA jwt token for rest api
+      authentication: false
+      #  restTls:
+      #    certfile: /var/https-server.crt
+      #    keyfile: /var/https-server.key
+      # Prometheus settings
+      prometheus: false
+      prometheusPort: 20499
+      # The URL where hosts all of pre-build plugins. By default it's at packages.emqx.net
+      pluginHosts: https://packages.emqx.net
+      # Whether to ignore case in SQL processing. Note that, the name of customized function by plugins are case-sensitive.
+      ignoreCase: true
+
+    # The default options for all rules. Each rule can override this setting by defining its own option
+    rule:
+      # The qos of the rule. The values can be 0: At most once; 1: At least once; 2: Exactly once
+      # If qos is bigger than 0, the checkpoint mechanism will launch to save states so that they can be
+      # restored for unintended interrupt or planned restart of the rule. The performance may be affected
+      # to enable the checkpoint mechanism
+      qos: 0
+      # The interval in millisecond to run the checkpoint mechanism.
+      checkpointInterval: 300000
+      # Whether to send errors to sinks
+      sendError: true
+
+    sink:
+      # The cache persistence threshold size. If the message in sink cache is larger than 10, then it triggers persistence. If you find
+      # the remote system is slow to response, or sink throughput is small, then it's recommend to increase below 2 configurations.
+      # More memory is required with the increase of below 2 configurations.
+      # If the message count reaches below value, then it triggers persistence.
+      cacheThreshold: 10
+      # The message persistence is triggered by a ticker, and cacheTriggerCount is for using configure the count to trigger the persistence procedure
+      # regardless if the message number reaches cacheThreshold or not. This is to prevent the data won't be saved as the cache never pass the threshold.
+      cacheTriggerCount: 15
+
+      # Control to disable cache or not. If it's set to true, then the cache will be disabled, otherwise, it will be enabled.
+      disableCache: true
+
+    store:
+      #Type of store that will be used for keeping state of the application
+      type: sqlite
+      redis:
+        host: localhost
+        port: 6379
+        password: kuiper
+        #Timeout in ms
+        timeout: 1000
+      sqlite:
+        #Sqlite file name, if left empty name of db will be sqliteKV.db
+        name:
+
+    # The settings for portable plugin
+    portable:
+      # The executable of python. Specify this if you have multiple python instances in your system
+      # or other circumstance where the python executable cannot be successfully invoked through the default command.
+      pythonBin: python
+
+# TODO
+# -- remove this when the mqtt_source configmap is available
+ekuiperEnv:
+  enabled: true
+  key:
+    mqttDefaultServer: MQTT_SOURCE__DEFAULT__SERVER
+  value:
+    mqttDefaultServer: "tcp://broker.emqx.io:1883"
diff --git a/deploy/chart/kuiper/README.md b/deploy/chart/kuiper/README.md
deleted file mode 100644
index 1cfdb332..00000000
--- a/deploy/chart/kuiper/README.md
+++ /dev/null
@@ -1,221 +0,0 @@
-eKuiper can be deployed at k3s/k8s cluster through Helm chart. Below takes k3s as an example for demonstrating how to deploy at k3s.
-
-## Prepare
-
-+ Install K3S
-  ```shell
-  $ curl -sfL https://get.k3s.io | sh -
-  $ sudo chmod 755 /etc/rancher/k3s/k3s.yaml
-  $ kubectl get nodes
-  NAME               STATUS   ROLES    AGE     VERSION
-  ip-172-31-16-120   Ready    master   4m31s   v1.16.3-k3s.2
-  ```
-
-+ Install helm3
-  ```shell
-  $ curl -sfL https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash -
-  Downloading https://get.helm.sh/helm-v3.0.1-linux-amd64.tar.gz
-  Preparing to install helm into /usr/local/bin
-  helm installed into /usr/local/bin/helm
-  
-  ## K8S can skip this step
-  $ export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
-  ```
-
-## Get eKuiper Helm Chart
-
-+ With any approaches in below to get eKuiper Helm Chart, here uses `git clone` to get Helm chart.
-
-  + Git clone
-
-    ```shell
-    $ git clone https://github.com/lf-edge/ekuiper
-    $ cd ekuiper/deploy/chart/Kuiper
-    ```
-
-  + Helm repo (TODO)
-
-    + Add Helm repo
-
-      ```shell
-      $ helm repo add emqx https://repos.emqx.io/charts
-      ```
-
-    + Search Kuiper
-
-      ```shell
-      helm search kuiper
-      NAME     		CHART VERSION	APP VERSION  	DESCRIPTION
-      lfedge/ekuiper	0.0.3	        0.0.3	        A lightweight IoT edge analytic software
-      ```
-
-+ By edit  `values.yaml` file or use command `helm install --set` to edit ``eKuiper Helm Chart`` configurations.
-
-  ##### eKuiper Helm Chart Configurations 
-
-  | Parameters                     | Descriptions                                         | Default Value            |
-  | ------------------------------ | ---------------------------------------------------- | ------------------------ |
-  | `replicaCount`                 | Deployed eKuiper instance number                      | 1                        |
-  | `image.repository`             | Docker image name                                    | lfedge/ekuiper              |
-  | `image.pullPolicy`             | Pull policy                                          | IfNotPresent             |
-  | `service.type`  | Kubernetes Service type. |ClusterIP|
-  | `service.kuiper`  | Port for eKuiper. |20498|
-  | `service.restapi`  | Port for ReseApi. |9081|
-  | `service.nodePorts.kuiper`  | Kubernetes node port for eKuiper. |nil|
-  | `service.nodePorts.restapi` | Kubernetes node port for RestAPi. |nil|
-  | `service.loadBalancerIP`  | loadBalancerIP for Service |	nil |
-  | `service.loadBalancerSourceRanges` |	Address(es) that are allowed when service is LoadBalancer |	[] |
-  | `service.annotations` |	Service annotations |	{}(evaluated as a template)|
-  | `persistence.enabled`          | Enable PVC                                           | false                    |
-  | `persistence.storageClass`     | Storage class name                                   | `nil`                    |
-  | `persistence.existingClaim`    | PV name                                              | ""                       |
-  | `persistence.accessMode`       | PVC access mode                                      | ReadWriteOnce            |
-  | `persistence.size`             | PVC size                                             | 20Mi                     |
-  | `resources`                    | CPU/Memory                                           | {}                       |
-  | `nodeSelector`                 | Node selector                                        | {}                       |
-  | `tolerations`                  | Tolerations                                          | []                       |
-  | `affinity`                     | Affinity                                             | {}                       |
-  | `kuiperConfig`                 | Configuration file in the eKuiper `etc` directory     |                          |
-
-## Deploy eKuiper through Helm
-
-#### Deploy eKuiper quickly
-
-+ Deploy eKuiper through Helm
-
-  ```shell
-  $ helm install my-kuiper .
-  NAME: my-kuiper
-  LAST DEPLOYED: Mon Dec  9 09:56:32 2019
-  NAMESPACE: default
-  STATUS: deployed
-  REVISION: 1
-  TEST SUITE: None
-  ```
-
-+ Deployment is successful
-
-  ```shell
-  $ kubectl get pods
-  NAME       READY   STATUS    RESTARTS   AGE
-  my-kuiper-0   1/1     Running   0          19s
-  
-  $ kubectl exec -it  my-kuiper-0 sh
-  /kuiper # ./bin/kuiper
-  Connecting to 127.0.0.1:20498...
-  ```
-
-#### Deploy persisted eKuiper
-
-+ eKuiper realized persisted  `pods` through creating PVC resources and mount `/ekuiper/data` directory. **Before deploying Kuiper, user need to create PVC or Storage Classes resource in Kubernetes.**
-
-+ Open and edit `values.yaml` file, set  `persistence.enabled=true`
-
-  + If user deploys PVC resource, , then set`persistence.existingClaim=your_pv_name`
-  + If user deploys Storage Classes resource, then set `persistence.storageClass=your_storageClass_name`
-
-+ Deploy eKuiper through Helm 
-
-  ```
-  $ helm install my-kuiper .
-  NAME: my-kuiper
-  LAST DEPLOYED: Mon Dec  9 09:56:32 2019
-  NAMESPACE: default
-  STATUS: deployed
-  REVISION: 1
-  TEST SUITE: None
-  ```
-
-+ Deployment is successful
-
-  ```shell
-  $ kubectl get pods
-  NAME       READY   STATUS    RESTARTS   AGE
-  my-kuiper-0   1/1     Running   0          19s
-  
-  $ kubectl exec -it  my-kuiper-0 sh
-  /kuiper # ./bin/kuiper
-  Connecting to 127.0.0.1:20498...
-  ```
-
-#### Deploy eKuiper and using SSL certification and key
-
-+ Use command `kubectl create secret` , create certification & private keys to ``Secret resources``, the usage of command `kubectl create secret`  is listed as in below：
-
-  ```shell
-  $ kubectl create secret generic your-secret-name --from-file=/path/to/file
-  ```
-
-  Create Secret resource for certification file: 
-
-  ```shell
-  $ kubectl create secret generic client-cert --from-file=certs/client-cert.pem
-  ```
-
-  Create Secret for private key file: 
-
-  ```shell
-  $ kubectl create secret generic client-key --from-file=certs/client-key.pem
-  ```
-
-  Review Secret resources
-
-  ```shell
-  $ kubectl get secret
-  NAME                                         TYPE                                  DATA   AGE
-  client-cert                                  Opaque                                1      25m
-  client-key                                   Opaque                                1      24m
-  ```
-
-+ Open and edit `values.yaml` file
-
-  ```shell
-  $ vim value.yaml
-  kuiperConfig:
-  ...
-    "mqtt_source.yaml":
-      #Global MQTT configurations
-      default:
-        qos: 1
-        sharedSubscription: true
-        server: tcp://127.0.0.1:1883
-        concurrency: 1
-        #username: user1
-        #password: password
-        certificationSecretName: client-cert  # Set certification Secret resource name
-        certificationPath: /var/kuiper/certificate.pem # Set certification file path
-        privateKeySecretName: client-key  # Set private key Secret resource name
-        privateKeyPath: /var/kuiper/xyz-private.pem.key # Set private key file path
-  ...
-  ```
-
-+ Deploy eKuiper through Helm 
-
-  ```shell
-  $ helm install my-kuiper .
-  NAME: my-kuiper
-  LAST DEPLOYED: Mon Dec  9 09:56:32 2019
-  NAMESPACE: default
-  STATUS: deployed
-  REVISION: 1
-  TEST SUITE: None
-  ```
-
-+ Deployment is successful
-
-  ```shell
-  $ kubectl get pods
-  NAME       READY   STATUS    RESTARTS   AGE
-  my-kuiper-0   1/1     Running   0          19s
-  
-  $ kubectl exec -it my-kuiper-0 -- ls -al /var/kuiper
-  total 8
-  drwxr-xr-x    4 root     root          4096 Dec 10 02:23 .
-  drwxr-xr-x    1 root     root          4096 Dec 10 02:23 ..
-  drwxrwxrwt    3 root     root           100 Dec 10 02:23 certificate.pem
-  drwxrwxrwt    3 root     root           100 Dec 10 02:23 private.pem.key
-  
-  $ kubectl exec -it  my-kuiper-0 sh
-  /kuiper # ./bin/kuiper
-  Connecting to 127.0.0.1:20498...
-  ```
\ No newline at end of file
diff --git a/deploy/chart/kuiper/README_zh.md b/deploy/chart/kuiper/README_zh.md
deleted file mode 100644
index 25ddb828..00000000
--- a/deploy/chart/kuiper/README_zh.md
+++ /dev/null
@@ -1,221 +0,0 @@
-eKuiper 可以通过 Helm chart 部署在 k3s / k8s 集群上。下面以 k3s 为例演示如何部署 eKuiper：
-
-## Prepare：
-
-+ 安装 K3S: 
-  ```shell
-  $ curl -sfL https://get.k3s.io | sh -
-  $ sudo chmod 644 /etc/rancher/k3s/k3s.yaml
-  $ kubectl get nodes
-  NAME               STATUS   ROLES    AGE     VERSION
-  ip-172-31-16-120   Ready    master   4m31s   v1.16.3-k3s.2
-  ```
-
-+ 安装 helm3
-  ```shell
-  $ curl -sfL https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash -
-  Downloading https://get.helm.sh/helm-v3.0.1-linux-amd64.tar.gz
-  Preparing to install helm into /usr/local/bin
-  helm installed into /usr/local/bin/helm
-  
-  ## K8S 可以跳过这一步
-  $ export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
-  ```
-
-## 获取 eKuiper Helm Chart
-
-+ 可以通过一下两种方法的任意一种获取 eKuiper Helm Chart，本文以使用 `git clone` 拉取代码的方式为例讲解。
-
-  + Git clone
-
-    ```shell
-    $ git clone https://github.com/lf-edge/ekuiper
-    $ cd ekuiper/deploy/chart/kuiper
-    ```
-
-  + Helm repo
-
-    + 添加Helm repo
-
-      ```shell
-      $ helm repo add emqx https://repos.emqx.io/charts
-      ```
-
-    + 查询 Kuiper
-
-      ```shell
-      $ helm search repo kuiper
-      NAME       	CHART VERSION	APP VERSION	DESCRIPTION
-      lfedge/ekuiper	0.0.4        	0.0.4      	A lightweight IoT edge analytic software
-      ```
-
-+ 可以通过编辑 `values.yaml` 文件或使用 `helm install --set` 命令编辑 eKuiper Helm Chart 的配置
-
-  ##### eKuiper Helm Chart 配置项
-
-  | 参数                           | 描述                                | Default Value            |
-  | ------------------------------ | ----------------------------------- | ------------------------ |
-  | `replicaCount`                 | 部署eKuiper数量                      | 1                        |
-  | `image.repository`             | 拉取镜像名称                        | lfedge/ekuiper              |
-  | `image.pullPolicy`             | 拉取镜像策略                        | IfNotPresent             |
-  | `service.type`  | Kubernetes Service type. |ClusterIP|
-  | `service.kuiper`  | eKuiper 端口 |20498|
-  | `service.restapi`  | eKuiper ReseApi 端口 . |9081|
-  | `service.nodePorts.kuiper`  | Kubernetes node port for eKuiper. |nil|
-  | `service.nodePorts.restapi` | Kubernetes node port for RestAPi. |nil|
-  | `service.loadBalancerIP`  | loadBalancerIP for Service |	nil |
-  | `service.loadBalancerSourceRanges` |	Address(es) that are allowed when service is LoadBalancer |	[] |
-  | `service.annotations` |	Service annotations |	{}(evaluated as a template)|
-  | `persistence.enabled`          | 是否启用 PVC                        | false                    |
-  | `persistence.storageClass`     | Storage class 名称                  | `nil`                    |
-  | `persistence.existingClaim`    | PV 名称                             | ""                       |
-  | `persistence.accessMode`       | PVC 访问模式                        | ReadWriteOnce            |
-  | `persistence.size`             | PVC 容量                            | 20Mi                     |
-  | `resources`                    | CPU/内存资源                        | {}                       |
-  | `nodeSelector`                 | 节点选择                            | {}                       |
-  | `tolerations`                  | 污点容忍                            | []                       |
-  | `affinity`                     | 节点亲和性                          | {}                       |
-  | `kuiperConfig`                 | eKuiper `etc` 目录下的配置文件           |                        |
-
-## 通过 Helm 部署 eKuiper
-
-#### 快速部署 eKuiper
-
-+ 使用 Helm 部署 eKuiper
-
-  ```shell
-  $ helm install my-kuiper .
-  NAME: my-kuiper
-  LAST DEPLOYED: Mon Dec  9 09:56:32 2019
-  NAMESPACE: default
-  STATUS: deployed
-  REVISION: 1
-  TEST SUITE: None
-  ```
-
-+ 部署成功
-
-  ```shell
-  $ kubectl get pods
-  NAME       READY   STATUS    RESTARTS   AGE
-  my-kuiper-0   1/1     Running   0          19s
-
-  $ kubectl exec -it  my-kuiper-0 sh
-  /kuiper # ./bin/kuiper
-  Connecting to 127.0.0.1:20498...
-  ```
-
-#### 部署持久化的 eKuiper
-
-+ eKuiper 通过 创建 PVC 资源挂载 `/ekuiper/data` 目录实现持久化 `pods`，**在部署 eKuiper 之前，用户需要自行在 Kubernetes 中创建 PVC 资源或 Storage Classes 资源**
-
-+ 编辑 `values.yaml` 文件，设置 `persistence.enabled=true`
-
-  + 如果用户部署了 PVC 资源，那么设置 `persistence.existingClaim=your_pv_name`
-  + 如果用户部署了 Storage Classes 资源，那么设置`persistence.storageClass=your_storageClass_name`
-
-+ 使用 Helm 部署 eKuiper
-
-  ```shell
-  $ helm install my-kuiper .
-  NAME: my-kuiper
-  LAST DEPLOYED: Mon Dec  9 09:56:32 2019
-  NAMESPACE: default
-  STATUS: deployed
-  REVISION: 1
-  TEST SUITE: None
-  ```
-
-+ 部署成功
-
-  ```shell
-  $ kubectl get pods
-  NAME       READY   STATUS    RESTARTS   AGE
-  my-kuiper-0   1/1     Running   0          19s
-  
-  $ kubectl exec -it  my-kuiper-0 sh
-  /kuiper # ./bin/kuiper
-  Connecting to 127.0.0.1:20498...
-  ```
-
-#### 部署 eKuiper 并使用证书
-
-+ 使用 `kubectl create secret` 将证书文件和私钥创建成 Secret 资源，`kubectl create secret` 命令的语法如下：
-
-  ```shell
-  $ kubectl create secret generic your-secret-name --from-file=/path/to/file
-  ```
-
-  创建证书文件 Secret 资源：
-
-  ```shell
-  $ kubectl create secret generic client-cert --from-file=certs/client-cert.pem
-  ```
-
-  创建私钥文件 Secret 资源：
-
-  ```shell
-  $ kubectl create secret generic client-key --from-file=certs/client-key.pem
-  ```
-
-  查看 Secret 资源：
-
-  ```shell
-  $ kubectl get secret
-  NAME                                         TYPE                                  DATA   AGE
-  client-cert                                  Opaque                                1      25m
-  client-key                                   Opaque                                1      24m
-  ```
-
-+ 编辑 `values.yaml` 文件
-
-  ```shell
-  $ vim value.yaml
-  kuiperConfig:
-  ...
-    "mqtt_source.yaml":
-      #Global MQTT configurations
-      default:
-        qos: 1
-        sharedSubscription: true
-        server: tcp://127.0.0.1:1883
-        concurrency: 1
-        #username: user1
-        #password: password
-        certificationSecretName: client-cert  # 设置证书文件 Secret resource name
-        certificationPath: /var/kuiper/certificate.pem # 设置证书文件部署路径
-        privateKeySecretName: client-key  # 设置私钥文件的 Secret resource name
-        privateKeyPath: /var/kuiper/xyz-private.pem.key # 设置私钥文件部署路径
-  ...
-  ```
-
-+ 使用 Helm 部署 eKuiper
-
-  ```shell
-  $ helm install my-kuiper .
-  NAME: my-kuiper
-  LAST DEPLOYED: Mon Dec  9 09:56:32 2019
-  NAMESPACE: default
-  STATUS: deployed
-  REVISION: 1
-  TEST SUITE: None
-  ```
-
-+ 部署成功
-
-  ```shell
-  $ kubectl get pods
-  NAME       READY   STATUS    RESTARTS   AGE
-  my-kuiper-0   1/1     Running   0          19s
-
-  $ kubectl exec -it my-kuiper-0 -- ls -al /var/kuiper
-  total 8
-  drwxr-xr-x    4 root     root          4096 Dec 10 02:23 .
-  drwxr-xr-x    1 root     root          4096 Dec 10 02:23 ..
-  drwxrwxrwt    3 root     root           100 Dec 10 02:23 certificate.pem
-  drwxrwxrwt    3 root     root           100 Dec 10 02:23 private.pem.key
-
-  $ kubectl exec -it  my-kuiper-0 sh
-  /kuiper # ./bin/kuiper
-  Connecting to 127.0.0.1:20498...
-  ```
\ No newline at end of file
diff --git a/deploy/chart/kuiper/templates/StatefulSet.yaml b/deploy/chart/kuiper/templates/StatefulSet.yaml
deleted file mode 100644
index 39a4c7dd..00000000
--- a/deploy/chart/kuiper/templates/StatefulSet.yaml
+++ /dev/null
@@ -1,142 +0,0 @@
-apiVersion: apps/v1
-kind: StatefulSet
-metadata:
-  name: {{ include "kuiper.fullname" . }}
-  namespace: {{ .Release.Namespace }}
-  labels:
-    {{- include "kuiper.labels" . | nindent 4 }}
-spec:
-  replicas: {{ .Values.replicaCount }}
-  serviceName: {{ include "kuiper.fullname" . }}-headless
-  {{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }}
-  volumeClaimTemplates:
-    - metadata:
-        name: kuiper-data
-        namespace: {{ .Release.Namespace }}
-        labels:
-          {{- include "kuiper.labels" . | nindent 4 }}
-        annotations:
-        {{- if .Values.persistence.storageClass }}
-          volume.beta.kubernetes.io/storage-class: {{ .Values.persistence.storageClass | quote }}
-        {{- else }}
-          volume.alpha.kubernetes.io/storage-class: default
-        {{- end }}
-      spec:
-        accessModes:
-          - {{ .Values.persistence.accessMode | quote }}
-        resources:
-         requests:
-           storage: {{ .Values.persistence.size | quote }}
-  {{- end }}
-  selector:
-    matchLabels:
-      {{- include "kuiper.selectorLabels" . | nindent 6 }}
-  template:
-    metadata:
-      labels:
-        {{- include "kuiper.selectorLabels" . | nindent 8 }}
-    spec:
-      volumes:
-      {{- if not .Values.persistence.enabled }}
-      - name: kuiper-data
-        emptyDir: {}
-      {{- else if .Values.persistence.existingClaim }}
-      - name: kuiper-data
-        persistentVolumeClaim:
-        {{- with .Values.persistence.existingClaim }}
-          claimName: {{ tpl . $ }}
-        {{- end }}
-      {{- end }}
-      - name: kuiper-config
-        configMap:
-          name: {{ include "kuiper.fullname" . }}
-          items:
-          - key: mqtt_source.yaml
-            path: mqtt_source.yaml
-          - key: kuiper.yaml
-            path: kuiper.yaml
-          - key: client.yaml
-            path: client.yaml
-          - key: edgex.yaml
-            path: edgex.yaml
-          - key: random.yaml
-            path: random.yaml
-          - key: zmq.yaml
-            path: zmq.yaml
-      {{ $certificationSecretName := index .Values "kuiperConfig" "mqtt_source.yaml" "default" "certificationSecretName" }}
-      {{- if $certificationSecretName }}
-      - name: kuiper-certification
-        secret:
-          secretName: {{ $certificationSecretName }}
-      {{- end }}
-      {{ $privateKeySecretName := index .Values "kuiperConfig" "mqtt_source.yaml" "default" "privateKeySecretName" }}
-      {{- if $privateKeySecretName }}
-      - name: kuiper-private-key
-        secret:
-          secretName: {{ $privateKeySecretName }}
-      {{- end }}
-      containers:
-        - name: kuiper
-          image: "{{ .Values.image.repository }}:{{ .Chart.AppVersion }}-alpine"
-          imagePullPolicy: {{ .Values.image.pullPolicy }}
-          command: ["./bin/kuiperd"]
-          ports:
-          {{ $restPort := index .Values "kuiperConfig" "kuiper.yaml" "basic" "restPort" }}
-          - name: restapi
-            containerPort: {{ $restPort | default 9081 }}
-          {{ $port := index .Values "kuiperConfig" "kuiper.yaml" "basic" "port" }}
-          - name: kuiper
-            containerPort: {{ $port | default 20498 }}
-          volumeMounts:
-          - name: kuiper-data
-            mountPath: "/kuiper/data"
-          - name: kuiper-config
-            mountPath: "/kuiper/etc/mqtt_source.yaml"
-            subPath: "mqtt_source.yaml"
-          - name: kuiper-config
-            mountPath: "/kuiper/etc/kuiper.yaml"
-            subPath: "kuiper.yaml"
-          - name: kuiper-config
-            mountPath: "/kuiper/etc/client.yaml"
-            subPath: "client.yaml"
-          - name: kuiper-config
-            mountPath: "/kuiper/etc/sources/edgex.yaml"
-            subPath: "edgex.yaml"
-          - name: kuiper-config
-            mountPath: "/kuiper/etc/sources/random.yaml"
-            subPath: "random.yaml"
-          - name: kuiper-config
-            mountPath: "/kuiper/etc/sources/zmq.yaml"
-            subPath: "zmq.yaml"
-          readinessProbe:
-            httpGet:
-              {{ $restPort := index .Values "kuiperConfig" "kuiper.yaml" "basic" "restPort" }}
-              port: {{ $restPort | default 9081 }}
-            initialDelaySeconds: 5
-            periodSeconds: 5
-          {{ $certificationSecretName := index .Values "kuiperConfig" "mqtt_source.yaml" "default" "certificationSecretName" }}
-          {{- if $certificationSecretName }}
-          - name: kuiper-certification
-            mountPath: {{ index .Values "kuiperConfig" "mqtt_source.yaml" "default" "certificationPath" | default "/var/kuiper/certificate.pem" }}
-            readOnly: true
-          {{ end }}
-          {{ $privateKeySecretName := index .Values "kuiperConfig" "mqtt_source.yaml" "default" "privateKeySecretName" }}
-          {{- if $privateKeySecretName }}
-          - name: kuiper-private-key
-            mountPath: {{ index .Values "kuiperConfig" "mqtt_source.yaml" "default" "privateKeyPath" | default "/var/kuiper/private.pem.key" }}
-            readOnly: true
-          {{ end }}
-          resources:
-          {{- toYaml .Values.resources | nindent 12 }}
-    {{- with .Values.nodeSelector }}
-      nodeSelector:
-        {{- toYaml . | nindent 8 }}
-      {{- end }}
-    {{- with .Values.affinity }}
-      affinity:
-        {{- toYaml . | nindent 8 }}
-    {{- end }}
-    {{- with .Values.tolerations }}
-      tolerations:
-        {{- toYaml . | nindent 8 }}
-    {{- end }}
diff --git a/deploy/chart/kuiper/templates/configmap.yaml b/deploy/chart/kuiper/templates/configmap.yaml
deleted file mode 100644
index 3bb4c141..00000000
--- a/deploy/chart/kuiper/templates/configmap.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ include "kuiper.fullname" . }}
-  namespace: {{ .Release.Namespace }}
-  labels:
-    {{- include "kuiper.labels" . | nindent 4 }}
-data:
-  "client.yaml": |
-    {{ $client := index .Values "kuiperConfig" "client.yaml" }}
-    {{- toYaml $client | nindent 6 }}
-  "kuiper.yaml": |
-    {{ $kuiper := index .Values "kuiperConfig" "kuiper.yaml" }}
-    {{- toYaml $kuiper | nindent 6 }}
-  "mqtt_source.yaml": |
-    {{ $mqtt := index .Values "kuiperConfig" "mqtt_source.yaml" }}
-    {{- toYaml $mqtt | nindent 6 }}
-  "edgex.yaml": |
-    {{ $edgex := index .Values "kuiperConfig" "sources/edgex.yaml" }}
-    {{- toYaml $edgex | nindent 6 }}
-  "random.yaml": |
-    {{ $random := index .Values "kuiperConfig" "sources/random.yaml" }}
-    {{- toYaml $random | nindent 6 }}
-  "zmq.yaml": |
-    {{ $zmq := index .Values "kuiperConfig" "sources/zmq.yaml" }}
-    {{- toYaml $zmq | nindent 6 }}
\ No newline at end of file
diff --git a/deploy/chart/kuiper/values.yaml b/deploy/chart/kuiper/values.yaml
deleted file mode 100644
index 6f390c07..00000000
--- a/deploy/chart/kuiper/values.yaml
+++ /dev/null
@@ -1,337 +0,0 @@
-# Default values for kuiper.
-# This is a YAML-formatted file.
-# Declare variables to be passed into your templates.
-
-replicaCount: 1
-
-image:
-  repository: lfedge/ekuiper
-  pullPolicy: IfNotPresent
-
-service:
-  ## Service type
-  ##
-  type: ClusterIP
-  ## Port for Kuiper
-  ##
-  kuiper: 20498
-  ## Port for RestApi
-  ##
-  restapi: 9081
-  ## Specify the nodePort(s) value for the LoadBalancer and NodePort service types.
-  ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
-  ##
-  nodePorts:
-    kuiper:
-    restapi:
-  ## Set the LoadBalancer service type to internal only.
-  ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer
-  ##
-  # loadBalancerIP:
-  ## Load Balancer sources
-  ## ref: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service
-  ## Example:
-  ## loadBalancerSourceRanges:
-  ## - 10.10.10.0/24
-  ##
-  loadBalancerSourceRanges: []
-  ## Provide any additional annotations which may be required. Evaluated as a template
-  ##
-  annotations: {}
-
-persistence:
-  enabled: false
-  size: 20Mi
-  ## If defined, volume.beta.kubernetes.io/storage-class: <storageClass>
-  ## Default: volume.alpha.kubernetes.io/storage-class: default
-  # storageClass: "-"
-  accessMode: ReadWriteOnce
-  ## Existing PersistentVolumeClaims
-  ## The value is evaluated as a template
-  ## So, for example, the name can depend on .Release or .Chart
-  # existingClaim: ""
-
-resources: {}
-  # We usually recommend not to specify default resources and to leave this as a conscious
-  # choice for the user. This also increases chances charts run on environments with little
-  # resources, such as Minikube. If you do want to specify resources, uncomment the following
-  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
-  # limits:
-  #   cpu: 100m
-  #   memory: 128Mi
-  # requests:
-  #   cpu: 100m
-  #   memory: 128Mi
-
-nodeSelector: {}
-
-tolerations: []
-
-affinity: {}
-
-kuiperConfig:
-  "client.yaml":
-    basic:
-      host: 127.0.0.1
-      port: 20498
-  "kuiper.yaml":
-    basic:
-      # true|false, with debug level, it prints more debug info
-      debug: false
-      # true|false, if it's set to true, then the log will be print to console
-      consoleLog: false
-      # true|false, if it's set to true, then the log will be print to log file
-      fileLog: true
-      # How many hours to split the file
-      rotateTime: 24
-      # Maximum file storage hours
-      maxAge: 72
-      # CLI ip
-      ip: 0.0.0.0
-      # CLI port
-      port: 20498
-      # REST service ip
-      restIp: 0.0.0.0
-      # REST service port
-      restPort: 9081
-      # true|false, when true, will check the RSA jwt token for rest api
-      authentication: false
-      #  restTls:
-      #    certfile: /var/https-server.crt
-      #    keyfile: /var/https-server.key
-      # Prometheus settings
-      prometheus: false
-      prometheusPort: 20499
-      # The URL where hosts all of pre-build plugins. By default it's at packages.emqx.net
-      pluginHosts: https://packages.emqx.net
-      # Whether to ignore case in SQL processing. Note that, the name of customized function by plugins are case-sensitive.
-      ignoreCase: true
-
-    # The default options for all rules. Each rule can override this setting by defining its own option
-    rule:
-      # The qos of the rule. The values can be 0: At most once; 1: At least once; 2: Exactly once
-      # If qos is bigger than 0, the checkpoint mechanism will launch to save states so that they can be
-      # restored for unintended interrupt or planned restart of the rule. The performance may be affected
-      # to enable the checkpoint mechanism
-      qos: 0
-      # The interval in millisecond to run the checkpoint mechanism.
-      checkpointInterval: 300000
-      # Whether to send errors to sinks
-      sendError: true
-
-    sink:
-      # The cache persistence threshold size. If the message in sink cache is larger than 10, then it triggers persistence. If you find
-      # the remote system is slow to response, or sink throughput is small, then it's recommend to increase below 2 configurations.
-      # More memory is required with the increase of below 2 configurations.
-      # If the message count reaches below value, then it triggers persistence.
-      cacheThreshold: 10
-      # The message persistence is triggered by a ticker, and cacheTriggerCount is for using configure the count to trigger the persistence procedure
-      # regardless if the message number reaches cacheThreshold or not. This is to prevent the data won't be saved as the cache never pass the threshold.
-      cacheTriggerCount: 15
-
-      # Control to disable cache or not. If it's set to true, then the cache will be disabled, otherwise, it will be enabled.
-      disableCache: true
-
-    store:
-      #Type of store that will be used for keeping state of the application
-      type: sqlite
-      redis:
-        host: localhost
-        port: 6379
-        password: kuiper
-        #Timeout in ms
-        timeout: 1000
-      sqlite:
-        #Sqlite file name, if left empty name of db will be sqliteKV.db
-        name:
-
-    # The settings for portable plugin
-    portable:
-      # The executable of python. Specify this if you have multiple python instances in your system
-      # or other circumstance where the python executable cannot be successfully invoked through the default command.
-      pythonBin: python
-  "connections/connection.yaml":
-    mqtt:
-      localConnection: #connection key
-        server: "tcp://127.0.0.1:1883"
-        username: ekuiper
-        password: password
-        #certificationPath: /var/kuiper/xyz-certificate.pem
-        #privateKeyPath: /var/kuiper/xyz-private.pem.key
-        #rootCaPath: /var/kuiper/xyz-rootca.pem
-        #insecureSkipVerify: false
-        #protocolVersion: 3
-        clientid: ekuiper
-      cloudConnection: #connection key
-        server: "tcp://broker.emqx.io:1883"
-        username: user1
-        password: password
-        #certificationPath: /var/kuiper/xyz-certificate.pem
-        #privateKeyPath: /var/kuiper/xyz-private.pem.ke
-        #rootCaPath: /var/kuiper/xyz-rootca.pem
-        #insecureSkipVerify: false
-        #protocolVersion: 3
-    edgex:
-      redisMsgBus: #connection key
-        protocol: redis
-        server: 127.0.0.1
-        port: 6379
-        type: redis
-        #  Below is optional configurations settings for mqtt
-        #  type: mqtt
-        #  optional:
-        #    ClientId: client1
-        #    Username: user1
-        #    Password: password
-        #    Qos: 1
-        #    KeepAlive: 5000
-        #    Retained: true/false
-        #    ConnectionPayload:
-        #    CertFile:
-        #    KeyFile:
-        #    CertPEMBlock:
-        #    KeyPEMBlock:
-        #    SkipCertVerify: true/false
-      mqttMsgBus: #connection key
-        protocol: tcp
-        server: 127.0.0.1
-        port: 1883
-        topic: events
-        type: mqtt
-        optional:
-          ClientId: "client1"
-  "mqtt_source.yaml":
-    #Global MQTT configurations
-    default:
-      qos: 1
-      server: "tcp://127.0.0.1:1883"
-      #username: user1
-      #password: password
-      #certificationPath: /var/kuiper/xyz-certificate.pem
-      #privateKeyPath: /var/kuiper/xyz-private.pem.key
-      #rootCaPath: /var/kuiper/xyz-rootca.pem
-      #insecureSkipVerify: false
-      #connectionSelector: mqtt.mqtt_conf1
-      #kubeedgeVersion:
-      #kubeedgeModelFile: ""
-
-    demo_conf: #Conf_key
-      qos: 0
-      server: "tcp://10.211.55.6:1883"
-  "sources/edgex.yaml":
-    #Global Edgex configurations
-    default:
-      protocol: redis
-      server: localhost
-      port: 5563
-      topic: events
-      type: redis
-      # Could be 'event' or 'request'.
-      # If the message is from app service, the message type is an event;
-      # Otherwise, if it is from the message bus directly, it should be a request
-      messageType: event
-    #  Below is optional configurations settings for mqtt
-    #  type: mqtt
-    #  optional:
-    #    ClientId: client1
-    #    Username: user1
-    #    Password: password
-    #    Qos: 1
-    #    KeepAlive: 5000
-    #    Retained: true/false
-    #    ConnectionPayload:
-    #    CertFile:
-    #    KeyFile:
-    #    CertPEMBlock:
-    #    KeyPEMBlock:
-    #    SkipCertVerify: true/false
-
-    #Override the global configurations
-    zmq_conf: #Conf_key
-      protocol: tcp
-      server: localhost
-      port: 5563
-      topic: events
-      type: zero
-      messageType: event
-
-    application_conf: #Conf_key
-      protocol: tcp
-      server: localhost
-      port: 5571
-      topic: application
-      type: zero
-      messageType: request
-
-    mqtt_conf: #Conf_key
-      protocol: tcp
-      server: 127.0.0.1
-      port: 1883
-      topic: events
-      type: mqtt
-      optional:
-        ClientId: "client1"
-
-    share_conf: #Conf_key
-      protocol: tcp
-      server: 127.0.0.1
-      port: 1883
-      topic: events
-      type: mqtt
-      connectionSelector: edgex.redisMsgBus
-  "sources/file.yaml":
-    default:
-      fileType: json
-      # The directory of the file relative to kuiper root or an absolute path.
-      # Do not include the file name here. The file name should be defined in the stream data source
-      path: data
-      # The interval between reading the files, time unit is ms. If only read once, set it to 0
-      interval: 0
-
-    test:
-      path: test
-  "sources/httppull.yaml":
-    #Global httppull configurations
-    default:
-      # url of the request server address
-      url: http://localhost
-      # post, get, put, delete
-      method: post
-      # The interval between the requests, time unit is ms
-      interval: 10000
-      # The timeout for http request, time unit is ms
-      timeout: 5000
-      # If it's set to true, then will compare with last result; If response of two requests are the same, then will skip sending out the result.
-      # The possible setting could be: true/false
-      incremental: false
-      # The body of request, such as '{"data": "data", "method": 1}'
-      body: '{}'
-      # Body type, none|text|json|html|xml|javascript|form
-      bodyType: json
-      # Control if to skip the certification verification. If it is set to true, then skip certification verification; Otherwise, verify the certification
-      insecureSkipVerify: true
-      # HTTP headers required for the request
-      headers:
-        Accept: application/json
-
-    #Override the global configurations
-    application_conf: #Conf_key
-      incremental: true
-      url: http://localhost:9090/
-  "sources/memory.yaml":
-  "sources/random.yaml":
-    default:
-      interval: 1000
-      seed: 1
-      pattern:
-        count: 50
-      deduplicate: 0
-    ext:
-      interval: 100
-    dedup:
-      interval: 100
-      deduplicate: 50
-  "sources/zmq.yaml":
-    #Global Zmq configurations
-    default:
-      server: tcp://127.0.0.1:5563


Test patch:
diff --git a/.github/workflows/run_fvt_tests.yaml b/.github/workflows/run_fvt_tests.yaml
index 1c309357..5a8e3aba 100644
--- a/.github/workflows/run_fvt_tests.yaml
+++ b/.github/workflows/run_fvt_tests.yaml
@@ -286,61 +286,25 @@ jobs:
       run: |
         version=$(git describe --tags --always)
         emqx_address=$(kubectl get svc --namespace default emqx -o jsonpath="{.spec.clusterIP}")
-        
+
         sudo docker save lfedge/ekuiper:$version-alpine -o kuier.tar.gz
         sudo k3s ctr image import kuier.tar.gz
 
-        sed -i -r "s/^appVersion: .*$/appVersion: \"${version}\"/g" deploy/chart/kuiper/Chart.yaml
-        sed -i -r 's/  pullPolicy: .*$/  pullPolicy: Never/g' deploy/chart/kuiper/values.yaml
-        sed -i -r "s/      server: .*$/      server: tcp:\/\/${emqx_address}:1883/g" deploy/chart/kuiper/values.yaml
-        
-        helm install kuiper deploy/chart/kuiper --debug --dry-run
-        helm install kuiper deploy/chart/kuiper
-        while [ "$(kubectl get StatefulSet -l app.kubernetes.io/name=kuiper -o jsonpath='{.items[0].status.replicas}')" \
-          != "$(kubectl get StatefulSet -l app.kubernetes.io/name=kuiper -o jsonpath='{.items[0].status.readyReplicas}')" ]; do
-          echo "=============================="
-          kubectl describe pods kuiper-0
-          echo "=============================="
-          kubectl get pods
-          echo "=============================="
-          echo "waiting kuiper started"
-          sleep 10
+        sed -i -r "s/^appVersion: .*$/appVersion: \"${version}\"/g" deploy/chart/ekuiper/Chart.yaml
+        sed -i -r 's/  pullPolicy: .*$/  pullPolicy: Never/g' deploy/chart/ekuiper/values.yaml
+
+        helm install ekuiper deploy/chart/ekuiper --debug --dry-run
+        helm install ekuiper deploy/chart/ekuiper
+        while [ "$(kubectl get pods -l app.kubernetes.io/name=ekuiper -o json | jq '.items[0].status.containerStatuses[] | select(.ready==true) | .containerID')" = "" ]; do
+            echo "=============================="
+            kubectl get pods
+            echo "=============================="
+            echo "waiting ekuiper started"
+            sleep 10
         done
-        kuiper_address=$(kubectl get svc --namespace default kuiper -o jsonpath="{.spec.clusterIP}")
-        if [ $(curl -w %{http_code} -fsSL -o /dev/null $kuiper_address:9081) != 200 ];then
-          kubectl logs kuiper-0
+        ekuiper_address=$(kubectl get svc --namespace default ekuiper -o jsonpath="{.spec.clusterIP}")
+        if [ $(curl -w %{http_code} -fsSL -o /dev/null $ekuiper_address:9081) != 200 ];then
+          ekuiper_pod=$(kubectl get pod -l app.kubernetes.io/instance=ekuiper -o jsonpath="{.items[0].metadata.name}")
+          kubectl logs $ekuiper_pod
           exit 1;
         fi
-    - name: check kuiper
-      env:
-        KUBECONFIG: "/etc/rancher/k3s/k3s.yaml"
-      timeout-minutes: 5
-      run: |
-        emqx_address=$(kubectl get svc --namespace default emqx -o jsonpath="{.spec.clusterIP}")
-        kuiper_address=$(kubectl get svc --namespace default kuiper -o jsonpath="{.spec.clusterIP}")
-        /opt/jmeter/bin/jmeter.sh -Jjmeter.save.saveservice.output_format=xml -n -t test/select_aggr_rule.jmx -Dsrv=${kuiper_address} -Dmqtt_srv=${emqx_address} -l jmeter_logs/select_aggr_rule.jtl -j jmeter_logs/select_aggr_rule.log
-        mkdir -p kuiper_logs
-        kubectl exec kuiper-0 -- cat /kuiper/log/stream.log > kuiper_logs/stream.log
-    - uses: actions/upload-artifact@v1
-      if: always()
-      with:
-        name: kuiper_logs_with_helm
-        path: ./kuiper_logs
-    - uses: actions/upload-artifact@v1
-      if: always()
-      with:
-        name: jmeter_logs_with_helm
-        path: ./jmeter_logs
-    - name: check logs
-      run: |
-        sudo apt update && sudo apt install -y libxml2-utils
-        cd jmeter_logs
-        for file in `ls *.jtl`
-        do
-          if [ ! -z "$(cat $file| grep '<failure>' | awk -F '>' '{print $2}' | awk -F '<' '{print $1}' | grep true)" ] ||
-           [ "$(xmllint --format --xpath '/testResults/sample/@rc' $file | sed -r 's/ /\n/g;' | sort -u | grep -E 'rc=\"[45][0-9][0-9]\"|rc=\"\"')" != "" ]; then
-            echo -e "---------------------------------------------\n"
-            echo "FVT tests error for $file"
-            exit 1
-          fi
-        done