From bb1e8805dc203e9bb6d82884e03e02f208718815 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Mon, 15 Sep 2025 16:26:54 +0200 Subject: [PATCH] [seaweedfs] Refactor config; add resources Co-authored-by: kklinch0 Signed-off-by: Andrei Kvapil --- packages/extra/seaweedfs/Chart.yaml | 2 +- packages/extra/seaweedfs/README.md | 66 ++- .../extra/seaweedfs/templates/seaweedfs.yaml | 97 ++-- packages/extra/seaweedfs/values.schema.json | 427 ++++++++++++++++-- packages/extra/seaweedfs/values.yaml | 103 +++-- packages/extra/versions_map | 3 +- .../system/seaweedfs/templates/database.yaml | 7 +- packages/system/seaweedfs/values.yaml | 12 +- scripts/migrations/19 | 48 ++ 9 files changed, 634 insertions(+), 131 deletions(-) create mode 100755 scripts/migrations/19 diff --git a/packages/extra/seaweedfs/Chart.yaml b/packages/extra/seaweedfs/Chart.yaml index 24796add..b39b8a34 100644 --- a/packages/extra/seaweedfs/Chart.yaml +++ b/packages/extra/seaweedfs/Chart.yaml @@ -16,7 +16,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.6.0 +version: 0.7.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/packages/extra/seaweedfs/README.md b/packages/extra/seaweedfs/README.md index a2cb311e..5207dea9 100644 --- a/packages/extra/seaweedfs/README.md +++ b/packages/extra/seaweedfs/README.md @@ -4,19 +4,55 @@ ### Common parameters -| Name | Description | Type | Value | -| ---------------------- | ------------------------------------------------------------------------------------------------------ | ------------------- | -------- | -| `host` | The hostname used to access the SeaweedFS externally (defaults to 's3' subdomain for the tenant host). | `*string` | `""` | -| `topology` | The topology of the SeaweedFS cluster. (allowed values: Simple, MultiZone, Client) | `string` | `Simple` | -| `replicationFactor` | Replication factor: number of replicas for each volume in the SeaweedFS cluster. | `int` | `2` | -| `replicas` | Number of replicas | `int` | `2` | -| `size` | Persistent Volume size | `quantity` | `10Gi` | -| `storageClass` | StorageClass used to store the data | `*string` | `""` | -| `zones` | A map of zones for MultiZone topology. Each zone can have its own number of replicas and size. | `map[string]object` | `{...}` | -| `zones[name].replicas` | Number of replicas in the zone | `int` | `0` | -| `zones[name].size` | Zone storage size | `quantity` | `""` | -| `filer` | Filer service configuration | `*object` | `{}` | -| `filer.grpcHost` | The hostname used to expose or access the filer service externally. | `*string` | `""` | -| `filer.grpcPort` | The port used to access the filer service externally. | `*int` | `443` | -| `filer.whitelist` | A list of IP addresses or CIDR ranges that are allowed to access the filer service. | `[]*string` | `[]` | +| Name | Description | Type | Value | +| ------------------- | ------------------------------------------------------------------------------------------------------ | --------- | -------- | +| `host` | The hostname used to access the SeaweedFS externally (defaults to 's3' subdomain for the tenant host). | `*string` | `""` | +| `topology` | The topology of the SeaweedFS cluster. (allowed values: Simple, MultiZone, Client) | `string` | `Simple` | +| `replicationFactor` | Replication factor: number of replicas for each volume in the SeaweedFS cluster. | `int` | `2` | + + +### SeaweedFS Components Configuration + +| Name | Description | Type | Value | +| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | ------- | +| `db` | Database Configuration | `object` | `{}` | +| `db.replicas` | Number of database replicas | `*int` | `2` | +| `db.size` | Persistent Volume size | `*quantity` | `10Gi` | +| `db.storageClass` | StorageClass used to store the data | `*string` | `""` | +| `db.resources` | Explicit CPU and memory configuration for the database. When left empty, the preset defined in `resourcesPreset` is applied. | `object` | `{}` | +| `db.resources.cpu` | The number of CPU cores allocated | `*quantity` | `null` | +| `db.resources.memory` | The amount of memory allocated | `*quantity` | `null` | +| `db.resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `small` | +| `master` | Master service configuration | `*object` | `{}` | +| `master.replicas` | Number of master replicas | `*int` | `3` | +| `master.resources` | Explicit CPU and memory configuration for the master. When left empty, the preset defined in `resourcesPreset` is applied. | `object` | `{}` | +| `master.resources.cpu` | The number of CPU cores allocated | `*quantity` | `null` | +| `master.resources.memory` | The amount of memory allocated | `*quantity` | `null` | +| `master.resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `small` | +| `filer` | Filer service configuration | `*object` | `{}` | +| `filer.replicas` | Number of filer replicas | `*int` | `2` | +| `filer.resources` | Explicit CPU and memory configuration for the filer. When left empty, the preset defined in `resourcesPreset` is applied. | `object` | `{}` | +| `filer.resources.cpu` | The number of CPU cores allocated | `*quantity` | `null` | +| `filer.resources.memory` | The amount of memory allocated | `*quantity` | `null` | +| `filer.resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `small` | +| `filer.grpcHost` | The hostname used to expose or access the filer service externally. | `*string` | `""` | +| `filer.grpcPort` | The port used to access the filer service externally. | `*int` | `443` | +| `filer.whitelist` | A list of IP addresses or CIDR ranges that are allowed to access the filer service. | `[]*string` | `[]` | +| `volume` | Volume service configuration | `*object` | `{}` | +| `volume.replicas` | Number of volume replicas | `*int` | `2` | +| `volume.size` | Persistent Volume size | `*quantity` | `10Gi` | +| `volume.storageClass` | StorageClass used to store the data | `*string` | `""` | +| `volume.resources` | Explicit CPU and memory configuration for the volume. When left empty, the preset defined in `resourcesPreset` is applied. | `object` | `{}` | +| `volume.resources.cpu` | The number of CPU cores allocated | `*quantity` | `null` | +| `volume.resources.memory` | The amount of memory allocated | `*quantity` | `null` | +| `volume.resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `small` | +| `volume.zones` | A map of zones for MultiZone topology. Each zone can have its own number of replicas and size. | `map[string]object` | `{}` | +| `volume.zones.replicas` | Number of replicas in the zone | `*int` | `null` | +| `volume.zones.size` | Zone storage size | `*quantity` | `null` | +| `s3` | S3 service configuration | `*object` | `{}` | +| `s3.replicas` | Number of s3 replicas | `*int` | `2` | +| `s3.resources` | Explicit CPU and memory configuration for the s3. When left empty, the preset defined in `resourcesPreset` is applied. | `object` | `{}` | +| `s3.resources.cpu` | The number of CPU cores allocated | `*quantity` | `null` | +| `s3.resources.memory` | The amount of memory allocated | `*quantity` | `null` | +| `s3.resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `small` | diff --git a/packages/extra/seaweedfs/templates/seaweedfs.yaml b/packages/extra/seaweedfs/templates/seaweedfs.yaml index db6d7371..b29a0e40 100644 --- a/packages/extra/seaweedfs/templates/seaweedfs.yaml +++ b/packages/extra/seaweedfs/templates/seaweedfs.yaml @@ -9,11 +9,11 @@ {{- fail "Invalid value for .Values.replicationFactor. Must be at least 1." }} {{- end }} {{- if eq .Values.topology "MultiZone" }} -{{- if (eq (len .Values.zones) 0) }} +{{- if (eq (len .Values.volume.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." }} +{{- if and (hasKey .Values.volume "zones") (gt (int .Values.replicationFactor) (len .Values.volume.zones)) }} +{{- fail "replicationFactor must be less than or equal to the number of zones defined in .Values.volume.zones." }} {{- end }} {{- end }} @@ -62,6 +62,13 @@ spec: values: global: serviceAccountName: "{{ .Release.Namespace }}-seaweedfs" + db: + replicas: {{ .Values.db.replicas }} + resources: {{- include "cozy-lib.resources.defaultingSanitize" (list .Values.db.resourcesPreset .Values.db.resources $) | nindent 8 }} + size: {{ .Values.db.size }} + {{- with .Values.db.storageClass }} + storageClass: {{ . }} + {{- end }} seaweedfs: master: {{ if eq .Values.topology "Simple" }} @@ -69,36 +76,25 @@ spec: {{- else if eq .Values.topology "MultiZone" }} defaultReplicaPlacement: "{{ sub .Values.replicationFactor 1 }}00" {{- end }} - resources: - requests: - cpu: "100m" - memory: "128Mi" - limits: - cpu: "500m" - memory: "512Mi" + replicas: {{ .Values.master.replicas }} + resources: {{- include "cozy-lib.resources.defaultingSanitize" (list .Values.master.resourcesPreset .Values.master.resources $) | nindent 10 }} volume: {{ if eq .Values.topology "MultiZone" }} enabled: false {{- end }} - replicas: {{ .Values.replicas }} - resources: - requests: - cpu: "100m" - memory: "128Mi" - limits: - cpu: "500m" - memory: "512Mi" + replicas: {{ .Values.volume.replicas }} + resources: {{- include "cozy-lib.resources.defaultingSanitize" (list .Values.volume.resourcesPreset .Values.volume.resources $) | nindent 10 }} dataDirs: - name: data1 type: "persistentVolumeClaim" - size: "{{ .Values.size }}" - {{- with .Values.storageClass }} + size: "{{ .Values.volume.size }}" + {{- with .Values.volume.storageClass }} storageClass: {{ . }} {{- end }} maxVolumes: 0 {{ if eq .Values.topology "MultiZone" }} volumes: - {{- range $zoneName, $zone := .Values.zones }} + {{- range $zoneName, $zone := .Values.volume.zones }} {{ $zoneName }}: {{ with $zone.replicas }} replicas: {{ . }} @@ -113,8 +109,8 @@ spec: {{- end }} {{- if $zone.storageClass }} storageClass: {{ $zone.storageClass }} - {{- else if $.Values.storageClass }} - storageClass: {{ $.Values.storageClass }} + {{- else if $.Values.volume.storageClass }} + storageClass: {{ $.Values.volume.storageClass }} {{- end }} maxVolumes: 0 nodeSelector: | @@ -130,13 +126,7 @@ spec: {{- end }} s3: domainName: {{ .Values.host | default (printf "s3.%s" $host) }} - resources: - requests: - cpu: "100m" - memory: "128Mi" - limits: - cpu: "500m" - memory: "512Mi" + resources: {{- include "cozy-lib.resources.defaultingSanitize" (list .Values.filer.resourcesPreset .Values.filer.resources $) | nindent 10 }} s3: ingress: className: {{ $ingress }} @@ -150,6 +140,7 @@ spec: - hosts: - {{ .Values.host | default (printf "s3.%s" $host) }} secretName: {{ .Release.Name }}-s3-ingress-tls + resources: {{- include "cozy-lib.resources.defaultingSanitize" (list .Values.s3.resourcesPreset .Values.s3.resources $) | nindent 10 }} cosi: driverName: "{{ .Release.Namespace }}.seaweedfs.objectstorage.k8s.io" bucketClassName: "{{ .Release.Namespace }}" @@ -166,8 +157,8 @@ kind: WorkloadMonitor metadata: name: {{ $.Release.Name }}-master spec: - replicas: 3 - minReplicas: 2 + replicas: {{ .Values.master.replicas }} + minReplicas: {{ div .Values.master.replicas 2 | add1 }} kind: seaweedfs type: master selector: @@ -180,7 +171,7 @@ kind: WorkloadMonitor metadata: name: {{ $.Release.Name }}-filer spec: - replicas: 2 + replicas: {{ .Values.filer.replicas }} minReplicas: 1 kind: seaweedfs type: filer @@ -188,27 +179,47 @@ spec: app.kubernetes.io/component: filer app.kubernetes.io/name: seaweedfs version: {{ $.Chart.Version }} + +{{ if eq .Values.topology "Simple" }} --- apiVersion: cozystack.io/v1alpha1 kind: WorkloadMonitor metadata: name: {{ $.Release.Name }}-volume spec: - replicas: {{ .Values.replicas }} - minReplicas: {{ div .Values.replicas 2 | add1 }} + replicas: {{ .Values.volume.replicas }} + minReplicas: 1 kind: seaweedfs type: volume selector: app.kubernetes.io/component: volume app.kubernetes.io/name: seaweedfs version: {{ $.Chart.Version }} +{{- else if eq .Values.topology "MultiZone" }} +{{- range $zoneName, $zoneSpec := .Values.volume.zones }} +--- +apiVersion: cozystack.io/v1alpha1 +kind: WorkloadMonitor +metadata: + name: {{ $.Release.Name }}-volume-{{ $zoneName }} +spec: + replicas: {{ default $.Values.volume.replicas $zoneSpec.replicas }} + minReplicas: 1 + kind: seaweedfs + type: volume + selector: + app.kubernetes.io/component: volume-{{ $zoneName }} + app.kubernetes.io/name: seaweedfs + version: {{ $.Chart.Version }} +{{- end }} +{{- end }} --- apiVersion: cozystack.io/v1alpha1 kind: WorkloadMonitor metadata: name: {{ $.Release.Name }}-db spec: - replicas: 2 + replicas: {{ .Values.db.replicas }} minReplicas: 1 kind: seaweedfs type: postgres @@ -216,4 +227,18 @@ spec: cnpg.io/cluster: seaweedfs-db cnpg.io/podRole: instance version: {{ $.Chart.Version }} +--- +apiVersion: cozystack.io/v1alpha1 +kind: WorkloadMonitor +metadata: + name: {{ $.Release.Name }}-s3 +spec: + replicas: {{ .Values.s3.replicas }} + minReplicas: 1 + kind: seaweedfs + type: s3 + selector: + app.kubernetes.io/component: s3 + app.kubernetes.io/name: seaweedfs + version: {{ $.Chart.Version }} {{- end }} diff --git a/packages/extra/seaweedfs/values.schema.json b/packages/extra/seaweedfs/values.schema.json index 2d890f27..4ec42d45 100644 --- a/packages/extra/seaweedfs/values.schema.json +++ b/packages/extra/seaweedfs/values.schema.json @@ -2,14 +2,108 @@ "title": "Chart Values", "type": "object", "properties": { + "db": { + "description": "Database Configuration", + "type": "object", + "default": { + "replicas": 2, + "resources": {}, + "resourcesPreset": "small", + "size": "10Gi", + "storageClass": "" + }, + "required": [ + "resources", + "resourcesPreset" + ], + "properties": { + "replicas": { + "description": "Number of database replicas", + "type": "integer", + "default": 2 + }, + "resources": { + "description": "Explicit CPU and memory configuration for the database. When left empty, the preset defined in `resourcesPreset` is applied.", + "type": "object", + "default": {}, + "properties": { + "cpu": { + "description": "The number of CPU cores allocated", + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "x-kubernetes-int-or-string": true + }, + "memory": { + "description": "The amount of memory allocated", + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "x-kubernetes-int-or-string": true + } + } + }, + "resourcesPreset": { + "description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.", + "type": "string", + "default": "small", + "enum": [ + "nano", + "micro", + "small", + "medium", + "large", + "xlarge", + "2xlarge" + ] + }, + "size": { + "description": "Persistent Volume size", + "default": "10Gi", + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "x-kubernetes-int-or-string": true + }, + "storageClass": { + "description": "StorageClass used to store the data", + "type": "string" + } + } + }, "filer": { "description": "Filer service configuration", "type": "object", "default": { "grpcHost": "", "grpcPort": 443, + "replicas": 2, + "resources": {}, + "resourcesPreset": "small", "whitelist": {} }, + "required": [ + "resources", + "resourcesPreset" + ], "properties": { "grpcHost": { "description": "The hostname used to expose or access the filer service externally.", @@ -20,6 +114,58 @@ "type": "integer", "default": 443 }, + "replicas": { + "description": "Number of filer replicas", + "type": "integer", + "default": 2 + }, + "resources": { + "description": "Explicit CPU and memory configuration for the filer. When left empty, the preset defined in `resourcesPreset` is applied.", + "type": "object", + "default": {}, + "properties": { + "cpu": { + "description": "The number of CPU cores allocated", + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "x-kubernetes-int-or-string": true + }, + "memory": { + "description": "The amount of memory allocated", + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "x-kubernetes-int-or-string": true + } + } + }, + "resourcesPreset": { + "description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.", + "type": "string", + "default": "small", + "enum": [ + "nano", + "micro", + "small", + "medium", + "large", + "xlarge", + "2xlarge" + ] + }, "whitelist": { "description": "A list of IP addresses or CIDR ranges that are allowed to access the filer service.", "type": "array", @@ -34,33 +180,144 @@ "description": "The hostname used to access the SeaweedFS externally (defaults to 's3' subdomain for the tenant host).", "type": "string" }, - "replicas": { - "description": "Number of replicas", - "type": "integer", - "default": 2 + "master": { + "description": "Master service configuration", + "type": "object", + "default": { + "replicas": 3, + "resources": {}, + "resourcesPreset": "small" + }, + "required": [ + "resources", + "resourcesPreset" + ], + "properties": { + "replicas": { + "description": "Number of master replicas", + "type": "integer", + "default": 3 + }, + "resources": { + "description": "Explicit CPU and memory configuration for the master. When left empty, the preset defined in `resourcesPreset` is applied.", + "type": "object", + "default": {}, + "properties": { + "cpu": { + "description": "The number of CPU cores allocated", + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "x-kubernetes-int-or-string": true + }, + "memory": { + "description": "The amount of memory allocated", + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "x-kubernetes-int-or-string": true + } + } + }, + "resourcesPreset": { + "description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.", + "type": "string", + "default": "small", + "enum": [ + "nano", + "micro", + "small", + "medium", + "large", + "xlarge", + "2xlarge" + ] + } + } }, "replicationFactor": { "description": "Replication factor: number of replicas for each volume in the SeaweedFS cluster.", "type": "integer", "default": 2 }, - "size": { - "description": "Persistent Volume size", - "default": "10Gi", - "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", - "anyOf": [ - { - "type": "integer" - }, - { - "type": "string" - } + "s3": { + "description": "S3 service configuration", + "type": "object", + "default": { + "replicas": 2, + "resources": {}, + "resourcesPreset": "small" + }, + "required": [ + "resources", + "resourcesPreset" ], - "x-kubernetes-int-or-string": true - }, - "storageClass": { - "description": "StorageClass used to store the data", - "type": "string" + "properties": { + "replicas": { + "description": "Number of s3 replicas", + "type": "integer", + "default": 2 + }, + "resources": { + "description": "Explicit CPU and memory configuration for the s3. When left empty, the preset defined in `resourcesPreset` is applied.", + "type": "object", + "default": {}, + "properties": { + "cpu": { + "description": "The number of CPU cores allocated", + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "x-kubernetes-int-or-string": true + }, + "memory": { + "description": "The amount of memory allocated", + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "x-kubernetes-int-or-string": true + } + } + }, + "resourcesPreset": { + "description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.", + "type": "string", + "default": "small", + "enum": [ + "nano", + "micro", + "small", + "medium", + "large", + "xlarge", + "2xlarge" + ] + } + } }, "topology": { "description": "The topology of the SeaweedFS cluster. (allowed values: Simple, MultiZone, Client)", @@ -72,33 +329,117 @@ "Client" ] }, - "zones": { - "description": "A map of zones for MultiZone topology. Each zone can have its own number of replicas and size.", + "volume": { + "description": "Volume service configuration", "type": "object", - "default": {}, - "additionalProperties": { - "type": "object", - "required": [ - "replicas", - "size" - ], - "properties": { - "replicas": { - "description": "Number of replicas in the zone", - "type": "integer" - }, - "size": { - "description": "Zone storage size", - "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", - "anyOf": [ - { + "default": { + "replicas": 2, + "resources": {}, + "resourcesPreset": "small", + "size": "10Gi", + "storageClass": "", + "zones": {} + }, + "required": [ + "resources", + "resourcesPreset" + ], + "properties": { + "replicas": { + "description": "Number of volume replicas", + "type": "integer", + "default": 2 + }, + "resources": { + "description": "Explicit CPU and memory configuration for the volume. When left empty, the preset defined in `resourcesPreset` is applied.", + "type": "object", + "default": {}, + "properties": { + "cpu": { + "description": "The number of CPU cores allocated", + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "x-kubernetes-int-or-string": true + }, + "memory": { + "description": "The amount of memory allocated", + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "x-kubernetes-int-or-string": true + } + } + }, + "resourcesPreset": { + "description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.", + "type": "string", + "default": "small", + "enum": [ + "nano", + "micro", + "small", + "medium", + "large", + "xlarge", + "2xlarge" + ] + }, + "size": { + "description": "Persistent Volume size", + "default": "10Gi", + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "x-kubernetes-int-or-string": true + }, + "storageClass": { + "description": "StorageClass used to store the data", + "type": "string" + }, + "zones": { + "description": "A map of zones for MultiZone topology. Each zone can have its own number of replicas and size.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "object", + "properties": { + "replicas": { + "description": "Number of replicas in the zone", "type": "integer" }, - { - "type": "string" + "size": { + "description": "Zone storage size", + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "x-kubernetes-int-or-string": true } - ], - "x-kubernetes-int-or-string": true + } } } } diff --git a/packages/extra/seaweedfs/values.yaml b/packages/extra/seaweedfs/values.yaml index 40f33d1b..d4eb33e5 100644 --- a/packages/extra/seaweedfs/values.yaml +++ b/packages/extra/seaweedfs/values.yaml @@ -4,42 +4,93 @@ host: "" ## @param topology {string enum:"Simple,MultiZone,Client"} The topology of the SeaweedFS cluster. (allowed values: Simple, MultiZone, Client) -## topology: Simple ## @param replicationFactor {int} Replication factor: number of replicas for each volume in the SeaweedFS cluster. replicationFactor: 2 -## @param replicas {int} Number of replicas +## @section SeaweedFS Components Configuration ## -replicas: 2 -## @param size {quantity} Persistent Volume size -size: 10Gi -## @param storageClass {*string} StorageClass used to store the data -storageClass: "" +## @param db {db} Database Configuration +db: + ## @field db.replicas {*int} Number of database replicas + ## @field db.size {*quantity} Persistent Volume size + ## @field db.storageClass {*string} StorageClass used to store the data + replicas: 2 + size: "10Gi" + storageClass: "" + ## @field db.resources {resources} Explicit CPU and memory configuration for the database. When left empty, the preset defined in `resourcesPreset` is applied. + ## @field resources {*resources} Resource configuration for etcd + ## @field resources.cpu {*quantity} The number of CPU cores allocated + ## @field resources.memory {*quantity} The amount of memory allocated + ## e.g: + ## resources: + ## cpu: 4000m + ## memory: 4Gi + ## + ## @field db.resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. + resources: {} + resourcesPreset: "small" -## @param zones {map[string]zone} A map of zones for MultiZone topology. Each zone can have its own number of replicas and size. -## @field zone.replicas {int} Number of replicas in the zone -## @field zone.size {quantity} Zone storage size -## Example: -## zones: -## dc1: -## replicas: 2 -## size: 10Gi -## dc2: -## replicas: 2 -## size: 10Gi -## dc3: -## replicas: 2 -## size: 10Gi -zones: {} +## @param master {*master} Master service configuration +master: + ## @field master.replicas {*int} Number of master replicas + ## @field master.resources {resources} Explicit CPU and memory configuration for the master. When left empty, the preset defined in `resourcesPreset` is applied. + ## @field master.resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. + replicas: 3 + resources: {} + resourcesPreset: "small" ## @param filer {*filer} Filer service configuration -## @field filer.grpcHost {*string} The hostname used to expose or access the filer service externally. -## @field filer.grpcPort {*int} The port used to access the filer service externally. -## TODO: select a more appropriate type after resolving https://github.com/cozystack/cozyvalues-gen/issues/4 -## @field filer.whitelist {[]*string} A list of IP addresses or CIDR ranges that are allowed to access the filer service. filer: + ## @field filer.replicas {*int} Number of filer replicas + ## @field filer.resources {resources} Explicit CPU and memory configuration for the filer. When left empty, the preset defined in `resourcesPreset` is applied. + ## @field filer.resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. + replicas: 2 + resources: {} + resourcesPreset: "small" + + ## @field filer.grpcHost {*string} The hostname used to expose or access the filer service externally. + ## @field filer.grpcPort {*int} The port used to access the filer service externally. + ## @field filer.whitelist {[]*string} A list of IP addresses or CIDR ranges that are allowed to access the filer service. grpcHost: "" grpcPort: 443 whitelist: [] + +## @param volume {*volume} Volume service configuration +volume: + ## @field volume.replicas {*int} Number of volume replicas + ## @field volume.size {*quantity} Persistent Volume size + ## @field volume.storageClass {*string} StorageClass used to store the data + ## @field volume.resources {resources} Explicit CPU and memory configuration for the volume. When left empty, the preset defined in `resourcesPreset` is applied. + ## @field volume.resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. + replicas: 2 + size: 10Gi + storageClass: "" + resources: {} + resourcesPreset: "small" + + ## @field volume.zones {map[string]zone} A map of zones for MultiZone topology. Each zone can have its own number of replicas and size. + ## @field zone.replicas {*int} Number of replicas in the zone + ## @field zone.size {*quantity} Zone storage size + ## Example: + ## zones: + ## dc1: + ## replicas: 2 + ## size: 10Gi + ## dc2: + ## replicas: 2 + ## size: 10Gi + ## dc3: + ## replicas: 2 + ## size: 10Gi + zones: {} + +## @param s3 {*s3} S3 service configuration +s3: + ## @field s3.replicas {*int} Number of s3 replicas + ## @field s3.resources {resources} Explicit CPU and memory configuration for the s3. When left empty, the preset defined in `resourcesPreset` is applied. + ## @field s3.resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. + replicas: 2 + resources: {} + resourcesPreset: "small" diff --git a/packages/extra/versions_map b/packages/extra/versions_map index ce0cdd27..c4da9c51 100644 --- a/packages/extra/versions_map +++ b/packages/extra/versions_map @@ -63,4 +63,5 @@ seaweedfs 0.3.0 45a7416c seaweedfs 0.4.0 632224a3 seaweedfs 0.4.1 8c86905b seaweedfs 0.5.0 9584e5f5 -seaweedfs 0.6.0 HEAD +seaweedfs 0.6.0 8f1975d1 +seaweedfs 0.7.0 HEAD diff --git a/packages/system/seaweedfs/templates/database.yaml b/packages/system/seaweedfs/templates/database.yaml index dc11b101..e78caa89 100644 --- a/packages/system/seaweedfs/templates/database.yaml +++ b/packages/system/seaweedfs/templates/database.yaml @@ -4,9 +4,12 @@ kind: Cluster metadata: name: seaweedfs-db spec: - instances: 2 + instances: {{ .Values.db.replicas }} storage: - size: 10Gi + size: {{ .Values.db.size }} + {{- with .Values.db.storageClass }} + storageClass: {{ . }} + {{- end }} monitoring: enablePodMonitor: true diff --git a/packages/system/seaweedfs/values.yaml b/packages/system/seaweedfs/values.yaml index 9cb6d915..f7ff2388 100644 --- a/packages/system/seaweedfs/values.yaml +++ b/packages/system/seaweedfs/values.yaml @@ -70,6 +70,7 @@ seaweedfs: key: password name: seaweedfs-db-app s3: + replicas: 2 enabled: true port: 8333 httpsPort: 0 @@ -109,13 +110,6 @@ seaweedfs: - hosts: - seaweedfs.demo.cozystack.io secretName: seaweedfs-s3-ingress-tls - resources: - limits: - cpu: "2" - memory: "2Gi" - requests: - cpu: "500m" - memory: "1Gi" cosi: enabled: true podLabels: @@ -132,3 +126,7 @@ seaweedfs: keySize: 2048 duration: 2160h # 90d renewBefore: 360h # 15d +db: + replicas: 2 + size: 10Gi + storageClass: "" diff --git a/scripts/migrations/19 b/scripts/migrations/19 new file mode 100755 index 00000000..0a9c961a --- /dev/null +++ b/scripts/migrations/19 @@ -0,0 +1,48 @@ +#!/bin/sh +# Migration 19 --> 20 + +set -euo pipefail + +kubectl get helmreleases.helm.toolkit.fluxcd.io -A \ + --field-selector=metadata.name=seaweedfs -o json | jq -r ' + .items[] as $o + | ($o.metadata.namespace // "") as $ns + | $o.metadata.name as $name + | $o.spec as $s + | $o.spec.values as $v + + # Нужно ли менять + | ( + ($s.chart.spec.version? // "") != "0.7.0" + or ($v.size? != null) + or ($v.storageClass? != null) + or ($v.replicas? != null) + or ($v.zones? != null) + ) as $needsChange + | select($needsChange) + + # JSON Patch + | [ + { op:"add", path:"/spec/chart/spec/version", value:"0.7.0" }, + + (if ($v.volume? | type) != "object" then {op:"add", path:"/spec/values/volume", value:{}} else empty end), + + (if $v.size? then {op:"add", path:"/spec/values/volume/size", value:$v.size} else empty end), + (if $v.storageClass? then {op:"add", path:"/spec/values/volume/storageClass", value:$v.storageClass} else empty end), + (if $v.replicas? then {op:"add", path:"/spec/values/volume/replicas", value:$v.replicas} else empty end), + (if $v.zones? then {op:"add", path:"/spec/values/volume/zones", value:$v.zones} else empty end), + + (if $v.size? then {op:"remove", path:"/spec/values/size"} else empty end), + (if $v.storageClass? then {op:"remove", path:"/spec/values/storageClass"} else empty end), + (if $v.replicas? then {op:"remove", path:"/spec/values/replicas"} else empty end), + (if $v.zones? then {op:"remove", path:"/spec/values/zones"} else empty end) + ] as $patch + + | "kubectl " + + (if $ns != "" then "-n \($ns) " else "" end) + + "patch helmreleases.helm.toolkit.fluxcd.io \($name) --type=json -p '\''\($patch|tojson)'\''" +' | sh -ex + +# Stamp version +kubectl create configmap -n cozy-system cozystack-version \ + --from-literal=version=20 --dry-run=client -o yaml | kubectl apply -f-