From 5d10b0245820c8cf8760b913e3b7f6af02aa463d Mon Sep 17 00:00:00 2001 From: Justin Klein Date: Sat, 3 Oct 2026 20:40:47 +0000 Subject: [PATCH] fix(garage): compressionLevel disables with "none", never with 0 My own values comment claimed 0 switches compression off. It does not: Garage's deserializer takes an integer OR the literal string "none" (src/util/config.rs, deserialize_compression), and 0 is a valid integer that zstd reads as its default level - 3, i.e. MORE compression than the chart's 1, not none. A comment that invites an operator to write 0 for "off" is the values-that-must-not-lie shape with the lie in the documentation instead of in the template. The schema now accepts an integer (negative included, those are zstd's fast modes) or exactly "none", and the ConfigMap quotes the string form so the rendered TOML stays valid. Verified: 1, 7, -3 render unquoted, "none" renders quoted and the result still parses as TOML, and any other string is rejected by the schema. No version bump: the chart is not published yet. --- garage/templates/garage.configmap.yaml | 9 +++++++++ garage/values.schema.json | 8 +++++--- garage/values.yaml | 10 +++++++++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/garage/templates/garage.configmap.yaml b/garage/templates/garage.configmap.yaml index 4a60a95..5f60c28 100644 --- a/garage/templates/garage.configmap.yaml +++ b/garage/templates/garage.configmap.yaml @@ -92,7 +92,16 @@ data: metadata_auto_snapshot_interval = "{{ $settings.metadataAutoSnapshotInterval }}" block_size = "{{ $settings.blockSize }}" + # An integer is the zstd level; the literal "none" disables compression and + # has to be QUOTED to stay valid TOML. Garage's deserializer takes exactly + # those two forms - and 0 is not the second one: it is a valid integer that + # zstd reads as its default level (3), so writing 0 to "switch compression + # off" quietly turns it up. + {{- if kindIs "string" $settings.compressionLevel }} + compression_level = {{ $settings.compressionLevel | quote }} + {{- else }} compression_level = {{ $settings.compressionLevel | int64 }} + {{- end }} # Inter-node RPC. There are no other nodes here (no bootstrap_peers, no # kubernetes_discovery - see values.yaml), but Garage binds this listener diff --git a/garage/values.schema.json b/garage/values.schema.json index c5ca314..b33211e 100644 --- a/garage/values.schema.json +++ b/garage/values.schema.json @@ -77,9 +77,11 @@ "minLength": 1 }, "compressionLevel": { - "description": "zstd level for stored blocks; 0 disables compression.", - "type": "integer", - "minimum": 0 + "description": "zstd level for stored blocks, or the literal string \"none\" to disable compression. NOT 0 for disabling: Garage accepts 0 as an integer and zstd reads it as its default level (3), i.e. more compression than 1, not none. Negative integers are zstd's fast modes.", + "oneOf": [ + { "type": "integer" }, + { "type": "string", "enum": ["none"] } + ] }, "bindAddress": { "description": "Host part of the S3, web and RPC listeners. '[::]' accepts IPv4 as well while net.ipv6.bindv6only is 0.", diff --git a/garage/values.yaml b/garage/values.yaml index e54d38a..85f1601 100644 --- a/garage/values.yaml +++ b/garage/values.yaml @@ -212,7 +212,15 @@ garage: # Garage's defaults, exposed because they are the two knobs that trade disk # against CPU. blockSize is the chunk size objects are split into; # compressionLevel is the zstd level for stored blocks (1 = fast, higher = - # smaller, "none" is not a value here - set 0 to disable). + # smaller, negative levels are zstd's "fast" modes). + # + # TO DISABLE COMPRESSION, WRITE THE STRING "none" - and not 0, which is the + # trap this comment exists for: Garage's deserializer accepts an integer or + # the literal "none" (src/util/config.rs, deserialize_compression), and 0 is + # a perfectly valid integer that zstd reads as "use my default level", i.e. + # level 3 - MORE compression than the 1 below, not less. The schema therefore + # accepts an integer or exactly "none", and the ConfigMap quotes the string + # form so the rendered TOML stays valid. blockSize: "1M" compressionLevel: 1