Group 2 of the #114 sweep: the charts whose behaviour hangs off an nginx
annotation - calibre-web-automated, outline, paperless-ngx, zipline
(proxy-body-size) and freesailarr (rewrite-target).
Each gets the form the pilot (cyberchef, PR #115) fixed and group 1 (PR #116)
repeated: an httpRoute block off by default, a template rendering ONLY an
HTTPRoute with parentRefs - no Gateway, no gatewayClassName, no Certificate, no
implementation-specific policy object - render aborts on both modes at once
(naming both value paths), on an empty parentRefs and on a missing hostname,
empty hostnames meaning [ingress.domain], a schema entry closed against unknown
keys with an open parentRef definition, and a NOTES.txt that names the active
mode and what the mode costs.
Minor, additive, defaults unchanged: `helm template` with each chart's CI values
is byte-identical to origin/main for all five.
The upload limit is DOCUMENTED, not rebuilt (decision 2 of the issue). The
Gateway API knows no body size; a policy object would bind the chart to one
implementation. So the Gateway branch of NOTES.txt says, per chart and in the
chart's own terms, that the value is NOT ENFORCED and names where to set it: an
e-book library (calibre), an upload service (zipline), the web-UI half of the
document intake while the consume directory keeps no limit at all (paperless),
and the open #12 pair (outline).
Four findings that were not in the plan, each argued in the file it changes:
freesailarr gated freesailarr.sharedIngressApps on ingress.enabled, and that
list is read by the <APP>__SERVER__URLBASE variables as well as by the routing
objects. In Gateway mode it would have come out EMPTY while the route served
radarr, sonarr and prowlarr under their prefixes: UrlBase unset, assets and API
calls linked at the host root, broken UI behind a Ready pod. The helper's two
guards (seerr/mediathekarr only at "/", no duplicate paths) would have gone
unenforced there too. Fixed with freesailarr.published (ingress.enabled OR
httpRoute.enabled) - the same shape as sure.publishedOverTls in group 1, and
identical to ingress.enabled while httpRoute.enabled is false. Measured: on
origin/main with ingress.enabled: false the render emits ZERO URLBASE
variables; with this change in Gateway mode it emits three.
paperless-ngx was the last chart in the repository rendering its Ingress
UNCONDITIONALLY. Without an ingress.enabled switch there is no second value
path for the mutual-exclusion abort to name, and the Ingress plus its
unconditional required() on clusterIssuer would have kept rendering in Gateway
mode - a value demanded for nothing, which is issue #114's "Folge 1" and
README guideline 12. The switch was added, defaulting to true, so the render is
unchanged.
paperless-ngx PAPERLESS_URL had no required() of its own: it relied on the
Ingress template's, which stops firing the moment the Ingress is switchable.
With httpRoute.hostnames set and ingress.domain empty it would have rendered
"https://" and refused every login POST as a CSRF failure. It now carries its
own required(), naming what the value is for.
calibre-web-automated claimed, in values.yaml and in its schema, that
ingress.domain is read nowhere but in the Ingress template. The HTTPRoute reads
it, so the claim now holds only while both modes are off. Corrected rather than
left standing - the same correction garage needed in group 1.
freesailarr is where the Gateway API is LESS machinery than what it replaces,
not a translation of it. rewrite-target applies per Ingress OBJECT, so
qBittorrent (no base path, prefix must be stripped) needed a second Ingress on
the shared host, which then had to repeat the first object's TLS secret name,
omit the cert-manager annotation conditionally so only one Certificate is
requested, and match an ImplementationSpecific regex path for the rewrite's
capture group. A URLRewrite filter applies per RULE: one route, one rule per
app, the filter on qBittorrent's rule, a plain PathPrefix. All four crutches
gone. It is also the only chart without httpRoute.hostnames - it has no
ingress.domain either, and a chart-global hostname list could not say which of
the ten apps it belonged to, so the hostnames stay in ingress.host and
<app>.ingress.host.
CI: one render overlay per chart under ci/httproute/, so the assertion is not
vacuum-green - ci/run-httproute-match-test.sh goes from 20 held assertions over
10 charts to 36 over 15. freesailarr's overlay moves bazarr onto a host of its
own, so the shared-host route AND the per-app route are both rendered; without
that the per-app branch would be exercised by nothing. The install-test fixtures
stay in Ingress mode: the install runs one configuration per chart, cyberchef
already pays that price against the real Gateway-API CRDs, and for paperless-ngx
that fixture is the only install of the valkey-subchart path anywhere.
README also carries a stale figure fixed here: the HTTPRoute test was still
documented at the pilot's 4 assertions over 2 charts, although group 1 had taken
it to 20 over 10.
Not proven, by construction: that traffic flows. No Gateway controller runs in
CI. Not run locally either: k3d, Docker, Trivy. The Gateway branch of NOTES.txt
is EXECUTED by the render test (a template error in it fails the job, verified)
but its text is printed by no pipeline stage - helm template does not emit
notes, and the install-test installs in Ingress mode.
Part of #114
Largest values surface of the programme, and the first chart where the
null-safety covers two workloads.
1. values.schema.json (#68): additionalProperties: false on every
chart-owned object level, including files.barcodes, ocr (with enums
for the 3.x modes), scripts, tikaGotenberg, the oidc provider block
and the SMB CronJob.
2. Null-safety for hardening, probes and resources (#99), for the server
AND the SMB consume-mover CronJob. It reuses the defaultedDict helper
the barcodes block already introduced (#61) instead of adding a second
mechanism - one merge helper, now with more callers.
The server's pod context is consumed twice: as the pod securityContext
and by the /run-ownership init container, which chowns /run to
runAsUser:runAsGroup because s6-overlay refuses to start unless /run is
owned by the runtime uid. Both reads now go through the same helper, so
the chown cannot disagree with the context it has to match. Erasing
that block used to abort rendering with a nil-pointer error; it now
falls back to the defaults like every other chart.
The CronJob has no probes (documented exception), so only its two
contexts and resources are covered.
files.storage stays deliberately not null-safe: an erased value yields an
invalid PVC, which is the loud class #99 excludes.
Rendering is byte-identical to 11.0.0, both with the CI values (which
include the #61 regression guard) and with the production paperless-jk
bundle values.
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
Batch-3 major PR for paperless-ngx (issue #32):
- secrets.redisRef/databaseRef/paperlessRef -> redisSecretRef/
databaseSecretRef/paperlessSecretRef (consistent with the other
SecretRef values in the same block); CI fixtures updated
- TLS secret renamed to the standard tls-<release>-<chart>-ingress
(domain no longer part of the name)
- busybox init/cronjob image pinned via paperless.busybox.image
values, default bumped 1.28 -> 1.38.0
- probes values-configurable (defaults unchanged, incl. the 600s
startup budget); consume CronJob deliberately stays probe-less
- ingress standard: ingress.className (default nginx) and
ingress.annotations merge; domain/clusterIssuer stay required
- additive paperless.env block rendered through tpl (value,
secretKeyRef, configMapKeyRef forms)
- disabled scripts ConfigMap renamed to ...-configmap; PVC names kept
as documented naming-scheme exception (comments in the templates)
- chart 8.0.1+up3.0.5 -> 9.0.0+up3.0.5 (breaking values changes)
Major app jump 2.20.15 -> 3.0.5. Chart major bump (7.1.1 -> 8.0.0):
the paperless.files.barcodes.scanner value is removed (pyzbar and
PAPERLESS_CONSUMER_BARCODE_SCANNER were removed upstream), the
paperless.ocr.mode default changes from the removed "skip" to "auto",
and the startup probe budget is raised to 600s for the one-time
Whoosh -> Tantivy index rebuild. New optional values:
paperless.ocr.archiveFileGeneration, paperless.files.deleteDuplicates,
oidc.provider.tokenAuthMethod.
Every Deployment/StatefulSet now takes its replica count from a replicas
value (default 1, explicit 0 allowed) via a new per-chart <chart>.replicas
helper; the helper uses a kindIs "invalid" nil check so an explicit 0 is
not swallowed by Helm's default function. A chart-global scaleDown flag
(default false) takes precedence: it renders every workload with
replicas: 0 and suspends the paperless-ngx consume CronJob, stopping the
app without uninstalling it (PVCs, Secrets, Services and Ingress remain).
Defaults leave the rendered manifests byte-identical to main, so all
published charts get a minor version bump; the template-chart carries the
reference helper implementation and stays unversioned.
Fixes#25
Every chart now renders its container resources through a duplicated
_helpers.tpl helper (reference implementation in template-chart): requests
ship as chart defaults, missing memory and ephemeral-storage limits are
computed as resources.limitFactor x the request (default 3, satisfactory
keeps 2 to preserve its previously published 8Gi limit), an explicitly set
limit always wins, and a CPU limit is only rendered when set explicitly.
Fixed limit defaults are removed from all values.yaml files; teamspeak-server
gains a values-driven resources block instead of hardcoded template values.
Major version bump for all published charts.
Add securityContext hardening (runAsNonRoot, readOnlyRootFilesystem,
capabilities drop ALL, allowPrivilegeEscalation false) to the 10 workloads
that lacked it: apache-tika, cyberchef, gotenberg, homeassistant,
matrix-delegation-nginx, paperless-server, paperless-consume cronjob
(plus automountServiceAccountToken false), patchmon-frontend,
urlaubsverwaltung and zipline. All contexts are configurable via
securityContext.pod / securityContext.container in values.yaml; writable
paths are provided as emptyDirs. Image-forced deviations (Home Assistant
root start for s6-overlay + NET_RAW for discovery, paperless root init
container for /run ownership) are documented in the charts' values.yaml.
Major version bump for every changed published chart.
Every container in every Deployment/StatefulSet now defines all three
probes. The paperless-ngx consume CronJob intentionally has none (batch
workload).
- Add probes: apache-tika, calibre-web-automated, cyberchef, gotenberg,
homeassistant, patchmon-backend, samba (tcp/445), teamspeak-server
(tcp/30033), zipline (/api/healthcheck)
- Fix voucher-vault null probe values with real defaults
- Fix startup-probe semantics in template-chart and rallly (no
initialDelaySeconds, generous failureThreshold)
- Switch outline probes to its /_health endpoint
- Add readiness/startup probes to satisfactory
- Add startup probes to matrix-synapse, matrix-delegation-nginx,
paperless-server, patchmon-frontend, urlaubsverwaltung
- Major version bump for all published charts