Skip to content

Commit 4596fa5

Browse files
Merge pull request #2486 from jfrog/xray-103.150.31-20260821-075748
[xray] 103.150.31 release
2 parents ef50173 + a666d79 commit 4596fa5

11 files changed

Lines changed: 906 additions & 170 deletions

File tree

stable/xray/CHANGELOG.md

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,105 @@
11
# JFrog Xray Chart Changelog
22
All changes to this chart will be documented in this file.
33

4-
## [103.150.24] - Jun 26, 2026
4+
## [103.150.31] - Jun 26, 2026
55
* Fix `wait-for-rabbitmq-replicas-quorum` init container exposing RabbitMQ credentials in pod logs due to bash trace mode (`-x`).
66
* Added support for the rabbitmq `quorum_queue_non_voters` feature flag and increased `max_message_size` to 128 MB.
77
* Update valkey.kubectl.image.repository and valkey.kubectl.image.tag to `echohq/kubectl:1.35.6`
88
* Added optional per-service `kedaJobs` overrides that inherit from `splitXraytoSeparateDeployments.kedaJobs`. Setting `<service>.kedaJobs` to `true` or `false` overrides the global flag for that service; leaving it unset or `null` inherits the global value.
99
* Added `.Values.jasexposures.exitOnIdleTimeToWait` and `.Values.jascontextual.exitOnIdleTimeToWait` to configure `JF_SHARED_EXIT_ON_IDLE_TIME_TO_WAIT` separately for each of those KEDA ScaledJobs (default `900`).
10+
* **Valkey `maxmemory` and `maxmemory-policy` are now set by the sizing profiles**
11+
12+
Valkey shipped without a `maxmemory`, which leaves the dataset unbounded: rather than evicting, a Valkey node grows until it reaches its container memory limit and is OOMKilled by the kernel. With Sentinel that costs a failover, and the replacement node fills up the same way.
13+
14+
* **Breaking change: Valkey Sentinel enabled by default — the Valkey StatefulSet and its PVCs are replaced**
15+
16+
What changed: Valkey now runs in replication + Sentinel (HA) mode — `valkey.architecture: replication`, `valkey.replica.replicaCount: 3`, `valkey.sentinel.enabled: true`. Chart versions up to and including `103.143.0` ran `valkey.architecture: standalone` with `valkey.replica.replicaCount: 0`.
17+
18+
Who is affected: only environments that already have `valkey.enabled: true` deployed. Valkey is disabled by default.
19+
20+
Standalone mode deploys a single StatefulSet `<release>-valkey-primary`; with Sentinel the chart deploys `<release>-valkey-node` with all nodes in one StatefulSet. Because the name differs, `helm upgrade` creates the new StatefulSet and removes the old one instead of updating it — so the upgrade itself does not fail, but **the PVCs are recreated rather than migrated**. A StatefulSet's `volumeClaimTemplates` is immutable, so the claims cannot be carried across the replacement: the new StatefulSet provisions its own `valkey-data-<release>-valkey-node-<ordinal>` PVCs, one per node, and `valkey-data-<release>-valkey-primary-0` is neither reused nor deleted.
21+
22+
Two consequences:
23+
24+
* **The cached data is discarded.** Valkey here only backs the catalog cache, so it repopulates on demand and no action is required.
25+
* **The old PVC is left behind.** StatefulSet PVCs carry no `ownerReferences`, so deleting the StatefulSet does not delete them and nothing reclaims them automatically — the volume stays allocated until removed by hand. After the upgrade:
26+
```shell
27+
kubectl get pvc -l app.kubernetes.io/name=valkey,app.kubernetes.io/instance=<release> --namespace <namespace> -o name | grep -E '/valkey-data-.*-valkey-(primary|replicas)-'
28+
29+
kubectl get pvc -l app.kubernetes.io/name=valkey,app.kubernetes.io/instance=<release> --namespace <namespace> -o name | grep -E '/valkey-data-.*-valkey-(primary|replicas)-' \
30+
| xargs -r kubectl delete --namespace <namespace>
31+
```
32+
33+
Also note that storage goes from one Valkey PVC to one per node (three by default), so confirm the StorageClass can provision that before upgrading.
34+
* **Breaking change: Valkey PVC size default increased from `1Gi` to `200Gi`**
35+
36+
What changed: `valkey.primary.persistence.size` and `valkey.replica.persistence.size` both moved from `1Gi` to `200Gi`. With Sentinel enabled — the default since `103.150.31` — all Valkey nodes run in one StatefulSet whose PVC size comes from `valkey.replica.persistence.size`; `valkey.primary.persistence.size` has no effect in that mode.
37+
38+
Who is affected: only environments that already have `valkey.enabled: true` deployed. Fresh installs with `valkey.enabled: true` create Valkey PVCs at 200Gi and need no extra steps; default chart installs leave Valkey disabled and create no Valkey PVCs.
39+
40+
Why an upgrade needs a manual step: a PVC size lives in the StatefulSet's `volumeClaimTemplates`, and Kubernetes treats that field as immutable once the StatefulSet exists, so the StatefulSet has to be replaced for the new size to take effect. Where the StatefulSet keeps its name, `helm upgrade` would otherwise fail with:
41+
```text
42+
Forbidden: updates to statefulset spec for fields other than 'replicas', 'ordinals', 'template', 'updateStrategy', 'persistentVolumeClaimRetentionPolicy' and 'minReadySeconds' are forbidden
43+
```
44+
45+
On an upgrade of an existing `valkey.enabled: true` release, the chart stops with the steps below printed instead.
46+
47+
**Step 1 — See which Valkey objects the release has.** The object names depend on the architecture the release was deployed with, so discover them rather than assuming a layout or a replica count. Filtering on the `valkey-data-` prefix keeps Sentinel's `sentinel-data` PVCs out of the resize — they carry identical labels, hold Sentinel state rather than cache, and must be left alone.
48+
```shell
49+
kubectl get statefulset -l app.kubernetes.io/name=valkey,app.kubernetes.io/instance=<release> --namespace <namespace> -o name
50+
kubectl get pvc -l app.kubernetes.io/name=valkey,app.kubernetes.io/instance=<release> --namespace <namespace> -o name | grep '/valkey-data-'
51+
```
52+
53+
Each command in the following steps re-runs that lookup and pipes it into `kubectl`. Do not collect the list into a shell variable and pass it unquoted — zsh does not split it into separate arguments, and `kubectl` rejects it with `arguments in resource/name form may not have more than one slash`.
54+
55+
Both must return something before continuing. The StatefulSet name tells you which case you are in:
56+
57+
| StatefulSet | Deployed from | PVCs | Use |
58+
|---|---|---|---|
59+
| `<release>-valkey-primary` (and `-valkey-replicas`) | 103.143.x or earlier — `architecture: standalone`, `replicaCount: 0` | `valkey-data-<release>-valkey-primary-0` | Step 3b |
60+
| `<release>-valkey-node` | 103.150.x or later — replication + Sentinel | `valkey-data-<release>-valkey-node-0``-<replicaCount - 1>` | Step 3a or 3b |
61+
62+
In the first case this upgrade also moves the release to the Sentinel layout, whose StatefulSet is named `<release>-valkey-node`. Because that is a different name, Helm creates it and removes the old StatefulSet, and it provisions its own PVCs at 200Gi — the old `valkey-data` PVCs are not reused, and StatefulSet PVCs carry no `ownerReferences`, so nothing reclaims them automatically. Step 3b deletes them.
63+
64+
**Step 2 — Check whether volume expansion is enabled in the StorageClass of the Valkey PVCs**
65+
```shell
66+
kubectl get pvc -l app.kubernetes.io/name=valkey,app.kubernetes.io/instance=<release> --namespace <namespace> -o name | grep '/valkey-data-' \
67+
| xargs -r kubectl get --namespace <namespace> -o custom-columns=NAME:.metadata.name,SIZE:.spec.resources.requests.storage,CLASS:.spec.storageClassName
68+
69+
kubectl get storageclass <storage-class> -o jsonpath='{.allowVolumeExpansion}'
70+
```
71+
72+
If the SIZE column already reads `200Gi`, there is nothing to resize — skip to step 4.
73+
74+
**Step 3 — Replace or expand the PVCs**
75+
76+
3a. Expand in place — keeps the cached data. Only for a `<release>-valkey-node` StatefulSet **and** `allowVolumeExpansion: true`. Patching PVCs that belong to a `-valkey-primary` / `-valkey-replicas` StatefulSet has no effect on this upgrade: the new Sentinel StatefulSet creates its own PVCs, and the patched ones are left behind — stuck part-expanded if the StorageClass has no resizer.
77+
```shell
78+
kubectl delete statefulset -l app.kubernetes.io/name=valkey,app.kubernetes.io/instance=<release> --namespace <namespace>
79+
80+
kubectl get pvc -l app.kubernetes.io/name=valkey,app.kubernetes.io/instance=<release> --namespace <namespace> -o name | grep '/valkey-data-' \
81+
| xargs -r -I{} kubectl patch {} --namespace <namespace> --type=json -p '[{"op": "replace", "path": "/spec/resources/requests/storage", "value": "200Gi"}]'
82+
```
83+
84+
3b. Replace — discards the cache, and works for either layout on any StorageClass. Valkey here only backs the catalog cache, so its data is disposable and repopulates on demand. Delete the StatefulSet before the PVCs: while its pods are running, PVC deletion blocks on the in-use protection finalizer.
85+
```shell
86+
kubectl delete statefulset -l app.kubernetes.io/name=valkey,app.kubernetes.io/instance=<release> --namespace <namespace>
87+
88+
kubectl get pvc -l app.kubernetes.io/name=valkey,app.kubernetes.io/instance=<release> --namespace <namespace> -o name | grep '/valkey-data-' \
89+
| xargs -r kubectl delete --namespace <namespace>
90+
```
91+
92+
**Step 4 — REQUIRED: add this to your custom values file.** The upgrade stays blocked until it is present, and it must stay there for all future upgrades.
93+
```yaml
94+
valkeyPvcResizeAcknowledged: true
95+
```
96+
97+
**Step 5 — Run the upgrade again**
98+
```shell
99+
helm upgrade <release> ... --namespace <namespace>
100+
```
101+
102+
Already on `200Gi`, or already done steps 1-3? Then only steps 4 and 5 are needed.
10103

