Teil von #157.
The null-safe fallback helpers from #99 pass values through fromYaml, which
goes over JSON and therefore parses every number as float64. Go's "%v"
switches float64 to exponential notation from about 1e6 upwards, so a bare
byte count like 1048576 turned into "1.048576e+06" - not a valid Kubernetes
quantity. The suffix check in multiplyQuantity then aborted the render with
unsupported resource quantity suffix "e+06" in "1.048576e+06"
The second "%v" - the one printing a non-integer product - never reaches that
check and failed silently instead: with a fractional limitFactor it rendered
"1.4999985e+06" into the manifest, which only the API server rejects on apply.
Both call sites now go through a new rss-bridge.formatNumber helper that
forces decimal notation via printf "%.10f" and trims the padding zeros again;
the leading dot in the regex protects "100.0000000000" from collapsing to
"1". Strings such as "512Mi" pass through untouched.
This is the canonical fix from #157, applied verbatim with this chart's
prefix; the round-trip itself is not touched.
Note on this chart specifically: rss-bridge sets explicit memory and
ephemeral-storage limits as chart defaults, and an explicit limit always
wins, so multiplyQuantity is not reachable through this chart's values at
all - the bug was reproduced and the fix verified on a throwaway copy with
those default limits removed. The rendered output for the chart defaults and
for ci/rss-bridge/test-values.yaml is byte-identical to main.
Patch bump: no behavior and no values-schema change.
One step: 2025-08-05 is the immediate successor release, no publication
in between (verified against the project's release list). Tag present on
Docker Hub for amd64 and arm64.
Patch bump, because the changelog review found nothing that touches the
values surface or the chart's behaviour. Checked against the shipped
source of both images rather than against the release notes:
- whitelist.txt format: lib/Configuration.php is byte-identical apart
from its VERSION constant, so the parsing the chart relies on (trim,
split on newline, drop empty entries, "*" wildcard) is unchanged.
- the five production bridges: all present, none renamed. Youtube,
TheHackerNews, ARDMediathek and Reddit are byte-identical; Heise has a
content-level change only (paywalled heise+ items now carry an
archive.is link, two more CSS selectors stripped). The three bridges
removed upstream - Askfm, DansTonChat, FirstLookMediaTech - are none
of ours.
- RSSBRIDGE_* environment mapping: same file, therefore unchanged.
- write paths: re-derived empirically rather than inferred, because the
opcache lock file in /tmp appears in no filesystem diff. The new image
needs exactly the same five, and a control run without /tmp still dies
with "Unable to create lock file: Read-only file system".
- health endpoint: actions/ is identical, /?action=health intact.
- PHP 8.2.28 -> 8.2.29, nginx and Debian unchanged, so the
/run/php/php8.2-fpm.sock path the chart mounts still applies. Measured
fresh-start peak under five concurrent feed fetches: 64.5 MiB on the
new image against 71.1 MiB on the old one under an identical
procedure. Requests and limits stay as they are.
The memory comments in values.yaml are refreshed to the image the chart
now ships, and the older 119 MiB figure is labelled as what it was - a
warm container, not a fresh start.
We stay on the dated release tag. The newest release is itself over
twelve months old and the project now pushes latest and commit-based
sha-* tags continuously, but a sha-* tag is not more released than the
release, only newer, and latest is rolling - both conflict with the
repo's convention of reproducible pinned tags.
Fixes#135
Takes over the four loose manifests in cluster-config/rss-bridge/ as a
proper chart, on the current template-chart standard: strict values
schema, null-safe helpers, computed limits, replicas/scaleDown,
checksum/config, NOTES.txt.
Two things deviate from the repo standard on purpose:
- The Ingress models host AND TLS secret name per entry instead of the
single conventional tls-<release>-<chart>-ingress. The installation
this replaces has grown three separate certificates, one per host.
Renaming them would make cert-manager issue three new ones and leave
each host unreachable until it did - a self-inflicted outage on a
deployment that has been up for over a year. Entries sharing a secret
name are grouped into one tls entry, and omitting the name falls back
to the convention, so consolidating later is a values change.
- Requests and limits are decoupled. The old manifest requested 2Gi of
ephemeral storage, identical to its limit, reserving two gigabytes for
a workload measured at 2.2 MB after fetching all five whitelisted
bridges. The request drops to 64Mi; the limit stays at 2Gi.
Hardening was verified rather than assumed. The image ships no USER and
runs as root by default, but runs fully hardened once its writable paths
are provided: uid/gid 33, readOnlyRootFilesystem, all capabilities
dropped, seccompProfile RuntimeDefault. The writable paths were found by
running the image with a writable rootfs, exercising every bridge and
reading its diff layer - /app/cache, /run, /run/php, /var/lib/nginx.
/tmp did not show up that way, because PHP's opcache creates its lock
file there and unlinks it immediately; it only surfaced when the
hardened container died at startup. Stopping at the first writable path
would have shipped a chart that cannot start.
Probes use the app's own /?action=health, which renders fixed JSON
without touching the cache or any remote site, so neither a scraped site
going down nor an unwritable cache can restart the pod.
Fixes#128