Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions .github/workflows/smoke-test.yml
Original file line number Diff line number Diff line change
@@ -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
4 changes: 4 additions & 0 deletions charts/devlake/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -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 -}}
Expand Down
1 change: 1 addition & 0 deletions charts/devlake/templates/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ data:
DB_CHARSET: "utf8mb4"
DB_PARSE_TIME: "True"
DB_LOCATION: "{{ .Values.commonEnvs.TZ }}"
DB_CUSTOM_PARAMS: "{{ .Values.mysql.extraParams }}"
{{- end }}
4 changes: 2 additions & 2 deletions charts/devlake/templates/deployments.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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 $ }}"
Expand Down
24 changes: 10 additions & 14 deletions charts/devlake/templates/statefulsets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down
48 changes: 45 additions & 3 deletions charts/devlake/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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: ""
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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.
Expand Down