11104
## [103.148.0] - Jun 25, 2026
12105
* Update postgresql tag version to `17.10.0-debian`

stable/xray/Chart.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ dependencies:
77
version: 15.4.1
88
- name: catalog
99
repository: https://charts.jfrog.io/
10-
version: 101.43.5
10+
version: 101.44.0
1111
- name: valkey
1212
repository: https://charts.jfrog.io/
1313
version: 3.0.16
14-
digest: sha256:3f60323381ded9aa7617d9007e7fd3f961db9c61a01325a12254a20b9dc2f049
15-
generated: "2026-08-05T12:41:03.775677059Z"
14+
digest: sha256:af53cd3e41e72356290ba05ccb30bd705df050363ccfd474a71b53c6232f6785
15+
generated: "2026-08-17T06:48:59.324662754Z"

stable/xray/Chart.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
apiVersion: v2
2-
appVersion: 3.150.24
2+
appVersion: 3.150.31
33
dependencies:
44
- condition: postgresql.enabled
55
name: postgresql
@@ -12,7 +12,7 @@ dependencies:
1212
- condition: catalog.enabled
1313
name: catalog
1414
repository: https://charts.jfrog.io/
15-
version: 101.43.5
15+
version: 101.44.0
1616
- condition: valkey.enabled
1717
name: valkey
1818
repository: https://charts.jfrog.io/
@@ -32,4 +32,4 @@ name: xray
3232
sources:
3333
- https://github.com/jfrog/charts
3434
type: application
35-
version: 103.150.24
35+
version: 103.150.31

