diff --git a/packages/extra/seaweedfs/Makefile b/packages/extra/seaweedfs/Makefile index bc02a298..e7d05b33 100644 --- a/packages/extra/seaweedfs/Makefile +++ b/packages/extra/seaweedfs/Makefile @@ -4,3 +4,4 @@ include ../../../scripts/package.mk generate: readme-generator -v values.yaml -s values.schema.json -r README.md + yq -o json -i '.properties.topology.enum = ["Simple","MultiZone"]' values.schema.json diff --git a/packages/extra/seaweedfs/README.md b/packages/extra/seaweedfs/README.md index 557c1e00..6e354956 100644 --- a/packages/extra/seaweedfs/README.md +++ b/packages/extra/seaweedfs/README.md @@ -4,10 +4,13 @@ ### Common parameters -| Name | Description | Value | -| -------------- | --------------------------------------------------------------------------------------------------------- | ------ | -| `host` | The hostname used to access the grafana externally (defaults to 'grafana' subdomain for the tenant host). | `""` | -| `replicas` | Persistent Volume size for NATS | `2` | -| `size` | Persistent Volume size | `10Gi` | -| `storageClass` | StorageClass used to store the data | `""` | +| Name | Description | Value | +| ------------------- | ------------------------------------------------------------------------------------------------------ | -------- | +| `host` | The hostname used to access the SeaweedFS externally (defaults to 's3' subdomain for the tenant host). | `""` | +| `topology` | The topology of the SeaweedFS cluster. (allowed values: Simple, MultiZone) | `Simple` | +| `replicationFactor` | The number of replicas for each volume in the SeaweedFS cluster. | `2` | +| `replicas` | Persistent Volume size for SeaweedFS | `2` | +| `size` | Persistent Volume size | `10Gi` | +| `storageClass` | StorageClass used to store the data | `""` | +| `zones` | A map of zones for MultiZone topology. Each zone can have its own number of replicas and size. | `{}` | diff --git a/packages/extra/seaweedfs/templates/seaweedfs.yaml b/packages/extra/seaweedfs/templates/seaweedfs.yaml index a2fcb30c..eafdb4e3 100644 --- a/packages/extra/seaweedfs/templates/seaweedfs.yaml +++ b/packages/extra/seaweedfs/templates/seaweedfs.yaml @@ -1,3 +1,28 @@ +{{- /* Preflight checks for Helm template */ -}} +{{- if not (has .Values.topology (list "Simple" "MultiZone")) }} +{{- fail "Invalid value for .Values.topology. Must be one of 'Simple' or 'MultiZone'." }} +{{- end }} +{{- if lt (int .Values.replicationFactor) 1 }} +{{- fail "Invalid value for .Values.replicationFactor. Must be at least 1." }} +{{- end }} +{{- if eq .Values.topology "MultiZone" }} +{{- if (eq (len .Values.zones) 0) }} +{{- fail "Zones must be defined for MultiZone topology." }} +{{- end }} +{{- if and (hasKey .Values "zones") (gt (int .Values.replicationFactor) (len .Values.zones)) }} +{{- fail "replicationFactor must be less than or equal to the number of zones defined in .Values.zones." }} +{{- end }} +{{- end }} +{{- if lookup "v1" "PersistentVolumeClaim" "" (printf "%s-data1-seaweedfs-volume-0" .Release.Name) }} +{{- if eq .Values.topology "MultiZone" }} +{{- fail "Not allowed to switch between Simple and MultiZone topologies after the first deployment." }} +{{- end }} +{{- else }} +{{- if and (eq .Values.topology "Simple") (.Release.IsUpgrade) }} +{{- fail "Not allowed to switch between Simple and MultiZone topologies after the first deployment." }} +{{- end }} +{{- end }} + {{- $myNS := lookup "v1" "Namespace" "" .Release.Namespace }} {{- $ingress := index $myNS.metadata.annotations "namespace.cozystack.io/ingress" }} {{- $host := index $myNS.metadata.annotations "namespace.cozystack.io/host" }} @@ -22,6 +47,11 @@ spec: serviceAccountName: "{{ .Release.Namespace }}-seaweedfs" seaweedfs: master: + {{ if eq .Values.topology "Simple" }} + defaultReplicaPlacement: "00{{ sub .Values.replicationFactor 1 }}" + {{- else if eq .Values.topology "MultiZone" }} + defaultReplicaPlacement: "{{ sub .Values.replicationFactor 1 }}00" + {{- end }} resources: requests: cpu: "100m" @@ -30,6 +60,9 @@ spec: cpu: "500m" memory: "512Mi" volume: + {{ if eq .Values.topology "MultiZone" }} + enabled: false + {{- end }} replicas: {{ .Values.replicas }} resources: requests: @@ -38,9 +71,6 @@ spec: limits: cpu: "500m" memory: "512Mi" - # TODO: workaround for non-working online resize - podAnnotations: - volume-size: "{{ .Values.size }}" dataDirs: - name: data1 type: "persistentVolumeClaim" @@ -49,7 +79,37 @@ spec: storageClass: {{ . }} {{- end }} maxVolumes: 0 + {{ if eq .Values.topology "MultiZone" }} + volumes: + {{- range $zoneName, $zone := .Values.zones }} + {{ $zoneName }}: + {{ with $zone.replicas }} + replicas: {{ . }} + {{- end }} + dataDirs: + - name: data1 + type: "persistentVolumeClaim" + {{- if $zone.size }} + size: "{{ $zone.size }}" + {{- else }} + size: "{{ $.Values.size }}" + {{- end }} + {{- if $zone.storageClass }} + storageClass: {{ $zone.storageClass }} + {{- else if $.Values.storageClass }} + storageClass: {{ $.Values.storageClass }} + {{- end }} + nodeSelector: | + topology.kubernetes.io/zone: {{ $zoneName }} + dataCenter: {{ $zone.dataCenter | default $zoneName }} + {{- end }} + {{- end }} filer: + {{ if eq .Values.topology "Simple" }} + defaultReplicaPlacement: "00{{ sub .Values.replicationFactor 1 }}" + {{- else if eq .Values.topology "MultiZone" }} + defaultReplicaPlacement: "{{ sub .Values.replicationFactor 1 }}00" + {{- end }} s3: domainName: {{ .Values.host | default (printf "s3.%s" $host) }} resources: diff --git a/packages/extra/seaweedfs/values.schema.json b/packages/extra/seaweedfs/values.schema.json index c7daa251..2c02336e 100644 --- a/packages/extra/seaweedfs/values.schema.json +++ b/packages/extra/seaweedfs/values.schema.json @@ -1,26 +1,45 @@ { - "title": "Chart Values", - "type": "object", - "properties": { - "host": { - "type": "string", - "description": "The hostname used to access the grafana externally (defaults to 'grafana' subdomain for the tenant host).", - "default": "" - }, - "replicas": { - "type": "number", - "description": "Persistent Volume size for NATS", - "default": 2 - }, - "size": { - "type": "string", - "description": "Persistent Volume size", - "default": "10Gi" - }, - "storageClass": { - "type": "string", - "description": "StorageClass used to store the data", - "default": "" - } + "title": "Chart Values", + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "The hostname used to access the SeaweedFS externally (defaults to 's3' subdomain for the tenant host).", + "default": "" + }, + "topology": { + "type": "string", + "description": "The topology of the SeaweedFS cluster. (allowed values: Simple, MultiZone)", + "default": "Simple", + "enum": [ + "Simple", + "MultiZone" + ] + }, + "replicationFactor": { + "type": "number", + "description": "The number of replicas for each volume in the SeaweedFS cluster.", + "default": 2 + }, + "replicas": { + "type": "number", + "description": "Persistent Volume size for SeaweedFS", + "default": 2 + }, + "size": { + "type": "string", + "description": "Persistent Volume size", + "default": "10Gi" + }, + "storageClass": { + "type": "string", + "description": "StorageClass used to store the data", + "default": "" + }, + "zones": { + "type": "object", + "description": "A map of zones for MultiZone topology. Each zone can have its own number of replicas and size.", + "default": {} } -} \ No newline at end of file + } +} diff --git a/packages/extra/seaweedfs/values.yaml b/packages/extra/seaweedfs/values.yaml index 5921ac55..50846fcc 100644 --- a/packages/extra/seaweedfs/values.yaml +++ b/packages/extra/seaweedfs/values.yaml @@ -1,12 +1,33 @@ ## @section Common parameters -## @param host The hostname used to access the grafana externally (defaults to 'grafana' subdomain for the tenant host). +## @param host The hostname used to access the SeaweedFS externally (defaults to 's3' subdomain for the tenant host). host: "" -## @param replicas Persistent Volume size for NATS +## @param topology The topology of the SeaweedFS cluster. (allowed values: Simple, MultiZone) +## +topology: Simple + +## @param replicationFactor The number of replicas for each volume in the SeaweedFS cluster. +replicationFactor: 2 + +## @param replicas Persistent Volume size for SeaweedFS ## @param size Persistent Volume size ## @param storageClass StorageClass used to store the data ## replicas: 2 size: 10Gi storageClass: "" + +## @param zones A map of zones for MultiZone topology. Each zone can have its own number of replicas and size. +## Example: +## zones: +## dc1: +## replicas: 2 +## size: 10Gi +## dc2: +## replicas: 2 +## size: 10Gi +## dc3: +## replicas: 2 +## size: 10Gi +zones: {}