diff --git a/charts/temporal/templates/_helpers.tpl b/charts/temporal/templates/_helpers.tpl index f49de879..5d8ba2de 100644 --- a/charts/temporal/templates/_helpers.tpl +++ b/charts/temporal/templates/_helpers.tpl @@ -412,10 +412,12 @@ Source: https://stackoverflow.com/a/52024583/3027614 All Cassandra hosts. */}} {{- define "cassandra.hosts" -}} -{{- range $i := (until (int .Values.cassandra.config.cluster_size)) }} +{{- $hosts := list -}} +{{- range $i := (until (int .Values.cassandra.config.cluster_size)) -}} {{- $cassandraName := include "call-nested" (list $ "cassandra" "cassandra.fullname") -}} -{{- printf "%s.%s," $cassandraName $.Release.Namespace -}} -{{- end }} +{{- $hosts = append $hosts (printf "%s.%s" $cassandraName $.Release.Namespace) -}} +{{- end -}} +{{- join "," $hosts -}} {{- end -}} {{/* diff --git a/charts/temporal/templates/server-deployment.yaml b/charts/temporal/templates/server-deployment.yaml index da48dd2b..53ca31a2 100644 --- a/charts/temporal/templates/server-deployment.yaml +++ b/charts/temporal/templates/server-deployment.yaml @@ -21,7 +21,7 @@ spec: template: metadata: annotations: - checksum/config: {{ include (print $.Template.BasePath "/server-configmap.yaml") $ | sha256sum }} + checksum/config: {{ include (print $.Template.BasePath "/server-sprig-configmap.yaml") $ | sha256sum }}-{{ include (print $.Template.BasePath "/server-dockerize-configmap.yaml") $ | sha256sum }} {{- if (dig "metrics" "annotations" "enabled" $.Values.server.metrics.annotations.enabled $serviceValues) }} prometheus.io/job: {{ $.Chart.Name }}-{{ $service }} prometheus.io/scrape: 'true' @@ -38,7 +38,7 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} {{- end }} - {{- if or (or $.Values.server.additionalInitContainers $.Values.cassandra.enabled) (or $.Values.elasticsearch.enabled $.Values.elasticsearch.external)}} + {{- if or $.Values.server.additionalInitContainers $.Values.cassandra.enabled (or $.Values.elasticsearch.enabled $.Values.elasticsearch.external) }} initContainers: {{- with $.Values.server.additionalInitContainers }} {{- toYaml . | nindent 8}} @@ -65,7 +65,28 @@ spec: - name: check-elasticsearch-index image: "{{ $.Values.admintools.image.repository }}:{{ $.Values.admintools.image.tag }}" imagePullPolicy: {{ $.Values.admintools.image.pullPolicy }} - command: ['sh', '-c', 'until curl --silent --fail --user "$ES_USER:$ES_PWD" $ES_SCHEME://$ES_HOST:$ES_PORT/$ES_VISIBILITY_INDEX 2>&1 > /dev/null; do echo waiting for elasticsearch index to become ready; sleep 1; done;'] + command: ['/bin/sh', '-c'] + args: + - | + set -e + echo "Waiting for Elasticsearch index to become ready..." + + if [ -x /usr/local/bin/temporal-elasticsearch-tool ]; then + echo "Using temporal-elasticsearch-tool to check index: $ES_VISIBILITY_INDEX" + # Use ping to verify ES is accessible, assuming index was created by setup job + until temporal-elasticsearch-tool --endpoint "$ES_SCHEME://$ES_HOST:$ES_PORT" --user "$ES_USER" --password "$ES_PWD" ping 2>&1 > /dev/null; do + sleep 1 + done + elif command -v curl >/dev/null 2>&1; then + echo "Using curl to check index: $ES_VISIBILITY_INDEX" + until curl --silent --fail --user "$ES_USER:$ES_PWD" "$ES_SCHEME://$ES_HOST:$ES_PORT/$ES_VISIBILITY_INDEX" 2>&1 > /dev/null; do + sleep 1 + done + else + echo "ERROR: Neither temporal-elasticsearch-tool nor curl found" >&2 + exit 1 + fi + echo "Elasticsearch index is ready" env: {{- include "temporal.admintools-env" (list $ "visibility") | nindent 12 }} {{- with $serviceValues.containerSecurityContext }} @@ -78,6 +99,9 @@ spec: - name: {{ $.Chart.Name }}-{{ $service }} image: "{{ $.Values.server.image.repository }}:{{ $.Values.server.image.tag }}" imagePullPolicy: {{ $.Values.server.image.pullPolicy }} + {{- if $.Values.server.useEntrypointScript }} + command: ['/entrypoint/entrypoint.sh'] + {{- end }} env: - name: POD_IP valueFrom: @@ -85,6 +109,8 @@ spec: fieldPath: status.podIP - name: SERVICES value: {{ $service }} + - name: TEMPORAL_SERVICES + value: {{ $service }} - name: TEMPORAL_SERVER_CONFIG_FILE_PATH value: /etc/temporal/config/config_template.yaml {{- if ne (include "temporal.persistence.driver" (list $ "default")) "custom" }} @@ -143,9 +169,33 @@ spec: port: rpc {{- end }} volumeMounts: - - name: config + {{- if $.Values.server.useEntrypointScript }} + {{- if or (eq $.Values.server.configMapsToMount "both") (eq $.Values.server.configMapsToMount "dockerize") }} + - name: config-dockerize + mountPath: /etc/temporal/config-source/dockerize + readOnly: true + {{- end }} + {{- if or (eq $.Values.server.configMapsToMount "both") (eq $.Values.server.configMapsToMount "sprig") }} + - name: config-sprig + mountPath: /etc/temporal/config-source/sprig + readOnly: true + {{- end }} + - name: entrypoint-script + mountPath: /entrypoint + readOnly: true + - name: config-processed + mountPath: /etc/temporal/config + {{- else }} + {{- if eq $.Values.server.configMapsToMount "dockerize" }} + - name: config-dockerize mountPath: /etc/temporal/config/config_template.yaml subPath: config_template.yaml + {{- else }} + - name: config-sprig + mountPath: /etc/temporal/config/config_template.yaml + subPath: config_template.yaml + {{- end }} + {{- end }} - name: dynamic-config mountPath: /etc/temporal/dynamic_config {{- if $.Values.server.additionalVolumeMounts }} @@ -162,9 +212,24 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} volumes: - - name: config + {{- if or (eq $.Values.server.configMapsToMount "both") (eq $.Values.server.configMapsToMount "dockerize") }} + - name: config-dockerize + configMap: + name: "{{ include "temporal.fullname" $ }}-dockerize-config" + {{- end }} + {{- if or (eq $.Values.server.configMapsToMount "both") (eq $.Values.server.configMapsToMount "sprig") }} + - name: config-sprig configMap: - name: "{{ include "temporal.fullname" $ }}-config" + name: "{{ include "temporal.fullname" $ }}-sprig-config" + {{- end }} + {{- if $.Values.server.useEntrypointScript }} + - name: entrypoint-script + configMap: + name: "{{ include "temporal.fullname" $ }}-entrypoint-script" + defaultMode: 0755 + - name: config-processed + emptyDir: {} + {{- end }} - name: dynamic-config configMap: name: "{{ include "temporal.fullname" $ }}-dynamic-config" diff --git a/charts/temporal/templates/server-configmap.yaml b/charts/temporal/templates/server-dockerize-configmap.yaml similarity index 96% rename from charts/temporal/templates/server-configmap.yaml rename to charts/temporal/templates/server-dockerize-configmap.yaml index 155569c1..35003006 100644 --- a/charts/temporal/templates/server-configmap.yaml +++ b/charts/temporal/templates/server-dockerize-configmap.yaml @@ -1,10 +1,10 @@ -{{- if .Values.server.enabled -}} +{{- if and .Values.server.enabled (or (eq .Values.server.configMapsToMount "both") (eq .Values.server.configMapsToMount "dockerize")) -}} {{- $server := .Values.server -}} {{- $elasticsearch := .Values.elasticsearch -}} apiVersion: v1 kind: ConfigMap metadata: - name: "{{ include "temporal.fullname" $ }}-config" + name: "{{ include "temporal.fullname" $ }}-dockerize-config" labels: {{- include "temporal.resourceLabels" (list $ "" "") | nindent 4 }} data: @@ -83,7 +83,7 @@ data: membership: name: temporal maxJoinDuration: 30s - broadcastAddress: {{ `{{ default .Env.POD_IP "0.0.0.0" }}` }} + broadcastAddress: {{ `{{ .Env.POD_IP }}` }} pprof: port: 7936 diff --git a/charts/temporal/templates/server-entrypoint-script.yaml b/charts/temporal/templates/server-entrypoint-script.yaml new file mode 100644 index 00000000..be24da93 --- /dev/null +++ b/charts/temporal/templates/server-entrypoint-script.yaml @@ -0,0 +1,49 @@ +{{- if and .Values.server.enabled .Values.server.useEntrypointScript -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ include "temporal.fullname" $ }}-entrypoint-script" + labels: + {{- include "temporal.resourceLabels" (list $ "" "") | nindent 4 }} +data: + entrypoint.sh: |- + #!/bin/sh + set -e + + echo "Temporal entrypoint override - starting ${TEMPORAL_SERVICES}" + + {{- if eq .Values.server.configMapsToMount "both" }} + # Auto-detect config format based on dockerize availability + if command -v dockerize >/dev/null 2>&1; then + echo "Using dockerize config" + SOURCE_CONFIG="/etc/temporal/config-source/dockerize/config_template.yaml" + TARGET_CONFIG="/etc/temporal/config/docker.yaml" + dockerize -template "${SOURCE_CONFIG}:${TARGET_CONFIG}" + exec temporal-server --root / --config etc/temporal/config --env docker start --service="${TEMPORAL_SERVICES}" + else + echo "Using sprig config" + export TEMPORAL_SERVER_CONFIG_FILE_PATH="/etc/temporal/config-source/sprig/config_template.yaml" + exec temporal-server start + fi + {{- else if eq .Values.server.configMapsToMount "dockerize" }} + if ! command -v dockerize >/dev/null 2>&1; then + echo "ERROR: dockerize config requires dockerize but it was not found" >&2 + echo "Either install an image with dockerize or use configMapsToMount: sprig" >&2 + exit 1 + fi + + echo "Using dockerize config" + SOURCE_CONFIG="/etc/temporal/config-source/dockerize/config_template.yaml" + TARGET_CONFIG="/etc/temporal/config/docker.yaml" + dockerize -template "${SOURCE_CONFIG}:${TARGET_CONFIG}" + exec temporal-server --root / --config etc/temporal/config --env docker start --service="${TEMPORAL_SERVICES}" + {{- else if eq .Values.server.configMapsToMount "sprig" }} + echo "Using sprig config" + export TEMPORAL_SERVER_CONFIG_FILE_PATH="/etc/temporal/config-source/sprig/config_template.yaml" + exec temporal-server start + {{- else }} + echo "ERROR: Invalid configMapsToMount value: {{ .Values.server.configMapsToMount }}" >&2 + echo "Must be one of: both, dockerize, sprig" >&2 + exit 1 + {{- end }} +{{- end }} diff --git a/charts/temporal/templates/server-job.yaml b/charts/temporal/templates/server-job.yaml index 4b79ef15..2ae3184d 100644 --- a/charts/temporal/templates/server-job.yaml +++ b/charts/temporal/templates/server-job.yaml @@ -41,7 +41,27 @@ spec: - name: check-elasticsearch image: "{{ $.Values.admintools.image.repository }}:{{ $.Values.admintools.image.tag }}" imagePullPolicy: {{ $.Values.admintools.image.pullPolicy }} - command: ['sh', '-c', 'until curl --silent --fail --user "$ES_USER:$ES_PWD" $ES_SCHEME://$ES_HOST:$ES_PORT 2>&1 > /dev/null; do echo waiting for elasticsearch to start; sleep 1; done;'] + command: ['/bin/sh', '-c'] + args: + - | + set -e + echo "Waiting for Elasticsearch to become available..." + + if [ -x /usr/local/bin/temporal-elasticsearch-tool ]; then + echo "Using temporal-elasticsearch-tool for Elasticsearch health check" + until temporal-elasticsearch-tool --endpoint "$ES_SCHEME://$ES_HOST:$ES_PORT" --user "$ES_USER" --password "$ES_PWD" ping 2>&1 > /dev/null; do + sleep 1 + done + elif command -v curl >/dev/null 2>&1; then + echo "Using curl for Elasticsearch health check" + until curl --silent --fail --user "$ES_USER:$ES_PWD" "$ES_SCHEME://$ES_HOST:$ES_PORT" 2>&1 > /dev/null; do + sleep 1 + done + else + echo "ERROR: Neither temporal-elasticsearch-tool nor curl found" >&2 + exit 1 + fi + echo "Elasticsearch is ready" env: {{- include "temporal.admintools-env" (list $ "visibility") | nindent 12 }} {{- with $.Values.schema.containerSecurityContext }} @@ -92,11 +112,56 @@ spec: {{- else if eq $driver "sql" }} command: ['temporal-sql-tool', 'setup-schema', '-v', '0.0'] {{- else if eq $driver "elasticsearch" }} - command: ['sh', '-c'] + command: ['/bin/sh', '-c'] args: - - 'curl -X PUT --fail --user "$ES_USER:$ES_PWD" $ES_SCHEME://$ES_HOST:$ES_PORT/_template/temporal_visibility_v1_template -H "Content-Type: application/json" --data-binary "@schema/elasticsearch/visibility/index_template_$ES_VERSION.json" 2>&1 && - curl --head --fail --user "$ES_USER:$ES_PWD" $ES_SCHEME://$ES_HOST:$ES_PORT/$ES_VISIBILITY_INDEX 2>&1 || - curl -X PUT --fail --user "$ES_USER:$ES_PWD" $ES_SCHEME://$ES_HOST:$ES_PORT/$ES_VISIBILITY_INDEX 2>&1' + - | + set -e + echo "Setting up Elasticsearch visibility store..." + + if [ -x /usr/local/bin/temporal-elasticsearch-tool ]; then + echo "Using temporal-elasticsearch-tool for Elasticsearch setup" + + echo "Setting up cluster settings and index template" + temporal-elasticsearch-tool \ + --endpoint "$ES_SCHEME://$ES_HOST:$ES_PORT" \ + --user "$ES_USER" \ + --password "$ES_PWD" \ + setup-schema + + echo "Creating visibility index: $ES_VISIBILITY_INDEX" + temporal-elasticsearch-tool \ + --endpoint "$ES_SCHEME://$ES_HOST:$ES_PORT" \ + --user "$ES_USER" \ + --password "$ES_PWD" \ + create-index \ + --index "$ES_VISIBILITY_INDEX" \ + --fail + + elif command -v curl >/dev/null 2>&1; then + echo "Using curl for Elasticsearch setup" + + echo "Creating index template: temporal_visibility_v1_template" + curl -X PUT --fail --user "$ES_USER:$ES_PWD" \ + "$ES_SCHEME://$ES_HOST:$ES_PORT/_template/temporal_visibility_v1_template" \ + -H "Content-Type: application/json" \ + --data-binary "@schema/elasticsearch/visibility/index_template_$ES_VERSION.json" + + echo "Checking if index exists: $ES_VISIBILITY_INDEX" + if ! curl --head --fail --user "$ES_USER:$ES_PWD" \ + "$ES_SCHEME://$ES_HOST:$ES_PORT/$ES_VISIBILITY_INDEX" 2>&1 > /dev/null; then + echo "Creating index: $ES_VISIBILITY_INDEX" + curl -X PUT --fail --user "$ES_USER:$ES_PWD" \ + "$ES_SCHEME://$ES_HOST:$ES_PORT/$ES_VISIBILITY_INDEX" + else + echo "Index already exists" + fi + + else + echo "ERROR: Neither temporal-elasticsearch-tool nor curl found" >&2 + exit 1 + fi + + echo "Elasticsearch setup completed successfully" {{- end }} env: {{- include "temporal.admintools-env" (list $ $store) | nindent 12 }} diff --git a/charts/temporal/templates/server-sprig-configmap.yaml b/charts/temporal/templates/server-sprig-configmap.yaml new file mode 100644 index 00000000..6227902f --- /dev/null +++ b/charts/temporal/templates/server-sprig-configmap.yaml @@ -0,0 +1,186 @@ +{{- if and .Values.server.enabled (or (eq .Values.server.configMapsToMount "both") (eq .Values.server.configMapsToMount "sprig")) -}} +{{- $server := .Values.server -}} +{{- $elasticsearch := .Values.elasticsearch -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ include "temporal.fullname" $ }}-sprig-config" + labels: + {{- include "temporal.resourceLabels" (list $ "" "") | nindent 4 }} +data: + config_template.yaml: |- + # enable-template + log: + stdout: true + level: {{ $server.config.logLevel | quote }} + persistence: + defaultStore: {{ $server.config.persistence.defaultStore }} + visibilityStore: visibility + numHistoryShards: {{ $server.config.numHistoryShards }} + datastores: + {{- if ne (include "temporal.persistence.driver" (list $ "default")) "custom" }} + default: + {{- if eq (include "temporal.persistence.driver" (list $ "default")) "cassandra" }} + cassandra: + hosts: "{{ include "temporal.persistence.cassandra.hosts" (list $ "default") }}" + port: {{ include "temporal.persistence.cassandra.port" (list $ "default") }} + password: {{ `{{ env "TEMPORAL_STORE_PASSWORD" | quote }}` }} + {{- with (omit $server.config.persistence.default.cassandra "hosts" "port" "password" "existingSecret") }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- else if eq (include "temporal.persistence.driver" (list $ "default")) "sql" }} + sql: + pluginName: "{{ include "temporal.persistence.sql.driver" (list $ "default") }}" + driverName: "{{ include "temporal.persistence.sql.driver" (list $ "default") }}" + databaseName: "{{ $server.config.persistence.default.sql.database }}" + connectAddr: "{{ include "temporal.persistence.sql.host" (list $ "default") }}:{{ include "temporal.persistence.sql.port" (list $ "default") }}" + connectProtocol: "tcp" + user: {{ include "temporal.persistence.sql.user" (list $ "default") }} + password: {{ `{{ env "TEMPORAL_STORE_PASSWORD" | quote }}` }} + {{- with (omit $server.config.persistence.default.sql "driver" "driverName" "host" "port" "connectAddr" "connectProtocol" "database" "databaseName" "user" "password" "existingSecret") }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- end }} + {{- with $server.config.persistence.default.faultInjection}} + faultInjection: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- end }} + {{- with $server.config.persistence.additionalStores }} + {{- toYaml . | nindent 8 }} + {{- end }} + visibility: + {{- if or $elasticsearch.enabled $elasticsearch.external }} + elasticsearch: + version: "{{ $elasticsearch.version }}" + url: + scheme: "{{ $elasticsearch.scheme }}" + host: "{{ $elasticsearch.host }}:{{ $elasticsearch.port }}" + username: "{{ $elasticsearch.username }}" + password: {{ `{{ env "TEMPORAL_VISIBILITY_STORE_PASSWORD" | quote }}` }} + logLevel: "{{ $elasticsearch.logLevel }}" + indices: + visibility: "{{ $elasticsearch.visibilityIndex }}" + {{- with $elasticsearch.tls }} + tls: + {{- toYaml . | nindent 16 }} + {{- end }} + {{- else if eq (include "temporal.persistence.driver" (list $ "visibility")) "sql" }} + sql: + pluginName: "{{ include "temporal.persistence.sql.driver" (list $ "visibility") }}" + driverName: "{{ include "temporal.persistence.sql.driver" (list $ "visibility") }}" + databaseName: "{{ $server.config.persistence.visibility.sql.database }}" + connectAddr: "{{ include "temporal.persistence.sql.host" (list $ "visibility") }}:{{ include "temporal.persistence.sql.port" (list $ "visibility") }}" + connectProtocol: "tcp" + user: "{{ include "temporal.persistence.sql.user" (list $ "visibility") }}" + password: {{ `{{ env "TEMPORAL_VISIBILITY_STORE_PASSWORD" | quote }}` }} + {{- with (omit $server.config.persistence.visibility.sql "driver" "driverName" "host" "port" "connectAddr" "connectProtocol" "database" "databaseName" "user" "password" "existingSecret") }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- end }} + global: + membership: + name: temporal + maxJoinDuration: 30s + broadcastAddress: {{ `{{ env "POD_IP" }}` }} + pprof: + port: 7936 + metrics: + tags: + type: {{ `{{ env "TEMPORAL_SERVICES" }}` }} + {{- with $server.metrics.tags }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with $server.metrics.excludeTags }} + excludeTags: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with $server.metrics.prefix }} + prefix: "{{- . }}" + {{- end }} + {{- with $server.config.prometheus }} + prometheus: + {{- toYaml . | nindent 10 }} + {{- else }} + prometheus: + timerType: histogram + listenAddress: "0.0.0.0:9090" + {{- end }} + {{- with $server.config.tls }} + tls: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with $server.config.authorization }} + authorization: + {{- toYaml . | nindent 10 }} + {{- end }} + services: + frontend: + rpc: + grpcPort: {{ $server.frontend.service.port }} + httpPort: {{ $server.frontend.service.httpPort }} + membershipPort: {{ $server.frontend.service.membershipPort }} + bindOnIP: "0.0.0.0" + {{- if and (hasKey .Values.server "internalFrontend") .Values.server.internalFrontend.enabled }} + internal-frontend: + rpc: + grpcPort: {{ $server.internalFrontend.service.port }} + httpPort: {{ $server.internalFrontend.service.httpPort }} + membershipPort: {{ $server.internalFrontend.service.membershipPort }} + bindOnIP: "0.0.0.0" + {{- end }} + history: + rpc: + grpcPort: {{ $server.history.service.port }} + membershipPort: {{ $server.history.service.membershipPort }} + bindOnIP: "0.0.0.0" + matching: + rpc: + grpcPort: {{ $server.matching.service.port }} + membershipPort: {{ $server.matching.service.membershipPort }} + bindOnIP: "0.0.0.0" + worker: + rpc: + membershipPort: {{ $server.worker.service.membershipPort }} + bindOnIP: "0.0.0.0" + clusterMetadata: + {{- with $server.config.clusterMetadata }} + {{- toYaml . | nindent 8 }} + {{- else }} + enableGlobalDomain: false + failoverVersionIncrement: 10 + masterClusterName: "active" + currentClusterName: "active" + clusterInformation: + active: + enabled: true + initialFailoverVersion: 1 + rpcName: "temporal-frontend" + rpcAddress: "127.0.0.1:{{ $server.frontend.service.port }}" + httpAddress: "127.0.0.1:{{ $server.frontend.service.httpPort }}" + {{- end }} + dcRedirectionPolicy: + {{- with $server.config.dcRedirectionPolicy }} + {{- toYaml . | nindent 8 }} + {{- else }} + policy: "noop" + toDC: "" + {{- end }} + archival: + {{- with $server.archival }} + {{- toYaml . | nindent 6 }} + {{- else }} + status: "disabled" + {{- end }} + {{- with $server.namespaceDefaults }} + namespaceDefaults: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- if not (and (hasKey .Values.server "internalFrontend") .Values.server.internalFrontend.enabled) }} + publicClient: + hostPort: "{{ include "temporal.componentname" (list $ "frontend") }}:{{ $server.frontend.service.port }}" + {{- end }} + dynamicConfigClient: + filepath: "/etc/temporal/dynamic_config/dynamic_config.yaml" + pollInterval: "10s" +{{- end }} diff --git a/charts/temporal/tests/deployment_test.go b/charts/temporal/tests/deployment_test.go index 94ff6778..9c7607b8 100644 --- a/charts/temporal/tests/deployment_test.go +++ b/charts/temporal/tests/deployment_test.go @@ -176,3 +176,86 @@ func TestTemplateServerDeploymentLabels(t *testing.T) { require.Equal(t, "zero", deployment.ObjectMeta.Labels["zero"]) require.Equal(t, "zero", deployment.Spec.Template.ObjectMeta.Labels["zero"]) } + + +func TestTemplateServerEntrypointScript(t *testing.T) { + helmChartPath, err := filepath.Abs("../") + require.NoError(t, err) + + namespaceName := "temporal-" + strings.ToLower(random.UniqueId()) + + options := &helm.Options{ + SetValues: map[string]string{ + "server.useEntrypointScript": "true", + }, + KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName), + BuildDependencies: true, + } + + output := helm.RenderTemplate(t, options, helmChartPath, "temporal", []string{"templates/server-entrypoint-script.yaml"}) + + require.Contains(t, output, "ConfigMap") + require.Contains(t, output, "entrypoint.sh") + require.Contains(t, output, "dockerize") + require.Contains(t, output, "temporal-server") +} + +func TestTemplateServerDeploymentWithEntrypointScript(t *testing.T) { + helmChartPath, err := filepath.Abs("../") + require.NoError(t, err) + + namespaceName := "temporal-" + strings.ToLower(random.UniqueId()) + + testCases := []struct { + name string + configMapsToMount string + expectDockerize bool + expectSprig bool + }{ + {"both configs", "both", true, true}, + {"dockerize only", "dockerize", true, false}, + {"sprig only", "sprig", false, true}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + var deployment appsv1.Deployment + + options := &helm.Options{ + SetValues: map[string]string{ + "server.useEntrypointScript": "true", + "server.configMapsToMount": tc.configMapsToMount, + }, + KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName), + BuildDependencies: true, + } + + output := helm.RenderTemplate(t, options, helmChartPath, "temporal", []string{"templates/server-deployment.yaml"}) + helm.UnmarshalK8SYaml(t, output, &deployment) + + // Verify command override + require.Equal(t, []string{"/entrypoint/entrypoint.sh"}, deployment.Spec.Template.Spec.Containers[0].Command) + + // Verify volume configuration + volumeNames := make([]string, len(deployment.Spec.Template.Spec.Volumes)) + for i, vol := range deployment.Spec.Template.Spec.Volumes { + volumeNames[i] = vol.Name + } + + require.Contains(t, volumeNames, "entrypoint-script") + require.Contains(t, volumeNames, "config-processed") + + if tc.expectDockerize { + require.Contains(t, volumeNames, "config-dockerize") + } else { + require.NotContains(t, volumeNames, "config-dockerize") + } + + if tc.expectSprig { + require.Contains(t, volumeNames, "config-sprig") + } else { + require.NotContains(t, volumeNames, "config-sprig") + } + }) + } +} diff --git a/charts/temporal/tests/init_container_tools_test.yaml b/charts/temporal/tests/init_container_tools_test.yaml new file mode 100644 index 00000000..349ad5c9 --- /dev/null +++ b/charts/temporal/tests/init_container_tools_test.yaml @@ -0,0 +1,136 @@ +suite: test init container tool checks +templates: + - server-deployment.yaml + - server-job.yaml + - server-entrypoint-script.yaml + - server-dockerize-configmap.yaml + - server-sprig-configmap.yaml + - server-dynamicconfigmap.yaml + - _helpers.tpl +release: + name: test-release + namespace: default +set: + cassandra: + enabled: true + config: + cluster_size: 1 + elasticsearch: + enabled: true +tests: + # Test Cassandra init container uses cassandra image + - it: should use cassandra image for cassandra init containers + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: test-release-temporal-frontend + asserts: + - equal: + path: spec.template.spec.initContainers[?(@.name == "check-cassandra")].image + value: "cassandra:3.11.3" + - equal: + path: spec.template.spec.initContainers[?(@.name == "check-cassandra-temporal-schema")].image + value: "cassandra:3.11.3" + + # Test Cassandra init container uses cqlsh commands + - it: should use cqlsh for cassandra checks + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: test-release-temporal-frontend + asserts: + - matchRegex: + path: spec.template.spec.initContainers[?(@.name == "check-cassandra")].command[2] + pattern: "cqlsh.*SHOW VERSION" + - matchRegex: + path: spec.template.spec.initContainers[?(@.name == "check-cassandra-temporal-schema")].command[2] + pattern: "cqlsh.*SELECT keyspace_name FROM system_schema.keyspaces" + + # Test Elasticsearch init container checks temporal-elasticsearch-tool first + - it: should check for temporal-elasticsearch-tool before curl in deployment + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: test-release-temporal-frontend + asserts: + - matchRegex: + path: spec.template.spec.initContainers[?(@.name == "check-elasticsearch-index")].args[0] + pattern: 'if \[ -x /usr/local/bin/temporal-elasticsearch-tool \][\s\S]*elif command -v curl' + + # Test Elasticsearch init container in job checks temporal-elasticsearch-tool first + - it: should check for temporal-elasticsearch-tool before curl in job + template: templates/server-job.yaml + asserts: + - matchRegex: + path: spec.template.spec.initContainers[?(@.name == "check-elasticsearch")].args[0] + pattern: 'if \[ -x /usr/local/bin/temporal-elasticsearch-tool \][\s\S]*elif command -v curl' + + # Test Elasticsearch init container error messages + - it: should have proper error messages for elasticsearch checks + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: test-release-temporal-frontend + asserts: + - matchRegex: + path: spec.template.spec.initContainers[?(@.name == "check-elasticsearch-index")].args[0] + pattern: "ERROR: Neither temporal-elasticsearch-tool nor curl found" + + # Test Cassandra hosts without trailing comma + - it: should not have trailing comma in cassandra hosts + template: templates/server-dockerize-configmap.yaml + asserts: + - notMatchRegex: + path: data["config_template.yaml"] + pattern: 'hosts: ".*,"' + - matchRegex: + path: data["config_template.yaml"] + pattern: 'hosts: "test-release-cassandra\.default"' + + # Test entrypoint script has correct --root flag + - it: should have correct temporal-server command with --root flag + template: templates/server-entrypoint-script.yaml + set: + server: + useEntrypointScript: true + asserts: + - matchRegex: + path: data["entrypoint.sh"] + pattern: "temporal-server --root / --config etc/temporal/config --env docker start" + + # Test that all four service deployments have cassandra init containers + - it: should have cassandra init containers in all service deployments + template: templates/server-deployment.yaml + asserts: + - hasDocuments: + count: 4 + + # Test that cassandra init containers use proper host helper + - it: should use cassandra.host helper in init containers + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: test-release-temporal-frontend + asserts: + - matchRegex: + path: spec.template.spec.initContainers[?(@.name == "check-cassandra")].command[2] + pattern: 'test-release-cassandra\.default' + - matchRegex: + path: spec.template.spec.initContainers[?(@.name == "check-cassandra-temporal-schema")].command[2] + pattern: 'test-release-cassandra\.default' + + # Test multi-node cassandra cluster hosts + - it: should generate comma-separated hosts for multi-node cassandra without trailing comma + set: + cassandra: + enabled: true + config: + cluster_size: 3 + template: templates/server-dockerize-configmap.yaml + asserts: + - matchRegex: + path: data["config_template.yaml"] + pattern: 'hosts: "test-release-cassandra\.default,test-release-cassandra\.default,test-release-cassandra\.default"' + - notMatchRegex: + path: data["config_template.yaml"] + pattern: 'hosts: ".*,"$' diff --git a/charts/temporal/tests/server_deployment_test.yaml b/charts/temporal/tests/server_deployment_test.yaml index ed46b15f..bcf8a939 100644 --- a/charts/temporal/tests/server_deployment_test.yaml +++ b/charts/temporal/tests/server_deployment_test.yaml @@ -1,7 +1,8 @@ suite: test server deployment templates: - server-deployment.yaml - - server-configmap.yaml + - server-sprig-configmap.yaml + - server-dockerize-configmap.yaml set: server: replicaCount: 2 diff --git a/charts/temporal/tests/server_entrypoint_config_test.yaml b/charts/temporal/tests/server_entrypoint_config_test.yaml new file mode 100644 index 00000000..27b9320f --- /dev/null +++ b/charts/temporal/tests/server_entrypoint_config_test.yaml @@ -0,0 +1,511 @@ +suite: test server entrypoint and config mounting +templates: + - server-deployment.yaml + - server-sprig-configmap.yaml + - server-dockerize-configmap.yaml + - server-entrypoint-script.yaml +tests: + # Test entrypoint script ConfigMap creation + - it: creates entrypoint script ConfigMap when useEntrypointScript is true + template: templates/server-entrypoint-script.yaml + set: + server: + enabled: true + useEntrypointScript: true + asserts: + - isKind: + of: ConfigMap + - equal: + path: metadata.name + value: RELEASE-NAME-temporal-entrypoint-script + - exists: + path: data["entrypoint.sh"] + + - it: does not create entrypoint script ConfigMap when useEntrypointScript is false + template: templates/server-entrypoint-script.yaml + set: + server: + enabled: true + useEntrypointScript: false + asserts: + - hasDocuments: + count: 0 + + # Test configMapsToMount: "both" (default) + - it: creates both ConfigMaps when configMapsToMount is both + templates: + - templates/server-sprig-configmap.yaml + - templates/server-dockerize-configmap.yaml + set: + server: + enabled: true + configMapsToMount: "both" + asserts: + - template: templates/server-sprig-configmap.yaml + isKind: + of: ConfigMap + - template: templates/server-dockerize-configmap.yaml + isKind: + of: ConfigMap + + - it: mounts both config volumes when configMapsToMount is both with entrypoint + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: RELEASE-NAME-temporal-frontend + set: + server: + enabled: true + useEntrypointScript: true + configMapsToMount: "both" + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: config-dockerize + configMap: + name: RELEASE-NAME-temporal-dockerize-config + - contains: + path: spec.template.spec.volumes + content: + name: config-sprig + configMap: + name: RELEASE-NAME-temporal-sprig-config + + - it: mounts both configs to config-source paths when useEntrypointScript is true + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: RELEASE-NAME-temporal-frontend + set: + server: + enabled: true + useEntrypointScript: true + configMapsToMount: "both" + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: config-dockerize + mountPath: /etc/temporal/config-source/dockerize + readOnly: true + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: config-sprig + mountPath: /etc/temporal/config-source/sprig + readOnly: true + + # Test configMapsToMount: "dockerize" + - it: creates only dockerize ConfigMap when configMapsToMount is dockerize + templates: + - templates/server-sprig-configmap.yaml + - templates/server-dockerize-configmap.yaml + set: + server: + enabled: true + configMapsToMount: "dockerize" + asserts: + - template: templates/server-sprig-configmap.yaml + hasDocuments: + count: 0 + - template: templates/server-dockerize-configmap.yaml + isKind: + of: ConfigMap + + - it: mounts only dockerize config volume when configMapsToMount is dockerize + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: RELEASE-NAME-temporal-frontend + set: + server: + enabled: true + useEntrypointScript: true + configMapsToMount: "dockerize" + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: config-dockerize + configMap: + name: RELEASE-NAME-temporal-dockerize-config + - notContains: + path: spec.template.spec.volumes + content: + name: config-sprig + + # Test configMapsToMount: "sprig" + - it: creates only sprig ConfigMap when configMapsToMount is sprig + templates: + - templates/server-sprig-configmap.yaml + - templates/server-dockerize-configmap.yaml + set: + server: + enabled: true + configMapsToMount: "sprig" + asserts: + - template: templates/server-sprig-configmap.yaml + isKind: + of: ConfigMap + - template: templates/server-dockerize-configmap.yaml + hasDocuments: + count: 0 + + - it: mounts only sprig config volume when configMapsToMount is sprig + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: RELEASE-NAME-temporal-frontend + set: + server: + enabled: true + useEntrypointScript: true + configMapsToMount: "sprig" + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: config-sprig + configMap: + name: RELEASE-NAME-temporal-sprig-config + - notContains: + path: spec.template.spec.volumes + content: + name: config-dockerize + + # Test entrypoint command override + - it: overrides command to use entrypoint script when useEntrypointScript is true + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: RELEASE-NAME-temporal-frontend + set: + server: + enabled: true + useEntrypointScript: true + asserts: + - equal: + path: spec.template.spec.containers[0].command + value: ["/entrypoint/entrypoint.sh"] + + - it: does not override command when useEntrypointScript is false + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: RELEASE-NAME-temporal-frontend + set: + server: + enabled: true + useEntrypointScript: false + asserts: + - notExists: + path: spec.template.spec.containers[0].command + + # Test entrypoint script volume mount + - it: mounts entrypoint script volume when useEntrypointScript is true + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: RELEASE-NAME-temporal-frontend + set: + server: + enabled: true + useEntrypointScript: true + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: entrypoint-script + configMap: + name: RELEASE-NAME-temporal-entrypoint-script + defaultMode: 493 # 0755 in decimal + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: entrypoint-script + mountPath: /entrypoint + readOnly: true + + # Test config-processed emptyDir volume + - it: creates config-processed emptyDir volume when useEntrypointScript is true + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: RELEASE-NAME-temporal-frontend + set: + server: + enabled: true + useEntrypointScript: true + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: config-processed + emptyDir: {} + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: config-processed + mountPath: /etc/temporal/config + + # Test backward compatibility (useEntrypointScript: false) + - it: mounts config directly when useEntrypointScript is false with dockerize config + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: RELEASE-NAME-temporal-frontend + set: + server: + enabled: true + useEntrypointScript: false + configMapsToMount: "dockerize" + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: config-dockerize + mountPath: /etc/temporal/config/config_template.yaml + subPath: config_template.yaml + + - it: mounts config directly when useEntrypointScript is false with sprig config + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: RELEASE-NAME-temporal-frontend + set: + server: + enabled: true + useEntrypointScript: false + configMapsToMount: "sprig" + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: config-sprig + mountPath: /etc/temporal/config/config_template.yaml + subPath: config_template.yaml + + # Test environment variables + - it: does not set TEMPORAL_SERVER_CONFIG_FILE_PATH when useEntrypointScript is true + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: RELEASE-NAME-temporal-frontend + set: + server: + enabled: true + useEntrypointScript: true + asserts: + - notContains: + path: spec.template.spec.containers[0].env + content: + name: TEMPORAL_SERVER_CONFIG_FILE_PATH + + - it: sets TEMPORAL_SERVER_CONFIG_FILE_PATH when useEntrypointScript is false + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: RELEASE-NAME-temporal-frontend + set: + server: + enabled: true + useEntrypointScript: false + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: TEMPORAL_SERVER_CONFIG_FILE_PATH + value: /etc/temporal/config/config_template.yaml + + # Test entrypoint script content for auto-detection + # Test entrypoint script content for auto-detection + - it: entrypoint script contains dockerize detection logic for both configs + template: templates/server-entrypoint-script.yaml + set: + server: + enabled: true + useEntrypointScript: true + configMapsToMount: "both" + asserts: + - matchRegex: + path: data["entrypoint.sh"] + pattern: "if command -v dockerize" + - matchRegex: + path: data["entrypoint.sh"] + pattern: "Using dockerize config" + - matchRegex: + path: data["entrypoint.sh"] + pattern: "Using sprig config" + + - it: entrypoint script uses dockerize config when configMapsToMount is dockerize + template: templates/server-entrypoint-script.yaml + set: + server: + enabled: true + useEntrypointScript: true + configMapsToMount: "dockerize" + asserts: + - matchRegex: + path: data["entrypoint.sh"] + pattern: "Using dockerize config" + - matchRegex: + path: data["entrypoint.sh"] + pattern: "dockerize" + + - it: entrypoint script uses sprig config when configMapsToMount is sprig + template: templates/server-entrypoint-script.yaml + set: + server: + enabled: true + useEntrypointScript: true + configMapsToMount: "sprig" + asserts: + - matchRegex: + path: data["entrypoint.sh"] + pattern: "Using sprig config" + - matchRegex: + path: data["entrypoint.sh"] + pattern: "TEMPORAL_SERVER_CONFIG_FILE_PATH" + + # Test entrypoint script command-line arguments and paths + - it: entrypoint script uses correct temporal-server args for both/dockerize mode + template: templates/server-entrypoint-script.yaml + set: + server: + enabled: true + useEntrypointScript: true + configMapsToMount: "both" + asserts: + - matchRegex: + path: data["entrypoint.sh"] + pattern: 'temporal-server --root / --config etc/temporal/config --env docker start --service="\$\{TEMPORAL_SERVICES\}"' + - matchRegex: + path: data["entrypoint.sh"] + pattern: 'SOURCE_CONFIG="/etc/temporal/config-source/dockerize/config_template.yaml"' + - matchRegex: + path: data["entrypoint.sh"] + pattern: 'TARGET_CONFIG="/etc/temporal/config/docker.yaml"' + - matchRegex: + path: data["entrypoint.sh"] + pattern: 'dockerize -template "\$\{SOURCE_CONFIG\}:\$\{TARGET_CONFIG\}"' + + - it: entrypoint script uses simple temporal-server start for sprig mode + template: templates/server-entrypoint-script.yaml + set: + server: + enabled: true + useEntrypointScript: true + configMapsToMount: "sprig" + asserts: + - matchRegex: + path: data["entrypoint.sh"] + pattern: "exec temporal-server start$" + - matchRegex: + path: data["entrypoint.sh"] + pattern: 'export TEMPORAL_SERVER_CONFIG_FILE_PATH="/etc/temporal/config-source/sprig/config_template.yaml"' + + - it: entrypoint script uses correct args for dockerize-only mode + template: templates/server-entrypoint-script.yaml + set: + server: + enabled: true + useEntrypointScript: true + configMapsToMount: "dockerize" + asserts: + - matchRegex: + path: data["entrypoint.sh"] + pattern: 'temporal-server --root / --config etc/temporal/config --env docker start --service="\$\{TEMPORAL_SERVICES\}"' + - matchRegex: + path: data["entrypoint.sh"] + pattern: 'dockerize -template "\$\{SOURCE_CONFIG\}:\$\{TARGET_CONFIG\}"' + + # Test error handling in entrypoint script + - it: entrypoint script checks for dockerize when configMapsToMount is dockerize + template: templates/server-entrypoint-script.yaml + set: + server: + enabled: true + useEntrypointScript: true + configMapsToMount: "dockerize" + asserts: + - matchRegex: + path: data["entrypoint.sh"] + pattern: "if ! command -v dockerize" + - matchRegex: + path: data["entrypoint.sh"] + pattern: "ERROR: dockerize config requires dockerize but it was not found" + - matchRegex: + path: data["entrypoint.sh"] + pattern: "Either install an image with dockerize or use configMapsToMount: sprig" + - matchRegex: + path: data["entrypoint.sh"] + pattern: "exit 1" + + - it: entrypoint script does not check for dockerize when configMapsToMount is both + template: templates/server-entrypoint-script.yaml + set: + server: + enabled: true + useEntrypointScript: true + configMapsToMount: "both" + asserts: + - notMatchRegex: + path: data["entrypoint.sh"] + pattern: "ERROR: dockerize config requires dockerize" + + - it: entrypoint script does not check for dockerize when configMapsToMount is sprig + template: templates/server-entrypoint-script.yaml + set: + server: + enabled: true + useEntrypointScript: true + configMapsToMount: "sprig" + asserts: + - notMatchRegex: + path: data["entrypoint.sh"] + pattern: "ERROR: dockerize config requires dockerize" + + # Test entrypoint script uses TEMPORAL_SERVICES variable + - it: entrypoint script references TEMPORAL_SERVICES environment variable + template: templates/server-entrypoint-script.yaml + set: + server: + enabled: true + useEntrypointScript: true + configMapsToMount: "both" + asserts: + - matchRegex: + path: data["entrypoint.sh"] + pattern: 'echo "Temporal entrypoint override - starting \$\{TEMPORAL_SERVICES\}"' + - matchRegex: + path: data["entrypoint.sh"] + pattern: '--service="\$\{TEMPORAL_SERVICES\}"' + + # Test all services get the same configuration + - it: applies entrypoint configuration to all server services + template: templates/server-deployment.yaml + set: + server: + enabled: true + useEntrypointScript: true + configMapsToMount: "both" + asserts: + - hasDocuments: + count: 4 # frontend, history, matching, worker (internalFrontend is disabled by default) + - equal: + path: spec.template.spec.containers[0].command + value: ["/entrypoint/entrypoint.sh"] + documentIndex: 0 + - equal: + path: spec.template.spec.containers[0].command + value: ["/entrypoint/entrypoint.sh"] + documentIndex: 1 + - equal: + path: spec.template.spec.containers[0].command + value: ["/entrypoint/entrypoint.sh"] + documentIndex: 2 + - equal: + path: spec.template.spec.containers[0].command + value: ["/entrypoint/entrypoint.sh"] + documentIndex: 3 diff --git a/charts/temporal/tests/server_entrypoint_variants_test.yaml b/charts/temporal/tests/server_entrypoint_variants_test.yaml new file mode 100644 index 00000000..072c68dc --- /dev/null +++ b/charts/temporal/tests/server_entrypoint_variants_test.yaml @@ -0,0 +1,425 @@ +suite: test server entrypoint and configmap variants +templates: + - server-deployment.yaml + - server-entrypoint-script.yaml + - server-dockerize-configmap.yaml + - server-sprig-configmap.yaml + - _helpers.tpl +release: + name: test-release + namespace: default +tests: + # Test 1: Default configuration (useEntrypointScript: false, configMapsToMount: dockerize) + - it: should use default configuration (no entrypoint script, dockerize only) + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: test-release-temporal-frontend + asserts: + # Should not have entrypoint override (uses image default) + - notExists: + path: spec.template.spec.containers[0].command + # Should mount only dockerize configmap + - contains: + path: spec.template.spec.volumes + content: + name: config-dockerize + configMap: + name: test-release-temporal-dockerize-config + # Should NOT mount sprig configmap + - notContains: + path: spec.template.spec.volumes + content: + name: config-sprig + # Should NOT mount entrypoint-script volume + - notContains: + path: spec.template.spec.volumes + content: + name: entrypoint-script + + - it: should not render entrypoint script with default configuration + template: templates/server-entrypoint-script.yaml + asserts: + - hasDocuments: + count: 0 + + - it: should render dockerize configmap with default configuration + template: templates/server-dockerize-configmap.yaml + asserts: + - hasDocuments: + count: 1 + - exists: + path: data["config_template.yaml"] + + - it: should not render sprig configmap with default configuration + template: templates/server-sprig-configmap.yaml + asserts: + - hasDocuments: + count: 0 + + # Test 2: useEntrypointScript: true, configMapsToMount: both + - it: should mount both configmaps when useEntrypointScript true and configMapsToMount both + set: + server: + useEntrypointScript: true + configMapsToMount: "both" + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: test-release-temporal-frontend + asserts: + # Should have entrypoint override + - equal: + path: spec.template.spec.containers[0].command[0] + value: /entrypoint/entrypoint.sh + # Should mount dockerize configmap + - contains: + path: spec.template.spec.volumes + content: + name: config-dockerize + configMap: + name: test-release-temporal-dockerize-config + # Should mount sprig configmap + - contains: + path: spec.template.spec.volumes + content: + name: config-sprig + configMap: + name: test-release-temporal-sprig-config + # Should mount entrypoint script + - contains: + path: spec.template.spec.volumes + content: + name: entrypoint-script + configMap: + name: test-release-temporal-entrypoint-script + defaultMode: 493 + + - it: should render entrypoint script when useEntrypointScript true and configMapsToMount both + set: + server: + useEntrypointScript: true + configMapsToMount: "both" + template: templates/server-entrypoint-script.yaml + asserts: + - hasDocuments: + count: 1 + - exists: + path: data["entrypoint.sh"] + - matchRegex: + path: data["entrypoint.sh"] + pattern: "if command -v dockerize" + + - it: should render both configmaps when useEntrypointScript true and configMapsToMount both + set: + server: + useEntrypointScript: true + configMapsToMount: "both" + template: templates/server-dockerize-configmap.yaml + asserts: + - hasDocuments: + count: 1 + + - it: should render sprig configmap when useEntrypointScript true and configMapsToMount both + set: + server: + useEntrypointScript: true + configMapsToMount: "both" + template: templates/server-sprig-configmap.yaml + asserts: + - hasDocuments: + count: 1 + - exists: + path: data["config_template.yaml"] + - matchRegex: + path: data["config_template.yaml"] + pattern: "# enable-template" + + # Test 3: useEntrypointScript: true, configMapsToMount: dockerize + - it: should mount only dockerize configmap when useEntrypointScript true and configMapsToMount dockerize + set: + server: + useEntrypointScript: true + configMapsToMount: "dockerize" + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: test-release-temporal-frontend + asserts: + # Should have entrypoint override + - equal: + path: spec.template.spec.containers[0].command[0] + value: /entrypoint/entrypoint.sh + # Should mount dockerize configmap + - contains: + path: spec.template.spec.volumes + content: + name: config-dockerize + configMap: + name: test-release-temporal-dockerize-config + # Should mount entrypoint script + - contains: + path: spec.template.spec.volumes + content: + name: entrypoint-script + configMap: + name: test-release-temporal-entrypoint-script + defaultMode: 493 + # Should NOT mount sprig configmap + - notContains: + path: spec.template.spec.volumes + content: + name: config-sprig + + - it: should render entrypoint script when useEntrypointScript true and configMapsToMount dockerize + set: + server: + useEntrypointScript: true + configMapsToMount: "dockerize" + template: templates/server-entrypoint-script.yaml + asserts: + - hasDocuments: + count: 1 + + - it: should render dockerize configmap when useEntrypointScript true and configMapsToMount dockerize + set: + server: + useEntrypointScript: true + configMapsToMount: "dockerize" + template: templates/server-dockerize-configmap.yaml + asserts: + - hasDocuments: + count: 1 + + - it: should not render sprig configmap when useEntrypointScript true and configMapsToMount dockerize + set: + server: + useEntrypointScript: true + configMapsToMount: "dockerize" + template: templates/server-sprig-configmap.yaml + asserts: + - hasDocuments: + count: 0 + + # Test 4: useEntrypointScript: true, configMapsToMount: sprig + - it: should mount only sprig configmap when useEntrypointScript true and configMapsToMount sprig + set: + server: + useEntrypointScript: true + configMapsToMount: "sprig" + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: test-release-temporal-frontend + asserts: + # Should have entrypoint override + - equal: + path: spec.template.spec.containers[0].command[0] + value: /entrypoint/entrypoint.sh + # Should mount sprig configmap + - contains: + path: spec.template.spec.volumes + content: + name: config-sprig + configMap: + name: test-release-temporal-sprig-config + # Should mount entrypoint script + - contains: + path: spec.template.spec.volumes + content: + name: entrypoint-script + configMap: + name: test-release-temporal-entrypoint-script + defaultMode: 493 + # Should NOT mount dockerize configmap + - notContains: + path: spec.template.spec.volumes + content: + name: config-dockerize + + - it: should render entrypoint script when useEntrypointScript true and configMapsToMount sprig + set: + server: + useEntrypointScript: true + configMapsToMount: "sprig" + template: templates/server-entrypoint-script.yaml + asserts: + - hasDocuments: + count: 1 + + - it: should not render dockerize configmap when useEntrypointScript true and configMapsToMount sprig + set: + server: + useEntrypointScript: true + configMapsToMount: "sprig" + template: templates/server-dockerize-configmap.yaml + asserts: + - hasDocuments: + count: 0 + + - it: should render sprig configmap when useEntrypointScript true and configMapsToMount sprig + set: + server: + useEntrypointScript: true + configMapsToMount: "sprig" + template: templates/server-sprig-configmap.yaml + asserts: + - hasDocuments: + count: 1 + + # Test 5: useEntrypointScript: false, configMapsToMount: both (both requires entrypoint, so falls back to dockerize) + - it: should mount both configmaps when useEntrypointScript false and configMapsToMount both + set: + server: + useEntrypointScript: false + configMapsToMount: "both" + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: test-release-temporal-frontend + asserts: + # Should not have entrypoint override + - notExists: + path: spec.template.spec.containers[0].command + # Should mount both configmaps + - contains: + path: spec.template.spec.volumes + content: + name: config-dockerize + configMap: + name: test-release-temporal-dockerize-config + - contains: + path: spec.template.spec.volumes + content: + name: config-sprig + configMap: + name: test-release-temporal-sprig-config + # Should NOT mount entrypoint-script volume + - notContains: + path: spec.template.spec.volumes + content: + name: entrypoint-script + + - it: should not render entrypoint script when useEntrypointScript false regardless of configMapsToMount + set: + server: + useEntrypointScript: false + configMapsToMount: "both" + template: templates/server-entrypoint-script.yaml + asserts: + - hasDocuments: + count: 0 + + # Test 6: useEntrypointScript: false, configMapsToMount: dockerize (default behavior) + - it: should mount only dockerize when useEntrypointScript false and configMapsToMount dockerize + set: + server: + useEntrypointScript: false + configMapsToMount: "dockerize" + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: test-release-temporal-frontend + asserts: + # Should not have entrypoint override + - notExists: + path: spec.template.spec.containers[0].command + # Should mount dockerize configmap + - contains: + path: spec.template.spec.volumes + content: + name: config-dockerize + configMap: + name: test-release-temporal-dockerize-config + # Should NOT mount sprig configmap + - notContains: + path: spec.template.spec.volumes + content: + name: config-sprig + # Should NOT mount entrypoint-script volume + - notContains: + path: spec.template.spec.volumes + content: + name: entrypoint-script + + - it: should render dockerize configmap when useEntrypointScript false and configMapsToMount dockerize + set: + server: + useEntrypointScript: false + configMapsToMount: "dockerize" + template: templates/server-dockerize-configmap.yaml + asserts: + - hasDocuments: + count: 1 + + - it: should not render sprig configmap when useEntrypointScript false and configMapsToMount dockerize + set: + server: + useEntrypointScript: false + configMapsToMount: "dockerize" + template: templates/server-sprig-configmap.yaml + asserts: + - hasDocuments: + count: 0 + + # Test 7: useEntrypointScript: false, configMapsToMount: sprig + - it: should mount only sprig when useEntrypointScript false and configMapsToMount sprig + set: + server: + useEntrypointScript: false + configMapsToMount: "sprig" + template: templates/server-deployment.yaml + documentSelector: + path: metadata.name + value: test-release-temporal-frontend + asserts: + # Should not have entrypoint override (uses image default) + - notExists: + path: spec.template.spec.containers[0].command + # Should mount sprig configmap + - contains: + path: spec.template.spec.volumes + content: + name: config-sprig + configMap: + name: test-release-temporal-sprig-config + # Should NOT mount dockerize configmap + - notContains: + path: spec.template.spec.volumes + content: + name: config-dockerize + # Should NOT mount entrypoint-script volume + - notContains: + path: spec.template.spec.volumes + content: + name: entrypoint-script + + - it: should not render entrypoint script when useEntrypointScript false and configMapsToMount sprig + set: + server: + useEntrypointScript: false + configMapsToMount: "sprig" + template: templates/server-entrypoint-script.yaml + asserts: + - hasDocuments: + count: 0 + + - it: should not render dockerize configmap when useEntrypointScript false and configMapsToMount sprig + set: + server: + useEntrypointScript: false + configMapsToMount: "sprig" + template: templates/server-dockerize-configmap.yaml + asserts: + - hasDocuments: + count: 0 + + - it: should render sprig configmap when useEntrypointScript false and configMapsToMount sprig + set: + server: + useEntrypointScript: false + configMapsToMount: "sprig" + template: templates/server-sprig-configmap.yaml + asserts: + - hasDocuments: + count: 1 diff --git a/charts/temporal/values.yaml b/charts/temporal/values.yaml index 3b0d5612..99bede05 100644 --- a/charts/temporal/values.yaml +++ b/charts/temporal/values.yaml @@ -22,6 +22,16 @@ server: repository: temporalio/server tag: 1.29.1 pullPolicy: IfNotPresent + # Use entrypoint script that detects dockerize and processes config if available + # Set to false to use the image's default entrypoint + useEntrypointScript: false + # Control which config ConfigMaps to mount + # Options: "both", "dockerize", "sprig" + # - "both": mounts both ConfigMaps (requires useEntrypointScript: true), auto-detects which to use based on dockerize presence + # - "dockerize": mounts only dockerize config (DEPRECATED - for old images with dockerize, use temporalio/server:1.29.x or earlier) + # - "sprig": mounts only sprig config (RECOMMENDED - for new images temporalio/server:1.30.0+, uses built-in sprig templating) + # We recommend upgrading to "sprig" config format for better security and smaller images + configMapsToMount: "dockerize" # Global default settings (can be overridden per service) replicaCount: 1 metrics: