# _helpers.tpl
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "dask.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "dask.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "dask.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
 # dask-jupyter-config.yaml
{{ if .Values.jupyter.enabled -}}
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ template "dask.fullname" . }}-jupyter-config
  labels:
    app: {{ template "dask.name" . }}
    heritage: {{ .Release.Service | quote }}
    release: {{ .Release.Name | quote }}
    chart: {{ template "dask.chart" . }}
    component: jupyter
data:
  jupyter_notebook_config.py: |
    c = get_config()
    c.NotebookApp.password = '{{ .Values.jupyter.password }}'

{{ end }}
 # dask-jupyter-deployment.yaml
{{ if .Values.jupyter.enabled -}}

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ template "dask.fullname" . }}-jupyter
  labels:
    app: {{ template "dask.name" . }}
    heritage: {{ .Release.Service | quote }}
    release: {{ .Release.Name | quote }}
    chart: {{ template "dask.chart" . }}
    component: jupyter
spec:
  replicas: {{ .Values.jupyter.replicas }}
  selector:
    matchLabels:
      app: {{ template "dask.name" . }}
      release: {{ .Release.Name | quote }}
      component: jupyter
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: {{ template "dask.name" . }}
        release: {{ .Release.Name | quote }}
        component: jupyter
    spec:
      imagePullSecrets:
        {{- toYaml .Values.jupyter.image.pullSecrets | nindent 8 }}
      containers:
        - name: {{ template "dask.fullname" . }}-jupyter
          image: "{{ .Values.jupyter.image.repository }}:{{ .Values.jupyter.image.tag }}"
          imagePullPolicy: {{ .Values.jupyter.image.pullPolicy }}
          ports:
            - containerPort: 8888
          resources:
            {{- toYaml .Values.jupyter.resources | nindent 12 }}
          volumeMounts:
            - name: config-volume
              mountPath: /home/jovyan/.jupyter
          env:
            - name: DASK_SCHEDULER_ADDRESS
              value: {{ template "dask.fullname" . }}-scheduler:{{ .Values.scheduler.servicePort }}
          {{- if .Values.jupyter.env }}
            {{- toYaml .Values.jupyter.env | nindent 12 }}
          {{- end }}
      nodeSelector:
        {{- toYaml .Values.jupyter.nodeSelector | nindent 8 }}
      volumes:
        - name: config-volume
          configMap:
            name: {{ template "dask.fullname" . }}-jupyter-config
    {{- with .Values.jupyter.nodeSelector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
    {{- end }}
    {{- with .Values.jupyter.affinity }}
      affinity:
        {{- toYaml . | nindent 8 }}
    {{- end }}
    {{- with .Values.jupyter.tolerations }}
      tolerations:
        {{- toYaml . | nindent 8 }}
    {{- end }}
{{- end }}
 # dask-jupyter-ingress.yaml
{{- if .Values.jupyter.ingress.enabled -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{ template "dask.fullname" . }}-jupyter
  labels:
    app: {{ template "dask.fullname" . }}-jupyter
    chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    release: "{{ .Release.Name }}"
    heritage: "{{ .Release.Service }}"
  annotations:
{{ toYaml .Values.jupyter.ingress.annotations | indent 4 }}
spec:
{{- if .Values.jupyter.ingress.tls }}
  tls:
    - hosts:
      - {{ .Values.jupyter.ingress.hostname | quote }}
      secretName: {{ .Values.jupyter.ingress.secretName | default (printf "%s-jupyter-tls" (include "dask.fullname" .)) }}
{{- end }}
  rules:
  - host: {{ .Values.jupyter.ingress.hostname }}
    http:
      paths:
      - backend:
          serviceName: {{ template "dask.fullname" . }}-jupyter
          servicePort: {{ .Values.jupyter.servicePort }}
{{- end -}} # dask-jupyter-service.yaml
{{ if .Values.jupyter.enabled -}}

apiVersion: v1
kind: Service
metadata:
  name: {{ template "dask.fullname" . }}-jupyter
  labels:
    app: {{ template "dask.name" . }}
    heritage: {{ .Release.Service | quote }}
    release: {{ .Release.Name | quote }}
    chart: {{ template "dask.chart" . }}
    component: jupyter
spec:
  ports:
    - name: {{ template "dask.fullname" . }}-jupyter
      port: {{ .Values.jupyter.servicePort }}
      targetPort: 8888
  selector:
    app: {{ template "dask.name" . }}
    release: {{ .Release.Name | quote }}
    component: jupyter
  type: {{ .Values.jupyter.serviceType }}

{{ end }}
 # dask-scheduler-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ template "dask.fullname" . }}-scheduler
  labels:
    app: {{ template "dask.name" . }}
    heritage: {{ .Release.Service | quote }}
    release: {{ .Release.Name | quote }}
    chart: {{ template "dask.chart" . }}
    component: scheduler
spec:
  replicas: {{ .Values.scheduler.replicas }}
  selector:
    matchLabels:
      app: {{ template "dask.name" . }}
      release: {{ .Release.Name | quote }}
      component: scheduler
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: {{ template "dask.name" . }}
        release: {{ .Release.Name | quote }}
        component: scheduler
    spec:
      imagePullSecrets:
        {{- toYaml .Values.scheduler.image.pullSecrets | nindent 8 }}
      containers:
        - name: {{ template "dask.fullname" . }}-scheduler
          image: "{{ .Values.scheduler.image.repository }}:{{ .Values.scheduler.image.tag }}"
          imagePullPolicy: {{ .Values.scheduler.image.pullPolicy }}
          args:
            - dask-scheduler
            - --port
            - "{{ .Values.scheduler.servicePort }}"
            - --bokeh-port
            - "8787"
          ports:
            - containerPort: 8786
            - containerPort: 8787
          resources:
            {{- toYaml .Values.scheduler.resources | nindent 12 }}
          env:
            {{- toYaml .Values.scheduler.env | nindent 12 }}
    {{- with .Values.scheduler.nodeSelector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
    {{- end }}
    {{- with .Values.scheduler.affinity }}
      affinity:
        {{- toYaml . | nindent 8 }}
    {{- end }}
    {{- with .Values.scheduler.tolerations }}
      tolerations:
        {{- toYaml . | nindent 8 }}
    {{- end }}
 # dask-scheduler-ingress.yaml
{{- if .Values.webUI.ingress.enabled -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{ template "dask.fullname" . }}-scheduler
  labels:
    app: {{ template "dask.fullname" . }}-scheduler
    chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    release: "{{ .Release.Name }}"
    heritage: "{{ .Release.Service }}"
  annotations:
{{ toYaml .Values.webUI.ingress.annotations | indent 4 }}
spec:
{{- if .Values.webUI.ingress.tls }}
  tls:
    - hosts:
      - {{ .Values.webUI.ingress.hostname | quote }}
      secretName: {{ .Values.webUI.ingress.secretName | default (printf "%s-scheduler-tls" (include "dask.fullname" .)) }}
{{- end }}
  rules:
  - host: {{ .Values.webUI.ingress.hostname }}
    http:
      paths:
      - backend:
          serviceName: {{ template "dask.fullname" . }}-scheduler
          servicePort: {{ .Values.webUI.servicePort }}
{{- end -}} # dask-scheduler-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ template "dask.fullname" . }}-scheduler
  labels:
    app: {{ template "dask.name" . }}
    heritage: {{ .Release.Service | quote }}
    release: {{ .Release.Name | quote }}
    chart: {{ template "dask.chart" . }}
    component: scheduler
spec:
  ports:
    - name: {{ template "dask.fullname" . }}-scheduler
      port: {{ .Values.scheduler.servicePort }}
      targetPort: 8786
    - name: {{ template "dask.fullname" . }}-webui
      port: {{ .Values.webUI.servicePort }}
      targetPort: 8787
  selector:
    app: {{ template "dask.name" . }}
    release: {{ .Release.Name | quote }}
    component: scheduler
  type: {{ .Values.scheduler.serviceType }}
 # dask-worker-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ template "dask.fullname" . }}-worker
  labels:
    app: {{ template "dask.name" . }}
    heritage: {{ .Release.Service | quote }}
    release: {{ .Release.Name | quote }}
    chart: {{ template "dask.chart" . }}
    component: worker
spec:
  replicas: {{ .Values.worker.replicas }}
  selector:
    matchLabels:
      app: {{ template "dask.name" . }}
      release: {{ .Release.Name | quote }}
      component: worker
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: {{ template "dask.name" . }}
        release: {{ .Release.Name | quote }}
        component: worker
    spec:
      imagePullSecrets:
        {{- toYaml .Values.worker.image.pullSecrets | nindent 8 }}
      containers:
        - name: {{ template "dask.fullname" . }}-worker
          image: "{{ .Values.worker.image.repository }}:{{ .Values.worker.image.tag }}"
          imagePullPolicy: {{ .Values.worker.image.pullPolicy }}
          args:
            - {{ .Values.worker.image.dask_worker }}
            - {{ template "dask.fullname" . }}-scheduler:{{ .Values.scheduler.servicePort }}
          {{- if .Values.worker.resources.limits }}
            - --nthreads
            - {{ .Values.worker.resources.limits.cpu | default .Values.worker.default_resources.cpu | quote }}
            - --memory-limit
            - {{ .Values.worker.resources.limits.memory | default .Values.worker.default_resources.memory | quote }}
          {{- end }}
            - --no-bokeh
          ports:
            - containerPort: 8789
          resources:
            {{- toYaml .Values.worker.resources | nindent 12 }}
          env:
            {{- toYaml .Values.worker.env | nindent 12 }}
    {{- with .Values.worker.nodeSelector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
    {{- end }}
    {{- with .Values.worker.affinity }}
      affinity:
        {{- toYaml . | nindent 8 }}
    {{- end }}
    {{- with .Values.worker.tolerations }}
      tolerations:
        {{- toYaml . | nindent 8 }}
    {{- end }}

---
# nameOverride: dask
# fullnameOverride: dask

scheduler:
  name: scheduler
  image:
    repository: "daskdev/dask"
    tag: 1.1.5
    pullPolicy: IfNotPresent
    # See https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
    pullSecrets:
    #  - name: regcred
  replicas: 1
  # serviceType: "ClusterIP"
  # serviceType: "NodePort"
  serviceType: "LoadBalancer"
  servicePort: 8786
  resources: {}
  #  limits:
  #    cpu: 1.8
  #    memory: 6G
  #  requests:
  #    cpu: 1.8
  #    memory: 6G
  tolerations: []
  nodeSelector: {}
  affinity: {}

webUI:
  name: webui
  servicePort: 80
  ingress:
    enabled: false
    tls: false
    # secretName: dask-scheduler-tls
    hostname: dask-ui.example.com
    annotations:
     # kubernetes.io/ingress.class: "nginx"
     # secretName: my-tls-cert
     # kubernetes.io/tls-acme: "true"

worker:
  name: worker
  image:
    repository: "daskdev/dask"
    tag: 1.1.5
    pullPolicy: IfNotPresent
    # dask_worker: "dask-cuda-worker"
    dask_worker: "dask-worker"
    pullSecrets:
    #  - name: regcred
  replicas: 3
  aptPackages: >-
  default_resources:  # overwritten by resource limits if they exist
    cpu: 1
    memory: "4GiB"
  env:
  #  - name: EXTRA_CONDA_PACKAGES
  #    value: numba xarray -c conda-forge
  #  - name: EXTRA_PIP_PACKAGES
  #    value: s3fs dask-ml --upgrade
  resources: {}
  #  limits:
  #    cpu: 1
  #    memory: 3G
  #    nvidia.com/gpu: 1
  #  requests:
  #    cpu: 1
  #    memory: 3G
  #    nvidia.com/gpu: 1
  tolerations: []
  nodeSelector: {}
  affinity: {}

jupyter:
  name: jupyter
  enabled: true
  image:
    repository: "daskdev/dask-notebook"
    tag: 1.1.5
    pullPolicy: IfNotPresent
    pullSecrets:
    #  - name: regcred
  replicas: 1
  # serviceType: "ClusterIP"
  # serviceType: "NodePort"
  serviceType: "LoadBalancer"
  servicePort: 80
  # This hash corresponds to the password 'dask'
  password: 'sha1:aae8550c0a44:9507d45e087d5ee481a5ce9f4f16f37a0867318c'
  env:
  #  - name: EXTRA_CONDA_PACKAGES
  #    value: "numba xarray -c conda-forge"
  #  - name: EXTRA_PIP_PACKAGES
  #    value: "s3fs dask-ml --upgrade"
  resources: {}
  #  limits:
  #    cpu: 2
  #    memory: 6G
  #  requests:
  #    cpu: 2
  #    memory: 6G
  tolerations: []
  nodeSelector: {}
  affinity: {}
  ingress:
    enabled: false
    tls: false
    # secretName: dask-jupyter-tls
    hostname: dask-jupyter.example.com
    annotations:
      # kubernetes.io/ingress.class: "nginx"
      # secretName: my-tls-cert
      # kubernetes.io/tls-acme: "true"
