From 97b46783249af24fd46b8d72504d89fed1497287 Mon Sep 17 00:00:00 2001
From: Janne Mareike Koschinski <janne@kuschku.de>
Date: Wed, 15 Jun 2022 23:30:19 +0200
Subject: [PATCH] feat: implement chart for seafile

---
 .gitlab-ci.yml                    |   1 +
 seafile/Chart.yaml                |   6 ++
 seafile/pipeline.yml              |  16 ++++
 seafile/templates/_helpers.tpl    |  56 ++++++++++++++
 seafile/templates/deployment.yaml | 122 ++++++++++++++++++++++++++++++
 seafile/templates/ingress.yaml    |  27 +++++++
 seafile/templates/secret.yaml     |  86 +++++++++++++++++++++
 seafile/templates/service.yaml    |  19 +++++
 seafile/values.yaml               | 100 ++++++++++++++++++++++++
 9 files changed, 433 insertions(+)
 create mode 100644 seafile/Chart.yaml
 create mode 100644 seafile/pipeline.yml
 create mode 100644 seafile/templates/_helpers.tpl
 create mode 100644 seafile/templates/deployment.yaml
 create mode 100644 seafile/templates/ingress.yaml
 create mode 100644 seafile/templates/secret.yaml
 create mode 100644 seafile/templates/service.yaml
 create mode 100644 seafile/values.yaml

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 03cbfcc..889e30a 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -17,4 +17,5 @@ include:
 - /quassel/pipeline.yml
 - /restic/pipeline.yml
 - /rtorrent/pipeline.yml
+- /seafile/pipeline.yml
 - /wg-access-server/pipeline.yml