stable/xray/sizing/xray-2xlarge.yaml

Lines changed: 112 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,14 @@
33
# This size is intended for large organizations. It can be increased with adding replicas
44
##############################################################
55

6-
replicaCount: 3
6+
# For autoscaling, refer to the KEDA HPA example:
7+
# https://github.com/jfrog/charts/tree/master/examples/xray/xray-with-keda-hpa
8+
# If KEDA cannot be installed in your cluster, a static replicaCount (as set below) is recommended.
9+
replicaCount: 7
710
databaseUpgradeReady: true
811
waitForDatabase: true
912
unifiedUpgradeAllowed: true
1013

11-
autoscaling:
12-
enabled: true
13-
minReplicas: 3
14-
maxReplicas: 12
15-
targetCPUUtilizationPercentage: 200
16-
targetMemoryUtilizationPercentage: 800
17-
1814
xray:
1915
podAntiAffinity:
2016
## Valid values are "soft" or "hard"; any other value indicates no anti-affinity
@@ -24,7 +20,7 @@ xray:
2420
analysis:
2521
resources:
2622
requests:
27-
cpu: "100m"
23+
cpu: "60m"
2824
memory: 250Mi
2925
limits:
3026
# cpu: "4"
@@ -34,15 +30,15 @@ indexer:
3430
resources:
3531
requests:
3632
cpu: "300m"
37-
memory: 550Mi
33+
memory: 1Gi
3834
limits:
3935
# cpu: "6"
4036
memory: 8Gi
4137

4238
persist:
4339
resources:
4440
requests:
45-
cpu: "100m"
41+
cpu: "60m"
4642
memory: 250Mi
4743
limits:
4844
# cpu: "4"
@@ -51,34 +47,34 @@ persist:
5147
server:
5248
resources:
5349
requests:
54-
cpu: "300m"
50+
cpu: "180m"
5551
memory: 500Mi
5652
limits:
5753
# cpu: "4"
58-
memory: 6Gi
54+
memory: 10Gi
5955

6056
router:
6157
resources:
6258
requests:
6359
cpu: "60m"
6460
memory: 100Mi
6561
limits:
66-
# cpu: "1"
62+
# cpu: "3"
6763
memory: 1Gi
6864

