From 30e5b71e3f95aa51c65803e471bd52268450ba78 Mon Sep 17 00:00:00 2001 From: Nikita <166552198+nbykov0@users.noreply.github.com> Date: Tue, 2 Dec 2025 12:55:29 +0300 Subject: [PATCH 01/43] [system:monitoring-agents] rename coredns metrics service (#1676) ## What this PR does Renames coredns metrics service ### Release note ```release-note Renamed coredns metrics service not to interfere with coredns service used for name resolution in tenant k8s clusters. ``` --- .../system/monitoring-agents/templates/coredns-scrape.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/system/monitoring-agents/templates/coredns-scrape.yaml b/packages/system/monitoring-agents/templates/coredns-scrape.yaml index 9c7253eb..223d553f 100644 --- a/packages/system/monitoring-agents/templates/coredns-scrape.yaml +++ b/packages/system/monitoring-agents/templates/coredns-scrape.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Service metadata: - name: coredns + name: coredns-metrics namespace: kube-system labels: app: coredns @@ -19,7 +19,7 @@ spec: apiVersion: operator.victoriametrics.com/v1beta1 kind: VMServiceScrape metadata: - name: coredns + name: coredns-metrics namespace: cozy-monitoring spec: selector: From af56c105c2e2a0b6ba9c5e521db3f9f22954e116 Mon Sep 17 00:00:00 2001 From: Nikita <166552198+nbykov0@users.noreply.github.com> Date: Tue, 2 Dec 2025 14:48:34 +0300 Subject: [PATCH 02/43] [system:coredns] update coredns app labels to match Talos coredns labels (#1675) ## What this PR does Updates coredns app labels to match Talos coredns labels ### Release note ```release-note Coredns app labels updated to match Talos coredns labels. ``` --- packages/system/coredns/values.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/system/coredns/values.yaml b/packages/system/coredns/values.yaml index b52efda2..a1061a1e 100644 --- a/packages/system/coredns/values.yaml +++ b/packages/system/coredns/values.yaml @@ -3,3 +3,6 @@ coredns: repository: registry.k8s.io/coredns/coredns tag: v1.12.4 replicaCount: 2 + k8sAppLabelOverride: kube-dns + service: + name: kube-dns From 35907dd474c3460a87c21673909e0aacab1433e2 Mon Sep 17 00:00:00 2001 From: Nikita <166552198+nbykov0@users.noreply.github.com> Date: Tue, 2 Dec 2025 18:10:26 +0300 Subject: [PATCH 03/43] [core:installer] Address buildx warnings (#1682) ## What this PR does Buildx is worried about Dockerfile syntax, this pr fixes it. ``` - FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 1) - FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 16) ``` ### Release note ```release-note Buildx warnings addressed. ``` --- packages/core/installer/images/cozystack/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/installer/images/cozystack/Dockerfile b/packages/core/installer/images/cozystack/Dockerfile index 7327698e..c964c027 100644 --- a/packages/core/installer/images/cozystack/Dockerfile +++ b/packages/core/installer/images/cozystack/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.24-alpine as k8s-await-election-builder +FROM golang:1.24-alpine AS k8s-await-election-builder ARG K8S_AWAIT_ELECTION_GITREPO=https://github.com/LINBIT/k8s-await-election ARG K8S_AWAIT_ELECTION_VERSION=0.4.1 @@ -13,7 +13,7 @@ RUN git clone ${K8S_AWAIT_ELECTION_GITREPO} /usr/local/go/k8s-await-election/ \ && make \ && mv ./out/k8s-await-election-${TARGETARCH} /k8s-await-election -FROM golang:1.24-alpine as builder +FROM golang:1.24-alpine AS builder ARG TARGETOS ARG TARGETARCH From 2e22a6579eb0564647951409855a107d13ea0669 Mon Sep 17 00:00:00 2001 From: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com> Date: Thu, 4 Dec 2025 16:19:17 +0000 Subject: [PATCH 04/43] Prepare release v0.38.3 Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com> --- packages/apps/http-cache/images/nginx-cache.tag | 2 +- packages/apps/kubernetes/images/cluster-autoscaler.tag | 2 +- packages/apps/kubernetes/images/kubevirt-csi-driver.tag | 2 +- packages/core/installer/values.yaml | 2 +- packages/core/testing/values.yaml | 2 +- packages/extra/bootbox/images/matchbox.tag | 2 +- packages/extra/seaweedfs/images/objectstorage-sidecar.tag | 2 +- packages/system/bucket/images/s3manager.tag | 2 +- packages/system/cozystack-api/values.yaml | 2 +- packages/system/cozystack-controller/values.yaml | 4 ++-- packages/system/dashboard/templates/configmap.yaml | 2 +- packages/system/dashboard/values.yaml | 6 +++--- packages/system/kamaji/values.yaml | 4 ++-- packages/system/kubeovn-plunger/values.yaml | 2 +- packages/system/kubeovn-webhook/values.yaml | 2 +- packages/system/kubeovn/values.yaml | 2 +- packages/system/kubevirt-csi-node/values.yaml | 2 +- packages/system/lineage-controller-webhook/values.yaml | 2 +- packages/system/objectstorage-controller/values.yaml | 2 +- packages/system/seaweedfs/values.yaml | 2 +- 20 files changed, 24 insertions(+), 24 deletions(-) diff --git a/packages/apps/http-cache/images/nginx-cache.tag b/packages/apps/http-cache/images/nginx-cache.tag index 185dcc66..a5e4ca7b 100644 --- a/packages/apps/http-cache/images/nginx-cache.tag +++ b/packages/apps/http-cache/images/nginx-cache.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/nginx-cache:0.0.0@sha256:e0a07082bb6fc6aeaae2315f335386f1705a646c72f9e0af512aebbca5cb2b15 +ghcr.io/cozystack/cozystack/nginx-cache:0.0.0@sha256:b7633717cd7449c0042ae92d8ca9b36e4d69566561f5c7d44e21058e7d05c6d5 diff --git a/packages/apps/kubernetes/images/cluster-autoscaler.tag b/packages/apps/kubernetes/images/cluster-autoscaler.tag index d5ab33d1..56fcb024 100644 --- a/packages/apps/kubernetes/images/cluster-autoscaler.tag +++ b/packages/apps/kubernetes/images/cluster-autoscaler.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/cluster-autoscaler:0.0.0@sha256:2d39989846c3579dd020b9f6c77e6e314cc81aa344eaac0f6d633e723c17196d +ghcr.io/cozystack/cozystack/cluster-autoscaler:0.0.0@sha256:e1c0eb54d0ddadc8c7d72cee4f4282d56c957bf4ff0f62ef37db6b38dd0e8a01 diff --git a/packages/apps/kubernetes/images/kubevirt-csi-driver.tag b/packages/apps/kubernetes/images/kubevirt-csi-driver.tag index 80d3d2e6..3ac81184 100644 --- a/packages/apps/kubernetes/images/kubevirt-csi-driver.tag +++ b/packages/apps/kubernetes/images/kubevirt-csi-driver.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:d5c836ba33cf5dbed7e6f866784f668f80ffe69179e7c75847b680111984eefb +ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:16d58e3dde89301000322dbd48f41f6269e614ead0a4833d9285f29d3b81d9c9 diff --git a/packages/core/installer/values.yaml b/packages/core/installer/values.yaml index dbb7b846..69e4a7eb 100644 --- a/packages/core/installer/values.yaml +++ b/packages/core/installer/values.yaml @@ -1,2 +1,2 @@ cozystack: - image: ghcr.io/cozystack/cozystack/installer:v0.38.2@sha256:9ff92b655de6f9bea3cba4cd42dcffabd9aace6966dcfb1cc02dda2420ea4a15 + image: ghcr.io/cozystack/cozystack/installer:v0.38.3@sha256:4a6f0342ab48c206946f0d283072bf03f92a768bcbca525c66fc70cfa9fe1878 diff --git a/packages/core/testing/values.yaml b/packages/core/testing/values.yaml index de6bb330..9a05b875 100755 --- a/packages/core/testing/values.yaml +++ b/packages/core/testing/values.yaml @@ -1,2 +1,2 @@ e2e: - image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.38.2@sha256:84be9e42bc2c04b0765c8b89e0a9728c49ebf4676a92522b007af96ae9aec68d + image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.38.3@sha256:1edbc507b15dcdb26edd01cc00f2381f4c194c2653076ce95d056d7b41e1f363 diff --git a/packages/extra/bootbox/images/matchbox.tag b/packages/extra/bootbox/images/matchbox.tag index 2e63d30b..e7260e79 100644 --- a/packages/extra/bootbox/images/matchbox.tag +++ b/packages/extra/bootbox/images/matchbox.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/matchbox:v0.38.2@sha256:9cd7f46fcae119a3f8e35b428b018d0cb6da7b0cdd2ce764cc9fbf6dcd903f27 +ghcr.io/cozystack/cozystack/matchbox:v0.38.3@sha256:055da78b34e3e7f40716a5d73a7ffe2aa2e52b4c786f1a94a3365b42838f5f85 diff --git a/packages/extra/seaweedfs/images/objectstorage-sidecar.tag b/packages/extra/seaweedfs/images/objectstorage-sidecar.tag index ec59113f..f426312c 100644 --- a/packages/extra/seaweedfs/images/objectstorage-sidecar.tag +++ b/packages/extra/seaweedfs/images/objectstorage-sidecar.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.38.2@sha256:ff3281fe53a97d2cd5cd94bd4c4d8ff08189508729869bb39b3f60c80da5f919 +ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.38.3@sha256:60c979f9a81d560173f175bb04082b19a7e948fb3250e9d4acb560570fda68c9 diff --git a/packages/system/bucket/images/s3manager.tag b/packages/system/bucket/images/s3manager.tag index 1e12e68b..0bcbba4a 100644 --- a/packages/system/bucket/images/s3manager.tag +++ b/packages/system/bucket/images/s3manager.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/s3manager:v0.5.0@sha256:3825c9b4b6238f88f1b0de73bd18866a7e5f83f178d28fe2830f3bf24efb187d +ghcr.io/cozystack/cozystack/s3manager:v0.5.0@sha256:db7a293a3e37cb26a7428c387cbbaa7dd9b2adebd7f5d4e9c8fa945711313f47 diff --git a/packages/system/cozystack-api/values.yaml b/packages/system/cozystack-api/values.yaml index 8bf0a803..310cdb06 100644 --- a/packages/system/cozystack-api/values.yaml +++ b/packages/system/cozystack-api/values.yaml @@ -1,5 +1,5 @@ cozystackAPI: - image: ghcr.io/cozystack/cozystack/cozystack-api:v0.38.2@sha256:d17f1c59658731e5a2063c3db348adbc03b5cd31720052016b68449164cf2f14 + image: ghcr.io/cozystack/cozystack/cozystack-api:v0.38.3@sha256:123d8afa32bf2935fcffafdfa52366f799bbef2f8ecae5251925c212bdbe3236 localK8sAPIEndpoint: enabled: true replicas: 2 diff --git a/packages/system/cozystack-controller/values.yaml b/packages/system/cozystack-controller/values.yaml index 1b365a43..2d69bde3 100644 --- a/packages/system/cozystack-controller/values.yaml +++ b/packages/system/cozystack-controller/values.yaml @@ -1,6 +1,6 @@ cozystackController: - image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.38.2@sha256:468b2eccbc0aa00bd3d72d56624a46e6ba178fa279cdd19248af74d32ea7d319 + image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.38.3@sha256:ea9627e173e2d981cdf2d2106cb5bb153c0ae2be63ff8825cbe6f9b6e966825c debug: false disableTelemetry: false - cozystackVersion: "v0.38.2" + cozystackVersion: "v0.38.3" cozystackAPIKind: "DaemonSet" diff --git a/packages/system/dashboard/templates/configmap.yaml b/packages/system/dashboard/templates/configmap.yaml index bbf71610..e29ae562 100644 --- a/packages/system/dashboard/templates/configmap.yaml +++ b/packages/system/dashboard/templates/configmap.yaml @@ -1,6 +1,6 @@ {{- $brandingConfig:= lookup "v1" "ConfigMap" "cozy-system" "cozystack-branding" }} -{{- $tenantText := "v0.38.2" }} +{{- $tenantText := "v0.38.3" }} {{- $footerText := "Cozystack" }} {{- $titleText := "Cozystack Dashboard" }} {{- $logoText := "" }} diff --git a/packages/system/dashboard/values.yaml b/packages/system/dashboard/values.yaml index fed8149b..e3c37a38 100644 --- a/packages/system/dashboard/values.yaml +++ b/packages/system/dashboard/values.yaml @@ -1,6 +1,6 @@ openapiUI: - image: ghcr.io/cozystack/cozystack/openapi-ui:v0.38.2@sha256:5aafb6c864c5523418d021a9fe5b514990d36972b6f1de9c34a1cd41f9d8bf7e + image: ghcr.io/cozystack/cozystack/openapi-ui:v0.38.3@sha256:eabe3d9620450f48bdc7e4dc2797d4d0d1affa652f3c750aba0fab504adb3617 openapiUIK8sBff: - image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.38.2@sha256:7ffd8ae7b9da73fec7ae61a71c9c821a718d89a1b1df0197e09fda57678e1220 + image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.38.3@sha256:7646364cda96f3b6da421f28293db0256ae5dbce0a8912bf076eef3349968af2 tokenProxy: - image: ghcr.io/cozystack/cozystack/token-proxy:v0.38.2@sha256:fad27112617bb17816702571e1f39d0ac3fe5283468d25eb12f79906cdab566b + image: ghcr.io/cozystack/cozystack/token-proxy:v0.38.3@sha256:fad27112617bb17816702571e1f39d0ac3fe5283468d25eb12f79906cdab566b diff --git a/packages/system/kamaji/values.yaml b/packages/system/kamaji/values.yaml index b5b77213..5360e3ae 100644 --- a/packages/system/kamaji/values.yaml +++ b/packages/system/kamaji/values.yaml @@ -3,7 +3,7 @@ kamaji: deploy: false image: pullPolicy: IfNotPresent - tag: v0.38.2@sha256:13741b8f6dfede3ea0fd16d8bbebae810bc19254a81d7e5a139535efa17eabff + tag: v0.38.3@sha256:fa4ea889f29f50b48790c942d2f9b67d19c8643091047c0e6a33675fb3cd4127 repository: ghcr.io/cozystack/cozystack/kamaji resources: limits: @@ -13,4 +13,4 @@ kamaji: cpu: 100m memory: 100Mi extraArgs: - - --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.38.2@sha256:13741b8f6dfede3ea0fd16d8bbebae810bc19254a81d7e5a139535efa17eabff + - --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.38.3@sha256:fa4ea889f29f50b48790c942d2f9b67d19c8643091047c0e6a33675fb3cd4127 diff --git a/packages/system/kubeovn-plunger/values.yaml b/packages/system/kubeovn-plunger/values.yaml index 2e6fc195..43bfe135 100644 --- a/packages/system/kubeovn-plunger/values.yaml +++ b/packages/system/kubeovn-plunger/values.yaml @@ -1,4 +1,4 @@ portSecurity: true routes: "" -image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.38.2@sha256:76c8af24cbec0261718c13c0150aa81c238a956626d4fd7baa8970b47fb3a6f0 +image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.38.3@sha256:1c87e85c4c0aefbc1476637427c109b60cb43041d61e3ff572e17ef439c25e8b ovnCentralName: ovn-central diff --git a/packages/system/kubeovn-webhook/values.yaml b/packages/system/kubeovn-webhook/values.yaml index 9304c59d..360748e9 100644 --- a/packages/system/kubeovn-webhook/values.yaml +++ b/packages/system/kubeovn-webhook/values.yaml @@ -1,3 +1,3 @@ portSecurity: true routes: "" -image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.38.2@sha256:8e67b2971f8c079a8b0636be1d091a9545d6cb653d745ff222a5966f56f903bd +image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.38.3@sha256:6333b0bce5767f9c0e60534b44eed439495c8058059e1bea0106c5c0a69f6be4 diff --git a/packages/system/kubeovn/values.yaml b/packages/system/kubeovn/values.yaml index 72d62674..ebd16380 100644 --- a/packages/system/kubeovn/values.yaml +++ b/packages/system/kubeovn/values.yaml @@ -65,4 +65,4 @@ global: images: kubeovn: repository: kubeovn - tag: v1.14.11@sha256:8e6cf216687b4a80c35fa7c60bb4d511dd6aaaaf19d1ec53321dfef98d343f51 + tag: v1.14.11@sha256:6fd9d5fe756ccc25528751ecd0800994fdbe9212f60ac0e592510072ec8ddb55 diff --git a/packages/system/kubevirt-csi-node/values.yaml b/packages/system/kubevirt-csi-node/values.yaml index 8d2a7d45..e6c3dbb5 100644 --- a/packages/system/kubevirt-csi-node/values.yaml +++ b/packages/system/kubevirt-csi-node/values.yaml @@ -1,3 +1,3 @@ storageClass: replicated csiDriver: - image: ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:d5c836ba33cf5dbed7e6f866784f668f80ffe69179e7c75847b680111984eefb + image: ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:16d58e3dde89301000322dbd48f41f6269e614ead0a4833d9285f29d3b81d9c9 diff --git a/packages/system/lineage-controller-webhook/values.yaml b/packages/system/lineage-controller-webhook/values.yaml index ab5ccbbf..2fdd5c5d 100644 --- a/packages/system/lineage-controller-webhook/values.yaml +++ b/packages/system/lineage-controller-webhook/values.yaml @@ -1,5 +1,5 @@ lineageControllerWebhook: - image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.38.2@sha256:a5c750a0f46e8e25329b3ee2110d5dfb077c73e473195f1ed768d28d6f43902c + image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.38.3@sha256:20261c17e77d34daa08569e1f34613bc27ed5b147415a6a7292505970a5b30b3 debug: false localK8sAPIEndpoint: enabled: true diff --git a/packages/system/objectstorage-controller/values.yaml b/packages/system/objectstorage-controller/values.yaml index 7a5b5c22..54547a4c 100644 --- a/packages/system/objectstorage-controller/values.yaml +++ b/packages/system/objectstorage-controller/values.yaml @@ -1,3 +1,3 @@ objectstorage: controller: - image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.38.2@sha256:7d37495cce46d30d4613ecfacaa7b7f140e7ea8f3dbcc3e8c976e271de6cc71b" + image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.38.3@sha256:ee601d96a14e60dfbf3bf6c700688b797ba28c83db779068a1e0535b12b7daf8" diff --git a/packages/system/seaweedfs/values.yaml b/packages/system/seaweedfs/values.yaml index afe8283d..de7a0f92 100644 --- a/packages/system/seaweedfs/values.yaml +++ b/packages/system/seaweedfs/values.yaml @@ -124,7 +124,7 @@ seaweedfs: bucketClassName: "seaweedfs" region: "" sidecar: - image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.38.2@sha256:ff3281fe53a97d2cd5cd94bd4c4d8ff08189508729869bb39b3f60c80da5f919" + image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.38.3@sha256:60c979f9a81d560173f175bb04082b19a7e948fb3250e9d4acb560570fda68c9" certificates: commonName: "SeaweedFS CA" ipAddresses: [] From f1a75ab86407023eee19648e9cd461708727355a Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Sat, 6 Dec 2025 19:56:46 +0100 Subject: [PATCH 05/43] [linstor] Update piraeus-operator v2.10.2 Signed-off-by: Andrei Kvapil (cherry picked from commit 58dd1f5881d563af67cf4791f837f0c8467e7db1) --- .../charts/piraeus/Chart.yaml | 4 +-- .../charts/piraeus/templates/config.yaml | 8 ++--- .../charts/piraeus/templates/crds.yaml | 35 +++++++++++++++++++ 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/packages/system/piraeus-operator/charts/piraeus/Chart.yaml b/packages/system/piraeus-operator/charts/piraeus/Chart.yaml index 38bd15db..777722f3 100644 --- a/packages/system/piraeus-operator/charts/piraeus/Chart.yaml +++ b/packages/system/piraeus-operator/charts/piraeus/Chart.yaml @@ -3,8 +3,8 @@ name: piraeus description: | The Piraeus Operator manages software defined storage clusters using LINSTOR in Kubernetes. type: application -version: 2.10.1 -appVersion: "v2.10.1" +version: 2.10.2 +appVersion: "v2.10.2" maintainers: - name: Piraeus Datastore url: https://piraeus.io diff --git a/packages/system/piraeus-operator/charts/piraeus/templates/config.yaml b/packages/system/piraeus-operator/charts/piraeus/templates/config.yaml index a57dffd3..2e6963f0 100644 --- a/packages/system/piraeus-operator/charts/piraeus/templates/config.yaml +++ b/packages/system/piraeus-operator/charts/piraeus/templates/config.yaml @@ -23,10 +23,10 @@ data: tag: v1.32.3 image: piraeus-server linstor-csi: - tag: v1.10.2 + tag: v1.10.3 image: piraeus-csi nfs-server: - tag: v1.10.2 + tag: v1.10.3 image: piraeus-csi-nfs-server drbd-reactor: tag: v1.10.0 @@ -44,7 +44,7 @@ data: tag: v1.3.0 image: linstor-affinity-controller drbd-module-loader: - tag: v9.2.15 + tag: v9.2.16 # The special "match" attribute is used to select an image based on the node's reported OS. # The operator will first check the k8s node's ".status.nodeInfo.osImage" field, and compare it against the list # here. If one matches, that specific image name will be used instead of the fallback image. @@ -99,7 +99,7 @@ data: tag: v2.17.0 image: livenessprobe csi-provisioner: - tag: v6.0.0 + tag: v6.1.0 image: csi-provisioner csi-snapshotter: tag: v8.4.0 diff --git a/packages/system/piraeus-operator/charts/piraeus/templates/crds.yaml b/packages/system/piraeus-operator/charts/piraeus/templates/crds.yaml index 1821cb61..5bd9212c 100644 --- a/packages/system/piraeus-operator/charts/piraeus/templates/crds.yaml +++ b/packages/system/piraeus-operator/charts/piraeus/templates/crds.yaml @@ -993,6 +993,24 @@ spec: - Retain - Delete type: string + evacuationStrategy: + description: EvacuationStrategy configures the evacuation of volumes + from a Satellite when DeletionPolicy "Evacuate" is used. + nullable: true + properties: + attachedVolumeReattachTimeout: + default: 5m + description: |- + AttachedVolumeReattachTimeout configures how long evacuation waits for attached volumes to reattach on + different nodes. Setting this to 0 disable this evacuation step. + type: string + unattachedVolumeAttachTimeout: + default: 5m + description: |- + UnattachedVolumeAttachTimeout configures how long evacuation waits for unattached volumes to attach on + different nodes. Setting this to 0 disable this evacuation step. + type: string + type: object internalTLS: description: |- InternalTLS configures secure communication for the LINSTOR Satellite. @@ -1683,6 +1701,23 @@ spec: - Retain - Delete type: string + evacuationStrategy: + description: EvacuationStrategy configures the evacuation of volumes + from a Satellite when DeletionPolicy "Evacuate" is used. + properties: + attachedVolumeReattachTimeout: + default: 5m + description: |- + AttachedVolumeReattachTimeout configures how long evacuation waits for attached volumes to reattach on + different nodes. Setting this to 0 disable this evacuation step. + type: string + unattachedVolumeAttachTimeout: + default: 5m + description: |- + UnattachedVolumeAttachTimeout configures how long evacuation waits for unattached volumes to attach on + different nodes. Setting this to 0 disable this evacuation step. + type: string + type: object internalTLS: description: |- InternalTLS configures secure communication for the LINSTOR Satellite. From 891195018f3b895dee637b5c87f15b68c804795f Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Mon, 8 Dec 2025 23:27:24 +0100 Subject: [PATCH 06/43] [dashboard] Fix CustomFormsOverride schema to nest properties under spec.properties Signed-off-by: Andrei Kvapil (cherry picked from commit 578a810413c1521ff3f0e0b70c3da80ed31d851b) --- .../dashboard/customformsoverride.go | 20 +++- .../dashboard/customformsoverride_test.go | 94 +++++++++++-------- 2 files changed, 74 insertions(+), 40 deletions(-) diff --git a/internal/controller/dashboard/customformsoverride.go b/internal/controller/dashboard/customformsoverride.go index f88202bc..2b0daa08 100644 --- a/internal/controller/dashboard/customformsoverride.go +++ b/internal/controller/dashboard/customformsoverride.go @@ -105,8 +105,26 @@ func buildMultilineStringSchema(openAPISchema string) (map[string]any, error) { "properties": map[string]any{}, } + // Check if there's a spec property + specProp, ok := props["spec"].(map[string]any) + if !ok { + return map[string]any{}, nil + } + + specProps, ok := specProp["properties"].(map[string]any) + if !ok { + return map[string]any{}, nil + } + + // Create spec.properties structure in schema + schemaProps := schema["properties"].(map[string]any) + specSchema := map[string]any{ + "properties": map[string]any{}, + } + schemaProps["spec"] = specSchema + // Process spec properties recursively - processSpecProperties(props, schema["properties"].(map[string]any)) + processSpecProperties(specProps, specSchema["properties"].(map[string]any)) return schema, nil } diff --git a/internal/controller/dashboard/customformsoverride_test.go b/internal/controller/dashboard/customformsoverride_test.go index 2766bf17..9f7babe9 100644 --- a/internal/controller/dashboard/customformsoverride_test.go +++ b/internal/controller/dashboard/customformsoverride_test.go @@ -9,41 +9,46 @@ func TestBuildMultilineStringSchema(t *testing.T) { // Test OpenAPI schema with various field types openAPISchema := `{ "properties": { - "simpleString": { - "type": "string", - "description": "A simple string field" - }, - "stringWithEnum": { - "type": "string", - "enum": ["option1", "option2"], - "description": "String with enum should be skipped" - }, - "numberField": { - "type": "number", - "description": "Number field should be skipped" - }, - "nestedObject": { + "spec": { "type": "object", "properties": { - "nestedString": { + "simpleString": { "type": "string", - "description": "Nested string should get multilineString" + "description": "A simple string field" }, - "nestedStringWithEnum": { + "stringWithEnum": { "type": "string", - "enum": ["a", "b"], - "description": "Nested string with enum should be skipped" - } - } - }, - "arrayOfObjects": { - "type": "array", - "items": { - "type": "object", - "properties": { - "itemString": { - "type": "string", - "description": "String in array item" + "enum": ["option1", "option2"], + "description": "String with enum should be skipped" + }, + "numberField": { + "type": "number", + "description": "Number field should be skipped" + }, + "nestedObject": { + "type": "object", + "properties": { + "nestedString": { + "type": "string", + "description": "Nested string should get multilineString" + }, + "nestedStringWithEnum": { + "type": "string", + "enum": ["a", "b"], + "description": "Nested string with enum should be skipped" + } + } + }, + "arrayOfObjects": { + "type": "array", + "items": { + "type": "object", + "properties": { + "itemString": { + "type": "string", + "description": "String in array item" + } + } } } } @@ -70,33 +75,44 @@ func TestBuildMultilineStringSchema(t *testing.T) { t.Fatal("schema.properties is not a map") } - // Check simpleString - simpleString, ok := props["simpleString"].(map[string]any) + // Check spec property exists + spec, ok := props["spec"].(map[string]any) if !ok { - t.Fatal("simpleString not found in properties") + t.Fatal("spec not found in properties") + } + + specProps, ok := spec["properties"].(map[string]any) + if !ok { + t.Fatal("spec.properties is not a map") + } + + // Check simpleString + simpleString, ok := specProps["simpleString"].(map[string]any) + if !ok { + t.Fatal("simpleString not found in spec.properties") } if simpleString["type"] != "multilineString" { t.Errorf("simpleString should have type multilineString, got %v", simpleString["type"]) } // Check stringWithEnum should not be present (or should not have multilineString) - if stringWithEnum, ok := props["stringWithEnum"].(map[string]any); ok { + if stringWithEnum, ok := specProps["stringWithEnum"].(map[string]any); ok { if stringWithEnum["type"] == "multilineString" { t.Error("stringWithEnum should not have multilineString type") } } // Check numberField should not be present - if numberField, ok := props["numberField"].(map[string]any); ok { + if numberField, ok := specProps["numberField"].(map[string]any); ok { if numberField["type"] != nil { t.Error("numberField should not have any type override") } } // Check nested object - nestedObject, ok := props["nestedObject"].(map[string]any) + nestedObject, ok := specProps["nestedObject"].(map[string]any) if !ok { - t.Fatal("nestedObject not found in properties") + t.Fatal("nestedObject not found in spec.properties") } nestedProps, ok := nestedObject["properties"].(map[string]any) if !ok { @@ -113,9 +129,9 @@ func TestBuildMultilineStringSchema(t *testing.T) { } // Check array of objects - arrayOfObjects, ok := props["arrayOfObjects"].(map[string]any) + arrayOfObjects, ok := specProps["arrayOfObjects"].(map[string]any) if !ok { - t.Fatal("arrayOfObjects not found in properties") + t.Fatal("arrayOfObjects not found in spec.properties") } items, ok := arrayOfObjects["items"].(map[string]any) if !ok { From 548b2c0ed3dc9decb19ecab2682b53bc76157fd5 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Fri, 5 Dec 2025 17:18:01 +0100 Subject: [PATCH 07/43] [virtual-machine] Improve check for resizing job Signed-off-by: Andrei Kvapil (cherry picked from commit 0bab8950266b30476824feb1ef72b91007f5e8ff) --- .../virtual-machine/templates/vm-update-hook.yaml | 6 +++++- .../apps/vm-disk/templates/pvc-resize-hook.yaml | 15 ++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/packages/apps/virtual-machine/templates/vm-update-hook.yaml b/packages/apps/virtual-machine/templates/vm-update-hook.yaml index 74f76cc5..1197c027 100644 --- a/packages/apps/virtual-machine/templates/vm-update-hook.yaml +++ b/packages/apps/virtual-machine/templates/vm-update-hook.yaml @@ -27,7 +27,11 @@ {{- if and $existingPVC $desiredStorage -}} {{- $currentStorage := $existingPVC.spec.resources.requests.storage | toString -}} {{- if not (eq $currentStorage $desiredStorage) -}} - {{- $needResizePVC = true -}} + {{- $oldSize := (include "cozy-lib.resources.toFloat" $currentStorage) | float64 -}} + {{- $newSize := (include "cozy-lib.resources.toFloat" $desiredStorage) | float64 -}} + {{- if gt $newSize $oldSize -}} + {{- $needResizePVC = true -}} + {{- end -}} {{- end -}} {{- end -}} diff --git a/packages/apps/vm-disk/templates/pvc-resize-hook.yaml b/packages/apps/vm-disk/templates/pvc-resize-hook.yaml index 2619ed15..2454c599 100644 --- a/packages/apps/vm-disk/templates/pvc-resize-hook.yaml +++ b/packages/apps/vm-disk/templates/pvc-resize-hook.yaml @@ -1,5 +1,17 @@ {{- $existingPVC := lookup "v1" "PersistentVolumeClaim" .Release.Namespace .Release.Name }} -{{- if and $existingPVC (ne ($existingPVC.spec.resources.requests.storage | toString) .Values.storage) -}} +{{- $shouldResize := false -}} +{{- if and $existingPVC .Values.storage -}} + {{- $currentStorage := $existingPVC.spec.resources.requests.storage | toString -}} + {{- if ne $currentStorage .Values.storage -}} + {{- $oldSize := (include "cozy-lib.resources.toFloat" $currentStorage) | float64 -}} + {{- $newSize := (include "cozy-lib.resources.toFloat" .Values.storage) | float64 -}} + {{- if gt $newSize $oldSize -}} + {{- $shouldResize = true -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{- if $shouldResize -}} apiVersion: batch/v1 kind: Job metadata: @@ -23,6 +35,7 @@ spec: command: ["sh", "-xec"] args: - | + echo "Resizing PVC to {{ .Values.storage }}..." kubectl patch pvc {{ .Release.Name }} -p '{"spec":{"resources":{"requests":{"storage":"{{ .Values.storage }}"}}}}' --- apiVersion: v1 From 03328dc4e4389e84e4c8a1db4c576b57c040da1d Mon Sep 17 00:00:00 2001 From: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com> Date: Tue, 9 Dec 2025 16:23:14 +0000 Subject: [PATCH 08/43] Prepare release v0.38.4 Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com> --- packages/apps/http-cache/images/nginx-cache.tag | 2 +- packages/apps/kubernetes/images/kubevirt-csi-driver.tag | 2 +- packages/core/installer/values.yaml | 2 +- packages/core/testing/values.yaml | 2 +- packages/extra/bootbox/images/matchbox.tag | 2 +- packages/extra/seaweedfs/images/objectstorage-sidecar.tag | 2 +- packages/system/bucket/images/s3manager.tag | 2 +- packages/system/cozystack-api/values.yaml | 2 +- packages/system/cozystack-controller/values.yaml | 4 ++-- packages/system/dashboard/templates/configmap.yaml | 2 +- packages/system/dashboard/values.yaml | 6 +++--- packages/system/kamaji/values.yaml | 4 ++-- packages/system/kubeovn-plunger/values.yaml | 2 +- packages/system/kubeovn-webhook/values.yaml | 2 +- packages/system/kubeovn/values.yaml | 2 +- packages/system/kubevirt-csi-node/values.yaml | 2 +- packages/system/lineage-controller-webhook/values.yaml | 2 +- packages/system/objectstorage-controller/values.yaml | 2 +- packages/system/seaweedfs/values.yaml | 2 +- 19 files changed, 23 insertions(+), 23 deletions(-) diff --git a/packages/apps/http-cache/images/nginx-cache.tag b/packages/apps/http-cache/images/nginx-cache.tag index a5e4ca7b..0970e11c 100644 --- a/packages/apps/http-cache/images/nginx-cache.tag +++ b/packages/apps/http-cache/images/nginx-cache.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/nginx-cache:0.0.0@sha256:b7633717cd7449c0042ae92d8ca9b36e4d69566561f5c7d44e21058e7d05c6d5 +ghcr.io/cozystack/cozystack/nginx-cache:0.0.0@sha256:50ac1581e3100bd6c477a71161cb455a341ffaf9e5e2f6086802e4e25271e8af diff --git a/packages/apps/kubernetes/images/kubevirt-csi-driver.tag b/packages/apps/kubernetes/images/kubevirt-csi-driver.tag index 3ac81184..61e9f2ba 100644 --- a/packages/apps/kubernetes/images/kubevirt-csi-driver.tag +++ b/packages/apps/kubernetes/images/kubevirt-csi-driver.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:16d58e3dde89301000322dbd48f41f6269e614ead0a4833d9285f29d3b81d9c9 +ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:47396dac04a24f824f82892c90efa160539e1e0f8ac697f5dc8ecf397e1ac413 diff --git a/packages/core/installer/values.yaml b/packages/core/installer/values.yaml index 69e4a7eb..e1a56418 100644 --- a/packages/core/installer/values.yaml +++ b/packages/core/installer/values.yaml @@ -1,2 +1,2 @@ cozystack: - image: ghcr.io/cozystack/cozystack/installer:v0.38.3@sha256:4a6f0342ab48c206946f0d283072bf03f92a768bcbca525c66fc70cfa9fe1878 + image: ghcr.io/cozystack/cozystack/installer:v0.38.4@sha256:2530f78cd456e0b0619d8db607c4d47127bbdd36b99f82a4029758a106169f09 diff --git a/packages/core/testing/values.yaml b/packages/core/testing/values.yaml index 9a05b875..97c640db 100755 --- a/packages/core/testing/values.yaml +++ b/packages/core/testing/values.yaml @@ -1,2 +1,2 @@ e2e: - image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.38.3@sha256:1edbc507b15dcdb26edd01cc00f2381f4c194c2653076ce95d056d7b41e1f363 + image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.38.4@sha256:8284585dfdc337d6720f44b82417b42dc9321661025a8c046e085004d4573597 diff --git a/packages/extra/bootbox/images/matchbox.tag b/packages/extra/bootbox/images/matchbox.tag index e7260e79..48db300d 100644 --- a/packages/extra/bootbox/images/matchbox.tag +++ b/packages/extra/bootbox/images/matchbox.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/matchbox:v0.38.3@sha256:055da78b34e3e7f40716a5d73a7ffe2aa2e52b4c786f1a94a3365b42838f5f85 +ghcr.io/cozystack/cozystack/matchbox:v0.38.4@sha256:8398c5546dedfcd9bf68a6eef165e423b2f0bcb10a21f7e76b7ae4a6beb579e2 diff --git a/packages/extra/seaweedfs/images/objectstorage-sidecar.tag b/packages/extra/seaweedfs/images/objectstorage-sidecar.tag index f426312c..c302bef2 100644 --- a/packages/extra/seaweedfs/images/objectstorage-sidecar.tag +++ b/packages/extra/seaweedfs/images/objectstorage-sidecar.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.38.3@sha256:60c979f9a81d560173f175bb04082b19a7e948fb3250e9d4acb560570fda68c9 +ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.38.4@sha256:5136a36dddb14d2b95ceefbf8cc4b0cf6411b2ec9ae6898173b24c57790cc857 diff --git a/packages/system/bucket/images/s3manager.tag b/packages/system/bucket/images/s3manager.tag index 0bcbba4a..ec7741c2 100644 --- a/packages/system/bucket/images/s3manager.tag +++ b/packages/system/bucket/images/s3manager.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/s3manager:v0.5.0@sha256:db7a293a3e37cb26a7428c387cbbaa7dd9b2adebd7f5d4e9c8fa945711313f47 +ghcr.io/cozystack/cozystack/s3manager:v0.5.0@sha256:b58f5b192d1f47026c19ad51a857e31c256a9ff46c24a5fbbfcfe4f61981b8eb diff --git a/packages/system/cozystack-api/values.yaml b/packages/system/cozystack-api/values.yaml index 310cdb06..920222b6 100644 --- a/packages/system/cozystack-api/values.yaml +++ b/packages/system/cozystack-api/values.yaml @@ -1,5 +1,5 @@ cozystackAPI: - image: ghcr.io/cozystack/cozystack/cozystack-api:v0.38.3@sha256:123d8afa32bf2935fcffafdfa52366f799bbef2f8ecae5251925c212bdbe3236 + image: ghcr.io/cozystack/cozystack/cozystack-api:v0.38.4@sha256:58dba7b8b9915ece3a5785b6178536377fce56dc55451f2736415cdeab9185ff localK8sAPIEndpoint: enabled: true replicas: 2 diff --git a/packages/system/cozystack-controller/values.yaml b/packages/system/cozystack-controller/values.yaml index 2d69bde3..d1446268 100644 --- a/packages/system/cozystack-controller/values.yaml +++ b/packages/system/cozystack-controller/values.yaml @@ -1,6 +1,6 @@ cozystackController: - image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.38.3@sha256:ea9627e173e2d981cdf2d2106cb5bb153c0ae2be63ff8825cbe6f9b6e966825c + image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.38.4@sha256:a5cbe6b939ce10125b975e0395c9bd4a0c880aabe93dae832afc9334d33b7f63 debug: false disableTelemetry: false - cozystackVersion: "v0.38.3" + cozystackVersion: "v0.38.4" cozystackAPIKind: "DaemonSet" diff --git a/packages/system/dashboard/templates/configmap.yaml b/packages/system/dashboard/templates/configmap.yaml index e29ae562..6219aa0e 100644 --- a/packages/system/dashboard/templates/configmap.yaml +++ b/packages/system/dashboard/templates/configmap.yaml @@ -1,6 +1,6 @@ {{- $brandingConfig:= lookup "v1" "ConfigMap" "cozy-system" "cozystack-branding" }} -{{- $tenantText := "v0.38.3" }} +{{- $tenantText := "v0.38.4" }} {{- $footerText := "Cozystack" }} {{- $titleText := "Cozystack Dashboard" }} {{- $logoText := "" }} diff --git a/packages/system/dashboard/values.yaml b/packages/system/dashboard/values.yaml index e3c37a38..52983589 100644 --- a/packages/system/dashboard/values.yaml +++ b/packages/system/dashboard/values.yaml @@ -1,6 +1,6 @@ openapiUI: - image: ghcr.io/cozystack/cozystack/openapi-ui:v0.38.3@sha256:eabe3d9620450f48bdc7e4dc2797d4d0d1affa652f3c750aba0fab504adb3617 + image: ghcr.io/cozystack/cozystack/openapi-ui:v0.38.4@sha256:aae9aea2aa9aea905f0dea051104bff75f05bf554ed450ae013225359ae4f316 openapiUIK8sBff: - image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.38.3@sha256:7646364cda96f3b6da421f28293db0256ae5dbce0a8912bf076eef3349968af2 + image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.38.4@sha256:2845688891e0cf9513768aa468ff4de5b6b40e58cc763bacbfe2b417ebad1bdf tokenProxy: - image: ghcr.io/cozystack/cozystack/token-proxy:v0.38.3@sha256:fad27112617bb17816702571e1f39d0ac3fe5283468d25eb12f79906cdab566b + image: ghcr.io/cozystack/cozystack/token-proxy:v0.38.4@sha256:fad27112617bb17816702571e1f39d0ac3fe5283468d25eb12f79906cdab566b diff --git a/packages/system/kamaji/values.yaml b/packages/system/kamaji/values.yaml index 5360e3ae..40d85177 100644 --- a/packages/system/kamaji/values.yaml +++ b/packages/system/kamaji/values.yaml @@ -3,7 +3,7 @@ kamaji: deploy: false image: pullPolicy: IfNotPresent - tag: v0.38.3@sha256:fa4ea889f29f50b48790c942d2f9b67d19c8643091047c0e6a33675fb3cd4127 + tag: v0.38.4@sha256:458b8ae75e845e08c3c3d20f8af0ea1d7f8933739609d19f266fbf280417b764 repository: ghcr.io/cozystack/cozystack/kamaji resources: limits: @@ -13,4 +13,4 @@ kamaji: cpu: 100m memory: 100Mi extraArgs: - - --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.38.3@sha256:fa4ea889f29f50b48790c942d2f9b67d19c8643091047c0e6a33675fb3cd4127 + - --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.38.4@sha256:458b8ae75e845e08c3c3d20f8af0ea1d7f8933739609d19f266fbf280417b764 diff --git a/packages/system/kubeovn-plunger/values.yaml b/packages/system/kubeovn-plunger/values.yaml index 43bfe135..9dc9d594 100644 --- a/packages/system/kubeovn-plunger/values.yaml +++ b/packages/system/kubeovn-plunger/values.yaml @@ -1,4 +1,4 @@ portSecurity: true routes: "" -image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.38.3@sha256:1c87e85c4c0aefbc1476637427c109b60cb43041d61e3ff572e17ef439c25e8b +image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.38.4@sha256:e8bd1f93e38b7b7d124deddd0c2498f7df0fbe89b613d12a0fbf3e47220f9053 ovnCentralName: ovn-central diff --git a/packages/system/kubeovn-webhook/values.yaml b/packages/system/kubeovn-webhook/values.yaml index 360748e9..83bbfd1a 100644 --- a/packages/system/kubeovn-webhook/values.yaml +++ b/packages/system/kubeovn-webhook/values.yaml @@ -1,3 +1,3 @@ portSecurity: true routes: "" -image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.38.3@sha256:6333b0bce5767f9c0e60534b44eed439495c8058059e1bea0106c5c0a69f6be4 +image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.38.4@sha256:cb39773a626f01da04cb4e818faa9460a7d193e045f5c80f2c2e9116d18ef3c0 diff --git a/packages/system/kubeovn/values.yaml b/packages/system/kubeovn/values.yaml index ebd16380..7de48124 100644 --- a/packages/system/kubeovn/values.yaml +++ b/packages/system/kubeovn/values.yaml @@ -65,4 +65,4 @@ global: images: kubeovn: repository: kubeovn - tag: v1.14.11@sha256:6fd9d5fe756ccc25528751ecd0800994fdbe9212f60ac0e592510072ec8ddb55 + tag: v1.14.11@sha256:e277ee347814af85528851cf3d604a65ab9fb2e833b173e658490c35e00596b0 diff --git a/packages/system/kubevirt-csi-node/values.yaml b/packages/system/kubevirt-csi-node/values.yaml index e6c3dbb5..6ff9991a 100644 --- a/packages/system/kubevirt-csi-node/values.yaml +++ b/packages/system/kubevirt-csi-node/values.yaml @@ -1,3 +1,3 @@ storageClass: replicated csiDriver: - image: ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:16d58e3dde89301000322dbd48f41f6269e614ead0a4833d9285f29d3b81d9c9 + image: ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:47396dac04a24f824f82892c90efa160539e1e0f8ac697f5dc8ecf397e1ac413 diff --git a/packages/system/lineage-controller-webhook/values.yaml b/packages/system/lineage-controller-webhook/values.yaml index 2fdd5c5d..80db7f86 100644 --- a/packages/system/lineage-controller-webhook/values.yaml +++ b/packages/system/lineage-controller-webhook/values.yaml @@ -1,5 +1,5 @@ lineageControllerWebhook: - image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.38.3@sha256:20261c17e77d34daa08569e1f34613bc27ed5b147415a6a7292505970a5b30b3 + image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.38.4@sha256:557e6cee3dfce7ec9e69b404806c6b3c3766fa523cb3dc1cbd7155c24af2cc96 debug: false localK8sAPIEndpoint: enabled: true diff --git a/packages/system/objectstorage-controller/values.yaml b/packages/system/objectstorage-controller/values.yaml index 54547a4c..b902622e 100644 --- a/packages/system/objectstorage-controller/values.yaml +++ b/packages/system/objectstorage-controller/values.yaml @@ -1,3 +1,3 @@ objectstorage: controller: - image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.38.3@sha256:ee601d96a14e60dfbf3bf6c700688b797ba28c83db779068a1e0535b12b7daf8" + image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.38.4@sha256:91ed0ba4de7958708f77427d2c752dece969236c13927c17033d792700e9c6f4" diff --git a/packages/system/seaweedfs/values.yaml b/packages/system/seaweedfs/values.yaml index de7a0f92..52ab1551 100644 --- a/packages/system/seaweedfs/values.yaml +++ b/packages/system/seaweedfs/values.yaml @@ -124,7 +124,7 @@ seaweedfs: bucketClassName: "seaweedfs" region: "" sidecar: - image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.38.3@sha256:60c979f9a81d560173f175bb04082b19a7e948fb3250e9d4acb560570fda68c9" + image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.38.4@sha256:5136a36dddb14d2b95ceefbf8cc4b0cf6411b2ec9ae6898173b24c57790cc857" certificates: commonName: "SeaweedFS CA" ipAddresses: [] From 1491535b354618008bd894f419174674bfdb84d1 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Mon, 1 Dec 2025 20:00:53 +0100 Subject: [PATCH 09/43] [apps] Refactor apiserver to use typed objects and fix UnstructuredList GVK This commit refactors the apiserver REST handlers to use typed objects (appsv1alpha1.Application) instead of unstructured.Unstructured, eliminating the need for runtime conversions and simplifying the codebase. Additionally, it fixes an issue where UnstructuredList objects were using the first registered kind from typeToGVK instead of the kind from the object's field when multiple kinds are registered with the same Go type. This is a more comprehensive fix for the problem addressed in https://github.com/cozystack/cozystack/pull/1630, which was reverted in https://github.com/cozystack/cozystack/pull/1677. The fix includes the upstream fix from kubernetes/kubernetes#135537, which enables short-circuit path for UnstructuredList similar to regular Unstructured objects, using GVK from the object field instead of typeToGVK. Changes: - Refactored rest.go handlers to use typed Application objects - Removed unstructured.Unstructured conversions - Fixed UnstructuredList GVK handling - Updated dependencies in go.mod/go.sum - Added e2e test for OpenAPI validation - Updated Dockerfile Signed-off-by: Andrei Kvapil (cherry picked from commit ca29fc855ab333781211c92fa648ad2efb6a53e1) --- go.mod | 11 +- go.sum | 4 +- hack/e2e-test-openapi.bats | 19 +++ pkg/registry/apps/application/rest.go | 178 +++++-------------------- pkg/registry/core/tenantmodule/rest.go | 101 +++++--------- 5 files changed, 95 insertions(+), 218 deletions(-) diff --git a/go.mod b/go.mod index 041aa96a..a843d2f3 100644 --- a/go.mod +++ b/go.mod @@ -6,11 +6,15 @@ go 1.23.0 require ( github.com/fluxcd/helm-controller/api v1.1.0 + github.com/go-logr/logr v1.4.2 + github.com/go-logr/zapr v1.3.0 github.com/google/gofuzz v1.2.0 github.com/onsi/ginkgo/v2 v2.19.0 github.com/onsi/gomega v1.33.1 + github.com/prometheus/client_golang v1.19.1 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 + go.uber.org/zap v1.27.0 gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.31.2 k8s.io/apiextensions-apiserver v0.31.2 @@ -44,9 +48,7 @@ require ( github.com/fluxcd/pkg/apis/meta v1.6.1 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-logr/zapr v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.23.0 // indirect @@ -74,7 +76,6 @@ require ( github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect @@ -94,7 +95,6 @@ require ( go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.31.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/net v0.33.0 // indirect @@ -119,3 +119,6 @@ require ( sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) + +// See: issues.k8s.io/135537 +replace k8s.io/apimachinery => github.com/cozystack/apimachinery v0.0.0-20251201201312-18e522a87614 diff --git a/go.sum b/go.sum index a1090f31..a32e6b3b 100644 --- a/go.sum +++ b/go.sum @@ -18,6 +18,8 @@ github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cozystack/apimachinery v0.0.0-20251201201312-18e522a87614 h1:jH9elECUvhiIs3IMv3oS5k1JgCLVsSK6oU4dmq5gyW8= +github.com/cozystack/apimachinery v0.0.0-20251201201312-18e522a87614/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -291,8 +293,6 @@ k8s.io/api v0.31.2 h1:3wLBbL5Uom/8Zy98GRPXpJ254nEFpl+hwndmk9RwmL0= k8s.io/api v0.31.2/go.mod h1:bWmGvrGPssSK1ljmLzd3pwCQ9MgoTsRCuK35u6SygUk= k8s.io/apiextensions-apiserver v0.31.2 h1:W8EwUb8+WXBLu56ser5IudT2cOho0gAKeTOnywBLxd0= k8s.io/apiextensions-apiserver v0.31.2/go.mod h1:i+Geh+nGCJEGiCGR3MlBDkS7koHIIKWVfWeRFiOsUcM= -k8s.io/apimachinery v0.31.2 h1:i4vUt2hPK56W6mlT7Ry+AO8eEsyxMD1U44NR22CLTYw= -k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= k8s.io/apiserver v0.31.2 h1:VUzOEUGRCDi6kX1OyQ801m4A7AUPglpsmGvdsekmcI4= k8s.io/apiserver v0.31.2/go.mod h1:o3nKZR7lPlJqkU5I3Ove+Zx3JuoFjQobGX1Gctw6XuE= k8s.io/client-go v0.31.2 h1:Y2F4dxU5d3AQj+ybwSMqQnpZH9F30//1ObxOKlTI9yc= diff --git a/hack/e2e-test-openapi.bats b/hack/e2e-test-openapi.bats index d94cb422..88ed734b 100644 --- a/hack/e2e-test-openapi.bats +++ b/hack/e2e-test-openapi.bats @@ -21,14 +21,33 @@ } @test "Test kinds" { + val=$(kubectl get --raw /apis/apps.cozystack.io/v1alpha1/tenants | jq -r '.kind') + if [ "$val" != "TenantList" ]; then + echo "Expected kind to be TenantList, got $val" + exit 1 + fi val=$(kubectl get --raw /apis/apps.cozystack.io/v1alpha1/tenants | jq -r '.items[0].kind') if [ "$val" != "Tenant" ]; then echo "Expected kind to be Tenant, got $val" exit 1 fi + val=$(kubectl get --raw /apis/apps.cozystack.io/v1alpha1/ingresses | jq -r '.kind') + if [ "$val" != "IngressList" ]; then + echo "Expected kind to be IngressList, got $val" + exit 1 + fi val=$(kubectl get --raw /apis/apps.cozystack.io/v1alpha1/ingresses | jq -r '.items[0].kind') if [ "$val" != "Ingress" ]; then echo "Expected kind to be Ingress, got $val" exit 1 fi } + +@test "Create and delete namespace" { + kubectl create ns cozy-test-create-and-delete-namespace --dry-run=client -o yaml | kubectl apply -f - + if ! kubectl delete ns cozy-test-create-and-delete-namespace; then + echo "Failed to delete namespace" + kubectl describe ns cozy-test-create-and-delete-namespace + exit 1 + fi +} diff --git a/pkg/registry/apps/application/rest.go b/pkg/registry/apps/application/rest.go index 03de7c08..704cd709 100644 --- a/pkg/registry/apps/application/rest.go +++ b/pkg/registry/apps/application/rest.go @@ -28,7 +28,6 @@ import ( helmv2 "github.com/fluxcd/helm-controller/api/v2" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" fields "k8s.io/apimachinery/pkg/fields" labels "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" @@ -142,17 +141,9 @@ func (r *REST) GetSingularName() string { // Create handles the creation of a new Application by converting it to a HelmRelease func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { // Assert the object is of type Application - us, ok := obj.(*unstructured.Unstructured) + app, ok := obj.(*appsv1alpha1.Application) if !ok { - return nil, fmt.Errorf("expected unstructured.Unstructured object, got %T", obj) - } - - app := &appsv1alpha1.Application{} - - if err := runtime.DefaultUnstructuredConverter.FromUnstructured(us.Object, app); err != nil { - errMsg := fmt.Sprintf("returned unstructured.Unstructured object was not an Application") - klog.Errorf(errMsg) - return nil, fmt.Errorf(errMsg) + return nil, fmt.Errorf("expected *appsv1alpha1.Application object, got %T", obj) } // Convert Application to HelmRelease @@ -186,15 +177,8 @@ func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation klog.V(6).Infof("Successfully created and converted HelmRelease %s to Application", helmRelease.GetName()) - // Convert Application to unstructured format - unstructuredApp, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&convertedApp) - if err != nil { - klog.Errorf("Failed to convert Application to unstructured for resource %s: %v", convertedApp.GetName(), err) - return nil, fmt.Errorf("failed to convert Application to unstructured: %v", err) - } - - klog.V(6).Infof("Successfully retrieved and converted resource %s of type %s to unstructured", convertedApp.GetName(), r.gvr.Resource) - return &unstructured.Unstructured{Object: unstructuredApp}, nil + klog.V(6).Infof("Successfully retrieved and converted resource %s of type %s", convertedApp.GetName(), r.gvr.Resource) + return &convertedApp, nil } // Get retrieves an Application by converting the corresponding HelmRelease @@ -238,25 +222,8 @@ func (r *REST) Get(ctx context.Context, name string, options *metav1.GetOptions) return nil, fmt.Errorf("conversion error: %v", err) } - // Explicitly set apiVersion and kind for Application - convertedApp.TypeMeta = metav1.TypeMeta{ - APIVersion: "apps.cozystack.io/v1alpha1", - Kind: r.kindName, - } - - // Convert Application to unstructured format - unstructuredApp, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&convertedApp) - if err != nil { - klog.Errorf("Failed to convert Application to unstructured for resource %s: %v", name, err) - return nil, fmt.Errorf("failed to convert Application to unstructured: %v", err) - } - - // Explicitly set apiVersion and kind in unstructured object - unstructuredApp["apiVersion"] = "apps.cozystack.io/v1alpha1" - unstructuredApp["kind"] = r.kindName - - klog.V(6).Infof("Successfully retrieved and converted resource %s of kind %s to unstructured", name, r.gvr.Resource) - return &unstructured.Unstructured{Object: unstructuredApp}, nil + klog.V(6).Infof("Successfully retrieved and converted resource %s of kind %s", name, r.gvr.Resource) + return &convertedApp, nil } // List retrieves a list of Applications by converting HelmReleases @@ -339,8 +306,8 @@ func (r *REST) List(ctx context.Context, options *metainternalversion.ListOption return nil, err } - // Initialize unstructured items array - items := make([]unstructured.Unstructured, 0) + // Initialize Application items array + items := make([]appsv1alpha1.Application, 0, len(hrList.Items)) // Iterate over HelmReleases and convert to Applications for i := range hrList.Items { @@ -387,17 +354,11 @@ func (r *REST) List(ctx context.Context, options *metainternalversion.ListOption } } - // Convert Application to unstructured - unstructuredApp, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&app) - if err != nil { - klog.Errorf("Error converting Application %s to unstructured: %v", app.Name, err) - continue - } - items = append(items, unstructured.Unstructured{Object: unstructuredApp}) + items = append(items, app) } - // Explicitly set apiVersion and kind in unstructured object - appList := r.NewList().(*unstructured.UnstructuredList) + // Create ApplicationList with proper kind + appList := r.NewList().(*appsv1alpha1.ApplicationList) appList.SetResourceVersion(hrList.GetResourceVersion()) appList.Items = items @@ -447,16 +408,9 @@ func (r *REST) Update(ctx context.Context, name string, objInfo rest.UpdatedObje } // Assert the new object is of type Application - us, ok := newObj.(*unstructured.Unstructured) + app, ok := newObj.(*appsv1alpha1.Application) if !ok { - errMsg := fmt.Sprintf("expected unstructured.Unstructured object, got %T", newObj) - klog.Errorf(errMsg) - return nil, false, fmt.Errorf(errMsg) - } - app := &appsv1alpha1.Application{} - - if err := runtime.DefaultUnstructuredConverter.FromUnstructured(us.Object, app); err != nil { - errMsg := fmt.Sprintf("returned unstructured.Unstructured object was not an Application") + errMsg := fmt.Sprintf("expected *appsv1alpha1.Application object, got %T", newObj) klog.Errorf(errMsg) return nil, false, fmt.Errorf(errMsg) } @@ -517,24 +471,9 @@ func (r *REST) Update(ctx context.Context, name string, objInfo rest.UpdatedObje klog.V(6).Infof("Successfully updated and converted HelmRelease %s to Application", helmRelease.GetName()) - // Explicitly set apiVersion and kind for Application - convertedApp.TypeMeta = metav1.TypeMeta{ - APIVersion: "apps.cozystack.io/v1alpha1", - Kind: r.kindName, - } + klog.V(6).Infof("Returning updated Application object: %+v", convertedApp) - // Convert Application to unstructured format - unstructuredApp, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&convertedApp) - if err != nil { - klog.Errorf("Failed to convert Application to unstructured for resource %s: %v", convertedApp.GetName(), err) - return nil, false, fmt.Errorf("failed to convert Application to unstructured: %v", err) - } - obj := &unstructured.Unstructured{Object: unstructuredApp} - obj.SetGroupVersionKind(r.gvk) - - klog.V(6).Infof("Returning patched Application object: %+v", unstructuredApp) - - return obj, false, nil + return &convertedApp, false, nil } // Delete removes an Application by deleting the corresponding HelmRelease @@ -728,19 +667,10 @@ func (r *REST) Watch(ctx context.Context, options *metainternalversion.ListOptio } } - // Convert Application to unstructured - unstructuredApp, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&app) - if err != nil { - klog.Errorf("Failed to convert Application to unstructured: %v", err) - continue - } - obj := &unstructured.Unstructured{Object: unstructuredApp} - obj.SetGroupVersionKind(r.gvk) - // Create watch event with Application object appEvent := watch.Event{ Type: event.Type, - Object: obj, + Object: &app, } // Send event to custom watcher @@ -766,8 +696,8 @@ func (r *REST) Watch(ctx context.Context, options *metainternalversion.ListOptio // Helper function to get HelmRelease name from object func helmReleaseName(obj runtime.Object) string { - if u, ok := obj.(*unstructured.Unstructured); ok { - return u.GetName() + if app, ok := obj.(*appsv1alpha1.Application); ok { + return app.GetName() } return "" } @@ -1059,56 +989,6 @@ func (r *REST) ConvertToTable(ctx context.Context, object runtime.Object, tableO case *appsv1alpha1.Application: table = r.buildTableFromApplication(*obj) table.ListMeta.ResourceVersion = obj.GetResourceVersion() - case *unstructured.UnstructuredList: - apps := make([]appsv1alpha1.Application, 0, len(obj.Items)) - for _, u := range obj.Items { - var a appsv1alpha1.Application - err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &a) - if err != nil { - klog.Errorf("Failed to convert Unstructured to Application: %v", err) - continue - } - apps = append(apps, a) - } - table = r.buildTableFromApplications(apps) - table.ListMeta.ResourceVersion = obj.GetResourceVersion() - case *unstructured.Unstructured: - var apps []appsv1alpha1.Application - for { - var items interface{} - var ok bool - var objects []unstructured.Unstructured - if items, ok = obj.Object["items"]; !ok { - break - } - if objects, ok = items.([]unstructured.Unstructured); !ok { - break - } - apps = make([]appsv1alpha1.Application, 0, len(objects)) - var a appsv1alpha1.Application - for i := range objects { - err := runtime.DefaultUnstructuredConverter.FromUnstructured(objects[i].Object, &a) - if err != nil { - klog.Errorf("Failed to convert Unstructured to Application: %v", err) - continue - } - apps = append(apps, a) - } - break - } - if apps != nil { - table = r.buildTableFromApplications(apps) - table.ListMeta.ResourceVersion = obj.GetResourceVersion() - break - } - var app appsv1alpha1.Application - err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), &app) - if err != nil { - klog.Errorf("Failed to convert Unstructured to Application: %v", err) - return nil, fmt.Errorf("failed to convert Unstructured to Application: %v", err) - } - table = r.buildTableFromApplication(app) - table.ListMeta.ResourceVersion = obj.GetResourceVersion() default: resource := schema.GroupResource{} if info, ok := request.RequestInfoFrom(ctx); ok { @@ -1147,10 +1027,11 @@ func (r *REST) buildTableFromApplications(apps []appsv1alpha1.Application) metav } now := time.Now() - for _, app := range apps { + for i := range apps { + app := &apps[i] row := metav1.TableRow{ Cells: []interface{}{app.GetName(), getReadyStatus(app.Status.Conditions), computeAge(app.GetCreationTimestamp().Time, now), getVersion(app.Status.Version)}, - Object: runtime.RawExtension{Object: &app}, + Object: runtime.RawExtension{Object: app}, } table.Rows = append(table.Rows, row) } @@ -1171,9 +1052,10 @@ func (r *REST) buildTableFromApplication(app appsv1alpha1.Application) metav1.Ta } now := time.Now() + a := app row := metav1.TableRow{ Cells: []interface{}{app.GetName(), getReadyStatus(app.Status.Conditions), computeAge(app.GetCreationTimestamp().Time, now), getVersion(app.Status.Version)}, - Object: runtime.RawExtension{Object: &app}, + Object: runtime.RawExtension{Object: &a}, } table.Rows = append(table.Rows, row) @@ -1237,15 +1119,21 @@ func (r *REST) Destroy() { // New creates a new instance of Application func (r *REST) New() runtime.Object { - obj := &unstructured.Unstructured{} - obj.SetGroupVersionKind(r.gvk) + obj := &appsv1alpha1.Application{} + obj.TypeMeta = metav1.TypeMeta{ + APIVersion: r.gvk.GroupVersion().String(), + Kind: r.kindName, + } return obj } // NewList returns an empty list of Application objects func (r *REST) NewList() runtime.Object { - obj := &unstructured.UnstructuredList{} - obj.SetGroupVersionKind(r.gvk.GroupVersion().WithKind(r.kindName + "List")) + obj := &appsv1alpha1.ApplicationList{} + obj.TypeMeta = metav1.TypeMeta{ + APIVersion: r.gvk.GroupVersion().String(), + Kind: r.kindName + "List", + } return obj } diff --git a/pkg/registry/core/tenantmodule/rest.go b/pkg/registry/core/tenantmodule/rest.go index 852a0b64..8ca27dde 100644 --- a/pkg/registry/core/tenantmodule/rest.go +++ b/pkg/registry/core/tenantmodule/rest.go @@ -26,7 +26,6 @@ import ( helmv2 "github.com/fluxcd/helm-controller/api/v2" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" fields "k8s.io/apimachinery/pkg/fields" labels "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" @@ -147,25 +146,8 @@ func (r *REST) Get(ctx context.Context, name string, options *metav1.GetOptions) return nil, fmt.Errorf("conversion error: %v", err) } - // Explicitly set apiVersion and kind for TenantModule - convertedModule.TypeMeta = metav1.TypeMeta{ - APIVersion: "core.cozystack.io/v1alpha1", - Kind: r.kindName, - } - - // Convert TenantModule to unstructured format - unstructuredModule, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&convertedModule) - if err != nil { - klog.Errorf("Failed to convert TenantModule to unstructured for resource %s: %v", name, err) - return nil, fmt.Errorf("failed to convert TenantModule to unstructured: %v", err) - } - - // Explicitly set apiVersion and kind in unstructured object - unstructuredModule["apiVersion"] = "core.cozystack.io/v1alpha1" - unstructuredModule["kind"] = r.kindName - - klog.V(6).Infof("Successfully retrieved and converted resource %s of kind %s to unstructured", name, r.gvr.Resource) - return &unstructured.Unstructured{Object: unstructuredModule}, nil + klog.V(6).Infof("Successfully retrieved and converted resource %s of kind %s", name, r.gvr.Resource) + return &convertedModule, nil } // List retrieves a list of TenantModules by converting HelmReleases @@ -245,8 +227,8 @@ func (r *REST) List(ctx context.Context, options *metainternalversion.ListOption return nil, err } - // Initialize unstructured items array - items := make([]unstructured.Unstructured, 0) + // Initialize TenantModule items array + items := make([]corev1alpha1.TenantModule, 0, len(hrList.Items)) // Iterate over HelmReleases and convert to TenantModules for i := range hrList.Items { @@ -294,19 +276,15 @@ func (r *REST) List(ctx context.Context, options *metainternalversion.ListOption } } - // Convert TenantModule to unstructured - unstructuredModule, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&module) - if err != nil { - klog.Errorf("Error converting TenantModule %s to unstructured: %v", module.Name, err) - continue - } - items = append(items, unstructured.Unstructured{Object: unstructuredModule}) + items = append(items, module) } - // Explicitly set apiVersion and kind in unstructured object - moduleList := &unstructured.UnstructuredList{} - moduleList.SetAPIVersion("core.cozystack.io/v1alpha1") - moduleList.SetKind(r.kindName + "List") + // Create TenantModuleList with proper kind + moduleList := &corev1alpha1.TenantModuleList{} + moduleList.TypeMeta = metav1.TypeMeta{ + APIVersion: "core.cozystack.io/v1alpha1", + Kind: r.kindName + "List", + } moduleList.SetResourceVersion(hrList.GetResourceVersion()) moduleList.Items = items @@ -455,17 +433,10 @@ func (r *REST) Watch(ctx context.Context, options *metainternalversion.ListOptio } } - // Convert TenantModule to unstructured - unstructuredModule, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&module) - if err != nil { - klog.Errorf("Failed to convert TenantModule to unstructured: %v", err) - continue - } - // Create watch event with TenantModule object moduleEvent := watch.Event{ Type: event.Type, - Object: &unstructured.Unstructured{Object: unstructuredModule}, + Object: &module, } // Send event to custom watcher @@ -620,27 +591,11 @@ func (r *REST) ConvertToTable(ctx context.Context, object runtime.Object, tableO var table metav1.Table switch obj := object.(type) { - case *unstructured.UnstructuredList: - modules := make([]corev1alpha1.TenantModule, 0, len(obj.Items)) - for _, u := range obj.Items { - var m corev1alpha1.TenantModule - err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &m) - if err != nil { - klog.Errorf("Failed to convert Unstructured to TenantModule: %v", err) - continue - } - modules = append(modules, m) - } - table = r.buildTableFromTenantModules(modules) - table.ListMeta.ResourceVersion = obj.GetResourceVersion() - case *unstructured.Unstructured: - var module corev1alpha1.TenantModule - err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), &module) - if err != nil { - klog.Errorf("Failed to convert Unstructured to TenantModule: %v", err) - return nil, fmt.Errorf("failed to convert Unstructured to TenantModule: %v", err) - } - table = r.buildTableFromTenantModule(module) + case *corev1alpha1.TenantModuleList: + table = r.buildTableFromTenantModules(obj.Items) + table.ListMeta.ResourceVersion = obj.ListMeta.ResourceVersion + case *corev1alpha1.TenantModule: + table = r.buildTableFromTenantModule(*obj) table.ListMeta.ResourceVersion = obj.GetResourceVersion() default: resource := schema.GroupResource{} @@ -680,10 +635,11 @@ func (r *REST) buildTableFromTenantModules(modules []corev1alpha1.TenantModule) } now := time.Now() - for _, module := range modules { + for i := range modules { + module := &modules[i] row := metav1.TableRow{ Cells: []interface{}{module.GetName(), getReadyStatus(module.Status.Conditions), computeAge(module.GetCreationTimestamp().Time, now), getVersion(module.Status.Version)}, - Object: runtime.RawExtension{Object: &module}, + Object: runtime.RawExtension{Object: module}, } table.Rows = append(table.Rows, row) } @@ -704,9 +660,10 @@ func (r *REST) buildTableFromTenantModule(module corev1alpha1.TenantModule) meta } now := time.Now() + m := module row := metav1.TableRow{ Cells: []interface{}{module.GetName(), getReadyStatus(module.Status.Conditions), computeAge(module.GetCreationTimestamp().Time, now), getVersion(module.Status.Version)}, - Object: runtime.RawExtension{Object: &module}, + Object: runtime.RawExtension{Object: &m}, } table.Rows = append(table.Rows, row) @@ -751,12 +708,22 @@ func (r *REST) Destroy() { // New creates a new instance of TenantModule func (r *REST) New() runtime.Object { - return &corev1alpha1.TenantModule{} + obj := &corev1alpha1.TenantModule{} + obj.TypeMeta = metav1.TypeMeta{ + APIVersion: r.gvk.GroupVersion().String(), + Kind: r.kindName, + } + return obj } // NewList returns an empty list of TenantModule objects func (r *REST) NewList() runtime.Object { - return &corev1alpha1.TenantModuleList{} + obj := &corev1alpha1.TenantModuleList{} + obj.TypeMeta = metav1.TypeMeta{ + APIVersion: r.gvk.GroupVersion().String(), + Kind: r.kindName + "List", + } + return obj } // Kind returns the resource kind used for API discovery From 79165ca2f9497733552db6a89296d96d14fec531 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Mon, 15 Dec 2025 08:40:59 +0100 Subject: [PATCH 10/43] Update SeaweedFS v4.02 Signed-off-by: Andrei Kvapil (cherry picked from commit 1805be3c488ab4e33dae9a95f9583c9d266cd19b) --- packages/system/seaweedfs/Makefile | 1 - .../seaweedfs/charts/seaweedfs/Chart.yaml | 4 +- .../all-in-one/all-in-one-deployment.yaml | 116 +++++++---- .../templates/all-in-one/all-in-one-pvc.yaml | 25 ++- .../all-in-one/all-in-one-service.yml | 18 +- .../seaweedfs/templates/cert/ca-cert.yaml | 8 +- .../templates/filer/filer-ingress.yaml | 13 +- .../templates/filer/filer-statefulset.yaml | 21 +- .../templates/master/master-statefulset.yaml | 12 +- .../seaweedfs/templates/s3/s3-deployment.yaml | 7 +- .../seaweedfs/templates/s3/s3-ingress.yaml | 16 +- .../shared/post-install-bucket-hook.yaml | 71 +++++-- .../templates/volume/volume-statefulset.yaml | 4 +- .../seaweedfs/charts/seaweedfs/values.yaml | 187 ++++++++++++------ .../seaweedfs/images/seaweedfs/Dockerfile | 2 +- .../seaweedfs/patches/long-term-ca.diff | 13 -- 16 files changed, 333 insertions(+), 185 deletions(-) delete mode 100644 packages/system/seaweedfs/patches/long-term-ca.diff diff --git a/packages/system/seaweedfs/Makefile b/packages/system/seaweedfs/Makefile index 2344f6b5..9d1f47cd 100644 --- a/packages/system/seaweedfs/Makefile +++ b/packages/system/seaweedfs/Makefile @@ -12,7 +12,6 @@ update: sed -i.bak "/ARG VERSION/ s|=.*|=$${version}|g" images/seaweedfs/Dockerfile && \ rm -f images/seaweedfs/Dockerfile.bak patch --no-backup-if-mismatch -p4 < patches/resize-api-server-annotation.diff - patch --no-backup-if-mismatch -p4 < patches/long-term-ca.diff #patch --no-backup-if-mismatch -p4 < patches/retention-policy-delete.yaml image: diff --git a/packages/system/seaweedfs/charts/seaweedfs/Chart.yaml b/packages/system/seaweedfs/charts/seaweedfs/Chart.yaml index c595d65e..6ea31115 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/Chart.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 description: SeaweedFS name: seaweedfs -appVersion: "3.99" +appVersion: "4.02" # Dev note: Trigger a helm chart release by `git tag -a helm-` -version: 4.0.399 +version: 4.0.402 diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/all-in-one/all-in-one-deployment.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/all-in-one/all-in-one-deployment.yaml index 8700a8a6..f6237bb7 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/templates/all-in-one/all-in-one-deployment.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/all-in-one/all-in-one-deployment.yaml @@ -15,9 +15,9 @@ metadata: {{- toYaml .Values.allInOne.annotations | nindent 4 }} {{- end }} spec: - replicas: 1 + replicas: {{ .Values.allInOne.replicas | default 1 }} strategy: - type: Recreate + type: {{ .Values.allInOne.updateStrategy.type | default "Recreate" }} selector: matchLabels: app.kubernetes.io/name: {{ template "seaweedfs.name" . }} @@ -130,12 +130,23 @@ spec: value: {{ include "seaweedfs.cluster.masterAddress" . | quote }} - name: {{ $clusterFilerKey }} value: {{ include "seaweedfs.cluster.filerAddress" . | quote }} + {{- if .Values.allInOne.secretExtraEnvironmentVars }} + {{- range $key, $value := .Values.allInOne.secretExtraEnvironmentVars }} + - name: {{ $key }} + valueFrom: + {{ toYaml $value | nindent 16 }} + {{- end }} + {{- end }} command: - "/bin/sh" - "-ec" - | /usr/bin/weed \ + {{- if .Values.allInOne.loggingOverrideLevel }} + -v={{ .Values.allInOne.loggingOverrideLevel }} \ + {{- else }} -v={{ .Values.global.loggingLevel }} \ + {{- end }} server \ -dir=/data \ -master \ @@ -191,6 +202,9 @@ spec: {{- else if .Values.master.metricsPort }} -metricsPort={{ .Values.master.metricsPort }} \ {{- end }} + {{- if .Values.allInOne.metricsIp }} + -metricsIp={{ .Values.allInOne.metricsIp }} \ + {{- end }} -filer \ -filer.port={{ .Values.filer.port }} \ {{- if .Values.filer.disableDirListing }} @@ -219,61 +233,75 @@ spec: {{- end }} {{- if .Values.allInOne.s3.enabled }} -s3 \ - -s3.port={{ .Values.s3.port }} \ - {{- if .Values.s3.domainName }} - -s3.domainName={{ .Values.s3.domainName }} \ + -s3.port={{ .Values.allInOne.s3.port | default .Values.s3.port }} \ + {{- $domainName := .Values.allInOne.s3.domainName | default .Values.s3.domainName }} + {{- if $domainName }} + -s3.domainName={{ $domainName }} \ {{- end }} {{- if .Values.global.enableSecurity }} - {{- if .Values.s3.httpsPort }} - -s3.port.https={{ .Values.s3.httpsPort }} \ + {{- $httpsPort := .Values.allInOne.s3.httpsPort | default .Values.s3.httpsPort }} + {{- if $httpsPort }} + -s3.port.https={{ $httpsPort }} \ {{- end }} -s3.cert.file=/usr/local/share/ca-certificates/client/tls.crt \ -s3.key.file=/usr/local/share/ca-certificates/client/tls.key \ {{- end }} - {{- if eq (typeOf .Values.s3.allowEmptyFolder) "bool" }} - -s3.allowEmptyFolder={{ .Values.s3.allowEmptyFolder }} \ - {{- end }} - {{- if .Values.s3.enableAuth }} + {{- if or .Values.allInOne.s3.enableAuth .Values.s3.enableAuth .Values.filer.s3.enableAuth }} -s3.config=/etc/sw/s3/seaweedfs_s3_config \ {{- end }} - {{- if .Values.s3.auditLogConfig }} + {{- $auditLogConfig := .Values.allInOne.s3.auditLogConfig | default .Values.s3.auditLogConfig }} + {{- if $auditLogConfig }} -s3.auditLogConfig=/etc/sw/s3/s3_auditLogConfig.json \ {{- end }} {{- end }} {{- if .Values.allInOne.sftp.enabled }} -sftp \ - -sftp.port={{ .Values.sftp.port }} \ - {{- if .Values.sftp.sshPrivateKey }} - -sftp.sshPrivateKey={{ .Values.sftp.sshPrivateKey }} \ + -sftp.port={{ .Values.allInOne.sftp.port | default .Values.sftp.port }} \ + {{- $sshPrivateKey := .Values.allInOne.sftp.sshPrivateKey | default .Values.sftp.sshPrivateKey }} + {{- if $sshPrivateKey }} + -sftp.sshPrivateKey={{ $sshPrivateKey }} \ {{- end }} - {{- if .Values.sftp.hostKeysFolder }} - -sftp.hostKeysFolder={{ .Values.sftp.hostKeysFolder }} \ + {{- $hostKeysFolder := .Values.allInOne.sftp.hostKeysFolder | default .Values.sftp.hostKeysFolder }} + {{- if $hostKeysFolder }} + -sftp.hostKeysFolder={{ $hostKeysFolder }} \ {{- end }} - {{- if .Values.sftp.authMethods }} - -sftp.authMethods={{ .Values.sftp.authMethods }} \ + {{- $authMethods := .Values.allInOne.sftp.authMethods | default .Values.sftp.authMethods }} + {{- if $authMethods }} + -sftp.authMethods={{ $authMethods }} \ {{- end }} - {{- if .Values.sftp.maxAuthTries }} - -sftp.maxAuthTries={{ .Values.sftp.maxAuthTries }} \ + {{- $maxAuthTries := .Values.allInOne.sftp.maxAuthTries | default .Values.sftp.maxAuthTries }} + {{- if $maxAuthTries }} + -sftp.maxAuthTries={{ $maxAuthTries }} \ {{- end }} - {{- if .Values.sftp.bannerMessage }} - -sftp.bannerMessage="{{ .Values.sftp.bannerMessage }}" \ + {{- $bannerMessage := .Values.allInOne.sftp.bannerMessage | default .Values.sftp.bannerMessage }} + {{- if $bannerMessage }} + -sftp.bannerMessage="{{ $bannerMessage }}" \ {{- end }} - {{- if .Values.sftp.loginGraceTime }} - -sftp.loginGraceTime={{ .Values.sftp.loginGraceTime }} \ + {{- $loginGraceTime := .Values.allInOne.sftp.loginGraceTime | default .Values.sftp.loginGraceTime }} + {{- if $loginGraceTime }} + -sftp.loginGraceTime={{ $loginGraceTime }} \ {{- end }} - {{- if .Values.sftp.clientAliveInterval }} - -sftp.clientAliveInterval={{ .Values.sftp.clientAliveInterval }} \ + {{- $clientAliveInterval := .Values.allInOne.sftp.clientAliveInterval | default .Values.sftp.clientAliveInterval }} + {{- if $clientAliveInterval }} + -sftp.clientAliveInterval={{ $clientAliveInterval }} \ {{- end }} - {{- if .Values.sftp.clientAliveCountMax }} - -sftp.clientAliveCountMax={{ .Values.sftp.clientAliveCountMax }} \ + {{- $clientAliveCountMax := .Values.allInOne.sftp.clientAliveCountMax | default .Values.sftp.clientAliveCountMax }} + {{- if $clientAliveCountMax }} + -sftp.clientAliveCountMax={{ $clientAliveCountMax }} \ {{- end }} + {{- if or .Values.allInOne.sftp.enableAuth .Values.sftp.enableAuth }} -sftp.userStoreFile=/etc/sw/sftp/seaweedfs_sftp_config \ {{- end }} + {{- end }} + {{- $extraArgsCount := len .Values.allInOne.extraArgs }} + {{- range $i, $arg := .Values.allInOne.extraArgs }} + {{ $arg | quote }}{{ if ne (add1 $i) $extraArgsCount }} \{{ end }} + {{- end }} volumeMounts: - name: data mountPath: /data - {{- if and .Values.allInOne.s3.enabled (or .Values.s3.enableAuth .Values.filer.s3.enableAuth) }} + {{- if and .Values.allInOne.s3.enabled (or .Values.allInOne.s3.enableAuth .Values.s3.enableAuth .Values.filer.s3.enableAuth) }} - name: config-s3-users mountPath: /etc/sw/s3 readOnly: true @@ -282,10 +310,12 @@ spec: - name: config-ssh mountPath: /etc/sw/ssh readOnly: true + {{- if or .Values.allInOne.sftp.enableAuth .Values.sftp.enableAuth }} - mountPath: /etc/sw/sftp name: config-users readOnly: true {{- end }} + {{- end }} {{- if .Values.filer.notificationConfig }} - name: notification-config mountPath: /etc/seaweedfs/notification.toml @@ -332,15 +362,16 @@ spec: - containerPort: {{ .Values.filer.grpcPort }} name: swfs-fil-grpc {{- if .Values.allInOne.s3.enabled }} - - containerPort: {{ .Values.s3.port }} + - containerPort: {{ .Values.allInOne.s3.port | default .Values.s3.port }} name: swfs-s3 - {{- if .Values.s3.httpsPort }} - - containerPort: {{ .Values.s3.httpsPort }} + {{- $httpsPort := .Values.allInOne.s3.httpsPort | default .Values.s3.httpsPort }} + {{- if $httpsPort }} + - containerPort: {{ $httpsPort }} name: swfs-s3-tls {{- end }} {{- end }} {{- if .Values.allInOne.sftp.enabled }} - - containerPort: {{ .Values.sftp.port }} + - containerPort: {{ .Values.allInOne.sftp.port | default .Values.sftp.port }} name: swfs-sftp {{- end }} {{- if .Values.allInOne.metricsPort }} @@ -352,7 +383,7 @@ spec: httpGet: path: {{ .Values.allInOne.readinessProbe.httpGet.path }} port: {{ .Values.master.port }} - scheme: {{ .Values.allInOne.readinessProbe.scheme }} + scheme: {{ .Values.allInOne.readinessProbe.httpGet.scheme }} initialDelaySeconds: {{ .Values.allInOne.readinessProbe.initialDelaySeconds }} periodSeconds: {{ .Values.allInOne.readinessProbe.periodSeconds }} successThreshold: {{ .Values.allInOne.readinessProbe.successThreshold }} @@ -364,7 +395,7 @@ spec: httpGet: path: {{ .Values.allInOne.livenessProbe.httpGet.path }} port: {{ .Values.master.port }} - scheme: {{ .Values.allInOne.livenessProbe.scheme }} + scheme: {{ .Values.allInOne.livenessProbe.httpGet.scheme }} initialDelaySeconds: {{ .Values.allInOne.livenessProbe.initialDelaySeconds }} periodSeconds: {{ .Values.allInOne.livenessProbe.periodSeconds }} successThreshold: {{ .Values.allInOne.livenessProbe.successThreshold }} @@ -389,26 +420,31 @@ spec: path: {{ .Values.allInOne.data.hostPathPrefix }}/seaweedfs-all-in-one-data/ type: DirectoryOrCreate {{- else if eq .Values.allInOne.data.type "persistentVolumeClaim" }} + persistentVolumeClaim: + claimName: {{ template "seaweedfs.name" . }}-all-in-one-data + {{- else if eq .Values.allInOne.data.type "existingClaim" }} persistentVolumeClaim: claimName: {{ .Values.allInOne.data.claimName }} {{- else if eq .Values.allInOne.data.type "emptyDir" }} emptyDir: {} {{- end }} - {{- if and .Values.allInOne.s3.enabled (or .Values.s3.enableAuth .Values.filer.s3.enableAuth) }} + {{- if and .Values.allInOne.s3.enabled (or .Values.allInOne.s3.enableAuth .Values.s3.enableAuth .Values.filer.s3.enableAuth) }} - name: config-s3-users secret: defaultMode: 420 - secretName: {{ default (printf "%s-s3-secret" (include "seaweedfs.name" .)) (or .Values.s3.existingConfigSecret .Values.filer.s3.existingConfigSecret) }} + secretName: {{ default (printf "%s-s3-secret" (include "seaweedfs.name" .)) (or .Values.allInOne.s3.existingConfigSecret .Values.s3.existingConfigSecret .Values.filer.s3.existingConfigSecret) }} {{- end }} {{- if .Values.allInOne.sftp.enabled }} - name: config-ssh secret: defaultMode: 420 - secretName: {{ default (printf "%s-sftp-ssh-secret" (include "seaweedfs.name" .)) .Values.sftp.existingSshConfigSecret }} + secretName: {{ default (printf "%s-sftp-ssh-secret" (include "seaweedfs.name" .)) (or .Values.allInOne.sftp.existingSshConfigSecret .Values.sftp.existingSshConfigSecret) }} + {{- if or .Values.allInOne.sftp.enableAuth .Values.sftp.enableAuth }} - name: config-users secret: defaultMode: 420 - secretName: {{ default (printf "%s-sftp-secret" (include "seaweedfs.name" .)) .Values.sftp.existingConfigSecret }} + secretName: {{ default (printf "%s-sftp-secret" (include "seaweedfs.name" .)) (or .Values.allInOne.sftp.existingConfigSecret .Values.sftp.existingConfigSecret) }} + {{- end }} {{- end }} {{- if .Values.filer.notificationConfig }} - name: notification-config diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/all-in-one/all-in-one-pvc.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/all-in-one/all-in-one-pvc.yaml index 49ac2014..a62450c3 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/templates/all-in-one/all-in-one-pvc.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/all-in-one/all-in-one-pvc.yaml @@ -1,21 +1,28 @@ -{{- if and .Values.allInOne.enabled (eq .Values.allInOne.data.type "persistentVolumeClaim") }} +{{- if .Values.allInOne.enabled }} +{{- if eq .Values.allInOne.data.type "persistentVolumeClaim" }} apiVersion: v1 kind: PersistentVolumeClaim metadata: - name: {{ .Values.allInOne.data.claimName }} + name: {{ template "seaweedfs.name" . }}-all-in-one-data + namespace: {{ .Release.Namespace }} labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/component: seaweedfs-all-in-one - {{- if .Values.allInOne.annotations }} + {{- with .Values.allInOne.data.annotations }} annotations: - {{- toYaml .Values.allInOne.annotations | nindent 4 }} + {{- toYaml . | nindent 4 }} {{- end }} spec: accessModes: - - ReadWriteOnce - resources: - requests: - storage: {{ .Values.allInOne.data.size }} + {{- toYaml (.Values.allInOne.data.accessModes | default (list "ReadWriteOnce")) | nindent 4 }} {{- if .Values.allInOne.data.storageClass }} storageClassName: {{ .Values.allInOne.data.storageClass }} {{- end }} -{{- end }} \ No newline at end of file + resources: + requests: + storage: {{ .Values.allInOne.data.size | default "10Gi" }} +{{- end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/all-in-one/all-in-one-service.yml b/packages/system/seaweedfs/charts/seaweedfs/templates/all-in-one/all-in-one-service.yml index 14076a9c..b13f5789 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/templates/all-in-one/all-in-one-service.yml +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/all-in-one/all-in-one-service.yml @@ -15,6 +15,7 @@ metadata: {{- toYaml .Values.allInOne.service.annotations | nindent 4 }} {{- end }} spec: + type: {{ .Values.allInOne.service.type | default "ClusterIP" }} internalTrafficPolicy: {{ .Values.allInOne.service.internalTrafficPolicy | default "Cluster" }} ports: # Master ports @@ -50,13 +51,14 @@ spec: # S3 ports (if enabled) {{- if .Values.allInOne.s3.enabled }} - name: "swfs-s3" - port: {{ if .Values.allInOne.s3.enabled }}{{ .Values.s3.port }}{{ else }}{{ .Values.filer.s3.port }}{{ end }} - targetPort: {{ if .Values.allInOne.s3.enabled }}{{ .Values.s3.port }}{{ else }}{{ .Values.filer.s3.port }}{{ end }} + port: {{ .Values.allInOne.s3.port | default .Values.s3.port }} + targetPort: {{ .Values.allInOne.s3.port | default .Values.s3.port }} protocol: TCP - {{- if and .Values.allInOne.s3.enabled .Values.s3.httpsPort }} + {{- $httpsPort := .Values.allInOne.s3.httpsPort | default .Values.s3.httpsPort }} + {{- if $httpsPort }} - name: "swfs-s3-tls" - port: {{ .Values.s3.httpsPort }} - targetPort: {{ .Values.s3.httpsPort }} + port: {{ $httpsPort }} + targetPort: {{ $httpsPort }} protocol: TCP {{- end }} {{- end }} @@ -64,8 +66,8 @@ spec: # SFTP ports (if enabled) {{- if .Values.allInOne.sftp.enabled }} - name: "swfs-sftp" - port: {{ .Values.sftp.port }} - targetPort: {{ .Values.sftp.port }} + port: {{ .Values.allInOne.sftp.port | default .Values.sftp.port }} + targetPort: {{ .Values.allInOne.sftp.port | default .Values.sftp.port }} protocol: TCP {{- end }} @@ -80,4 +82,4 @@ spec: selector: app.kubernetes.io/name: {{ template "seaweedfs.name" . }} app.kubernetes.io/component: seaweedfs-all-in-one -{{- end }} \ No newline at end of file +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/cert/ca-cert.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/cert/ca-cert.yaml index f2572558..b01a8dcc 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/templates/cert/ca-cert.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/cert/ca-cert.yaml @@ -13,8 +13,12 @@ spec: secretName: {{ template "seaweedfs.name" . }}-ca-cert commonName: "{{ template "seaweedfs.name" . }}-root-ca" isCA: true - duration: 87600h - renewBefore: 720h + {{- if .Values.certificates.ca.duration }} + duration: {{ .Values.certificates.ca.duration }} + {{- end }} + {{- if .Values.certificates.ca.renewBefore }} + renewBefore: {{ .Values.certificates.ca.renewBefore }} + {{- end }} issuerRef: name: {{ template "seaweedfs.name" . }}-issuer kind: Issuer diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/filer/filer-ingress.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/filer/filer-ingress.yaml index 9ce15ae9..b185a58b 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/templates/filer/filer-ingress.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/filer/filer-ingress.yaml @@ -1,5 +1,8 @@ -{{- if .Values.filer.enabled }} -{{- if .Values.filer.ingress.enabled }} +{{- /* Filer ingress works for both normal mode (filer.enabled) and all-in-one mode (allInOne.enabled) */}} +{{- $filerEnabled := or .Values.filer.enabled .Values.allInOne.enabled }} +{{- if and $filerEnabled .Values.filer.ingress.enabled }} +{{- /* Determine service name based on deployment mode */}} +{{- $serviceName := ternary (printf "%s-all-in-one" (include "seaweedfs.name" .)) (printf "%s-filer" (include "seaweedfs.name" .)) .Values.allInOne.enabled }} {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }} apiVersion: networking.k8s.io/v1 {{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion }} @@ -33,16 +36,14 @@ spec: backend: {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }} service: - name: {{ template "seaweedfs.name" . }}-filer + name: {{ $serviceName }} port: number: {{ .Values.filer.port }} - #name: {{- else }} - serviceName: {{ template "seaweedfs.name" . }}-filer + serviceName: {{ $serviceName }} servicePort: {{ .Values.filer.port }} {{- end }} {{- if .Values.filer.ingress.host }} host: {{ .Values.filer.ingress.host }} {{- end }} {{- end }} -{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/filer/filer-statefulset.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/filer/filer-statefulset.yaml index 5c1a0950..2b8c2744 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/templates/filer/filer-statefulset.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/filer/filer-statefulset.yaml @@ -213,9 +213,6 @@ spec: -s3.cert.file=/usr/local/share/ca-certificates/client/tls.crt \ -s3.key.file=/usr/local/share/ca-certificates/client/tls.key \ {{- end }} - {{- if eq (typeOf .Values.filer.s3.allowEmptyFolder) "bool" }} - -s3.allowEmptyFolder={{ .Values.filer.s3.allowEmptyFolder }} \ - {{- end }} {{- if .Values.filer.s3.enableAuth }} -s3.config=/etc/sw/seaweedfs_s3_config \ {{- end }} @@ -289,7 +286,7 @@ spec: httpGet: path: {{ .Values.filer.readinessProbe.httpGet.path }} port: {{ .Values.filer.port }} - scheme: {{ .Values.filer.readinessProbe.scheme }} + scheme: {{ .Values.filer.readinessProbe.httpGet.scheme }} initialDelaySeconds: {{ .Values.filer.readinessProbe.initialDelaySeconds }} periodSeconds: {{ .Values.filer.readinessProbe.periodSeconds }} successThreshold: {{ .Values.filer.readinessProbe.successThreshold }} @@ -301,7 +298,7 @@ spec: httpGet: path: {{ .Values.filer.livenessProbe.httpGet.path }} port: {{ .Values.filer.port }} - scheme: {{ .Values.filer.livenessProbe.scheme }} + scheme: {{ .Values.filer.livenessProbe.httpGet.scheme }} initialDelaySeconds: {{ .Values.filer.livenessProbe.initialDelaySeconds }} periodSeconds: {{ .Values.filer.livenessProbe.periodSeconds }} successThreshold: {{ .Values.filer.livenessProbe.successThreshold }} @@ -392,10 +389,12 @@ spec: nodeSelector: {{ tpl .Values.filer.nodeSelector . | indent 8 | trim }} {{- end }} - {{- if and (.Values.filer.enablePVC) (eq .Values.filer.data.type "persistentVolumeClaim") }} + {{- if and (.Values.filer.enablePVC) (not .Values.filer.data) }} # DEPRECATION: Deprecate in favor of filer.data section below volumeClaimTemplates: - - metadata: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: name: data-filer spec: accessModes: @@ -411,7 +410,9 @@ spec: {{- if $pvc_exists }} volumeClaimTemplates: {{- if eq .Values.filer.data.type "persistentVolumeClaim" }} - - metadata: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: name: data-filer {{- with .Values.filer.data.annotations }} annotations: @@ -425,7 +426,9 @@ spec: storage: {{ .Values.filer.data.size }} {{- end }} {{- if eq .Values.filer.logs.type "persistentVolumeClaim" }} - - metadata: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: name: seaweedfs-filer-log-volume {{- with .Values.filer.logs.annotations }} annotations: diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/master/master-statefulset.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/master/master-statefulset.yaml index 01387fc9..a7067345 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/templates/master/master-statefulset.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/master/master-statefulset.yaml @@ -235,7 +235,7 @@ spec: httpGet: path: {{ .Values.master.readinessProbe.httpGet.path }} port: {{ .Values.master.port }} - scheme: {{ .Values.master.readinessProbe.scheme }} + scheme: {{ .Values.master.readinessProbe.httpGet.scheme }} initialDelaySeconds: {{ .Values.master.readinessProbe.initialDelaySeconds }} periodSeconds: {{ .Values.master.readinessProbe.periodSeconds }} successThreshold: {{ .Values.master.readinessProbe.successThreshold }} @@ -247,7 +247,7 @@ spec: httpGet: path: {{ .Values.master.livenessProbe.httpGet.path }} port: {{ .Values.master.port }} - scheme: {{ .Values.master.livenessProbe.scheme }} + scheme: {{ .Values.master.livenessProbe.httpGet.scheme }} initialDelaySeconds: {{ .Values.master.livenessProbe.initialDelaySeconds }} periodSeconds: {{ .Values.master.livenessProbe.periodSeconds }} successThreshold: {{ .Values.master.livenessProbe.successThreshold }} @@ -327,7 +327,9 @@ spec: {{- if $pvc_exists }} volumeClaimTemplates: {{- if eq .Values.master.data.type "persistentVolumeClaim"}} - - metadata: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: name: data-{{ .Release.Namespace }} {{- with .Values.master.data.annotations }} annotations: @@ -341,7 +343,9 @@ spec: storage: {{ .Values.master.data.size }} {{- end }} {{- if eq .Values.master.logs.type "persistentVolumeClaim"}} - - metadata: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: name: seaweedfs-master-log-volume {{- with .Values.master.logs.annotations }} annotations: diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-deployment.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-deployment.yaml index 0c6d52c3..29dd2d43 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-deployment.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-deployment.yaml @@ -143,9 +143,6 @@ spec: {{- if .Values.s3.domainName }} -domainName={{ .Values.s3.domainName }} \ {{- end }} - {{- if eq (typeOf .Values.s3.allowEmptyFolder) "bool" }} - -allowEmptyFolder={{ .Values.s3.allowEmptyFolder }} \ - {{- end }} {{- if .Values.s3.enableAuth }} -config=/etc/sw/seaweedfs_s3_config \ {{- end }} @@ -204,7 +201,7 @@ spec: httpGet: path: {{ .Values.s3.readinessProbe.httpGet.path }} port: {{ .Values.s3.port }} - scheme: {{ .Values.s3.readinessProbe.scheme }} + scheme: {{ .Values.s3.readinessProbe.httpGet.scheme }} initialDelaySeconds: {{ .Values.s3.readinessProbe.initialDelaySeconds }} periodSeconds: {{ .Values.s3.readinessProbe.periodSeconds }} successThreshold: {{ .Values.s3.readinessProbe.successThreshold }} @@ -216,7 +213,7 @@ spec: httpGet: path: {{ .Values.s3.livenessProbe.httpGet.path }} port: {{ .Values.s3.port }} - scheme: {{ .Values.s3.livenessProbe.scheme }} + scheme: {{ .Values.s3.livenessProbe.httpGet.scheme }} initialDelaySeconds: {{ .Values.s3.livenessProbe.initialDelaySeconds }} periodSeconds: {{ .Values.s3.livenessProbe.periodSeconds }} successThreshold: {{ .Values.s3.livenessProbe.successThreshold }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-ingress.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-ingress.yaml index a856923e..899773ae 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-ingress.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-ingress.yaml @@ -1,4 +1,9 @@ -{{- if .Values.s3.ingress.enabled }} +{{- /* S3 ingress works for standalone S3 gateway (s3.enabled), S3 on Filer (filer.s3.enabled), and all-in-one mode (allInOne.s3.enabled) */}} +{{- $s3Enabled := or .Values.s3.enabled (and .Values.filer.s3.enabled (not .Values.allInOne.enabled)) (and .Values.allInOne.enabled .Values.allInOne.s3.enabled) }} +{{- if and $s3Enabled .Values.s3.ingress.enabled }} +{{- /* Determine service name based on deployment mode */}} +{{- $serviceName := ternary (printf "%s-all-in-one" (include "seaweedfs.name" .)) (printf "%s-s3" (include "seaweedfs.name" .)) .Values.allInOne.enabled }} +{{- $s3Port := .Values.allInOne.s3.port | default .Values.s3.port }} {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }} apiVersion: networking.k8s.io/v1 {{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion }} @@ -32,13 +37,12 @@ spec: backend: {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }} service: - name: {{ template "seaweedfs.name" . }}-s3 + name: {{ $serviceName }} port: - number: {{ .Values.s3.port }} - #name: + number: {{ $s3Port }} {{- else }} - serviceName: {{ template "seaweedfs.name" . }}-s3 - servicePort: {{ .Values.s3.port }} + serviceName: {{ $serviceName }} + servicePort: {{ $s3Port }} {{- end }} {{- if .Values.s3.ingress.host }} host: {{ .Values.s3.ingress.host | quote }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/shared/post-install-bucket-hook.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/shared/post-install-bucket-hook.yaml index 44d65089..a0c56edc 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/templates/shared/post-install-bucket-hook.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/shared/post-install-bucket-hook.yaml @@ -1,6 +1,32 @@ -{{- if .Values.master.enabled }} -{{- if .Values.filer.s3.enabled }} -{{- if .Values.filer.s3.createBuckets }} +{{- /* Support bucket creation for both standalone filer.s3 and allInOne modes */}} +{{- $createBuckets := list }} +{{- $s3Enabled := false }} +{{- $enableAuth := false }} +{{- $existingConfigSecret := "" }} + +{{- /* Check allInOne mode first */}} +{{- if .Values.allInOne.enabled }} + {{- if .Values.allInOne.s3.enabled }} + {{- $s3Enabled = true }} + {{- if .Values.allInOne.s3.createBuckets }} + {{- $createBuckets = .Values.allInOne.s3.createBuckets }} + {{- end }} + {{- $enableAuth = or .Values.allInOne.s3.enableAuth .Values.s3.enableAuth .Values.filer.s3.enableAuth }} + {{- $existingConfigSecret = or .Values.allInOne.s3.existingConfigSecret .Values.s3.existingConfigSecret .Values.filer.s3.existingConfigSecret }} + {{- end }} +{{- else if .Values.master.enabled }} + {{- /* Check standalone filer.s3 mode */}} + {{- if .Values.filer.s3.enabled }} + {{- $s3Enabled = true }} + {{- if .Values.filer.s3.createBuckets }} + {{- $createBuckets = .Values.filer.s3.createBuckets }} + {{- end }} + {{- $enableAuth = .Values.filer.s3.enableAuth }} + {{- $existingConfigSecret = .Values.filer.s3.existingConfigSecret }} + {{- end }} +{{- end }} + +{{- if and $s3Enabled $createBuckets }} --- apiVersion: batch/v1 kind: Job @@ -32,9 +58,9 @@ spec: - name: WEED_CLUSTER_DEFAULT value: "sw" - name: WEED_CLUSTER_SW_MASTER - value: "{{ template "seaweedfs.name" . }}-master.{{ .Release.Namespace }}:{{ .Values.master.port }}" + value: {{ include "seaweedfs.cluster.masterAddress" . | quote }} - name: WEED_CLUSTER_SW_FILER - value: "{{ template "seaweedfs.name" . }}-filer-client.{{ .Release.Namespace }}:{{ .Values.filer.port }}" + value: {{ include "seaweedfs.cluster.filerAddress" . | quote }} - name: POD_IP valueFrom: fieldRef: @@ -71,24 +97,29 @@ spec: echo "Service at $url failed to become ready within 5 minutes" exit 1 } + {{- if .Values.allInOne.enabled }} + wait_for_service "http://$WEED_CLUSTER_SW_MASTER{{ .Values.allInOne.readinessProbe.httpGet.path }}" + wait_for_service "http://$WEED_CLUSTER_SW_FILER{{ .Values.filer.readinessProbe.httpGet.path }}" + {{- else }} wait_for_service "http://$WEED_CLUSTER_SW_MASTER{{ .Values.master.readinessProbe.httpGet.path }}" wait_for_service "http://$WEED_CLUSTER_SW_FILER{{ .Values.filer.readinessProbe.httpGet.path }}" - {{- range $reg, $props := $.Values.filer.s3.createBuckets }} - exec /bin/echo \ - "s3.bucket.create --name {{ $props.name }}" |\ + {{- end }} + {{- range $createBuckets }} + /bin/echo \ + "s3.bucket.create --name {{ .name }}" |\ /usr/bin/weed shell {{- end }} - {{- range $reg, $props := $.Values.filer.s3.createBuckets }} - {{- if $props.anonymousRead }} - exec /bin/echo \ + {{- range $createBuckets }} + {{- if .anonymousRead }} + /bin/echo \ "s3.configure --user anonymous \ - --buckets {{ $props.name }} \ + --buckets {{ .name }} \ --actions Read \ --apply true" |\ /usr/bin/weed shell {{- end }} {{- end }} - {{- if .Values.filer.s3.enableAuth }} + {{- if $enableAuth }} volumeMounts: - name: config-users mountPath: /etc/sw @@ -106,17 +137,15 @@ spec: {{- if .Values.filer.containerSecurityContext.enabled }} securityContext: {{- omit .Values.filer.containerSecurityContext "enabled" | toYaml | nindent 12 }} {{- end }} - {{- if .Values.filer.s3.enableAuth }} + {{- if $enableAuth }} volumes: - name: config-users secret: defaultMode: 420 - {{- if not (empty .Values.filer.s3.existingConfigSecret) }} - secretName: {{ .Values.filer.s3.existingConfigSecret }} + {{- if $existingConfigSecret }} + secretName: {{ $existingConfigSecret }} {{- else }} - secretName: seaweedfs-s3-secret + secretName: {{ template "seaweedfs.name" . }}-s3-secret {{- end }} - {{- end }}{{/** if .Values.filer.s3.enableAuth **/}} -{{- end }}{{/** if .Values.master.enabled **/}} -{{- end }}{{/** if .Values.filer.s3.enabled **/}} -{{- end }}{{/** if .Values.filer.s3.createBuckets **/}} + {{- end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/volume/volume-statefulset.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/volume/volume-statefulset.yaml index 29a035a2..1a8964a5 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/templates/volume/volume-statefulset.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/volume/volume-statefulset.yaml @@ -251,7 +251,7 @@ spec: httpGet: path: {{ $volume.readinessProbe.httpGet.path }} port: {{ $volume.port }} - scheme: {{ $volume.readinessProbe.scheme }} + scheme: {{ $volume.readinessProbe.httpGet.scheme }} initialDelaySeconds: {{ $volume.readinessProbe.initialDelaySeconds }} periodSeconds: {{ $volume.readinessProbe.periodSeconds }} successThreshold: {{ $volume.readinessProbe.successThreshold }} @@ -263,7 +263,7 @@ spec: httpGet: path: {{ $volume.livenessProbe.httpGet.path }} port: {{ $volume.port }} - scheme: {{ $volume.livenessProbe.scheme }} + scheme: {{ $volume.livenessProbe.httpGet.scheme }} initialDelaySeconds: {{ $volume.livenessProbe.initialDelaySeconds }} periodSeconds: {{ $volume.livenessProbe.periodSeconds }} successThreshold: {{ $volume.livenessProbe.successThreshold }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/values.yaml b/packages/system/seaweedfs/charts/seaweedfs/values.yaml index cf16623c..b71e1071 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/values.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/values.yaml @@ -22,6 +22,8 @@ global: serviceAccountName: "seaweedfs" automountServiceAccountToken: true certificates: + duration: 87600h + renewBefore: 720h alphacrds: false monitoring: enabled: false @@ -235,27 +237,27 @@ master: ingress: enabled: false - className: "nginx" + className: "" # host: false for "*" hostname host: "master.seaweedfs.local" path: "/sw-master/?(.*)" pathType: ImplementationSpecific - annotations: - nginx.ingress.kubernetes.io/auth-type: "basic" - nginx.ingress.kubernetes.io/auth-secret: "default/ingress-basic-auth-secret" - nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - SW-Master' - nginx.ingress.kubernetes.io/service-upstream: "true" - nginx.ingress.kubernetes.io/rewrite-target: /$1 - nginx.ingress.kubernetes.io/use-regex: "true" - nginx.ingress.kubernetes.io/enable-rewrite-log: "true" - nginx.ingress.kubernetes.io/ssl-redirect: "false" - nginx.ingress.kubernetes.io/force-ssl-redirect: "false" - nginx.ingress.kubernetes.io/configuration-snippet: | - sub_filter '' ' '; #add base url - sub_filter '="/' '="./'; #make absolute paths to relative - sub_filter '=/' '=./'; - sub_filter '/seaweedfsstatic' './seaweedfsstatic'; - sub_filter_once off; + annotations: {} + # nginx.ingress.kubernetes.io/auth-type: "basic" + # nginx.ingress.kubernetes.io/auth-secret: "default/ingress-basic-auth-secret" + # nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - SW-Master' + # nginx.ingress.kubernetes.io/service-upstream: "true" + # nginx.ingress.kubernetes.io/rewrite-target: /$1 + # nginx.ingress.kubernetes.io/use-regex: "true" + # nginx.ingress.kubernetes.io/enable-rewrite-log: "true" + # nginx.ingress.kubernetes.io/ssl-redirect: "false" + # nginx.ingress.kubernetes.io/force-ssl-redirect: "false" + # nginx.ingress.kubernetes.io/configuration-snippet: | + # sub_filter '' ' '; #add base url + # sub_filter '="/' '="./'; #make absolute paths to relative + # sub_filter '=/' '=./'; + # sub_filter '/seaweedfsstatic' './seaweedfsstatic'; + # sub_filter_once off; tls: [] extraEnvironmentVars: @@ -308,7 +310,7 @@ volume: # limit file size to avoid out of memory, default 256mb fileSizeLimitMB: null # minimum free disk space(in percents). If free disk space lower this value - all volumes marks as ReadOnly - minFreeSpacePercent: 7 + minFreeSpacePercent: 1 # Custom command line arguments to add to the volume command # Example to fix IPv6 metrics connectivity issues: @@ -769,28 +771,28 @@ filer: ingress: enabled: false - className: "nginx" + className: "" # host: false for "*" hostname host: "seaweedfs.cluster.local" path: "/sw-filer/?(.*)" pathType: ImplementationSpecific - annotations: - nginx.ingress.kubernetes.io/backend-protocol: GRPC - nginx.ingress.kubernetes.io/auth-type: "basic" - nginx.ingress.kubernetes.io/auth-secret: "default/ingress-basic-auth-secret" - nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - SW-Filer' - nginx.ingress.kubernetes.io/service-upstream: "true" - nginx.ingress.kubernetes.io/rewrite-target: /$1 - nginx.ingress.kubernetes.io/use-regex: "true" - nginx.ingress.kubernetes.io/enable-rewrite-log: "true" - nginx.ingress.kubernetes.io/ssl-redirect: "false" - nginx.ingress.kubernetes.io/force-ssl-redirect: "false" - nginx.ingress.kubernetes.io/configuration-snippet: | - sub_filter '' ' '; #add base url - sub_filter '="/' '="./'; #make absolute paths to relative - sub_filter '=/' '=./'; - sub_filter '/seaweedfsstatic' './seaweedfsstatic'; - sub_filter_once off; + annotations: {} + # nginx.ingress.kubernetes.io/backend-protocol: GRPC + # nginx.ingress.kubernetes.io/auth-type: "basic" + # nginx.ingress.kubernetes.io/auth-secret: "default/ingress-basic-auth-secret" + # nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - SW-Filer' + # nginx.ingress.kubernetes.io/service-upstream: "true" + # nginx.ingress.kubernetes.io/rewrite-target: /$1 + # nginx.ingress.kubernetes.io/use-regex: "true" + # nginx.ingress.kubernetes.io/enable-rewrite-log: "true" + # nginx.ingress.kubernetes.io/ssl-redirect: "false" + # nginx.ingress.kubernetes.io/force-ssl-redirect: "false" + # nginx.ingress.kubernetes.io/configuration-snippet: | + # sub_filter '' ' '; #add base url + # sub_filter '="/' '="./'; #make absolute paths to relative + # sub_filter '=/' '=./'; + # sub_filter '/seaweedfsstatic' './seaweedfsstatic'; + # sub_filter_once off; # extraEnvVars is a list of extra environment variables to set with the stateful set. extraEnvironmentVars: @@ -854,8 +856,6 @@ filer: port: 8333 # add additional https port httpsPort: 0 - # allow empty folders - allowEmptyFolder: false # Suffix of the host name, {bucket}.{domainName} domainName: "" # enable user & permission to s3 (need to inject to all services) @@ -873,7 +873,7 @@ filer: # anonymousRead: false s3: - enabled: true + enabled: false imageOverride: null restartPolicy: null replicas: 1 @@ -883,8 +883,6 @@ s3: httpsPort: 0 metricsPort: 9327 loggingOverrideLevel: null - # allow empty folders - allowEmptyFolder: true # enable user & permission to s3 (need to inject to all services) enableAuth: false # set to the name of an existing kubernetes Secret with the s3 json config file @@ -977,9 +975,9 @@ s3: extraEnvironmentVars: # Custom command line arguments to add to the s3 command - # Example to fix connection idle seconds: - extraArgs: ["-idleTimeout=30"] - # extraArgs: [] + # Default idleTimeout is 120 seconds. Example to customize: + # extraArgs: ["-idleTimeout=300"] + extraArgs: [] # used to configure livenessProbe on s3 containers # @@ -1009,7 +1007,7 @@ s3: ingress: enabled: false - className: "nginx" + className: "" # host: false for "*" hostname host: "seaweedfs.cluster.local" path: "/" @@ -1095,6 +1093,7 @@ allInOne: enabled: false imageOverride: null restartPolicy: Always + replicas: 1 # Number of replicas (note: multiple replicas may require shared storage) # Core configuration idleTimeout: 30 # Connection idle seconds @@ -1106,24 +1105,85 @@ allInOne: metricsIp: "" # Metrics listen IP. If empty, defaults to bindAddress loggingOverrideLevel: null # Override logging level - # Service configuration + # Custom command line arguments to add to the server command + # Example to fix IPv6 metrics connectivity issues: + # extraArgs: ["-metricsIp", "0.0.0.0"] + # Example with multiple args: + # extraArgs: ["-customFlag", "value", "-anotherFlag"] + extraArgs: [] + + # Update strategy configuration + # type: Recreate or RollingUpdate + # For single replica, Recreate is recommended to avoid data conflicts. + # For multiple replicas with RollingUpdate, you MUST use shared storage + # (e.g., data.type: persistentVolumeClaim with ReadWriteMany access mode) + # to avoid data loss or inconsistency between pods. + updateStrategy: + type: Recreate + + # S3 gateway configuration + # Note: Most parameters below default to null, which means they inherit from + # the global s3.* settings. Set explicit values here to override for allInOne only. s3: enabled: false # Whether to enable S3 gateway + port: null # S3 gateway port (null inherits from s3.port) + httpsPort: null # S3 gateway HTTPS port (null inherits from s3.httpsPort) + domainName: null # Suffix of the host name (null inherits from s3.domainName) + enableAuth: false # Enable user & permission to S3 + # Set to the name of an existing kubernetes Secret with the s3 json config file + # should have a secret key called seaweedfs_s3_config with an inline json config + existingConfigSecret: null + auditLogConfig: null # S3 audit log configuration (null inherits from s3.auditLogConfig) + # You may specify buckets to be created during the install process. + # Buckets may be exposed publicly by setting `anonymousRead` to `true` + # createBuckets: + # - name: bucket-a + # anonymousRead: true + # - name: bucket-b + # anonymousRead: false + + # SFTP server configuration + # Note: Most parameters below default to null, which means they inherit from + # the global sftp.* settings. Set explicit values here to override for allInOne only. sftp: enabled: false # Whether to enable SFTP server + port: null # SFTP port (null inherits from sftp.port) + sshPrivateKey: null # Path to SSH private key (null inherits from sftp.sshPrivateKey) + hostKeysFolder: null # Path to SSH host keys folder (null inherits from sftp.hostKeysFolder) + authMethods: null # Comma-separated auth methods (null inherits from sftp.authMethods) + maxAuthTries: null # Maximum authentication attempts (null inherits from sftp.maxAuthTries) + bannerMessage: null # Banner message (null inherits from sftp.bannerMessage) + loginGraceTime: null # Login grace time (null inherits from sftp.loginGraceTime) + clientAliveInterval: null # Client keep-alive interval (null inherits from sftp.clientAliveInterval) + clientAliveCountMax: null # Maximum missed keep-alive messages (null inherits from sftp.clientAliveCountMax) + enableAuth: false # Enable SFTP authentication + # Set to the name of an existing kubernetes Secret with the sftp json config file + existingConfigSecret: null + # Set to the name of an existing kubernetes Secret with the SSH keys + existingSshConfigSecret: null # Service settings service: annotations: {} # Annotations for the service type: ClusterIP # Service type (ClusterIP, NodePort, LoadBalancer) + internalTrafficPolicy: Cluster # Internal traffic policy + + # Note: For ingress in all-in-one mode, use the standard s3.ingress and + # filer.ingress settings. The templates automatically detect all-in-one mode + # and point to the correct service (seaweedfs-all-in-one instead of + # seaweedfs-s3 or seaweedfs-filer). # Storage configuration data: - type: "emptyDir" # Options: "hostPath", "persistentVolumeClaim", "emptyDir" + type: "emptyDir" # Options: "hostPath", "persistentVolumeClaim", "emptyDir", "existingClaim" hostPathPrefix: /mnt/data # Path prefix for hostPath volumes - claimName: seaweedfs-data-pvc # Name of the PVC to use - size: "" # Size of the PVC - storageClass: "" # Storage class for the PVC + claimName: seaweedfs-data-pvc # Name of the PVC to use (for existingClaim type) + size: null # Size of the PVC (null defaults to 10Gi for persistentVolumeClaim type) + storageClass: null # Storage class for the PVC (null uses cluster default) + # accessModes for the PVC. Default is ["ReadWriteOnce"]. + # For multi-replica deployments, use ["ReadWriteMany"] with a compatible storage class. + accessModes: [] + annotations: {} # Annotations for the PVC # Health checks readinessProbe: @@ -1131,7 +1191,7 @@ allInOne: httpGet: path: /cluster/status port: 9333 - scheme: HTTP + scheme: HTTP initialDelaySeconds: 10 periodSeconds: 15 successThreshold: 1 @@ -1143,7 +1203,7 @@ allInOne: httpGet: path: /cluster/status port: 9333 - scheme: HTTP + scheme: HTTP initialDelaySeconds: 20 periodSeconds: 30 successThreshold: 1 @@ -1152,6 +1212,18 @@ allInOne: # Additional resources extraEnvironmentVars: {} # Additional environment variables + # Secret environment variables (for database credentials, etc.) + # Example: + # secretExtraEnvironmentVars: + # WEED_POSTGRES_USERNAME: + # secretKeyRef: + # name: postgres-credentials + # key: username + # WEED_POSTGRES_PASSWORD: + # secretKeyRef: + # name: postgres-credentials + # key: password + secretExtraEnvironmentVars: {} extraVolumeMounts: "" # Additional volume mounts extraVolumes: "" # Additional volumes initContainers: "" # Init containers @@ -1171,7 +1243,7 @@ allInOne: matchLabels: app.kubernetes.io/name: {{ template "seaweedfs.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/component: master + app.kubernetes.io/component: seaweedfs-all-in-one topologyKey: kubernetes.io/hostname # Topology Spread Constraints Settings @@ -1179,16 +1251,16 @@ allInOne: # for a PodSpec. By Default no constraints are set. topologySpreadConstraints: "" - # Toleration Settings for master pods + # Toleration Settings for pods # This should be a multi-line string matching the Toleration array # in a PodSpec. tolerations: "" - # nodeSelector labels for master pod assignment, formatted as a muli-line string. + # nodeSelector labels for pod assignment, formatted as a muli-line string. # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector nodeSelector: "" - # Used to assign priority to master pods + # Used to assign priority to pods # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ priorityClassName: "" @@ -1268,6 +1340,9 @@ certificates: keySize: 2048 duration: 2160h # 90d renewBefore: 360h # 15d + ca: + duration: 87600h # 10 years + renewBefore: 720h # 30d externalCertificates: # This will avoid the need to use cert-manager and will rely on providing your own external certificates and CA # you will need to store your provided certificates in the secret read by the different services: diff --git a/packages/system/seaweedfs/images/seaweedfs/Dockerfile b/packages/system/seaweedfs/images/seaweedfs/Dockerfile index 48776a56..7177c70f 100644 --- a/packages/system/seaweedfs/images/seaweedfs/Dockerfile +++ b/packages/system/seaweedfs/images/seaweedfs/Dockerfile @@ -1,2 +1,2 @@ -ARG VERSION=3.99 +ARG VERSION=4.02 FROM chrislusf/seaweedfs:${VERSION} diff --git a/packages/system/seaweedfs/patches/long-term-ca.diff b/packages/system/seaweedfs/patches/long-term-ca.diff deleted file mode 100644 index a53d697d..00000000 --- a/packages/system/seaweedfs/patches/long-term-ca.diff +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/cert/ca-cert.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/cert/ca-cert.yaml -index 0fd6615e..f2572558 100644 ---- a/packages/system/seaweedfs/charts/seaweedfs/templates/cert/ca-cert.yaml -+++ b/packages/system/seaweedfs/charts/seaweedfs/templates/cert/ca-cert.yaml -@@ -13,6 +13,8 @@ spec: - secretName: {{ template "seaweedfs.name" . }}-ca-cert - commonName: "{{ template "seaweedfs.name" . }}-root-ca" - isCA: true -+ duration: 87600h -+ renewBefore: 720h - issuerRef: - name: {{ template "seaweedfs.name" . }}-issuer - kind: Issuer From 540e1c6e0db744093569162158f41cc36fa1bbe0 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Tue, 9 Dec 2025 11:37:32 +0100 Subject: [PATCH 11/43] [virtual-machine,vm-instance] Add nodeAffinity for Windows VMs based on scheduling config Signed-off-by: Andrei Kvapil (cherry picked from commit 3975da93c6b8ac0c856c9756f1d0557e5045136c) --- .../virtual-machine/templates/_helpers.tpl | 33 +++++++++++++++++++ .../apps/virtual-machine/templates/vm.yaml | 2 ++ .../apps/vm-instance/templates/_helpers.tpl | 33 +++++++++++++++++++ packages/apps/vm-instance/templates/vm.yaml | 3 ++ 4 files changed, 71 insertions(+) diff --git a/packages/apps/virtual-machine/templates/_helpers.tpl b/packages/apps/virtual-machine/templates/_helpers.tpl index f3ade695..7b6929ac 100644 --- a/packages/apps/virtual-machine/templates/_helpers.tpl +++ b/packages/apps/virtual-machine/templates/_helpers.tpl @@ -69,3 +69,36 @@ Generate a stable UUID for cloud-init re-initialization upon upgrade. {{- end }} {{- $uuid }} {{- end }} + +{{/* +Node Affinity for Windows VMs +*/}} +{{- define "virtual-machine.nodeAffinity" -}} +{{- $configMap := lookup "v1" "ConfigMap" "cozy-system" "cozystack-scheduling" -}} +{{- if $configMap -}} +{{- $dedicatedNodesForWindowsVMs := get $configMap.data "dedicatedNodesForWindowsVMs" -}} +{{- if eq $dedicatedNodesForWindowsVMs "true" -}} +{{- $isWindows := hasPrefix "windows" (toString .Values.instanceProfile) -}} +affinity: + nodeAffinity: + {{- if $isWindows }} + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: scheduling.cozystack.io/vm-windows + operator: In + values: + - "true" + {{- else }} + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + preference: + matchExpressions: + - key: scheduling.cozystack.io/vm-windows + operator: NotIn + values: + - "true" + {{- end }} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/packages/apps/virtual-machine/templates/vm.yaml b/packages/apps/virtual-machine/templates/vm.yaml index 92084acb..efadf3af 100644 --- a/packages/apps/virtual-machine/templates/vm.yaml +++ b/packages/apps/virtual-machine/templates/vm.yaml @@ -124,6 +124,8 @@ spec: terminationGracePeriodSeconds: 30 + {{- include "virtual-machine.nodeAffinity" . | nindent 6 }} + volumes: - name: systemdisk dataVolume: diff --git a/packages/apps/vm-instance/templates/_helpers.tpl b/packages/apps/vm-instance/templates/_helpers.tpl index f3ade695..7b6929ac 100644 --- a/packages/apps/vm-instance/templates/_helpers.tpl +++ b/packages/apps/vm-instance/templates/_helpers.tpl @@ -69,3 +69,36 @@ Generate a stable UUID for cloud-init re-initialization upon upgrade. {{- end }} {{- $uuid }} {{- end }} + +{{/* +Node Affinity for Windows VMs +*/}} +{{- define "virtual-machine.nodeAffinity" -}} +{{- $configMap := lookup "v1" "ConfigMap" "cozy-system" "cozystack-scheduling" -}} +{{- if $configMap -}} +{{- $dedicatedNodesForWindowsVMs := get $configMap.data "dedicatedNodesForWindowsVMs" -}} +{{- if eq $dedicatedNodesForWindowsVMs "true" -}} +{{- $isWindows := hasPrefix "windows" (toString .Values.instanceProfile) -}} +affinity: + nodeAffinity: + {{- if $isWindows }} + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: scheduling.cozystack.io/vm-windows + operator: In + values: + - "true" + {{- else }} + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + preference: + matchExpressions: + - key: scheduling.cozystack.io/vm-windows + operator: NotIn + values: + - "true" + {{- end }} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/packages/apps/vm-instance/templates/vm.yaml b/packages/apps/vm-instance/templates/vm.yaml index 61fc65a7..acad3475 100644 --- a/packages/apps/vm-instance/templates/vm.yaml +++ b/packages/apps/vm-instance/templates/vm.yaml @@ -95,6 +95,9 @@ spec: noCloud: {} {{- end }} terminationGracePeriodSeconds: 30 + + {{- include "virtual-machine.nodeAffinity" . | nindent 6 }} + volumes: {{- range .Values.disks }} - name: disk-{{ .name }} From fb5b4da2b2745aa78ff751184c71a78f3f9cbdf3 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Tue, 16 Dec 2025 10:42:10 +0100 Subject: [PATCH 12/43] [cilium] Enable automatic pod rollout on configmap updates Signed-off-by: Andrei Kvapil (cherry picked from commit 97e8d2aa497b72fe5fa5ab53290256b7c3cf1f0a) --- packages/system/cilium/values.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/system/cilium/values.yaml b/packages/system/cilium/values.yaml index 72263556..abadcc36 100644 --- a/packages/system/cilium/values.yaml +++ b/packages/system/cilium/values.yaml @@ -18,3 +18,6 @@ cilium: digest: "sha256:81262986a41487bfa3d0465091d3a386def5bd1ab476350bd4af2fdee5846fe6" envoy: enabled: false + rollOutCiliumPods: true + operator: + rollOutPods: true From da44a65ba948bc664421ed06a35108f1a00323f2 Mon Sep 17 00:00:00 2001 From: Nikita <166552198+nbykov0@users.noreply.github.com> Date: Tue, 23 Dec 2025 17:11:22 +0300 Subject: [PATCH 13/43] [system/cilium] Enable topology-aware routing for services (#1734) --- packages/system/cilium/values.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/system/cilium/values.yaml b/packages/system/cilium/values.yaml index abadcc36..95159b1f 100644 --- a/packages/system/cilium/values.yaml +++ b/packages/system/cilium/values.yaml @@ -10,6 +10,7 @@ cilium: enabled: true loadBalancer: algorithm: maglev + serviceTopology: true ipam: mode: "kubernetes" image: From 37a2e3879827b8996924f0c9aa5cb7bfcae0ed57 Mon Sep 17 00:00:00 2001 From: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com> Date: Tue, 23 Dec 2025 16:27:57 +0000 Subject: [PATCH 14/43] Prepare release v0.39.0 Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com> --- packages/apps/http-cache/images/nginx-cache.tag | 2 +- packages/apps/kubernetes/images/kubevirt-csi-driver.tag | 2 +- packages/core/installer/values.yaml | 2 +- packages/core/testing/values.yaml | 2 +- packages/extra/bootbox/images/matchbox.tag | 2 +- packages/extra/seaweedfs/images/objectstorage-sidecar.tag | 2 +- packages/system/bucket/images/s3manager.tag | 2 +- packages/system/cozystack-api/values.yaml | 2 +- packages/system/cozystack-controller/values.yaml | 4 ++-- packages/system/dashboard/templates/configmap.yaml | 2 +- packages/system/dashboard/values.yaml | 6 +++--- packages/system/kamaji/values.yaml | 4 ++-- packages/system/kubeovn-plunger/values.yaml | 2 +- packages/system/kubeovn-webhook/values.yaml | 2 +- packages/system/kubeovn/values.yaml | 2 +- packages/system/kubevirt-csi-node/values.yaml | 2 +- packages/system/lineage-controller-webhook/values.yaml | 2 +- packages/system/objectstorage-controller/values.yaml | 2 +- packages/system/seaweedfs/values.yaml | 2 +- 19 files changed, 23 insertions(+), 23 deletions(-) diff --git a/packages/apps/http-cache/images/nginx-cache.tag b/packages/apps/http-cache/images/nginx-cache.tag index 0970e11c..185dcc66 100644 --- a/packages/apps/http-cache/images/nginx-cache.tag +++ b/packages/apps/http-cache/images/nginx-cache.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/nginx-cache:0.0.0@sha256:50ac1581e3100bd6c477a71161cb455a341ffaf9e5e2f6086802e4e25271e8af +ghcr.io/cozystack/cozystack/nginx-cache:0.0.0@sha256:e0a07082bb6fc6aeaae2315f335386f1705a646c72f9e0af512aebbca5cb2b15 diff --git a/packages/apps/kubernetes/images/kubevirt-csi-driver.tag b/packages/apps/kubernetes/images/kubevirt-csi-driver.tag index 61e9f2ba..550279b8 100644 --- a/packages/apps/kubernetes/images/kubevirt-csi-driver.tag +++ b/packages/apps/kubernetes/images/kubevirt-csi-driver.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:47396dac04a24f824f82892c90efa160539e1e0f8ac697f5dc8ecf397e1ac413 +ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:64c0b248e0d6b0a1578f59cab725152f3223a6d53ac0371eccaf023c0cd75904 diff --git a/packages/core/installer/values.yaml b/packages/core/installer/values.yaml index e1a56418..6f053bbd 100644 --- a/packages/core/installer/values.yaml +++ b/packages/core/installer/values.yaml @@ -1,2 +1,2 @@ cozystack: - image: ghcr.io/cozystack/cozystack/installer:v0.38.4@sha256:2530f78cd456e0b0619d8db607c4d47127bbdd36b99f82a4029758a106169f09 + image: ghcr.io/cozystack/cozystack/installer:v0.39.0@sha256:8fb2f4f9ab482a00b6200f56bed69fad68a117bb65b341d3beca4bed5bd7b80f diff --git a/packages/core/testing/values.yaml b/packages/core/testing/values.yaml index 97c640db..7bf63e3a 100755 --- a/packages/core/testing/values.yaml +++ b/packages/core/testing/values.yaml @@ -1,2 +1,2 @@ e2e: - image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.38.4@sha256:8284585dfdc337d6720f44b82417b42dc9321661025a8c046e085004d4573597 + image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.39.0@sha256:c113cb262e8e8fd87c013a347c16def906e3a3dd179519f2ad6a5c054a44f271 diff --git a/packages/extra/bootbox/images/matchbox.tag b/packages/extra/bootbox/images/matchbox.tag index 48db300d..20f412c7 100644 --- a/packages/extra/bootbox/images/matchbox.tag +++ b/packages/extra/bootbox/images/matchbox.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/matchbox:v0.38.4@sha256:8398c5546dedfcd9bf68a6eef165e423b2f0bcb10a21f7e76b7ae4a6beb579e2 +ghcr.io/cozystack/cozystack/matchbox:v0.39.0@sha256:ec0d9e2a74e313c76a93f6a0522e31731f33cfc6575d14d93ddfe24f2fe53eec diff --git a/packages/extra/seaweedfs/images/objectstorage-sidecar.tag b/packages/extra/seaweedfs/images/objectstorage-sidecar.tag index c302bef2..0a20a5d9 100644 --- a/packages/extra/seaweedfs/images/objectstorage-sidecar.tag +++ b/packages/extra/seaweedfs/images/objectstorage-sidecar.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.38.4@sha256:5136a36dddb14d2b95ceefbf8cc4b0cf6411b2ec9ae6898173b24c57790cc857 +ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.0@sha256:d5a52df856002b81cbff9c08c28d600271ccbaf202c36fc01aab7fdaec0ac7c9 diff --git a/packages/system/bucket/images/s3manager.tag b/packages/system/bucket/images/s3manager.tag index ec7741c2..3ba8a1db 100644 --- a/packages/system/bucket/images/s3manager.tag +++ b/packages/system/bucket/images/s3manager.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/s3manager:v0.5.0@sha256:b58f5b192d1f47026c19ad51a857e31c256a9ff46c24a5fbbfcfe4f61981b8eb +ghcr.io/cozystack/cozystack/s3manager:v0.5.0@sha256:eb363ee78465884ac314a3e5357ff30b0274dbee6ca2b94935b2ee2193870e0f diff --git a/packages/system/cozystack-api/values.yaml b/packages/system/cozystack-api/values.yaml index 920222b6..65587d04 100644 --- a/packages/system/cozystack-api/values.yaml +++ b/packages/system/cozystack-api/values.yaml @@ -1,5 +1,5 @@ cozystackAPI: - image: ghcr.io/cozystack/cozystack/cozystack-api:v0.38.4@sha256:58dba7b8b9915ece3a5785b6178536377fce56dc55451f2736415cdeab9185ff + image: ghcr.io/cozystack/cozystack/cozystack-api:v0.39.0@sha256:d9669a49fd22b3f1ed56aa21857f99c63e88426488530092f606ad275f6ce650 localK8sAPIEndpoint: enabled: true replicas: 2 diff --git a/packages/system/cozystack-controller/values.yaml b/packages/system/cozystack-controller/values.yaml index d1446268..b8ba4408 100644 --- a/packages/system/cozystack-controller/values.yaml +++ b/packages/system/cozystack-controller/values.yaml @@ -1,6 +1,6 @@ cozystackController: - image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.38.4@sha256:a5cbe6b939ce10125b975e0395c9bd4a0c880aabe93dae832afc9334d33b7f63 + image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.39.0@sha256:af229b1d63705af9eb8bbf6867b4e94412516cd41ecfbc73f7fb19ac705e739a debug: false disableTelemetry: false - cozystackVersion: "v0.38.4" + cozystackVersion: "v0.39.0" cozystackAPIKind: "DaemonSet" diff --git a/packages/system/dashboard/templates/configmap.yaml b/packages/system/dashboard/templates/configmap.yaml index 6219aa0e..e2baa680 100644 --- a/packages/system/dashboard/templates/configmap.yaml +++ b/packages/system/dashboard/templates/configmap.yaml @@ -1,6 +1,6 @@ {{- $brandingConfig:= lookup "v1" "ConfigMap" "cozy-system" "cozystack-branding" }} -{{- $tenantText := "v0.38.4" }} +{{- $tenantText := "v0.39.0" }} {{- $footerText := "Cozystack" }} {{- $titleText := "Cozystack Dashboard" }} {{- $logoText := "" }} diff --git a/packages/system/dashboard/values.yaml b/packages/system/dashboard/values.yaml index 52983589..5ce5fdd5 100644 --- a/packages/system/dashboard/values.yaml +++ b/packages/system/dashboard/values.yaml @@ -1,6 +1,6 @@ openapiUI: - image: ghcr.io/cozystack/cozystack/openapi-ui:v0.38.4@sha256:aae9aea2aa9aea905f0dea051104bff75f05bf554ed450ae013225359ae4f316 + image: ghcr.io/cozystack/cozystack/openapi-ui:v0.39.0@sha256:ea8b99160f7ab94de418bb445651769b8546b0659ae1f598670d4c581d370f88 openapiUIK8sBff: - image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.38.4@sha256:2845688891e0cf9513768aa468ff4de5b6b40e58cc763bacbfe2b417ebad1bdf + image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.39.0@sha256:0a5168e29ba667cc3532ebc6814c7f9c9f1102874a9d8b0c038e9fa2eefb6efd tokenProxy: - image: ghcr.io/cozystack/cozystack/token-proxy:v0.38.4@sha256:fad27112617bb17816702571e1f39d0ac3fe5283468d25eb12f79906cdab566b + image: ghcr.io/cozystack/cozystack/token-proxy:v0.39.0@sha256:fad27112617bb17816702571e1f39d0ac3fe5283468d25eb12f79906cdab566b diff --git a/packages/system/kamaji/values.yaml b/packages/system/kamaji/values.yaml index 40d85177..b8d00f00 100644 --- a/packages/system/kamaji/values.yaml +++ b/packages/system/kamaji/values.yaml @@ -3,7 +3,7 @@ kamaji: deploy: false image: pullPolicy: IfNotPresent - tag: v0.38.4@sha256:458b8ae75e845e08c3c3d20f8af0ea1d7f8933739609d19f266fbf280417b764 + tag: v0.39.0@sha256:a8981fc592628855693aeeebc3a1f51058a8e667fa2405416b6ed1b1cbe86c09 repository: ghcr.io/cozystack/cozystack/kamaji resources: limits: @@ -13,4 +13,4 @@ kamaji: cpu: 100m memory: 100Mi extraArgs: - - --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.38.4@sha256:458b8ae75e845e08c3c3d20f8af0ea1d7f8933739609d19f266fbf280417b764 + - --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.39.0@sha256:a8981fc592628855693aeeebc3a1f51058a8e667fa2405416b6ed1b1cbe86c09 diff --git a/packages/system/kubeovn-plunger/values.yaml b/packages/system/kubeovn-plunger/values.yaml index 9dc9d594..3478e16c 100644 --- a/packages/system/kubeovn-plunger/values.yaml +++ b/packages/system/kubeovn-plunger/values.yaml @@ -1,4 +1,4 @@ portSecurity: true routes: "" -image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.38.4@sha256:e8bd1f93e38b7b7d124deddd0c2498f7df0fbe89b613d12a0fbf3e47220f9053 +image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.39.0@sha256:ce250d9ac04dc251f105f385d204f58ec3c27ced6e1023e52e7e8121b3c99fd5 ovnCentralName: ovn-central diff --git a/packages/system/kubeovn-webhook/values.yaml b/packages/system/kubeovn-webhook/values.yaml index 83bbfd1a..7c3cbf0a 100644 --- a/packages/system/kubeovn-webhook/values.yaml +++ b/packages/system/kubeovn-webhook/values.yaml @@ -1,3 +1,3 @@ portSecurity: true routes: "" -image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.38.4@sha256:cb39773a626f01da04cb4e818faa9460a7d193e045f5c80f2c2e9116d18ef3c0 +image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.39.0@sha256:7bfd458299a507f2cf82cddb65941ded6991fd4ba92fd46010cbc8c363126085 diff --git a/packages/system/kubeovn/values.yaml b/packages/system/kubeovn/values.yaml index 7de48124..2b7f4f62 100644 --- a/packages/system/kubeovn/values.yaml +++ b/packages/system/kubeovn/values.yaml @@ -65,4 +65,4 @@ global: images: kubeovn: repository: kubeovn - tag: v1.14.11@sha256:e277ee347814af85528851cf3d604a65ab9fb2e833b173e658490c35e00596b0 + tag: v1.14.11@sha256:d413fa033b6e2971866f2b27d25d5482f923099afe4b58ceedcfd031b22e410d diff --git a/packages/system/kubevirt-csi-node/values.yaml b/packages/system/kubevirt-csi-node/values.yaml index 6ff9991a..2de432c4 100644 --- a/packages/system/kubevirt-csi-node/values.yaml +++ b/packages/system/kubevirt-csi-node/values.yaml @@ -1,3 +1,3 @@ storageClass: replicated csiDriver: - image: ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:47396dac04a24f824f82892c90efa160539e1e0f8ac697f5dc8ecf397e1ac413 + image: ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:64c0b248e0d6b0a1578f59cab725152f3223a6d53ac0371eccaf023c0cd75904 diff --git a/packages/system/lineage-controller-webhook/values.yaml b/packages/system/lineage-controller-webhook/values.yaml index 80db7f86..ee39e044 100644 --- a/packages/system/lineage-controller-webhook/values.yaml +++ b/packages/system/lineage-controller-webhook/values.yaml @@ -1,5 +1,5 @@ lineageControllerWebhook: - image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.38.4@sha256:557e6cee3dfce7ec9e69b404806c6b3c3766fa523cb3dc1cbd7155c24af2cc96 + image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.39.0@sha256:cb264b193256dd5db79ba50ad44fc2301fb19ac34155f6f6638d6cadfd45e370 debug: false localK8sAPIEndpoint: enabled: true diff --git a/packages/system/objectstorage-controller/values.yaml b/packages/system/objectstorage-controller/values.yaml index b902622e..e7d1e757 100644 --- a/packages/system/objectstorage-controller/values.yaml +++ b/packages/system/objectstorage-controller/values.yaml @@ -1,3 +1,3 @@ objectstorage: controller: - image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.38.4@sha256:91ed0ba4de7958708f77427d2c752dece969236c13927c17033d792700e9c6f4" + image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.39.0@sha256:91ed0ba4de7958708f77427d2c752dece969236c13927c17033d792700e9c6f4" diff --git a/packages/system/seaweedfs/values.yaml b/packages/system/seaweedfs/values.yaml index 52ab1551..6d8d396d 100644 --- a/packages/system/seaweedfs/values.yaml +++ b/packages/system/seaweedfs/values.yaml @@ -124,7 +124,7 @@ seaweedfs: bucketClassName: "seaweedfs" region: "" sidecar: - image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.38.4@sha256:5136a36dddb14d2b95ceefbf8cc4b0cf6411b2ec9ae6898173b24c57790cc857" + image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.0@sha256:d5a52df856002b81cbff9c08c28d600271ccbaf202c36fc01aab7fdaec0ac7c9" certificates: commonName: "SeaweedFS CA" ipAddresses: [] From b6106305926a1a1d8b31fd50412d159e468774e3 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Thu, 18 Dec 2025 09:13:35 +0100 Subject: [PATCH 15/43] [monitoring] Add SLACK_SEVERITY_FILTER field and VMAgent for tenant monitoring (#1712) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [monitoring] Add SLACK_SEVERITY_FILTER field and VMAgent for tenant monitoring What this PR does This PR introduces the SLACK_SEVERITY_FILTER environment variable in the Alerta deployment to enable filtering of alert severities for Slack notifications based on the disabledSeverity configuration. Additionally, it adds a VMAgent resource template for scraping metrics within tenant namespaces, improving monitoring granularity and control. ```release-note [monitoring] Add SLACK_SEVERITY_FILTER for filtering Slack alert severities and VMAgent configuration for tenant-specific metrics scraping. ``` * **New Features** * Added configurable severity filtering for Telegram alerts. * Extended Slack severity filtering to accept lists of severities. * **Bug Fixes / Behavior** * Severity settings now accept arrays (multiple severities) instead of single comma-separated strings. * **Documentation** * Updated configuration docs and examples to show list-style severity settings. ✏️ Tip: You can customize this high-level summary in your review settings. --- packages/extra/monitoring/README.md | 39 ++++++++++--------- .../monitoring/templates/alerta/alerta.yaml | 8 +++- packages/extra/monitoring/values.schema.json | 17 ++++++-- packages/extra/monitoring/values.yaml | 6 ++- .../cozyrds/monitoring.yaml | 4 +- 5 files changed, 47 insertions(+), 27 deletions(-) diff --git a/packages/extra/monitoring/README.md b/packages/extra/monitoring/README.md index 3666765b..1bbd14b6 100644 --- a/packages/extra/monitoring/README.md +++ b/packages/extra/monitoring/README.md @@ -55,25 +55,26 @@ ### Alerta configuration -| Name | Description | Type | Value | -| ----------------------------------------- | ----------------------------------------------------------------- | ---------- | ------- | -| `alerta` | Configuration for the Alerta service. | `object` | `{}` | -| `alerta.storage` | Persistent volume size for the database. | `string` | `10Gi` | -| `alerta.storageClassName` | StorageClass used for the database. | `string` | `""` | -| `alerta.resources` | Resource configuration. | `object` | `{}` | -| `alerta.resources.requests` | Resource requests. | `object` | `{}` | -| `alerta.resources.requests.cpu` | CPU request. | `quantity` | `100m` | -| `alerta.resources.requests.memory` | Memory request. | `quantity` | `256Mi` | -| `alerta.resources.limits` | Resource limits. | `object` | `{}` | -| `alerta.resources.limits.cpu` | CPU limit. | `quantity` | `1` | -| `alerta.resources.limits.memory` | Memory limit. | `quantity` | `1Gi` | -| `alerta.alerts` | Alert routing configuration. | `object` | `{}` | -| `alerta.alerts.telegram` | Configuration for Telegram alerts. | `object` | `{}` | -| `alerta.alerts.telegram.token` | Telegram bot token. | `string` | `""` | -| `alerta.alerts.telegram.chatID` | Telegram chat ID(s), separated by commas. | `string` | `""` | -| `alerta.alerts.telegram.disabledSeverity` | List of severities without alerts (e.g. "informational,warning"). | `string` | `""` | -| `alerta.alerts.slack` | Configuration for Slack alerts. | `object` | `{}` | -| `alerta.alerts.slack.url` | Configuration uri for Slack alerts. | `string` | `""` | +| Name | Description | Type | Value | +| ----------------------------------------- | --------------------------------------------------------------------- | ---------- | ------- | +| `alerta` | Configuration for the Alerta service. | `object` | `{}` | +| `alerta.storage` | Persistent volume size for the database. | `string` | `10Gi` | +| `alerta.storageClassName` | StorageClass used for the database. | `string` | `""` | +| `alerta.resources` | Resource configuration. | `object` | `{}` | +| `alerta.resources.requests` | Resource requests. | `object` | `{}` | +| `alerta.resources.requests.cpu` | CPU request. | `quantity` | `100m` | +| `alerta.resources.requests.memory` | Memory request. | `quantity` | `256Mi` | +| `alerta.resources.limits` | Resource limits. | `object` | `{}` | +| `alerta.resources.limits.cpu` | CPU limit. | `quantity` | `1` | +| `alerta.resources.limits.memory` | Memory limit. | `quantity` | `1Gi` | +| `alerta.alerts` | Alert routing configuration. | `object` | `{}` | +| `alerta.alerts.telegram` | Configuration for Telegram alerts. | `object` | `{}` | +| `alerta.alerts.telegram.token` | Telegram bot token. | `string` | `""` | +| `alerta.alerts.telegram.chatID` | Telegram chat ID(s), separated by commas. | `string` | `""` | +| `alerta.alerts.telegram.disabledSeverity` | List of severities without alerts (e.g. ["informational","warning"]). | `[]string` | `[]` | +| `alerta.alerts.slack` | Configuration for Slack alerts. | `object` | `{}` | +| `alerta.alerts.slack.url` | Configuration uri for Slack alerts. | `string` | `""` | +| `alerta.alerts.slack.disabledSeverity` | List of severities without alerts (e.g. ["informational","warning"]). | `[]string` | `[]` | ### Grafana configuration diff --git a/packages/extra/monitoring/templates/alerta/alerta.yaml b/packages/extra/monitoring/templates/alerta/alerta.yaml index 71336286..72500948 100644 --- a/packages/extra/monitoring/templates/alerta/alerta.yaml +++ b/packages/extra/monitoring/templates/alerta/alerta.yaml @@ -129,13 +129,19 @@ spec: value: "{{ .Values.alerta.alerts.telegram.token }}" - name: TELEGRAM_WEBHOOK_URL value: "https://{{ printf "alerta.%s" (.Values.host | default $host) }}/api/webhooks/telegram?api-key={{ $apiKey }}" + {{- if .Values.alerta.alerts.telegram.disabledSeverity }} - name: TELEGRAM_DISABLE_NOTIFICATION_SEVERITY - value: "{{ .Values.alerta.alerts.telegram.disabledSeverity }}" + value: {{ .Values.alerta.alerts.telegram.disabledSeverity | toJson | quote }} + {{- end }} {{- end }} {{- if .Values.alerta.alerts.slack.url }} - name: "SLACK_WEBHOOK_URL" value: "{{ .Values.alerta.alerts.slack.url }}" + {{- if .Values.alerta.alerts.slack.disabledSeverity }} + - name: SLACK_SEVERITY_FILTER + value: {{ .Values.alerta.alerts.slack.disabledSeverity | toJson | quote }} + {{- end }} {{- end }} ports: diff --git a/packages/extra/monitoring/values.schema.json b/packages/extra/monitoring/values.schema.json index de81acd1..dcf8d320 100644 --- a/packages/extra/monitoring/values.schema.json +++ b/packages/extra/monitoring/values.schema.json @@ -20,6 +20,14 @@ "url" ], "properties": { + "disabledSeverity": { + "description": "List of severities without alerts (e.g. [\"informational\",\"warning\"]).", + "type": "array", + "default": [], + "items": { + "type": "string" + } + }, "url": { "description": "Configuration uri for Slack alerts.", "type": "string", @@ -42,9 +50,12 @@ "default": "" }, "disabledSeverity": { - "description": "List of severities without alerts (e.g. \"informational,warning\").", - "type": "string", - "default": "" + "description": "List of severities without alerts (e.g. [\"informational\",\"warning\"]).", + "type": "array", + "default": [], + "items": { + "type": "string" + } }, "token": { "description": "Telegram bot token.", diff --git a/packages/extra/monitoring/values.yaml b/packages/extra/monitoring/values.yaml index d687f213..6ac0fbf4 100644 --- a/packages/extra/monitoring/values.yaml +++ b/packages/extra/monitoring/values.yaml @@ -99,10 +99,11 @@ logsStorages: ## @typedef {struct} TelegramAlerts - Telegram alert configuration. ## @field {string} token - Telegram bot token. ## @field {string} chatID - Telegram chat ID(s), separated by commas. -## @field {string} [disabledSeverity] - List of severities without alerts (e.g. "informational,warning"). +## @field {[]string} [disabledSeverity] - List of severities without alerts (e.g. ["informational","warning"]). ## @typedef {struct} SlackAlerts - Slack alert configuration. ## @field {string} url - Configuration uri for Slack alerts. +## @field {[]string} [disabledSeverity] - List of severities without alerts (e.g. ["informational","warning"]). ## @typedef {struct} Alerts - Alert routing configuration. ## @field {TelegramAlerts} [telegram] - Configuration for Telegram alerts. @@ -129,9 +130,10 @@ alerta: telegram: token: "" chatID: "" - disabledSeverity: "" + disabledSeverity: [] slack: url: "" + disabledSeverity: [] ## ## @section Grafana configuration ## diff --git a/packages/system/cozystack-resource-definitions/cozyrds/monitoring.yaml b/packages/system/cozystack-resource-definitions/cozyrds/monitoring.yaml index 520e4671..774beccf 100644 --- a/packages/system/cozystack-resource-definitions/cozyrds/monitoring.yaml +++ b/packages/system/cozystack-resource-definitions/cozyrds/monitoring.yaml @@ -8,7 +8,7 @@ spec: singular: monitoring plural: monitorings openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"alerta":{"description":"Configuration for the Alerta service.","type":"object","default":{},"properties":{"alerts":{"description":"Alert routing configuration.","type":"object","default":{},"properties":{"slack":{"description":"Configuration for Slack alerts.","type":"object","default":{},"required":["url"],"properties":{"url":{"description":"Configuration uri for Slack alerts.","type":"string","default":""}}},"telegram":{"description":"Configuration for Telegram alerts.","type":"object","default":{},"required":["chatID","token"],"properties":{"chatID":{"description":"Telegram chat ID(s), separated by commas.","type":"string","default":""},"disabledSeverity":{"description":"List of severities without alerts (e.g. \"informational,warning\").","type":"string","default":""},"token":{"description":"Telegram bot token.","type":"string","default":""}}}}},"resources":{"description":"Resource configuration.","type":"object","default":{},"properties":{"limits":{"description":"Resource limits.","type":"object","default":{},"properties":{"cpu":{"description":"CPU limit.","default":1,"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":"Memory limit.","default":"1Gi","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}}},"requests":{"description":"Resource requests.","type":"object","default":{},"properties":{"cpu":{"description":"CPU request.","default":"100m","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":"Memory request.","default":"256Mi","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}}}}},"storage":{"description":"Persistent volume size for the database.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used for the database.","type":"string","default":""}}},"grafana":{"description":"Configuration for Grafana.","type":"object","default":{},"properties":{"db":{"description":"Database configuration.","type":"object","default":{},"properties":{"size":{"description":"Persistent volume size for the database.","type":"string","default":"10Gi"}}},"resources":{"description":"Resource configuration.","type":"object","default":{},"properties":{"limits":{"description":"Resource limits.","type":"object","default":{},"properties":{"cpu":{"description":"CPU limit.","default":1,"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":"Memory limit.","default":"1Gi","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}}},"requests":{"description":"Resource requests.","type":"object","default":{},"properties":{"cpu":{"description":"CPU request.","default":"100m","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":"Memory request.","default":"256Mi","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}}}}}}},"host":{"description":"The hostname used to access Grafana externally (defaults to 'grafana' subdomain for the tenant host).","type":"string","default":""},"logsStorages":{"description":"Configuration of logs storage instances.","type":"array","default":[{"name":"generic","retentionPeriod":"1","storage":"10Gi","storageClassName":"replicated"}],"items":{"type":"object","required":["name","retentionPeriod","storage","storageClassName"],"properties":{"name":{"description":"Name of the storage instance.","type":"string"},"retentionPeriod":{"description":"Retention period for logs.","type":"string","default":"1"},"storage":{"description":"Persistent volume size.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"}}}},"metricsStorages":{"description":"Configuration of metrics storage instances.","type":"array","default":[{"deduplicationInterval":"15s","name":"shortterm","retentionPeriod":"3d","storage":"10Gi","storageClassName":""},{"deduplicationInterval":"5m","name":"longterm","retentionPeriod":"14d","storage":"10Gi","storageClassName":""}],"items":{"type":"object","required":["deduplicationInterval","name","retentionPeriod","storage"],"properties":{"deduplicationInterval":{"description":"Deduplication interval for metrics.","type":"string"},"name":{"description":"Name of the storage instance.","type":"string"},"retentionPeriod":{"description":"Retention period for metrics.","type":"string"},"storage":{"description":"Persistent volume size.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used for the data.","type":"string"},"vminsert":{"description":"Configuration for vminsert.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"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":"Memory limit.","default":"1Gi","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}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","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":"Memory request.","default":"256Mi","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}}}}},"vmselect":{"description":"Configuration for vmselect.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"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":"Memory limit.","default":"1Gi","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}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","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":"Memory request.","default":"256Mi","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}}}}},"vmstorage":{"description":"Configuration for vmstorage.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"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":"Memory limit.","default":"1Gi","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}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","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":"Memory request.","default":"256Mi","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}}}}}}}}}} + {"title":"Chart Values","type":"object","properties":{"alerta":{"description":"Configuration for the Alerta service.","type":"object","default":{},"properties":{"alerts":{"description":"Alert routing configuration.","type":"object","default":{},"properties":{"slack":{"description":"Configuration for Slack alerts.","type":"object","default":{},"required":["url"],"properties":{"disabledSeverity":{"description":"List of severities without alerts (e.g. [\"informational\",\"warning\"]).","type":"array","default":[],"items":{"type":"string"}},"url":{"description":"Configuration uri for Slack alerts.","type":"string","default":""}}},"telegram":{"description":"Configuration for Telegram alerts.","type":"object","default":{},"required":["chatID","token"],"properties":{"chatID":{"description":"Telegram chat ID(s), separated by commas.","type":"string","default":""},"disabledSeverity":{"description":"List of severities without alerts (e.g. [\"informational\",\"warning\"]).","type":"array","default":[],"items":{"type":"string"}},"token":{"description":"Telegram bot token.","type":"string","default":""}}}}},"resources":{"description":"Resource configuration.","type":"object","default":{},"properties":{"limits":{"description":"Resource limits.","type":"object","default":{},"properties":{"cpu":{"description":"CPU limit.","default":1,"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":"Memory limit.","default":"1Gi","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}}},"requests":{"description":"Resource requests.","type":"object","default":{},"properties":{"cpu":{"description":"CPU request.","default":"100m","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":"Memory request.","default":"256Mi","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}}}}},"storage":{"description":"Persistent volume size for the database.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used for the database.","type":"string","default":""}}},"grafana":{"description":"Configuration for Grafana.","type":"object","default":{},"properties":{"db":{"description":"Database configuration.","type":"object","default":{},"properties":{"size":{"description":"Persistent volume size for the database.","type":"string","default":"10Gi"}}},"resources":{"description":"Resource configuration.","type":"object","default":{},"properties":{"limits":{"description":"Resource limits.","type":"object","default":{},"properties":{"cpu":{"description":"CPU limit.","default":1,"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":"Memory limit.","default":"1Gi","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}}},"requests":{"description":"Resource requests.","type":"object","default":{},"properties":{"cpu":{"description":"CPU request.","default":"100m","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":"Memory request.","default":"256Mi","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}}}}}}},"host":{"description":"The hostname used to access Grafana externally (defaults to 'grafana' subdomain for the tenant host).","type":"string","default":""},"logsStorages":{"description":"Configuration of logs storage instances.","type":"array","default":[{"name":"generic","retentionPeriod":"1","storage":"10Gi","storageClassName":"replicated"}],"items":{"type":"object","required":["name","retentionPeriod","storage","storageClassName"],"properties":{"name":{"description":"Name of the storage instance.","type":"string"},"retentionPeriod":{"description":"Retention period for logs.","type":"string","default":"1"},"storage":{"description":"Persistent volume size.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"}}}},"metricsStorages":{"description":"Configuration of metrics storage instances.","type":"array","default":[{"deduplicationInterval":"15s","name":"shortterm","retentionPeriod":"3d","storage":"10Gi","storageClassName":""},{"deduplicationInterval":"5m","name":"longterm","retentionPeriod":"14d","storage":"10Gi","storageClassName":""}],"items":{"type":"object","required":["deduplicationInterval","name","retentionPeriod","storage"],"properties":{"deduplicationInterval":{"description":"Deduplication interval for metrics.","type":"string"},"name":{"description":"Name of the storage instance.","type":"string"},"retentionPeriod":{"description":"Retention period for metrics.","type":"string"},"storage":{"description":"Persistent volume size.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used for the data.","type":"string"},"vminsert":{"description":"Configuration for vminsert.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"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":"Memory limit.","default":"1Gi","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}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","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":"Memory request.","default":"256Mi","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}}}}},"vmselect":{"description":"Configuration for vmselect.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"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":"Memory limit.","default":"1Gi","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}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","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":"Memory request.","default":"256Mi","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}}}}},"vmstorage":{"description":"Configuration for vmstorage.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"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":"Memory limit.","default":"1Gi","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}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","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":"Memory request.","default":"256Mi","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}}}}}}}}}} release: prefix: "" labels: @@ -28,7 +28,7 @@ spec: description: Monitoring and observability stack module: true icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODdfMzI2OCkiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzY4N18zMjY4KSI+CjxwYXRoIGQ9Ik04OS41MDM5IDExMS43MDdINTQuNDk3QzU0LjE3MjcgMTExLjcwNyA1NC4wMTA4IDExMS4yMjEgNTQuMzM0OSAxMTEuMDU5TDU3LjI1MjIgMTA4Ljk1MkM2MC4zMzE0IDEwNi42ODMgNjEuOTUyMiAxMDIuNjMxIDYwLjk3OTcgOTguNzQxMkg4My4wMjFDODIuMDQ4NSAxMDIuNjMxIDgzLjY2OTMgMTA2LjY4MyA4Ni43NDg1IDEwOC45NTJMODkuNjY1OCAxMTEuMDU5Qzg5Ljk5IDExMS4yMjEgODkuODI3OSAxMTEuNzA3IDg5LjUwMzkgMTExLjcwN1oiIGZpbGw9IiNCMEI2QkIiLz4KPHBhdGggZD0iTTExMy4zMjggOTguNzQxSDMwLjY3MjVDMjcuNTkzMSA5OC43NDEgMjUgOTYuMTQ4IDI1IDkzLjA2ODdWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJWOTMuMDY4N0MxMTkgOTYuMTQ4IDExNi40MDcgOTguNzQxIDExMy4zMjggOTguNzQxWiIgZmlsbD0iI0U4RURFRSIvPgo8cGF0aCBkPSJNMTE5IDg0LjE1NDlIMjVWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJMMTE5IDg0LjE1NDlaIiBmaWxsPSIjMzg0NTRGIi8+CjxwYXRoIGQ9Ik05MC42Mzc0IDExNi41NjlINTMuMzYxNkM1Mi4wNjUxIDExNi41NjkgNTAuOTMwNyAxMTUuNDM1IDUwLjkzMDcgMTE0LjEzOEM1MC45MzA3IDExMi44NDEgNTIuMDY1MSAxMTEuNzA3IDUzLjM2MTYgMTExLjcwN0g5MC42Mzc0QzkxLjkzMzkgMTExLjcwNyA5My4wNjg0IDExMi44NDEgOTMuMDY4NCAxMTQuMTM4QzkzLjA2ODQgMTE1LjQzNSA5MS45MzM5IDExNi41NjkgOTAuNjM3NCAxMTYuNTY5WiIgZmlsbD0iI0U4RURFRSIvPgo8cGF0aCBkPSJNNTQuMTcyMiAzOC43NzU3SDMzLjEwMzJDMzIuMTMwNyAzOC43NzU3IDMxLjQ4MjQgMzguMTI3NCAzMS40ODI0IDM3LjE1NDlDMzEuNDgyNCAzNi4xODI0IDMyLjEzMDcgMzUuNTM0MiAzMy4xMDMyIDM1LjUzNDJINTQuMTcyMkM1NS4xNDQ3IDM1LjUzNDIgNTUuNzkzIDM2LjE4MjQgNTUuNzkzIDM3LjE1NDlDNTUuNzkyOCAzOC4xMjc0IDU1LjE0NDUgMzguNzc1NyA1NC4xNzIyIDM4Ljc3NTdaIiBmaWxsPSIjREQzNDJFIi8+CjxwYXRoIGQ9Ik02My44OTYzIDQ1LjI1OTFINDEuMjA2N0M0MC4yMzQyIDQ1LjI1OTEgMzkuNTg1OSA0NC42MTA4IDM5LjU4NTkgNDMuNjM4M0MzOS41ODU5IDQyLjY2NTggNDAuMjM0MiA0Mi4wMTc2IDQxLjIwNjcgNDIuMDE3Nkg2My44OTYzQzY0Ljg2ODggNDIuMDE3NiA2NS41MTcxIDQyLjY2NTggNjUuNTE3MSA0My42MzgzQzY1LjUxNzEgNDQuNjEwOCA2NC44Njg4IDQ1LjI1OTEgNjMuODk2MyA0NS4yNTkxWiIgZmlsbD0iIzczODNCRiIvPgo8cGF0aCBkPSJNMzQuNzI0IDQ1LjI1OTFIMzMuMTAzMkMzMi4xMzA3IDQ1LjI1OTEgMzEuNDgyNCA0NC42MTA4IDMxLjQ4MjQgNDMuNjM4M0MzMS40ODI0IDQyLjY2NTggMzIuMTMwNyA0Mi4wMTc2IDMzLjEwMzIgNDIuMDE3NkgzNC43MjRDMzUuNjk2NCA0Mi4wMTc2IDM2LjM0NDcgNDIuNjY1OCAzNi4zNDQ3IDQzLjYzODNDMzYuMzQ0NyA0NC42MTA4IDM1LjY5NjMgNDUuMjU5MSAzNC43MjQgNDUuMjU5MVoiIGZpbGw9IiM0MkIwNUMiLz4KPHBhdGggZD0iTTYzLjg5NjMgMzguNzc1N0g2MC42NTQ5QzU5LjY4MjQgMzguNzc1NyA1OS4wMzQyIDM4LjEyNzQgNTkuMDM0MiAzNy4xNTQ5QzU5LjAzNDIgMzYuMTgyNCA1OS42ODI0IDM1LjUzNDIgNjAuNjU0OSAzNS41MzQySDYzLjg5NjNDNjQuODY4OCAzNS41MzQyIDY1LjUxNzEgMzYuMTgyNCA2NS41MTcxIDM3LjE1NDlDNjUuNTE3MSAzOC4xMjc0IDY0Ljg2ODggMzguNzc1NyA2My44OTYzIDM4Ljc3NTdaIiBmaWxsPSIjRUNCQTE2Ii8+CjxwYXRoIGQ9Ik00Ny42ODkzIDUxLjc0MTNIMzMuMTAzMkMzMi4xMzA3IDUxLjc0MTMgMzEuNDgyNCA1MS4wOTMxIDMxLjQ4MjQgNTAuMTIwNkMzMS40ODI0IDQ5LjE0ODEgMzIuMTMwNyA0OC41IDMzLjEwMzIgNDguNUg0Ny42ODkzQzQ4LjY2MTggNDguNSA0OS4zMTAxIDQ5LjE0ODMgNDkuMzEwMSA1MC4xMjA4QzQ5LjMxMDEgNTEuMDkzMyA0OC42NjE4IDUxLjc0MTMgNDcuNjg5MyA1MS43NDEzWiIgZmlsbD0iI0REMzQyRSIvPgo8cGF0aCBkPSJNNjMuODk2OCA1MS43NDEzSDU0LjE3MjVDNTMuMiA1MS43NDEzIDUyLjU1MTggNTEuMDkzMSA1Mi41NTE4IDUwLjEyMDZDNTIuNTUxOCA0OS4xNDgxIDUzLjIwMDIgNDguNSA1NC4xNzI3IDQ4LjVINjMuODk2OUM2NC44Njk0IDQ4LjUgNjUuNTE3NyA0OS4xNDgzIDY1LjUxNzcgNTAuMTIwOEM2NS41MTc3IDUxLjA5MzMgNjQuODY5MiA1MS43NDEzIDYzLjg5NjggNTEuNzQxM1oiIGZpbGw9IiNFQ0JBMTYiLz4KPHBhdGggZD0iTTU0LjE3MjIgNTguMjI0SDMzLjEwMzJDMzIuMTMwNyA1OC4yMjQgMzEuNDgyNCA1Ny41NzU3IDMxLjQ4MjQgNTYuNjAzMkMzMS40ODI0IDU1LjYzMDcgMzIuMTMwNyA1NC45ODI0IDMzLjEwMzIgNTQuOTgyNEg1NC4xNzIyQzU1LjE0NDcgNTQuOTgyNCA1NS43OTMgNTUuNjMwNyA1NS43OTMgNTYuNjAzMkM1NS43OTMgNTcuNTc1NyA1NS4xNDQ1IDU4LjIyNCA1NC4xNzIyIDU4LjIyNFoiIGZpbGw9IiM0MkIwNUMiLz4KPHBhdGggZD0iTTYzLjg5NjMgNjQuNzA3NEg0MS4yMDY3QzQwLjIzNDIgNjQuNzA3NCAzOS41ODU5IDY0LjA1OTEgMzkuNTg1OSA2My4wODY2QzM5LjU4NTkgNjIuMTE0MSA0MC4yMzQyIDYxLjQ2NTggNDEuMjA2NyA2MS40NjU4SDYzLjg5NjNDNjQuODY4OCA2MS40NjU4IDY1LjUxNzEgNjIuMTE0MSA2NS41MTcxIDYzLjA4NjZDNjUuNTE3MSA2NC4wNTkxIDY0Ljg2ODggNjQuNzA3NCA2My44OTYzIDY0LjcwNzRaIiBmaWxsPSIjRUNCQTE2Ii8+CjxwYXRoIGQ9Ik0zNC43MjQgNjQuNzA3NEgzMy4xMDMyQzMyLjEzMDcgNjQuNzA3NCAzMS40ODI0IDY0LjA1OTEgMzEuNDgyNCA2My4wODY2QzMxLjQ4MjQgNjIuMTE0MSAzMi4xMzA3IDYxLjQ2NTggMzMuMTAzMiA2MS40NjU4SDM0LjcyNEMzNS42OTY0IDYxLjQ2NTggMzYuMzQ0NyA2Mi4xMTQxIDM2LjM0NDcgNjMuMDg2NkMzNi4zNDQ3IDY0LjA1OTEgMzUuNjk2MyA2NC43MDc0IDM0LjcyNCA2NC43MDc0WiIgZmlsbD0iI0REMzQyRSIvPgo8cGF0aCBkPSJNNDcuNjg5MyA3MS4xODk4SDMzLjEwMzJDMzIuMTMwNyA3MS4xODk4IDMxLjQ4MjQgNzAuNTQxNSAzMS40ODI0IDY5LjU2OUMzMS40ODI0IDY4LjU5NjUgMzIuMTMwNyA2Ny45NDgyIDMzLjEwMzIgNjcuOTQ4Mkg0Ny42ODkzQzQ4LjY2MTggNjcuOTQ4MiA0OS4zMTAxIDY4LjU5NjUgNDkuMzEwMSA2OS41NjlDNDkuMzEwMSA3MC41NDE1IDQ4LjY2MTggNzEuMTg5OCA0Ny42ODkzIDcxLjE4OThaIiBmaWxsPSIjNDJCMDVDIi8+CjxwYXRoIGQ9Ik02My44OTY4IDcxLjE4OThINTQuMTcyNUM1My4yIDcxLjE4OTggNTIuNTUxOCA3MC41NDE1IDUyLjU1MTggNjkuNTY5QzUyLjU1MTggNjguNTk2NSA1My4yIDY3Ljk0ODIgNTQuMTcyNSA2Ny45NDgySDYzLjg5NjhDNjQuODY5MiA2Ny45NDgyIDY1LjUxNzUgNjguNTk2NSA2NS41MTc1IDY5LjU2OUM2NS41MTc1IDcwLjU0MTUgNjQuODY5MiA3MS4xODk4IDYzLjg5NjggNzEuMTg5OFoiIGZpbGw9IiM3MzgzQkYiLz4KPHBhdGggZD0iTTU0LjE3MjIgNzcuNjcyMkgzMy4xMDMyQzMyLjEzMDcgNzcuNjcyMiAzMS40ODI0IDc3LjAyMzkgMzEuNDgyNCA3Ni4wNTE0QzMxLjQ4MjQgNzUuMDc4OSAzMi4xMzA3IDc0LjQzMDcgMzMuMTAzMiA3NC40MzA3SDU0LjE3MjJDNTUuMTQ0NyA3NC40MzA3IDU1Ljc5MyA3NS4wNzg5IDU1Ljc5MyA3Ni4wNTE0QzU1Ljc5MjggNzcuMDIzOSA1NS4xNDQ1IDc3LjY3MjIgNTQuMTcyMiA3Ny42NzIyWiIgZmlsbD0iI0VDQkExNiIvPgo8cGF0aCBkPSJNNjMuODk2MyA3Ny42NzIySDYwLjY1NDlDNTkuNjgyNCA3Ny42NzIyIDU5LjAzNDIgNzcuMDIzOSA1OS4wMzQyIDc2LjA1MTRDNTkuMDM0MiA3NS4wNzg5IDU5LjY4MjQgNzQuNDMwNyA2MC42NTQ5IDc0LjQzMDdINjMuODk2M0M2NC44Njg4IDc0LjQzMDcgNjUuNTE3MSA3NS4wNzg5IDY1LjUxNzEgNzYuMDUxNEM2NS41MTcxIDc3LjAyMzkgNjQuODY4OCA3Ny42NzIyIDYzLjg5NjMgNzcuNjcyMloiIGZpbGw9IiM0MkIwNUMiLz4KPHBhdGggZD0iTTEwMS4xNzIgNzcuNjcyMkg4MC4xMDMyQzc5LjEzMDcgNzcuNjcyMiA3OC40ODI0IDc3LjAyMzkgNzguNDgyNCA3Ni4wNTE0Qzc4LjQ4MjQgNzUuMDc4OSA3OS4xMzA3IDc0LjQzMDcgODAuMTAzMiA3NC40MzA3SDEwMS4xNzJDMTAyLjE0NSA3NC40MzA3IDEwMi43OTMgNzUuMDc4OSAxMDIuNzkzIDc2LjA1MTRDMTAyLjc5MyA3Ny4wMjM5IDEwMi4xNDUgNzcuNjcyMiAxMDEuMTcyIDc3LjY3MjJaIiBmaWxsPSIjREQzNDJFIi8+CjxwYXRoIGQ9Ik0xMTAuODk2IDc3LjY3MjJIMTA3LjY1NUMxMDYuNjgyIDc3LjY3MjIgMTA2LjAzNCA3Ny4wMjM5IDEwNi4wMzQgNzYuMDUxNEMxMDYuMDM0IDc1LjA3ODkgMTA2LjY4MiA3NC40MzA3IDEwNy42NTUgNzQuNDMwN0gxMTAuODk2QzExMS44NjkgNzQuNDMwNyAxMTIuNTE3IDc1LjA3ODkgMTEyLjUxNyA3Ni4wNTE0QzExMi41MTcgNzcuMDIzOSAxMTEuODY5IDc3LjY3MjIgMTEwLjg5NiA3Ny42NzIyWiIgZmlsbD0iIzQyQjA1QyIvPgo8cGF0aCBkPSJNNjMuODk2MyA1OC4yMjRINjAuNjU0OUM1OS42ODI0IDU4LjIyNCA1OS4wMzQyIDU3LjU3NTcgNTkuMDM0MiA1Ni42MDMyQzU5LjAzNDIgNTUuNjMwNyA1OS42ODI0IDU0Ljk4MjQgNjAuNjU0OSA1NC45ODI0SDYzLjg5NjNDNjQuODY4OCA1NC45ODI0IDY1LjUxNzEgNTUuNjMwNyA2NS41MTcxIDU2LjYwMzJDNjUuNTE3MSA1Ny41NzU3IDY0Ljg2ODggNTguMjI0IDYzLjg5NjMgNTguMjI0WiIgZmlsbD0iIzczODNCRiIvPgo8cGF0aCBkPSJNMTEyLjUxNyA1MS43NDExQzExMi41MTcgNjAuNjU0OSAxMDUuMjI0IDY3Ljk0OCA5Ni4zMTA0IDY3Ljk0OEM4Ny4zOTY2IDY3Ljk0OCA4MC4xMDM1IDYwLjY1NDkgODAuMTAzNSA1MS43NDExQzgwLjEwMzUgNDIuODI3MyA4Ny4zOTY2IDM1LjUzNDIgOTYuMzEwNCAzNS41MzQyQzEwNS4yMjQgMzUuNTM0MiAxMTIuNTE3IDQyLjgyNzMgMTEyLjUxNyA1MS43NDExWiIgZmlsbD0iI0VDQkExNiIvPgo8cGF0aCBkPSJNODAuMTAzNSA1MS43NDExQzgwLjEwMzUgNTIuMjI3MyA4MC4xMDM1IDUyLjg3NTUgODAuMTAzNSA1My4zNjE5SDk2LjMxMDRWMzUuNTM0MkM4Ny4zOTY2IDM1LjUzNDIgODAuMTAzNSA0Mi44MjczIDgwLjEwMzUgNTEuNzQxMVoiIGZpbGw9IiM0MkIwNUMiLz4KPC9nPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4N18zMjY4IiB4MT0iMS4yMzIzOWUtMDYiIHkxPSItOS41MDAwMSIgeDI9IjE2OCIgeTI9IjE2MiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjOEZEREZGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzAwNzVGRiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzY4N18zMjY4Ij4KPHJlY3Qgd2lkdGg9Ijk0IiBoZWlnaHQ9Ijk0IiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjUgMjUpIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg== - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "host"], ["spec", "metricsStorages"], ["spec", "logsStorages"], ["spec", "alerta"], ["spec", "alerta", "storage"], ["spec", "alerta", "storageClassName"], ["spec", "alerta", "resources"], ["spec", "alerta", "resources", "limits"], ["spec", "alerta", "resources", "limits", "cpu"], ["spec", "alerta", "resources", "limits", "memory"], ["spec", "alerta", "resources", "requests"], ["spec", "alerta", "resources", "requests", "cpu"], ["spec", "alerta", "resources", "requests", "memory"], ["spec", "alerta", "alerts"], ["spec", "alerta", "alerts", "telegram"], ["spec", "alerta", "alerts", "telegram", "token"], ["spec", "alerta", "alerts", "telegram", "chatID"], ["spec", "alerta", "alerts", "telegram", "disabledSeverity"], ["spec", "alerta", "alerts", "slack"], ["spec", "alerta", "alerts", "slack", "url"], ["spec", "grafana"], ["spec", "grafana", "db"], ["spec", "grafana", "db", "size"], ["spec", "grafana", "resources"], ["spec", "grafana", "resources", "limits"], ["spec", "grafana", "resources", "limits", "cpu"], ["spec", "grafana", "resources", "limits", "memory"], ["spec", "grafana", "resources", "requests"], ["spec", "grafana", "resources", "requests", "cpu"], ["spec", "grafana", "resources", "requests", "memory"]] + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "host"], ["spec", "metricsStorages"], ["spec", "logsStorages"], ["spec", "alerta"], ["spec", "alerta", "storage"], ["spec", "alerta", "storageClassName"], ["spec", "alerta", "resources"], ["spec", "alerta", "resources", "limits"], ["spec", "alerta", "resources", "limits", "cpu"], ["spec", "alerta", "resources", "limits", "memory"], ["spec", "alerta", "resources", "requests"], ["spec", "alerta", "resources", "requests", "cpu"], ["spec", "alerta", "resources", "requests", "memory"], ["spec", "alerta", "alerts"], ["spec", "alerta", "alerts", "telegram"], ["spec", "alerta", "alerts", "telegram", "token"], ["spec", "alerta", "alerts", "telegram", "chatID"], ["spec", "alerta", "alerts", "telegram", "disabledSeverity"], ["spec", "alerta", "alerts", "slack"], ["spec", "alerta", "alerts", "slack", "url"], ["spec", "alerta", "alerts", "slack", "disabledSeverity"], ["spec", "grafana"], ["spec", "grafana", "db"], ["spec", "grafana", "db", "size"], ["spec", "grafana", "resources"], ["spec", "grafana", "resources", "limits"], ["spec", "grafana", "resources", "limits", "cpu"], ["spec", "grafana", "resources", "limits", "memory"], ["spec", "grafana", "resources", "requests"], ["spec", "grafana", "resources", "requests", "cpu"], ["spec", "grafana", "resources", "requests", "memory"]] secrets: exclude: [] include: From 0e262838d2be9a35f98e05067b9dcc71f9614071 Mon Sep 17 00:00:00 2001 From: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com> Date: Tue, 23 Dec 2025 23:26:06 +0000 Subject: [PATCH 16/43] Prepare release v0.39.1 Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com> --- packages/apps/http-cache/images/nginx-cache.tag | 2 +- packages/core/installer/values.yaml | 2 +- packages/core/testing/values.yaml | 2 +- packages/extra/bootbox/images/matchbox.tag | 2 +- packages/extra/seaweedfs/images/objectstorage-sidecar.tag | 2 +- packages/system/bucket/images/s3manager.tag | 2 +- packages/system/cozystack-api/values.yaml | 2 +- packages/system/cozystack-controller/values.yaml | 4 ++-- packages/system/dashboard/templates/configmap.yaml | 2 +- packages/system/dashboard/values.yaml | 6 +++--- packages/system/kamaji/values.yaml | 4 ++-- packages/system/kubeovn-plunger/values.yaml | 2 +- packages/system/kubeovn-webhook/values.yaml | 2 +- packages/system/kubeovn/values.yaml | 2 +- packages/system/lineage-controller-webhook/values.yaml | 2 +- packages/system/objectstorage-controller/values.yaml | 2 +- packages/system/seaweedfs/values.yaml | 2 +- 17 files changed, 21 insertions(+), 21 deletions(-) diff --git a/packages/apps/http-cache/images/nginx-cache.tag b/packages/apps/http-cache/images/nginx-cache.tag index 185dcc66..a5e4ca7b 100644 --- a/packages/apps/http-cache/images/nginx-cache.tag +++ b/packages/apps/http-cache/images/nginx-cache.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/nginx-cache:0.0.0@sha256:e0a07082bb6fc6aeaae2315f335386f1705a646c72f9e0af512aebbca5cb2b15 +ghcr.io/cozystack/cozystack/nginx-cache:0.0.0@sha256:b7633717cd7449c0042ae92d8ca9b36e4d69566561f5c7d44e21058e7d05c6d5 diff --git a/packages/core/installer/values.yaml b/packages/core/installer/values.yaml index 6f053bbd..eaf0ace4 100644 --- a/packages/core/installer/values.yaml +++ b/packages/core/installer/values.yaml @@ -1,2 +1,2 @@ cozystack: - image: ghcr.io/cozystack/cozystack/installer:v0.39.0@sha256:8fb2f4f9ab482a00b6200f56bed69fad68a117bb65b341d3beca4bed5bd7b80f + image: ghcr.io/cozystack/cozystack/installer:v0.39.1@sha256:165b5d5d5fdf48aca552db070bf145fbf328e9e523a8d8cbb1b68112fdbd5d5d diff --git a/packages/core/testing/values.yaml b/packages/core/testing/values.yaml index 7bf63e3a..d896d2aa 100755 --- a/packages/core/testing/values.yaml +++ b/packages/core/testing/values.yaml @@ -1,2 +1,2 @@ e2e: - image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.39.0@sha256:c113cb262e8e8fd87c013a347c16def906e3a3dd179519f2ad6a5c054a44f271 + image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.39.1@sha256:22fdbc676c17b679e4ea39fd88741fa35c449250f89ef3c75333c1849008eca7 diff --git a/packages/extra/bootbox/images/matchbox.tag b/packages/extra/bootbox/images/matchbox.tag index 20f412c7..404abc9d 100644 --- a/packages/extra/bootbox/images/matchbox.tag +++ b/packages/extra/bootbox/images/matchbox.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/matchbox:v0.39.0@sha256:ec0d9e2a74e313c76a93f6a0522e31731f33cfc6575d14d93ddfe24f2fe53eec +ghcr.io/cozystack/cozystack/matchbox:v0.39.1@sha256:f3a8a55e5048a08b41a0efd4a36980b2ea508373acf1e5caca7849276cc4f2a6 diff --git a/packages/extra/seaweedfs/images/objectstorage-sidecar.tag b/packages/extra/seaweedfs/images/objectstorage-sidecar.tag index 0a20a5d9..1674f9e6 100644 --- a/packages/extra/seaweedfs/images/objectstorage-sidecar.tag +++ b/packages/extra/seaweedfs/images/objectstorage-sidecar.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.0@sha256:d5a52df856002b81cbff9c08c28d600271ccbaf202c36fc01aab7fdaec0ac7c9 +ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.1@sha256:df9e205a0d063a30da6cff595d9d1951a76d35bf8cad9d21ac66aacef47a1f65 diff --git a/packages/system/bucket/images/s3manager.tag b/packages/system/bucket/images/s3manager.tag index 3ba8a1db..aaa70840 100644 --- a/packages/system/bucket/images/s3manager.tag +++ b/packages/system/bucket/images/s3manager.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/s3manager:v0.5.0@sha256:eb363ee78465884ac314a3e5357ff30b0274dbee6ca2b94935b2ee2193870e0f +ghcr.io/cozystack/cozystack/s3manager:v0.5.0@sha256:75760dcae5fc01743328b1f8456fa451f6be2cc2b3f639ee84897a0ee99cdd14 diff --git a/packages/system/cozystack-api/values.yaml b/packages/system/cozystack-api/values.yaml index 65587d04..97ca88c5 100644 --- a/packages/system/cozystack-api/values.yaml +++ b/packages/system/cozystack-api/values.yaml @@ -1,5 +1,5 @@ cozystackAPI: - image: ghcr.io/cozystack/cozystack/cozystack-api:v0.39.0@sha256:d9669a49fd22b3f1ed56aa21857f99c63e88426488530092f606ad275f6ce650 + image: ghcr.io/cozystack/cozystack/cozystack-api:v0.39.1@sha256:fa6bd65b041e75bb2f11f0e564dc78060ab12091188e0d7e03161fec68e03014 localK8sAPIEndpoint: enabled: true replicas: 2 diff --git a/packages/system/cozystack-controller/values.yaml b/packages/system/cozystack-controller/values.yaml index b8ba4408..342c0889 100644 --- a/packages/system/cozystack-controller/values.yaml +++ b/packages/system/cozystack-controller/values.yaml @@ -1,6 +1,6 @@ cozystackController: - image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.39.0@sha256:af229b1d63705af9eb8bbf6867b4e94412516cd41ecfbc73f7fb19ac705e739a + image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.39.1@sha256:5258fd467f62aa04120a163642694f32aa2e4fc8752980f8b1c50509e301f23d debug: false disableTelemetry: false - cozystackVersion: "v0.39.0" + cozystackVersion: "v0.39.1" cozystackAPIKind: "DaemonSet" diff --git a/packages/system/dashboard/templates/configmap.yaml b/packages/system/dashboard/templates/configmap.yaml index e2baa680..7fb1a3cf 100644 --- a/packages/system/dashboard/templates/configmap.yaml +++ b/packages/system/dashboard/templates/configmap.yaml @@ -1,6 +1,6 @@ {{- $brandingConfig:= lookup "v1" "ConfigMap" "cozy-system" "cozystack-branding" }} -{{- $tenantText := "v0.39.0" }} +{{- $tenantText := "v0.39.1" }} {{- $footerText := "Cozystack" }} {{- $titleText := "Cozystack Dashboard" }} {{- $logoText := "" }} diff --git a/packages/system/dashboard/values.yaml b/packages/system/dashboard/values.yaml index 5ce5fdd5..164d8bb9 100644 --- a/packages/system/dashboard/values.yaml +++ b/packages/system/dashboard/values.yaml @@ -1,6 +1,6 @@ openapiUI: - image: ghcr.io/cozystack/cozystack/openapi-ui:v0.39.0@sha256:ea8b99160f7ab94de418bb445651769b8546b0659ae1f598670d4c581d370f88 + image: ghcr.io/cozystack/cozystack/openapi-ui:v0.39.1@sha256:97aeeabcd8e50a4dfc30e0b849d2dc0361e322e1f2fa716da5daf44e470d20b9 openapiUIK8sBff: - image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.39.0@sha256:0a5168e29ba667cc3532ebc6814c7f9c9f1102874a9d8b0c038e9fa2eefb6efd + image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.39.1@sha256:0a5168e29ba667cc3532ebc6814c7f9c9f1102874a9d8b0c038e9fa2eefb6efd tokenProxy: - image: ghcr.io/cozystack/cozystack/token-proxy:v0.39.0@sha256:fad27112617bb17816702571e1f39d0ac3fe5283468d25eb12f79906cdab566b + image: ghcr.io/cozystack/cozystack/token-proxy:v0.39.1@sha256:fad27112617bb17816702571e1f39d0ac3fe5283468d25eb12f79906cdab566b diff --git a/packages/system/kamaji/values.yaml b/packages/system/kamaji/values.yaml index b8d00f00..33f2c420 100644 --- a/packages/system/kamaji/values.yaml +++ b/packages/system/kamaji/values.yaml @@ -3,7 +3,7 @@ kamaji: deploy: false image: pullPolicy: IfNotPresent - tag: v0.39.0@sha256:a8981fc592628855693aeeebc3a1f51058a8e667fa2405416b6ed1b1cbe86c09 + tag: v0.39.1@sha256:ab66ab206da1b8b2fe1aa623a4accd8c91d2c5560aa857f949ee9183d79087ad repository: ghcr.io/cozystack/cozystack/kamaji resources: limits: @@ -13,4 +13,4 @@ kamaji: cpu: 100m memory: 100Mi extraArgs: - - --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.39.0@sha256:a8981fc592628855693aeeebc3a1f51058a8e667fa2405416b6ed1b1cbe86c09 + - --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.39.1@sha256:ab66ab206da1b8b2fe1aa623a4accd8c91d2c5560aa857f949ee9183d79087ad diff --git a/packages/system/kubeovn-plunger/values.yaml b/packages/system/kubeovn-plunger/values.yaml index 3478e16c..875932dd 100644 --- a/packages/system/kubeovn-plunger/values.yaml +++ b/packages/system/kubeovn-plunger/values.yaml @@ -1,4 +1,4 @@ portSecurity: true routes: "" -image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.39.0@sha256:ce250d9ac04dc251f105f385d204f58ec3c27ced6e1023e52e7e8121b3c99fd5 +image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.39.1@sha256:135ceb7289bc0522680fe9002f76ff2dc5feec03cdbc6b3008109aba9093e069 ovnCentralName: ovn-central diff --git a/packages/system/kubeovn-webhook/values.yaml b/packages/system/kubeovn-webhook/values.yaml index 7c3cbf0a..15eb396b 100644 --- a/packages/system/kubeovn-webhook/values.yaml +++ b/packages/system/kubeovn-webhook/values.yaml @@ -1,3 +1,3 @@ portSecurity: true routes: "" -image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.39.0@sha256:7bfd458299a507f2cf82cddb65941ded6991fd4ba92fd46010cbc8c363126085 +image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.39.1@sha256:fc777726120350e5bdf4b864f49826b89983eb07a63c768d4907ce1330b35049 diff --git a/packages/system/kubeovn/values.yaml b/packages/system/kubeovn/values.yaml index 2b7f4f62..3f3841c2 100644 --- a/packages/system/kubeovn/values.yaml +++ b/packages/system/kubeovn/values.yaml @@ -65,4 +65,4 @@ global: images: kubeovn: repository: kubeovn - tag: v1.14.11@sha256:d413fa033b6e2971866f2b27d25d5482f923099afe4b58ceedcfd031b22e410d + tag: v1.14.11@sha256:3ff2a91ed1f9ca7b3cb6281c7685dbb6bdc2108cb0d9ae3bfe74e8126125190a diff --git a/packages/system/lineage-controller-webhook/values.yaml b/packages/system/lineage-controller-webhook/values.yaml index ee39e044..d954b181 100644 --- a/packages/system/lineage-controller-webhook/values.yaml +++ b/packages/system/lineage-controller-webhook/values.yaml @@ -1,5 +1,5 @@ lineageControllerWebhook: - image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.39.0@sha256:cb264b193256dd5db79ba50ad44fc2301fb19ac34155f6f6638d6cadfd45e370 + image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.39.1@sha256:58e20b3a403a319b1de3e27a3dea103421517052134dfaa3c13a5d41c5a0458d debug: false localK8sAPIEndpoint: enabled: true diff --git a/packages/system/objectstorage-controller/values.yaml b/packages/system/objectstorage-controller/values.yaml index e7d1e757..7b45a2b0 100644 --- a/packages/system/objectstorage-controller/values.yaml +++ b/packages/system/objectstorage-controller/values.yaml @@ -1,3 +1,3 @@ objectstorage: controller: - image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.39.0@sha256:91ed0ba4de7958708f77427d2c752dece969236c13927c17033d792700e9c6f4" + image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.39.1@sha256:91ed0ba4de7958708f77427d2c752dece969236c13927c17033d792700e9c6f4" diff --git a/packages/system/seaweedfs/values.yaml b/packages/system/seaweedfs/values.yaml index 6d8d396d..5d85ed54 100644 --- a/packages/system/seaweedfs/values.yaml +++ b/packages/system/seaweedfs/values.yaml @@ -124,7 +124,7 @@ seaweedfs: bucketClassName: "seaweedfs" region: "" sidecar: - image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.0@sha256:d5a52df856002b81cbff9c08c28d600271ccbaf202c36fc01aab7fdaec0ac7c9" + image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.1@sha256:df9e205a0d063a30da6cff595d9d1951a76d35bf8cad9d21ac66aacef47a1f65" certificates: commonName: "SeaweedFS CA" ipAddresses: [] From 1ffa1ef45466f024222d3436f74f95e2b05d491b Mon Sep 17 00:00:00 2001 From: Timofei Larkin Date: Fri, 19 Dec 2025 14:37:46 +0300 Subject: [PATCH 17/43] [vm] Always expose VMs with a service ## What this PR does When VMs are created without a public IP, no service is created for them and they have no in-cluster DNS name. This PR fixes this and resolves #1731. ### Release note ```release-note [vm] Always expose VMs with at least a ClusterIP service. ``` Signed-off-by: Timofei Larkin (cherry picked from commit ba50d01877736a28c62310d117d93c2f62047fad) --- packages/apps/virtual-machine/templates/service.yaml | 10 +++++++++- packages/apps/vm-instance/templates/service.yaml | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/apps/virtual-machine/templates/service.yaml b/packages/apps/virtual-machine/templates/service.yaml index f212db62..b12f7612 100644 --- a/packages/apps/virtual-machine/templates/service.yaml +++ b/packages/apps/virtual-machine/templates/service.yaml @@ -1,4 +1,3 @@ -{{- if .Values.external }} --- apiVersion: v1 kind: Service @@ -7,17 +6,24 @@ metadata: labels: apps.cozystack.io/user-service: "true" {{- include "virtual-machine.labels" . | nindent 4 }} +{{- if .Values.external }} annotations: networking.cozystack.io/wholeIP: "true" +{{- end }} spec: type: {{ ternary "LoadBalancer" "ClusterIP" .Values.external }} +{{- if .Values.external }} externalTrafficPolicy: Local {{- if ((include "cozy-lib.network.disableLoadBalancerNodePorts" $) | fromYaml) }} allocateLoadBalancerNodePorts: false {{- end }} +{{- else }} + clusterIP: None +{{- end }} selector: {{- include "virtual-machine.selectorLabels" . | nindent 4 }} ports: +{{- if .Values.external }} {{- if and (eq .Values.externalMethod "WholeIP") (not .Values.externalPorts) }} - port: 65535 {{- else }} @@ -27,4 +33,6 @@ spec: targetPort: {{ . }} {{- end }} {{- end }} +{{- else }} + - port: 65535 {{- end }} diff --git a/packages/apps/vm-instance/templates/service.yaml b/packages/apps/vm-instance/templates/service.yaml index f212db62..b12f7612 100644 --- a/packages/apps/vm-instance/templates/service.yaml +++ b/packages/apps/vm-instance/templates/service.yaml @@ -1,4 +1,3 @@ -{{- if .Values.external }} --- apiVersion: v1 kind: Service @@ -7,17 +6,24 @@ metadata: labels: apps.cozystack.io/user-service: "true" {{- include "virtual-machine.labels" . | nindent 4 }} +{{- if .Values.external }} annotations: networking.cozystack.io/wholeIP: "true" +{{- end }} spec: type: {{ ternary "LoadBalancer" "ClusterIP" .Values.external }} +{{- if .Values.external }} externalTrafficPolicy: Local {{- if ((include "cozy-lib.network.disableLoadBalancerNodePorts" $) | fromYaml) }} allocateLoadBalancerNodePorts: false {{- end }} +{{- else }} + clusterIP: None +{{- end }} selector: {{- include "virtual-machine.selectorLabels" . | nindent 4 }} ports: +{{- if .Values.external }} {{- if and (eq .Values.externalMethod "WholeIP") (not .Values.externalPorts) }} - port: 65535 {{- else }} @@ -27,4 +33,6 @@ spec: targetPort: {{ . }} {{- end }} {{- end }} +{{- else }} + - port: 65535 {{- end }} From 13bfb72ea5551d52d28cfd77a52f7f0901591fb8 Mon Sep 17 00:00:00 2001 From: Aleksei Sviridkin Date: Mon, 29 Dec 2025 16:06:08 +0300 Subject: [PATCH 18/43] [kubevirt-operator] Fix typo in VMNotRunningFor10Minutes alert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix case sensitivity in status check: "running" → "Running". The metric uses "Running" (capital R), so the lowercase check was always triggering alerts even for running VMs. Fixes: https://github.com/cozystack/cozystack/issues/1552 Co-Authored-By: Claude Signed-off-by: Aleksei Sviridkin (cherry picked from commit 7fab919e077275db1a52f6af8f16fc28f7e56de1) --- packages/system/kubevirt-operator/alerts/PrometheusRule.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/system/kubevirt-operator/alerts/PrometheusRule.yaml b/packages/system/kubevirt-operator/alerts/PrometheusRule.yaml index 73ef3ce4..c4d73cc5 100644 --- a/packages/system/kubevirt-operator/alerts/PrometheusRule.yaml +++ b/packages/system/kubevirt-operator/alerts/PrometheusRule.yaml @@ -10,7 +10,7 @@ spec: expr: | max_over_time( kubevirt_vm_info{ - status!="running", + status!="Running", exported_namespace=~".+", name=~".+" }[10m] From d90a76bc25b5828d67a429f142122467144b0ed3 Mon Sep 17 00:00:00 2001 From: Aleksei Sviridkin Date: Fri, 26 Dec 2025 17:44:23 +0300 Subject: [PATCH 19/43] fix(tenant): allow egress to parent ingress pods Nested Kubernetes clusters with exposeMethod: Proxied cannot reach their own external domains because the clusterwide egress policy blocks traffic to ingress pods in parent namespaces. This breaks cert-manager HTTP-01 self-check and any scenario where pods need to access services exposed through parent ingress. Add egress rule allowing traffic to ingress pods (cozystack.io/service: ingress) in parent namespaces, following the same pattern as existing vminsert and etcd rules. Co-Authored-By: Claude Signed-off-by: Aleksei Sviridkin (cherry picked from commit 4dfdbfeb62c76facbb4a9f94e24e129f35f854db) --- packages/apps/tenant/templates/networkpolicy.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/apps/tenant/templates/networkpolicy.yaml b/packages/apps/tenant/templates/networkpolicy.yaml index b66e85ff..2c15a877 100644 --- a/packages/apps/tenant/templates/networkpolicy.yaml +++ b/packages/apps/tenant/templates/networkpolicy.yaml @@ -67,6 +67,19 @@ spec: {{- end }} {{- end }} {{- end }} + {{- if ne (include "tenant.name" .) "tenant-root" }} + - toEndpoints: + {{- if hasPrefix "tenant-" .Release.Namespace }} + {{- $parts := splitList "-" .Release.Namespace }} + {{- range $i, $v := $parts }} + {{- if ne $i 0 }} + - matchLabels: + cozystack.io/service: ingress + "k8s:io.kubernetes.pod.namespace": {{ join "-" (slice $parts 0 (add $i 1)) }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} --- apiVersion: cilium.io/v2 kind: CiliumClusterwideNetworkPolicy From 7c766fc27dafea3bcbde4de1493cac263ca610a7 Mon Sep 17 00:00:00 2001 From: Timofei Larkin Date: Tue, 30 Dec 2025 11:38:49 +0300 Subject: [PATCH 20/43] [tenant] Run cleanup job from system namespace ## What this PR does The Helm hook that creates a job deleting all applications in a tenant before deleting the tenant itself now runs this job from the cozy-system namespace. This prevents conflicts with resource quotas (not enough resources to run cleanup job) without temporary increases of the quota or similar vulnerability-introducing hacks. ### Release note ```release-note [tenant] Run cleanup job in system namespace to avoid conflicts on resource quotas. ``` Signed-off-by: Timofei Larkin (cherry picked from commit b94fc6c9c84cc73e5f53341a24bbdfe0f2fb0f62) --- packages/apps/tenant/templates/cleanup-job.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/apps/tenant/templates/cleanup-job.yaml b/packages/apps/tenant/templates/cleanup-job.yaml index 9a1bcdd5..9b2f2c50 100644 --- a/packages/apps/tenant/templates/cleanup-job.yaml +++ b/packages/apps/tenant/templates/cleanup-job.yaml @@ -3,7 +3,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: {{ include "tenant.name" . }}-cleanup - namespace: {{ include "tenant.name" . }} + namespace: cozy-system annotations: helm.sh/hook: pre-delete helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded @@ -39,13 +39,13 @@ roleRef: subjects: - kind: ServiceAccount name: {{ include "tenant.name" . }}-cleanup - namespace: {{ include "tenant.name" . }} + namespace: cozy-system --- apiVersion: batch/v1 kind: Job metadata: name: {{ include "tenant.name" . }}-cleanup - namespace: {{ include "tenant.name" . }} + namespace: cozy-system annotations: helm.sh/hook: pre-delete helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded From fc84b80b704e67507293d3387a75b49b3cf636d2 Mon Sep 17 00:00:00 2001 From: Matthieu ROBIN Date: Fri, 2 Jan 2026 15:53:54 +0100 Subject: [PATCH 21/43] Add resource requests and limits to etcd-defrag Added resource requests and limits for etcd-defrag container. Signed-off-by: Matthieu ROBIN (cherry picked from commit 675eaa6178df66161a68a487a1596cbf7eef91fc) --- packages/extra/etcd/templates/etcd-defrag.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/extra/etcd/templates/etcd-defrag.yaml b/packages/extra/etcd/templates/etcd-defrag.yaml index 21a8e514..089df920 100644 --- a/packages/extra/etcd/templates/etcd-defrag.yaml +++ b/packages/extra/etcd/templates/etcd-defrag.yaml @@ -12,6 +12,13 @@ spec: containers: - name: etcd-defrag image: ghcr.io/ahrtr/etcd-defrag:v0.13.0 + resources: + requests: + cpu: 200m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi args: - --endpoints={{ range $i, $e := until (int .Values.replicas) }}{{ if $i }},{{ end }}https://{{ $.Release.Name }}-{{ $i }}.{{ $.Release.Name }}-headless.{{ $.Release.Namespace }}.svc:2379{{ end }} - --cacert=/etc/etcd/pki/client/cert/ca.crt From f4ff44a18cecfac008d5515f1d8afe487af2bba4 Mon Sep 17 00:00:00 2001 From: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com> Date: Sat, 3 Jan 2026 01:38:23 +0000 Subject: [PATCH 22/43] Prepare release v0.39.2 Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com> --- packages/apps/kubernetes/images/kubevirt-csi-driver.tag | 2 +- packages/core/installer/values.yaml | 2 +- packages/core/testing/values.yaml | 2 +- packages/extra/bootbox/images/matchbox.tag | 2 +- packages/extra/seaweedfs/images/objectstorage-sidecar.tag | 2 +- packages/system/bucket/images/s3manager.tag | 2 +- packages/system/cozystack-api/values.yaml | 2 +- packages/system/cozystack-controller/values.yaml | 4 ++-- packages/system/dashboard/templates/configmap.yaml | 2 +- packages/system/dashboard/values.yaml | 6 +++--- packages/system/kamaji/values.yaml | 4 ++-- packages/system/kubeovn-plunger/values.yaml | 2 +- packages/system/kubeovn-webhook/values.yaml | 2 +- packages/system/kubeovn/values.yaml | 2 +- packages/system/kubevirt-csi-node/values.yaml | 2 +- packages/system/lineage-controller-webhook/values.yaml | 2 +- packages/system/objectstorage-controller/values.yaml | 2 +- packages/system/seaweedfs/values.yaml | 2 +- 18 files changed, 22 insertions(+), 22 deletions(-) diff --git a/packages/apps/kubernetes/images/kubevirt-csi-driver.tag b/packages/apps/kubernetes/images/kubevirt-csi-driver.tag index 550279b8..0e97fa7a 100644 --- a/packages/apps/kubernetes/images/kubevirt-csi-driver.tag +++ b/packages/apps/kubernetes/images/kubevirt-csi-driver.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:64c0b248e0d6b0a1578f59cab725152f3223a6d53ac0371eccaf023c0cd75904 +ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:ae0c5e3e005388d865617097a9fe4b4e8a2be6b62cec893e08f2143d0acde241 diff --git a/packages/core/installer/values.yaml b/packages/core/installer/values.yaml index eaf0ace4..9de2bcff 100644 --- a/packages/core/installer/values.yaml +++ b/packages/core/installer/values.yaml @@ -1,2 +1,2 @@ cozystack: - image: ghcr.io/cozystack/cozystack/installer:v0.39.1@sha256:165b5d5d5fdf48aca552db070bf145fbf328e9e523a8d8cbb1b68112fdbd5d5d + image: ghcr.io/cozystack/cozystack/installer:v0.39.2@sha256:1c0eef43e1a06f5bf653c0bb7a2821a623fcad71c41c2c15b080fe0f6c809e39 diff --git a/packages/core/testing/values.yaml b/packages/core/testing/values.yaml index d896d2aa..e6bd42c8 100755 --- a/packages/core/testing/values.yaml +++ b/packages/core/testing/values.yaml @@ -1,2 +1,2 @@ e2e: - image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.39.1@sha256:22fdbc676c17b679e4ea39fd88741fa35c449250f89ef3c75333c1849008eca7 + image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.39.2@sha256:9fe32b5faf233bdbae27859f1c6aaa229230b0ac9ee5212a1ddf2763182cea0f diff --git a/packages/extra/bootbox/images/matchbox.tag b/packages/extra/bootbox/images/matchbox.tag index 404abc9d..9a13bbb8 100644 --- a/packages/extra/bootbox/images/matchbox.tag +++ b/packages/extra/bootbox/images/matchbox.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/matchbox:v0.39.1@sha256:f3a8a55e5048a08b41a0efd4a36980b2ea508373acf1e5caca7849276cc4f2a6 +ghcr.io/cozystack/cozystack/matchbox:v0.39.2@sha256:80da0287d6705ffaec918d1d7dc02f1d0a512045c56b78afb2707743d09e629e diff --git a/packages/extra/seaweedfs/images/objectstorage-sidecar.tag b/packages/extra/seaweedfs/images/objectstorage-sidecar.tag index 1674f9e6..1f75983e 100644 --- a/packages/extra/seaweedfs/images/objectstorage-sidecar.tag +++ b/packages/extra/seaweedfs/images/objectstorage-sidecar.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.1@sha256:df9e205a0d063a30da6cff595d9d1951a76d35bf8cad9d21ac66aacef47a1f65 +ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.2@sha256:b180a6c4ce4d46cdf31af2731cc8b477e80ade99d4296d507ec5edb38c56a1ea diff --git a/packages/system/bucket/images/s3manager.tag b/packages/system/bucket/images/s3manager.tag index aaa70840..641bb877 100644 --- a/packages/system/bucket/images/s3manager.tag +++ b/packages/system/bucket/images/s3manager.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/s3manager:v0.5.0@sha256:75760dcae5fc01743328b1f8456fa451f6be2cc2b3f639ee84897a0ee99cdd14 +ghcr.io/cozystack/cozystack/s3manager:v0.5.0@sha256:7dde8d748442c4457fb7bf67c0e0f4abf0da60af00a9171c6d4c0bfcc8a8b9c5 diff --git a/packages/system/cozystack-api/values.yaml b/packages/system/cozystack-api/values.yaml index 97ca88c5..e61ab611 100644 --- a/packages/system/cozystack-api/values.yaml +++ b/packages/system/cozystack-api/values.yaml @@ -1,5 +1,5 @@ cozystackAPI: - image: ghcr.io/cozystack/cozystack/cozystack-api:v0.39.1@sha256:fa6bd65b041e75bb2f11f0e564dc78060ab12091188e0d7e03161fec68e03014 + image: ghcr.io/cozystack/cozystack/cozystack-api:v0.39.2@sha256:e859dc81b4905fa163b75b1d567e91bd1eac572f85931954c2dc646cb07d3959 localK8sAPIEndpoint: enabled: true replicas: 2 diff --git a/packages/system/cozystack-controller/values.yaml b/packages/system/cozystack-controller/values.yaml index 342c0889..41cda67a 100644 --- a/packages/system/cozystack-controller/values.yaml +++ b/packages/system/cozystack-controller/values.yaml @@ -1,6 +1,6 @@ cozystackController: - image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.39.1@sha256:5258fd467f62aa04120a163642694f32aa2e4fc8752980f8b1c50509e301f23d + image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.39.2@sha256:b96283a1774f23735849802069a907cb85f4fd57df89f8740a954a7d2922afc3 debug: false disableTelemetry: false - cozystackVersion: "v0.39.1" + cozystackVersion: "v0.39.2" cozystackAPIKind: "DaemonSet" diff --git a/packages/system/dashboard/templates/configmap.yaml b/packages/system/dashboard/templates/configmap.yaml index 7fb1a3cf..c74d63bf 100644 --- a/packages/system/dashboard/templates/configmap.yaml +++ b/packages/system/dashboard/templates/configmap.yaml @@ -1,6 +1,6 @@ {{- $brandingConfig:= lookup "v1" "ConfigMap" "cozy-system" "cozystack-branding" }} -{{- $tenantText := "v0.39.1" }} +{{- $tenantText := "v0.39.2" }} {{- $footerText := "Cozystack" }} {{- $titleText := "Cozystack Dashboard" }} {{- $logoText := "" }} diff --git a/packages/system/dashboard/values.yaml b/packages/system/dashboard/values.yaml index 164d8bb9..237dfb45 100644 --- a/packages/system/dashboard/values.yaml +++ b/packages/system/dashboard/values.yaml @@ -1,6 +1,6 @@ openapiUI: - image: ghcr.io/cozystack/cozystack/openapi-ui:v0.39.1@sha256:97aeeabcd8e50a4dfc30e0b849d2dc0361e322e1f2fa716da5daf44e470d20b9 + image: ghcr.io/cozystack/cozystack/openapi-ui:v0.39.2@sha256:fddab274cd6e0c590aed0a49faba584c2b34fe875c7deaab9c96678c4e33cd3d openapiUIK8sBff: - image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.39.1@sha256:0a5168e29ba667cc3532ebc6814c7f9c9f1102874a9d8b0c038e9fa2eefb6efd + image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.39.2@sha256:70b68d8666220b0b56dbdbda0297d85cf53c5c4fa225a24a8f36afad1ac65a70 tokenProxy: - image: ghcr.io/cozystack/cozystack/token-proxy:v0.39.1@sha256:fad27112617bb17816702571e1f39d0ac3fe5283468d25eb12f79906cdab566b + image: ghcr.io/cozystack/cozystack/token-proxy:v0.39.2@sha256:fad27112617bb17816702571e1f39d0ac3fe5283468d25eb12f79906cdab566b diff --git a/packages/system/kamaji/values.yaml b/packages/system/kamaji/values.yaml index 33f2c420..1b010243 100644 --- a/packages/system/kamaji/values.yaml +++ b/packages/system/kamaji/values.yaml @@ -3,7 +3,7 @@ kamaji: deploy: false image: pullPolicy: IfNotPresent - tag: v0.39.1@sha256:ab66ab206da1b8b2fe1aa623a4accd8c91d2c5560aa857f949ee9183d79087ad + tag: v0.39.2@sha256:dbf879e70fc4a98070980be8d086fb79dc6a5b3ae4c1a1cc7578df5c39d8bd36 repository: ghcr.io/cozystack/cozystack/kamaji resources: limits: @@ -13,4 +13,4 @@ kamaji: cpu: 100m memory: 100Mi extraArgs: - - --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.39.1@sha256:ab66ab206da1b8b2fe1aa623a4accd8c91d2c5560aa857f949ee9183d79087ad + - --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.39.2@sha256:dbf879e70fc4a98070980be8d086fb79dc6a5b3ae4c1a1cc7578df5c39d8bd36 diff --git a/packages/system/kubeovn-plunger/values.yaml b/packages/system/kubeovn-plunger/values.yaml index 875932dd..df21d7a8 100644 --- a/packages/system/kubeovn-plunger/values.yaml +++ b/packages/system/kubeovn-plunger/values.yaml @@ -1,4 +1,4 @@ portSecurity: true routes: "" -image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.39.1@sha256:135ceb7289bc0522680fe9002f76ff2dc5feec03cdbc6b3008109aba9093e069 +image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.39.2@sha256:72bf70c59caa0a196936867297fac38822db09e40742c0762abbed31ab6237b6 ovnCentralName: ovn-central diff --git a/packages/system/kubeovn-webhook/values.yaml b/packages/system/kubeovn-webhook/values.yaml index 15eb396b..13437ce0 100644 --- a/packages/system/kubeovn-webhook/values.yaml +++ b/packages/system/kubeovn-webhook/values.yaml @@ -1,3 +1,3 @@ portSecurity: true routes: "" -image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.39.1@sha256:fc777726120350e5bdf4b864f49826b89983eb07a63c768d4907ce1330b35049 +image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.39.2@sha256:d5023bbfe524ec97bc499d853a3fe67affa9b37dd849eac521f38c651d50382c diff --git a/packages/system/kubeovn/values.yaml b/packages/system/kubeovn/values.yaml index 3f3841c2..eb33c3d3 100644 --- a/packages/system/kubeovn/values.yaml +++ b/packages/system/kubeovn/values.yaml @@ -65,4 +65,4 @@ global: images: kubeovn: repository: kubeovn - tag: v1.14.11@sha256:3ff2a91ed1f9ca7b3cb6281c7685dbb6bdc2108cb0d9ae3bfe74e8126125190a + tag: v1.14.11@sha256:b7ab6447a8ba692942596bc3b0f0f95b446a97546c4d15af0ad82a17cb7622a0 diff --git a/packages/system/kubevirt-csi-node/values.yaml b/packages/system/kubevirt-csi-node/values.yaml index 2de432c4..101d6d73 100644 --- a/packages/system/kubevirt-csi-node/values.yaml +++ b/packages/system/kubevirt-csi-node/values.yaml @@ -1,3 +1,3 @@ storageClass: replicated csiDriver: - image: ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:64c0b248e0d6b0a1578f59cab725152f3223a6d53ac0371eccaf023c0cd75904 + image: ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:ae0c5e3e005388d865617097a9fe4b4e8a2be6b62cec893e08f2143d0acde241 diff --git a/packages/system/lineage-controller-webhook/values.yaml b/packages/system/lineage-controller-webhook/values.yaml index d954b181..29da9b95 100644 --- a/packages/system/lineage-controller-webhook/values.yaml +++ b/packages/system/lineage-controller-webhook/values.yaml @@ -1,5 +1,5 @@ lineageControllerWebhook: - image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.39.1@sha256:58e20b3a403a319b1de3e27a3dea103421517052134dfaa3c13a5d41c5a0458d + image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.39.2@sha256:eb1186a56be49a9e6d65dad7b95febc6446b555d1d2dadf337e9c4a75c43193b debug: false localK8sAPIEndpoint: enabled: true diff --git a/packages/system/objectstorage-controller/values.yaml b/packages/system/objectstorage-controller/values.yaml index 7b45a2b0..91b25cc2 100644 --- a/packages/system/objectstorage-controller/values.yaml +++ b/packages/system/objectstorage-controller/values.yaml @@ -1,3 +1,3 @@ objectstorage: controller: - image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.39.1@sha256:91ed0ba4de7958708f77427d2c752dece969236c13927c17033d792700e9c6f4" + image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.39.2@sha256:494394c28f0487e5382cabe88e77b83ce20235c0fe0b1d14cb81ecc4c4446c49" diff --git a/packages/system/seaweedfs/values.yaml b/packages/system/seaweedfs/values.yaml index 5d85ed54..569493c3 100644 --- a/packages/system/seaweedfs/values.yaml +++ b/packages/system/seaweedfs/values.yaml @@ -124,7 +124,7 @@ seaweedfs: bucketClassName: "seaweedfs" region: "" sidecar: - image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.1@sha256:df9e205a0d063a30da6cff595d9d1951a76d35bf8cad9d21ac66aacef47a1f65" + image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.2@sha256:b180a6c4ce4d46cdf31af2731cc8b477e80ade99d4296d507ec5edb38c56a1ea" certificates: commonName: "SeaweedFS CA" ipAddresses: [] From 591451537133c5bbb0c08700eb3938b44560bb89 Mon Sep 17 00:00:00 2001 From: Aleksei Sviridkin Date: Mon, 5 Jan 2026 17:35:56 +0300 Subject: [PATCH 23/43] [kubevirt-operator] Revert incorrect case change in VM alerts Revert PR #1770 which incorrectly changed status check from lowercase to uppercase. The actual metrics use lowercase: - kubevirt_vm_info uses status="running" (not "Running") - kubevirt_vmi_info uses phase="running" (not "Running") Verified by querying virt-controller metrics in instories cluster. Co-Authored-By: Claude Signed-off-by: Aleksei Sviridkin (cherry picked from commit 36836fd84e77a1234b21a7d86df665314490f90a) --- packages/system/kubevirt-operator/alerts/PrometheusRule.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/system/kubevirt-operator/alerts/PrometheusRule.yaml b/packages/system/kubevirt-operator/alerts/PrometheusRule.yaml index c4d73cc5..72fabfa0 100644 --- a/packages/system/kubevirt-operator/alerts/PrometheusRule.yaml +++ b/packages/system/kubevirt-operator/alerts/PrometheusRule.yaml @@ -10,7 +10,7 @@ spec: expr: | max_over_time( kubevirt_vm_info{ - status!="Running", + status!="running", exported_namespace=~".+", name=~".+" }[10m] @@ -27,7 +27,7 @@ spec: expr: | max_over_time( kubevirt_vmi_info{ - phase!="Running", + phase!="running", exported_namespace=~".+", name=~".+" }[10m] From ad3bff66929ffb5b8187a2e93f8d18554a838f9c Mon Sep 17 00:00:00 2001 From: Timofei Larkin Date: Fri, 5 Dec 2025 23:33:50 +0400 Subject: [PATCH 24/43] [kubeovn] Package from external repo (#1535) Previously, all system charts have had their versions bumped with every update of Cozystack, even if the underlying images and templates did not change. Additionally, some components would have their docker images rebuilt and get updated digests because of a changed docker context, even though no relevant code had been changed. This would cause an upgrade of several HelmReleases on every upgrade of Cozystack, even when in practice nothing had changed. This is especially noticeable for charts, such as kubeovn, which is a dependency for almost all other system HelmReleases. By moving kubeovn out of the monorepo and decoupling its release cycle from the release cycle of Cozystack, this issue can be resolved and is another step towards decomposing Cozystack. ```release-note [kubeovn] Decouple the release cycle of kubeovn from Cozystack's release cycle, preventing unnecessary redeployments of all Helm releases, when upgrading Cozystack. ``` --- Makefile | 1 - packages/system/Makefile | 4 +- packages/system/kubeovn/Chart.yaml | 2 +- packages/system/kubeovn/Makefile | 31 +---- .../system/kubeovn/images/kubeovn/Dockerfile | 47 -------- .../images/kubeovn/patches/northd_probe.diff | 109 ------------------ .../system/kubeovn/patches/cozyconfig.diff | 103 ----------------- packages/system/kubeovn/patches/mtu.diff | 14 --- packages/system/kubeovn/values.yaml | 2 +- 9 files changed, 10 insertions(+), 303 deletions(-) delete mode 100644 packages/system/kubeovn/images/kubeovn/Dockerfile delete mode 100644 packages/system/kubeovn/images/kubeovn/patches/northd_probe.diff delete mode 100644 packages/system/kubeovn/patches/cozyconfig.diff delete mode 100644 packages/system/kubeovn/patches/mtu.diff diff --git a/Makefile b/Makefile index 2038ff9f..31a947c4 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,6 @@ build: build-deps make -C packages/system/cozystack-controller image make -C packages/system/lineage-controller-webhook image make -C packages/system/cilium image - make -C packages/system/kubeovn image make -C packages/system/kubeovn-webhook image make -C packages/system/kubeovn-plunger image make -C packages/system/dashboard image diff --git a/packages/system/Makefile b/packages/system/Makefile index 2104647b..e068be8a 100644 --- a/packages/system/Makefile +++ b/packages/system/Makefile @@ -1,11 +1,13 @@ OUT=../../_out/repos/system -CHARTS := $(shell find . -maxdepth 2 -name Chart.yaml | awk -F/ '{print $$2}') +CHARTS := $(shell grep -F 'version: 0.0.0' */Chart.yaml | cut -f1 -d/) +VERSIONED_CHARTS := $(shell grep '^version:' */Chart.yaml | grep -Fv '0.0.0' | cut -f1 -d/) include ../../scripts/common-envs.mk repo: rm -rf "$(OUT)" helm package -d "$(OUT)" $(CHARTS) --version $(COZYSTACK_VERSION) + helm package -d "$(OUT)" $(VERSIONED_CHARTS) cd "$(OUT)" && helm repo index . fix-charts: diff --git a/packages/system/kubeovn/Chart.yaml b/packages/system/kubeovn/Chart.yaml index 16cb9dc5..d1532794 100644 --- a/packages/system/kubeovn/Chart.yaml +++ b/packages/system/kubeovn/Chart.yaml @@ -1,3 +1,3 @@ apiVersion: v2 name: cozy-kubeovn -version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process +version: 0.39.0 diff --git a/packages/system/kubeovn/Makefile b/packages/system/kubeovn/Makefile index 15373d2f..a4a0d1ed 100644 --- a/packages/system/kubeovn/Makefile +++ b/packages/system/kubeovn/Makefile @@ -1,4 +1,4 @@ -KUBEOVN_TAG=$(shell awk '$$1 == "version:" {print $$2}' charts/kube-ovn/Chart.yaml) +KUBEOVN_TAG=v0.39.0 export NAME=kubeovn export NAMESPACE=cozy-$(NAME) @@ -7,28 +7,7 @@ include ../../../scripts/common-envs.mk include ../../../scripts/package.mk update: - rm -rf charts && mkdir -p charts/kube-ovn - tag=$$(git ls-remote --tags --sort="v:refname" https://github.com/kubeovn/kube-ovn | awk -F'[/^]' '{print $$3}' | grep '^v1\.14\.' | tail -n1 ) && \ - curl -sSL https://github.com/kubeovn/kube-ovn/archive/refs/tags/$${tag}.tar.gz | \ - tar xzvf - --strip 1 kube-ovn-$${tag#*v}/charts/kube-ovn - patch --no-backup-if-mismatch -p4 < patches/cozyconfig.diff - patch --no-backup-if-mismatch -p4 < patches/mtu.diff - version=$$(awk '$$1 == "version:" {print $$2}' charts/kube-ovn/Chart.yaml) && \ - sed -i "s/ARG VERSION=.*/ARG VERSION=$${version}/" images/kubeovn/Dockerfile && \ - sed -i "s/ARG TAG=.*/ARG TAG=$${version}/" images/kubeovn/Dockerfile - -image: - docker buildx build images/kubeovn \ - --tag $(REGISTRY)/kubeovn:$(call settag,$(KUBEOVN_TAG)) \ - --tag $(REGISTRY)/kubeovn:$(call settag,$(KUBEOVN_TAG)-$(TAG)) \ - --cache-from type=registry,ref=$(REGISTRY)/kubeovn:latest \ - --cache-to type=inline \ - --metadata-file images/kubeovn.json \ - $(BUILDX_ARGS) - REGISTRY="$(REGISTRY)" \ - yq -i '.global.registry.address = strenv(REGISTRY)' values.yaml - REPOSITORY="kubeovn" \ - yq -i '.global.images.kubeovn.repository = strenv(REPOSITORY)' values.yaml - TAG="$(call settag,$(KUBEOVN_TAG))@$$(yq e '."containerimage.digest"' images/kubeovn.json -o json -r)" \ - yq -i '.global.images.kubeovn.tag = strenv(TAG)' values.yaml - rm -f images/kubeovn.json + rm -rf charts values.yaml Chart.yaml + tag=$(KUBEOVN_TAG) && \ + curl -sSL https://github.com/cozystack/kubeovn/archive/refs/tags/$${tag}.tar.gz | \ + tar xzvf - --strip 2 kubeovn-$${tag#*v}/chart diff --git a/packages/system/kubeovn/images/kubeovn/Dockerfile b/packages/system/kubeovn/images/kubeovn/Dockerfile deleted file mode 100644 index 5ea19c93..00000000 --- a/packages/system/kubeovn/images/kubeovn/Dockerfile +++ /dev/null @@ -1,47 +0,0 @@ -# syntax = docker/dockerfile:experimental -ARG VERSION=v1.14.11 -ARG BASE_TAG=$VERSION - -FROM golang:1.25-bookworm as builder - -ARG TAG=v1.14.11 -RUN git clone --branch ${TAG} --depth 1 https://github.com/kubeovn/kube-ovn /source - -WORKDIR /source - -COPY patches /patches -RUN git apply /patches/*.diff -RUN make build-go - -WORKDIR /source/dist/images - -# imported from https://github.com/kubeovn/kube-ovn/blob/master/dist/images/Dockerfile -FROM kubeovn/kube-ovn-base:$BASE_TAG AS setcap - -COPY --from=builder /source/dist/images/*.sh /kube-ovn/ -COPY --from=builder /source/dist/images/kubectl-ko /kube-ovn/kubectl-ko -COPY --from=builder /source/dist/images/01-kube-ovn.conflist /kube-ovn/01-kube-ovn.conflist - -COPY --from=builder /source/dist/images/kube-ovn /kube-ovn/kube-ovn -COPY --from=builder /source/dist/images/kube-ovn-cmd /kube-ovn/kube-ovn-cmd -COPY --from=builder /source/dist/images/kube-ovn-daemon /kube-ovn/kube-ovn-daemon -COPY --from=builder /source/dist/images/kube-ovn-controller /kube-ovn/kube-ovn-controller -RUN ln -s /kube-ovn/kube-ovn-cmd /kube-ovn/kube-ovn-monitor && \ - ln -s /kube-ovn/kube-ovn-cmd /kube-ovn/kube-ovn-speaker && \ - ln -s /kube-ovn/kube-ovn-cmd /kube-ovn/kube-ovn-webhook && \ - ln -s /kube-ovn/kube-ovn-cmd /kube-ovn/kube-ovn-leader-checker && \ - ln -s /kube-ovn/kube-ovn-cmd /kube-ovn/kube-ovn-ic-controller && \ - ln -s /kube-ovn/kube-ovn-controller /kube-ovn/kube-ovn-pinger && \ - setcap CAP_NET_BIND_SERVICE+eip /kube-ovn/kube-ovn-cmd && \ - setcap CAP_NET_RAW,CAP_NET_BIND_SERVICE+eip /kube-ovn/kube-ovn-controller && \ - setcap CAP_NET_ADMIN,CAP_NET_RAW,CAP_NET_BIND_SERVICE,CAP_SYS_ADMIN+eip /kube-ovn/kube-ovn-daemon - -FROM kubeovn/kube-ovn-base:$BASE_TAG - -COPY --chmod=0644 --from=builder /source/dist/images/logrotate/* /etc/logrotate.d/ -COPY --from=builder /source/dist/images/grace_stop_ovn_controller /usr/share/ovn/scripts/grace_stop_ovn_controller - -COPY --from=setcap /kube-ovn /kube-ovn -RUN /kube-ovn/iptables-wrapper-installer.sh --no-sanity-check - -WORKDIR /kube-ovn diff --git a/packages/system/kubeovn/images/kubeovn/patches/northd_probe.diff b/packages/system/kubeovn/images/kubeovn/patches/northd_probe.diff deleted file mode 100644 index 93edd879..00000000 --- a/packages/system/kubeovn/images/kubeovn/patches/northd_probe.diff +++ /dev/null @@ -1,109 +0,0 @@ -diff --git a/pkg/ovn_leader_checker/ovn.go b/pkg/ovn_leader_checker/ovn.go -index 0f86a371d..8ddf7bca6 100755 ---- a/pkg/ovn_leader_checker/ovn.go -+++ b/pkg/ovn_leader_checker/ovn.go -@@ -10,6 +10,7 @@ import ( - "os/exec" - "strconv" - "strings" -+ "sync" - "syscall" - "time" - -@@ -271,19 +272,56 @@ func checkNorthdSvcExist(cfg *Configuration, namespace, svcName string) bool { - return true - } - --func checkNorthdEpAvailable(ip string) bool { -- address := net.JoinHostPort(ip, OvnNorthdPort) -- conn, err := net.DialTimeout("tcp", address, 3*time.Second) -- if err != nil { -- klog.Errorf("failed to connect to northd leader %s, err: %v", ip, err) -- failCount++ -- if failCount >= MaxFailCount { -- return false -- } -- } else { -+func checkNorthdEpAvailable(ips ...string) bool { -+ var wg sync.WaitGroup -+ success := make(chan struct{}, 1) -+ failure := make(chan struct{}) -+ ctx, cancel := context.WithCancel(context.Background()) -+ defer cancel() -+ d := net.Dialer{Timeout: 3 * time.Second} -+ for _, ip := range ips { -+ address := net.JoinHostPort(ip, OvnNorthdPort) -+ wg.Add(1) -+ go func() { -+ defer wg.Done() -+ conn, err := d.DialContext(ctx, "tcp", address) -+ if err != nil { -+ klog.Errorf("failed to connect to northd leader %s, err: %v", ip, err) -+ return -+ } else { -+ defer conn.Close() -+ select { -+ case success <- struct{}{}: -+ klog.V(5).Infof("succeed to connect to northd leader %s", ip) -+ cancel() -+ default: -+ // someone else already succeeded -+ } -+ } -+ }() -+ } -+ go func() { -+ wg.Wait() -+ close(failure) -+ }() -+ select { -+ case <-success: - failCount = 0 -- klog.V(5).Infof("succeed to connect to northd leader %s", ip) -- _ = conn.Close() -+ return true -+ case <-failure: -+ // if the last groroutine is the one to succeed, -+ // there's a small chance that failure is selected, -+ // this is a guard for this -+ select { -+ case <-success: -+ failCount = 0 -+ return true -+ default: -+ failCount++ -+ if failCount >= MaxFailCount { -+ return false -+ } -+ } - } - return true - } -@@ -295,6 +333,8 @@ func checkNorthdEpAlive(cfg *Configuration, namespace, service string) bool { - return false - } - -+ addresses := []string{} -+ - for _, eps := range epsList.Items { - for _, ep := range eps.Endpoints { - if (ep.Conditions.Ready != nil && !*ep.Conditions.Ready) || len(ep.Addresses) == 0 { -@@ -303,12 +343,15 @@ func checkNorthdEpAlive(cfg *Configuration, namespace, service string) bool { - - // Found an address, check its availability. We only need one. - klog.V(5).Infof("found address %s in endpoint slice %s/%s for service %s, checking availability", ep.Addresses[0], eps.Namespace, eps.Name, service) -- return checkNorthdEpAvailable(ep.Addresses[0]) -+ addresses = append(addresses, ep.Addresses[0]) // Addresses are fungible by k8s API design - } - } - -- klog.V(5).Infof("no address found in any endpoint slices for service %s/%s", namespace, service) -- return false -+ if len(addresses) == 0 { -+ klog.V(5).Infof("no address found in any endpoint slices for service %s/%s", namespace, service) -+ return false -+ } -+ return checkNorthdEpAvailable(addresses...) - } - - func compactOvnDatabase(db string) { diff --git a/packages/system/kubeovn/patches/cozyconfig.diff b/packages/system/kubeovn/patches/cozyconfig.diff deleted file mode 100644 index f7a683f7..00000000 --- a/packages/system/kubeovn/patches/cozyconfig.diff +++ /dev/null @@ -1,103 +0,0 @@ - -diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml b/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml -index d9a9a67..b2e12dd 100644 ---- a/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml -+++ b/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml -@@ -51,18 +51,15 @@ spec: - - bash - - /kube-ovn/start-cniserver.sh - args: -+ {{- $cozyConfig := lookup "v1" "ConfigMap" "cozy-system" "cozystack" }} - - --enable-mirror={{- .Values.debug.ENABLE_MIRROR }} - - --mirror-iface={{- .Values.debug.MIRROR_IFACE }} - - --node-switch={{ .Values.networking.NODE_SUBNET }} - - --encap-checksum=true -- - --service-cluster-ip-range= -- {{- if eq .Values.networking.NET_STACK "dual_stack" -}} -- {{ .Values.dual_stack.SVC_CIDR }} -- {{- else if eq .Values.networking.NET_STACK "ipv4" -}} -- {{ .Values.ipv4.SVC_CIDR }} -- {{- else if eq .Values.networking.NET_STACK "ipv6" -}} -- {{ .Values.ipv6.SVC_CIDR }} -- {{- end }} -+ - --service-cluster-ip-range={{ index $cozyConfig.data "ipv4-svc-cidr" }} -+ {{- if .Values.global.logVerbosity }} -+ - --v={{ .Values.global.logVerbosity }} -+ {{- end }} - {{- if eq .Values.networking.NETWORK_TYPE "vlan" }} - - --iface= - {{- else}} -diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/controller-deploy.yaml b/packages/system/kubeovn/charts/kube-ovn/templates/controller-deploy.yaml -index 0e69494..756eb7c 100644 ---- a/packages/system/kubeovn/charts/kube-ovn/templates/controller-deploy.yaml -+++ b/packages/system/kubeovn/charts/kube-ovn/templates/controller-deploy.yaml -@@ -52,46 +52,22 @@ spec: - image: {{ .Values.global.registry.address }}/{{ .Values.global.images.kubeovn.repository }}:{{ .Values.global.images.kubeovn.tag }} - imagePullPolicy: {{ .Values.image.pullPolicy }} - args: -+ {{- $cozyConfig := lookup "v1" "ConfigMap" "cozy-system" "cozystack" }} - - /kube-ovn/start-controller.sh - - --default-ls={{ .Values.networking.DEFAULT_SUBNET }} -- - --default-cidr= -- {{- if eq .Values.networking.NET_STACK "dual_stack" -}} -- {{ .Values.dual_stack.POD_CIDR }} -- {{- else if eq .Values.networking.NET_STACK "ipv4" -}} -- {{ .Values.ipv4.POD_CIDR }} -- {{- else if eq .Values.networking.NET_STACK "ipv6" -}} -- {{ .Values.ipv6.POD_CIDR }} -- {{- end }} -- - --default-gateway= -- {{- if eq .Values.networking.NET_STACK "dual_stack" -}} -- {{ .Values.dual_stack.POD_GATEWAY }} -- {{- else if eq .Values.networking.NET_STACK "ipv4" -}} -- {{ .Values.ipv4.POD_GATEWAY }} -- {{- else if eq .Values.networking.NET_STACK "ipv6" -}} -- {{ .Values.ipv6.POD_GATEWAY }} -- {{- end }} -+ - --default-cidr={{ index $cozyConfig.data "ipv4-pod-cidr" }} -+ - --default-gateway={{ index $cozyConfig.data "ipv4-pod-gateway" }} - - --default-gateway-check={{- .Values.func.CHECK_GATEWAY }} - - --default-logical-gateway={{- .Values.func.LOGICAL_GATEWAY }} - - --default-u2o-interconnection={{- .Values.func.U2O_INTERCONNECTION }} - - --default-exclude-ips={{- .Values.networking.EXCLUDE_IPS }} - - --cluster-router={{ .Values.networking.DEFAULT_VPC }} - - --node-switch={{ .Values.networking.NODE_SUBNET }} -- - --node-switch-cidr= -- {{- if eq .Values.networking.NET_STACK "dual_stack" -}} -- {{ .Values.dual_stack.JOIN_CIDR }} -- {{- else if eq .Values.networking.NET_STACK "ipv4" -}} -- {{ .Values.ipv4.JOIN_CIDR }} -- {{- else if eq .Values.networking.NET_STACK "ipv6" -}} -- {{ .Values.ipv6.JOIN_CIDR }} -- {{- end }} -- - --service-cluster-ip-range= -- {{- if eq .Values.networking.NET_STACK "dual_stack" -}} -- {{ .Values.dual_stack.SVC_CIDR }} -- {{- else if eq .Values.networking.NET_STACK "ipv4" -}} -- {{ .Values.ipv4.SVC_CIDR }} -- {{- else if eq .Values.networking.NET_STACK "ipv6" -}} -- {{ .Values.ipv6.SVC_CIDR }} -- {{- end }} -+ - --node-switch-cidr={{ index $cozyConfig.data "ipv4-join-cidr" }} -+ - --service-cluster-ip-range={{ index $cozyConfig.data "ipv4-svc-cidr" }} -+ {{- if .Values.global.logVerbosity }} -+ - --v={{ .Values.global.logVerbosity }} -+ {{- end }} - - --network-type={{- .Values.networking.NETWORK_TYPE }} - - --default-provider-name={{ .Values.networking.vlan.PROVIDER_NAME }} - - --default-interface-name={{- .Values.networking.vlan.VLAN_INTERFACE_NAME }} -diff --git a/packages/system/kubeovn/charts/kube-ovn/values.yaml b/packages/system/kubeovn/charts/kube-ovn/values.yaml -index bfffc4d..b880749 100644 ---- a/packages/system/kubeovn/charts/kube-ovn/values.yaml -+++ b/packages/system/kubeovn/charts/kube-ovn/values.yaml -@@ -70,10 +70,6 @@ func: - ENABLE_TPROXY: false - - ipv4: -- POD_CIDR: "10.16.0.0/16" -- POD_GATEWAY: "10.16.0.1" -- SVC_CIDR: "10.96.0.0/12" -- JOIN_CIDR: "100.64.0.0/16" - PINGER_EXTERNAL_ADDRESS: "1.1.1.1" - PINGER_EXTERNAL_DOMAIN: "alauda.cn." - diff --git a/packages/system/kubeovn/patches/mtu.diff b/packages/system/kubeovn/patches/mtu.diff deleted file mode 100644 index da3de3aa..00000000 --- a/packages/system/kubeovn/patches/mtu.diff +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml b/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml -index 63f4258..dafe1fd 100644 ---- a/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml -+++ b/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml -@@ -112,6 +112,9 @@ spec: - - --secure-serving={{- .Values.func.SECURE_SERVING }} - - --enable-ovn-ipsec={{- .Values.func.ENABLE_OVN_IPSEC }} - - --set-vxlan-tx-off={{- .Values.func.SET_VXLAN_TX_OFF }} -+ {{- with .Values.mtu }} -+ - --mtu={{ . }} -+ {{- end }} - securityContext: - runAsUser: 0 - privileged: false diff --git a/packages/system/kubeovn/values.yaml b/packages/system/kubeovn/values.yaml index eb33c3d3..89f20e7c 100644 --- a/packages/system/kubeovn/values.yaml +++ b/packages/system/kubeovn/values.yaml @@ -65,4 +65,4 @@ global: images: kubeovn: repository: kubeovn - tag: v1.14.11@sha256:b7ab6447a8ba692942596bc3b0f0f95b446a97546c4d15af0ad82a17cb7622a0 + tag: v1.14.11@sha256:0e3e9db960a9600d58c33c0787cabd0e9bf263930fd8c9fe65417e258c383d01 From 143da399ff041bbc1b97c48754561a2e6a34f694 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Tue, 16 Dec 2025 10:50:19 +0100 Subject: [PATCH 25/43] [kubernetes] Fix endpoints for cilium-gateway Signed-off-by: Andrei Kvapil (cherry picked from commit f59665208c2d0d7847150354a5ea6cdd7c291913) --- .../patches/{354.diff => 379.diff} | 83 ++++++++++++++++++- 1 file changed, 80 insertions(+), 3 deletions(-) rename packages/apps/kubernetes/images/kubevirt-cloud-provider/patches/{354.diff => 379.diff} (63%) diff --git a/packages/apps/kubernetes/images/kubevirt-cloud-provider/patches/354.diff b/packages/apps/kubernetes/images/kubevirt-cloud-provider/patches/379.diff similarity index 63% rename from packages/apps/kubernetes/images/kubevirt-cloud-provider/patches/354.diff rename to packages/apps/kubernetes/images/kubevirt-cloud-provider/patches/379.diff index 3410ea93..ad1ec9c5 100644 --- a/packages/apps/kubernetes/images/kubevirt-cloud-provider/patches/354.diff +++ b/packages/apps/kubernetes/images/kubevirt-cloud-provider/patches/379.diff @@ -1,5 +1,5 @@ diff --git a/pkg/controller/kubevirteps/kubevirteps_controller.go b/pkg/controller/kubevirteps/kubevirteps_controller.go -index 53388eb8e..28644236f 100644 +index 53388eb8e..873060251 100644 --- a/pkg/controller/kubevirteps/kubevirteps_controller.go +++ b/pkg/controller/kubevirteps/kubevirteps_controller.go @@ -12,7 +12,6 @@ import ( @@ -10,12 +10,17 @@ index 53388eb8e..28644236f 100644 "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" utilruntime "k8s.io/apimachinery/pkg/util/runtime" -@@ -669,35 +668,50 @@ func (c *Controller) getDesiredEndpoints(service *v1.Service, tenantSlices []*di +@@ -666,38 +665,62 @@ func (c *Controller) getDesiredEndpoints(service *v1.Service, tenantSlices []*di + // for extracting the nodes it does not matter what type of address we are dealing with + // all nodes with an endpoint for a corresponding slice will be selected. + nodeSet := sets.Set[string]{} ++ hasEndpointsWithoutNodeName := false for _, slice := range tenantSlices { for _, endpoint := range slice.Endpoints { // find all unique nodes that correspond to an endpoint in a tenant slice + if endpoint.NodeName == nil { + klog.Warningf("Skipping endpoint without NodeName in slice %s/%s", slice.Namespace, slice.Name) ++ hasEndpointsWithoutNodeName = true + continue + } nodeSet.Insert(*endpoint.NodeName) @@ -23,6 +28,13 @@ index 53388eb8e..28644236f 100644 } - klog.Infof("Desired nodes for service %s in namespace %s: %v", service.Name, service.Namespace, sets.List(nodeSet)) ++ // Fallback: if no endpoints with NodeName were found, but there are endpoints without NodeName, ++ // distribute traffic to all VMIs (similar to ExternalTrafficPolicy=Cluster behavior) ++ if nodeSet.Len() == 0 && hasEndpointsWithoutNodeName { ++ klog.Infof("No endpoints with NodeName found for service %s/%s, falling back to all VMIs", service.Namespace, service.Name) ++ return c.getAllVMIEndpoints() ++ } ++ + klog.Infof("Desired nodes for service %s/%s: %v", service.Namespace, service.Name, sets.List(nodeSet)) for _, node := range sets.List(nodeSet) { @@ -68,7 +80,7 @@ index 53388eb8e..28644236f 100644 desiredEndpoints = append(desiredEndpoints, &discovery.Endpoint{ Addresses: []string{i.IP}, Conditions: discovery.EndpointConditions{ -@@ -705,9 +719,9 @@ func (c *Controller) getDesiredEndpoints(service *v1.Service, tenantSlices []*di +@@ -705,9 +728,9 @@ func (c *Controller) getDesiredEndpoints(service *v1.Service, tenantSlices []*di Serving: &serving, Terminating: &terminating, }, @@ -80,6 +92,71 @@ index 53388eb8e..28644236f 100644 } } } +@@ -716,6 +739,64 @@ func (c *Controller) getDesiredEndpoints(service *v1.Service, tenantSlices []*di + return desiredEndpoints + } + ++// getAllVMIEndpoints returns endpoints for all VMIs in the infra namespace. ++// This is used as a fallback when tenant endpoints don't have NodeName specified, ++// similar to ExternalTrafficPolicy=Cluster behavior where traffic is distributed to all nodes. ++func (c *Controller) getAllVMIEndpoints() []*discovery.Endpoint { ++ var endpoints []*discovery.Endpoint ++ ++ // List all VMIs in the infra namespace ++ vmiList, err := c.infraDynamic. ++ Resource(kubevirtv1.VirtualMachineInstanceGroupVersionKind.GroupVersion().WithResource("virtualmachineinstances")). ++ Namespace(c.infraNamespace). ++ List(context.TODO(), metav1.ListOptions{}) ++ if err != nil { ++ klog.Errorf("Failed to list VMIs in namespace %q: %v", c.infraNamespace, err) ++ return endpoints ++ } ++ ++ for _, obj := range vmiList.Items { ++ vmi := &kubevirtv1.VirtualMachineInstance{} ++ err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, vmi) ++ if err != nil { ++ klog.Errorf("Failed to convert Unstructured to VirtualMachineInstance: %v", err) ++ continue ++ } ++ ++ if vmi.Status.NodeName == "" { ++ klog.Warningf("Skipping VMI %s/%s: NodeName is empty", vmi.Namespace, vmi.Name) ++ continue ++ } ++ nodeNamePtr := &vmi.Status.NodeName ++ ++ ready := vmi.Status.Phase == kubevirtv1.Running ++ serving := vmi.Status.Phase == kubevirtv1.Running ++ terminating := vmi.Status.Phase == kubevirtv1.Failed || vmi.Status.Phase == kubevirtv1.Succeeded ++ ++ for _, i := range vmi.Status.Interfaces { ++ if i.Name == "default" { ++ if i.IP == "" { ++ klog.Warningf("VMI %s/%s interface %q has no IP, skipping", vmi.Namespace, vmi.Name, i.Name) ++ continue ++ } ++ endpoints = append(endpoints, &discovery.Endpoint{ ++ Addresses: []string{i.IP}, ++ Conditions: discovery.EndpointConditions{ ++ Ready: &ready, ++ Serving: &serving, ++ Terminating: &terminating, ++ }, ++ NodeName: nodeNamePtr, ++ }) ++ break ++ } ++ } ++ } ++ ++ klog.Infof("Fallback: created %d endpoints from all VMIs in namespace %s", len(endpoints), c.infraNamespace) ++ return endpoints ++} ++ + func (c *Controller) ensureEndpointSliceLabels(slice *discovery.EndpointSlice, svc *v1.Service) (map[string]string, bool) { + labels := make(map[string]string) + labelsChanged := false diff --git a/pkg/controller/kubevirteps/kubevirteps_controller_test.go b/pkg/controller/kubevirteps/kubevirteps_controller_test.go index 1c97035b4..d205d0bed 100644 --- a/pkg/controller/kubevirteps/kubevirteps_controller_test.go From 07982b2646cf6b973b49e3c90312413d9ea86fdc Mon Sep 17 00:00:00 2001 From: Timofei Larkin Date: Mon, 5 Jan 2026 15:27:36 +0300 Subject: [PATCH 26/43] [testing] Add aliases and autocomplete ## What this PR does Adds a `k=kubectl` alias and bash completion for kubectl to the e2e-testing sandbox container to maintainers have an easier time exec'ing into the CI container when something needs to be debugged. ### Release note ```release-note [testing] Add k=kubectl alias and enable kubectl completion in the CI container. ``` Signed-off-by: Timofei Larkin (cherry picked from commit bf1928c96f8ed61c87d3d4b923b24d83d08f9c85) --- packages/core/testing/Chart.yaml | 0 packages/core/testing/Makefile | 0 packages/core/testing/images/e2e-sandbox/Dockerfile | 10 +++++++++- packages/core/testing/values.yaml | 0 4 files changed, 9 insertions(+), 1 deletion(-) mode change 100755 => 100644 packages/core/testing/Chart.yaml mode change 100755 => 100644 packages/core/testing/Makefile mode change 100755 => 100644 packages/core/testing/images/e2e-sandbox/Dockerfile mode change 100755 => 100644 packages/core/testing/values.yaml diff --git a/packages/core/testing/Chart.yaml b/packages/core/testing/Chart.yaml old mode 100755 new mode 100644 diff --git a/packages/core/testing/Makefile b/packages/core/testing/Makefile old mode 100755 new mode 100644 diff --git a/packages/core/testing/images/e2e-sandbox/Dockerfile b/packages/core/testing/images/e2e-sandbox/Dockerfile old mode 100755 new mode 100644 index 069a1905..1dabdc55 --- a/packages/core/testing/images/e2e-sandbox/Dockerfile +++ b/packages/core/testing/images/e2e-sandbox/Dockerfile @@ -9,7 +9,7 @@ ARG TARGETOS ARG TARGETARCH RUN apt update -q -RUN apt install -yq --no-install-recommends psmisc genisoimage ca-certificates qemu-kvm qemu-utils iproute2 iptables wget xz-utils netcat curl jq make git +RUN apt install -yq --no-install-recommends psmisc genisoimage ca-certificates qemu-kvm qemu-utils iproute2 iptables wget xz-utils netcat curl jq make git bash-completion RUN curl -sSL "https://github.com/siderolabs/talos/releases/download/v${TALOSCTL_VERSION}/talosctl-${TARGETOS}-${TARGETARCH}" -o /usr/local/bin/talosctl \ && chmod +x /usr/local/bin/talosctl RUN curl -sSL "https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/${TARGETOS}/${TARGETARCH}/kubectl" -o /usr/local/bin/kubectl \ @@ -21,5 +21,13 @@ RUN curl -sSL "https://fluxcd.io/install.sh" | bash RUN curl -sSL "https://github.com/cozystack/cozypkg/raw/refs/heads/main/hack/install.sh" | sh -s -- -v "${COZYPKG_VERSION}" RUN curl https://dl.min.io/client/mc/release/${TARGETOS}-${TARGETARCH}/mc --create-dirs -o /usr/local/bin/mc \ && chmod +x /usr/local/bin/mc +RUN <<'EOF' +cat <<'EOT' >> /etc/bash.bashrc +. /etc/bash_completion +. <(kubectl completion bash) +alias k=kubectl +complete -F __start_kubectl k +EOT +EOF COPY entrypoint.sh /usr/local/bin/entrypoint.sh ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/packages/core/testing/values.yaml b/packages/core/testing/values.yaml old mode 100755 new mode 100644 From cb0e457ddad963970a3e5579fed8c5450e3c31d4 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Tue, 16 Dec 2025 02:37:32 +0100 Subject: [PATCH 27/43] feat(linstor): build linstor-server with custom patches Add patches for piraeus-server: - adjust-on-resfile-change: handle resource file changes - allow-toggle-disk-retry: enable disk operation retries - force-metadata-check-on-disk-add: verify metadata on disk addition Update plunger-satellite script and values.yaml for new build. Signed-off-by: Andrei Kvapil (cherry picked from commit daa91fd2f36b9c9ee791e99569f613f858c1b842) --- Makefile | 1 + packages/system/linstor/Makefile | 19 ++ .../linstor/hack/plunger/plunger-satellite.sh | 122 ++++++++- .../linstor/images/piraeus-server/Dockerfile | 172 +++++++++++++ .../images/piraeus-server/patches/README.md | 12 + .../patches/adjust-on-resfile-change.diff | 48 ++++ .../patches/allow-toggle-disk-retry.diff | 235 ++++++++++++++++++ .../force-metadata-check-on-disk-add.diff | 63 +++++ .../skip-adjust-when-device-inaccessible.diff | 93 +++++++ .../system/linstor/templates/_helpers.tpl | 24 -- .../system/linstor/templates/cluster.yaml | 4 +- .../linstor/templates/satellites-cozy.yaml | 1 + .../linstor/templates/satellites-plunger.yaml | 4 +- packages/system/linstor/values.yaml | 5 +- 14 files changed, 773 insertions(+), 30 deletions(-) create mode 100644 packages/system/linstor/images/piraeus-server/Dockerfile create mode 100644 packages/system/linstor/images/piraeus-server/patches/README.md create mode 100644 packages/system/linstor/images/piraeus-server/patches/adjust-on-resfile-change.diff create mode 100644 packages/system/linstor/images/piraeus-server/patches/allow-toggle-disk-retry.diff create mode 100644 packages/system/linstor/images/piraeus-server/patches/force-metadata-check-on-disk-add.diff create mode 100644 packages/system/linstor/images/piraeus-server/patches/skip-adjust-when-device-inaccessible.diff delete mode 100644 packages/system/linstor/templates/_helpers.tpl diff --git a/Makefile b/Makefile index 31a947c4..56322b04 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,7 @@ build: build-deps make -C packages/system/cozystack-controller image make -C packages/system/lineage-controller-webhook image make -C packages/system/cilium image + make -C packages/system/linstor image make -C packages/system/kubeovn-webhook image make -C packages/system/kubeovn-plunger image make -C packages/system/dashboard image diff --git a/packages/system/linstor/Makefile b/packages/system/linstor/Makefile index 5de22194..da895085 100644 --- a/packages/system/linstor/Makefile +++ b/packages/system/linstor/Makefile @@ -1,4 +1,23 @@ export NAME=linstor export NAMESPACE=cozy-$(NAME) +include ../../../scripts/common-envs.mk include ../../../scripts/package.mk + +LINSTOR_VERSION ?= 1.32.3 + +image: + docker buildx build images/piraeus-server \ + --build-arg LINSTOR_VERSION=$(LINSTOR_VERSION) \ + --build-arg K8S_AWAIT_ELECTION_VERSION=v0.4.2 \ + --tag $(REGISTRY)/piraeus-server:$(call settag,$(LINSTOR_VERSION)) \ + --tag $(REGISTRY)/piraeus-server:$(call settag,$(LINSTOR_VERSION)-$(TAG)) \ + --cache-from type=registry,ref=$(REGISTRY)/piraeus-server:latest \ + --cache-to type=inline \ + --metadata-file images/piraeus-server.json \ + $(BUILDX_ARGS) + REPOSITORY="$(REGISTRY)/piraeus-server" \ + yq -i '.piraeusServer.image.repository = strenv(REPOSITORY)' values.yaml + TAG="$(call settag,$(LINSTOR_VERSION))@$$(yq e '."containerimage.digest"' images/piraeus-server.json -o json -r)" \ + yq -i '.piraeusServer.image.tag = strenv(TAG)' values.yaml + rm -f images/piraeus-server.json diff --git a/packages/system/linstor/hack/plunger/plunger-satellite.sh b/packages/system/linstor/hack/plunger/plunger-satellite.sh index 688cfd65..4a488a51 100755 --- a/packages/system/linstor/hack/plunger/plunger-satellite.sh +++ b/packages/system/linstor/hack/plunger/plunger-satellite.sh @@ -10,10 +10,125 @@ trap terminate SIGINT SIGQUIT SIGTERM echo "Starting Linstor per-satellite plunger" +INTERVAL_SEC="${INTERVAL_SEC:-30}" +STALL_ITERS="${STALL_ITERS:-4}" +STATE_FILE="${STATE_FILE:-/run/drbd-sync-watch.state}" + +log() { printf '%s %s\n' "$(date -Is)" "$*" >&2; } + +drbd_status_json() { + drbdsetup status --json 2>/dev/null || true +} + +# Detect DRBD resources where resync is stuck: +# - at least one local device is Inconsistent +# - there is an active SyncTarget peer +# - there are other peers suspended with resync-suspended:dependency +# Output format: " " +drbd_stall_candidates() { + jq -r ' + .[]? + | . as $r + | select(any($r.devices[]?; ."disk-state" == "Inconsistent")) + | ( + [ $r.connections[]? + | . as $c + | $c.peer_devices[]? + | select(."replication-state" == "SyncTarget") + | { peer: $c.name, pct: (."percent-in-sync" // empty) } + ] | .[0]? + ) as $sync + | select($sync != null and ($sync.pct|tostring) != "") + | select(any($r.connections[]?.peer_devices[]?; ."resync-suspended" == "dependency")) + | "\($r.name) \($sync.peer) \($sync.pct)" + ' +} + +drbd_stall_load_state() { + [ -f "$STATE_FILE" ] && cat "$STATE_FILE" || true +} + +drbd_stall_save_state() { + local tmp="${STATE_FILE}.tmp" + cat >"$tmp" + mv "$tmp" "$STATE_FILE" +} + +# Break stalled resync by disconnecting the current SyncTarget peer. +# After reconnect, DRBD will typically pick another eligible peer and continue syncing. +drbd_stall_act() { + local res="$1" + local peer="$2" + local pct="$3" + log "STALL detected: res=$res sync_peer=$peer percent_in_sync=$pct -> disconnect/connect" + drbdadm disconnect "${res}:${peer}" && drbdadm connect "$res" || log "WARN: action failed for ${res}:${peer}" +} + +# Track percent-in-sync progress across iterations. +# If progress does not change for STALL_ITERS loops, trigger reconnect. +drbd_fix_stalled_sync() { + local now prev json out + now="$(date +%s)" + prev="$(drbd_stall_load_state)" + + json="$(drbd_status_json)" + [ -n "$json" ] || return 0 + + out="$(printf '%s' "$json" | drbd_stall_candidates)" + + local new_state="" + local acts="" + + while IFS= read -r line; do + [ -n "$line" ] || continue + set -- $line + local res="$1" peer="$2" pct="$3" + local key="${res} ${peer}" + + local prev_line + prev_line="$(printf '%s\n' "$prev" | awk -v k="$key" '$1" "$2==k {print; exit}')" + + local cnt last_act prev_pct prev_cnt prev_act + if [ -n "$prev_line" ]; then + set -- $prev_line + prev_pct="$3" + prev_cnt="$4" + prev_act="$5" + if [ "$pct" = "$prev_pct" ]; then + cnt=$((prev_cnt + 1)) + else + cnt=1 + fi + last_act="$prev_act" + else + cnt=1 + last_act=0 + fi + + if [ "$cnt" -ge "$STALL_ITERS" ]; then + acts="${acts}${res} ${peer} ${pct}"$'\n' + cnt=0 + last_act="$now" + fi + + new_state="${new_state}${res} ${peer} ${pct} ${cnt} ${last_act}"$'\n' + done <<< "$out" + + if [ -n "$acts" ]; then + while IFS= read -r a; do + [ -n "$a" ] || continue + set -- $a + drbd_stall_act "$1" "$2" "$3" + done <<< "$acts" + fi + + printf '%s' "$new_state" | drbd_stall_save_state +} + while true; do # timeout at the start of the loop to give a chance for the fresh linstor-satellite instance to cleanup itself - sleep 30 & + sleep "$INTERVAL_SEC" & pid=$! wait $pid @@ -21,7 +136,7 @@ while true; do # the `/` path could not be a backing file for a loop device, so it's a good indicator of a stuck loop device # TODO describe the issue in more detail # Using the direct /usr/sbin/losetup as the linstor-satellite image has own wrapper in /usr/local - stale_loopbacks=$(/usr/sbin/losetup --json | jq -r '.[][] | select(."back-file" == "/" or ."back-file" == "/ (deleted)").name' ) + stale_loopbacks=$(/usr/sbin/losetup --json | jq -r '.[][] | select(."back-file" == "/" or ."back-file" == "/ (deleted)").name') for stale_device in $stale_loopbacks; do ( echo "Detaching stuck loop device ${stale_device}" set -x @@ -39,4 +154,7 @@ while true; do drbdadm up "${secondary}" || echo "Command failed" ); done + # Detect and fix stalled DRBD resync by switching SyncTarget peer + drbd_fix_stalled_sync || true + done diff --git a/packages/system/linstor/images/piraeus-server/Dockerfile b/packages/system/linstor/images/piraeus-server/Dockerfile new file mode 100644 index 00000000..049a3f47 --- /dev/null +++ b/packages/system/linstor/images/piraeus-server/Dockerfile @@ -0,0 +1,172 @@ +ARG DISTRO=bookworm +ARG LINSTOR_VERSION + +# ------------------------------------------------------------------------------ +# Build linstor-server from source +FROM debian:bookworm AS builder + +ARG LINSTOR_VERSION +ARG VERSION=${LINSTOR_VERSION} +ARG DISTRO + +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update \ + && apt-get -y upgrade \ + && apt-get -y install build-essential git default-jdk-headless python3-all debhelper wget unzip && \ + wget https://services.gradle.org/distributions/gradle-8.9-bin.zip -O /tmp/gradle.zip && \ + unzip -d /opt /tmp/gradle.zip && \ + rm /tmp/gradle.zip && \ + ln -s /opt/gradle-8.9/bin/gradle /usr/local/bin/gradle + +RUN git clone https://github.com/LINBIT/linstor-server.git /linstor-server +WORKDIR /linstor-server +RUN git checkout v${VERSION} + +# Apply patches +COPY patches /patches +RUN git apply /patches/*.diff && \ + git config user.email "build@cozystack.io" && \ + git config user.name "Cozystack Builder" && \ + git add -A && \ + git commit -m "Apply patches" + +# Initialize git submodules +RUN git submodule update --init --recursive || make check-submods + +# Pre-download ALL dependencies before make tarball +# This ensures all transitive dependencies are cached, including optional ones like AWS SDK +RUN ./gradlew getProtoc +RUN ./gradlew generateJava +RUN ./gradlew --no-daemon --gradle-user-home .gradlehome downloadDependencies + +# Manually create tarball without removing caches +# make tarball removes .gradlehome/caches/[0-9]* which deletes dependencies +# So we'll do the steps manually but keep the caches +RUN make check-submods versioninfo gen-java FORCE=1 VERSION=${VERSION} +RUN make server/jar.deps controller/jar.deps satellite/jar.deps jclcrypto/jar.deps FORCE=1 VERSION=${VERSION} +RUN make .filelist FORCE=1 VERSION=${VERSION} PRESERVE_DEBIAN=1 +# Don't remove caches - we need them for offline build +RUN rm -Rf .gradlehome/wrapper .gradlehome/native .gradlehome/.tmp || true +RUN mkdir -p ./libs +RUN make tgz VERSION=${VERSION} + +# Extract tarball and build DEB packages from it +RUN mv linstor-server-${VERSION}.tar.gz /linstor-server_${VERSION}.orig.tar.gz \ + && tar -C / -xvf /linstor-server_${VERSION}.orig.tar.gz + +WORKDIR /linstor-server-${VERSION} +# Verify .gradlehome is present in extracted tarball +RUN test -d .gradlehome && echo ".gradlehome found in tarball" || (echo ".gradlehome not found in tarball!" && exit 1) + +# Build DEB packages from tarball +# Override GRADLE_FLAGS to remove --offline flag, allowing Gradle to download missing dependencies +RUN sed -i 's/GRADLE_FLAGS = --offline/GRADLE_FLAGS =/' debian/rules || true +RUN LD_LIBRARY_PATH='' dpkg-buildpackage -rfakeroot -b -uc + +# Copy built .deb packages to a location accessible from final image +# dpkg-buildpackage creates packages in parent directory +RUN mkdir -p /packages-output && \ + find .. -maxdepth 1 -name "linstor-*.deb" -exec cp {} /packages-output/ \; && \ + test -n "$(ls -A /packages-output)" || (echo "ERROR: No linstor .deb packages found after build." && exit 1) + +# ------------------------------------------------------------------------------ +# Final image +FROM debian:${DISTRO} + +LABEL maintainer="Roland Kammerer " + +ARG LINSTOR_VERSION +ARG DISTRO + +# Copy built .deb packages from builder stage +# dpkg-buildpackage creates packages in parent directory, we copied them to /packages-output +COPY --from=builder /packages-output/ /packages/ + +RUN { echo 'APT::Install-Recommends "false";' ; echo 'APT::Install-Suggests "false";' ; } > /etc/apt/apt.conf.d/99_piraeus + +RUN --mount=type=cache,target=/var/cache,sharing=private \ + --mount=type=cache,target=/var/lib/apt/lists,sharing=private \ + --mount=type=tmpfs,target=/var/log \ + # Install wget first for downloading keyring + apt-get update && apt-get install -y wget ca-certificates && \ + # Enable contrib repos for zfsutils \ + . /etc/os-release && \ + sed -i -r 's/^Components: (.*)$/Components: \1 contrib/' /etc/apt/sources.list.d/debian.sources && \ + echo "deb http://deb.debian.org/debian $VERSION_CODENAME-backports contrib" > /etc/apt/sources.list.d/backports.list && \ + wget https://packages.linbit.com/public/linbit-keyring.deb -O /var/cache/linbit-keyring.deb && \ + dpkg -i /var/cache/linbit-keyring.deb && \ + echo "deb http://packages.linbit.com/public $VERSION_CODENAME misc" > /etc/apt/sources.list.d/linbit.list && \ + apt-get update && \ + # Install useful utilities and general dependencies + apt-get install -y udev drbd-utils jq net-tools iputils-ping iproute2 dnsutils netcat-traditional sysstat curl util-linux && \ + # Install dependencies for optional features \ + apt-get install -y \ + # cryptsetup: luks layer + cryptsetup \ + # e2fsprogs: LINSTOR can create file systems \ + e2fsprogs \ + # lsscsi: exos layer \ + lsscsi \ + # lvm2: manage lvm storage pools \ + lvm2 \ + # multipath-tools: exos layer \ + multipath-tools \ + # nvme-cli: nvme layer + nvme-cli \ + # procps: used by LINSTOR to find orphaned send/receive processes \ + procps \ + # socat: used with thin-send-recv to send snapshots to another LINSTOR cluster + socat \ + # thin-send-recv: used to send/receive snapshots of LVM thin volumes \ + thin-send-recv \ + # xfsprogs: LINSTOR can create file systems; xfs deps \ + xfsprogs \ + # zstd: used with thin-send-recv to send snapshots to another LINSTOR cluster \ + zstd \ + # zfsutils-linux: for zfs storage pools \ + zfsutils-linux/$VERSION_CODENAME-backports \ + && \ + # remove udev, no need for it in the container \ + apt-get remove -y udev && \ + # Install linstor packages from built .deb files and linstor-client from repository + apt-get install -y default-jre-headless python3-all python3-natsort linstor-client \ + && ls packages/*.deb >/dev/null && (dpkg -i packages/*.deb || apt-get install -f -y) \ + && rm -rf /packages \ + && sed -i 's/"-Djdk.tls.acknowledgeCloseNotify=true"//g' /usr/share/linstor-server/bin/Controller \ + && apt-get clean + +# Log directory need to be group writable. OpenShift assigns random UID and GID, without extra RBAC changes we can only influence the GID. +RUN mkdir /var/log/linstor-controller && \ + chown 0:1000 /var/log/linstor-controller && \ + chmod -R 0775 /var/log/linstor-controller && \ + # Ensure we log to files in containers, otherwise SOS reports won't show any logs at all + sed -i 's###' /usr/share/linstor-server/lib/conf/logback.xml + + +RUN lvmconfig --type current --mergedconfig --config 'activation { udev_sync = 0 udev_rules = 0 monitoring = 0 } devices { global_filter = [ "r|^/dev/drbd|" ] obtain_device_list_from_udev = 0}' > /etc/lvm/lvm.conf.new && mv /etc/lvm/lvm.conf.new /etc/lvm/lvm.conf +RUN echo 'global { usage-count no; }' > /etc/drbd.d/global_common.conf + +# controller +EXPOSE 3376/tcp 3377/tcp 3370/tcp 3371/tcp + +# satellite +EXPOSE 3366/tcp 3367/tcp + +RUN wget https://raw.githubusercontent.com/piraeusdatastore/piraeus/refs/heads/master/dockerfiles/piraeus-server/entry.sh -O /usr/bin/piraeus-entry.sh \ + && chmod +x /usr/bin/piraeus-entry.sh + +ARG K8S_AWAIT_ELECTION_VERSION=v0.4.2 +# TARGETARCH is a docker special variable: https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope +ARG TARGETARCH + +RUN wget https://github.com/LINBIT/k8s-await-election/releases/download/${K8S_AWAIT_ELECTION_VERSION}/k8s-await-election-${K8S_AWAIT_ELECTION_VERSION}-linux-${TARGETARCH}.tar.gz -O - | tar -xvz -C /usr/bin/ + +ARG LOSETUP_CONTAINER_VERSION=v1.0.1 +RUN wget "https://github.com/LINBIT/losetup-container/releases/download/${LOSETUP_CONTAINER_VERSION}/losetup-container-$(uname -m)-unknown-linux-gnu.tar.gz" -O - | tar -xvz -C /usr/local/sbin && \ + printf '#!/bin/sh\nLOSETUP_CONTAINER_ORIGINAL_LOSETUP=%s exec /usr/local/sbin/losetup-container "$@"\n' $(command -v losetup) > /usr/local/sbin/losetup && \ + chmod +x /usr/local/sbin/losetup + +RUN wget "https://dl.k8s.io/$(wget -O - https://dl.k8s.io/release/stable.txt)/bin/linux/${TARGETARCH}/kubectl" -O /usr/local/bin/kubectl && chmod +x /usr/local/bin/kubectl + +CMD ["startSatellite"] +ENTRYPOINT ["/usr/bin/k8s-await-election", "/usr/bin/piraeus-entry.sh"] diff --git a/packages/system/linstor/images/piraeus-server/patches/README.md b/packages/system/linstor/images/piraeus-server/patches/README.md new file mode 100644 index 00000000..c219eaf3 --- /dev/null +++ b/packages/system/linstor/images/piraeus-server/patches/README.md @@ -0,0 +1,12 @@ +# LINSTOR Server Patches + +Custom patches for piraeus-server (linstor-server) v1.32.3. + +- **adjust-on-resfile-change.diff** — Use actual device path in res file during toggle-disk; fix LUKS data offset + - Upstream: [#473](https://github.com/LINBIT/linstor-server/pull/473), [#472](https://github.com/LINBIT/linstor-server/pull/472) +- **allow-toggle-disk-retry.diff** — Allow retry and cancellation of failed toggle-disk operations + - Upstream: [#475](https://github.com/LINBIT/linstor-server/pull/475) +- **force-metadata-check-on-disk-add.diff** — Create metadata during toggle-disk from diskless to diskful + - Upstream: [#474](https://github.com/LINBIT/linstor-server/pull/474) +- **skip-adjust-when-device-inaccessible.diff** — Skip DRBD adjust/res file regeneration when child layer device is inaccessible + - Upstream: [#471](https://github.com/LINBIT/linstor-server/pull/471) diff --git a/packages/system/linstor/images/piraeus-server/patches/adjust-on-resfile-change.diff b/packages/system/linstor/images/piraeus-server/patches/adjust-on-resfile-change.diff new file mode 100644 index 00000000..6788efaf --- /dev/null +++ b/packages/system/linstor/images/piraeus-server/patches/adjust-on-resfile-change.diff @@ -0,0 +1,48 @@ +diff --git a/satellite/src/main/java/com/linbit/linstor/layer/drbd/utils/ConfFileBuilder.java b/satellite/src/main/java/com/linbit/linstor/layer/drbd/utils/ConfFileBuilder.java +index 36c52ccf8..c0bb7b967 100644 +--- a/satellite/src/main/java/com/linbit/linstor/layer/drbd/utils/ConfFileBuilder.java ++++ b/satellite/src/main/java/com/linbit/linstor/layer/drbd/utils/ConfFileBuilder.java +@@ -894,12 +894,16 @@ public class ConfFileBuilder + if (((Volume) vlmData.getVolume()).getFlags().isUnset(localAccCtx, Volume.Flags.DELETE)) + { + final String disk; ++ // Check if we're in toggle-disk operation (adding disk to diskless resource) ++ boolean isDiskAdding = vlmData.getVolume().getAbsResource().getStateFlags().isSomeSet( ++ localAccCtx, Resource.Flags.DISK_ADD_REQUESTED, Resource.Flags.DISK_ADDING); + if ((!isPeerRsc && vlmData.getDataDevice() == null) || + (isPeerRsc && + // FIXME: vlmData.getRscLayerObject().getFlags should be used here + vlmData.getVolume().getAbsResource().disklessForDrbdPeers(accCtx) + ) || +- (!isPeerRsc && ++ // For toggle-disk: if dataDevice is set and we're adding disk, use the actual device ++ (!isPeerRsc && !isDiskAdding && + // FIXME: vlmData.getRscLayerObject().getFlags should be used here + vlmData.getVolume().getAbsResource().isDrbdDiskless(accCtx) + ) +diff --git a/satellite/src/main/java/com/linbit/linstor/layer/luks/CryptSetupCommands.java b/satellite/src/main/java/com/linbit/linstor/layer/luks/CryptSetupCommands.java +index 54dd5c19f..018de58cf 100644 +--- a/satellite/src/main/java/com/linbit/linstor/layer/luks/CryptSetupCommands.java ++++ b/satellite/src/main/java/com/linbit/linstor/layer/luks/CryptSetupCommands.java +@@ -34,6 +34,9 @@ public class CryptSetupCommands implements Luks + private static final Version V2_1_0 = new Version(2, 1, 0); + private static final Version V2_0_0 = new Version(2, 0, 0); + private static final String PBDKF_MAX_MEMORY_KIB = "262144"; // 256 MiB ++ // Fixed LUKS2 data offset in 512-byte sectors (16 MiB = 32768 sectors) ++ // This ensures consistent LUKS header size across all nodes regardless of system defaults ++ private static final String LUKS2_DATA_OFFSET_SECTORS = "32768"; + + @SuppressWarnings("unused") + private final ErrorReporter errorReporter; +@@ -78,6 +81,11 @@ public class CryptSetupCommands implements Luks + command.add(CRYPTSETUP); + command.add("-q"); + command.add("luksFormat"); ++ // Always specify explicit offset to ensure consistent LUKS header size across all nodes ++ // Without this, different systems may create LUKS with different header sizes (16MiB vs 32MiB) ++ // which causes "Low.dev. smaller than requested DRBD-dev. size" errors during toggle-disk ++ command.add("--offset"); ++ command.add(LUKS2_DATA_OFFSET_SECTORS); + if (version.greaterOrEqual(V2_0_0)) + { + command.add("--pbkdf-memory"); diff --git a/packages/system/linstor/images/piraeus-server/patches/allow-toggle-disk-retry.diff b/packages/system/linstor/images/piraeus-server/patches/allow-toggle-disk-retry.diff new file mode 100644 index 00000000..4f4f2fc6 --- /dev/null +++ b/packages/system/linstor/images/piraeus-server/patches/allow-toggle-disk-retry.diff @@ -0,0 +1,235 @@ +diff --git a/controller/src/main/java/com/linbit/linstor/core/apicallhandler/controller/CtrlRscToggleDiskApiCallHandler.java b/controller/src/main/java/com/linbit/linstor/core/apicallhandler/controller/CtrlRscToggleDiskApiCallHandler.java +index 1a6f7b7f0..bd447e049 100644 +--- a/controller/src/main/java/com/linbit/linstor/core/apicallhandler/controller/CtrlRscToggleDiskApiCallHandler.java ++++ b/controller/src/main/java/com/linbit/linstor/core/apicallhandler/controller/CtrlRscToggleDiskApiCallHandler.java +@@ -58,7 +58,9 @@ import com.linbit.linstor.stateflags.StateFlags; + import com.linbit.linstor.storage.StorageException; + import com.linbit.linstor.storage.data.adapter.drbd.DrbdRscData; + import com.linbit.linstor.storage.interfaces.categories.resource.AbsRscLayerObject; ++import com.linbit.linstor.storage.interfaces.categories.resource.VlmProviderObject; + import com.linbit.linstor.storage.kinds.DeviceLayerKind; ++import com.linbit.linstor.storage.kinds.DeviceProviderKind; + import com.linbit.linstor.storage.utils.LayerUtils; + import com.linbit.linstor.tasks.AutoDiskfulTask; + import com.linbit.linstor.utils.layer.LayerRscUtils; +@@ -317,21 +319,90 @@ public class CtrlRscToggleDiskApiCallHandler implements CtrlSatelliteConnectionL + + Resource rsc = ctrlApiDataLoader.loadRsc(nodeName, rscName, true); + ++ // Allow retry of the same operation if the previous attempt failed ++ // (the requested flag remains set for retry on reconnection, but we should also allow manual retry) ++ // Also allow cancellation of a failed operation by requesting the opposite operation + if (hasDiskAddRequested(rsc)) + { +- throw new ApiRcException(ApiCallRcImpl.simpleEntry( +- ApiConsts.FAIL_RSC_BUSY, +- "Addition of disk to resource already requested", +- true +- )); ++ if (removeDisk) ++ { ++ // User wants to cancel the failed add-disk operation and go back to diskless ++ // Use the existing disk removal flow to properly cleanup storage on satellite ++ errorReporter.logInfo( ++ "Toggle Disk cancel on %s/%s - cancelling failed DISK_ADD_REQUESTED, reverting to diskless", ++ nodeNameStr, rscNameStr); ++ unmarkDiskAddRequested(rsc); ++ // Also clear DISK_ADDING if it was set ++ unmarkDiskAdding(rsc); ++ ++ // Set storage pool to diskless pool (overwrite the diskful pool that was set) ++ Props rscProps = ctrlPropsHelper.getProps(rsc); ++ rscProps.map().put(ApiConsts.KEY_STOR_POOL_NAME, LinStor.DISKLESS_STOR_POOL_NAME); ++ ++ // Set DISK_REMOVE_REQUESTED to use the existing disk removal flow ++ // This will: ++ // 1. updateAndAdjustDisk sets DISK_REMOVING flag ++ // 2. Satellite sees DISK_REMOVING and deletes LUKS/storage devices ++ // 3. finishOperation rebuilds layer stack as diskless ++ // We keep the existing layer data so satellite can properly cleanup ++ markDiskRemoveRequested(rsc); ++ ++ ctrlTransactionHelper.commit(); ++ ++ // Use existing disk removal flow - this will properly cleanup storage on satellite ++ return Flux ++ .just(ApiCallRcImpl.singleApiCallRc( ++ ApiConsts.MODIFIED, ++ "Cancelling disk addition, reverting to diskless" ++ )) ++ .concatWith(updateAndAdjustDisk(nodeName, rscName, true, toggleIntoTiebreakerRef, context)) ++ .concatWith(ctrlRscDfnApiCallHandler.get().updateProps(rsc.getResourceDefinition())); ++ } ++ // If adding disk and DISK_ADD_REQUESTED is already set, treat as retry ++ // First clean up partially created storage by removing and recreating layer data ++ errorReporter.logInfo( ++ "Toggle Disk retry on %s/%s - DISK_ADD_REQUESTED already set, cleaning up and retrying", ++ nodeNameStr, rscNameStr); ++ ++ // Remove old layer data and recreate to ensure clean state ++ // This forces satellite to delete any partially created storage and start fresh ++ LayerPayload payload = new LayerPayload(); ++ copyDrbdNodeIdIfExists(rsc, payload); ++ List layerList = removeLayerData(rsc); ++ ctrlLayerStackHelper.ensureStackDataExists(rsc, layerList, payload); ++ ++ ctrlTransactionHelper.commit(); ++ return Flux ++ .just(new ApiCallRcImpl()) ++ .concatWith(updateAndAdjustDisk(nodeName, rscName, false, toggleIntoTiebreakerRef, context)) ++ .concatWith(ctrlRscDfnApiCallHandler.get().updateProps(rsc.getResourceDefinition())); + } + if (hasDiskRemoveRequested(rsc)) + { +- throw new ApiRcException(ApiCallRcImpl.simpleEntry( +- ApiConsts.FAIL_RSC_BUSY, +- "Removal of disk from resource already requested", +- true +- )); ++ if (!removeDisk) ++ { ++ // User wants to cancel the failed remove-disk operation ++ errorReporter.logInfo( ++ "Toggle Disk cancel on %s/%s - cancelling failed DISK_REMOVE_REQUESTED", ++ nodeNameStr, rscNameStr); ++ unmarkDiskRemoveRequested(rsc); ++ ctrlTransactionHelper.commit(); ++ return Flux.just( ++ ApiCallRcImpl.singleApiCallRc( ++ ApiConsts.MODIFIED, ++ "Cancelled disk removal request" ++ ) ++ ); ++ } ++ // If removing disk and DISK_REMOVE_REQUESTED is already set, treat as retry ++ errorReporter.logInfo( ++ "Toggle Disk retry on %s/%s - DISK_REMOVE_REQUESTED already set, continuing operation", ++ nodeNameStr, rscNameStr); ++ ctrlTransactionHelper.commit(); ++ return Flux ++ .just(new ApiCallRcImpl()) ++ .concatWith(updateAndAdjustDisk(nodeName, rscName, true, toggleIntoTiebreakerRef, context)) ++ .concatWith(ctrlRscDfnApiCallHandler.get().updateProps(rsc.getResourceDefinition())); + } + + if (!removeDisk && !ctrlVlmCrtApiHelper.isDiskless(rsc)) +@@ -342,17 +413,43 @@ public class CtrlRscToggleDiskApiCallHandler implements CtrlSatelliteConnectionL + true + )); + } ++ ResourceDefinition rscDfn = rsc.getResourceDefinition(); ++ AccessContext peerCtx = peerAccCtx.get(); ++ + if (removeDisk && ctrlVlmCrtApiHelper.isDiskless(rsc)) + { ++ // Resource is marked as diskless - check if it has orphaned storage layers that need cleanup ++ AbsRscLayerObject layerData = getLayerData(peerCtx, rsc); ++ if (layerData != null && (LayerUtils.hasLayer(layerData, DeviceLayerKind.LUKS) || ++ hasNonDisklessStorageLayer(layerData))) ++ { ++ // Resource is marked as diskless but has orphaned storage layers - need cleanup ++ // Use the existing disk removal flow to properly cleanup storage on satellite ++ errorReporter.logInfo( ++ "Toggle Disk cleanup on %s/%s - resource is diskless but has orphaned storage layers, cleaning up", ++ nodeNameStr, rscNameStr); ++ ++ // Set DISK_REMOVE_REQUESTED to use the existing disk removal flow ++ // This will trigger proper satellite cleanup via DISK_REMOVING flag ++ markDiskRemoveRequested(rsc); ++ ++ ctrlTransactionHelper.commit(); ++ ++ // Use existing disk removal flow - this will properly cleanup storage on satellite ++ return Flux ++ .just(ApiCallRcImpl.singleApiCallRc( ++ ApiConsts.MODIFIED, ++ "Cleaning up orphaned storage layers" ++ )) ++ .concatWith(updateAndAdjustDisk(nodeName, rscName, true, toggleIntoTiebreakerRef, context)) ++ .concatWith(ctrlRscDfnApiCallHandler.get().updateProps(rsc.getResourceDefinition())); ++ } + throw new ApiRcException(ApiCallRcImpl.simpleEntry( + ApiConsts.WARN_RSC_ALREADY_DISKLESS, + "Resource already diskless", + true + )); + } +- +- ResourceDefinition rscDfn = rsc.getResourceDefinition(); +- AccessContext peerCtx = peerAccCtx.get(); + if (removeDisk) + { + // Prevent removal of the last disk +@@ -1324,6 +1421,30 @@ public class CtrlRscToggleDiskApiCallHandler implements CtrlSatelliteConnectionL + } + } + ++ private void unmarkDiskAddRequested(Resource rsc) ++ { ++ try ++ { ++ rsc.getStateFlags().disableFlags(apiCtx, Resource.Flags.DISK_ADD_REQUESTED); ++ } ++ catch (AccessDeniedException | DatabaseException exc) ++ { ++ throw new ImplementationError(exc); ++ } ++ } ++ ++ private void unmarkDiskRemoveRequested(Resource rsc) ++ { ++ try ++ { ++ rsc.getStateFlags().disableFlags(apiCtx, Resource.Flags.DISK_REMOVE_REQUESTED); ++ } ++ catch (AccessDeniedException | DatabaseException exc) ++ { ++ throw new ImplementationError(exc); ++ } ++ } ++ + private void markDiskAdded(Resource rscData) + { + try +@@ -1389,6 +1510,41 @@ public class CtrlRscToggleDiskApiCallHandler implements CtrlSatelliteConnectionL + return layerData; + } + ++ /** ++ * Check if the layer stack has a non-diskless STORAGE layer. ++ * This is used to detect orphaned storage layers that need cleanup. ++ */ ++ private boolean hasNonDisklessStorageLayer(AbsRscLayerObject layerDataRef) ++ { ++ boolean hasNonDiskless = false; ++ if (layerDataRef != null) ++ { ++ if (layerDataRef.getLayerKind() == DeviceLayerKind.STORAGE) ++ { ++ for (VlmProviderObject vlmData : layerDataRef.getVlmLayerObjects().values()) ++ { ++ if (vlmData.getProviderKind() != DeviceProviderKind.DISKLESS) ++ { ++ hasNonDiskless = true; ++ break; ++ } ++ } ++ } ++ if (!hasNonDiskless) ++ { ++ for (AbsRscLayerObject child : layerDataRef.getChildren()) ++ { ++ if (hasNonDisklessStorageLayer(child)) ++ { ++ hasNonDiskless = true; ++ break; ++ } ++ } ++ } ++ } ++ return hasNonDiskless; ++ } ++ + private LockGuard createLockGuard() + { + return lockGuardFactory.buildDeferred(LockType.WRITE, LockObj.NODES_MAP, LockObj.RSC_DFN_MAP); diff --git a/packages/system/linstor/images/piraeus-server/patches/force-metadata-check-on-disk-add.diff b/packages/system/linstor/images/piraeus-server/patches/force-metadata-check-on-disk-add.diff new file mode 100644 index 00000000..0c413005 --- /dev/null +++ b/packages/system/linstor/images/piraeus-server/patches/force-metadata-check-on-disk-add.diff @@ -0,0 +1,63 @@ +diff --git a/satellite/src/main/java/com/linbit/linstor/layer/drbd/DrbdLayer.java b/satellite/src/main/java/com/linbit/linstor/layer/drbd/DrbdLayer.java +index a302ee835..01967a31f 100644 +--- a/satellite/src/main/java/com/linbit/linstor/layer/drbd/DrbdLayer.java ++++ b/satellite/src/main/java/com/linbit/linstor/layer/drbd/DrbdLayer.java +@@ -371,10 +371,13 @@ public class DrbdLayer implements DeviceLayer + boolean isDiskless = drbdRscData.getAbsResource().isDrbdDiskless(workerCtx); + StateFlags rscFlags = drbdRscData.getAbsResource().getStateFlags(); + boolean isDiskRemoving = rscFlags.isSet(workerCtx, Resource.Flags.DISK_REMOVING); ++ // Check if we're in toggle-disk operation (adding disk to diskless resource) ++ boolean isDiskAdding = rscFlags.isSomeSet(workerCtx, Resource.Flags.DISK_ADD_REQUESTED, Resource.Flags.DISK_ADDING); + + boolean contProcess = isDiskless; + +- boolean processChildren = !isDiskless || isDiskRemoving; ++ // Process children when: has disk, removing disk, OR adding disk (toggle-disk) ++ boolean processChildren = !isDiskless || isDiskRemoving || isDiskAdding; + // do not process children when ONLY DRBD_DELETE flag is set (DELETE flag is still unset) + processChildren &= (!rscFlags.isSet(workerCtx, Resource.Flags.DRBD_DELETE) || + rscFlags.isSet(workerCtx, Resource.Flags.DELETE)); +@@ -570,7 +573,11 @@ public class DrbdLayer implements DeviceLayer + { + // hasMetaData needs to be run after child-resource processed + List> createMetaData = new ArrayList<>(); +- if (!drbdRscData.getAbsResource().isDrbdDiskless(workerCtx) && !skipDisk) ++ // Check if we're in toggle-disk operation (adding disk to diskless resource) ++ boolean isDiskAddingForMd = drbdRscData.getAbsResource().getStateFlags() ++ .isSomeSet(workerCtx, Resource.Flags.DISK_ADD_REQUESTED, Resource.Flags.DISK_ADDING); ++ // Create metadata when: has disk OR adding disk (toggle-disk), and skipDisk is disabled ++ if ((!drbdRscData.getAbsResource().isDrbdDiskless(workerCtx) || isDiskAddingForMd) && !skipDisk) + { + // do not try to create meta data while the resource is diskless or skipDisk is enabled + for (DrbdVlmData drbdVlmData : checkMetaData) +@@ -988,8 +995,10 @@ public class DrbdLayer implements DeviceLayer + { + List> checkMetaData = new ArrayList<>(); + Resource rsc = drbdRscData.getAbsResource(); ++ // Include DISK_ADD_REQUESTED/DISK_ADDING for toggle-disk scenario where we need to check/create metadata + if (!rsc.isDrbdDiskless(workerCtx) || +- rsc.getStateFlags().isSet(workerCtx, Resource.Flags.DISK_REMOVING) ++ rsc.getStateFlags().isSet(workerCtx, Resource.Flags.DISK_REMOVING) || ++ rsc.getStateFlags().isSomeSet(workerCtx, Resource.Flags.DISK_ADD_REQUESTED, Resource.Flags.DISK_ADDING) + ) + { + // using a dedicated list to prevent concurrentModificationException +@@ -1177,9 +1186,16 @@ public class DrbdLayer implements DeviceLayer + + boolean hasMetaData; + ++ // Check if we need to verify/create metadata ++ // Force metadata check when: ++ // 1. checkMetaData is enabled ++ // 2. volume doesn't have disk yet (diskless -> diskful transition) ++ // 3. DISK_ADD_REQUESTED/DISK_ADDING flag is set (retry scenario where storage exists but no metadata) ++ boolean isDiskAddingState = drbdVlmData.getRscLayerObject().getAbsResource().getStateFlags() ++ .isSomeSet(workerCtx, Resource.Flags.DISK_ADD_REQUESTED, Resource.Flags.DISK_ADDING); + if (drbdVlmData.checkMetaData() || +- // when adding a disk, DRBD believes that it is diskless but we still need to create metadata +- !drbdVlmData.hasDisk()) ++ !drbdVlmData.hasDisk() || ++ isDiskAddingState) + { + if (mdUtils.hasMetaData()) + { diff --git a/packages/system/linstor/images/piraeus-server/patches/skip-adjust-when-device-inaccessible.diff b/packages/system/linstor/images/piraeus-server/patches/skip-adjust-when-device-inaccessible.diff new file mode 100644 index 00000000..09e7ccf9 --- /dev/null +++ b/packages/system/linstor/images/piraeus-server/patches/skip-adjust-when-device-inaccessible.diff @@ -0,0 +1,93 @@ +diff --git a/satellite/src/main/java/com/linbit/linstor/layer/drbd/DrbdLayer.java b/satellite/src/main/java/com/linbit/linstor/layer/drbd/DrbdLayer.java +index 01967a3..871d830 100644 +--- a/satellite/src/main/java/com/linbit/linstor/layer/drbd/DrbdLayer.java ++++ b/satellite/src/main/java/com/linbit/linstor/layer/drbd/DrbdLayer.java +@@ -592,7 +592,29 @@ public class DrbdLayer implements DeviceLayer + // The .res file might not have been generated in the prepare method since it was + // missing information from the child-layers. Now that we have processed them, we + // need to make sure the .res file exists in all circumstances. +- regenerateResFile(drbdRscData); ++ // However, if the underlying devices are not accessible (e.g., LUKS device is closed ++ // during resource deletion), we skip regenerating the res file to avoid errors ++ boolean canRegenerateResFile = true; ++ if (!skipDisk && !drbdRscData.getAbsResource().isDrbdDiskless(workerCtx)) ++ { ++ AbsRscLayerObject dataChild = drbdRscData.getChildBySuffix(RscLayerSuffixes.SUFFIX_DATA); ++ if (dataChild != null) ++ { ++ for (DrbdVlmData drbdVlmData : drbdRscData.getVlmLayerObjects().values()) ++ { ++ VlmProviderObject childVlm = dataChild.getVlmProviderObject(drbdVlmData.getVlmNr()); ++ if (childVlm == null || !childVlm.exists() || childVlm.getDevicePath() == null) ++ { ++ canRegenerateResFile = false; ++ break; ++ } ++ } ++ } ++ } ++ if (canRegenerateResFile) ++ { ++ regenerateResFile(drbdRscData); ++ } + + // createMetaData needs rendered resFile + for (DrbdVlmData drbdVlmData : createMetaData) +@@ -766,19 +788,47 @@ public class DrbdLayer implements DeviceLayer + + if (drbdRscData.isAdjustRequired()) + { +- try ++ // Check if underlying devices are accessible before adjusting ++ // This is important for encrypted resources (LUKS) where the device ++ // might be closed during deletion ++ boolean canAdjust = true; ++ if (!skipDisk && !drbdRscData.getAbsResource().isDrbdDiskless(workerCtx)) + { +- drbdUtils.adjust( +- drbdRscData, +- false, +- skipDisk, +- false +- ); ++ AbsRscLayerObject dataChild = drbdRscData.getChildBySuffix(RscLayerSuffixes.SUFFIX_DATA); ++ if (dataChild != null) ++ { ++ for (DrbdVlmData drbdVlmData : drbdRscData.getVlmLayerObjects().values()) ++ { ++ VlmProviderObject childVlm = dataChild.getVlmProviderObject(drbdVlmData.getVlmNr()); ++ if (childVlm == null || !childVlm.exists() || childVlm.getDevicePath() == null) ++ { ++ canAdjust = false; ++ break; ++ } ++ } ++ } + } +- catch (ExtCmdFailedException extCmdExc) ++ ++ if (canAdjust) ++ { ++ try ++ { ++ drbdUtils.adjust( ++ drbdRscData, ++ false, ++ skipDisk, ++ false ++ ); ++ } ++ catch (ExtCmdFailedException extCmdExc) ++ { ++ restoreBackupResFile(drbdRscData); ++ throw extCmdExc; ++ } ++ } ++ else + { +- restoreBackupResFile(drbdRscData); +- throw extCmdExc; ++ drbdRscData.setAdjustRequired(false); + } + } + diff --git a/packages/system/linstor/templates/_helpers.tpl b/packages/system/linstor/templates/_helpers.tpl deleted file mode 100644 index 20d43863..00000000 --- a/packages/system/linstor/templates/_helpers.tpl +++ /dev/null @@ -1,24 +0,0 @@ -{{- define "cozy.linstor.version" -}} -{{- $piraeusConfigMap := lookup "v1" "ConfigMap" "cozy-linstor" "piraeus-operator-image-config"}} -{{- if not $piraeusConfigMap }} - {{- fail "Piraeus controller is not yet installed, ConfigMap cozy-linstor/piraeus-operator-image-config is missing" }} -{{- end }} -{{- $piraeusImagesConfig := $piraeusConfigMap | dig "data" "0_piraeus_datastore_images.yaml" nil | required "No image config" | fromYaml }} -base: {{ $piraeusImagesConfig.base | required "No image base in piraeus config" }} -controller: - image: {{ $piraeusImagesConfig | dig "components" "linstor-controller" "image" nil | required "No controller image" }} - tag: {{ $piraeusImagesConfig | dig "components" "linstor-controller" "tag" nil | required "No controller tag" }} -satellite: - image: {{ $piraeusImagesConfig | dig "components" "linstor-satellite" "image" nil | required "No satellite image" }} - tag: {{ $piraeusImagesConfig | dig "components" "linstor-satellite" "tag" nil | required "No satellite tag" }} -{{- end -}} - -{{- define "cozy.linstor.version.controller" -}} -{{- $version := (include "cozy.linstor.version" .) | fromYaml }} -{{- printf "%s/%s:%s" $version.base $version.controller.image $version.controller.tag }} -{{- end -}} - -{{- define "cozy.linstor.version.satellite" -}} -{{- $version := (include "cozy.linstor.version" .) | fromYaml }} -{{- printf "%s/%s:%s" $version.base $version.satellite.image $version.satellite.tag }} -{{- end -}} diff --git a/packages/system/linstor/templates/cluster.yaml b/packages/system/linstor/templates/cluster.yaml index 68af90fd..584fd850 100644 --- a/packages/system/linstor/templates/cluster.yaml +++ b/packages/system/linstor/templates/cluster.yaml @@ -27,8 +27,10 @@ spec: podTemplate: spec: containers: + - name: linstor-controller + image: {{ .Values.piraeusServer.image.repository }}:{{ .Values.piraeusServer.image.tag }} - name: plunger - image: {{ include "cozy.linstor.version.controller" . }} + image: {{ .Values.piraeusServer.image.repository }}:{{ .Values.piraeusServer.image.tag }} command: - "/scripts/plunger-controller.sh" securityContext: diff --git a/packages/system/linstor/templates/satellites-cozy.yaml b/packages/system/linstor/templates/satellites-cozy.yaml index a4c1baa7..c621126d 100644 --- a/packages/system/linstor/templates/satellites-cozy.yaml +++ b/packages/system/linstor/templates/satellites-cozy.yaml @@ -13,6 +13,7 @@ spec: hostNetwork: true containers: - name: linstor-satellite + image: {{ .Values.piraeusServer.image.repository }}:{{ .Values.piraeusServer.image.tag }} securityContext: # real-world installations need some debugging from time to time readOnlyRootFilesystem: false diff --git a/packages/system/linstor/templates/satellites-plunger.yaml b/packages/system/linstor/templates/satellites-plunger.yaml index e3cfa3b1..ab71298b 100644 --- a/packages/system/linstor/templates/satellites-plunger.yaml +++ b/packages/system/linstor/templates/satellites-plunger.yaml @@ -11,7 +11,7 @@ spec: spec: containers: - name: plunger - image: {{ include "cozy.linstor.version.satellite" . }} + image: {{ .Values.piraeusServer.image.repository }}:{{ .Values.piraeusServer.image.tag }} command: - "/scripts/plunger-satellite.sh" securityContext: @@ -48,7 +48,7 @@ spec: name: script-volume readOnly: true - name: drbd-logger - image: {{ include "cozy.linstor.version.satellite" . }} + image: {{ .Values.piraeusServer.image.repository }}:{{ .Values.piraeusServer.image.tag }} command: - "/scripts/plunger-drbd-logger.sh" securityContext: diff --git a/packages/system/linstor/values.yaml b/packages/system/linstor/values.yaml index 8b137891..23179bce 100644 --- a/packages/system/linstor/values.yaml +++ b/packages/system/linstor/values.yaml @@ -1 +1,4 @@ - +piraeusServer: + image: + repository: ghcr.io/cozystack/cozystack/piraeus-server + tag: latest@sha256:417532baa2801288147cd9ac9ae260751c1a7754f0b829725d09b72a770c111a From 0aee5b4dfa2ac65f6193393124e02e37b31efdd9 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Wed, 7 Jan 2026 13:27:06 +0100 Subject: [PATCH 28/43] fix(linstor): prevent orphaned DRBD devices during toggle-disk retry The previous retry logic in toggle-disk removed layer data from controller DB and recreated it. However, removeLayerData() only deletes from the database without calling drbdadm down on the satellite, leaving orphaned DRBD devices in the kernel that occupy ports and block new operations. This fix changes retry to simply repeat the operation with existing layer data, allowing the satellite to handle it idempotently. Upstream: https://github.com/LINBIT/linstor-server/pull/475 Co-Authored-By: Claude Signed-off-by: Andrei Kvapil (cherry picked from commit 8151e1e41a9b2b7e28ce128fdd6c258c6453a505) --- .../patches/allow-toggle-disk-retry.diff | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/packages/system/linstor/images/piraeus-server/patches/allow-toggle-disk-retry.diff b/packages/system/linstor/images/piraeus-server/patches/allow-toggle-disk-retry.diff index 4f4f2fc6..264e0221 100644 --- a/packages/system/linstor/images/piraeus-server/patches/allow-toggle-disk-retry.diff +++ b/packages/system/linstor/images/piraeus-server/patches/allow-toggle-disk-retry.diff @@ -1,8 +1,8 @@ diff --git a/controller/src/main/java/com/linbit/linstor/core/apicallhandler/controller/CtrlRscToggleDiskApiCallHandler.java b/controller/src/main/java/com/linbit/linstor/core/apicallhandler/controller/CtrlRscToggleDiskApiCallHandler.java -index 1a6f7b7f0..bd447e049 100644 +index d93a18014..cc8ce4f04 100644 --- a/controller/src/main/java/com/linbit/linstor/core/apicallhandler/controller/CtrlRscToggleDiskApiCallHandler.java +++ b/controller/src/main/java/com/linbit/linstor/core/apicallhandler/controller/CtrlRscToggleDiskApiCallHandler.java -@@ -58,7 +58,9 @@ import com.linbit.linstor.stateflags.StateFlags; +@@ -57,7 +57,9 @@ import com.linbit.linstor.stateflags.StateFlags; import com.linbit.linstor.storage.StorageException; import com.linbit.linstor.storage.data.adapter.drbd.DrbdRscData; import com.linbit.linstor.storage.interfaces.categories.resource.AbsRscLayerObject; @@ -12,7 +12,7 @@ index 1a6f7b7f0..bd447e049 100644 import com.linbit.linstor.storage.utils.LayerUtils; import com.linbit.linstor.tasks.AutoDiskfulTask; import com.linbit.linstor.utils.layer.LayerRscUtils; -@@ -317,21 +319,90 @@ public class CtrlRscToggleDiskApiCallHandler implements CtrlSatelliteConnectionL +@@ -387,21 +389,84 @@ public class CtrlRscToggleDiskApiCallHandler implements CtrlSatelliteConnectionL Resource rsc = ctrlApiDataLoader.loadRsc(nodeName, rscName, true); @@ -61,18 +61,12 @@ index 1a6f7b7f0..bd447e049 100644 + .concatWith(ctrlRscDfnApiCallHandler.get().updateProps(rsc.getResourceDefinition())); + } + // If adding disk and DISK_ADD_REQUESTED is already set, treat as retry -+ // First clean up partially created storage by removing and recreating layer data ++ // Simply retry the operation with existing layer data - satellite will handle it idempotently ++ // NOTE: We don't remove/recreate layer data here because removeLayerData() only deletes ++ // from controller DB without calling drbdadm down on satellite, leaving orphaned DRBD devices + errorReporter.logInfo( -+ "Toggle Disk retry on %s/%s - DISK_ADD_REQUESTED already set, cleaning up and retrying", ++ "Toggle Disk retry on %s/%s - DISK_ADD_REQUESTED already set, retrying operation", + nodeNameStr, rscNameStr); -+ -+ // Remove old layer data and recreate to ensure clean state -+ // This forces satellite to delete any partially created storage and start fresh -+ LayerPayload payload = new LayerPayload(); -+ copyDrbdNodeIdIfExists(rsc, payload); -+ List layerList = removeLayerData(rsc); -+ ctrlLayerStackHelper.ensureStackDataExists(rsc, layerList, payload); -+ + ctrlTransactionHelper.commit(); + return Flux + .just(new ApiCallRcImpl()) @@ -113,7 +107,7 @@ index 1a6f7b7f0..bd447e049 100644 } if (!removeDisk && !ctrlVlmCrtApiHelper.isDiskless(rsc)) -@@ -342,17 +413,43 @@ public class CtrlRscToggleDiskApiCallHandler implements CtrlSatelliteConnectionL +@@ -412,17 +477,43 @@ public class CtrlRscToggleDiskApiCallHandler implements CtrlSatelliteConnectionL true )); } @@ -160,7 +154,7 @@ index 1a6f7b7f0..bd447e049 100644 if (removeDisk) { // Prevent removal of the last disk -@@ -1324,6 +1421,30 @@ public class CtrlRscToggleDiskApiCallHandler implements CtrlSatelliteConnectionL +@@ -1446,6 +1537,30 @@ public class CtrlRscToggleDiskApiCallHandler implements CtrlSatelliteConnectionL } } @@ -191,7 +185,7 @@ index 1a6f7b7f0..bd447e049 100644 private void markDiskAdded(Resource rscData) { try -@@ -1389,6 +1510,41 @@ public class CtrlRscToggleDiskApiCallHandler implements CtrlSatelliteConnectionL +@@ -1511,6 +1626,41 @@ public class CtrlRscToggleDiskApiCallHandler implements CtrlSatelliteConnectionL return layerData; } From 8c8ab1f1a0c2287796eebcfb2ab2588351ea880b Mon Sep 17 00:00:00 2001 From: nbykov0 <166552198+nbykov0@users.noreply.github.com> Date: Wed, 31 Dec 2025 16:33:00 +0300 Subject: [PATCH 29/43] [lineage-webhook] Tolerate all taints Signed-off-by: nbykov0 <166552198+nbykov0@users.noreply.github.com> (cherry picked from commit aa66b8c0d3a71e60905cf1637d992650e94b88ab) --- .../lineage-controller-webhook/templates/daemonset.yaml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/system/lineage-controller-webhook/templates/daemonset.yaml b/packages/system/lineage-controller-webhook/templates/daemonset.yaml index 22074e1d..b6b73ac7 100644 --- a/packages/system/lineage-controller-webhook/templates/daemonset.yaml +++ b/packages/system/lineage-controller-webhook/templates/daemonset.yaml @@ -16,12 +16,7 @@ spec: nodeSelector: node-role.kubernetes.io/control-plane: "" tolerations: - - key: "node-role.kubernetes.io/control-plane" - operator: "Exists" - effect: "NoSchedule" - - key: "node-role.kubernetes.io/master" - operator: "Exists" - effect: "NoSchedule" + - operator: Exists serviceAccountName: lineage-controller-webhook containers: - name: lineage-controller-webhook From 363c8cf0669efe6c08bf32da13dca3898f0342a4 Mon Sep 17 00:00:00 2001 From: nbykov0 <166552198+nbykov0@users.noreply.github.com> Date: Wed, 31 Dec 2025 16:33:21 +0300 Subject: [PATCH 30/43] [cozystack-api] Tolerate all taints Signed-off-by: nbykov0 <166552198+nbykov0@users.noreply.github.com> (cherry picked from commit 4e602fd55d9f50c1c9d9d7c89175f362eafb7bd2) --- packages/system/cozystack-api/templates/deployment.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/system/cozystack-api/templates/deployment.yaml b/packages/system/cozystack-api/templates/deployment.yaml index 1a63a0e0..ee7e532f 100644 --- a/packages/system/cozystack-api/templates/deployment.yaml +++ b/packages/system/cozystack-api/templates/deployment.yaml @@ -21,6 +21,8 @@ spec: labels: app: cozystack-api spec: + tolerations: + - operator: Exists serviceAccountName: cozystack-api {{- if .Values.cozystackAPI.localK8sAPIEndpoint.enabled }} nodeSelector: From 25f31022f0ab67c4b9786f526441c41f377e72f0 Mon Sep 17 00:00:00 2001 From: nbykov0 <166552198+nbykov0@users.noreply.github.com> Date: Tue, 23 Dec 2025 23:11:19 +0300 Subject: [PATCH 31/43] [ingress] Add topology anti-affinities Signed-off-by: nbykov0 <166552198+nbykov0@users.noreply.github.com> (cherry picked from commit 6ca8011dfa85302d96372e8f7176ffdd41a30d77) --- packages/system/ingress-nginx/values.yaml | 38 ++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/packages/system/ingress-nginx/values.yaml b/packages/system/ingress-nginx/values.yaml index 5571ff37..68436f51 100644 --- a/packages/system/ingress-nginx/values.yaml +++ b/packages/system/ingress-nginx/values.yaml @@ -54,9 +54,45 @@ ingress-nginx: requests: cpu: 100m memory: 90Mi + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 10 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - '{{ include "ingress-nginx.name" . }}' + - key: app.kubernetes.io/instance + operator: In + values: + - '{{ .Release.Name }}' + - key: app.kubernetes.io/component + operator: In + values: + - controller + topologyKey: kubernetes.io/hostname + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - '{{ include "ingress-nginx.name" . }}' + - key: app.kubernetes.io/instance + operator: In + values: + - '{{ .Release.Name }}' + - key: app.kubernetes.io/component + operator: In + values: + - controller + topologyKey: topology.kubernetes.io/zone defaultBackend: - ## enabled: true resources: limits: From 48ebe418b26231dba90da75126244e2fc4681ae8 Mon Sep 17 00:00:00 2001 From: nbykov0 <166552198+nbykov0@users.noreply.github.com> Date: Tue, 23 Dec 2025 23:12:21 +0300 Subject: [PATCH 32/43] [seaweedfs] Traffic locality for seaweedfs Signed-off-by: nbykov0 <166552198+nbykov0@users.noreply.github.com> (cherry picked from commit 2a8a8a480f57a2cadc0c8524782124ad3fea91e0) --- packages/system/seaweedfs/Makefile | 1 + .../seaweedfs/templates/s3/s3-service.yaml | 1 + .../patches/s3-traffic-distribution.patch | 12 ++++ packages/system/seaweedfs/values.yaml | 71 ++++++++++++++++--- 4 files changed, 76 insertions(+), 9 deletions(-) create mode 100644 packages/system/seaweedfs/patches/s3-traffic-distribution.patch diff --git a/packages/system/seaweedfs/Makefile b/packages/system/seaweedfs/Makefile index 9d1f47cd..43f4053b 100644 --- a/packages/system/seaweedfs/Makefile +++ b/packages/system/seaweedfs/Makefile @@ -12,6 +12,7 @@ update: sed -i.bak "/ARG VERSION/ s|=.*|=$${version}|g" images/seaweedfs/Dockerfile && \ rm -f images/seaweedfs/Dockerfile.bak patch --no-backup-if-mismatch -p4 < patches/resize-api-server-annotation.diff + patch --no-backup-if-mismatch -p4 < patches/s3-traffic-distribution.patch #patch --no-backup-if-mismatch -p4 < patches/retention-policy-delete.yaml image: diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-service.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-service.yaml index 8afd4865..86e0424e 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-service.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-service.yaml @@ -14,6 +14,7 @@ metadata: {{- toYaml .Values.s3.annotations | nindent 4 }} {{- end }} spec: + trafficDistribution: PreferClose internalTrafficPolicy: {{ .Values.s3.internalTrafficPolicy | default "Cluster" }} ports: - name: "swfs-s3" diff --git a/packages/system/seaweedfs/patches/s3-traffic-distribution.patch b/packages/system/seaweedfs/patches/s3-traffic-distribution.patch new file mode 100644 index 00000000..93c72384 --- /dev/null +++ b/packages/system/seaweedfs/patches/s3-traffic-distribution.patch @@ -0,0 +1,12 @@ +diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-service.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-service.yaml +index 8afd4865..86e0424e 100644 +--- a/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-service.yaml ++++ b/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-service.yaml +@@ -14,6 +14,7 @@ metadata: + {{- toYaml .Values.s3.annotations | nindent 4 }} + {{- end }} + spec: ++ trafficDistribution: PreferClose + internalTrafficPolicy: {{ .Values.s3.internalTrafficPolicy | default "Cluster" }} + ports: + - name: "swfs-s3" diff --git a/packages/system/seaweedfs/values.yaml b/packages/system/seaweedfs/values.yaml index 569493c3..c49b2252 100644 --- a/packages/system/seaweedfs/values.yaml +++ b/packages/system/seaweedfs/values.yaml @@ -1,16 +1,12 @@ global: enableSecurity: true serviceAccountName: "tenant-foo-seaweedfs" - imageName: "seaweedfs" extraEnvironmentVars: WEED_CLUSTER_SW_MASTER: "seaweedfs-master:9333" WEED_CLUSTER_SW_FILER: "seaweedfs-filer-client:8888" monitoring: enabled: true seaweedfs: - image: - tag: "latest@sha256:944e9bff98b088773847270238b63ce57dc5291054814d08e0226a139b3affb2" - registry: ghcr.io/cozystack/cozystack master: volumeSizeLimitMB: 30000 replicas: 3 @@ -75,7 +71,7 @@ seaweedfs: name: seaweedfs-db-app s3: replicas: 2 - enabled: true + enabled: false port: 8333 httpsPort: 0 # Suffix of the host name, {bucket}.{domainName} @@ -87,20 +83,24 @@ seaweedfs: existingConfigSecret: null auditLogConfig: {} s3: - enabled: false + enabled: true + replicas: 2 + port: 8333 extraArgs: - -idleTimeout=60 enableAuth: false readinessProbe: - scheme: HTTPS + httpGet: + scheme: HTTPS livenessProbe: - scheme: HTTPS + httpGet: + scheme: HTTPS logs: type: "" ingress: enabled: true className: "tenant-root" - host: "seaweedfs2.demo.cozystack.io" + host: "seaweedfs.demo.cozystack.io" annotations: nginx.ingress.kubernetes.io/proxy-body-size: "0" nginx.ingress.kubernetes.io/proxy-buffering: "off" @@ -110,12 +110,65 @@ seaweedfs: nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" nginx.ingress.kubernetes.io/client-body-timeout: "3600" nginx.ingress.kubernetes.io/client-header-timeout: "120" + nginx.ingress.kubernetes.io/service-upstream: "true" acme.cert-manager.io/http01-ingress-class: tenant-root cert-manager.io/cluster-issuer: letsencrypt-prod tls: - hosts: - seaweedfs.demo.cozystack.io secretName: seaweedfs-s3-ingress-tls + affinity: | + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 10 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - '{{ template "seaweedfs.name" . }}' + - key: app.kubernetes.io/instance + operator: In + values: + - '{{ .Release.Name }}' + - key: app.kubernetes.io/component + operator: In + values: + - s3 + topologyKey: kubernetes.io/hostname + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - '{{ template "seaweedfs.name" . }}' + - key: app.kubernetes.io/instance + operator: In + values: + - '{{ .Release.Name }}' + - key: app.kubernetes.io/component + operator: In + values: + - s3 + topologyKey: topology.kubernetes.io/zone + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 20 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - ingress-nginx + - key: app.kubernetes.io/component + operator: In + values: + - controller + topologyKey: kubernetes.io/hostname cosi: enabled: true podLabels: From 765cffdc6612f5c41d906a5580ab18499f3c465a Mon Sep 17 00:00:00 2001 From: nbykov0 <166552198+nbykov0@users.noreply.github.com> Date: Mon, 5 Jan 2026 17:24:16 +0300 Subject: [PATCH 33/43] [seaweed] Update to 4.05 Signed-off-by: nbykov0 <166552198+nbykov0@users.noreply.github.com> (cherry picked from commit aede1b9217e9a346c025add2ac98276264dbbd6c) --- .../seaweedfs/charts/seaweedfs/Chart.yaml | 4 +- .../seaweedfs/charts/seaweedfs/README.md | 185 ++++++++++ .../seaweedfs-grafana-dashboard.json | 304 ++++++++++++++- .../templates/admin/admin-ingress.yaml | 52 +++ .../templates/admin/admin-secret.yaml | 20 + .../templates/admin/admin-service.yaml | 39 ++ .../templates/admin/admin-servicemonitor.yaml | 33 ++ .../templates/admin/admin-statefulset.yaml | 345 ++++++++++++++++++ .../seaweedfs/templates/cert/admin-cert.yaml | 43 +++ .../seaweedfs/templates/cert/worker-cert.yaml | 43 +++ .../templates/filer/filer-statefulset.yaml | 2 +- .../templates/master/master-statefulset.yaml | 2 +- .../seaweedfs/templates/s3/s3-ingress.yaml | 28 +- .../seaweedfs/templates/shared/_helpers.tpl | 54 +++ .../templates/shared/security-configmap.yaml | 8 + .../templates/volume/volume-statefulset.yaml | 5 +- .../templates/worker/worker-deployment.yaml | 288 +++++++++++++++ .../templates/worker/worker-service.yaml | 26 ++ .../worker/worker-servicemonitor.yaml | 33 ++ .../seaweedfs/charts/seaweedfs/values.yaml | 247 ++++++++++++- 20 files changed, 1750 insertions(+), 11 deletions(-) create mode 100644 packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-ingress.yaml create mode 100644 packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-secret.yaml create mode 100644 packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-service.yaml create mode 100644 packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml create mode 100644 packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-statefulset.yaml create mode 100644 packages/system/seaweedfs/charts/seaweedfs/templates/cert/admin-cert.yaml create mode 100644 packages/system/seaweedfs/charts/seaweedfs/templates/cert/worker-cert.yaml create mode 100644 packages/system/seaweedfs/charts/seaweedfs/templates/worker/worker-deployment.yaml create mode 100644 packages/system/seaweedfs/charts/seaweedfs/templates/worker/worker-service.yaml create mode 100644 packages/system/seaweedfs/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml diff --git a/packages/system/seaweedfs/charts/seaweedfs/Chart.yaml b/packages/system/seaweedfs/charts/seaweedfs/Chart.yaml index 6ea31115..107149cf 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/Chart.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 description: SeaweedFS name: seaweedfs -appVersion: "4.02" +appVersion: "4.05" # Dev note: Trigger a helm chart release by `git tag -a helm-` -version: 4.0.402 +version: 4.0.405 diff --git a/packages/system/seaweedfs/charts/seaweedfs/README.md b/packages/system/seaweedfs/charts/seaweedfs/README.md index 30885aee..7f27cb22 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/README.md +++ b/packages/system/seaweedfs/charts/seaweedfs/README.md @@ -145,6 +145,191 @@ stringData: seaweedfs_s3_config: '{"identities":[{"name":"anvAdmin","credentials":[{"accessKey":"snu8yoP6QAlY0ne4","secretKey":"PNzBcmeLNEdR0oviwm04NQAicOrDH1Km"}],"actions":["Admin","Read","Write"]},{"name":"anvReadOnly","credentials":[{"accessKey":"SCigFee6c5lbi04A","secretKey":"kgFhbT38R8WUYVtiFQ1OiSVOrYr3NKku"}],"actions":["Read"]}]}' ``` +## Admin Component + +The admin component provides a modern web-based administration interface for managing SeaweedFS clusters. It includes: + +- **Dashboard**: Real-time cluster status and metrics +- **Volume Management**: Monitor volume servers, capacity, and health +- **File Browser**: Browse and manage files in the filer +- **Maintenance Operations**: Trigger maintenance tasks via workers +- **Object Store Management**: Create and manage buckets with web interface + +### Enabling Admin + +To enable the admin interface, add the following to your values.yaml: + +```yaml +admin: + enabled: true + port: 23646 + grpcPort: 33646 # For worker connections + adminUser: "admin" + adminPassword: "your-secure-password" # Leave empty to disable auth + + # Optional: persist admin data + data: + type: "persistentVolumeClaim" + size: "10Gi" + storageClass: "your-storage-class" + + # Optional: enable ingress + ingress: + enabled: true + host: "admin.seaweedfs.local" + className: "nginx" +``` + +The admin interface will be available at `http://:23646` (or via ingress). Workers connect to the admin server via gRPC on port `33646`. + +### Admin Authentication + +If `adminPassword` is set, the admin interface requires authentication: +- Username: Value of `adminUser` (default: `admin`) +- Password: Value of `adminPassword` + +If `adminPassword` is empty or not set, the admin interface runs without authentication (not recommended for production). + +### Admin Data Persistence + +The admin component can store configuration and maintenance data. You can configure storage in several ways: + +- **emptyDir** (default): Data is lost when pod restarts +- **persistentVolumeClaim**: Data persists across pod restarts +- **hostPath**: Data stored on the host filesystem +- **existingClaim**: Use an existing PVC + +## Worker Component + +Workers are maintenance agents that execute cluster maintenance tasks such as vacuum, volume balancing, and erasure coding. Workers connect to the admin server via gRPC and receive task assignments. + +### Enabling Workers + +To enable workers, add the following to your values.yaml: + +```yaml +worker: + enabled: true + replicas: 2 # Scale based on workload + capabilities: "vacuum,balance,erasure_coding" # Tasks this worker can handle + maxConcurrent: 3 # Maximum concurrent tasks per worker + + # Working directory for task execution + # Default: "/tmp/seaweedfs-worker" + # Note: /tmp is ephemeral - use persistent storage (hostPath/existingClaim) for long-running tasks + workingDir: "/tmp/seaweedfs-worker" + + # Optional: configure admin server address + # If not specified, auto-discovers from admin service in the same namespace by looking for + # a service named "-admin" (e.g., "seaweedfs-admin"). + # Auto-discovery only works if the admin is in the same namespace and same Helm release. + # For cross-namespace or separate release scenarios, explicitly set this value. + # Example: If main SeaweedFS is deployed in "production" namespace: + # adminServer: "seaweedfs-admin.production.svc:33646" + adminServer: "" + + # Workers need storage for task execution + # Note: Workers use a Deployment, which does not support `volumeClaimTemplates` + # for dynamic PVC creation per pod. To use persistent storage, you must + # pre-provision a PersistentVolumeClaim and use `type: "existingClaim"`. + data: + type: "emptyDir" # Options: "emptyDir", "hostPath", or "existingClaim" + hostPathPrefix: /storage # For hostPath + # claimName: "worker-pvc" # For existingClaim with pre-provisioned PVC + + # Resource limits for worker pods + resources: + requests: + cpu: "500m" + memory: "512Mi" + limits: + cpu: "2" + memory: "2Gi" +``` + +### Worker Capabilities + +Workers can be configured with different capabilities: +- **vacuum**: Reclaim deleted file space +- **balance**: Balance volumes across volume servers +- **erasure_coding**: Handle erasure coding operations + +You can configure workers with all capabilities or create specialized worker pools with specific capabilities. + +### Worker Deployment Strategy + +For production deployments, consider: + +1. **Multiple Workers**: Deploy 2+ worker replicas for high availability +2. **Resource Allocation**: Workers need sufficient CPU/memory for maintenance tasks +3. **Storage**: Workers need temporary storage for vacuum and balance operations (size depends on volume size) +4. **Specialized Workers**: Create separate worker deployments for different capabilities if needed + +Example specialized worker configuration: + +For specialized worker pools, deploy separate Helm releases with different capabilities: + +**values-worker-vacuum.yaml** (for vacuum operations): +```yaml +# Disable all other components, enable only workers +master: + enabled: false +volume: + enabled: false +filer: + enabled: false +s3: + enabled: false +admin: + enabled: false + +worker: + enabled: true + replicas: 2 + capabilities: "vacuum" + maxConcurrent: 2 + # REQUIRED: Point to the admin service of your main SeaweedFS release + # Replace with the namespace where your main seaweedfs is deployed + # Example: If deploying in namespace "production": + # adminServer: "seaweedfs-admin.production.svc:33646" + adminServer: "seaweedfs-admin..svc:33646" +``` + +**values-worker-balance.yaml** (for balance operations): +```yaml +# Disable all other components, enable only workers +master: + enabled: false +volume: + enabled: false +filer: + enabled: false +s3: + enabled: false +admin: + enabled: false + +worker: + enabled: true + replicas: 1 + capabilities: "balance" + maxConcurrent: 1 + # REQUIRED: Point to the admin service of your main SeaweedFS release + # Replace with the namespace where your main seaweedfs is deployed + # Example: If deploying in namespace "production": + # adminServer: "seaweedfs-admin.production.svc:33646" + adminServer: "seaweedfs-admin..svc:33646" +``` + +Deploy the specialized workers as separate releases: +```bash +# Deploy vacuum workers +helm install seaweedfs-worker-vacuum seaweedfs/seaweedfs -f values-worker-vacuum.yaml + +# Deploy balance workers +helm install seaweedfs-worker-balance seaweedfs/seaweedfs -f values-worker-balance.yaml +``` + ## Enterprise For enterprise users, please visit [seaweedfs.com](https://seaweedfs.com) for the SeaweedFS Enterprise Edition, diff --git a/packages/system/seaweedfs/charts/seaweedfs/dashboards/seaweedfs-grafana-dashboard.json b/packages/system/seaweedfs/charts/seaweedfs/dashboards/seaweedfs-grafana-dashboard.json index 30b43f86..ca08b7d0 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/dashboards/seaweedfs-grafana-dashboard.json +++ b/packages/system/seaweedfs/charts/seaweedfs/dashboards/seaweedfs-grafana-dashboard.json @@ -1595,6 +1595,101 @@ "title": "S3 Bucket Traffic Sent", "type": "timeseries" }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "reqps", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 41 + }, + "id": 86, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "expr": "sum(rate(SeaweedFS_s3_request_total{namespace=\"$NAMESPACE\"}[$__interval])) by (bucket)", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{bucket}}", + "refId": "A" + } + ], + "title": "S3 API Calls per Bucket", + "type": "timeseries" + }, { "datasource": { "type": "prometheus", @@ -1659,8 +1754,8 @@ }, "gridPos": { "h": 7, - "w": 24, - "x": 0, + "w": 12, + "x": 12, "y": 41 }, "id": 72, @@ -3266,6 +3361,209 @@ ], "title": "Filer Go Routines", "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 48 + }, + "id": 89, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max(SeaweedFS_s3_bucket_size_bytes{namespace=\"$NAMESPACE\"}) by (bucket)", + "legendFormat": "{{bucket}} (logical)", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max(SeaweedFS_s3_bucket_physical_size_bytes{namespace=\"$NAMESPACE\"}) by (bucket)", + "legendFormat": "{{bucket}} (physical)", + "range": true, + "refId": "B" + } + ], + "title": "S3 Bucket Size", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 48 + }, + "id": 90, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max(SeaweedFS_s3_bucket_object_count{namespace=\"$NAMESPACE\"}) by (bucket)", + "legendFormat": "{{bucket}}", + "range": true, + "refId": "A" + } + ], + "title": "S3 Bucket Object Count", + "type": "timeseries" } ], "refresh": "", @@ -3356,4 +3654,4 @@ "uid": "a24009d7-cbda-4443-a132-1cc1c4677304", "version": 1, "weekStart": "" -} +} \ No newline at end of file diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-ingress.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-ingress.yaml new file mode 100644 index 00000000..216ef8a8 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-ingress.yaml @@ -0,0 +1,52 @@ +{{- if and .Values.admin.enabled .Values.admin.ingress.enabled }} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion }} +apiVersion: networking.k8s.io/v1beta1 +{{- else }} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: ingress-{{ template "seaweedfs.name" . }}-admin + namespace: {{ .Release.Namespace }} + annotations: + {{- if and (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) .Values.admin.ingress.className }} + kubernetes.io/ingress.class: {{ .Values.admin.ingress.className }} + {{- end }} + {{- with .Values.admin.ingress.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: admin +spec: + {{- if and (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) .Values.admin.ingress.className }} + ingressClassName: {{ .Values.admin.ingress.className | quote }} + {{- end }} + tls: + {{ .Values.admin.ingress.tls | default list | toYaml | nindent 6}} + rules: + - {{- if .Values.admin.ingress.host }} + host: {{ .Values.admin.ingress.host | quote }} + {{- end }} + http: + paths: + - path: {{ .Values.admin.ingress.path | quote }} + {{- if semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion }} + pathType: {{ .Values.admin.ingress.pathType | quote }} + {{- end }} + backend: +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }} + service: + name: {{ template "seaweedfs.name" . }}-admin + port: + number: {{ .Values.admin.port }} +{{- else }} + serviceName: {{ template "seaweedfs.name" . }}-admin + servicePort: {{ .Values.admin.port }} +{{- end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-secret.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-secret.yaml new file mode 100644 index 00000000..bc104456 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-secret.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.admin.enabled .Values.admin.secret.adminPassword (not .Values.admin.secret.existingSecret) }} +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: {{ template "seaweedfs.name" . }}-admin-secret + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/resource-policy": keep + "helm.sh/hook": "pre-install,pre-upgrade" + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: admin +data: + adminUser: {{ .Values.admin.secret.adminUser | b64enc }} + adminPassword: {{ .Values.admin.secret.adminPassword | b64enc }} +{{- end}} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-service.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-service.yaml new file mode 100644 index 00000000..825049a4 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-service.yaml @@ -0,0 +1,39 @@ +{{- if .Values.admin.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "seaweedfs.name" . }}-admin + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: admin +{{- if .Values.admin.service.annotations }} + annotations: + {{- toYaml .Values.admin.service.annotations | nindent 4 }} +{{- end }} +spec: + type: {{ .Values.admin.service.type }} + ports: + - name: "http" + port: {{ .Values.admin.port }} + targetPort: {{ .Values.admin.port }} + protocol: TCP + - name: "grpc" + port: {{ .Values.admin.grpcPort }} + targetPort: {{ .Values.admin.grpcPort }} + protocol: TCP + {{- if .Values.admin.metricsPort }} + - name: "metrics" + port: {{ .Values.admin.metricsPort }} + targetPort: {{ .Values.admin.metricsPort }} + protocol: TCP + {{- end }} + selector: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: admin +{{- end }} + diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml new file mode 100644 index 00000000..271197a3 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-servicemonitor.yaml @@ -0,0 +1,33 @@ +{{- if .Values.admin.enabled }} +{{- if .Values.admin.metricsPort }} +{{- if .Values.global.monitoring.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "seaweedfs.name" . }}-admin + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: admin + {{- with .Values.global.monitoring.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- with .Values.admin.serviceMonitor.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +spec: + endpoints: + - interval: 30s + port: metrics + scrapeTimeout: 5s + selector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/component: admin +{{- end }} +{{- end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-statefulset.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-statefulset.yaml new file mode 100644 index 00000000..208f73d1 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/admin/admin-statefulset.yaml @@ -0,0 +1,345 @@ +{{- if .Values.admin.enabled }} +{{- if and (not .Values.admin.masters) (not .Values.global.masterServer) (not .Values.master.enabled) }} +{{- fail "admin.masters or global.masterServer must be set if master.enabled is false" -}} +{{- end }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "seaweedfs.name" . }}-admin + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: admin +{{- if .Values.admin.annotations }} + annotations: + {{- toYaml .Values.admin.annotations | nindent 4 }} +{{- end }} +spec: + serviceName: {{ template "seaweedfs.name" . }}-admin + podManagementPolicy: {{ .Values.admin.podManagementPolicy }} + replicas: {{ .Values.admin.replicas }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: admin + template: + metadata: + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: admin + {{ with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.admin.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{ with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.admin.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + restartPolicy: {{ default .Values.global.restartPolicy .Values.admin.restartPolicy }} + {{- if .Values.admin.affinity }} + affinity: + {{ tpl .Values.admin.affinity . | nindent 8 | trim }} + {{- end }} + {{- if .Values.admin.topologySpreadConstraints }} + topologySpreadConstraints: + {{ tpl .Values.admin.topologySpreadConstraints . | nindent 8 | trim }} + {{- end }} + {{- if .Values.admin.tolerations }} + tolerations: + {{ tpl .Values.admin.tolerations . | nindent 8 | trim }} + {{- end }} + {{- include "seaweedfs.imagePullSecrets" . | nindent 6 }} + terminationGracePeriodSeconds: 30 + {{- if .Values.admin.priorityClassName }} + priorityClassName: {{ .Values.admin.priorityClassName | quote }} + {{- end }} + enableServiceLinks: false + {{- if .Values.admin.serviceAccountName }} + serviceAccountName: {{ .Values.admin.serviceAccountName | quote }} + {{- end }} + {{- if .Values.admin.initContainers }} + initContainers: + {{ tpl .Values.admin.initContainers . | nindent 8 | trim }} + {{- end }} + {{- if .Values.admin.podSecurityContext.enabled }} + securityContext: {{- omit .Values.admin.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + containers: + - name: seaweedfs + image: {{ template "admin.image" . }} + imagePullPolicy: {{ default "IfNotPresent" .Values.global.imagePullPolicy }} + {{- $adminAuthEnabled := or .Values.admin.secret.existingSecret .Values.admin.secret.adminPassword }} + {{- if and .Values.admin.secret.existingSecret (not .Values.admin.secret.userKey) -}} + {{- fail "admin.secret.userKey must be set when admin.secret.existingSecret is provided" -}} + {{- end -}} + {{- if and .Values.admin.secret.existingSecret (not .Values.admin.secret.pwKey) -}} + {{- fail "admin.secret.pwKey must be set when admin.secret.existingSecret is provided" -}} + {{- end -}} + {{- $adminSecretName := .Values.admin.secret.existingSecret | default (printf "%s-admin-secret" (include "seaweedfs.name" .)) }} + env: + {{- if $adminAuthEnabled }} + - name: SEAWEEDFS_ADMIN_USER + valueFrom: + secretKeyRef: + name: {{ $adminSecretName }} + key: {{ if .Values.admin.secret.existingSecret }}{{ .Values.admin.secret.userKey }}{{ else }}adminUser{{ end }} + - name: SEAWEEDFS_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: {{ $adminSecretName }} + key: {{ if .Values.admin.secret.existingSecret }}{{ .Values.admin.secret.pwKey }}{{ else }}adminPassword{{ end }} + {{- end }} + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: SEAWEEDFS_FULLNAME + value: "{{ template "seaweedfs.name" . }}" + {{- if .Values.admin.extraEnvironmentVars }} + {{- range $key, $value := .Values.admin.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + {{- if .Values.global.extraEnvironmentVars }} + {{- range $key, $value := .Values.global.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + exec /usr/bin/weed \ + {{- if or (eq .Values.admin.logs.type "hostPath") (eq .Values.admin.logs.type "persistentVolumeClaim") (eq .Values.admin.logs.type "emptyDir") (eq .Values.admin.logs.type "existingClaim") }} + -logdir=/logs \ + {{- else }} + -logtostderr=true \ + {{- end }} + {{- if .Values.admin.loggingOverrideLevel }} + -v={{ .Values.admin.loggingOverrideLevel }} \ + {{- else }} + -v={{ .Values.global.loggingLevel }} \ + {{- end }} + admin \ + -port={{ .Values.admin.port }} \ + -port.grpc={{ .Values.admin.grpcPort }} \ + {{- if or (eq .Values.admin.data.type "hostPath") (eq .Values.admin.data.type "persistentVolumeClaim") (eq .Values.admin.data.type "emptyDir") (eq .Values.admin.data.type "existingClaim") }} + -dataDir=/data \ + {{- else if .Values.admin.dataDir }} + -dataDir={{ .Values.admin.dataDir }} \ + {{- end }} + {{- if $adminAuthEnabled }} + -adminUser="${SEAWEEDFS_ADMIN_USER}" \ + -adminPassword="${SEAWEEDFS_ADMIN_PASSWORD}" \ + {{- end }} + {{- if .Values.admin.masters }} + -masters={{ .Values.admin.masters }}{{- if .Values.admin.extraArgs }} \{{ end }} + {{- else if .Values.global.masterServer }} + -masters={{ .Values.global.masterServer }}{{- if .Values.admin.extraArgs }} \{{ end }} + {{- else }} + -masters={{ range $index := until (.Values.master.replicas | int) }}${SEAWEEDFS_FULLNAME}-master-{{ $index }}.${SEAWEEDFS_FULLNAME}-master.{{ $.Release.Namespace }}:{{ $.Values.master.port }}{{ if lt $index (sub ($.Values.master.replicas | int) 1) }},{{ end }}{{ end }}{{- if .Values.admin.extraArgs }} \{{ end }} + {{- end }} + {{- range $index, $arg := .Values.admin.extraArgs }} + {{ $arg }}{{- if lt $index (sub (len $.Values.admin.extraArgs) 1) }} \{{ end }} + {{- end }} + volumeMounts: + {{- if or (eq .Values.admin.data.type "hostPath") (eq .Values.admin.data.type "persistentVolumeClaim") (eq .Values.admin.data.type "emptyDir") (eq .Values.admin.data.type "existingClaim") }} + - name: admin-data + mountPath: /data + {{- end }} + {{- if or (eq .Values.admin.logs.type "hostPath") (eq .Values.admin.logs.type "persistentVolumeClaim") (eq .Values.admin.logs.type "emptyDir") (eq .Values.admin.logs.type "existingClaim") }} + - name: admin-logs + mountPath: /logs + {{- end }} + {{- if .Values.global.enableSecurity }} + - name: security-config + readOnly: true + mountPath: /etc/seaweedfs/security.toml + subPath: security.toml + - name: ca-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/ca/ + - name: master-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/master/ + - name: volume-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/volume/ + - name: filer-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/filer/ + - name: client-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/client/ + - name: admin-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/admin/ + {{- end }} + {{ tpl .Values.admin.extraVolumeMounts . | nindent 12 | trim }} + ports: + - containerPort: {{ .Values.admin.port }} + name: http + - containerPort: {{ .Values.admin.grpcPort }} + name: grpc + {{- if .Values.admin.metricsPort }} + - containerPort: {{ .Values.admin.metricsPort }} + name: metrics + {{- end }} + {{- if .Values.admin.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: {{ .Values.admin.readinessProbe.httpGet.path }} + port: http + scheme: {{ .Values.admin.readinessProbe.httpGet.scheme }} + initialDelaySeconds: {{ .Values.admin.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.admin.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.admin.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.admin.readinessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.admin.readinessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.admin.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: {{ .Values.admin.livenessProbe.httpGet.path }} + port: http + scheme: {{ .Values.admin.livenessProbe.httpGet.scheme }} + initialDelaySeconds: {{ .Values.admin.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.admin.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.admin.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.admin.livenessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.admin.livenessProbe.timeoutSeconds }} + {{- end }} + {{- with .Values.admin.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.admin.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.admin.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.admin.sidecars }} + {{- include "common.tplvalues.render" (dict "value" .Values.admin.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + {{- if eq .Values.admin.data.type "hostPath" }} + - name: admin-data + hostPath: + path: {{ .Values.admin.data.hostPathPrefix }}/seaweedfs-admin-data + type: DirectoryOrCreate + {{- end }} + {{- if eq .Values.admin.data.type "emptyDir" }} + - name: admin-data + emptyDir: {} + {{- end }} + {{- if eq .Values.admin.data.type "existingClaim" }} + - name: admin-data + persistentVolumeClaim: + claimName: {{ .Values.admin.data.claimName }} + {{- end }} + {{- if eq .Values.admin.logs.type "hostPath" }} + - name: admin-logs + hostPath: + path: {{ .Values.admin.logs.hostPathPrefix }}/logs/seaweedfs/admin + type: DirectoryOrCreate + {{- end }} + {{- if eq .Values.admin.logs.type "emptyDir" }} + - name: admin-logs + emptyDir: {} + {{- end }} + {{- if eq .Values.admin.logs.type "existingClaim" }} + - name: admin-logs + persistentVolumeClaim: + claimName: {{ .Values.admin.logs.claimName }} + {{- end }} + {{- if .Values.global.enableSecurity }} + - name: security-config + configMap: + name: {{ template "seaweedfs.name" . }}-security-config + - name: ca-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-ca-cert + - name: master-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-master-cert + - name: volume-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-volume-cert + - name: filer-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-filer-cert + - name: client-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-client-cert + - name: admin-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-admin-cert + {{- end }} + {{ tpl .Values.admin.extraVolumes . | indent 8 | trim }} + {{- if .Values.admin.nodeSelector }} + nodeSelector: + {{ tpl .Values.admin.nodeSelector . | indent 8 | trim }} + {{- end }} + {{- $pvc_exists := include "admin.pvc_exists" . -}} + {{- if $pvc_exists }} + volumeClaimTemplates: + {{- if eq .Values.admin.data.type "persistentVolumeClaim" }} + - metadata: + name: admin-data + {{- with .Values.admin.data.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: {{ .Values.admin.data.storageClass }} + resources: + requests: + storage: {{ .Values.admin.data.size }} + {{- end }} + {{- if eq .Values.admin.logs.type "persistentVolumeClaim" }} + - metadata: + name: admin-logs + {{- with .Values.admin.logs.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: {{ .Values.admin.logs.storageClass }} + resources: + requests: + storage: {{ .Values.admin.logs.size }} + {{- end }} + {{- end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/cert/admin-cert.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/cert/admin-cert.yaml new file mode 100644 index 00000000..be526601 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/cert/admin-cert.yaml @@ -0,0 +1,43 @@ +{{- if and .Values.global.enableSecurity (not .Values.certificates.externalCertificates.enabled)}} +apiVersion: cert-manager.io/v1{{ if .Values.global.certificates.alphacrds }}alpha1{{ end }} +kind: Certificate +metadata: + name: {{ template "seaweedfs.name" . }}-admin-cert + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: admin + {{- if .Values.admin.annotations }} + annotations: + {{- toYaml .Values.admin.annotations | nindent 4 }} + {{- end }} +spec: + secretName: {{ template "seaweedfs.name" . }}-admin-cert + issuerRef: + name: {{ template "seaweedfs.name" . }}-ca-issuer + kind: Issuer + commonName: {{ .Values.certificates.commonName }} + subject: + organizations: + - "SeaweedFS CA" + dnsNames: + - '*.{{ template "seaweedfs.name" . }}-admin' + - '*.{{ template "seaweedfs.name" . }}-admin.{{ .Release.Namespace }}' + - '*.{{ template "seaweedfs.name" . }}-admin.{{ .Release.Namespace }}.svc' + - '*.{{ template "seaweedfs.name" . }}-admin.{{ .Release.Namespace }}.svc.cluster.local' +{{- if .Values.certificates.ipAddresses }} + ipAddresses: + {{- range .Values.certificates.ipAddresses }} + - {{ . }} + {{- end }} +{{- end }} + privateKey: + algorithm: {{ .Values.certificates.keyAlgorithm }} + size: {{ .Values.certificates.keySize }} + duration: {{ .Values.certificates.duration }} + renewBefore: {{ .Values.certificates.renewBefore }} +{{- end }} + diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/cert/worker-cert.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/cert/worker-cert.yaml new file mode 100644 index 00000000..85edeb33 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/cert/worker-cert.yaml @@ -0,0 +1,43 @@ +{{- if and .Values.global.enableSecurity (not .Values.certificates.externalCertificates.enabled)}} +apiVersion: cert-manager.io/v1{{ if .Values.global.certificates.alphacrds }}alpha1{{ end }} +kind: Certificate +metadata: + name: {{ template "seaweedfs.name" . }}-worker-cert + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: worker + {{- if .Values.worker.annotations }} + annotations: + {{- toYaml .Values.worker.annotations | nindent 4 }} + {{- end }} +spec: + secretName: {{ template "seaweedfs.name" . }}-worker-cert + issuerRef: + name: {{ template "seaweedfs.name" . }}-ca-issuer + kind: Issuer + commonName: {{ .Values.certificates.commonName }} + subject: + organizations: + - "SeaweedFS CA" + dnsNames: + - '*.{{ template "seaweedfs.name" . }}-worker' + - '*.{{ template "seaweedfs.name" . }}-worker.{{ .Release.Namespace }}' + - '*.{{ template "seaweedfs.name" . }}-worker.{{ .Release.Namespace }}.svc' + - '*.{{ template "seaweedfs.name" . }}-worker.{{ .Release.Namespace }}.svc.cluster.local' +{{- if .Values.certificates.ipAddresses }} + ipAddresses: + {{- range .Values.certificates.ipAddresses }} + - {{ . }} + {{- end }} +{{- end }} + privateKey: + algorithm: {{ .Values.certificates.keyAlgorithm }} + size: {{ .Values.certificates.keySize }} + duration: {{ .Values.certificates.duration }} + renewBefore: {{ .Values.certificates.renewBefore }} +{{- end }} + diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/filer/filer-statefulset.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/filer/filer-statefulset.yaml index 2b8c2744..e29239c3 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/templates/filer/filer-statefulset.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/filer/filer-statefulset.yaml @@ -220,7 +220,7 @@ spec: -s3.auditLogConfig=/etc/sw/filer_s3_auditLogConfig.json \ {{- end }} {{- end }} - -master={{ if .Values.global.masterServer }}{{.Values.global.masterServer}}{{ else }}{{ range $index := until (.Values.master.replicas | int) }}${SEAWEEDFS_FULLNAME}-master-{{ $index }}.${SEAWEEDFS_FULLNAME}-master.{{ $.Release.Namespace }}:{{ $.Values.master.port }}{{ if lt $index (sub ($.Values.master.replicas | int) 1) }},{{ end }}{{ end }}{{ end }} \ + -master={{ include "seaweedfs.masterServerArg" . }} \ {{- range .Values.filer.extraArgs }} {{ . }} \ {{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/master/master-statefulset.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/master/master-statefulset.yaml index a7067345..50e0e97d 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/templates/master/master-statefulset.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/master/master-statefulset.yaml @@ -184,7 +184,7 @@ spec: -garbageThreshold={{ .Values.master.garbageThreshold }} \ {{- end }} -ip=${POD_NAME}.${SEAWEEDFS_FULLNAME}-master.{{ .Release.Namespace }} \ - -peers={{ range $index := until (.Values.master.replicas | int) }}${SEAWEEDFS_FULLNAME}-master-{{ $index }}.${SEAWEEDFS_FULLNAME}-master.{{ $.Release.Namespace }}:{{ $.Values.master.port }}{{ if lt $index (sub ($.Values.master.replicas | int) 1) }},{{ end }}{{ end }} \ + -peers={{ include "seaweedfs.masterServers" . }} \ {{- range .Values.master.extraArgs }} {{ . }} \ {{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-ingress.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-ingress.yaml index 899773ae..e884f4fc 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-ingress.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/s3/s3-ingress.yaml @@ -4,6 +4,13 @@ {{- /* Determine service name based on deployment mode */}} {{- $serviceName := ternary (printf "%s-all-in-one" (include "seaweedfs.name" .)) (printf "%s-s3" (include "seaweedfs.name" .)) .Values.allInOne.enabled }} {{- $s3Port := .Values.allInOne.s3.port | default .Values.s3.port }} +{{- /* Build hosts list - support both legacy .host (string) and new .hosts (array) for backwards compatibility */}} +{{- $hosts := list }} +{{- if kindIs "slice" .Values.s3.ingress.host }} + {{- $hosts = .Values.s3.ingress.host }} +{{- else if .Values.s3.ingress.host }} + {{- $hosts = list .Values.s3.ingress.host }} +{{- end }} {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }} apiVersion: networking.k8s.io/v1 {{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion }} @@ -30,6 +37,25 @@ spec: tls: {{ .Values.s3.ingress.tls | default list | toYaml | nindent 6}} rules: +{{- if $hosts }} +{{- range $hosts }} + - host: {{ . | quote }} + http: + paths: + - path: {{ $.Values.s3.ingress.path | quote }} + pathType: {{ $.Values.s3.ingress.pathType | quote }} + backend: +{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} + service: + name: {{ $serviceName }} + port: + number: {{ $s3Port }} +{{- else }} + serviceName: {{ $serviceName }} + servicePort: {{ $s3Port }} +{{- end }} +{{- end }} +{{- else }} - http: paths: - path: {{ .Values.s3.ingress.path | quote }} @@ -44,7 +70,5 @@ spec: serviceName: {{ $serviceName }} servicePort: {{ $s3Port }} {{- end }} -{{- if .Values.s3.ingress.host }} - host: {{ .Values.s3.ingress.host | quote }} {{- end }} {{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/shared/_helpers.tpl b/packages/system/seaweedfs/charts/seaweedfs/templates/shared/_helpers.tpl index d22d1422..557bb9d4 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/templates/shared/_helpers.tpl +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/shared/_helpers.tpl @@ -83,6 +83,26 @@ Inject extra environment vars in the format key:value, if populated {{- end -}} {{- end -}} +{{/* Return the proper admin image */}} +{{- define "admin.image" -}} +{{- if .Values.admin.imageOverride -}} +{{- $imageOverride := .Values.admin.imageOverride -}} +{{- printf "%s" $imageOverride -}} +{{- else -}} +{{- include "common.image" . }} +{{- end -}} +{{- end -}} + +{{/* Return the proper worker image */}} +{{- define "worker.image" -}} +{{- if .Values.worker.imageOverride -}} +{{- $imageOverride := .Values.worker.imageOverride -}} +{{- printf "%s" $imageOverride -}} +{{- else -}} +{{- include "common.image" . }} +{{- end -}} +{{- end -}} + {{/* Return the proper volume image */}} {{- define "volume.image" -}} {{- if .Values.volume.imageOverride -}} @@ -136,6 +156,15 @@ Inject extra environment vars in the format key:value, if populated {{- end -}} {{- end -}} +{{/* check if any Admin PVC exists */}} +{{- define "admin.pvc_exists" -}} +{{- if or (eq .Values.admin.data.type "persistentVolumeClaim") (eq .Values.admin.logs.type "persistentVolumeClaim") -}} +{{- printf "true" -}} +{{- else -}} +{{- printf "" -}} +{{- end -}} +{{- end -}} + {{/* check if any InitContainers exist for Volumes */}} {{- define "volume.initContainers_exists" -}} {{- if or (not (empty .Values.volume.idx )) (not (empty .Values.volume.initContainers )) -}} @@ -246,3 +275,28 @@ If allInOne is enabled, point to the all-in-one service; otherwise, point to the {{- end -}} {{- printf "%s%s.%s:%d" (include "seaweedfs.name" .) $serviceNameSuffix .Release.Namespace (int .Values.filer.port) -}} {{- end -}} + +{{/* +Generate comma-separated list of master server addresses. +Usage: {{ include "seaweedfs.masterServers" . }} +Output example: ${SEAWEEDFS_FULLNAME}-master-0.${SEAWEEDFS_FULLNAME}-master.namespace:9333,${SEAWEEDFS_FULLNAME}-master-1... +*/}} +{{- define "seaweedfs.masterServers" -}} +{{- $fullname := include "seaweedfs.name" . -}} +{{- range $index := until (.Values.master.replicas | int) -}} +{{- if $index }},{{ end -}} +${SEAWEEDFS_FULLNAME}-master-{{ $index }}.${SEAWEEDFS_FULLNAME}-master.{{ $.Release.Namespace }}:{{ $.Values.master.port }} +{{- end -}} +{{- end -}} + +{{/* +Generate master server argument value, using global.masterServer if set, otherwise the generated list. +Usage: {{ include "seaweedfs.masterServerArg" . }} +*/}} +{{- define "seaweedfs.masterServerArg" -}} +{{- if .Values.global.masterServer -}} +{{- .Values.global.masterServer -}} +{{- else -}} +{{- include "seaweedfs.masterServers" . -}} +{{- end -}} +{{- end -}} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/shared/security-configmap.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/shared/security-configmap.yaml index 6f229c59..f7fb69ea 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/templates/shared/security-configmap.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/shared/security-configmap.yaml @@ -65,6 +65,14 @@ data: cert = "/usr/local/share/ca-certificates/filer/tls.crt" key = "/usr/local/share/ca-certificates/filer/tls.key" + [grpc.admin] + cert = "/usr/local/share/ca-certificates/admin/tls.crt" + key = "/usr/local/share/ca-certificates/admin/tls.key" + + [grpc.worker] + cert = "/usr/local/share/ca-certificates/worker/tls.crt" + key = "/usr/local/share/ca-certificates/worker/tls.key" + # use this for any place needs a grpc client # i.e., "weed backup|benchmark|filer.copy|filer.replicate|mount|s3|upload" [grpc.client] diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/volume/volume-statefulset.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/volume/volume-statefulset.yaml index 1a8964a5..045b95c2 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/templates/volume/volume-statefulset.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/volume/volume-statefulset.yaml @@ -176,6 +176,9 @@ spec: {{- if $volume.dataCenter }} -dataCenter={{ $volume.dataCenter }} \ {{- end }} + {{- if $volume.id }} + -id={{ $volume.id }} \ + {{- end }} -ip.bind={{ $volume.ipBind }} \ -readMode={{ $volume.readMode }} \ {{- if $volume.whiteList }} @@ -196,7 +199,7 @@ spec: -minFreeSpacePercent={{ $volume.minFreeSpacePercent }} \ -ip=${POD_NAME}.${SEAWEEDFS_FULLNAME}-{{ $volumeName }}.{{ $.Release.Namespace }} \ -compactionMBps={{ $volume.compactionMBps }} \ - -mserver={{ if $.Values.global.masterServer }}{{ $.Values.global.masterServer}}{{ else }}{{ range $index := until ($.Values.master.replicas | int) }}${SEAWEEDFS_FULLNAME}-master-{{ $index }}.${SEAWEEDFS_FULLNAME}-master.{{ $.Release.Namespace }}:{{ $.Values.master.port }}{{ if lt $index (sub ($.Values.master.replicas | int) 1) }},{{ end }}{{ end }}{{ end }} + -master={{ include "seaweedfs.masterServerArg" $ }} \ {{- range $volume.extraArgs }} {{ . }} \ {{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/worker/worker-deployment.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/worker/worker-deployment.yaml new file mode 100644 index 00000000..7a6e0524 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/worker/worker-deployment.yaml @@ -0,0 +1,288 @@ +{{- if .Values.worker.enabled }} +{{- if and (not .Values.worker.adminServer) (not .Values.admin.enabled) }} +{{- fail "worker.adminServer must be set if admin.enabled is false within the same release" -}} +{{- end }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "seaweedfs.name" . }}-worker + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: worker +{{- if .Values.worker.annotations }} + annotations: + {{- toYaml .Values.worker.annotations | nindent 4 }} +{{- end }} +spec: + replicas: {{ .Values.worker.replicas }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: worker + template: + metadata: + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: worker + {{ with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.worker.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{ with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.worker.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + restartPolicy: {{ default .Values.global.restartPolicy .Values.worker.restartPolicy }} + {{- if .Values.worker.affinity }} + affinity: + {{ tpl .Values.worker.affinity . | nindent 8 | trim }} + {{- end }} + {{- if .Values.worker.topologySpreadConstraints }} + topologySpreadConstraints: + {{ tpl .Values.worker.topologySpreadConstraints . | nindent 8 | trim }} + {{- end }} + {{- if .Values.worker.tolerations }} + tolerations: + {{ tpl .Values.worker.tolerations . | nindent 8 | trim }} + {{- end }} + {{- include "seaweedfs.imagePullSecrets" . | nindent 6 }} + terminationGracePeriodSeconds: 60 + {{- if .Values.worker.priorityClassName }} + priorityClassName: {{ .Values.worker.priorityClassName | quote }} + {{- end }} + enableServiceLinks: false + {{- if .Values.worker.serviceAccountName }} + serviceAccountName: {{ .Values.worker.serviceAccountName | quote }} + {{- end }} + {{- if .Values.worker.initContainers }} + initContainers: + {{ tpl .Values.worker.initContainers . | nindent 8 | trim }} + {{- end }} + {{- if .Values.worker.podSecurityContext.enabled }} + securityContext: {{- omit .Values.worker.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + containers: + - name: seaweedfs + image: {{ template "worker.image" . }} + imagePullPolicy: {{ default "IfNotPresent" .Values.global.imagePullPolicy }} + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: SEAWEEDFS_FULLNAME + value: "{{ template "seaweedfs.name" . }}" + {{- if .Values.worker.extraEnvironmentVars }} + {{- range $key, $value := .Values.worker.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + {{- if .Values.global.extraEnvironmentVars }} + {{- range $key, $value := .Values.global.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + exec /usr/bin/weed \ + {{- if or (eq .Values.worker.logs.type "hostPath") (eq .Values.worker.logs.type "emptyDir") (eq .Values.worker.logs.type "existingClaim") }} + -logdir=/logs \ + {{- else }} + -logtostderr=true \ + {{- end }} + {{- if .Values.worker.loggingOverrideLevel }} + -v={{ .Values.worker.loggingOverrideLevel }} \ + {{- else }} + -v={{ .Values.global.loggingLevel }} \ + {{- end }} + worker \ + {{- if .Values.worker.adminServer }} + -admin={{ .Values.worker.adminServer }} \ + {{- else }} + -admin={{ template "seaweedfs.name" . }}-admin.{{ .Release.Namespace }}:{{ .Values.admin.port }}{{ if .Values.admin.grpcPort }}.{{ .Values.admin.grpcPort }}{{ end }} \ + {{- end }} + -capabilities={{ .Values.worker.capabilities }} \ + -maxConcurrent={{ .Values.worker.maxConcurrent }} \ + -workingDir={{ .Values.worker.workingDir }}{{- if or .Values.worker.metricsPort .Values.worker.extraArgs }} \{{ end }} + {{- if .Values.worker.metricsPort }} + -metricsPort={{ .Values.worker.metricsPort }}{{- if .Values.worker.extraArgs }} \{{ end }} + {{- end }} + {{- range $index, $arg := .Values.worker.extraArgs }} + {{ $arg }}{{- if lt $index (sub (len $.Values.worker.extraArgs) 1) }} \{{ end }} + {{- end }} + volumeMounts: + {{- if or (eq .Values.worker.data.type "hostPath") (eq .Values.worker.data.type "emptyDir") (eq .Values.worker.data.type "existingClaim") }} + - name: worker-data + mountPath: {{ .Values.worker.workingDir }} + {{- end }} + {{- if or (eq .Values.worker.logs.type "hostPath") (eq .Values.worker.logs.type "emptyDir") (eq .Values.worker.logs.type "existingClaim") }} + - name: worker-logs + mountPath: /logs + {{- end }} + {{- if .Values.global.enableSecurity }} + - name: security-config + readOnly: true + mountPath: /etc/seaweedfs/security.toml + subPath: security.toml + - name: ca-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/ca/ + - name: master-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/master/ + - name: volume-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/volume/ + - name: filer-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/filer/ + - name: client-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/client/ + - name: worker-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/worker/ + {{- end }} + {{ tpl .Values.worker.extraVolumeMounts . | nindent 12 | trim }} + ports: + {{- if .Values.worker.metricsPort }} + - containerPort: {{ .Values.worker.metricsPort }} + name: metrics + {{- end }} + {{- with .Values.worker.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.worker.livenessProbe.enabled }} + livenessProbe: + {{- if .Values.worker.livenessProbe.httpGet }} + httpGet: + path: {{ .Values.worker.livenessProbe.httpGet.path }} + port: {{ .Values.worker.livenessProbe.httpGet.port }} + {{- else if .Values.worker.livenessProbe.tcpSocket }} + tcpSocket: + port: {{ .Values.worker.livenessProbe.tcpSocket.port }} + {{- end }} + initialDelaySeconds: {{ .Values.worker.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.worker.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.worker.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.worker.livenessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.worker.livenessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.worker.readinessProbe.enabled }} + readinessProbe: + {{- if .Values.worker.readinessProbe.httpGet }} + httpGet: + path: {{ .Values.worker.readinessProbe.httpGet.path }} + port: {{ .Values.worker.readinessProbe.httpGet.port }} + {{- else if .Values.worker.readinessProbe.tcpSocket }} + tcpSocket: + port: {{ .Values.worker.readinessProbe.tcpSocket.port }} + {{- end }} + initialDelaySeconds: {{ .Values.worker.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.worker.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.worker.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.worker.readinessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.worker.readinessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.worker.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.worker.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.worker.sidecars }} + {{- include "common.tplvalues.render" (dict "value" .Values.worker.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + {{- if eq .Values.worker.data.type "hostPath" }} + - name: worker-data + hostPath: + path: {{ .Values.worker.data.hostPathPrefix }}/seaweedfs-worker-data + type: DirectoryOrCreate + {{- end }} + {{- if eq .Values.worker.data.type "emptyDir" }} + - name: worker-data + emptyDir: {} + {{- end }} + {{- if eq .Values.worker.data.type "existingClaim" }} + - name: worker-data + persistentVolumeClaim: + claimName: {{ .Values.worker.data.claimName }} + {{- end }} + {{- if eq .Values.worker.logs.type "hostPath" }} + - name: worker-logs + hostPath: + path: {{ .Values.worker.logs.hostPathPrefix }}/logs/seaweedfs/worker + type: DirectoryOrCreate + {{- end }} + {{- if eq .Values.worker.logs.type "emptyDir" }} + - name: worker-logs + emptyDir: {} + {{- end }} + {{- if eq .Values.worker.logs.type "existingClaim" }} + - name: worker-logs + persistentVolumeClaim: + claimName: {{ .Values.worker.logs.claimName }} + {{- end }} + {{- if .Values.global.enableSecurity }} + - name: security-config + configMap: + name: {{ template "seaweedfs.name" . }}-security-config + - name: ca-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-ca-cert + - name: master-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-master-cert + - name: volume-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-volume-cert + - name: filer-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-filer-cert + - name: client-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-client-cert + - name: worker-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-worker-cert + {{- end }} + {{ tpl .Values.worker.extraVolumes . | indent 8 | trim }} + {{- if .Values.worker.nodeSelector }} + nodeSelector: + {{ tpl .Values.worker.nodeSelector . | indent 8 | trim }} + {{- end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/worker/worker-service.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/worker/worker-service.yaml new file mode 100644 index 00000000..cf9885e2 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/worker/worker-service.yaml @@ -0,0 +1,26 @@ +{{- if .Values.worker.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "seaweedfs.name" . }}-worker + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: worker +spec: + clusterIP: None # Headless service + {{- if .Values.worker.metricsPort }} + ports: + - name: "metrics" + port: {{ .Values.worker.metricsPort }} + targetPort: {{ .Values.worker.metricsPort }} + protocol: TCP + {{- end }} + selector: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: worker +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml new file mode 100644 index 00000000..7f9590da --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml @@ -0,0 +1,33 @@ +{{- if .Values.worker.enabled }} +{{- if .Values.worker.metricsPort }} +{{- if .Values.global.monitoring.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "seaweedfs.name" . }}-worker + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: worker + {{- with .Values.global.monitoring.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- with .Values.worker.serviceMonitor.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +spec: + endpoints: + - interval: 30s + port: metrics + scrapeTimeout: 5s + selector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/component: worker +{{- end }} +{{- end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/values.yaml b/packages/system/seaweedfs/charts/seaweedfs/values.yaml index b71e1071..a2419805 100644 --- a/packages/system/seaweedfs/charts/seaweedfs/values.yaml +++ b/packages/system/seaweedfs/charts/seaweedfs/values.yaml @@ -401,6 +401,10 @@ volume: # Volume server's rack name rack: null + # Stable identifier for the volume server, independent of IP address + # Useful for Kubernetes environments with hostPath volumes to maintain stable identity + id: null + # Volume server's data center name dataCenter: null @@ -1008,7 +1012,7 @@ s3: ingress: enabled: false className: "" - # host: false for "*" hostname + # host: false for "*" hostname, or an array for multiple hostnames host: "seaweedfs.cluster.local" path: "/" pathType: Prefix @@ -1088,6 +1092,247 @@ sftp: failureThreshold: 100 timeoutSeconds: 10 +admin: + enabled: false + imageOverride: null + restartPolicy: null + replicas: 1 + port: 23646 # Default admin port + grpcPort: 33646 # Default gRPC port for worker connections + metricsPort: 9327 + loggingOverrideLevel: null + + # Admin authentication + secret: + # Name of an existing secret containing admin credentials. If set, adminUser and adminPassword below are ignored. + existingSecret: "" + # Key in the existing secret for the admin username. Required if existingSecret is set. + userKey: "" + # Key in the existing secret for the admin password. Required if existingSecret is set. + pwKey: "" + adminUser: "admin" + adminPassword: "" # If empty, authentication is disabled. + + # Data directory for admin configuration and maintenance data + dataDir: "" # If empty, configuration is kept in memory only + + # Master servers to connect to + # If empty, uses global.masterServer or auto-discovers from master statefulset + masters: "" + + # Custom command line arguments to add to the admin command + # Example: ["-customFlag", "value", "-anotherFlag"] + extraArgs: [] + + # Storage configuration + data: + type: "emptyDir" # Options: "hostPath", "persistentVolumeClaim", "emptyDir", "existingClaim" + size: "10Gi" + storageClass: "" + hostPathPrefix: /storage + claimName: "" + annotations: {} + + logs: + type: "emptyDir" # Options: "hostPath", "persistentVolumeClaim", "emptyDir", "existingClaim" + size: "5Gi" + storageClass: "" + hostPathPrefix: /storage + claimName: "" + annotations: {} + + # Additional resources + sidecars: [] + initContainers: "" + extraVolumes: "" + extraVolumeMounts: "" + podLabels: {} + podAnnotations: {} + annotations: {} + + ## Set podManagementPolicy + podManagementPolicy: Parallel + + # Affinity Settings + # Commenting out or setting as empty the affinity variable, will allow + # deployment to single node services such as Minikube + affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: admin + topologyKey: kubernetes.io/hostname + + # Topology Spread Constraints Settings + # This should map directly to the value of the topologySpreadConstraints + # for a PodSpec. By Default no constraints are set. + topologySpreadConstraints: "" + + resources: {} + tolerations: "" + nodeSelector: "" + priorityClassName: "" + serviceAccountName: "" + podSecurityContext: {} + containerSecurityContext: {} + + extraEnvironmentVars: {} + + # Health checks + livenessProbe: + enabled: true + httpGet: + path: /health + scheme: HTTP + initialDelaySeconds: 20 + periodSeconds: 60 + successThreshold: 1 + failureThreshold: 5 + timeoutSeconds: 10 + + readinessProbe: + enabled: true + httpGet: + path: /health + scheme: HTTP + initialDelaySeconds: 15 + periodSeconds: 15 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 10 + + ingress: + enabled: false + className: "nginx" + # host: false for "*" hostname + host: "admin.seaweedfs.local" + path: "/" + pathType: Prefix + annotations: {} + tls: [] + + service: + type: ClusterIP + annotations: {} + + # ServiceMonitor annotations (separate from pod/deployment annotations) + serviceMonitor: + annotations: {} + +worker: + enabled: false + imageOverride: null + restartPolicy: null + replicas: 1 + loggingOverrideLevel: null + metricsPort: 9327 + + # Admin server to connect to + adminServer: "" + + + # Worker capabilities - comma-separated list + # Available: vacuum, balance, erasure_coding + # Default: "vacuum,balance,erasure_coding" (all capabilities) + capabilities: "vacuum,balance,erasure_coding" + + # Maximum number of concurrent tasks + maxConcurrent: 3 + + # Working directory for task execution + workingDir: "/tmp/seaweedfs-worker" + + # Custom command line arguments to add to the worker command + # Example: ["-customFlag", "value", "-anotherFlag"] + extraArgs: [] + + # Storage configuration for working directory + # Note: Workers use Deployment, so use "emptyDir", "hostPath", or "existingClaim" + # Do NOT use "persistentVolumeClaim" - use "existingClaim" with pre-provisioned PVC instead + data: + type: "emptyDir" # Options: "hostPath", "emptyDir", "existingClaim" + hostPathPrefix: /storage + claimName: "" # For existingClaim type + + logs: + type: "emptyDir" # Options: "hostPath", "emptyDir", "existingClaim" + hostPathPrefix: /storage + claimName: "" # For existingClaim type + + # Additional resources + sidecars: [] + initContainers: "" + extraVolumes: "" + extraVolumeMounts: "" + podLabels: {} + podAnnotations: {} + annotations: {} + + # Affinity Settings + # Commenting out or setting as empty the affinity variable, will allow + # deployment to single node services such as Minikube + affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: worker + topologyKey: kubernetes.io/hostname + + # Topology Spread Constraints Settings + # This should map directly to the value of the topologySpreadConstraints + # for a PodSpec. By Default no constraints are set. + topologySpreadConstraints: "" + + resources: + requests: + cpu: "500m" + memory: "512Mi" + limits: + cpu: "2" + memory: "2Gi" + tolerations: "" + nodeSelector: "" + priorityClassName: "" + serviceAccountName: "" + podSecurityContext: {} + containerSecurityContext: {} + + extraEnvironmentVars: {} + + # Health checks for worker pods + # Workers expose /health (liveness) and /ready (readiness) endpoints on the metricsPort + livenessProbe: + enabled: true + httpGet: + path: /health + port: metrics + initialDelaySeconds: 30 + periodSeconds: 60 + successThreshold: 1 + failureThreshold: 5 + timeoutSeconds: 10 + + readinessProbe: + enabled: true + httpGet: + path: /ready + port: metrics + initialDelaySeconds: 20 + periodSeconds: 15 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 10 + + # ServiceMonitor annotations (separate from pod/deployment annotations) + serviceMonitor: + annotations: {} + # All-in-one deployment configuration allInOne: enabled: false From a9de6bf07ea0850b0852d7d000c7b343f6c4e035 Mon Sep 17 00:00:00 2001 From: nbykov0 <166552198+nbykov0@users.noreply.github.com> Date: Mon, 5 Jan 2026 17:29:29 +0300 Subject: [PATCH 34/43] [seaweed] Use upstream images Signed-off-by: nbykov0 <166552198+nbykov0@users.noreply.github.com> (cherry picked from commit bcd4b8976aa523e95f05ad5ffb791380ca160977) --- packages/system/seaweedfs/Makefile | 17 +---------------- .../seaweedfs/images/seaweedfs/Dockerfile | 2 -- 2 files changed, 1 insertion(+), 18 deletions(-) delete mode 100644 packages/system/seaweedfs/images/seaweedfs/Dockerfile diff --git a/packages/system/seaweedfs/Makefile b/packages/system/seaweedfs/Makefile index 43f4053b..d1f21a80 100644 --- a/packages/system/seaweedfs/Makefile +++ b/packages/system/seaweedfs/Makefile @@ -8,23 +8,8 @@ update: mkdir -p charts version=$$(git ls-remote --tags --sort="v:refname" https://github.com/seaweedfs/seaweedfs | grep -v '\^{}' | grep 'refs/tags/[0-9]' | awk -F'/' 'END{print $$3}') && \ curl -sSL https://github.com/seaweedfs/seaweedfs/archive/refs/tags/$${version}.tar.gz | \ - tar xzvf - --strip 3 -C charts seaweedfs-$${version}/k8s/charts/seaweedfs && \ - sed -i.bak "/ARG VERSION/ s|=.*|=$${version}|g" images/seaweedfs/Dockerfile && \ - rm -f images/seaweedfs/Dockerfile.bak + tar xzvf - --strip 3 -C charts seaweedfs-$${version}/k8s/charts/seaweedfs patch --no-backup-if-mismatch -p4 < patches/resize-api-server-annotation.diff patch --no-backup-if-mismatch -p4 < patches/s3-traffic-distribution.patch #patch --no-backup-if-mismatch -p4 < patches/retention-policy-delete.yaml -image: - docker buildx build images/seaweedfs \ - --tag $(REGISTRY)/seaweedfs:$(call settag,$(TAG)) \ - --cache-from type=registry,ref=$(REGISTRY)/seaweedfs:latest \ - --cache-to type=inline \ - --metadata-file images/seaweedfs.json \ - $(BUILDX_ARGS) - REGISTRY="$(REGISTRY)" \ - yq -i '.seaweedfs.image.registry = strenv(REGISTRY)' values.yaml - TAG=$(TAG)@$$(yq e '."containerimage.digest"' images/seaweedfs.json -o json -r) \ - yq -i '.seaweedfs.image.tag = strenv(TAG)' values.yaml - yq -i '.global.imageName = "seaweedfs"' values.yaml - rm -f images/seaweedfs.json diff --git a/packages/system/seaweedfs/images/seaweedfs/Dockerfile b/packages/system/seaweedfs/images/seaweedfs/Dockerfile deleted file mode 100644 index 7177c70f..00000000 --- a/packages/system/seaweedfs/images/seaweedfs/Dockerfile +++ /dev/null @@ -1,2 +0,0 @@ -ARG VERSION=4.02 -FROM chrislusf/seaweedfs:${VERSION} From 3ab4707c6a01f82a0d132719e5f3f79fd5d5068c Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Thu, 8 Jan 2026 12:13:24 +0100 Subject: [PATCH 35/43] fix(linstor): update skip-adjust-when-device-inaccessible patch Add physical device path existence check to prevent race condition where lsblk is called before kernel creates DRBD device node after drbdadm adjust. This fixes issue where resources ended up in Unknown state after satellite restart because: - drbdadm adjust completes successfully (brings devices up) - updateDiscGran() immediately tries lsblk - /dev/drbd* doesn't exist yet (kernel hasn't created node) - lsblk fails with "not a block device" exit code 32 - StorageException interrupts DeviceManager cycle - Device remains in incomplete state The patch now checks Files.exists(devicePath) before lsblk, allowing the check to be retried in next cycle when device node is available. Upstream: https://github.com/LINBIT/linstor-server/pull/471 Co-Authored-By: Claude Signed-off-by: Andrei Kvapil (cherry picked from commit a2a07471427207d2204dd1b9323dd196a3664e2d) --- .../skip-adjust-when-device-inaccessible.diff | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/system/linstor/images/piraeus-server/patches/skip-adjust-when-device-inaccessible.diff b/packages/system/linstor/images/piraeus-server/patches/skip-adjust-when-device-inaccessible.diff index 09e7ccf9..18399c41 100644 --- a/packages/system/linstor/images/piraeus-server/patches/skip-adjust-when-device-inaccessible.diff +++ b/packages/system/linstor/images/piraeus-server/patches/skip-adjust-when-device-inaccessible.diff @@ -1,3 +1,28 @@ +diff --git a/satellite/src/main/java/com/linbit/linstor/core/devmgr/DeviceHandlerImpl.java b/satellite/src/main/java/com/linbit/linstor/core/devmgr/DeviceHandlerImpl.java +index abc123def..def456abc 100644 +--- a/satellite/src/main/java/com/linbit/linstor/core/devmgr/DeviceHandlerImpl.java ++++ b/satellite/src/main/java/com/linbit/linstor/core/devmgr/DeviceHandlerImpl.java +@@ -83,6 +83,8 @@ import java.util.TreeMap; + import java.util.TreeSet; + import java.util.concurrent.atomic.AtomicBoolean; + import java.util.function.Function; ++import java.nio.file.Files; ++import java.nio.file.Paths; + + @Singleton + public class DeviceHandlerImpl implements DeviceHandler +@@ -1646,7 +1648,10 @@ public class DeviceHandlerImpl implements DeviceHandler + private void updateDiscGran(VlmProviderObject vlmData) throws DatabaseException, StorageException + { + String devicePath = vlmData.getDevicePath(); +- if (devicePath != null && vlmData.exists()) ++ // Check if device path physically exists before calling lsblk ++ // This is important for DRBD devices which might be temporarily unavailable during adjust ++ // (drbdadm adjust brings devices down/up, and kernel might not have created the device node yet) ++ if (devicePath != null && vlmData.exists() && Files.exists(Paths.get(devicePath))) + { + if (vlmData.getDiscGran() == VlmProviderObject.UNINITIALIZED_SIZE) + { diff --git a/satellite/src/main/java/com/linbit/linstor/layer/drbd/DrbdLayer.java b/satellite/src/main/java/com/linbit/linstor/layer/drbd/DrbdLayer.java index 01967a3..871d830 100644 --- a/satellite/src/main/java/com/linbit/linstor/layer/drbd/DrbdLayer.java From 3028dc9f1a2ae133caf768da75ed83d4c6c2285b Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Tue, 6 Jan 2026 18:06:01 +0100 Subject: [PATCH 36/43] feat(kubeovn): update to v1.14.25 Update kube-ovn from v1.14.11 to v1.14.25. Sync chart templates with upstream changes. Co-Authored-By: Claude Signed-off-by: Andrei Kvapil (cherry picked from commit d73773eaa128149f616a633bc1e3454dfe3a63ed) --- packages/system/kubeovn/Chart.yaml | 2 +- packages/system/kubeovn/Makefile | 2 +- .../system/kubeovn/charts/kube-ovn/Chart.yaml | 4 +- .../system/kubeovn/charts/kube-ovn/README.md | 12 +++++ .../charts/kube-ovn/templates/_helpers.tpl | 5 +- .../kube-ovn/templates/central-deploy.yaml | 4 ++ .../kube-ovn/templates/controller-deploy.yaml | 4 ++ .../templates/ic-controller-deploy.yaml | 4 ++ .../kube-ovn/templates/kube-ovn-crd.yaml | 48 +++++++++++++++++++ .../kube-ovn/templates/monitor-deploy.yaml | 4 ++ .../kube-ovn/templates/ovn-dpdk-ds.yaml | 4 ++ .../charts/kube-ovn/templates/ovn-sa.yaml | 4 ++ .../charts/kube-ovn/templates/ovncni-ds.yaml | 17 +++++-- .../charts/kube-ovn/templates/ovsovn-ds.yaml | 5 ++ .../charts/kube-ovn/templates/pinger-ds.yaml | 6 ++- .../kube-ovn/templates/post-delete-hook.yaml | 6 ++- .../kube-ovn/templates/upgrade-ovs-ovn.yaml | 6 ++- .../kubeovn/charts/kube-ovn/values.yaml | 3 +- packages/system/kubeovn/values.yaml | 2 +- 19 files changed, 129 insertions(+), 13 deletions(-) diff --git a/packages/system/kubeovn/Chart.yaml b/packages/system/kubeovn/Chart.yaml index d1532794..b1a4e05b 100644 --- a/packages/system/kubeovn/Chart.yaml +++ b/packages/system/kubeovn/Chart.yaml @@ -1,3 +1,3 @@ apiVersion: v2 name: cozy-kubeovn -version: 0.39.0 +version: 0.38.0 diff --git a/packages/system/kubeovn/Makefile b/packages/system/kubeovn/Makefile index a4a0d1ed..45c5ab25 100644 --- a/packages/system/kubeovn/Makefile +++ b/packages/system/kubeovn/Makefile @@ -1,4 +1,4 @@ -KUBEOVN_TAG=v0.39.0 +KUBEOVN_TAG=v0.40.0 export NAME=kubeovn export NAMESPACE=cozy-$(NAME) diff --git a/packages/system/kubeovn/charts/kube-ovn/Chart.yaml b/packages/system/kubeovn/charts/kube-ovn/Chart.yaml index f7be2d3b..0621c7c7 100644 --- a/packages/system/kubeovn/charts/kube-ovn/Chart.yaml +++ b/packages/system/kubeovn/charts/kube-ovn/Chart.yaml @@ -15,12 +15,12 @@ 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: v1.14.11 +version: v1.14.25 # 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 # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "1.14.11" +appVersion: "1.14.25" kubeVersion: ">= 1.29.0-0" diff --git a/packages/system/kubeovn/charts/kube-ovn/README.md b/packages/system/kubeovn/charts/kube-ovn/README.md index 3af408e6..74e5c3f1 100644 --- a/packages/system/kubeovn/charts/kube-ovn/README.md +++ b/packages/system/kubeovn/charts/kube-ovn/README.md @@ -2,6 +2,18 @@ Currently supported version: 1.9 +## Installing the Chart + +### From OCI Registry + +The Helm chart is available from GitHub Container Registry: + +```bash +helm install kube-ovn oci://ghcr.io/kubeovn/charts/kube-ovn --version v1.15.0 +``` + +### From Source + Installation : ```bash diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/_helpers.tpl b/packages/system/kubeovn/charts/kube-ovn/templates/_helpers.tpl index e6697c6e..fd6db240 100644 --- a/packages/system/kubeovn/charts/kube-ovn/templates/_helpers.tpl +++ b/packages/system/kubeovn/charts/kube-ovn/templates/_helpers.tpl @@ -1,8 +1,10 @@ {{/* -Get IP-addresses of master nodes +Get IP-addresses of master nodes. If no nodes are returned, we assume this is +a dry-run/template call and return nothing. */}} {{- define "kubeovn.nodeIPs" -}} {{- $nodes := lookup "v1" "Node" "" "" -}} +{{- if $nodes -}} {{- $ips := list -}} {{- range $node := $nodes.items -}} {{- $label := splitList "=" $.Values.MASTER_NODES_LABEL }} @@ -25,6 +27,7 @@ Get IP-addresses of master nodes {{- end -}} {{ join "," $ips }} {{- end -}} +{{- end -}} {{/* Number of master nodes diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/central-deploy.yaml b/packages/system/kubeovn/charts/kube-ovn/templates/central-deploy.yaml index bbc1e09d..505e0925 100644 --- a/packages/system/kubeovn/charts/kube-ovn/templates/central-deploy.yaml +++ b/packages/system/kubeovn/charts/kube-ovn/templates/central-deploy.yaml @@ -39,7 +39,11 @@ spec: topologyKey: kubernetes.io/hostname priorityClassName: system-cluster-critical serviceAccountName: ovn-ovs + automountServiceAccountToken: true hostNetwork: true + securityContext: + seccompProfile: + type: RuntimeDefault initContainers: - name: hostpath-init image: {{ .Values.global.registry.address }}/{{ .Values.global.images.kubeovn.repository }}:{{ .Values.global.images.kubeovn.tag }} diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/controller-deploy.yaml b/packages/system/kubeovn/charts/kube-ovn/templates/controller-deploy.yaml index 5c4587f9..cd0728b3 100644 --- a/packages/system/kubeovn/charts/kube-ovn/templates/controller-deploy.yaml +++ b/packages/system/kubeovn/charts/kube-ovn/templates/controller-deploy.yaml @@ -46,7 +46,11 @@ spec: topologyKey: kubernetes.io/hostname priorityClassName: system-cluster-critical serviceAccountName: ovn + automountServiceAccountToken: true hostNetwork: true + securityContext: + seccompProfile: + type: RuntimeDefault initContainers: - name: hostpath-init image: {{ .Values.global.registry.address }}/{{ .Values.global.images.kubeovn.repository }}:{{ .Values.global.images.kubeovn.tag }} diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/ic-controller-deploy.yaml b/packages/system/kubeovn/charts/kube-ovn/templates/ic-controller-deploy.yaml index ee3e1461..53ecfa24 100644 --- a/packages/system/kubeovn/charts/kube-ovn/templates/ic-controller-deploy.yaml +++ b/packages/system/kubeovn/charts/kube-ovn/templates/ic-controller-deploy.yaml @@ -40,7 +40,11 @@ spec: topologyKey: kubernetes.io/hostname priorityClassName: system-cluster-critical serviceAccountName: ovn + automountServiceAccountToken: true hostNetwork: true + securityContext: + seccompProfile: + type: RuntimeDefault initContainers: - name: hostpath-init image: {{ .Values.global.registry.address }}/{{ .Values.global.images.kubeovn.repository }}:{{ .Values.global.images.kubeovn.tag }} diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/kube-ovn-crd.yaml b/packages/system/kubeovn/charts/kube-ovn/templates/kube-ovn-crd.yaml index 3bddfbe1..78ac7d38 100644 --- a/packages/system/kubeovn/charts/kube-ovn/templates/kube-ovn-crd.yaml +++ b/packages/system/kubeovn/charts/kube-ovn/templates/kube-ovn-crd.yaml @@ -1200,6 +1200,52 @@ spec: required: - key - operator + tolerations: + description: optional tolerations applied to the workload pods + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + enum: + - NoSchedule + - PreferNoSchedule + - NoExecute + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + enum: + - Exists + - Equal + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -2871,6 +2917,8 @@ spec: type: array items: type: string + autoCreateVlanSubinterfaces: + type: boolean required: - defaultInterface status: diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/monitor-deploy.yaml b/packages/system/kubeovn/charts/kube-ovn/templates/monitor-deploy.yaml index e4c3322c..dc4eac22 100644 --- a/packages/system/kubeovn/charts/kube-ovn/templates/monitor-deploy.yaml +++ b/packages/system/kubeovn/charts/kube-ovn/templates/monitor-deploy.yaml @@ -37,7 +37,11 @@ spec: topologyKey: kubernetes.io/hostname priorityClassName: system-cluster-critical serviceAccountName: kube-ovn-app + automountServiceAccountToken: true hostNetwork: true + securityContext: + seccompProfile: + type: RuntimeDefault initContainers: - name: hostpath-init image: {{ .Values.global.registry.address }}/{{ .Values.global.images.kubeovn.repository }}:{{ .Values.global.images.kubeovn.tag }} diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/ovn-dpdk-ds.yaml b/packages/system/kubeovn/charts/kube-ovn/templates/ovn-dpdk-ds.yaml index 9a1d591f..330c9b6f 100644 --- a/packages/system/kubeovn/charts/kube-ovn/templates/ovn-dpdk-ds.yaml +++ b/packages/system/kubeovn/charts/kube-ovn/templates/ovn-dpdk-ds.yaml @@ -27,8 +27,12 @@ spec: - operator: Exists priorityClassName: system-node-critical serviceAccountName: ovn-ovs + automountServiceAccountToken: true hostNetwork: true hostPID: true + securityContext: + seccompProfile: + type: RuntimeDefault containers: - name: openvswitch image: {{ .Values.global.registry.address }}/{{ .Values.global.images.kubeovn.repository }}:{{ .Values.DPDK_IMAGE_TAG }} diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/ovn-sa.yaml b/packages/system/kubeovn/charts/kube-ovn/templates/ovn-sa.yaml index 1e5e9b5c..744b3b90 100644 --- a/packages/system/kubeovn/charts/kube-ovn/templates/ovn-sa.yaml +++ b/packages/system/kubeovn/charts/kube-ovn/templates/ovn-sa.yaml @@ -3,6 +3,7 @@ kind: ServiceAccount metadata: name: ovn namespace: {{ .Values.namespace }} +automountServiceAccountToken: false {{- if .Values.global.registry.imagePullSecrets }} imagePullSecrets: {{- range $index, $secret := .Values.global.registry.imagePullSecrets }} @@ -18,6 +19,7 @@ kind: ServiceAccount metadata: name: ovn-ovs namespace: {{ .Values.namespace }} +automountServiceAccountToken: false {{- if .Values.global.registry.imagePullSecrets }} imagePullSecrets: {{- range $index, $secret := .Values.global.registry.imagePullSecrets }} @@ -33,6 +35,7 @@ kind: ServiceAccount metadata: name: kube-ovn-cni namespace: {{ .Values.namespace }} +automountServiceAccountToken: false {{- if .Values.global.registry.imagePullSecrets }} imagePullSecrets: {{- range $index, $secret := .Values.global.registry.imagePullSecrets }} @@ -48,6 +51,7 @@ kind: ServiceAccount metadata: name: kube-ovn-app namespace: {{ .Values.namespace }} +automountServiceAccountToken: false {{- if .Values.global.registry.imagePullSecrets }} imagePullSecrets: {{- range $index, $secret := .Values.global.registry.imagePullSecrets }} diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml b/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml index 947ec454..c68e041d 100644 --- a/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml +++ b/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml @@ -26,8 +26,12 @@ spec: operator: Exists priorityClassName: system-node-critical serviceAccountName: kube-ovn-cni + automountServiceAccountToken: true hostNetwork: true hostPID: true + securityContext: + seccompProfile: + type: RuntimeDefault initContainers: - name: hostpath-init image: {{ .Values.global.registry.address }}/{{ .Values.global.images.kubeovn.repository }}:{{ .Values.global.images.kubeovn.tag }} @@ -35,7 +39,9 @@ spec: command: - sh - -xec - - iptables -V + - | + chmod +t /usr/local/sbin + iptables -V securityContext: allowPrivilegeEscalation: true capabilities: @@ -60,16 +66,21 @@ spec: imagePullPolicy: {{ .Values.image.pullPolicy }} command: - /kube-ovn/install-cni.sh - - --cni-conf-dir={{ .Values.cni_conf.CNI_CONF_DIR }} + - --cni-conf-dir={{ .Values.cni_conf.MOUNT_CNI_CONF_DIR }} - --cni-conf-file={{ .Values.cni_conf.CNI_CONF_FILE }} - --cni-conf-name={{- .Values.cni_conf.CNI_CONFIG_PRIORITY -}}-kube-ovn.conflist + env: + - name: POD_IPS + valueFrom: + fieldRef: + fieldPath: status.podIPs securityContext: runAsUser: 0 privileged: true volumeMounts: - mountPath: /opt/cni/bin name: cni-bin - - mountPath: /etc/cni/net.d + - mountPath: {{ .Values.cni_conf.MOUNT_CNI_CONF_DIR }} name: cni-conf {{- if .Values.cni_conf.MOUNT_LOCAL_BIN_DIR }} - mountPath: /usr/local/bin diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/ovsovn-ds.yaml b/packages/system/kubeovn/charts/kube-ovn/templates/ovsovn-ds.yaml index 17743d5f..7146ec71 100644 --- a/packages/system/kubeovn/charts/kube-ovn/templates/ovsovn-ds.yaml +++ b/packages/system/kubeovn/charts/kube-ovn/templates/ovsovn-ds.yaml @@ -34,8 +34,12 @@ spec: operator: Exists priorityClassName: system-node-critical serviceAccountName: ovn-ovs + automountServiceAccountToken: true hostNetwork: true hostPID: true + securityContext: + seccompProfile: + type: RuntimeDefault initContainers: - name: hostpath-init image: {{ .Values.global.registry.address }}/{{ .Values.global.images.kubeovn.repository }}:{{ .Values.global.images.kubeovn.tag }} @@ -44,6 +48,7 @@ spec: - sh - -xec - | + chmod +t /usr/local/sbin chown -R nobody: /var/run/ovn /var/log/ovn /etc/openvswitch /var/run/openvswitch /var/log/openvswitch iptables -V {{- if not .Values.DISABLE_MODULES_MANAGEMENT }} diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/pinger-ds.yaml b/packages/system/kubeovn/charts/kube-ovn/templates/pinger-ds.yaml index 66a34853..fbc82171 100644 --- a/packages/system/kubeovn/charts/kube-ovn/templates/pinger-ds.yaml +++ b/packages/system/kubeovn/charts/kube-ovn/templates/pinger-ds.yaml @@ -28,7 +28,11 @@ spec: - key: CriticalAddonsOnly operator: Exists serviceAccountName: kube-ovn-app - hostPID: true + automountServiceAccountToken: true + hostPID: false + securityContext: + seccompProfile: + type: RuntimeDefault initContainers: - name: hostpath-init image: {{ .Values.global.registry.address }}/{{ .Values.global.images.kubeovn.repository }}:{{ .Values.global.images.kubeovn.tag }} diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/post-delete-hook.yaml b/packages/system/kubeovn/charts/kube-ovn/templates/post-delete-hook.yaml index a4c0d618..682b5a96 100644 --- a/packages/system/kubeovn/charts/kube-ovn/templates/post-delete-hook.yaml +++ b/packages/system/kubeovn/charts/kube-ovn/templates/post-delete-hook.yaml @@ -9,6 +9,7 @@ metadata: "helm.sh/hook": post-delete "helm.sh/hook-weight": "1" "helm.sh/hook-delete-policy": hook-succeeded +automountServiceAccountToken: false --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -102,8 +103,11 @@ spec: hostNetwork: true nodeSelector: kubernetes.io/os: "linux" - serviceAccount: kube-ovn-post-delete-hook serviceAccountName: kube-ovn-post-delete-hook + automountServiceAccountToken: true + securityContext: + seccompProfile: + type: RuntimeDefault containers: - name: remove-subnet-finalizer image: "{{ .Values.global.registry.address}}/{{ .Values.global.images.kubeovn.repository }}:{{ .Values.global.images.kubeovn.tag }}" diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/upgrade-ovs-ovn.yaml b/packages/system/kubeovn/charts/kube-ovn/templates/upgrade-ovs-ovn.yaml index fc5ac4ba..ab646e03 100644 --- a/packages/system/kubeovn/charts/kube-ovn/templates/upgrade-ovs-ovn.yaml +++ b/packages/system/kubeovn/charts/kube-ovn/templates/upgrade-ovs-ovn.yaml @@ -11,6 +11,7 @@ metadata: "helm.sh/hook": post-upgrade "helm.sh/hook-weight": "1" "helm.sh/hook-delete-policy": hook-succeeded +automountServiceAccountToken: false --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -133,8 +134,11 @@ spec: hostNetwork: true nodeSelector: kubernetes.io/os: "linux" - serviceAccount: ovs-ovn-upgrade serviceAccountName: ovs-ovn-upgrade + automountServiceAccountToken: true + securityContext: + seccompProfile: + type: RuntimeDefault containers: - name: ovs-ovn-upgrade image: "{{ .Values.global.registry.address}}/{{ .Values.global.images.kubeovn.repository }}:{{ .Values.global.images.kubeovn.tag }}" diff --git a/packages/system/kubeovn/charts/kube-ovn/values.yaml b/packages/system/kubeovn/charts/kube-ovn/values.yaml index 3652386d..430ea428 100644 --- a/packages/system/kubeovn/charts/kube-ovn/values.yaml +++ b/packages/system/kubeovn/charts/kube-ovn/values.yaml @@ -9,7 +9,7 @@ global: kubeovn: repository: kube-ovn vpcRepository: vpc-nat-gateway - tag: v1.14.11 + tag: v1.14.25 support_arm: true thirdparty: true @@ -111,6 +111,7 @@ debug: cni_conf: CNI_CONFIG_PRIORITY: "01" CNI_CONF_DIR: "/etc/cni/net.d" + MOUNT_CNI_CONF_DIR: "/etc/cni/net.d" CNI_BIN_DIR: "/opt/cni/bin" CNI_CONF_FILE: "/kube-ovn/01-kube-ovn.conflist" LOCAL_BIN_DIR: "/usr/local/bin" diff --git a/packages/system/kubeovn/values.yaml b/packages/system/kubeovn/values.yaml index 89f20e7c..700960ee 100644 --- a/packages/system/kubeovn/values.yaml +++ b/packages/system/kubeovn/values.yaml @@ -65,4 +65,4 @@ global: images: kubeovn: repository: kubeovn - tag: v1.14.11@sha256:0e3e9db960a9600d58c33c0787cabd0e9bf263930fd8c9fe65417e258c383d01 + tag: v1.14.25@sha256:d0b29daaf36e81cac0f9fb15d0ea6b1b49f1abba81a14c73b88a2e60ffcc5978 From ee600b0ce67413e684f9808c88191054c69acab7 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Thu, 8 Jan 2026 23:14:34 +0100 Subject: [PATCH 37/43] [multus] Remove memory limit (#1834) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes multus memory limit due to short but unpredictable and large memory consumption in some cases, such as starting up after a node reboot (reported up to 3Gi). The root cause will be fixed in future releases. ```release-note Multus memory limit removed. ``` * **Chores** * Updated Multus system namespace configuration and DaemonSet naming for improved environment organization. * Adjusted container resource allocation: increased memory requests and refined memory limits for optimized performance. * Updated deployment template specifications to reflect infrastructure changes. ✏️ Tip: You can customize this high-level summary in your review settings. --- packages/system/multus/templates/multus-daemonset-thick.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/system/multus/templates/multus-daemonset-thick.yml b/packages/system/multus/templates/multus-daemonset-thick.yml index 7d99ab98..2f00de85 100644 --- a/packages/system/multus/templates/multus-daemonset-thick.yml +++ b/packages/system/multus/templates/multus-daemonset-thick.yml @@ -162,7 +162,6 @@ spec: memory: "100Mi" limits: cpu: "100m" - memory: "300Mi" securityContext: privileged: true terminationMessagePolicy: FallbackToLogsOnError From cbe36e4ccf9615c4ce102bea1021ba1dec527ae9 Mon Sep 17 00:00:00 2001 From: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com> Date: Fri, 9 Jan 2026 01:33:57 +0000 Subject: [PATCH 38/43] Prepare release v0.39.3 Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com> --- packages/apps/http-cache/images/nginx-cache.tag | 2 +- packages/apps/kubernetes/images/cluster-autoscaler.tag | 2 +- packages/apps/kubernetes/images/kubevirt-cloud-provider.tag | 2 +- packages/apps/kubernetes/images/kubevirt-csi-driver.tag | 2 +- packages/apps/kubernetes/images/ubuntu-container-disk.tag | 2 +- packages/apps/mysql/images/mariadb-backup.tag | 2 +- packages/core/installer/values.yaml | 2 +- packages/core/testing/values.yaml | 2 +- packages/extra/bootbox/images/matchbox.tag | 2 +- packages/extra/monitoring/images/grafana.tag | 2 +- packages/extra/seaweedfs/images/objectstorage-sidecar.tag | 2 +- packages/system/bucket/images/s3manager.tag | 2 +- packages/system/cozystack-api/values.yaml | 2 +- packages/system/cozystack-controller/values.yaml | 4 ++-- packages/system/dashboard/templates/configmap.yaml | 2 +- packages/system/dashboard/values.yaml | 6 +++--- packages/system/kamaji/values.yaml | 4 ++-- packages/system/kubeovn-plunger/values.yaml | 2 +- packages/system/kubeovn-webhook/values.yaml | 2 +- packages/system/kubevirt-csi-node/values.yaml | 2 +- packages/system/lineage-controller-webhook/values.yaml | 2 +- packages/system/linstor/values.yaml | 2 +- packages/system/metallb/values.yaml | 4 ++-- packages/system/objectstorage-controller/values.yaml | 2 +- packages/system/seaweedfs/values.yaml | 2 +- 25 files changed, 30 insertions(+), 30 deletions(-) diff --git a/packages/apps/http-cache/images/nginx-cache.tag b/packages/apps/http-cache/images/nginx-cache.tag index a5e4ca7b..3f0bbd33 100644 --- a/packages/apps/http-cache/images/nginx-cache.tag +++ b/packages/apps/http-cache/images/nginx-cache.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/nginx-cache:0.0.0@sha256:b7633717cd7449c0042ae92d8ca9b36e4d69566561f5c7d44e21058e7d05c6d5 +ghcr.io/cozystack/cozystack/nginx-cache:0.0.0@sha256:31ebc09cfa11d8b438d2bbb32fa61b133aaf4b48b1a1282c9e59b5c127af61c1 diff --git a/packages/apps/kubernetes/images/cluster-autoscaler.tag b/packages/apps/kubernetes/images/cluster-autoscaler.tag index 56fcb024..b1c2fe04 100644 --- a/packages/apps/kubernetes/images/cluster-autoscaler.tag +++ b/packages/apps/kubernetes/images/cluster-autoscaler.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/cluster-autoscaler:0.0.0@sha256:e1c0eb54d0ddadc8c7d72cee4f4282d56c957bf4ff0f62ef37db6b38dd0e8a01 +ghcr.io/cozystack/cozystack/cluster-autoscaler:0.0.0@sha256:372ad087ae96bd0cd642e2b0855ec7ffb1369d6cf4f0b92204725557c11bc0ff diff --git a/packages/apps/kubernetes/images/kubevirt-cloud-provider.tag b/packages/apps/kubernetes/images/kubevirt-cloud-provider.tag index 8120dd48..ca661f3a 100644 --- a/packages/apps/kubernetes/images/kubevirt-cloud-provider.tag +++ b/packages/apps/kubernetes/images/kubevirt-cloud-provider.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/kubevirt-cloud-provider:0.0.0@sha256:5335c044313b69ee13b30ca4941687e509005e55f4ae25723861edbf2fbd6dd2 +ghcr.io/cozystack/cozystack/kubevirt-cloud-provider:0.0.0@sha256:dee69d15fa8616aa6a1e5a67fc76370e7698a7f58b25e30650eb39c9fb826de8 diff --git a/packages/apps/kubernetes/images/kubevirt-csi-driver.tag b/packages/apps/kubernetes/images/kubevirt-csi-driver.tag index 0e97fa7a..ccb369a3 100644 --- a/packages/apps/kubernetes/images/kubevirt-csi-driver.tag +++ b/packages/apps/kubernetes/images/kubevirt-csi-driver.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:ae0c5e3e005388d865617097a9fe4b4e8a2be6b62cec893e08f2143d0acde241 +ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:b42c6af641ee0eadb7e0a42e368021b4759f443cb7b71b7e745a64f0fc8b752e diff --git a/packages/apps/kubernetes/images/ubuntu-container-disk.tag b/packages/apps/kubernetes/images/ubuntu-container-disk.tag index a35d1278..06de29fa 100644 --- a/packages/apps/kubernetes/images/ubuntu-container-disk.tag +++ b/packages/apps/kubernetes/images/ubuntu-container-disk.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/ubuntu-container-disk:v1.33@sha256:a09724a7f95283f9130b3da2a89d81c4c6051c6edf0392a81b6fc90f404b76b6 +ghcr.io/cozystack/cozystack/ubuntu-container-disk:v1.33@sha256:d25e567bc8b17b596e050f5ff410e36112c7966e33f4b372c752e7350bacc894 diff --git a/packages/apps/mysql/images/mariadb-backup.tag b/packages/apps/mysql/images/mariadb-backup.tag index af6247da..792c010b 100644 --- a/packages/apps/mysql/images/mariadb-backup.tag +++ b/packages/apps/mysql/images/mariadb-backup.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/mariadb-backup:0.0.0@sha256:1c0beb1b23a109b0e13727b4c73d2c74830e11cede92858ab20101b66f45a858 +ghcr.io/cozystack/cozystack/mariadb-backup:0.0.0@sha256:aca403030ff5d831415d72367866fdf291fab73ee2cfddbe4c93c2915a316ab1 diff --git a/packages/core/installer/values.yaml b/packages/core/installer/values.yaml index 9de2bcff..97945ea8 100644 --- a/packages/core/installer/values.yaml +++ b/packages/core/installer/values.yaml @@ -1,2 +1,2 @@ cozystack: - image: ghcr.io/cozystack/cozystack/installer:v0.39.2@sha256:1c0eef43e1a06f5bf653c0bb7a2821a623fcad71c41c2c15b080fe0f6c809e39 + image: ghcr.io/cozystack/cozystack/installer:v0.39.3@sha256:adc178641d41a210d7f2dad45431c54d4e9b0f14109b18570146c64b4e273fec diff --git a/packages/core/testing/values.yaml b/packages/core/testing/values.yaml index e6bd42c8..8f1d9658 100644 --- a/packages/core/testing/values.yaml +++ b/packages/core/testing/values.yaml @@ -1,2 +1,2 @@ e2e: - image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.39.2@sha256:9fe32b5faf233bdbae27859f1c6aaa229230b0ac9ee5212a1ddf2763182cea0f + image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.39.3@sha256:3395a0e3c02e85878a44d3177cae3c37b087edeb4fab6547cb8227862b1de773 diff --git a/packages/extra/bootbox/images/matchbox.tag b/packages/extra/bootbox/images/matchbox.tag index 9a13bbb8..ba4ab2ed 100644 --- a/packages/extra/bootbox/images/matchbox.tag +++ b/packages/extra/bootbox/images/matchbox.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/matchbox:v0.39.2@sha256:80da0287d6705ffaec918d1d7dc02f1d0a512045c56b78afb2707743d09e629e +ghcr.io/cozystack/cozystack/matchbox:v0.39.3@sha256:5cada8140a77e12d2d45e19e5944c131931f0d466f1ce51dc3c72b23552edd05 diff --git a/packages/extra/monitoring/images/grafana.tag b/packages/extra/monitoring/images/grafana.tag index 9d53b4f1..06fa403d 100644 --- a/packages/extra/monitoring/images/grafana.tag +++ b/packages/extra/monitoring/images/grafana.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/grafana:0.0.0@sha256:c63978e1ed0304e8518b31ddee56c4e8115541b997d8efbe1c0a74da57140399 +ghcr.io/cozystack/cozystack/grafana:0.0.0@sha256:8ce0cd90c8f614cdabf5a41f8aa50b7dfbd02b31b9a0bd7897927e7f89968e07 diff --git a/packages/extra/seaweedfs/images/objectstorage-sidecar.tag b/packages/extra/seaweedfs/images/objectstorage-sidecar.tag index 1f75983e..b6d5371a 100644 --- a/packages/extra/seaweedfs/images/objectstorage-sidecar.tag +++ b/packages/extra/seaweedfs/images/objectstorage-sidecar.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.2@sha256:b180a6c4ce4d46cdf31af2731cc8b477e80ade99d4296d507ec5edb38c56a1ea +ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.3@sha256:2d1833c78c35b697a3634d4b3be9a3218edae95a77583e9e121c10a92e7433ec diff --git a/packages/system/bucket/images/s3manager.tag b/packages/system/bucket/images/s3manager.tag index 641bb877..3574feff 100644 --- a/packages/system/bucket/images/s3manager.tag +++ b/packages/system/bucket/images/s3manager.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/s3manager:v0.5.0@sha256:7dde8d748442c4457fb7bf67c0e0f4abf0da60af00a9171c6d4c0bfcc8a8b9c5 +ghcr.io/cozystack/cozystack/s3manager:v0.5.0@sha256:ecb140d026ed72660306953a7eec140d7ac81e79544d5bbf1aba5f62aa5f8b69 diff --git a/packages/system/cozystack-api/values.yaml b/packages/system/cozystack-api/values.yaml index e61ab611..4b1fa676 100644 --- a/packages/system/cozystack-api/values.yaml +++ b/packages/system/cozystack-api/values.yaml @@ -1,5 +1,5 @@ cozystackAPI: - image: ghcr.io/cozystack/cozystack/cozystack-api:v0.39.2@sha256:e859dc81b4905fa163b75b1d567e91bd1eac572f85931954c2dc646cb07d3959 + image: ghcr.io/cozystack/cozystack/cozystack-api:v0.39.3@sha256:51574c6bb61ae31e63193f84daf18c14ceb71580786e262191c4aa0ac44b1519 localK8sAPIEndpoint: enabled: true replicas: 2 diff --git a/packages/system/cozystack-controller/values.yaml b/packages/system/cozystack-controller/values.yaml index 41cda67a..b3536c25 100644 --- a/packages/system/cozystack-controller/values.yaml +++ b/packages/system/cozystack-controller/values.yaml @@ -1,6 +1,6 @@ cozystackController: - image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.39.2@sha256:b96283a1774f23735849802069a907cb85f4fd57df89f8740a954a7d2922afc3 + image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.39.3@sha256:904e447df43e7d79d124be5caa4a1d2bb3a41e0b5ba48f2ff5ff49e4eb82ac47 debug: false disableTelemetry: false - cozystackVersion: "v0.39.2" + cozystackVersion: "v0.39.3" cozystackAPIKind: "DaemonSet" diff --git a/packages/system/dashboard/templates/configmap.yaml b/packages/system/dashboard/templates/configmap.yaml index c74d63bf..bfc65ae1 100644 --- a/packages/system/dashboard/templates/configmap.yaml +++ b/packages/system/dashboard/templates/configmap.yaml @@ -1,6 +1,6 @@ {{- $brandingConfig:= lookup "v1" "ConfigMap" "cozy-system" "cozystack-branding" }} -{{- $tenantText := "v0.39.2" }} +{{- $tenantText := "v0.39.3" }} {{- $footerText := "Cozystack" }} {{- $titleText := "Cozystack Dashboard" }} {{- $logoText := "" }} diff --git a/packages/system/dashboard/values.yaml b/packages/system/dashboard/values.yaml index 237dfb45..45caa6eb 100644 --- a/packages/system/dashboard/values.yaml +++ b/packages/system/dashboard/values.yaml @@ -1,6 +1,6 @@ openapiUI: - image: ghcr.io/cozystack/cozystack/openapi-ui:v0.39.2@sha256:fddab274cd6e0c590aed0a49faba584c2b34fe875c7deaab9c96678c4e33cd3d + image: ghcr.io/cozystack/cozystack/openapi-ui:v0.39.3@sha256:13fd38cf733c9b2ddde21c4189837729ef92fc0b1df987adc3cbdd591d005af2 openapiUIK8sBff: - image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.39.2@sha256:70b68d8666220b0b56dbdbda0297d85cf53c5c4fa225a24a8f36afad1ac65a70 + image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.39.3@sha256:c905f98598526820bd71e3997fdc62868b9c3d7a4e9700b01d73b017b0953257 tokenProxy: - image: ghcr.io/cozystack/cozystack/token-proxy:v0.39.2@sha256:fad27112617bb17816702571e1f39d0ac3fe5283468d25eb12f79906cdab566b + image: ghcr.io/cozystack/cozystack/token-proxy:v0.39.3@sha256:4fc8a11f8a1a81aa0774ae2b1ed2e05d36d0b3ef1e37979cc4994e65114d93ae diff --git a/packages/system/kamaji/values.yaml b/packages/system/kamaji/values.yaml index 1b010243..95954a1f 100644 --- a/packages/system/kamaji/values.yaml +++ b/packages/system/kamaji/values.yaml @@ -3,7 +3,7 @@ kamaji: deploy: false image: pullPolicy: IfNotPresent - tag: v0.39.2@sha256:dbf879e70fc4a98070980be8d086fb79dc6a5b3ae4c1a1cc7578df5c39d8bd36 + tag: v0.39.3@sha256:4588de4380fb70c29c4a762fb19a9bbe210e68bc5ff67035c752c44daf319bfc repository: ghcr.io/cozystack/cozystack/kamaji resources: limits: @@ -13,4 +13,4 @@ kamaji: cpu: 100m memory: 100Mi extraArgs: - - --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.39.2@sha256:dbf879e70fc4a98070980be8d086fb79dc6a5b3ae4c1a1cc7578df5c39d8bd36 + - --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.39.3@sha256:4588de4380fb70c29c4a762fb19a9bbe210e68bc5ff67035c752c44daf319bfc diff --git a/packages/system/kubeovn-plunger/values.yaml b/packages/system/kubeovn-plunger/values.yaml index df21d7a8..98edc6b1 100644 --- a/packages/system/kubeovn-plunger/values.yaml +++ b/packages/system/kubeovn-plunger/values.yaml @@ -1,4 +1,4 @@ portSecurity: true routes: "" -image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.39.2@sha256:72bf70c59caa0a196936867297fac38822db09e40742c0762abbed31ab6237b6 +image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.39.3@sha256:aae60ffe66cd82583dc0a7de4cd8a5c4b0a46090a56a98916a0cdb2d1aa6b6e3 ovnCentralName: ovn-central diff --git a/packages/system/kubeovn-webhook/values.yaml b/packages/system/kubeovn-webhook/values.yaml index 13437ce0..44c41ddd 100644 --- a/packages/system/kubeovn-webhook/values.yaml +++ b/packages/system/kubeovn-webhook/values.yaml @@ -1,3 +1,3 @@ portSecurity: true routes: "" -image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.39.2@sha256:d5023bbfe524ec97bc499d853a3fe67affa9b37dd849eac521f38c651d50382c +image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.39.3@sha256:e18f9fd679e38f65362a8d0042f25468272f6d081136ad47027168d8e7e07a4a diff --git a/packages/system/kubevirt-csi-node/values.yaml b/packages/system/kubevirt-csi-node/values.yaml index 101d6d73..4111f825 100644 --- a/packages/system/kubevirt-csi-node/values.yaml +++ b/packages/system/kubevirt-csi-node/values.yaml @@ -1,3 +1,3 @@ storageClass: replicated csiDriver: - image: ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:ae0c5e3e005388d865617097a9fe4b4e8a2be6b62cec893e08f2143d0acde241 + image: ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:b42c6af641ee0eadb7e0a42e368021b4759f443cb7b71b7e745a64f0fc8b752e diff --git a/packages/system/lineage-controller-webhook/values.yaml b/packages/system/lineage-controller-webhook/values.yaml index 29da9b95..7299e072 100644 --- a/packages/system/lineage-controller-webhook/values.yaml +++ b/packages/system/lineage-controller-webhook/values.yaml @@ -1,5 +1,5 @@ lineageControllerWebhook: - image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.39.2@sha256:eb1186a56be49a9e6d65dad7b95febc6446b555d1d2dadf337e9c4a75c43193b + image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.39.3@sha256:044ab44440280de6d9f87791719add0cfeaa630ff655eff7ccbaf35694bbdb6b debug: false localK8sAPIEndpoint: enabled: true diff --git a/packages/system/linstor/values.yaml b/packages/system/linstor/values.yaml index 23179bce..5fa4d16d 100644 --- a/packages/system/linstor/values.yaml +++ b/packages/system/linstor/values.yaml @@ -1,4 +1,4 @@ piraeusServer: image: repository: ghcr.io/cozystack/cozystack/piraeus-server - tag: latest@sha256:417532baa2801288147cd9ac9ae260751c1a7754f0b829725d09b72a770c111a + tag: 1.32.3@sha256:c6fbe1825514a3059088175968a651d7e10f477590023a33f1a9e6584fd98e04 diff --git a/packages/system/metallb/values.yaml b/packages/system/metallb/values.yaml index d392f4c4..dd5f76e6 100644 --- a/packages/system/metallb/values.yaml +++ b/packages/system/metallb/values.yaml @@ -4,8 +4,8 @@ metallb: controller: image: repository: ghcr.io/cozystack/cozystack/metallb-controller - tag: v0.15.2@sha256:0e9080234fc8eedab78ad2831fb38df375c383e901a752d72b353c8d13b9605f + tag: v0.15.2@sha256:623ce74b5802bff6e29f29478ccab29ce4162a64148be006c69e16cc3207e289 speaker: image: repository: ghcr.io/cozystack/cozystack/metallb-speaker - tag: v0.15.2@sha256:e14d4c328c3ab91a6eadfeea90da96388503492d165e7e8582f291b1872e53b2 + tag: v0.15.2@sha256:f264058afd9228452a260ab9c9dd1859404745627a2a38c2ba4671e27f3b3bb2 diff --git a/packages/system/objectstorage-controller/values.yaml b/packages/system/objectstorage-controller/values.yaml index 91b25cc2..ec28244b 100644 --- a/packages/system/objectstorage-controller/values.yaml +++ b/packages/system/objectstorage-controller/values.yaml @@ -1,3 +1,3 @@ objectstorage: controller: - image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.39.2@sha256:494394c28f0487e5382cabe88e77b83ce20235c0fe0b1d14cb81ecc4c4446c49" + image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.39.3@sha256:cbf22bcbeed7049340aa41f41cc130596bdb962873116e0c4eb5bab123ae13b0" diff --git a/packages/system/seaweedfs/values.yaml b/packages/system/seaweedfs/values.yaml index c49b2252..634144ce 100644 --- a/packages/system/seaweedfs/values.yaml +++ b/packages/system/seaweedfs/values.yaml @@ -177,7 +177,7 @@ seaweedfs: bucketClassName: "seaweedfs" region: "" sidecar: - image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.2@sha256:b180a6c4ce4d46cdf31af2731cc8b477e80ade99d4296d507ec5edb38c56a1ea" + image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.3@sha256:2d1833c78c35b697a3634d4b3be9a3218edae95a77583e9e121c10a92e7433ec" certificates: commonName: "SeaweedFS CA" ipAddresses: [] From ce6ec2c0bb350c5787fe16f535efc46b4a2d0471 Mon Sep 17 00:00:00 2001 From: nbykov0 <166552198+nbykov0@users.noreply.github.com> Date: Fri, 9 Jan 2026 19:27:47 +0300 Subject: [PATCH 39/43] [paas-full] Add multus dependency as other CNIs Signed-off-by: nbykov0 <166552198+nbykov0@users.noreply.github.com> --- packages/core/platform/bundles/paas-full.yaml | 87 ++++++++++--------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/packages/core/platform/bundles/paas-full.yaml b/packages/core/platform/bundles/paas-full.yaml index 4382bd62..b96dac5d 100644 --- a/packages/core/platform/bundles/paas-full.yaml +++ b/packages/core/platform/bundles/paas-full.yaml @@ -87,25 +87,25 @@ releases: releaseName: cozystack chart: cozy-cozy-proxy namespace: cozy-system - dependsOn: [cilium,kubeovn] + dependsOn: [cilium,kubeovn,multus] - name: cert-manager-crds releaseName: cert-manager-crds chart: cozy-cert-manager-crds namespace: cozy-cert-manager - dependsOn: [cilium, kubeovn] + dependsOn: [] - name: cozystack-api releaseName: cozystack-api chart: cozy-cozystack-api namespace: cozy-system - dependsOn: [cilium,kubeovn,cozystack-controller] + dependsOn: [cilium,kubeovn,multus,cozystack-controller] - name: cozystack-controller releaseName: cozystack-controller chart: cozy-cozystack-controller namespace: cozy-system - dependsOn: [cilium,kubeovn] + dependsOn: [cilium,kubeovn,multus] {{- if eq (index $cozyConfig.data "telemetry-enabled") "false" }} values: cozystackController: @@ -116,44 +116,44 @@ releases: releaseName: lineage-controller-webhook chart: cozy-lineage-controller-webhook namespace: cozy-system - dependsOn: [cozystack-controller,cilium,kubeovn,cert-manager] + dependsOn: [cozystack-controller,cilium,kubeovn,multus,cert-manager] - name: cozystack-resource-definition-crd releaseName: cozystack-resource-definition-crd chart: cozystack-resource-definition-crd namespace: cozy-system - dependsOn: [cilium,kubeovn,cozystack-api,cozystack-controller] + dependsOn: [cilium,kubeovn,multus,cozystack-api,cozystack-controller] - name: cozystack-resource-definitions releaseName: cozystack-resource-definitions chart: cozystack-resource-definitions namespace: cozy-system - dependsOn: [cilium,kubeovn,cozystack-api,cozystack-controller,cozystack-resource-definition-crd] + dependsOn: [cilium,kubeovn,multus,cozystack-api,cozystack-controller,cozystack-resource-definition-crd] - name: cert-manager releaseName: cert-manager chart: cozy-cert-manager namespace: cozy-cert-manager - dependsOn: [cert-manager-crds] + dependsOn: [cilium,kubeovn,multus,cert-manager-crds] - name: cert-manager-issuers releaseName: cert-manager-issuers chart: cozy-cert-manager-issuers namespace: cozy-cert-manager - dependsOn: [cilium,kubeovn,cert-manager] + dependsOn: [cilium,kubeovn,multus,cert-manager] - name: victoria-metrics-operator releaseName: victoria-metrics-operator chart: cozy-victoria-metrics-operator namespace: cozy-victoria-metrics-operator - dependsOn: [cilium,kubeovn,cert-manager] + dependsOn: [cilium,kubeovn,multus,cert-manager] - name: monitoring-agents releaseName: monitoring-agents chart: cozy-monitoring-agents namespace: cozy-monitoring privileged: true - dependsOn: [victoria-metrics-operator, vertical-pod-autoscaler-crds] + dependsOn: [victoria-metrics-operator,vertical-pod-autoscaler-crds] values: scrapeRules: etcd: @@ -163,14 +163,14 @@ releases: releaseName: kubevirt-operator chart: cozy-kubevirt-operator namespace: cozy-kubevirt - dependsOn: [cilium,kubeovn,victoria-metrics-operator] + dependsOn: [cilium,kubeovn,multus,victoria-metrics-operator] - name: kubevirt releaseName: kubevirt chart: cozy-kubevirt namespace: cozy-kubevirt privileged: true - dependsOn: [cilium,kubeovn,kubevirt-operator] + dependsOn: [cilium,kubeovn,multus,kubevirt-operator] {{- $cpuAllocationRatio := index $cozyConfig.data "cpu-allocation-ratio" }} {{- if $cpuAllocationRatio }} values: @@ -181,19 +181,19 @@ releases: releaseName: kubevirt-instancetypes chart: cozy-kubevirt-instancetypes namespace: cozy-kubevirt - dependsOn: [cilium,kubeovn,kubevirt-operator,kubevirt] + dependsOn: [cilium,kubeovn,multus,kubevirt-operator,kubevirt] - name: kubevirt-cdi-operator releaseName: kubevirt-cdi-operator chart: cozy-kubevirt-cdi-operator namespace: cozy-kubevirt-cdi - dependsOn: [cilium,kubeovn] + dependsOn: [cilium,kubeovn,multus] - name: kubevirt-cdi releaseName: kubevirt-cdi chart: cozy-kubevirt-cdi namespace: cozy-kubevirt-cdi - dependsOn: [cilium,kubeovn,kubevirt-cdi-operator] + dependsOn: [cilium,kubeovn,multus,kubevirt-cdi-operator] - name: gpu-operator releaseName: gpu-operator @@ -201,7 +201,7 @@ releases: namespace: cozy-gpu-operator privileged: true optional: true - dependsOn: [cilium,kubeovn] + dependsOn: [cilium,kubeovn,multus] valuesFiles: - values.yaml - values-talos.yaml @@ -211,25 +211,25 @@ releases: chart: cozy-metallb namespace: cozy-metallb privileged: true - dependsOn: [cilium,kubeovn] + dependsOn: [cilium,kubeovn,multus] - name: etcd-operator releaseName: etcd-operator chart: cozy-etcd-operator namespace: cozy-etcd-operator - dependsOn: [cilium,kubeovn,cert-manager] + dependsOn: [cilium,kubeovn,multus,cert-manager] - name: grafana-operator releaseName: grafana-operator chart: cozy-grafana-operator namespace: cozy-grafana-operator - dependsOn: [cilium,kubeovn] + dependsOn: [cilium,kubeovn,multus] - name: mariadb-operator releaseName: mariadb-operator chart: cozy-mariadb-operator namespace: cozy-mariadb-operator - dependsOn: [cilium,kubeovn,cert-manager,victoria-metrics-operator] + dependsOn: [cilium,kubeovn,multus,cert-manager,victoria-metrics-operator] values: mariadb-operator: clusterName: {{ $clusterDomain }} @@ -238,13 +238,13 @@ releases: releaseName: postgres-operator chart: cozy-postgres-operator namespace: cozy-postgres-operator - dependsOn: [cilium,kubeovn,cert-manager] + dependsOn: [cilium,kubeovn,multus,cert-manager] - name: kafka-operator releaseName: kafka-operator chart: cozy-kafka-operator namespace: cozy-kafka-operator - dependsOn: [cilium,kubeovn,victoria-metrics-operator] + dependsOn: [cilium,kubeovn,multus,victoria-metrics-operator] values: strimzi-kafka-operator: kubernetesServiceDnsDomain: {{ $clusterDomain }} @@ -253,65 +253,65 @@ releases: releaseName: clickhouse-operator chart: cozy-clickhouse-operator namespace: cozy-clickhouse-operator - dependsOn: [cilium,kubeovn,victoria-metrics-operator] + dependsOn: [cilium,kubeovn,multus,victoria-metrics-operator] - name: foundationdb-operator releaseName: foundationdb-operator chart: cozy-foundationdb-operator namespace: cozy-foundationdb-operator - dependsOn: [cilium,kubeovn,cert-manager] + dependsOn: [cilium,kubeovn,multus,cert-manager] - name: rabbitmq-operator releaseName: rabbitmq-operator chart: cozy-rabbitmq-operator namespace: cozy-rabbitmq-operator - dependsOn: [cilium,kubeovn] + dependsOn: [cilium,kubeovn,multus] - name: redis-operator releaseName: redis-operator chart: cozy-redis-operator namespace: cozy-redis-operator - dependsOn: [cilium,kubeovn] + dependsOn: [cilium,kubeovn,multus] - name: piraeus-operator releaseName: piraeus-operator chart: cozy-piraeus-operator namespace: cozy-linstor - dependsOn: [cilium,kubeovn,cert-manager,victoria-metrics-operator] + dependsOn: [cilium,kubeovn,multus,cert-manager,victoria-metrics-operator] - name: linstor releaseName: linstor chart: cozy-linstor namespace: cozy-linstor privileged: true - dependsOn: [piraeus-operator,cilium,kubeovn,cert-manager,snapshot-controller] + dependsOn: [piraeus-operator,cilium,kubeovn,multus,cert-manager,snapshot-controller] - name: nfs-driver releaseName: nfs-driver chart: cozy-nfs-driver namespace: cozy-nfs-driver privileged: true - dependsOn: [cilium,kubeovn] + dependsOn: [cilium,kubeovn,multus] optional: true - name: snapshot-controller releaseName: snapshot-controller chart: cozy-snapshot-controller namespace: cozy-snapshot-controller - dependsOn: [cilium,kubeovn,cert-manager-issuers] + dependsOn: [cilium,kubeovn,multus,cert-manager-issuers] - name: objectstorage-controller releaseName: objectstorage-controller chart: cozy-objectstorage-controller namespace: cozy-objectstorage-controller - dependsOn: [cilium,kubeovn] + dependsOn: [cilium,kubeovn,multus] - name: telepresence releaseName: traffic-manager chart: cozy-telepresence namespace: cozy-telepresence optional: true - dependsOn: [cilium,kubeovn] + dependsOn: [cilium,kubeovn,multus] - name: dashboard releaseName: dashboard @@ -324,6 +324,7 @@ releases: dependsOn: - cilium - kubeovn + - multus {{- if eq $oidcEnabled "true" }} - keycloak-configure {{- end }} @@ -332,56 +333,56 @@ releases: releaseName: kamaji chart: cozy-kamaji namespace: cozy-kamaji - dependsOn: [cilium,kubeovn,cert-manager] + dependsOn: [cilium,kubeovn,multus,cert-manager] - name: capi-operator releaseName: capi-operator chart: cozy-capi-operator namespace: cozy-cluster-api privileged: true - dependsOn: [cilium,kubeovn,cert-manager] + dependsOn: [cilium,kubeovn,multus,cert-manager] - name: capi-providers-bootstrap releaseName: capi-providers-bootstrap chart: cozy-capi-providers-bootstrap namespace: cozy-cluster-api privileged: true - dependsOn: [cilium,kubeovn,capi-operator] + dependsOn: [cilium,kubeovn,multus,capi-operator] - name: capi-providers-core releaseName: capi-providers-core chart: cozy-capi-providers-core namespace: cozy-cluster-api privileged: true - dependsOn: [cilium,kubeovn,capi-operator] + dependsOn: [cilium,kubeovn,multus,capi-operator] - name: capi-providers-cpprovider releaseName: capi-providers-cpprovider chart: cozy-capi-providers-cpprovider namespace: cozy-cluster-api privileged: true - dependsOn: [cilium,kubeovn,capi-operator] + dependsOn: [cilium,kubeovn,multus,capi-operator] - name: capi-providers-infraprovider releaseName: capi-providers-infraprovider chart: cozy-capi-providers-infraprovider namespace: cozy-cluster-api privileged: true - dependsOn: [cilium,kubeovn,capi-operator] + dependsOn: [cilium,kubeovn,multus,capi-operator] - name: external-dns releaseName: external-dns chart: cozy-external-dns namespace: cozy-external-dns optional: true - dependsOn: [cilium,kubeovn] + dependsOn: [cilium,kubeovn,multus] - name: external-secrets-operator releaseName: external-secrets-operator chart: cozy-external-secrets-operator namespace: cozy-external-secrets-operator optional: true - dependsOn: [cilium,kubeovn] + dependsOn: [cilium,kubeovn,multus] - name: bootbox releaseName: bootbox @@ -389,7 +390,7 @@ releases: namespace: cozy-bootbox privileged: true optional: true - dependsOn: [cilium,kubeovn] + dependsOn: [cilium,kubeovn,multus] {{- if $oidcEnabled }} - name: keycloak @@ -438,7 +439,7 @@ releases: chart: cozy-vertical-pod-autoscaler-crds namespace: cozy-vertical-pod-autoscaler privileged: true - dependsOn: [cilium, kubeovn] + dependsOn: [] - name: reloader releaseName: reloader From 909997da1d0d45039ce26959bceb2cf19f04bccc Mon Sep 17 00:00:00 2001 From: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com> Date: Sat, 10 Jan 2026 01:36:19 +0000 Subject: [PATCH 40/43] Prepare release v0.39.4 Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com> --- packages/core/installer/values.yaml | 2 +- packages/core/testing/values.yaml | 2 +- packages/extra/bootbox/images/matchbox.tag | 2 +- packages/extra/seaweedfs/images/objectstorage-sidecar.tag | 2 +- packages/system/cozystack-api/values.yaml | 2 +- packages/system/cozystack-controller/values.yaml | 4 ++-- packages/system/dashboard/templates/configmap.yaml | 2 +- packages/system/dashboard/values.yaml | 6 +++--- packages/system/kamaji/values.yaml | 4 ++-- packages/system/kubeovn-plunger/values.yaml | 2 +- packages/system/kubeovn-webhook/values.yaml | 2 +- packages/system/lineage-controller-webhook/values.yaml | 2 +- packages/system/objectstorage-controller/values.yaml | 2 +- packages/system/seaweedfs/values.yaml | 2 +- 14 files changed, 18 insertions(+), 18 deletions(-) diff --git a/packages/core/installer/values.yaml b/packages/core/installer/values.yaml index 97945ea8..75f5b4ee 100644 --- a/packages/core/installer/values.yaml +++ b/packages/core/installer/values.yaml @@ -1,2 +1,2 @@ cozystack: - image: ghcr.io/cozystack/cozystack/installer:v0.39.3@sha256:adc178641d41a210d7f2dad45431c54d4e9b0f14109b18570146c64b4e273fec + image: ghcr.io/cozystack/cozystack/installer:v0.39.4@sha256:81004b1328583814ab99965cc2241bc84cd3866970a087930e5fe691a55f32bf diff --git a/packages/core/testing/values.yaml b/packages/core/testing/values.yaml index 8f1d9658..89ac68a4 100644 --- a/packages/core/testing/values.yaml +++ b/packages/core/testing/values.yaml @@ -1,2 +1,2 @@ e2e: - image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.39.3@sha256:3395a0e3c02e85878a44d3177cae3c37b087edeb4fab6547cb8227862b1de773 + image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.39.4@sha256:3395a0e3c02e85878a44d3177cae3c37b087edeb4fab6547cb8227862b1de773 diff --git a/packages/extra/bootbox/images/matchbox.tag b/packages/extra/bootbox/images/matchbox.tag index ba4ab2ed..27247fe5 100644 --- a/packages/extra/bootbox/images/matchbox.tag +++ b/packages/extra/bootbox/images/matchbox.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/matchbox:v0.39.3@sha256:5cada8140a77e12d2d45e19e5944c131931f0d466f1ce51dc3c72b23552edd05 +ghcr.io/cozystack/cozystack/matchbox:v0.39.4@sha256:b2eca3ab3c844a527617449c3167ecdf80db052b9c91f028c139e2e1143de365 diff --git a/packages/extra/seaweedfs/images/objectstorage-sidecar.tag b/packages/extra/seaweedfs/images/objectstorage-sidecar.tag index b6d5371a..d1488b54 100644 --- a/packages/extra/seaweedfs/images/objectstorage-sidecar.tag +++ b/packages/extra/seaweedfs/images/objectstorage-sidecar.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.3@sha256:2d1833c78c35b697a3634d4b3be9a3218edae95a77583e9e121c10a92e7433ec +ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.4@sha256:2d1833c78c35b697a3634d4b3be9a3218edae95a77583e9e121c10a92e7433ec diff --git a/packages/system/cozystack-api/values.yaml b/packages/system/cozystack-api/values.yaml index 4b1fa676..44edd320 100644 --- a/packages/system/cozystack-api/values.yaml +++ b/packages/system/cozystack-api/values.yaml @@ -1,5 +1,5 @@ cozystackAPI: - image: ghcr.io/cozystack/cozystack/cozystack-api:v0.39.3@sha256:51574c6bb61ae31e63193f84daf18c14ceb71580786e262191c4aa0ac44b1519 + image: ghcr.io/cozystack/cozystack/cozystack-api:v0.39.4@sha256:51574c6bb61ae31e63193f84daf18c14ceb71580786e262191c4aa0ac44b1519 localK8sAPIEndpoint: enabled: true replicas: 2 diff --git a/packages/system/cozystack-controller/values.yaml b/packages/system/cozystack-controller/values.yaml index b3536c25..8f47d088 100644 --- a/packages/system/cozystack-controller/values.yaml +++ b/packages/system/cozystack-controller/values.yaml @@ -1,6 +1,6 @@ cozystackController: - image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.39.3@sha256:904e447df43e7d79d124be5caa4a1d2bb3a41e0b5ba48f2ff5ff49e4eb82ac47 + image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.39.4@sha256:94fde65fe25af01c977db2b16a64703b740f2833f9c878894a8cc8247de21fa2 debug: false disableTelemetry: false - cozystackVersion: "v0.39.3" + cozystackVersion: "v0.39.4" cozystackAPIKind: "DaemonSet" diff --git a/packages/system/dashboard/templates/configmap.yaml b/packages/system/dashboard/templates/configmap.yaml index bfc65ae1..27204801 100644 --- a/packages/system/dashboard/templates/configmap.yaml +++ b/packages/system/dashboard/templates/configmap.yaml @@ -1,6 +1,6 @@ {{- $brandingConfig:= lookup "v1" "ConfigMap" "cozy-system" "cozystack-branding" }} -{{- $tenantText := "v0.39.3" }} +{{- $tenantText := "v0.39.4" }} {{- $footerText := "Cozystack" }} {{- $titleText := "Cozystack Dashboard" }} {{- $logoText := "" }} diff --git a/packages/system/dashboard/values.yaml b/packages/system/dashboard/values.yaml index 45caa6eb..38ab2bf5 100644 --- a/packages/system/dashboard/values.yaml +++ b/packages/system/dashboard/values.yaml @@ -1,6 +1,6 @@ openapiUI: - image: ghcr.io/cozystack/cozystack/openapi-ui:v0.39.3@sha256:13fd38cf733c9b2ddde21c4189837729ef92fc0b1df987adc3cbdd591d005af2 + image: ghcr.io/cozystack/cozystack/openapi-ui:v0.39.4@sha256:2c6b0cbf45494ffc8031a064080c366961d0a40ab023d92b188059a797e17bad openapiUIK8sBff: - image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.39.3@sha256:c905f98598526820bd71e3997fdc62868b9c3d7a4e9700b01d73b017b0953257 + image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.39.4@sha256:c905f98598526820bd71e3997fdc62868b9c3d7a4e9700b01d73b017b0953257 tokenProxy: - image: ghcr.io/cozystack/cozystack/token-proxy:v0.39.3@sha256:4fc8a11f8a1a81aa0774ae2b1ed2e05d36d0b3ef1e37979cc4994e65114d93ae + image: ghcr.io/cozystack/cozystack/token-proxy:v0.39.4@sha256:4fc8a11f8a1a81aa0774ae2b1ed2e05d36d0b3ef1e37979cc4994e65114d93ae diff --git a/packages/system/kamaji/values.yaml b/packages/system/kamaji/values.yaml index 95954a1f..810db5f3 100644 --- a/packages/system/kamaji/values.yaml +++ b/packages/system/kamaji/values.yaml @@ -3,7 +3,7 @@ kamaji: deploy: false image: pullPolicy: IfNotPresent - tag: v0.39.3@sha256:4588de4380fb70c29c4a762fb19a9bbe210e68bc5ff67035c752c44daf319bfc + tag: v0.39.4@sha256:4588de4380fb70c29c4a762fb19a9bbe210e68bc5ff67035c752c44daf319bfc repository: ghcr.io/cozystack/cozystack/kamaji resources: limits: @@ -13,4 +13,4 @@ kamaji: cpu: 100m memory: 100Mi extraArgs: - - --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.39.3@sha256:4588de4380fb70c29c4a762fb19a9bbe210e68bc5ff67035c752c44daf319bfc + - --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.39.4@sha256:4588de4380fb70c29c4a762fb19a9bbe210e68bc5ff67035c752c44daf319bfc diff --git a/packages/system/kubeovn-plunger/values.yaml b/packages/system/kubeovn-plunger/values.yaml index 98edc6b1..e8ed91cd 100644 --- a/packages/system/kubeovn-plunger/values.yaml +++ b/packages/system/kubeovn-plunger/values.yaml @@ -1,4 +1,4 @@ portSecurity: true routes: "" -image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.39.3@sha256:aae60ffe66cd82583dc0a7de4cd8a5c4b0a46090a56a98916a0cdb2d1aa6b6e3 +image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.39.4@sha256:3cf53c35deeca4a8d28e5290e584565e7e7457b8e347513ac517b34d0ef6ca8c ovnCentralName: ovn-central diff --git a/packages/system/kubeovn-webhook/values.yaml b/packages/system/kubeovn-webhook/values.yaml index 44c41ddd..2acb18f0 100644 --- a/packages/system/kubeovn-webhook/values.yaml +++ b/packages/system/kubeovn-webhook/values.yaml @@ -1,3 +1,3 @@ portSecurity: true routes: "" -image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.39.3@sha256:e18f9fd679e38f65362a8d0042f25468272f6d081136ad47027168d8e7e07a4a +image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.39.4@sha256:e6334c29d3aaf0dea766c88e3e05b53ad623d1bb497b3c836e6f76adade45b29 diff --git a/packages/system/lineage-controller-webhook/values.yaml b/packages/system/lineage-controller-webhook/values.yaml index 7299e072..28789358 100644 --- a/packages/system/lineage-controller-webhook/values.yaml +++ b/packages/system/lineage-controller-webhook/values.yaml @@ -1,5 +1,5 @@ lineageControllerWebhook: - image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.39.3@sha256:044ab44440280de6d9f87791719add0cfeaa630ff655eff7ccbaf35694bbdb6b + image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.39.4@sha256:88abeaae6b1147ed12a45bad5f2c8e2d724d95195f46eb049d011631fb9be70e debug: false localK8sAPIEndpoint: enabled: true diff --git a/packages/system/objectstorage-controller/values.yaml b/packages/system/objectstorage-controller/values.yaml index ec28244b..bcc05129 100644 --- a/packages/system/objectstorage-controller/values.yaml +++ b/packages/system/objectstorage-controller/values.yaml @@ -1,3 +1,3 @@ objectstorage: controller: - image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.39.3@sha256:cbf22bcbeed7049340aa41f41cc130596bdb962873116e0c4eb5bab123ae13b0" + image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.39.4@sha256:cbf22bcbeed7049340aa41f41cc130596bdb962873116e0c4eb5bab123ae13b0" diff --git a/packages/system/seaweedfs/values.yaml b/packages/system/seaweedfs/values.yaml index 634144ce..6ed1700f 100644 --- a/packages/system/seaweedfs/values.yaml +++ b/packages/system/seaweedfs/values.yaml @@ -177,7 +177,7 @@ seaweedfs: bucketClassName: "seaweedfs" region: "" sidecar: - image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.3@sha256:2d1833c78c35b697a3634d4b3be9a3218edae95a77583e9e121c10a92e7433ec" + image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.4@sha256:2d1833c78c35b697a3634d4b3be9a3218edae95a77583e9e121c10a92e7433ec" certificates: commonName: "SeaweedFS CA" ipAddresses: [] From 8e9b398a2125b4f11e376b369cb1d4064afa2f86 Mon Sep 17 00:00:00 2001 From: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com> Date: Mon, 12 Jan 2026 01:38:28 +0000 Subject: [PATCH 41/43] Prepare release v0.39.4 Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com> --- packages/apps/kubernetes/images/cluster-autoscaler.tag | 2 +- packages/core/installer/values.yaml | 2 +- packages/extra/bootbox/images/matchbox.tag | 2 +- packages/extra/seaweedfs/images/objectstorage-sidecar.tag | 2 +- packages/system/cozystack-controller/values.yaml | 2 +- packages/system/dashboard/values.yaml | 4 ++-- packages/system/kamaji/values.yaml | 4 ++-- packages/system/kubeovn-plunger/values.yaml | 2 +- packages/system/lineage-controller-webhook/values.yaml | 2 +- packages/system/objectstorage-controller/values.yaml | 2 +- packages/system/seaweedfs/values.yaml | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/apps/kubernetes/images/cluster-autoscaler.tag b/packages/apps/kubernetes/images/cluster-autoscaler.tag index b1c2fe04..03a5ad61 100644 --- a/packages/apps/kubernetes/images/cluster-autoscaler.tag +++ b/packages/apps/kubernetes/images/cluster-autoscaler.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/cluster-autoscaler:0.0.0@sha256:372ad087ae96bd0cd642e2b0855ec7ffb1369d6cf4f0b92204725557c11bc0ff +ghcr.io/cozystack/cozystack/cluster-autoscaler:0.0.0@sha256:6f2b1d6b0b2bdc66f1cbb30c59393369cbf070cb8f5fec748f176952273483cc diff --git a/packages/core/installer/values.yaml b/packages/core/installer/values.yaml index 75f5b4ee..925dcd84 100644 --- a/packages/core/installer/values.yaml +++ b/packages/core/installer/values.yaml @@ -1,2 +1,2 @@ cozystack: - image: ghcr.io/cozystack/cozystack/installer:v0.39.4@sha256:81004b1328583814ab99965cc2241bc84cd3866970a087930e5fe691a55f32bf + image: ghcr.io/cozystack/cozystack/installer:v0.39.4@sha256:c5ed44094954d687b2598f637427dba0e746d46b4c1463bb189c635cfb4f615c diff --git a/packages/extra/bootbox/images/matchbox.tag b/packages/extra/bootbox/images/matchbox.tag index 27247fe5..c92d6f57 100644 --- a/packages/extra/bootbox/images/matchbox.tag +++ b/packages/extra/bootbox/images/matchbox.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/matchbox:v0.39.4@sha256:b2eca3ab3c844a527617449c3167ecdf80db052b9c91f028c139e2e1143de365 +ghcr.io/cozystack/cozystack/matchbox:v0.39.4@sha256:c8fda3d6c6dfe82dc54527a047dfce29a43e6551768b742841d039beffded47e diff --git a/packages/extra/seaweedfs/images/objectstorage-sidecar.tag b/packages/extra/seaweedfs/images/objectstorage-sidecar.tag index d1488b54..957e1f3a 100644 --- a/packages/extra/seaweedfs/images/objectstorage-sidecar.tag +++ b/packages/extra/seaweedfs/images/objectstorage-sidecar.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.4@sha256:2d1833c78c35b697a3634d4b3be9a3218edae95a77583e9e121c10a92e7433ec +ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.4@sha256:9d1b4d75d81f3ebddb79d1c081f6b82f682f11a0347866b03a7cb56c1146854c diff --git a/packages/system/cozystack-controller/values.yaml b/packages/system/cozystack-controller/values.yaml index 8f47d088..3a2caf10 100644 --- a/packages/system/cozystack-controller/values.yaml +++ b/packages/system/cozystack-controller/values.yaml @@ -1,5 +1,5 @@ cozystackController: - image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.39.4@sha256:94fde65fe25af01c977db2b16a64703b740f2833f9c878894a8cc8247de21fa2 + image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.39.4@sha256:7664f9367f7a108c53489f4cddd39eff88e4d19ff32ce9e1beb318beb6b99589 debug: false disableTelemetry: false cozystackVersion: "v0.39.4" diff --git a/packages/system/dashboard/values.yaml b/packages/system/dashboard/values.yaml index 38ab2bf5..b6157328 100644 --- a/packages/system/dashboard/values.yaml +++ b/packages/system/dashboard/values.yaml @@ -1,6 +1,6 @@ openapiUI: - image: ghcr.io/cozystack/cozystack/openapi-ui:v0.39.4@sha256:2c6b0cbf45494ffc8031a064080c366961d0a40ab023d92b188059a797e17bad + image: ghcr.io/cozystack/cozystack/openapi-ui:v0.39.4@sha256:a329691ef90708bda0de5539981f1cef8affd1d410614a11de38ad0eec35b2c5 openapiUIK8sBff: - image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.39.4@sha256:c905f98598526820bd71e3997fdc62868b9c3d7a4e9700b01d73b017b0953257 + image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.39.4@sha256:0ed112d44973dcff64b65f7f1438a35df98c7fdee4590343a790668f728d9024 tokenProxy: image: ghcr.io/cozystack/cozystack/token-proxy:v0.39.4@sha256:4fc8a11f8a1a81aa0774ae2b1ed2e05d36d0b3ef1e37979cc4994e65114d93ae diff --git a/packages/system/kamaji/values.yaml b/packages/system/kamaji/values.yaml index 810db5f3..0f465802 100644 --- a/packages/system/kamaji/values.yaml +++ b/packages/system/kamaji/values.yaml @@ -3,7 +3,7 @@ kamaji: deploy: false image: pullPolicy: IfNotPresent - tag: v0.39.4@sha256:4588de4380fb70c29c4a762fb19a9bbe210e68bc5ff67035c752c44daf319bfc + tag: v0.39.4@sha256:cade9c7052a312c5a0295d8ccd6db0858bac556bd9da897cb2da4583b57bd712 repository: ghcr.io/cozystack/cozystack/kamaji resources: limits: @@ -13,4 +13,4 @@ kamaji: cpu: 100m memory: 100Mi extraArgs: - - --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.39.4@sha256:4588de4380fb70c29c4a762fb19a9bbe210e68bc5ff67035c752c44daf319bfc + - --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.39.4@sha256:cade9c7052a312c5a0295d8ccd6db0858bac556bd9da897cb2da4583b57bd712 diff --git a/packages/system/kubeovn-plunger/values.yaml b/packages/system/kubeovn-plunger/values.yaml index e8ed91cd..a6f52635 100644 --- a/packages/system/kubeovn-plunger/values.yaml +++ b/packages/system/kubeovn-plunger/values.yaml @@ -1,4 +1,4 @@ portSecurity: true routes: "" -image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.39.4@sha256:3cf53c35deeca4a8d28e5290e584565e7e7457b8e347513ac517b34d0ef6ca8c +image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.39.4@sha256:d3b07e4e2f6ac0570d45abccf0c4bb2dd25469bfea490c5340b7f0ed72fc4cab ovnCentralName: ovn-central diff --git a/packages/system/lineage-controller-webhook/values.yaml b/packages/system/lineage-controller-webhook/values.yaml index 28789358..2b3e90b8 100644 --- a/packages/system/lineage-controller-webhook/values.yaml +++ b/packages/system/lineage-controller-webhook/values.yaml @@ -1,5 +1,5 @@ lineageControllerWebhook: - image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.39.4@sha256:88abeaae6b1147ed12a45bad5f2c8e2d724d95195f46eb049d011631fb9be70e + image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.39.4@sha256:7262f91a66ce9b133cff7d6d6c6f6330dbc12536f0c627f9ab6febbec26a76d4 debug: false localK8sAPIEndpoint: enabled: true diff --git a/packages/system/objectstorage-controller/values.yaml b/packages/system/objectstorage-controller/values.yaml index bcc05129..e5c78f02 100644 --- a/packages/system/objectstorage-controller/values.yaml +++ b/packages/system/objectstorage-controller/values.yaml @@ -1,3 +1,3 @@ objectstorage: controller: - image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.39.4@sha256:cbf22bcbeed7049340aa41f41cc130596bdb962873116e0c4eb5bab123ae13b0" + image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.39.4@sha256:628b3757e1011902642b7967eb6b79e4f084881d9493be4a6ee2f32b4f4253a1" diff --git a/packages/system/seaweedfs/values.yaml b/packages/system/seaweedfs/values.yaml index 6ed1700f..cc326f59 100644 --- a/packages/system/seaweedfs/values.yaml +++ b/packages/system/seaweedfs/values.yaml @@ -177,7 +177,7 @@ seaweedfs: bucketClassName: "seaweedfs" region: "" sidecar: - image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.4@sha256:2d1833c78c35b697a3634d4b3be9a3218edae95a77583e9e121c10a92e7433ec" + image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.4@sha256:9d1b4d75d81f3ebddb79d1c081f6b82f682f11a0347866b03a7cb56c1146854c" certificates: commonName: "SeaweedFS CA" ipAddresses: [] From 274a3a57a8a2246e99cccf857e5776dbc2821580 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Mon, 12 Jan 2026 15:31:46 +0100 Subject: [PATCH 42/43] [linstor] Update piraeus-server patches with critical fixes Update piraeus-server patches to address critical production issues: - Add fix-duplicate-tcp-ports.diff to prevent duplicate TCP ports after toggle-disk operations (upstream PR #476) - Update skip-adjust-when-device-inaccessible.diff with comprehensive fixes for resources stuck in StandAlone after reboot, Unknown state race condition, and encrypted LUKS resource deletion (upstream PR #477) ```release-note [linstor] Fix DRBD resources stuck in StandAlone state after reboot and encrypted resource deletion issues ``` Co-Authored-By: Claude Signed-off-by: Andrei Kvapil (cherry picked from commit dc2773ba267ee82ec5128f3c49d57912483ae0d0) --- .../images/piraeus-server/patches/README.md | 6 +- .../patches/fix-duplicate-tcp-ports.diff | 87 ++++++++ .../skip-adjust-when-device-inaccessible.diff | 192 +++++++++++++++--- 3 files changed, 258 insertions(+), 27 deletions(-) create mode 100644 packages/system/linstor/images/piraeus-server/patches/fix-duplicate-tcp-ports.diff diff --git a/packages/system/linstor/images/piraeus-server/patches/README.md b/packages/system/linstor/images/piraeus-server/patches/README.md index c219eaf3..5ee29318 100644 --- a/packages/system/linstor/images/piraeus-server/patches/README.md +++ b/packages/system/linstor/images/piraeus-server/patches/README.md @@ -8,5 +8,7 @@ Custom patches for piraeus-server (linstor-server) v1.32.3. - Upstream: [#475](https://github.com/LINBIT/linstor-server/pull/475) - **force-metadata-check-on-disk-add.diff** — Create metadata during toggle-disk from diskless to diskful - Upstream: [#474](https://github.com/LINBIT/linstor-server/pull/474) -- **skip-adjust-when-device-inaccessible.diff** — Skip DRBD adjust/res file regeneration when child layer device is inaccessible - - Upstream: [#471](https://github.com/LINBIT/linstor-server/pull/471) +- **fix-duplicate-tcp-ports.diff** — Prevent duplicate TCP ports after toggle-disk operations + - Upstream: [#476](https://github.com/LINBIT/linstor-server/pull/476) +- **skip-adjust-when-device-inaccessible.diff** — Fix resources stuck in StandAlone after reboot, Unknown state race condition, and encrypted resource deletion + - Upstream: [#477](https://github.com/LINBIT/linstor-server/pull/477) diff --git a/packages/system/linstor/images/piraeus-server/patches/fix-duplicate-tcp-ports.diff b/packages/system/linstor/images/piraeus-server/patches/fix-duplicate-tcp-ports.diff new file mode 100644 index 00000000..07cd9eac --- /dev/null +++ b/packages/system/linstor/images/piraeus-server/patches/fix-duplicate-tcp-ports.diff @@ -0,0 +1,87 @@ +From 1250abe99d64a0501795e37d3b6af62410002239 Mon Sep 17 00:00:00 2001 +From: Andrei Kvapil +Date: Mon, 12 Jan 2026 13:44:46 +0100 +Subject: [PATCH] fix(drbd): prevent duplicate TCP ports after toggle-disk + operations + +Remove redundant ensureStackDataExists() call with empty payload from +resetStoragePools() method that was causing TCP port conflicts after +toggle-disk operations. + +Root Cause: +----------- +The resetStoragePools() method, introduced in 2019 (commit 95cc17d0b8), +calls ensureStackDataExists() with an empty LayerPayload. This worked +correctly when TCP ports were stored at RscDfn level. + +After the TCP port migration to per-node level (commit f754943463, May +2025), this empty payload results in DrbdRscData being created without +TCP ports assigned. The controller then sends a Pojo with an empty port +Set to satellites. + +On satellites, when DrbdRscData is initialized with an empty port list, +initPorts() uses preferredNewPortsRef from peer resources. Since +SatelliteDynamicNumberPool.tryAllocate() always returns true (no-op), +any port from preferredNewPortsRef is accepted without conflict checking, +leading to duplicate TCP port assignments. + +Impact: +------- +This regression affects toggle-disk operations, particularly: +- Snapshot creation/restore operations +- Manual toggle-disk operations +- Any operation calling resetStoragePools() + +Symptoms include: +- DRBD resources failing to adjust with "port is also used" errors +- Resources stuck in StandAlone or Connecting states +- Multiple resources on the same node using identical TCP ports + +Solution: +--------- +Remove the ensureStackDataExists() call from resetStoragePools() as it +is redundant. The calling code (e.g., CtrlRscToggleDiskApiCallHandler +line 1071) already invokes ensureStackDataExists() with the correct +payload immediately after resetStoragePools(). + +This fix ensures: +1. resetStoragePools() only resets storage pool assignments +2. Layer data creation with proper TCP ports happens via the caller's + ensureStackDataExists() with correct payload +3. No DrbdRscData objects are created without TCP port assignments + +Related Issues: +--------------- +Fixes #454 - Duplicate TCP ports after backup/restore operations +Related to user reports of resources stuck in StandAlone after node +reboots when toggle-disk or backup operations were in progress. + +Testing: +-------- +Verified that: +- Toggle-disk operations no longer create resources without TCP ports +- Backup/restore operations complete without TCP port conflicts +- Resources maintain unique TCP ports across toggle-disk cycles + +Co-Authored-By: Claude +Signed-off-by: Andrei Kvapil +--- + .../linbit/linstor/layer/resource/CtrlRscLayerDataFactory.java | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/controller/src/main/java/com/linbit/linstor/layer/resource/CtrlRscLayerDataFactory.java b/controller/src/main/java/com/linbit/linstor/layer/resource/CtrlRscLayerDataFactory.java +index 3538b380c..4f589145e 100644 +--- a/controller/src/main/java/com/linbit/linstor/layer/resource/CtrlRscLayerDataFactory.java ++++ b/controller/src/main/java/com/linbit/linstor/layer/resource/CtrlRscLayerDataFactory.java +@@ -276,8 +276,6 @@ public class CtrlRscLayerDataFactory + + rscDataToProcess.addAll(rscData.getChildren()); + } +- +- ensureStackDataExists(rscRef, null, new LayerPayload()); + } + catch (AccessDeniedException exc) + { +-- +2.39.5 (Apple Git-154) + diff --git a/packages/system/linstor/images/piraeus-server/patches/skip-adjust-when-device-inaccessible.diff b/packages/system/linstor/images/piraeus-server/patches/skip-adjust-when-device-inaccessible.diff index 18399c41..65c8be7c 100644 --- a/packages/system/linstor/images/piraeus-server/patches/skip-adjust-when-device-inaccessible.diff +++ b/packages/system/linstor/images/piraeus-server/patches/skip-adjust-when-device-inaccessible.diff @@ -1,30 +1,27 @@ -diff --git a/satellite/src/main/java/com/linbit/linstor/core/devmgr/DeviceHandlerImpl.java b/satellite/src/main/java/com/linbit/linstor/core/devmgr/DeviceHandlerImpl.java -index abc123def..def456abc 100644 ---- a/satellite/src/main/java/com/linbit/linstor/core/devmgr/DeviceHandlerImpl.java -+++ b/satellite/src/main/java/com/linbit/linstor/core/devmgr/DeviceHandlerImpl.java -@@ -83,6 +83,8 @@ import java.util.TreeMap; - import java.util.TreeSet; - import java.util.concurrent.atomic.AtomicBoolean; - import java.util.function.Function; -+import java.nio.file.Files; -+import java.nio.file.Paths; +From 6a556821b9a0996d34389a27b941694ce810a44c Mon Sep 17 00:00:00 2001 +From: Andrei Kvapil +Date: Mon, 12 Jan 2026 14:26:57 +0100 +Subject: [PATCH 1/3] Fix: Skip DRBD adjust/res file regeneration when child + layer device is inaccessible + +When deleting encrypted (LUKS) resources, the LUKS layer may close its device +before the DRBD layer attempts to adjust the resource or regenerate the res +file. This causes 'Failed to adjust DRBD resource' errors. + +This fix adds checks before regenerateResFile() and drbdUtils.adjust() +to verify that child layer devices are accessible. If a child device doesn't +exist or is not accessible (e.g., LUKS device is closed during resource +deletion), these operations are skipped and the adjustRequired flag is cleared, +allowing resource deletion to proceed successfully. + +Co-Authored-By: Claude +Signed-off-by: Andrei Kvapil +--- + .../linbit/linstor/layer/drbd/DrbdLayer.java | 72 ++++++++++++++++--- + 1 file changed, 61 insertions(+), 11 deletions(-) - @Singleton - public class DeviceHandlerImpl implements DeviceHandler -@@ -1646,7 +1648,10 @@ public class DeviceHandlerImpl implements DeviceHandler - private void updateDiscGran(VlmProviderObject vlmData) throws DatabaseException, StorageException - { - String devicePath = vlmData.getDevicePath(); -- if (devicePath != null && vlmData.exists()) -+ // Check if device path physically exists before calling lsblk -+ // This is important for DRBD devices which might be temporarily unavailable during adjust -+ // (drbdadm adjust brings devices down/up, and kernel might not have created the device node yet) -+ if (devicePath != null && vlmData.exists() && Files.exists(Paths.get(devicePath))) - { - if (vlmData.getDiscGran() == VlmProviderObject.UNINITIALIZED_SIZE) - { diff --git a/satellite/src/main/java/com/linbit/linstor/layer/drbd/DrbdLayer.java b/satellite/src/main/java/com/linbit/linstor/layer/drbd/DrbdLayer.java -index 01967a3..871d830 100644 +index 01967a31f..871d830d1 100644 --- a/satellite/src/main/java/com/linbit/linstor/layer/drbd/DrbdLayer.java +++ b/satellite/src/main/java/com/linbit/linstor/layer/drbd/DrbdLayer.java @@ -592,7 +592,29 @@ public class DrbdLayer implements DeviceLayer @@ -116,3 +113,148 @@ index 01967a3..871d830 100644 } } +-- +2.39.5 (Apple Git-154) + + +From afe51ea674c4a350c27d1f2cacfecf6fe42b8a7a Mon Sep 17 00:00:00 2001 +From: Andrei Kvapil +Date: Mon, 12 Jan 2026 14:27:52 +0100 +Subject: [PATCH 2/3] fix(satellite): skip lsblk when device path doesn't + physically exist + +Add physical device path existence check before calling lsblk in updateDiscGran(). +This prevents race condition when drbdadm adjust temporarily brings devices down/up +and the kernel hasn't created the device node yet. + +Issue: After satellite restart with patched code, some DRBD resources ended up in +Unknown state because: +1. drbdadm adjust successfully completes (brings devices up) +2. updateDiscGran() immediately tries to check discard granularity +3. /dev/drbd* device node doesn't exist yet (kernel hasn't created it) +4. lsblk fails with exit code 32 "not a block device" +5. StorageException interrupts DeviceManager cycle +6. DRBD device remains in incomplete state + +Solution: Check Files.exists(devicePath) before calling lsblk. If device doesn't +exist yet, skip the check - it will be retried in the next DeviceManager cycle +when the device node is available. + +Co-Authored-By: Claude +Signed-off-by: Andrei Kvapil +--- + .../linbit/linstor/core/devmgr/DeviceHandlerImpl.java | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/satellite/src/main/java/com/linbit/linstor/core/devmgr/DeviceHandlerImpl.java b/satellite/src/main/java/com/linbit/linstor/core/devmgr/DeviceHandlerImpl.java +index 49138a8fd..1c13cfc9d 100644 +--- a/satellite/src/main/java/com/linbit/linstor/core/devmgr/DeviceHandlerImpl.java ++++ b/satellite/src/main/java/com/linbit/linstor/core/devmgr/DeviceHandlerImpl.java +@@ -68,6 +68,8 @@ import javax.inject.Inject; + import javax.inject.Provider; + import javax.inject.Singleton; + ++import java.nio.file.Files; ++import java.nio.file.Paths; + import java.util.ArrayList; + import java.util.Collection; + import java.util.Collections; +@@ -1645,8 +1647,11 @@ public class DeviceHandlerImpl implements DeviceHandler + + private void updateDiscGran(VlmProviderObject vlmData) throws DatabaseException, StorageException + { +- String devicePath = vlmData.getDevicePath(); +- if (devicePath != null && vlmData.exists()) ++ @Nullable String devicePath = vlmData.getDevicePath(); ++ // Check if device path physically exists before calling lsblk ++ // This is important for DRBD devices which might be temporarily unavailable during adjust ++ // (drbdadm adjust brings devices down/up, and kernel might not have created the device node yet) ++ if (devicePath != null && vlmData.exists() && Files.exists(Paths.get(devicePath))) + { + if (vlmData.getDiscGran() == VlmProviderObject.UNINITIALIZED_SIZE) + { +-- +2.39.5 (Apple Git-154) + + +From de1f22e7c008c5479f85a3b1ebdf8461944210f4 Mon Sep 17 00:00:00 2001 +From: Andrei Kvapil +Date: Mon, 12 Jan 2026 14:28:23 +0100 +Subject: [PATCH 3/3] fix(drbd): only check child devices when disk access is + actually needed +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The previous implementation blocked `drbdadm adjust` whenever child +device paths were unavailable, even for operations that don't require +disk access (like network reconnect from StandAlone to Connected). + +After node reboot, DRBD resources often remain in StandAlone state +because: +1. updateResourceToCurrentDrbdState() correctly detects StandAlone + and sets adjustRequired=true +2. However, canAdjust check fails because child volumes may have + devicePath=null (due to INACTIVE flag, cloning state, or + initialization race) +3. adjust is skipped → adjustRequired=false → resources stay StandAlone + +Root cause: The canAdjust check was added to protect LUKS deletion +scenarios but was applied to ALL cases, including network reconnect +which doesn't need disk access. + +Fix: Check child device accessibility only when disk access is actually +required (volume creation, resize, metadata operations). Network +reconnect operations (StandAlone → Connected) now proceed without +checking child devices. + +This ensures automatic DRBD reconnection after reboot while preserving +protection for LUKS deletion scenarios. + +Co-Authored-By: Claude +Signed-off-by: Andrei Kvapil +--- + .../linbit/linstor/layer/drbd/DrbdLayer.java | 27 ++++++++++++++++++- + 1 file changed, 26 insertions(+), 1 deletion(-) + +diff --git a/satellite/src/main/java/com/linbit/linstor/layer/drbd/DrbdLayer.java b/satellite/src/main/java/com/linbit/linstor/layer/drbd/DrbdLayer.java +index 871d830d1..78b8195a4 100644 +--- a/satellite/src/main/java/com/linbit/linstor/layer/drbd/DrbdLayer.java ++++ b/satellite/src/main/java/com/linbit/linstor/layer/drbd/DrbdLayer.java +@@ -792,7 +792,32 @@ public class DrbdLayer implements DeviceLayer + // This is important for encrypted resources (LUKS) where the device + // might be closed during deletion + boolean canAdjust = true; +- if (!skipDisk && !drbdRscData.getAbsResource().isDrbdDiskless(workerCtx)) ++ ++ // IMPORTANT: Check child volumes only when disk access is actually needed. ++ // For network reconnect (StandAlone -> Connected), disk access is not required. ++ boolean needsDiskAccess = false; ++ ++ // Check if there are pending operations that require disk access ++ for (DrbdVlmData drbdVlmData : drbdRscData.getVlmLayerObjects().values()) ++ { ++ Volume vlm = (Volume) drbdVlmData.getVolume(); ++ StateFlags vlmFlags = vlm.getFlags(); ++ ++ // Disk access is needed if: ++ // - creating a new volume ++ // - resizing ++ // - checking/creating metadata ++ if (!drbdVlmData.exists() || ++ drbdVlmData.checkMetaData() || ++ vlmFlags.isSomeSet(workerCtx, Volume.Flags.RESIZE, Volume.Flags.DRBD_RESIZE)) ++ { ++ needsDiskAccess = true; ++ break; ++ } ++ } ++ ++ // Check child volumes only if disk access is actually needed ++ if (needsDiskAccess && !skipDisk && !drbdRscData.getAbsResource().isDrbdDiskless(workerCtx)) + { + AbsRscLayerObject dataChild = drbdRscData.getChildBySuffix(RscLayerSuffixes.SUFFIX_DATA); + if (dataChild != null) +-- +2.39.5 (Apple Git-154) + From ea0abcc4658bdc5dc3dc2f72e4d26bb4eb22bd47 Mon Sep 17 00:00:00 2001 From: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com> Date: Tue, 13 Jan 2026 01:39:12 +0000 Subject: [PATCH 43/43] Prepare release v0.39.5 Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com> --- packages/core/installer/values.yaml | 2 +- packages/core/testing/values.yaml | 2 +- packages/extra/bootbox/images/matchbox.tag | 2 +- packages/extra/seaweedfs/images/objectstorage-sidecar.tag | 2 +- packages/system/cozystack-api/values.yaml | 2 +- packages/system/cozystack-controller/values.yaml | 4 ++-- packages/system/dashboard/templates/configmap.yaml | 2 +- packages/system/dashboard/values.yaml | 6 +++--- packages/system/kamaji/values.yaml | 4 ++-- packages/system/kubeovn-plunger/values.yaml | 2 +- packages/system/kubeovn-webhook/values.yaml | 2 +- packages/system/lineage-controller-webhook/values.yaml | 2 +- packages/system/linstor/values.yaml | 2 +- packages/system/objectstorage-controller/values.yaml | 2 +- packages/system/seaweedfs/values.yaml | 2 +- 15 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/core/installer/values.yaml b/packages/core/installer/values.yaml index 925dcd84..ae6b3763 100644 --- a/packages/core/installer/values.yaml +++ b/packages/core/installer/values.yaml @@ -1,2 +1,2 @@ cozystack: - image: ghcr.io/cozystack/cozystack/installer:v0.39.4@sha256:c5ed44094954d687b2598f637427dba0e746d46b4c1463bb189c635cfb4f615c + image: ghcr.io/cozystack/cozystack/installer:v0.39.5@sha256:0d1b48c61278b0c6214c50ca06f354cfbe6181cd282e9d6ef35c968456fcc951 diff --git a/packages/core/testing/values.yaml b/packages/core/testing/values.yaml index 89ac68a4..5ff898ce 100644 --- a/packages/core/testing/values.yaml +++ b/packages/core/testing/values.yaml @@ -1,2 +1,2 @@ e2e: - image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.39.4@sha256:3395a0e3c02e85878a44d3177cae3c37b087edeb4fab6547cb8227862b1de773 + image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.39.5@sha256:3395a0e3c02e85878a44d3177cae3c37b087edeb4fab6547cb8227862b1de773 diff --git a/packages/extra/bootbox/images/matchbox.tag b/packages/extra/bootbox/images/matchbox.tag index c92d6f57..60ce7049 100644 --- a/packages/extra/bootbox/images/matchbox.tag +++ b/packages/extra/bootbox/images/matchbox.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/matchbox:v0.39.4@sha256:c8fda3d6c6dfe82dc54527a047dfce29a43e6551768b742841d039beffded47e +ghcr.io/cozystack/cozystack/matchbox:v0.39.5@sha256:7a0c29d75a0b5416e2409d4703131b2f3f09cdc39e55ee916803cabf0606f724 diff --git a/packages/extra/seaweedfs/images/objectstorage-sidecar.tag b/packages/extra/seaweedfs/images/objectstorage-sidecar.tag index 957e1f3a..225aaf22 100644 --- a/packages/extra/seaweedfs/images/objectstorage-sidecar.tag +++ b/packages/extra/seaweedfs/images/objectstorage-sidecar.tag @@ -1 +1 @@ -ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.4@sha256:9d1b4d75d81f3ebddb79d1c081f6b82f682f11a0347866b03a7cb56c1146854c +ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.5@sha256:4bb47c8adb34543403a16d1ff61b307939850e8cf5fc365388469e30dfb9681b diff --git a/packages/system/cozystack-api/values.yaml b/packages/system/cozystack-api/values.yaml index 44edd320..01444c7f 100644 --- a/packages/system/cozystack-api/values.yaml +++ b/packages/system/cozystack-api/values.yaml @@ -1,5 +1,5 @@ cozystackAPI: - image: ghcr.io/cozystack/cozystack/cozystack-api:v0.39.4@sha256:51574c6bb61ae31e63193f84daf18c14ceb71580786e262191c4aa0ac44b1519 + image: ghcr.io/cozystack/cozystack/cozystack-api:v0.39.5@sha256:51574c6bb61ae31e63193f84daf18c14ceb71580786e262191c4aa0ac44b1519 localK8sAPIEndpoint: enabled: true replicas: 2 diff --git a/packages/system/cozystack-controller/values.yaml b/packages/system/cozystack-controller/values.yaml index 3a2caf10..9aea39ec 100644 --- a/packages/system/cozystack-controller/values.yaml +++ b/packages/system/cozystack-controller/values.yaml @@ -1,6 +1,6 @@ cozystackController: - image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.39.4@sha256:7664f9367f7a108c53489f4cddd39eff88e4d19ff32ce9e1beb318beb6b99589 + image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.39.5@sha256:dd6bb910842151ec60cea74f43b03ac35f461a03f6fe4370b12c7aaf48fee7b8 debug: false disableTelemetry: false - cozystackVersion: "v0.39.4" + cozystackVersion: "v0.39.5" cozystackAPIKind: "DaemonSet" diff --git a/packages/system/dashboard/templates/configmap.yaml b/packages/system/dashboard/templates/configmap.yaml index 27204801..9dd83fc8 100644 --- a/packages/system/dashboard/templates/configmap.yaml +++ b/packages/system/dashboard/templates/configmap.yaml @@ -1,6 +1,6 @@ {{- $brandingConfig:= lookup "v1" "ConfigMap" "cozy-system" "cozystack-branding" }} -{{- $tenantText := "v0.39.4" }} +{{- $tenantText := "v0.39.5" }} {{- $footerText := "Cozystack" }} {{- $titleText := "Cozystack Dashboard" }} {{- $logoText := "" }} diff --git a/packages/system/dashboard/values.yaml b/packages/system/dashboard/values.yaml index b6157328..59ddc47e 100644 --- a/packages/system/dashboard/values.yaml +++ b/packages/system/dashboard/values.yaml @@ -1,6 +1,6 @@ openapiUI: - image: ghcr.io/cozystack/cozystack/openapi-ui:v0.39.4@sha256:a329691ef90708bda0de5539981f1cef8affd1d410614a11de38ad0eec35b2c5 + image: ghcr.io/cozystack/cozystack/openapi-ui:v0.39.5@sha256:6c48044fd9bfaea65478c39fc9f3e7322d06aef46022211847621eeb6d46c51c openapiUIK8sBff: - image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.39.4@sha256:0ed112d44973dcff64b65f7f1438a35df98c7fdee4590343a790668f728d9024 + image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.39.5@sha256:fda379dce49c2cd8cb8d7d2a1d8ec6f7bedb3419c058c4355ecdece1c1e937f4 tokenProxy: - image: ghcr.io/cozystack/cozystack/token-proxy:v0.39.4@sha256:4fc8a11f8a1a81aa0774ae2b1ed2e05d36d0b3ef1e37979cc4994e65114d93ae + image: ghcr.io/cozystack/cozystack/token-proxy:v0.39.5@sha256:4fc8a11f8a1a81aa0774ae2b1ed2e05d36d0b3ef1e37979cc4994e65114d93ae diff --git a/packages/system/kamaji/values.yaml b/packages/system/kamaji/values.yaml index 0f465802..1dc6c5c1 100644 --- a/packages/system/kamaji/values.yaml +++ b/packages/system/kamaji/values.yaml @@ -3,7 +3,7 @@ kamaji: deploy: false image: pullPolicy: IfNotPresent - tag: v0.39.4@sha256:cade9c7052a312c5a0295d8ccd6db0858bac556bd9da897cb2da4583b57bd712 + tag: v0.39.5@sha256:0bcfb2d376224b18a0627d7b18ba6202bb8a553f71796023e12740d9513740c7 repository: ghcr.io/cozystack/cozystack/kamaji resources: limits: @@ -13,4 +13,4 @@ kamaji: cpu: 100m memory: 100Mi extraArgs: - - --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.39.4@sha256:cade9c7052a312c5a0295d8ccd6db0858bac556bd9da897cb2da4583b57bd712 + - --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.39.5@sha256:0bcfb2d376224b18a0627d7b18ba6202bb8a553f71796023e12740d9513740c7 diff --git a/packages/system/kubeovn-plunger/values.yaml b/packages/system/kubeovn-plunger/values.yaml index a6f52635..ec204b89 100644 --- a/packages/system/kubeovn-plunger/values.yaml +++ b/packages/system/kubeovn-plunger/values.yaml @@ -1,4 +1,4 @@ portSecurity: true routes: "" -image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.39.4@sha256:d3b07e4e2f6ac0570d45abccf0c4bb2dd25469bfea490c5340b7f0ed72fc4cab +image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.39.5@sha256:52b7764b06ca3d6e5a2e74ba3d6d68ecdcf6b71a227e50b1344a8f11bf693a23 ovnCentralName: ovn-central diff --git a/packages/system/kubeovn-webhook/values.yaml b/packages/system/kubeovn-webhook/values.yaml index 2acb18f0..e3422b5c 100644 --- a/packages/system/kubeovn-webhook/values.yaml +++ b/packages/system/kubeovn-webhook/values.yaml @@ -1,3 +1,3 @@ portSecurity: true routes: "" -image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.39.4@sha256:e6334c29d3aaf0dea766c88e3e05b53ad623d1bb497b3c836e6f76adade45b29 +image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.39.5@sha256:e6334c29d3aaf0dea766c88e3e05b53ad623d1bb497b3c836e6f76adade45b29 diff --git a/packages/system/lineage-controller-webhook/values.yaml b/packages/system/lineage-controller-webhook/values.yaml index 2b3e90b8..9f2f7cf2 100644 --- a/packages/system/lineage-controller-webhook/values.yaml +++ b/packages/system/lineage-controller-webhook/values.yaml @@ -1,5 +1,5 @@ lineageControllerWebhook: - image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.39.4@sha256:7262f91a66ce9b133cff7d6d6c6f6330dbc12536f0c627f9ab6febbec26a76d4 + image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.39.5@sha256:dc5c7c990e468b291390a54f5fb5970097a1ff65ba4be6e95317e3ee7bf4430d debug: false localK8sAPIEndpoint: enabled: true diff --git a/packages/system/linstor/values.yaml b/packages/system/linstor/values.yaml index 5fa4d16d..fd73a84f 100644 --- a/packages/system/linstor/values.yaml +++ b/packages/system/linstor/values.yaml @@ -1,4 +1,4 @@ piraeusServer: image: repository: ghcr.io/cozystack/cozystack/piraeus-server - tag: 1.32.3@sha256:c6fbe1825514a3059088175968a651d7e10f477590023a33f1a9e6584fd98e04 + tag: 1.32.3@sha256:1138c8dc0a117360ef70e2e2ab97bc2696419b63f46358f7668c7e01a96c419b diff --git a/packages/system/objectstorage-controller/values.yaml b/packages/system/objectstorage-controller/values.yaml index e5c78f02..3b560815 100644 --- a/packages/system/objectstorage-controller/values.yaml +++ b/packages/system/objectstorage-controller/values.yaml @@ -1,3 +1,3 @@ objectstorage: controller: - image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.39.4@sha256:628b3757e1011902642b7967eb6b79e4f084881d9493be4a6ee2f32b4f4253a1" + image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.39.5@sha256:e8f605a5ec4b801dfaf49aa7bce8d7a1ce28df578e23a0b859571f60f98efe8c" diff --git a/packages/system/seaweedfs/values.yaml b/packages/system/seaweedfs/values.yaml index cc326f59..83f1347b 100644 --- a/packages/system/seaweedfs/values.yaml +++ b/packages/system/seaweedfs/values.yaml @@ -177,7 +177,7 @@ seaweedfs: bucketClassName: "seaweedfs" region: "" sidecar: - image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.4@sha256:9d1b4d75d81f3ebddb79d1c081f6b82f682f11a0347866b03a7cb56c1146854c" + image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.39.5@sha256:4bb47c8adb34543403a16d1ff61b307939850e8cf5fc365388469e30dfb9681b" certificates: commonName: "SeaweedFS CA" ipAddresses: []