{{- if .Capabilities.APIVersions.Has "apps/v1" }} apiVersion: apps/v1 {{- else }} apiVersion: apps/v1beta1 {{- end }} kind: StatefulSet metadata: name: {{ template "jenkins.fullname" . }} namespace: {{ template "jenkins.namespace" . }} labels: "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' {{- if .Values.renderHelmLabels }} "helm.sh/chart": "{{ template "jenkins.label" .}}" {{- end }} "app.kubernetes.io/managed-by": "{{ .Release.Service }}" "app.kubernetes.io/instance": "{{ .Release.Name }}" "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" {{- range $key, $val := .Values.controller.statefulSetLabels }} {{ $key }}: {{ $val | quote }} {{- end}} {{- if .Values.controller.statefulSetAnnotations }} annotations: {{ toYaml .Values.controller.statefulSetAnnotations | indent 4 }} {{- end }} spec: serviceName: {{ template "jenkins.fullname" . }} replicas: 1 selector: matchLabels: "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" "app.kubernetes.io/instance": "{{ .Release.Name }}" {{- if .Values.controller.updateStrategy }} updateStrategy: {{ toYaml .Values.controller.updateStrategy | indent 4 }} {{- end }} template: metadata: labels: "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' "app.kubernetes.io/managed-by": "{{ .Release.Service }}" "app.kubernetes.io/instance": "{{ .Release.Name }}" "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" {{- range $key, $val := .Values.controller.podLabels }} {{ $key }}: {{ $val | quote }} {{- end}} annotations: checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }} {{- if .Values.controller.initScripts }} checksum/config-init-scripts: {{ include (print $.Template.BasePath "/config-init-scripts.yaml") . | sha256sum }} {{- end }} {{- if .Values.controller.podAnnotations }} {{ tpl (toYaml .Values.controller.podAnnotations | indent 8) . }} {{- end }} spec: {{- if .Values.controller.schedulerName }} schedulerName: {{ .Values.controller.schedulerName }} {{- end }} {{- if .Values.controller.nodeSelector }} nodeSelector: {{ toYaml .Values.controller.nodeSelector | indent 8 }} {{- end }} {{- if .Values.controller.tolerations }} tolerations: {{ toYaml .Values.controller.tolerations | indent 8 }} {{- end }} {{- if .Values.controller.affinity }} affinity: {{ toYaml .Values.controller.affinity | indent 8 }} {{- end }} {{- if quote .Values.controller.terminationGracePeriodSeconds }} terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }} {{- end }} {{- if .Values.controller.priorityClassName }} priorityClassName: {{ .Values.controller.priorityClassName }} {{- end }} {{- if .Values.controller.shareProcessNamespace }} shareProcessNamespace: true {{- end }} {{- if .Values.controller.usePodSecurityContext }} securityContext: {{- if hasKey .Values.controller "podSecurityContextOverride" }} {{- tpl (toYaml .Values.controller.podSecurityContextOverride | nindent 8) . -}} {{- else }} {{/* The rest of this section should be replaced with the contents of this comment one the runAsUser, fsGroup, and securityContextCapabilities Helm chart values have been removed: runAsUser: 1000 fsGroup: 1000 runAsNonRoot: true */}} runAsUser: {{ default 0 .Values.controller.runAsUser }} {{- if and (.Values.controller.runAsUser) (.Values.controller.fsGroup) }} {{- if not (eq (int .Values.controller.runAsUser) 0) }} fsGroup: {{ .Values.controller.fsGroup }} runAsNonRoot: true {{- end }} {{- if .Values.controller.securityContextCapabilities }} capabilities: {{- toYaml .Values.controller.securityContextCapabilities | nindent 10 }} {{- end }} {{- end }} {{- end }} {{- end }} serviceAccountName: "{{ template "jenkins.serviceAccountName" . }}" {{- if .Values.controller.hostNetworking }} hostNetwork: true dnsPolicy: ClusterFirstWithHostNet {{- end }} {{- if .Values.controller.hostAliases }} hostAliases: {{- toYaml .Values.controller.hostAliases | nindent 8 }} {{- end }} initContainers: {{- if .Values.controller.customInitContainers }} {{ tpl (toYaml .Values.controller.customInitContainers) . | indent 8 }} {{- end }} {{- if .Values.controller.sidecars.configAutoReload.enabled }} {{- include "jenkins.configReloadContainer" (list $ "config-reload-init" "init") | nindent 8 }} {{- end}} - name: "init" image: "{{ .Values.controller.image }}:{{- include "controller.tag" . -}}" imagePullPolicy: "{{ .Values.controller.imagePullPolicy }}" {{- if .Values.controller.containerSecurityContext }} securityContext: {{- toYaml .Values.controller.containerSecurityContext | nindent 12 }} {{- end }} command: [ "sh", "/var/jenkins_config/apply_config.sh" ] {{- if .Values.controller.initContainerEnvFrom }} envFrom: {{ (tpl (toYaml .Values.controller.initContainerEnvFrom) .) | indent 12 }} {{- end }} {{- if .Values.controller.initContainerEnv }} env: {{ (tpl (toYaml .Values.controller.initContainerEnv) .) | indent 12 }} {{- end }} resources: {{- if .Values.controller.initContainerResources }} {{ toYaml .Values.controller.initContainerResources | indent 12 }} {{- else }} {{ toYaml .Values.controller.resources | indent 12 }} {{- end }} volumeMounts: {{- if .Values.persistence.mounts }} {{ toYaml .Values.persistence.mounts | indent 12 }} {{- end }} - mountPath: {{ .Values.controller.jenkinsHome }} name: jenkins-home {{- if .Values.persistence.subPath }} subPath: {{ .Values.persistence.subPath }} {{- end }} - mountPath: /var/jenkins_config name: jenkins-config {{- if .Values.controller.installPlugins }} {{- if .Values.controller.overwritePluginsFromImage }} - mountPath: {{ .Values.controller.jenkinsRef }}/plugins name: plugins {{- end }} - mountPath: /var/jenkins_plugins name: plugin-dir - mountPath: /tmp name: tmp-volume {{- end }} {{- if or .Values.controller.initScripts .Values.controller.initConfigMap }} - mountPath: {{ .Values.controller.jenkinsHome }}/init.groovy.d name: init-scripts {{- end }} {{- if and .Values.controller.httpsKeyStore.enable (not .Values.controller.httpsKeyStore.disableSecretMount) }} {{- $httpsJKSDirPath := printf "%s" .Values.controller.httpsKeyStore.path }} - mountPath: {{ $httpsJKSDirPath }} name: jenkins-https-keystore {{- end }} containers: - name: jenkins image: "{{ .Values.controller.image }}:{{- include "controller.tag" . -}}" imagePullPolicy: "{{ .Values.controller.imagePullPolicy }}" {{- if .Values.controller.containerSecurityContext }} securityContext: {{- toYaml .Values.controller.containerSecurityContext | nindent 12 }} {{- end }} {{- if .Values.controller.overrideArgs }} args: [ {{- range $overrideArg := .Values.controller.overrideArgs }} "{{- tpl $overrideArg $ }}", {{- end }} ] {{- else if .Values.controller.httpsKeyStore.enable }} {{- $httpsJKSFilePath := printf "%s/%s" .Values.controller.httpsKeyStore.path .Values.controller.httpsKeyStore.fileName }} args: [ "--httpPort={{.Values.controller.httpsKeyStore.httpPort}}", "--httpsPort={{.Values.controller.targetPort}}", '--httpsKeyStore={{ $httpsJKSFilePath }}', "--httpsKeyStorePassword=$(JENKINS_HTTPS_KEYSTORE_PASSWORD)" ] {{- else }} args: [ "--httpPort={{.Values.controller.targetPort}}"] {{- end }} {{- if .Values.controller.lifecycle }} lifecycle: {{ toYaml .Values.controller.lifecycle | indent 12 }} {{- end }} {{- if .Values.controller.terminationMessagePath }} terminationMessagePath: {{ .Values.controller.terminationMessagePath }} {{- end }} {{- if .Values.controller.terminationMessagePolicy }} terminationMessagePolicy: {{ .Values.controller.terminationMessagePolicy }} {{- end }} {{- if .Values.controller.containerEnvFrom }} envFrom: {{ (tpl ( toYaml .Values.controller.containerEnvFrom) .) | indent 12 }} {{- end }} env: {{- if .Values.controller.containerEnv }} {{ (tpl ( toYaml .Values.controller.containerEnv) .) | indent 12 }} {{- end }} {{- if or .Values.controller.additionalSecrets .Values.controller.existingSecret .Values.controller.additionalExistingSecrets .Values.controller.adminSecret }} - name: SECRETS value: /run/secrets/additional {{- end }} - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: JAVA_OPTS value: >- {{ if .Values.controller.sidecars.configAutoReload.enabled }} -Dcasc.reload.token=$(POD_NAME) {{ end }}{{ default "" .Values.controller.javaOpts }} - name: JENKINS_OPTS value: >- {{ if .Values.controller.jenkinsUriPrefix }}--prefix={{ .Values.controller.jenkinsUriPrefix }} {{ end }} --webroot=/var/jenkins_cache/war {{ default "" .Values.controller.jenkinsOpts}} - name: JENKINS_SLAVE_AGENT_PORT value: "{{ .Values.controller.agentListenerPort }}" {{- if .Values.controller.httpsKeyStore.enable }} - name: JENKINS_HTTPS_KEYSTORE_PASSWORD {{- if not .Values.controller.httpsKeyStore.disableSecretMount }} valueFrom: secretKeyRef: name: {{ if .Values.controller.httpsKeyStore.jenkinsHttpsJksPasswordSecretName }} {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksPasswordSecretName }} {{ else if .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ else }} {{ template "jenkins.fullname" . }}-https-jks {{ end }} key: "{{ .Values.controller.httpsKeyStore.jenkinsHttpsJksPasswordSecretKey }}" {{- else }} value: {{ .Values.controller.httpsKeyStore.password }} {{- end }} {{- end }} - name: CASC_JENKINS_CONFIG value: {{ .Values.controller.sidecars.configAutoReload.folder | default (printf "%s/casc_configs" (.Values.controller.jenkinsRef)) }}{{- if .Values.controller.JCasC.configUrls }},{{ join "," .Values.controller.JCasC.configUrls }}{{- end }} ports: {{- if .Values.controller.httpsKeyStore.enable }} - containerPort: {{.Values.controller.httpsKeyStore.httpPort}} {{- else }} - containerPort: {{.Values.controller.targetPort}} {{- end }} name: http - containerPort: {{ .Values.controller.agentListenerPort }} name: agent-listener {{- if .Values.controller.agentListenerHostPort }} hostPort: {{ .Values.controller.agentListenerHostPort }} {{- end }} {{- if .Values.controller.jmxPort }} - containerPort: {{ .Values.controller.jmxPort }} name: jmx {{- end }} {{- range $index, $port := .Values.controller.extraPorts }} - containerPort: {{ $port.port }} name: {{ $port.name }} {{- end }} {{- if and .Values.controller.healthProbes .Values.controller.probes}} {{- if semverCompare ">=1.16-0" .Capabilities.KubeVersion.GitVersion }} startupProbe: {{ tpl (toYaml .Values.controller.probes.startupProbe | indent 12) .}} {{- end }} livenessProbe: {{ tpl (toYaml .Values.controller.probes.livenessProbe | indent 12) .}} readinessProbe: {{ tpl (toYaml .Values.controller.probes.readinessProbe | indent 12) .}} {{- end }} resources: {{ toYaml .Values.controller.resources | indent 12 }} volumeMounts: {{- if .Values.persistence.mounts }} {{ toYaml .Values.persistence.mounts | indent 12 }} {{- end }} {{- if and .Values.controller.httpsKeyStore.enable (not .Values.controller.httpsKeyStore.disableSecretMount) }} {{- $httpsJKSDirPath := printf "%s" .Values.controller.httpsKeyStore.path }} - mountPath: {{ $httpsJKSDirPath }} name: jenkins-https-keystore {{- end }} - mountPath: {{ .Values.controller.jenkinsHome }} name: jenkins-home readOnly: false {{- if .Values.persistence.subPath }} subPath: {{ .Values.persistence.subPath }} {{- end }} - mountPath: /var/jenkins_config name: jenkins-config readOnly: true {{- if .Values.controller.installPlugins }} - mountPath: {{ .Values.controller.jenkinsRef }}/plugins/ name: plugin-dir readOnly: false {{- end }} {{- if or .Values.controller.initScripts .Values.controller.initConfigMap }} - mountPath: {{ .Values.controller.jenkinsHome }}/init.groovy.d name: init-scripts {{- end }} {{- if .Values.controller.sidecars.configAutoReload.enabled }} - name: sc-config-volume mountPath: {{ .Values.controller.sidecars.configAutoReload.folder | default (printf "%s/casc_configs" (.Values.controller.jenkinsRef)) }} {{- end }} {{- if or .Values.controller.additionalSecrets .Values.controller.existingSecret .Values.controller.additionalExistingSecrets .Values.controller.adminSecret }} - name: jenkins-secrets mountPath: /run/secrets/additional readOnly: true {{- end }} - name: jenkins-cache mountPath: /var/jenkins_cache - mountPath: /tmp name: tmp-volume {{- if .Values.controller.sidecars.configAutoReload.enabled }} {{- include "jenkins.configReloadContainer" (list $ "config-reload" "sidecar") | nindent 8 }} {{- end}} {{- if .Values.controller.sidecars.other}} {{ tpl (toYaml .Values.controller.sidecars.other | indent 8) .}} {{- end }} volumes: {{- if .Values.persistence.volumes }} {{ tpl (toYaml .Values.persistence.volumes | indent 6) . }} {{- end }} {{- if .Values.controller.installPlugins }} {{- if .Values.controller.overwritePluginsFromImage }} - name: plugins emptyDir: {} {{- end }} {{- end }} {{- if and .Values.controller.initScripts .Values.controller.initConfigMap }} - name: init-scripts projected: sources: - configMap: name: {{ template "jenkins.fullname" . }}-init-scripts - configMap: name: {{ .Values.controller.initConfigMap }} {{- else if .Values.controller.initConfigMap }} - name: init-scripts configMap: name: {{ .Values.controller.initConfigMap }} {{- else if .Values.controller.initScripts }} - name: init-scripts configMap: name: {{ template "jenkins.fullname" . }}-init-scripts {{- end }} - name: jenkins-config configMap: name: {{ template "jenkins.fullname" . }} {{- if .Values.controller.installPlugins }} - name: plugin-dir emptyDir: {} {{- end }} {{- if or .Values.controller.additionalSecrets .Values.controller.existingSecret .Values.controller.additionalExistingSecrets .Values.controller.adminSecret }} - name: jenkins-secrets projected: sources: {{- if .Values.controller.additionalSecrets }} - secret: name: {{ template "jenkins.fullname" . }}-additional-secrets {{- end }} {{- if .Values.controller.additionalExistingSecrets }} {{- range $key, $value := .Values.controller.additionalExistingSecrets }} - secret: name: {{ tpl $value.name $ }} items: - key: {{ tpl $value.keyName $ }} path: {{ tpl $value.name $ }}-{{ tpl $value.keyName $ }} {{- end }} {{- end }} {{- if .Values.controller.adminSecret }} - secret: name: {{ .Values.controller.admin.existingSecret | default (include "jenkins.fullname" .) }} items: - key: {{ .Values.controller.admin.userKey | default "jenkins-admin-user" }} path: chart-admin-username - key: {{ .Values.controller.admin.passwordKey | default "jenkins-admin-password" }} path: chart-admin-password {{- end }} {{- if .Values.controller.existingSecret }} - secret: name: {{ .Values.controller.existingSecret }} {{- end }} {{- end }} - name: jenkins-cache emptyDir: {} {{- if not (contains "jenkins-home" (quote .Values.persistence.volumes)) }} - name: jenkins-home {{- if .Values.persistence.enabled }} persistentVolumeClaim: claimName: {{ .Values.persistence.existingClaim | default (include "jenkins.fullname" .) }} {{- else }} emptyDir: {} {{- end -}} {{- end }} - name: sc-config-volume emptyDir: {} - name: tmp-volume emptyDir: {} {{- if and .Values.controller.httpsKeyStore.enable (not .Values.controller.httpsKeyStore.disableSecretMount) }} - name: jenkins-https-keystore secret: secretName: {{ if .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ else }} {{ template "jenkins.fullname" . }}-https-jks {{ end }} items: - key: {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretKey }} path: {{ .Values.controller.httpsKeyStore.fileName }} {{- end }} {{- if .Values.controller.imagePullSecretName }} imagePullSecrets: - name: {{ .Values.controller.imagePullSecretName }} {{- end -}}