diff --git a/seafile/Chart.yaml b/seafile/Chart.yaml
new file mode 100644
index 0000000..f70707a
--- /dev/null
+++ b/seafile/Chart.yaml
@@ -0,0 +1,6 @@
+apiVersion: v2
+name: seafile
+description: Helm Chart for seafile
+type: application
+version: 0.1.0
+appVersion: "66c35794"
diff --git a/seafile/pipeline.yml b/seafile/pipeline.yml
new file mode 100644
index 0000000..07273d8
--- /dev/null
+++ b/seafile/pipeline.yml
@@ -0,0 +1,16 @@
+lint-seafile:
+  stage: lint
+  script:
+    - helm lint seafile
+
+release-seafile:
+  stage: release
+  needs:
+    - lint-seafile
+  rules:
+    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
+  script:
+    - apk add --no-cache git
+    - helm plugin install https://github.com/chartmuseum/helm-push.git
+    - helm repo add --username gitlab-ci-token --password $CI_JOB_TOKEN repo ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/helm/stable
+    - helm cm-push seafile repo
diff --git a/seafile/templates/_helpers.tpl b/seafile/templates/_helpers.tpl
new file mode 100644
index 0000000..6305ba9
--- /dev/null
+++ b/seafile/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "seafile-helm.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 "seafile-helm.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 "seafile-helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Common labels
+*/}}
+{{- define "seafile-helm.labels" -}}
+helm.sh/chart: {{ include "seafile-helm.chart" . }}
+{{ include "seafile-helm.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "seafile-helm.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "seafile-helm.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+
+{{- define "seafile-helm.sslPath" -}}
+/certs
+{{- end }}
diff --git a/seafile/templates/deployment.yaml b/seafile/templates/deployment.yaml
new file mode 100644
index 0000000..471f7cf
--- /dev/null
+++ b/seafile/templates/deployment.yaml
@@ -0,0 +1,122 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "seafile-helm.fullname" . }}
+  labels:
+    {{- include "seafile-helm.labels" . | nindent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      {{- include "seafile-helm.selectorLabels" . | nindent 6 }}
+  template:
+    metadata:
+      {{- with .Values.podAnnotations }}
+      annotations:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      labels:
+        {{- include "seafile-helm.selectorLabels" . | nindent 8 }}
+    spec:
+      {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      volumes:
+        - name: seafile
+          {{- .Values.volumes.seafile | nindent 10 }}
+        - name: seahub
+          {{- .Values.volumes.seahub | nindent 10 }}
+        - name: config
+          secret:
+            secretName: {{ include "seafile-helm.fullname" . }}
+        - name: tmp
+          emptyDir: {}
+      initContainers:
+        - name: seahub-media
+          securityContext:
+            {{- toYaml .Values.securityContext | nindent 12 }}
+          image: "{{ .Values.image.repository }}:seahub-{{ .Values.image.tag | default .Chart.AppVersion }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          command:
+            - "/bin/sh"
+            - "-c"
+          args:
+            - "rsync -avH /source/seahub/media/avatars/ /media"
+          volumeMounts:
+            - mountPath: "/media"
+              name: seahub
+      containers:
+        - name: seafile
+          securityContext:
+            {{- toYaml .Values.securityContext | nindent 12 }}
+          image: "{{ .Values.image.repository }}:seafile-{{ .Values.image.tag | default .Chart.AppVersion }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: seafhttp
+              containerPort: 8082
+              protocol: TCP
+          startupProbe:
+            tcpSocket:
+              port: seafhttp
+          livenessProbe:
+            tcpSocket:
+              port: seafhttp
+          readinessProbe:
+            tcpSocket:
+              port: seafhttp
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+          volumeMounts:
+            - mountPath: "/data"
+              name: seafile
+            - mountPath: "/conf"
+              name: config
+            - mountPath: "/tmp"
+              name: tmp
+        - name: seahub
+          securityContext:
+            {{- toYaml .Values.securityContext | nindent 12 }}
+          image: "{{ .Values.image.repository }}:seahub-{{ .Values.image.tag | default .Chart.AppVersion }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: seahub
+              containerPort: 8000
+              protocol: TCP
+          startupProbe:
+            httpGet:
+              path: /
+              port: seahub
+          livenessProbe:
+            httpGet:
+              path: /
+              port: seahub
+          readinessProbe:
+            httpGet:
+              path: /
+              port: seahub
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+          volumeMounts:
+            - mountPath: "/data"
+              name: seafile
+            - mountPath: "/source/seahub/media/avatars/"
+              name: seahub
+            - mountPath: "/conf"
+              name: config
+            - mountPath: "/tmp"
+              name: tmp
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
diff --git a/seafile/templates/ingress.yaml b/seafile/templates/ingress.yaml
new file mode 100644
index 0000000..872a8d4
--- /dev/null
+++ b/seafile/templates/ingress.yaml
@@ -0,0 +1,27 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+  name: {{ include "seafile-helm.fullname" . }}
+  labels:
+    {{- include "seafile-helm.labels" . | nindent 4 }}
+  annotations:
+    {{- .Values.ingress.annotations | toYaml | nindent 4 }}
+spec:
+  rules:
+    - host: "{{ .Values.ingress.host }}"
+      http:
+        paths:
+          - path: "{{ .Values.ingress.seahub_path }}"
+            backend:
+              service:
+                name: {{ include "seafile-helm.fullname" . }}
+                port:
+                  name: seahub
+            pathType: Prefix
+          - path: "{{ .Values.ingress.seafhttp_path }}"
+            backend:
+              service:
+                name: {{ include "seafile-helm.fullname" . }}
+                port:
+                  name: seafhttp
+            pathType: Prefix
diff --git a/seafile/templates/secret.yaml b/seafile/templates/secret.yaml
new file mode 100644
index 0000000..18b4afd
--- /dev/null
+++ b/seafile/templates/secret.yaml
@@ -0,0 +1,86 @@
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ include "seafile-helm.fullname" . }}
+  labels:
+    {{- include "seafile-helm.labels" . | nindent 4 }}
+stringData:
+  ccnet.ini: |-
+    [Database]
+    ENGINE = {{ .Values.ccnet.database.backend }}
+    HOST = {{ .Values.ccnet.database.hostname }}
+    PORT = {{ .Values.ccnet.database.port }}
+    USER = {{ .Values.ccnet.database.username }}
+    PASSWD = {{ .Values.ccnet.database.password }}
+    DB = {{ .Values.ccnet.database.name }}
+    CREATE_TABLES = {{ .Values.ccnet.create_tables }}
+
+    [General]
+    SERVICE_URL = {{ .Values.ingress.external_schema }}://{{ .Values.ingress.host }}{{ .Values.ingress.path }}
+
+    [Client]
+    PORT = 13419
+    UNIX_SOCKET = /tmp/seafile.sock
+  gunicorn.conf: |-
+    import os
+
+    daemon = True
+    workers = 5
+
+    bind = "127.0.0.1:8000"
+
+    pids_dir = '/tmp'
+    pidfile = os.path.join(pids_dir, 'seahub.pid')
+
+    timeout = 1200
+    limit_request_line = 8190
+  seafile.conf: |-
+    [fileserver]
+    port = 8082
+
+    [database]
+    type = {{ .Values.seafile.database.backend }}
+    host = {{ .Values.seafile.database.hostname }}
+    port = {{ .Values.seafile.database.port }}
+    user = {{ .Values.seafile.database.username }}
+    password = {{ .Values.seafile.database.password }}
+    db_name = {{ .Values.seafile.database.name }}
+    create_tables = {{ .Values.seafile.create_tables }}
+  seahub_settings.py: |-
+    FILE_SERVER_ROOT = '{{ .Values.ingress.external_schema }}://{{ .Values.ingress.host }}{{ .Values.ingress.seafhttp_path }}'
+
+    SECRET_KEY = "{{ .Values.cookie_secret }}"
+
+    DATABASES = {
+        'default': {
+            'ENGINE': '{{ .Values.seahub.database.backend }}',
+            'NAME': '{{ .Values.seahub.database.name }}',
+            'USER': '{{ .Values.seahub.database.username }}',
+            'PASSWORD': '{{ .Values.seahub.database.password }}',
+            'HOST': '{{ .Values.seahub.database.hostname }}',
+            'PORT': '{{ .Values.seahub.database.port }}',
+        }
+    }
+
+    {{ if .Values.seahub.cache.enabled }}
+    CACHES = {
+        'default': {
+            'BACKEND': '{{ .Values.seahub.cache.backend }}',
+            'LOCATION': [
+              {{- range .Values.seahub.cache.locations -}}
+              '{{ . }}',
+              {{- end -}}
+            ],
+        },
+    }
+    {{ end }}
+
+    EMAIL_HOST = '{{ .Values.seahub.email.hostname }}'
+    EMAIL_PORT = {{ .Values.seahub.email.port }}
+    EMAIL_USE_TLS = {{ .Values.seahub.email.port }}
+    EMAIL_HOST_USER = '{{ .Values.seahub.email.username }}'
+    EMAIL_HOST_PASSWORD = '{{ .Values.seahub.email.password }}'
+
+    DEFAULT_FROM_EMAIL = '{{ .Values.seahub.email.default_from_email }}'
+    SERVER_EMAIL = '{{ .Values.seahub.email.server_email }}'
+  mykey.peer: "{{ .Values.ccnet.key }}"
diff --git a/seafile/templates/service.yaml b/seafile/templates/service.yaml
new file mode 100644
index 0000000..c45cb75
--- /dev/null
+++ b/seafile/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "seafile-helm.fullname" . }}
+  labels:
+    {{- include "seafile-helm.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: 8082
+      targetPort: seafhttp
+      protocol: TCP
+      name: seafhttp
+    - port: 80
+      targetPort: seahub
+      protocol: TCP
+      name: seahub
+  selector:
+    {{- include "seafile-helm.selectorLabels" . | nindent 4 }}
diff --git a/seafile/values.yaml b/seafile/values.yaml
new file mode 100644
index 0000000..4721cc5
--- /dev/null
+++ b/seafile/values.yaml
@@ -0,0 +1,100 @@
+replicaCount: 1
+
+image:
+  repository: k8r.eu/justjanne/seafile
+  pullPolicy: IfNotPresent
+  tag: ""
+
+imagePullSecrets: [ ]
+nameOverride: ""
+fullnameOverride: ""
+
+# use a proper random secret key here
+# undefined by default to force you to choose one
+# cookie_secret: ""
+
+ccnet:
+  create_tables: true
+  key: |-
+    -----BEGIN RSA PRIVATE KEY-----
+    ...
+    -----END RSA PRIVATE KEY-----
+  database:
+    backend: pgsql
+    hostname: "example.tld"
+    port: 5432
+    name: "ccnet"
+    username: "username"
+    password: "password"
+
+seafile:
+  create_tables: true
+  database:
+    backend: pgsql
+    hostname: "example.tld"
+    port: 5432
+    name: "seafile"
+    username: "username"
+    password: "password"
+  volume: |-
+    emptyDir: {}
+
+seahub:
+  database:
+    backend: "django.db.backends.postgresql"
+    hostname: "example.tld"
+    port: 5432
+    name: "seahub"
+    username: "username"
+    password: "password"
+  cache:
+    enabled: false
+    backend: "django.core.cache.backends.memcached.PyMemcacheCache"
+    locations:
+      - "example.tld:11211"
+  email:
+    use_tls: true
+    hostname: "example.tld"
+    port: 587
+    username: "user@example.tld"
+    password: "password"
+    default_from_email: "user@example.tld"
+    server_email: "user@example.tld"
+  volume: |-
+    emptyDir: {}
+
+service:
+  type: ClusterIP
+
+ingress:
+  external_schema: "https"
+  host: "example.com"
+  seafhttp_path: "/seafhttp"
+  seahub_path: "/"
+  annotations: { }
+
+securityContext: { }
+#  capabilities:
+#    drop:
+#      - ALL
+#  runAsNonRoot: true
+#  runAsUser: 1000
+
+resources:
+  limits:
+    cpu: 500m
+    memory: 2Gi
+  requests:
+    cpu: 200m
+    memory: 500Mi
+
+podAnnotations: { }
+
+podSecurityContext:
+  fsGroup: 2000
+
+nodeSelector: { }
+
+tolerations: [ ]
+
+affinity: { }
-- 
GitLab