From d1a2f9b10e69d3b8eb64d62c4c3f8c677a829606 Mon Sep 17 00:00:00 2001 From: kahirokunn Date: Tue, 2 Sep 2025 17:00:43 +0900 Subject: [PATCH 1/7] 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 --- charts/devlake/templates/configmap.yaml | 1 + charts/devlake/templates/deployments.yaml | 2 +- charts/devlake/values.yaml | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/charts/devlake/templates/configmap.yaml b/charts/devlake/templates/configmap.yaml index 502f44c8..207e6d49 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 d23bc0e2..a80960d4 100644 --- a/charts/devlake/templates/deployments.yaml +++ b/charts/devlake/templates/deployments.yaml @@ -199,7 +199,7 @@ spec: value: "{{ .Values.lake.port }}" {{- if (eq .Values.option.database "mysql") }} - 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/values.yaml b/charts/devlake/values.yaml index cc0b819a..4cb35aa0 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 From d81a0ae6d4e62ed3ef136e5e2ff08c25804ba89c Mon Sep 17 00:00:00 2001 From: kahirokunn Date: Tue, 2 Sep 2025 23:09:36 +0900 Subject: [PATCH 2/7] Enable optional DB URL auto-assembly for MySQL Signed-off-by: kahirokunn --- charts/devlake/templates/deployments.yaml | 2 +- charts/devlake/values.yaml | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/charts/devlake/templates/deployments.yaml b/charts/devlake/templates/deployments.yaml index a80960d4..db012d3d 100644 --- a/charts/devlake/templates/deployments.yaml +++ b/charts/devlake/templates/deployments.yaml @@ -197,7 +197,7 @@ 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){{ .Values.mysql.extraParams }}" {{- end }} diff --git a/charts/devlake/values.yaml b/charts/devlake/values.yaml index 4cb35aa0..6010ee75 100644 --- a/charts/devlake/values.yaml +++ b/charts/devlake/values.yaml @@ -437,6 +437,10 @@ option: # the existing k8s secret name of db connection auth. The secret name should be as same as .Values.grafana.envFromSecret connectionSecretName: "devlake-mysql-auth" 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. From 8d76d43d27e9e69cebbbc9d3fffaaa81891bf436 Mon Sep 17 00:00:00 2001 From: kahirokunn Date: Wed, 3 Sep 2025 00:30:50 +0900 Subject: [PATCH 3/7] 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 --- charts/devlake/templates/_helpers.tpl | 4 ++++ charts/devlake/values.yaml | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/charts/devlake/templates/_helpers.tpl b/charts/devlake/templates/_helpers.tpl index 5fbc671f..731af593 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/values.yaml b/charts/devlake/values.yaml index 6010ee75..f7efa719 100644 --- a/charts/devlake/values.yaml +++ b/charts/devlake/values.yaml @@ -169,9 +169,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" + # the ConfigMap name should be the same as .Values.option.connectionConfigmapName + extraEnvFrom: + - configMapRef: + name: "devlake-mysql-auth-config" #keep grafana timezone same as other pods, which is set by .Values.commonEnvs.TZ env: TZ: "UTC" @@ -436,6 +440,9 @@ option: 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" + # 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 From d55881d8a53d8066f1ef09f7a86c87630302b478 Mon Sep 17 00:00:00 2001 From: kahirokunn Date: Tue, 2 Sep 2025 23:55:29 +0900 Subject: [PATCH 4/7] Add Helm smoke test workflow Signed-off-by: kahirokunn --- .github/workflows/smoke-test.yml | 72 ++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 .github/workflows/smoke-test.yml diff --git a/.github/workflows/smoke-test.yml b/.github/workflows/smoke-test.yml new file mode 100644 index 00000000..84e81cdd --- /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 From 52b8df2c6269d764f52e2e25749a1d699d33477a Mon Sep 17 00:00:00 2001 From: kahirokunn Date: Wed, 3 Sep 2025 09:12:29 +0900 Subject: [PATCH 5/7] Link Secret and ConfigMap names in values.yaml Signed-off-by: kahirokunn --- charts/devlake/values.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/charts/devlake/values.yaml b/charts/devlake/values.yaml index f7efa719..d241f26a 100644 --- a/charts/devlake/values.yaml +++ b/charts/devlake/values.yaml @@ -171,11 +171,11 @@ grafana: root_url: "%(protocol)s://%(domain)s/grafana" # 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" + 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" @@ -439,10 +439,10 @@ 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" + 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 From 5d45b328163f883f6812465cffa2f11418efd718 Mon Sep 17 00:00:00 2001 From: kahirokunn Date: Wed, 3 Sep 2025 09:31:43 +0900 Subject: [PATCH 6/7] Add customizable probes for MySQL containers Signed-off-by: kahirokunn --- charts/devlake/templates/statefulsets.yaml | 24 +++++++++----------- charts/devlake/values.yaml | 26 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/charts/devlake/templates/statefulsets.yaml b/charts/devlake/templates/statefulsets.yaml index 477f6db2..1b49d088 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 d241f26a..1390b48c 100644 --- a/charts/devlake/values.yaml +++ b/charts/devlake/values.yaml @@ -95,6 +95,32 @@ mysql: podAnnotations: {} + # Probes for MySQL container + startupProbe: + exec: &mysql_ping_exec + command: + - "sh" + - "-c" + - "mysqladmin ping -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: "" From 84178195dc4eb4d24c8569c8f9eb70e1953deef8 Mon Sep 17 00:00:00 2001 From: kahirokunn Date: Wed, 3 Sep 2025 10:58:40 +0900 Subject: [PATCH 7/7] fix(mysql): Resolve environment-dependent startup failures by switching MySQL probes to TCP Signed-off-by: kahirokunn --- charts/devlake/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/devlake/values.yaml b/charts/devlake/values.yaml index 1390b48c..64311594 100644 --- a/charts/devlake/values.yaml +++ b/charts/devlake/values.yaml @@ -101,7 +101,7 @@ mysql: command: - "sh" - "-c" - - "mysqladmin ping -u root -p$MYSQL_ROOT_PASSWORD" + - "mysqladmin ping --protocol=TCP -h 127.0.0.1 -u root -p$MYSQL_ROOT_PASSWORD" initialDelaySeconds: 120 periodSeconds: 10 timeoutSeconds: 10