paperless-ngx: an empty barcodes block falls back to the chart defaults
A "barcodes:" key left without children (e.g. after deleting the last remaining sub-key, PAPERLESS_CONSUMER_BARCODE_SCANNER, which paperless-ngx 3.0 removed) is YAML null and replaced the whole default sub-tree on merge. Rendering then failed on the nil pointer, so the release simply stopped updating. An empty or null block now means "the chart defaults apply". The merge runs through a new paperless-ngx.defaultedDict helper: nulls never delete, nested maps merge recursively, and explicitly set values win - including false and 0, which "default" and "mergeOverwrite" would swallow. A scalar where the defaults define a map is rejected with the values path in the message. Major bump: the meaning of a values override changes. Fixes #61
This commit is contained in:
5 files changed
+99
-5
No files matched your search
@@ -9,5 +9,12 @@ ingress:
|
|||||||
# apply - there is no cert-manager in the CI cluster.
|
# apply - there is no cert-manager in the CI cluster.
|
||||||
clusterIssuer: ci
|
clusterIssuer: ci
|
||||||
|
|
||||||
|
paperless:
|
||||||
|
files:
|
||||||
|
# Regression guard for issue #61: a childless "barcodes:" key is YAML null.
|
||||||
|
# It must fall back to the chart defaults (barcodes enabled, "PATCHT") and
|
||||||
|
# neither erase them nor break rendering.
|
||||||
|
barcodes:
|
||||||
|
|
||||||
# smbConnection and oidc stay disabled (defaults): the SMB CSI driver and a
|
# smbConnection and oidc stay disabled (defaults): the SMB CSI driver and a
|
||||||
# real OIDC login flow are out of scope for the CI install-test.
|
# real OIDC login flow are out of scope for the CI install-test.
|
||||||
@@ -5,7 +5,7 @@ icon: https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/dev/src-ui/s
|
|||||||
|
|
||||||
type: application
|
type: application
|
||||||
|
|
||||||
version: 10.0.0+up3.0.5
|
version: 11.0.0+up3.0.5
|
||||||
|
|
||||||
appVersion: 3.0.5
|
appVersion: 3.0.5
|
||||||
|
|
||||||
|
|||||||
@@ -114,3 +114,78 @@ template-chart is the reference implementation.
|
|||||||
1
|
1
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Merge a user-supplied values sub-tree onto a dict of chart defaults so that a
|
||||||
|
null / empty override falls back to the defaults instead of erasing them.
|
||||||
|
|
||||||
|
Input: dict "defaults" <dict> "given" <dict|nil> "path" <string, optional
|
||||||
|
values path used in error messages>. Output: YAML of the merged dict (consume
|
||||||
|
it with fromYaml).
|
||||||
|
|
||||||
|
Why this exists (issue #61): Helm merges values maps recursively, but an
|
||||||
|
override key written without children — e.g. a leftover
|
||||||
|
|
||||||
|
barcodes:
|
||||||
|
|
||||||
|
after deleting its last remaining sub-key — is YAML null and replaces the
|
||||||
|
whole default sub-tree. The chart then renders with no barcode settings at
|
||||||
|
all. This helper defines the opposite semantics: an empty block means "chart
|
||||||
|
defaults apply".
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
- a nil "given" is treated as an empty dict (all defaults apply).
|
||||||
|
- a key whose override value is null keeps the default (nulls never delete).
|
||||||
|
- a key present in both as a map is merged recursively, so a partially
|
||||||
|
filled block only overrides the keys it actually sets.
|
||||||
|
- a scalar override for a key the defaults define as a map is rejected with
|
||||||
|
a message naming the values path, instead of failing later with a template
|
||||||
|
field error.
|
||||||
|
- any other set value wins as given, including an explicit false or 0 —
|
||||||
|
Helm's "default" and sprig's "mergeOverwrite" would both swallow those
|
||||||
|
zero values, hence the explicit kindIs "invalid" nil check.
|
||||||
|
- keys only present in the override are passed through unchanged.
|
||||||
|
*/}}
|
||||||
|
{{- define "paperless-ngx.defaultedDict" -}}
|
||||||
|
{{- $defaults := .defaults | default dict -}}
|
||||||
|
{{- $given := .given -}}
|
||||||
|
{{- $path := .path | default "value" -}}
|
||||||
|
{{- if kindIs "invalid" $given -}}
|
||||||
|
{{- $given = dict -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- if not (kindIs "map" $given) -}}
|
||||||
|
{{- fail (printf "%s must be a mapping or null, got %s (%v)" $path (kindOf $given) $given) -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- $out := deepCopy $defaults -}}
|
||||||
|
{{- range $key, $value := $given -}}
|
||||||
|
{{- if not (kindIs "invalid" $value) -}}
|
||||||
|
{{- $default := index $defaults $key -}}
|
||||||
|
{{- if and (kindIs "map" $value) (kindIs "map" $default) -}}
|
||||||
|
{{- $_ := set $out $key (fromYaml (include "paperless-ngx.defaultedDict" (dict "defaults" $default "given" $value "path" (printf "%s.%s" $path $key)))) -}}
|
||||||
|
{{- else if kindIs "map" $default -}}
|
||||||
|
{{- fail (printf "%s.%s must be a mapping or null, got %s (%v)" $path $key (kindOf $value) $value) -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- $_ := set $out $key $value -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- toYaml $out -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
The effective barcode settings, rendered as YAML (consume with fromYaml).
|
||||||
|
|
||||||
|
Input: .Values.paperless.files.barcodes (may be nil, empty or partial).
|
||||||
|
|
||||||
|
The defaults below MUST stay in sync with the barcodes block in values.yaml,
|
||||||
|
which stays the documented, user-facing place for them; this copy is only the
|
||||||
|
fallback for the case where an override has erased the block.
|
||||||
|
*/}}
|
||||||
|
{{- define "paperless-ngx.barcodes" -}}
|
||||||
|
{{- $defaults := dict
|
||||||
|
"enabled" true
|
||||||
|
"barcodeString" "PATCHT"
|
||||||
|
"retainBarcodePage" false
|
||||||
|
"asn" (dict "enabled" true) -}}
|
||||||
|
{{- include "paperless-ngx.defaultedDict" (dict "defaults" $defaults "given" . "path" "paperless.files.barcodes") -}}
|
||||||
|
{{- end -}}
|
||||||
@@ -1,3 +1,8 @@
|
|||||||
|
{{- /*
|
||||||
|
Barcode settings, defended against a null / empty "barcodes:" override:
|
||||||
|
an empty block falls back to the chart defaults (issue #61).
|
||||||
|
*/ -}}
|
||||||
|
{{- $barcodes := fromYaml (include "paperless-ngx.barcodes" .Values.paperless.files.barcodes) -}}
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: StatefulSet
|
kind: StatefulSet
|
||||||
metadata:
|
metadata:
|
||||||
@@ -137,13 +142,13 @@ spec:
|
|||||||
- name: PAPERLESS_URL
|
- name: PAPERLESS_URL
|
||||||
value: "https://{{ .Values.ingress.domain }}"
|
value: "https://{{ .Values.ingress.domain }}"
|
||||||
- name: PAPERLESS_CONSUMER_ENABLE_ASN_BARCODE
|
- name: PAPERLESS_CONSUMER_ENABLE_ASN_BARCODE
|
||||||
value: "{{ .Values.paperless.files.barcodes.asn.enabled }}"
|
value: "{{ $barcodes.asn.enabled }}"
|
||||||
- name: PAPERLESS_CONSUMER_ENABLE_BARCODES
|
- name: PAPERLESS_CONSUMER_ENABLE_BARCODES
|
||||||
value: "{{ .Values.paperless.files.barcodes.enabled }}"
|
value: "{{ $barcodes.enabled }}"
|
||||||
- name: PAPERLESS_CONSUMER_BARCODE_STRING
|
- name: PAPERLESS_CONSUMER_BARCODE_STRING
|
||||||
value: "{{ .Values.paperless.files.barcodes.barcodeString }}"
|
value: "{{ $barcodes.barcodeString }}"
|
||||||
- name: PAPERLESS_CONSUMER_BARCODE_RETAIN_SPLIT_PAGES
|
- name: PAPERLESS_CONSUMER_BARCODE_RETAIN_SPLIT_PAGES
|
||||||
value: "{{ .Values.paperless.files.barcodes.retainBarcodePage }}"
|
value: "{{ $barcodes.retainBarcodePage }}"
|
||||||
- name: PAPERLESS_CONSUMER_DELETE_DUPLICATES
|
- name: PAPERLESS_CONSUMER_DELETE_DUPLICATES
|
||||||
value: "{{ .Values.paperless.files.deleteDuplicates }}"
|
value: "{{ .Values.paperless.files.deleteDuplicates }}"
|
||||||
{{- if .Values.paperless.files.tikaGotenberg.enabled }}
|
{{- if .Values.paperless.files.tikaGotenberg.enabled }}
|
||||||
|
|||||||
@@ -48,6 +48,13 @@ paperless:
|
|||||||
# The barcode scanner backend is no longer configurable: paperless-ngx 3.0
|
# The barcode scanner backend is no longer configurable: paperless-ngx 3.0
|
||||||
# removed pyzbar and PAPERLESS_CONSUMER_BARCODE_SCANNER; zxing-cpp is the
|
# removed pyzbar and PAPERLESS_CONSUMER_BARCODE_SCANNER; zxing-cpp is the
|
||||||
# only backend now.
|
# only backend now.
|
||||||
|
#
|
||||||
|
# An empty or null "barcodes:" block in an override means "the defaults
|
||||||
|
# below apply" — the chart merges the block onto these defaults instead of
|
||||||
|
# letting a childless key erase them (issue #61; the fallback copy lives in
|
||||||
|
# the paperless-ngx.barcodes helper and is kept in sync with this block).
|
||||||
|
# To switch barcode handling off, set barcodes.enabled: false explicitly;
|
||||||
|
# deleting the sub-keys does not disable it.
|
||||||
barcodes:
|
barcodes:
|
||||||
enabled: true
|
enabled: true
|
||||||
barcodeString: "PATCHT"
|
barcodeString: "PATCHT"
|
||||||
|
|||||||
Reference in new issue
Block a user