diff --git a/README.md b/README.md index c406b57..c821287 100644 --- a/README.md +++ b/README.md @@ -32,23 +32,56 @@ helm install openlist openlist/openlist --namespace openlist The default values.yaml should be suitable for most basic deployments. -| Parameter | Description | Default | -|----------------------------|-----------------------------------------------------------------------------|--------------------------| -| `image.registry` | Imag registry | `docker.io` | -| `image.repository` | Image name | `openlistteam/openlist` | -| `image.tag` | Image tag | `v4.1.6` | -| `image.pullPolicy` | Image pull policy | `IfNotPresent` | -| `persistence.storageClass` | Specify the storageClass used to provision the volume | | -| `persistence.accessMode` | The access mode of the volume | `ReadWriteOnce` | -| `persistence.size` | The size of the volume | `5Gi` | -| `service.type` | Kubernetes service type | `ClusterIP` | -| `service.loadBalancerIP` | Kubernetes service loadBalancerIP | | -| `service.http.port` | Kubernetes service http port | `5244` | -| `service.http.targetPort` | Kubernetes service http targetPort | `5244` | -| `service.http.nodePort` | Kubernetes service http nodePort (valid only when `service.type=NodePort`) | `35244` | -| `service.https.port` | Kubernetes service https port | `5245` | -| `service.https.targetPort` | Kubernetes service https targetPort | `5245` | -| `service.https.nodePort` | Kubernetes service https nodePort (valid only when `service.type=NodePort`) | `35245` | +| Parameter | Description | Default | +|-----------------------------|-----------------------------------------------------------------------------|-------------------------| +| `image.registry` | Image registry | `docker.io` | +| `image.repository` | Image name | `openlistteam/openlist` | +| `image.tag` | Image tag | `v4.2.2` | +| `image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `nameOverride` | Override the chart name | | +| `fullnameOverride` | Override the full resource name | | +| `namespaceOverride` | Override the namespace for namespaced resources | | +| `replicaCount` | Number of OpenList replicas | `1` | +| `updateStrategy` | Deployment update strategy. Use `Recreate` with RWO volumes; `RollingUpdate` requires RWX volumes | `{type: Recreate}` | +| `admin.password` | Initial admin password. Used only when OpenList creates the admin user | | +| `admin.existingSecret` | Existing Secret containing key `OPENLIST_ADMIN_PASSWORD` | | +| `timezone` | Value for the `TZ` environment variable | `UTC` | +| `umask` | Value for the `UMASK` environment variable | `022` | +| `podAnnotations` | Additional pod annotations | `{}` | +| `podLabels` | Additional pod labels | `{}` | +| `extraEnv` | Additional container environment variables | `[]` | +| `resources` | Container resource requests and limits | `{}` | +| `livenessProbe` | Container liveness probe configuration | `{}` | +| `readinessProbe` | Container readiness probe configuration | `{}` | +| `nodeSelector` | Pod node selector | `{}` | +| `tolerations` | Pod tolerations | `[]` | +| `affinity` | Pod affinity | `{}` | +| `persistence.storageClass` | Specify the storageClass used to provision the volume | | +| `persistence.accessMode` | The access mode of the volume | `ReadWriteOnce` | +| `persistence.size` | The size of the volume | `5Gi` | +| `storage.enabled` | Enable a separate PVC for OpenList Local driver file storage | `false` | +| `storage.mountPath` | Container path where the file storage PVC is mounted | `/storage` | +| `storage.existingClaim` | Existing PVC to mount as file storage instead of creating one | | +| `storage.storageClass` | Specify the storageClass used to provision the file storage volume | | +| `storage.accessMode` | The access mode of the file storage volume | `ReadWriteOnce` | +| `storage.size` | The size of the file storage volume | `100Gi` | +| `service.type` | Kubernetes service type | `ClusterIP` | +| `service.annotations` | Additional service annotations | `{}` | +| `service.labels` | Additional service labels | `{}` | +| `service.loadBalancerIP` | Kubernetes service loadBalancerIP | | +| `service.http.port` | Kubernetes service http port | `5244` | +| `service.http.targetPort` | Kubernetes service http targetPort | `5244` | +| `service.http.nodePort` | Kubernetes service http nodePort (valid only when `service.type=NodePort`) | `35244` | +| `service.https.enabled` | Enable the https service port | `true` | +| `service.https.port` | Kubernetes service https port | `5245` | +| `service.https.targetPort` | Kubernetes service https targetPort | `5245` | +| `service.https.nodePort` | Kubernetes service https nodePort (valid only when `service.type=NodePort`) | `35245` | +| `httpRoute.enabled` | Enable Gateway API HTTPRoute | `false` | +| `httpRoute.annotations` | Additional HTTPRoute annotations | `{}` | +| `httpRoute.labels` | Additional HTTPRoute labels | `{}` | +| `httpRoute.parentRefs` | Gateway API parent references | `[]` | +| `httpRoute.hostnames` | HTTPRoute hostnames | `[]` | +| `httpRoute.rules` | HTTPRoute rules. Defaults to routing `/` to the HTTP service port | `[]` | If your Kubernetes cluster does not have a default StorageClass configured, please specify one explicitly. For example: @@ -57,6 +90,37 @@ For example: helm install openlist openlist/openlist --namespace openlist --set persistence.storageClass=longhorn ``` +### Gateway API HTTPRoute + +Enable `httpRoute` to expose OpenList through a Gateway API implementation: + +```yaml +httpRoute: + enabled: true + parentRefs: + - name: envoy-gateway + namespace: envoy-gateway + hostnames: + - openlist.example.com +``` + +When `httpRoute.rules` is empty, the chart creates a `PathPrefix` `/` rule that forwards traffic to the OpenList HTTP service port. + +### Local file storage + +The `persistence` volume is mounted at `/opt/openlist/data` for OpenList application data such as config, database, and logs. Do not use it as a Local driver root. + +Enable `storage` to mount a separate PVC for files: + +```yaml +storage: + enabled: true + mountPath: /storage + size: 100Gi +``` + +Then configure the OpenList Local driver with root folder path `/storage`. + ## Uninstallation To uninstall/delete the openlist deployment: diff --git a/charts/openlist/Chart.yaml b/charts/openlist/Chart.yaml index 19ec33a..dd9c65f 100644 --- a/charts/openlist/Chart.yaml +++ b/charts/openlist/Chart.yaml @@ -1,11 +1,11 @@ apiVersion: v1 name: openlist -version: 0.1.1 -appVersion: v4.1.6 +version: 0.2.0 +appVersion: v4.2.2 description: OpenList is a resilient, long-term governance, community-driven fork of AList - built to defend open source against trust-based attacks. keywords: - openlist sources: - https://github.com/OpenListTeam/OpenList.git home: https://oplist.org/ -icon: https://raw.githubusercontent.com/OpenListTeam/Logo/main/logo.svg \ No newline at end of file +icon: https://raw.githubusercontent.com/OpenListTeam/Logo/main/logo.svg diff --git a/charts/openlist/templates/_helpers.tpl b/charts/openlist/templates/_helpers.tpl index 3b3bea1..b641cc0 100644 --- a/charts/openlist/templates/_helpers.tpl +++ b/charts/openlist/templates/_helpers.tpl @@ -24,9 +24,52 @@ If release name contains chart name it will be used as a full name. {{- end -}} {{- end -}} +{{/* +Resolve the namespace for namespaced resources. +*/}} +{{- define "openlist.namespace" -}} +{{- default .Release.Namespace .Values.namespaceOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + {{/* Create chart name and version as used by the chart label. */}} {{- define "openlist.chart" -}} {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} {{- end -}} + +{{/* +Common labels. +*/}} +{{- define "openlist.labels" -}} +helm.sh/chart: {{ include "openlist.chart" . }} +app.kubernetes.io/name: {{ include "openlist.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app: {{ include "openlist.name" . }} +chart: {{ include "openlist.chart" . }} +release: {{ .Release.Name }} +{{- end -}} + +{{/* +Selector labels kept compatible with earlier chart releases. +*/}} +{{- define "openlist.selectorLabels" -}} +app: {{ include "openlist.name" . }} +release: {{ .Release.Name }} +{{- end -}} + +{{/* +Name of the Secret containing the initial admin password. +*/}} +{{- define "openlist.adminSecretName" -}} +{{- default (printf "%s-admin" (include "openlist.fullname" .)) .Values.admin.existingSecret | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Name of the PVC mounted as user file storage. +*/}} +{{- define "openlist.storageClaimName" -}} +{{- default (printf "%s-storage" (include "openlist.fullname" .)) .Values.storage.existingClaim | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/charts/openlist/templates/openlist-admin-secret.yaml b/charts/openlist/templates/openlist-admin-secret.yaml new file mode 100644 index 0000000..77ab636 --- /dev/null +++ b/charts/openlist/templates/openlist-admin-secret.yaml @@ -0,0 +1,12 @@ +{{- if and .Values.admin.password (not .Values.admin.existingSecret) -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "openlist.adminSecretName" . }} + namespace: {{ include "openlist.namespace" . }} + labels: + {{- include "openlist.labels" . | nindent 4 }} +type: Opaque +stringData: + OPENLIST_ADMIN_PASSWORD: {{ .Values.admin.password | quote }} +{{- end }} diff --git a/charts/openlist/templates/openlist-deployment.yaml b/charts/openlist/templates/openlist-deployment.yaml index fae3b09..cadc5f1 100644 --- a/charts/openlist/templates/openlist-deployment.yaml +++ b/charts/openlist/templates/openlist-deployment.yaml @@ -2,39 +2,73 @@ apiVersion: apps/v1 kind: Deployment metadata: labels: - app: {{ template "openlist.name" . }} - chart: {{ template "openlist.chart" . }} - release: {{ .Release.Name }} + {{- include "openlist.labels" . | nindent 4 }} name: {{ template "openlist.fullname" . }} + namespace: {{ include "openlist.namespace" . }} spec: replicas: {{ .Values.replicaCount }} + strategy: + {{- toYaml .Values.updateStrategy | nindent 4 }} selector: matchLabels: - app: {{ template "openlist.name" . }} - release: {{ .Release.Name }} + {{- include "openlist.selectorLabels" . | nindent 6 }} template: metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} labels: - app: {{ template "openlist.name" . }} - release: {{ .Release.Name }} + {{- include "openlist.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} spec: containers: - env: - name: TZ - value: UTC + value: {{ .Values.timezone | quote }} - name: UMASK - value: "022" + value: {{ .Values.umask | quote }} + {{- if or .Values.admin.password .Values.admin.existingSecret }} + - name: OPENLIST_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "openlist.adminSecretName" . }} + key: OPENLIST_ADMIN_PASSWORD + {{- end }} + {{- with .Values.extraEnv }} + {{- toYaml . | nindent 8 }} + {{- end }} name: {{ .Chart.Name }} image: "{{ .Values.image.registry}}/{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - containerPort: {{ .Values.service.http.port }} protocol: TCP + {{- if .Values.service.https.enabled }} - containerPort: {{ .Values.service.https.port }} protocol: TCP + {{- end }} + {{- with .Values.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 10 }} + {{- end }} volumeMounts: - mountPath: /opt/openlist/data name: openlist-data + {{- if .Values.storage.enabled }} + - mountPath: {{ .Values.storage.mountPath | quote }} + name: openlist-storage + {{- end }} restartPolicy: Always enableServiceLinks: false securityContext: @@ -43,3 +77,20 @@ spec: - name: openlist-data persistentVolumeClaim: claimName: {{ template "openlist.fullname" . }} + {{- if .Values.storage.enabled }} + - name: openlist-storage + persistentVolumeClaim: + claimName: {{ include "openlist.storageClaimName" . }} + {{- end }} + {{- 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/charts/openlist/templates/openlist-httproute.yaml b/charts/openlist/templates/openlist-httproute.yaml new file mode 100644 index 0000000..c912234 --- /dev/null +++ b/charts/openlist/templates/openlist-httproute.yaml @@ -0,0 +1,36 @@ +{{- if .Values.httpRoute.enabled -}} +{{- $fullName := include "openlist.fullname" . -}} +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: {{ $fullName }} + namespace: {{ include "openlist.namespace" . }} + labels: + {{- include "openlist.labels" . | nindent 4 }} + {{- with .Values.httpRoute.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.httpRoute.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + parentRefs: + {{- required "A valid .Values.httpRoute.parentRefs entry is required when httpRoute.enabled is true" .Values.httpRoute.parentRefs | toYaml | nindent 4 }} + {{- with .Values.httpRoute.hostnames }} + hostnames: + {{- toYaml . | nindent 4 }} + {{- end }} + rules: + {{- if .Values.httpRoute.rules }} + {{- toYaml .Values.httpRoute.rules | nindent 4 }} + {{- else }} + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: {{ $fullName }} + port: {{ .Values.service.http.port }} + {{- end }} +{{- end }} diff --git a/charts/openlist/templates/openlist-persistentvolumeclaim.yaml b/charts/openlist/templates/openlist-persistentvolumeclaim.yaml index ae9cdca..2aabc35 100644 --- a/charts/openlist/templates/openlist-persistentvolumeclaim.yaml +++ b/charts/openlist/templates/openlist-persistentvolumeclaim.yaml @@ -2,10 +2,9 @@ apiVersion: v1 kind: PersistentVolumeClaim metadata: name: {{ template "openlist.fullname" . }} + namespace: {{ include "openlist.namespace" . }} labels: - app: {{ template "openlist.name" . }} - chart: {{ template "openlist.chart" . }} - release: {{ .Release.Name }} + {{- include "openlist.labels" . | nindent 4 }} spec: accessModes: - {{ .Values.persistence.accessMode | quote }} diff --git a/charts/openlist/templates/openlist-service.yaml b/charts/openlist/templates/openlist-service.yaml index 428a1bd..4a9519e 100644 --- a/charts/openlist/templates/openlist-service.yaml +++ b/charts/openlist/templates/openlist-service.yaml @@ -2,6 +2,16 @@ apiVersion: v1 kind: Service metadata: name: {{ template "openlist.fullname" . }} + namespace: {{ include "openlist.namespace" . }} + labels: + {{- include "openlist.labels" . | nindent 4 }} + {{- with .Values.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} spec: type: {{ .Values.service.type | default "ClusterIP" }} {{- if and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerIP)) }} @@ -15,6 +25,7 @@ spec: {{- if (and (eq .Values.service.type "NodePort") ( .Values.service.http.nodePort)) }} nodePort: {{ .Values.service.http.nodePort }} {{- end }} + {{- if .Values.service.https.enabled }} - name: https protocol: TCP port: {{ .Values.service.https.port }} @@ -22,6 +33,6 @@ spec: {{- if (and (eq .Values.service.type "NodePort") ( .Values.service.https.nodePort)) }} nodePort: {{ .Values.service.https.nodePort }} {{- end }} + {{- end }} selector: - app: {{ template "openlist.name" . }} - release: {{ .Release.Name }} \ No newline at end of file + {{- include "openlist.selectorLabels" . | nindent 4 }} diff --git a/charts/openlist/templates/openlist-storage-persistentvolumeclaim.yaml b/charts/openlist/templates/openlist-storage-persistentvolumeclaim.yaml new file mode 100644 index 0000000..9002daa --- /dev/null +++ b/charts/openlist/templates/openlist-storage-persistentvolumeclaim.yaml @@ -0,0 +1,22 @@ +{{- if and .Values.storage.enabled (not .Values.storage.existingClaim) -}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "openlist.storageClaimName" . }} + namespace: {{ include "openlist.namespace" . }} + labels: + {{- include "openlist.labels" . | nindent 4 }} +spec: + accessModes: + - {{ .Values.storage.accessMode | quote }} + resources: + requests: + storage: {{ .Values.storage.size | quote }} + {{- if .Values.storage.storageClass }} + {{- if (eq "-" .Values.storage.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ .Values.storage.storageClass }}" + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/openlist/values.yaml b/charts/openlist/values.yaml index 2ed954f..234cf40 100644 --- a/charts/openlist/values.yaml +++ b/charts/openlist/values.yaml @@ -2,27 +2,76 @@ nameOverride: "" fullnameOverride: "" +namespaceOverride: "" + image: registry: docker.io - repository: openlistteam/openlist - tag: v4.1.6 + repository: openlistteam/openlist + tag: v4.2.2 pullPolicy: IfNotPresent replicaCount: 1 +# Use Recreate with ReadWriteOnce volumes. RollingUpdate requires ReadWriteMany +# volumes or another storage backend that can be mounted by old and new pods at +# the same time. +updateStrategy: + type: Recreate + +admin: + password: "" + # existingSecret must contain a key named OPENLIST_ADMIN_PASSWORD. + existingSecret: "" + +timezone: UTC +umask: "022" + +podAnnotations: {} +podLabels: {} + +extraEnv: [] + +resources: {} + +livenessProbe: {} +readinessProbe: {} + +nodeSelector: {} +tolerations: [] +affinity: {} + persistence: storageClass: "" accessMode: ReadWriteOnce size: 5Gi +storage: + enabled: false + mountPath: /storage + existingClaim: "" + storageClass: "" + accessMode: ReadWriteOnce + size: 100Gi + service: type: ClusterIP + annotations: {} + labels: {} loadBalancerIP: ~ http: port: 5244 targetPort: 5244 nodePort: 35244 https: + enabled: true port: 5245 targetPort: 5245 - nodePort: 35245 \ No newline at end of file + nodePort: 35245 + +httpRoute: + enabled: false + annotations: {} + labels: {} + parentRefs: [] + hostnames: [] + rules: []