This is an automated email from the ASF dual-hosted git repository. klesh pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/incubator-devlake-helm-chart.git
The following commit(s) were added to refs/heads/main by this push: new 9d32ec3 helm: make MySQL `DB_URL` extensible/overridable, wire Grafana datasource envs, and add smoke-test CI (#350) 9d32ec3 is described below commit 9d32ec344d6fc25be60edd400acc586147350c13 Author: kahirokunn <okinakah...@gmail.com> AuthorDate: Wed Sep 3 12:17:16 2025 +0900 helm: make MySQL `DB_URL` extensible/overridable, wire Grafana datasource envs, and add smoke-test CI (#350) * Add custom MySQL DSN query params feature - Introduce `DB_CUSTOM_PARAMS` in `configmap.yaml`. - Enhance `DB_URL` in `deployments.yaml` to include custom params. - Define `mysql.extraParams` in `values.yaml` for configuration. Signed-off-by: kahirokunn <okinakah...@gmail.com> * Enable optional DB URL auto-assembly for MySQL Signed-off-by: kahirokunn <okinakah...@gmail.com> * fix: Pass MySQL env vars to Grafana for datasource setup - Introduced `connectionConfigmapName` to optionally override the default ConfigMap name for better configurability. Signed-off-by: kahirokunn <okinakah...@gmail.com> * Add Helm smoke test workflow Signed-off-by: kahirokunn <okinakah...@gmail.com> * Link Secret and ConfigMap names in values.yaml Signed-off-by: kahirokunn <okinakah...@gmail.com> * Add customizable probes for MySQL containers Signed-off-by: kahirokunn <okinakah...@gmail.com> * fix(mysql): Resolve environment-dependent startup failures by switching MySQL probes to TCP Signed-off-by: kahirokunn <okinakah...@gmail.com> --------- Signed-off-by: kahirokunn <okinakah...@gmail.com> --- .github/workflows/smoke-test.yml | 72 ++++++++++++++++++++++++++++++ charts/devlake/templates/_helpers.tpl | 4 ++ charts/devlake/templates/configmap.yaml | 1 + charts/devlake/templates/deployments.yaml | 4 +- charts/devlake/templates/statefulsets.yaml | 24 +++++----- charts/devlake/values.yaml | 48 ++++++++++++++++++-- 6 files changed, 134 insertions(+), 19 deletions(-) diff --git a/.github/workflows/smoke-test.yml b/.github/workflows/smoke-test.yml new file mode 100644 index 0000000..84e81cd --- /dev/null +++ b/.github/workflows/smoke-test.yml @@ -0,0 +1,72 @@ +name: DevLake Helm Smoke Test + +on: + push: + branches: [ "**" ] + pull_request: + branches: [ "**" ] + +jobs: + smoke-test: + name: Smoke Test + runs-on: ubuntu-latest + timeout-minutes: 50 + env: + RELEASE_NAME: devlake + NAMESPACE: devlake + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Set up Helm + uses: azure/setup-helm@v4 + + - name: Create kind cluster + uses: helm/kind-action@v1.12.0 + with: + cluster_name: devlake-e2e + + - name: Set up kubectl + uses: azure/setup-kubectl@v4 + + - name: Add Helm repos + run: | + helm repo add grafana https://grafana.github.io/helm-charts + helm repo update + + - name: Build chart dependencies + run: | + helm dependency build charts/devlake + + - name: Install DevLake chart + run: | + kubectl get events -n "$NAMESPACE" -w & + kubectl get pods -n "$NAMESPACE" -w & + ENCRYPTION_SECRET=$(openssl rand -base64 2000 | tr -dc 'A-Z' | fold -w 128 | head -n 1) + helm install "$RELEASE_NAME" ./charts/devlake \ + --namespace "$NAMESPACE" \ + --create-namespace \ + --wait \ + --set lake.encryptionSecret.secret="${ENCRYPTION_SECRET}" + + - name: Dump diagnostics on failure + if: failure() + run: | + echo "=== Helm status for release ===" + helm status "$RELEASE_NAME" -n "$NAMESPACE" || true + echo "=== Kubernetes resources (all) ===" + kubectl get all -n "$NAMESPACE" -o wide || true + echo "=== Kubernetes events (latest 200) ===" + kubectl get events -n "$NAMESPACE" --sort-by=.lastTimestamp | tail -n 200 || true + echo "=== Describe deployments/statefulsets ===" + kubectl describe deploy -n "$NAMESPACE" || true + kubectl describe statefulset -n "$NAMESPACE" || true + echo "=== Describe pods ===" + kubectl describe pods -n "$NAMESPACE" || true + echo "=== Logs from all pods (current and previous, last 200 lines) ===" + for pod in $(kubectl get pods -n "$NAMESPACE" -o jsonpath='{.items[*].metadata.name}'); do + echo "----- logs for ${pod} -----" + kubectl logs -n "$NAMESPACE" "$pod" --all-containers --tail=200 || true + echo "----- previous logs for ${pod} -----" + kubectl logs -n "$NAMESPACE" "$pod" --all-containers --previous --tail=200 || true + done diff --git a/charts/devlake/templates/_helpers.tpl b/charts/devlake/templates/_helpers.tpl index 5fbc671..731af59 100644 --- a/charts/devlake/templates/_helpers.tpl +++ b/charts/devlake/templates/_helpers.tpl @@ -105,8 +105,12 @@ The ui endpoint {{- end -}} {{- define "devlake.mysql.configmap" -}} +{{- if .Values.option.connectionConfigmapName -}} +{{- .Values.option.connectionConfigmapName -}} +{{- else -}} {{ include "devlake.fullname" . }}-config {{- end -}} +{{- end -}} {{- define "devlake.ui.auth.secret" -}} {{- if .Values.ui.basicAuth.secretName -}} diff --git a/charts/devlake/templates/configmap.yaml b/charts/devlake/templates/configmap.yaml index 502f44c..207e6d4 100644 --- a/charts/devlake/templates/configmap.yaml +++ b/charts/devlake/templates/configmap.yaml @@ -32,4 +32,5 @@ data: DB_CHARSET: "utf8mb4" DB_PARSE_TIME: "True" DB_LOCATION: "{{ .Values.commonEnvs.TZ }}" + DB_CUSTOM_PARAMS: "{{ .Values.mysql.extraParams }}" {{- end }} diff --git a/charts/devlake/templates/deployments.yaml b/charts/devlake/templates/deployments.yaml index d23bc0e..db012d3 100644 --- a/charts/devlake/templates/deployments.yaml +++ b/charts/devlake/templates/deployments.yaml @@ -197,9 +197,9 @@ spec: env: - name: PORT value: "{{ .Values.lake.port }}" - {{- if (eq .Values.option.database "mysql") }} + {{- if and (eq .Values.option.database "mysql") (.Values.option.assembleDbUrl) }} - name: DB_URL - value: "mysql://$(MYSQL_USER):$(MYSQL_PASSWORD)@$(MYSQL_SERVER):$(MYSQL_PORT)/$(MYSQL_DATABASE)?charset=$(DB_CHARSET)&parseTime=$(DB_PARSE_TIME)&loc=$(DB_LOCATION)" + value: "mysql://$(MYSQL_USER):$(MYSQL_PASSWORD)@$(MYSQL_SERVER):$(MYSQL_PORT)/$(MYSQL_DATABASE)?charset=$(DB_CHARSET)&parseTime=$(DB_PARSE_TIME)&loc=$(DB_LOCATION){{ .Values.mysql.extraParams }}" {{- end }} {{- range $key1, $value1 := .Values.lake.envs }} - name: "{{ tpl $key1 $ }}" diff --git a/charts/devlake/templates/statefulsets.yaml b/charts/devlake/templates/statefulsets.yaml index 477f6db..1b49d08 100644 --- a/charts/devlake/templates/statefulsets.yaml +++ b/charts/devlake/templates/statefulsets.yaml @@ -69,22 +69,18 @@ spec: - name: mysql containerPort: 3306 protocol: TCP + {{- with .Values.mysql.startupProbe }} + startupProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.mysql.livenessProbe }} livenessProbe: - exec: - command: - - "sh" - - "-c" - - "mysqladmin ping -u root -p$MYSQL_ROOT_PASSWORD" - initialDelaySeconds: 60 - timeoutSeconds: 30 + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.mysql.readinessProbe }} readinessProbe: - exec: - command: - - "sh" - - "-c" - - "mysqladmin ping -u root -p$MYSQL_ROOT_PASSWORD" - initialDelaySeconds: 5 - timeoutSeconds: 10 + {{- toYaml . | nindent 12 }} + {{- end }} {{- with .Values.mysql.resources }} resources: {{- toYaml . | nindent 12 }} diff --git a/charts/devlake/values.yaml b/charts/devlake/values.yaml index cc0b819..6431159 100644 --- a/charts/devlake/values.yaml +++ b/charts/devlake/values.yaml @@ -47,6 +47,11 @@ mysql: # the database for devlake database: lake + # extra MySQL DSN query params appended to DB_URL. + # Note: include a leading '&' yourself. Empty string means no change. + # example: "&tls=skip-verify" or "&tls=skip-verify&autocommit=true" + extraParams: "" + # root password for mysql, only used when use_external=false rootPassword: admin @@ -90,6 +95,32 @@ mysql: podAnnotations: {} + # Probes for MySQL container + startupProbe: + exec: &mysql_ping_exec + command: + - "sh" + - "-c" + - "mysqladmin ping --protocol=TCP -h 127.0.0.1 -u root -p$MYSQL_ROOT_PASSWORD" + initialDelaySeconds: 120 + periodSeconds: 10 + timeoutSeconds: 10 + failureThreshold: 60 + + livenessProbe: + exec: *mysql_ping_exec + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 30 + failureThreshold: 5 + + readinessProbe: + exec: *mysql_ping_exec + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 10 + failureThreshold: 3 + service: type: "ClusterIP" nodePort: "" @@ -164,9 +195,13 @@ grafana: server: serve_from_subpath: "true" root_url: "%(protocol)s://%(domain)s/grafana" - #the secret name should be as same as .Values.option.connectionSecretName + # the Secret name should be the same as .Values.option.connectionSecretName envFromSecrets: - - name: "devlake-mysql-auth" + - name: &devlake_mysql_auth "devlake-mysql-auth" + # the ConfigMap name should be the same as .Values.option.connectionConfigmapName + extraEnvFrom: + - configMapRef: + name: &devlake_mysql_auth_config "devlake-mysql-auth-config" #keep grafana timezone same as other pods, which is set by .Values.commonEnvs.TZ env: TZ: "UTC" @@ -430,8 +465,15 @@ option: # database type, supported: [mysql] database: mysql # the existing k8s secret name of db connection auth. The secret name should be as same as .Values.grafana.envFromSecret - connectionSecretName: "devlake-mysql-auth" + connectionSecretName: *devlake_mysql_auth + # Optional: override the ConfigMap name for non-sensitive DB envs used across components + # Default is a fixed name to align references from subcharts + connectionConfigmapName: *devlake_mysql_auth_config autoCreateSecret: true + # If true, the chart assembles DB_URL automatically for MySQL. Set to false + # to disable auto-assembly and provide DB_URL yourself via `lake.envs` or + # an external secret referenced by `lake.extraEnvsFromSecret`. + assembleDbUrl: true # Define some extra resources to be created # This section is useful when you need ExternalResource or Secrets, etc.