apiVersion: apps/v1 kind: StatefulSet metadata: name: {{ template "artifactory-ha.node.name" . }} labels: app: {{ template "artifactory-ha.name" . }} chart: {{ template "artifactory-ha.chart" . }} component: {{ .Values.artifactory.name }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} force-update: "{{ randAlpha 63 | lower }}" {{- if .Values.artifactory.node.labels }} {{ toYaml .Values.artifactory.node.labels | indent 4 }} {{- end }} spec: serviceName: {{ template "artifactory-ha.node.name" . }} replicas: {{ .Values.artifactory.node.replicaCount }} updateStrategy: type: RollingUpdate selector: matchLabels: app: {{ template "artifactory-ha.name" . }} role: {{ template "artifactory-ha.node.name" . }} release: {{ .Release.Name }} template: metadata: labels: app: {{ template "artifactory-ha.name" . }} chart: {{ template "artifactory-ha.chart" . }} role: {{ template "artifactory-ha.node.name" . }} heritage: {{ .Release.Service }} component: {{ .Values.artifactory.name }} release: {{ .Release.Name }} annotations: checksum/binarystore: {{ include (print $.Template.BasePath "/artifactory-binarystore-secret.yaml") . | sha256sum }} checksum/systemyaml: {{ include (print $.Template.BasePath "/artifactory-system-yaml.yaml") . | sha256sum }} {{- range $key, $value := .Values.artifactory.annotations }} {{ $key }}: {{ $value | quote }} {{- end }} spec: {{- if .Values.artifactory.priorityClass.existingPriorityClass }} priorityClassName: {{ .Values.artifactory.priorityClass.existingPriorityClass }} {{- else -}} {{- if .Values.artifactory.priorityClass.create }} priorityClassName: {{ default (include "artifactory-ha.fullname" .) .Values.artifactory.priorityClass.name }} {{- end }} {{- end }} serviceAccountName: {{ template "artifactory-ha.serviceAccountName" . }} terminationGracePeriodSeconds: {{ .Values.artifactory.terminationGracePeriodSeconds }} {{- if .Values.imagePullSecrets }} imagePullSecrets: - name: {{ .Values.imagePullSecrets }} {{- end }} securityContext: runAsUser: {{ .Values.artifactory.uid }} fsGroup: {{ .Values.artifactory.uid }} initContainers: {{- if .Values.artifactory.customInitContainersBegin }} {{ tpl .Values.artifactory.customInitContainersBegin . | indent 6 }} {{- end }} {{- if .Values.artifactory.persistence.enabled }} {{- if eq .Values.artifactory.persistence.type "file-system" }} {{- if .Values.artifactory.persistence.fileSystem.existingSharedClaim.enabled }} - name: "create-artifactory-data-dir" image: "{{ .Values.initContainerImage }}" imagePullPolicy: {{ .Values.artifactory.image.pullPolicy }} resources: {{ toYaml .Values.initContainers.resources | indent 10 }} command: - 'sh' - '-c' - > mkdir -p {{ tpl .Values.artifactory.persistence.fileSystem.existingSharedClaim.dataDir . }}; volumeMounts: - mountPath: {{ .Values.artifactory.persistence.mountPath | quote }} name: volume {{- end }} {{- end }} {{- if .Values.artifactory.deleteDBPropertiesOnStartup }} - name: "delete-db-properties" image: "{{ .Values.initContainerImage }}" imagePullPolicy: {{ .Values.artifactory.image.pullPolicy }} resources: {{ toYaml .Values.initContainers.resources | indent 10 }} command: - 'sh' - '-c' - 'rm -fv {{ .Values.artifactory.persistence.mountPath }}/etc/db.properties' volumeMounts: - mountPath: {{ .Values.artifactory.persistence.mountPath | quote }} name: volume {{- end }} - name: "remove-lost-found" image: "{{ .Values.initContainerImage }}" imagePullPolicy: {{ .Values.artifactory.image.pullPolicy }} resources: {{ toYaml .Values.initContainers.resources | indent 10 }} command: - 'sh' - '-c' - > rm -rfv {{ .Values.artifactory.persistence.mountPath }}/lost+found volumeMounts: - mountPath: {{ .Values.artifactory.persistence.mountPath | quote }} name: volume {{- end }} - name: 'copy-system-yaml' image: '{{ .Values.initContainerImage }}' command: - '/bin/sh' - '-c' - > {{- if .Values.artifactory.node.waitForPrimaryStartup.enabled }} echo "Sleeping to allow time for primary node to come up"; sleep {{ .Values.artifactory.node.waitForPrimaryStartup.seconds }}; {{- end }} echo "Copy system.yaml to {{ .Values.artifactory.persistence.mountPath }}/etc"; mkdir -p {{ .Values.artifactory.persistence.mountPath }}/etc; mkdir -p {{ .Values.artifactory.persistence.mountPath }}/etc/access/keys/trusted; cp -fv /tmp/etc/system.yaml {{ .Values.artifactory.persistence.mountPath }}/etc/system.yaml; echo "Remove {{ .Values.artifactory.persistence.mountPath }}/lost+found folder if exists"; rm -rfv {{ .Values.artifactory.persistence.mountPath }}/lost+found; volumeMounts: - name: volume mountPath: {{ .Values.artifactory.persistence.mountPath | quote }} - name: systemyaml mountPath: "/tmp/etc/system.yaml" subPath: system.yaml {{- if .Values.artifactory.customPersistentPodVolumeClaim }} - name: "prepare-custom-persistent-volume" image: "{{ .Values.initContainerImage }}" command: - 'sh' - '-c' - > chown -Rv {{ .Values.artifactory.uid }}:{{ .Values.artifactory.uid }} {{ .Values.artifactory.customPersistentPodVolumeClaim.mountPath }} securityContext: runAsUser: 0 volumeMounts: - name: {{ .Values.artifactory.customPersistentPodVolumeClaim.name }} mountPath: {{ .Values.artifactory.customPersistentPodVolumeClaim.mountPath }} {{- end }} {{- if .Values.waitForDatabase }} {{- if or .Values.postgresql.enabled }} - name: "wait-for-db" image: "{{ .Values.initContainerImage }}" resources: {{ toYaml .Values.initContainers.resources | indent 10 }} command: - 'sh' - '-c' - > until nc -z -w 2 {{ .Release.Name }}-postgresql {{ .Values.postgresql.service.port }} && echo database ok; do sleep 2; done; {{- end }} {{- end }} {{- if .Values.artifactory.customInitContainers }} {{ tpl .Values.artifactory.customInitContainers . | indent 6 }} {{- end }} containers: - name: {{ .Values.artifactory.name }} image: '{{ .Values.artifactory.image.repository }}:{{ default .Chart.AppVersion .Values.artifactory.image.version }}' imagePullPolicy: {{ .Values.artifactory.image.pullPolicy }} securityContext: allowPrivilegeEscalation: false command: - '/bin/sh' - '-c' - > {{- if .Values.artifactory.userPluginSecrets }} echo "Copying plugins"; cp -Lrf /tmp/plugin/*/* /tmp/plugins; {{- end }} {{- if .Values.artifactory.preStartCommand }} echo "Running custom preStartCommand command"; {{ tpl .Values.artifactory.preStartCommand . }}; {{- end }} /entrypoint-artifactory.sh lifecycle: postStart: exec: command: - '/bin/sh' - '-c' - > echo; {{- if .Values.artifactory.postStartCommand }} {{ .Values.artifactory.postStartCommand }} {{- end }} env: {{- if .Values.database.secrets.user }} - name: JF_SHARED_DATABSE_USERNAME valueFrom: secretKeyRef: name: {{ .Values.database.secrets.user.name }} key: {{ .Values.database.secrets.user.key }} {{- end }} {{- if .Values.database.secrets.password }} - name: JF_SHARED_DATABASE_PASSWORD valueFrom: secretKeyRef: name: {{ .Values.database.secrets.password.name }} key: {{ .Values.database.secrets.password.key }} {{- end }} {{- if .Values.database.secrets.url }} - name: JF_SHARED_DATABSE_URL valueFrom: secretKeyRef: name: {{ .Values.database.secrets.url.name }} key: {{ .Values.database.secrets.url.key }} {{- end }} - name: JF_SHARED_NODE_PRIMARY value: "false" - name: JF_SHARED_NODE_HAENABLED value: "true" - name: JF_SHARED_DATABSE_USERNAME value: "artifactory" - name: JF_SHARED_DATABASE_PASSWORD valueFrom: secretKeyRef: name: {{ .Release.Name }}-postgresql key: postgresql-password ports: - containerPort: {{ .Values.artifactory.internalPort }} - containerPort: {{ .Values.artifactory.internalArtifactoryPort }} {{- if .Values.artifactory.node.javaOpts.jmx.enabled }} - containerPort: {{ .Values.artifactory.node.javaOpts.jmx.port }} {{- end }} volumeMounts: {{- if .Values.artifactory.customPersistentVolumeClaim }} - name: {{ .Values.artifactory.customPersistentVolumeClaim.name }} mountPath: {{ .Values.artifactory.customPersistentVolumeClaim.mountPath }} {{- end }} {{- if .Values.artifactory.customPersistentPodVolumeClaim }} - name: {{ .Values.artifactory.customPersistentPodVolumeClaim.name }} mountPath: {{ .Values.artifactory.customPersistentPodVolumeClaim.mountPath }} {{- end }} {{- if .Values.artifactory.userPluginSecrets }} - name: tmp-plugins mountPath: "/tmp/plugins/" {{- range .Values.artifactory.userPluginSecrets }} - name: {{ tpl . $ }} mountPath: "/tmp/plugin/{{ tpl . $ }}" {{- end }} {{- end }} - name: volume mountPath: "{{ .Values.artifactory.persistence.mountPath }}" {{- if eq .Values.artifactory.persistence.type "file-system" }} {{- if .Values.artifactory.persistence.fileSystem.existingSharedClaim.enabled }} {{- range $sharedClaimNumber, $e := until (.Values.artifactory.persistence.fileSystem.existingSharedClaim.numberOfExistingClaims|int) }} - name: artifactory-ha-data-{{ $sharedClaimNumber }} mountPath: "{{ tpl $.Values.artifactory.persistence.fileSystem.existingSharedClaim.dataDir $ }}/filestore{{ $sharedClaimNumber }}" {{- end }} - name: artifactory-ha-backup mountPath: "{{ $.Values.artifactory.persistence.fileSystem.existingSharedClaim.backupDir }}" {{- end }} {{- end }} {{- if eq .Values.artifactory.persistence.type "nfs" }} - name: artifactory-ha-data mountPath: "{{ .Values.artifactory.persistence.nfs.dataDir }}" - name: artifactory-ha-backup mountPath: "{{ .Values.artifactory.persistence.nfs.backupDir }}" {{- else }} {{- if .Values.artifactory.binarystore.enabled }} - name: binarystore-xml mountPath: "/artifactory_extra_conf/binarystore.xml" subPath: binarystore.xml {{- end }} {{- end }} - name: installer-info mountPath: "/artifactory_extra_conf/info/installer-info.json" subPath: installer-info.json {{- if .Values.artifactory.customVolumeMounts }} {{ tpl .Values.artifactory.customVolumeMounts . | indent 8 }} {{- end }} resources: {{ toYaml .Values.artifactory.node.resources | indent 10 }} {{- if .Values.artifactory.readinessProbe.enabled }} readinessProbe: httpGet: path: {{ .Values.artifactory.readinessProbe.path }} port: {{ .Values.artifactory.internalPort }} initialDelaySeconds: {{ .Values.artifactory.readinessProbe.initialDelaySeconds }} periodSeconds: {{ .Values.artifactory.readinessProbe.periodSeconds }} timeoutSeconds: {{ .Values.artifactory.readinessProbe.timeoutSeconds }} failureThreshold: {{ .Values.artifactory.readinessProbe.failureThreshold }} successThreshold: {{ .Values.artifactory.readinessProbe.successThreshold }} {{- end }} {{- if .Values.artifactory.livenessProbe.enabled }} livenessProbe: httpGet: path: {{ .Values.artifactory.livenessProbe.path }} port: {{ .Values.artifactory.internalPort }} initialDelaySeconds: {{ .Values.artifactory.livenessProbe.initialDelaySeconds }} periodSeconds: {{ .Values.artifactory.livenessProbe.periodSeconds }} timeoutSeconds: {{ .Values.artifactory.livenessProbe.timeoutSeconds }} failureThreshold: {{ .Values.artifactory.livenessProbe.failureThreshold }} successThreshold: {{ .Values.artifactory.livenessProbe.successThreshold }} {{- end }} {{- $image := .Values.logger.image.repository }} {{- $tag := .Values.logger.image.tag }} {{- $mountPath := .Values.artifactory.persistence.mountPath }} {{- range .Values.artifactory.loggers }} - name: {{ . | replace "_" "-" | replace "." "-" }} image: '{{ $image }}:{{ $tag }}' command: - tail args: - '-F' - '{{ $mountPath }}/logs/{{ . }}' volumeMounts: - name: volume mountPath: {{ $mountPath }} {{- end }} {{ if .Values.artifactory.catalinaLoggers }} {{- range .Values.artifactory.catalinaLoggers }} - name: {{ . | replace "_" "-" | replace "." "-" }} image: '{{ $image }}:{{ $tag }}' command: - 'sh' - '-c' - 'sh /scripts/tail-log.sh {{ $mountPath }}/logs/catalina {{ . }}' volumeMounts: - name: volume mountPath: {{ $mountPath }} - name: catalina-logger mountPath: /scripts/tail-log.sh subPath: tail-log.sh {{- end }} {{- end }} {{- if .Values.filebeat.enabled }} - name: {{ .Values.filebeat.name }} image: "{{ .Values.filebeat.image.repository }}:{{ .Values.filebeat.image.version }}" imagePullPolicy: {{ .Values.filebeat.image.pullPolicy }} args: - "-e" - "-E" - "http.enabled=true" securityContext: runAsUser: 0 volumeMounts: - name: filebeat-config mountPath: /usr/share/filebeat/filebeat.yml readOnly: true subPath: filebeat.yml - name: volume mountPath: "{{ .Values.artifactory.persistence.mountPath }}" livenessProbe: {{ toYaml .Values.filebeat.livenessProbe | indent 10 }} readinessProbe: {{ toYaml .Values.filebeat.readinessProbe | indent 10 }} resources: {{ toYaml .Values.filebeat.resources | indent 10 }} terminationGracePeriodSeconds: {{ .Values.terminationGracePeriod }} {{- end }} {{- if .Values.artifactory.customSidecarContainers }} {{ tpl .Values.artifactory.customSidecarContainers . | indent 6 }} {{- end }} {{- with .Values.artifactory.node.nodeSelector }} nodeSelector: {{ toYaml . | indent 8 }} {{- end }} {{- if .Values.artifactory.node.affinity }} {{- with .Values.artifactory.node.affinity }} affinity: {{ toYaml . | indent 8 }} {{- end }} {{- else if eq .Values.artifactory.node.podAntiAffinity.type "soft" }} affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: topologyKey: {{ .Values.artifactory.node.podAntiAffinity.topologyKey }} labelSelector: matchLabels: app: {{ template "artifactory-ha.name" . }} release: {{ .Release.Name }} {{- if eq .Values.artifactory.service.pool "members" }} role: {{ template "artifactory-ha.node.name" . }} {{- end }} {{- else if eq .Values.artifactory.node.podAntiAffinity.type "hard" }} affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - topologyKey: {{ .Values.artifactory.node.podAntiAffinity.topologyKey }} labelSelector: matchLabels: app: {{ template "artifactory-ha.name" . }} release: {{ .Release.Name }} {{- if eq .Values.artifactory.service.pool "members" }} role: {{ template "artifactory-ha.node.name" . }} {{- end }} {{- end }} {{- with .Values.artifactory.node.tolerations }} tolerations: {{ toYaml . | indent 8 }} {{- end }} volumes: {{- if .Values.artifactory.binarystore.enabled }} - name: binarystore-xml secret: {{- if .Values.artifactory.persistence.customBinarystoreXmlSecret }} secretName: {{ .Values.artifactory.persistence.customBinarystoreXmlSecret }} {{- else }} secretName: {{ template "artifactory-ha.fullname" . }}-binarystore {{- end }} {{- end }} - name: installer-info configMap: name: {{ template "artifactory-ha.fullname" . }}-installer-info {{- if .Values.artifactory.userPluginSecrets }} - name: tmp-plugins emptyDir: {} {{- range .Values.artifactory.userPluginSecrets }} - name: {{ tpl . $ }} secret: secretName: {{ tpl . $ }} {{- end }} {{- end }} {{- if .Values.artifactory.catalinaLoggers }} - name: catalina-logger configMap: name: {{ template "artifactory-ha.fullname" . }}-catalina-logger {{- end }} {{- if .Values.artifactory.configMaps }} - name: artifactory-configmaps configMap: name: {{ template "artifactory-ha.fullname" . }}-configmaps {{- end }} {{- if eq .Values.artifactory.persistence.type "file-system" }} {{- if .Values.artifactory.persistence.fileSystem.existingSharedClaim.enabled }} {{- range $sharedClaimNumber, $e := until (.Values.artifactory.persistence.fileSystem.existingSharedClaim.numberOfExistingClaims|int) }} - name: artifactory-ha-data-{{ $sharedClaimNumber }} persistentVolumeClaim: claimName: {{ template "artifactory-ha.fullname" $ }}-data-pvc-{{ $sharedClaimNumber }} {{- end }} - name: artifactory-ha-backup persistentVolumeClaim: claimName: {{ template "artifactory-ha.fullname" $ }}-backup-pvc {{- end }} {{- end }} {{- if eq .Values.artifactory.persistence.type "nfs" }} - name: artifactory-ha-data persistentVolumeClaim: claimName: {{ template "artifactory-ha.fullname" . }}-data-pvc - name: artifactory-ha-backup persistentVolumeClaim: claimName: {{ template "artifactory-ha.fullname" . }}-backup-pvc {{- end }} - name: systemyaml secret: secretName: {{ template "artifactory-ha.primary.name" . }}-system-yaml {{- if .Values.artifactory.customPersistentVolumeClaim }} - name: {{ .Values.artifactory.customPersistentVolumeClaim.name }} persistentVolumeClaim: claimName: {{ .Values.artifactory.customPersistentVolumeClaim.name }} {{- end }} {{- if .Values.filebeat.enabled }} - name: filebeat-config configMap: name: {{ template "artifactory-ha.fullname" . }}-filebeat-config {{- end }} {{- if .Values.artifactory.customVolumes }} {{ tpl .Values.artifactory.customVolumes . | indent 6 }} {{- end }} {{- if not .Values.artifactory.persistence.enabled }} - name: volume emptyDir: sizeLimit: {{ .Values.artifactory.persistence.size }} {{- end }} volumeClaimTemplates: {{- if .Values.artifactory.persistence.enabled }} - metadata: name: volume {{- if not .Values.artifactory.node.persistence.existingClaim }} spec: {{- if .Values.artifactory.persistence.storageClassName }} {{- if (eq "-" .Values.artifactory.persistence.storageClassName) }} storageClassName: "" {{- else }} storageClassName: "{{ .Values.artifactory.persistence.storageClassName }}" {{- end }} {{- end }} accessModes: [ "{{ .Values.artifactory.persistence.accessMode }}" ] resources: requests: storage: {{ .Values.artifactory.persistence.size }} {{- end }} {{- end }} {{- if .Values.artifactory.customPersistentPodVolumeClaim }} - metadata: name: {{ .Values.artifactory.customPersistentPodVolumeClaim.name }} spec: {{- if .Values.artifactory.customPersistentPodVolumeClaim.storageClassName }} {{- if (eq "-" .Values.artifactory.customPersistentPodVolumeClaim.storageClassName) }} storageClassName: "" {{- else }} storageClassName: "{{ .Values.artifactory.customPersistentPodVolumeClaim.storageClassName }}" {{- end }} {{- end }} accessModes: {{- range .Values.artifactory.customPersistentPodVolumeClaim.accessModes }} - {{ . | quote }} {{- end }} resources: requests: storage: {{ .Values.artifactory.customPersistentPodVolumeClaim.size }} {{- end }}