Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion charts/flowise/ci/queue-s3.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ architecture:
mode: queue

flowise:
replicaCount: 2
replicaCount: 1

persistence:
enabled: false
Expand Down
55 changes: 53 additions & 2 deletions charts/flowise/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,11 @@ redis-password
{{- end -}}

{{- define "flowise.mainCommand" -}}
sleep 3; flowise start
sleep {{ int .Values.flowise.startupDelaySeconds }}; flowise start
{{- end -}}

{{- define "flowise.workerCommand" -}}
sleep 3; flowise worker
sleep {{ int .Values.queue.worker.startupDelaySeconds }}; flowise worker
{{- end -}}

{{- define "flowise.backupSecretName" -}}
Expand Down Expand Up @@ -281,3 +281,54 @@ sleep 3; flowise worker
true
{{- end -}}
{{- end -}}

{{- define "flowise.validate" -}}
{{- $arch := include "flowise.architectureMode" . -}}
{{- $dbMode := include "flowise.databaseMode" . -}}
{{- if and (eq $arch "queue") (eq $dbMode "sqlite") -}}
{{- fail "architecture.mode=queue requires database.mode to resolve to external or postgresql, not sqlite" -}}
{{- end -}}
{{- if and (eq $arch "queue") (eq (include "flowise.redisMode" .) "none") -}}
{{- fail "architecture.mode=queue requires Redis: enable redis.enabled or configure redis.external.host" -}}
{{- end -}}
{{- if and (eq $arch "queue") (ne .Values.storage.type "s3") -}}
{{- fail "architecture.mode=queue requires storage.type=s3 for shared blob storage across main and worker pods" -}}
{{- end -}}
{{- if and (eq $arch "queue") .Values.persistence.enabled -}}
{{- fail "architecture.mode=queue requires persistence.enabled=false because shared local volumes are not a valid scalable topology for Flowise" -}}
{{- end -}}
{{- if and (eq $dbMode "sqlite") (gt (int .Values.flowise.replicaCount) 1) -}}
{{- fail "SQLite mode only supports flowise.replicaCount=1" -}}
{{- end -}}
{{- if and (eq .Values.storage.type "local") (gt (int .Values.flowise.replicaCount) 1) -}}
{{- fail "local storage only supports flowise.replicaCount=1; use storage.type=s3 for multiple replicas" -}}
{{- end -}}
{{- if and (eq .Values.storage.type "s3") (eq (.Values.storage.s3.bucketName | default "") "") -}}
{{- fail "storage.type=s3 requires storage.s3.bucketName" -}}
{{- end -}}
{{- if and (eq .Values.storage.type "s3") (not (or .Values.storage.s3.existingSecret (and .Values.storage.s3.accessKeyId .Values.storage.s3.secretAccessKey))) -}}
{{- fail "storage.type=s3 requires storage.s3.existingSecret or inline storage.s3.accessKeyId and storage.s3.secretAccessKey" -}}
{{- end -}}
{{- $podLabels := .Values.podLabels | default dict -}}
{{- if hasKey $podLabels "app.kubernetes.io/name" -}}
{{- fail "podLabels must not override the selector label app.kubernetes.io/name" -}}
{{- end -}}
{{- if hasKey $podLabels "app.kubernetes.io/instance" -}}
{{- fail "podLabels must not override the selector label app.kubernetes.io/instance" -}}
{{- end -}}
{{- if hasKey $podLabels "app.kubernetes.io/component" -}}
{{- fail "podLabels must not override the selector label app.kubernetes.io/component" -}}
{{- end -}}
{{- if eq $arch "queue" -}}
{{- $workerPodLabels := .Values.queue.worker.podLabels | default dict -}}
{{- if hasKey $workerPodLabels "app.kubernetes.io/name" -}}
{{- fail "queue.worker.podLabels must not override the selector label app.kubernetes.io/name" -}}
Comment thread
mberlofa marked this conversation as resolved.
{{- end -}}
{{- if hasKey $workerPodLabels "app.kubernetes.io/instance" -}}
{{- fail "queue.worker.podLabels must not override the selector label app.kubernetes.io/instance" -}}
{{- end -}}
{{- if hasKey $workerPodLabels "app.kubernetes.io/component" -}}
{{- fail "queue.worker.podLabels must not override the selector label app.kubernetes.io/component" -}}
{{- end -}}
{{- end -}}
{{- end -}}
29 changes: 2 additions & 27 deletions charts/flowise/templates/validate.yaml
Original file line number Diff line number Diff line change
@@ -1,27 +1,2 @@
{{/* SPDX-License-Identifier: Apache-2.0 */}}
{{- $arch := include "flowise.architectureMode" . -}}
{{- $dbMode := include "flowise.databaseMode" . -}}
{{- if and (eq $arch "queue") (eq $dbMode "sqlite") -}}
{{- fail "architecture.mode=queue requires database.mode to resolve to external or postgresql, not sqlite" -}}
{{- end -}}
{{- if and (eq $arch "queue") (eq (include "flowise.redisMode" .) "none") -}}
{{- fail "architecture.mode=queue requires Redis: enable redis.enabled or configure redis.external.host" -}}
{{- end -}}
{{- if and (eq $arch "queue") (ne .Values.storage.type "s3") -}}
{{- fail "architecture.mode=queue requires storage.type=s3 for shared blob storage across main and worker pods" -}}
{{- end -}}
{{- if and (eq $arch "queue") .Values.persistence.enabled -}}
{{- fail "architecture.mode=queue requires persistence.enabled=false because shared local volumes are not a valid scalable topology for Flowise" -}}
{{- end -}}
{{- if and (eq $dbMode "sqlite") (gt (int .Values.flowise.replicaCount) 1) -}}
{{- fail "SQLite mode only supports flowise.replicaCount=1" -}}
{{- end -}}
{{- if and (eq .Values.storage.type "local") (gt (int .Values.flowise.replicaCount) 1) -}}
{{- fail "local storage only supports flowise.replicaCount=1; use storage.type=s3 for multiple replicas" -}}
{{- end -}}
{{- if and (eq .Values.storage.type "s3") (eq (.Values.storage.s3.bucketName | default "") "") -}}
{{- fail "storage.type=s3 requires storage.s3.bucketName" -}}
{{- end -}}
{{- if and (eq .Values.storage.type "s3") (not (or .Values.storage.s3.existingSecret (and .Values.storage.s3.accessKeyId .Values.storage.s3.secretAccessKey))) -}}
{{- fail "storage.type=s3 requires storage.s3.existingSecret or inline storage.s3.accessKeyId and storage.s3.secretAccessKey" -}}
{{- end -}}
# SPDX-License-Identifier: Apache-2.0
{{- include "flowise.validate" . -}}
9 changes: 9 additions & 0 deletions charts/flowise/tests/deployment_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ tests:
path: spec.template.spec.containers[0].args
content: sleep 3; flowise start