6965
observability:
7066
resources:
7167
requests:
72-
cpu: "10m"
68+
cpu: "5m"
7369
memory: 25Mi
7470
limits:
75-
# cpu: "1"
71+
# cpu: "850m"
7672
memory: 250Mi
7773

7874
sbom:
7975
resources:
8076
requests:
81-
cpu: "100m"
77+
cpu: "60m"
8278
memory: 250Mi
8379
limits:
8480
# cpu: "4"
@@ -93,6 +89,60 @@ policyenforcer:
9389
memory: "8Gi"
9490
# cpu: "4"
9591

92+
aiscanner:
93+
resources:
94+
requests:
95+
cpu: "30m"
96+
memory: 100Mi
97+
limits:
98+
# cpu: "2"
99+
memory: 4Gi
100+
101+
curation:
102+
resources:
103+
requests:
104+
cpu: "180m"
105+
memory: 500Mi
106+
limits:
107+
# cpu: "4"
108+
memory: 6Gi
109+
110+
jascontextual:
111+
resources:
112+
requests:
113+
cpu: "1.5"
114+
memory: 4Gi
115+
limits:
116+
# cpu: "3.0"
117+
memory: 16Gi
118+
119+
jasexposures:
120+
resources:
121+
requests:
122+
cpu: "1.5"
123+
memory: 4Gi
124+
limits:
125+
# cpu: "3.0"
126+
memory: 16Gi
127+
128+
reporting:
129+
resources:
130+
requests:
131+
cpu: "180m"
132+
memory: 500Mi
133+
limits:
134+
# cpu: "4"
135+
memory: 10Gi
136+
137+
initContainers:
138+
resources:
139+
requests:
140+
memory: "50Mi"
141+
cpu: "12m"
142+
limits:
143+
memory: "1Gi"
144+
cpu: "250m"
145+
96146
# PostgreSQL
97147
## Configuration values for the postgresql dependency
98148
## ref: https://github.com/kubernetes/charts/blob/master/stable/postgresql/README.md
@@ -131,11 +181,11 @@ rabbitmq:
131181
{{- end }}
132182
resources:
133183
requests:
134-
cpu: "500m"
135-
memory: 1Gi
184+
cpu: "200m"
185+
memory: 500Mi
136186
limits:
137-
# cpu: "8"
138-
memory: 7Gi
187+
# cpu: "4"
188+
memory: 5Gi
139189
affinity:
140190
podAntiAffinity:
141191
requiredDuringSchedulingIgnoredDuringExecution:
@@ -153,8 +203,24 @@ catalog:
153203
cpu: "6"
154204
memory: 16Gi
155205
limits:
156-
cpu: "12"
206+
# cpu: "12"
157207
memory: 32Gi
208+
initContainers:
209+
resources:
210+
requests:
211+
memory: "50Mi"
212+
cpu: "12m"
213+
limits:
214+
memory: "1Gi"
215+
cpu: "250m"
216+
router:
217+
resources:
218+
requests:
219+
cpu: "60m"
220+
memory: 100Mi
221+
limits:
222+
# cpu: "3"
223+
memory: 1Gi
158224

159225
valkey:
160226
primary:
@@ -163,21 +229,41 @@ valkey:
163229
cpu: "4"
164230
memory: 12Gi
165231
limits:
166-
cpu: "8"
232+
# cpu: "8"
167233
memory: 24Gi
234+
## Bound the cache below limits.memory so Valkey evicts instead of being
235+
## OOMKilled. The headroom covers fork() copy-on-write during AOF rewrite,
236+
## replication buffers and allocator fragmentation.
237+
## Applied when sentinel.enabled=false; keep in sync with limits.memory.
238+
configuration: |-
239+
maxmemory 18gb
240+
maxmemory-policy allkeys-lru
168241
replica:
169242
resources:
170243
requests:
171244
cpu: "4"
172245
memory: 12Gi
173246
limits:
174-
cpu: "8"
247+
# cpu: "8"
175248
memory: 24Gi
249+
## With sentinel.enabled=true (the default) every node runs from this
250+
## block, so this is the setting that actually takes effect.
251+
configuration: |-
252+
maxmemory 18gb
253+
maxmemory-policy allkeys-lru
176254
sentinel:
177255
resources:
178256
requests:
179257
cpu: "250m"
180258
memory: 256Mi
181259
limits:
182-
cpu: "1"
183-
memory: 1Gi
260+
# cpu: "1"
261+
memory: 1Gi
262+
kubectl:
263+
resources:
264+
requests:
265+
memory: "50Mi"
266+
cpu: "12m"
267+
limits:
268+
memory: "250Mi"
269+
cpu: "250m"

0 commit comments

Comments
 (0)