- it: supports configurable startup delay for the main deployment
template: templates/deployment.yaml
set:
flowise.startupDelaySeconds: 12
asserts:
- contains:
path: spec.template.spec.containers[0].args
content: sleep 12; flowise start

- it: renders queue mode with redis and postgresql settings on the main deployment
template: templates/deployment.yaml
set:
Expand Down
119 changes: 119 additions & 0 deletions charts/flowise/tests/validation_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# SPDX-License-Identifier: Apache-2.0
suite: validation
templates:
- templates/validate.yaml
tests:
- it: passes with default values
asserts:
- hasDocuments:
count: 0

- it: fails when queue mode resolves to sqlite
set:
architecture.mode: queue
asserts:
- failedTemplate:
errorMessage: architecture.mode=queue requires database.mode to resolve to external or postgresql, not sqlite

- it: fails when queue mode has no Redis
set:
architecture.mode: queue
postgresql.enabled: true
persistence.enabled: false
storage.type: s3
storage.s3.bucketName: flowise
storage.s3.existingSecret: flowise-s3
asserts:
- failedTemplate:
errorMessage: "architecture.mode=queue requires Redis: enable redis.enabled or configure redis.external.host"

- it: fails when queue mode does not use S3 storage
set:
architecture.mode: queue
postgresql.enabled: true
redis.enabled: true
persistence.enabled: false
storage.type: local
asserts:
- failedTemplate:
errorMessage: architecture.mode=queue requires storage.type=s3 for shared blob storage across main and worker pods

- it: fails when queue mode leaves local persistence enabled
set:
architecture.mode: queue
postgresql.enabled: true
redis.enabled: true
storage.type: s3
storage.s3.bucketName: flowise
storage.s3.existingSecret: flowise-s3
persistence.enabled: true
asserts:
- failedTemplate:
errorMessage: architecture.mode=queue requires persistence.enabled=false because shared local volumes are not a valid scalable topology for Flowise

- it: fails when sqlite has multiple replicas
set:
flowise.replicaCount: 2
asserts:
- failedTemplate:
errorMessage: SQLite mode only supports flowise.replicaCount=1

- it: fails when local storage has multiple replicas
set:
database.mode: external
database.external.host: postgres.example.com
flowise.replicaCount: 2
storage.type: local
asserts:
- failedTemplate:
errorMessage: local storage only supports flowise.replicaCount=1; use storage.type=s3 for multiple replicas

- it: fails when S3 storage has no bucket
set:
storage.type: s3
storage.s3.existingSecret: flowise-s3
asserts:
- failedTemplate:
errorMessage: storage.type=s3 requires storage.s3.bucketName

- it: fails when S3 storage has no credentials
set:
storage.type: s3
storage.s3.bucketName: flowise
storage.s3.existingSecret: ""
storage.s3.accessKeyId: ""
storage.s3.secretAccessKey: ""
asserts:
- failedTemplate:
errorMessage: storage.type=s3 requires storage.s3.existingSecret or inline storage.s3.accessKeyId and storage.s3.secretAccessKey

- it: fails when podLabels override selector labels
set:
podLabels:
app.kubernetes.io/name: custom
asserts:
- failedTemplate:
errorMessage: podLabels must not override the selector label app.kubernetes.io/name

- it: fails when worker podLabels override selector labels
set:
architecture.mode: queue
persistence.enabled: false
storage.type: s3
storage.s3.bucketName: flowise
storage.s3.existingSecret: flowise-s3
postgresql.enabled: true
redis.enabled: true
queue.worker.podLabels:
app.kubernetes.io/component: custom
asserts:
- failedTemplate:
errorMessage: queue.worker.podLabels must not override the selector label app.kubernetes.io/component

- it: allows worker podLabels in standalone mode because no worker is rendered
set:
queue.worker.podLabels:
app.kubernetes.io/component: custom
asserts:
- hasDocuments:
count: 0
19 changes: 18 additions & 1 deletion charts/flowise/tests/worker-deployment_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ tests:
value: 3
- contains:
path: spec.template.spec.containers[0].args
content: sleep 3; flowise worker
content: sleep 30; flowise worker
- contains:
path: spec.template.spec.containers[0].env
content:
Expand All @@ -40,3 +40,20 @@ tests:
content:
name: WORKER_CONCURRENCY
value: "100000"

- it: supports configurable startup delay for workers
template: templates/worker-deployment.yaml
set:
architecture.mode: queue
persistence.enabled: false
storage.type: s3
storage.s3.bucketName: flowise
storage.s3.accessKeyId: minio
storage.s3.secretAccessKey: secret123
postgresql.enabled: true
redis.enabled: true
queue.worker.startupDelaySeconds: 45
asserts:
- contains:
path: spec.template.spec.containers[0].args
content: sleep 45; flowise worker
28 changes: 27 additions & 1 deletion charts/flowise/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"description": "Main Flowise application settings",
"properties": {
"replicaCount": { "type": "integer", "description": "Number of main Flowise server replicas" },
"startupDelaySeconds": { "type": "integer", "minimum": 0, "description": "Delay before starting the main Flowise server, in seconds" },
"appUrl": { "type": "string", "description": "Public application URL. Auto-detected from the first ingress host when empty." },
"logLevel": { "type": "string", "description": "Log level: error | warn | info | verbose | debug" },
"numberOfProxies": { "type": "integer", "description": "Rate-limit proxy count when running behind ingress or load balancers" },
Expand All @@ -53,7 +54,32 @@
}
},
"postgresql": { "type": "object", "description": "PostgreSQL subchart configuration" },
"queue": { "type": "object", "description": "Queue mode settings including worker replicas and concurrency" },
"queue": {
"type": "object",
"description": "Queue mode settings including worker replicas and concurrency",
"properties": {
"name": { "type": "string", "description": "Queue name used by Flowise main and workers" },
"worker": {
"type": "object",
"description": "Flowise worker settings used in queue mode",
"properties": {
"replicaCount": { "type": "integer", "minimum": 0, "description": "Number of Flowise worker replicas in queue mode" },
"startupDelaySeconds": {
"type": "integer",
"minimum": 0,
"description": "Delay before starting workers, in seconds"
},
"concurrency": { "type": "integer", "minimum": 0, "description": "Worker concurrency for BullMQ jobs" },
"removeOnAge": { "type": "integer", "minimum": 0, "description": "Number of completed jobs kept by age" },
"removeOnCount": { "type": "integer", "minimum": 0, "description": "Number of completed jobs kept by count" },
"podLabels": { "type": "object", "description": "Labels added to Flowise worker pods" },
"podAnnotations": { "type": "object", "description": "Annotations added to Flowise worker pods" },
"extraEnv": { "type": "array", "description": "Additional environment variables for Flowise workers", "items": { "type": "object" } },
"resources": { "type": "object", "description": "CPU and memory requests/limits for Flowise workers" }
}
}
}
},
"redis": { "type": "object", "description": "Redis subchart or external Redis configuration" },
"storage": {
"type": "object",
Expand Down
4 changes: 4 additions & 0 deletions charts/flowise/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ architecture:
flowise:
# -- Number of main Flowise server replicas
replicaCount: 1
# -- Delay before starting the main Flowise server, in seconds
startupDelaySeconds: 3
# -- Public application URL. Auto-detected from the first ingress host when empty.
appUrl: ""
# -- Log level: error | warn | info | verbose | debug
Expand Down Expand Up @@ -138,6 +140,8 @@ queue:
worker:
# -- Number of Flowise worker replicas in queue mode
replicaCount: 1
# -- Delay before starting workers, in seconds. Keeps first-boot migrations owned by the main server.
startupDelaySeconds: 30
# -- Worker concurrency for BullMQ jobs
concurrency: 100000
# -- Number of completed jobs kept by age
Expand Down