cbddba6972aee620f3d31ecb9322b4b869f1bf10
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
cbddba6972
|
Replace the obsolete no-dependencies rationale in every chart helper
Validate Helm Charts / Detect changed charts (pull_request) Successful in 4s
Validate Helm Charts / Resource quantities (pull_request) Successful in 8s
Validate Helm Charts / Build ${{ fromJSON(needs.detect-changed-charts.outputs.charts) }} (pull_request) Successful in 32s
Validate Helm Charts / Trivy config ${{ fromJSON(needs.detect-changed-charts.outputs.scan-charts) }} (pull_request) Successful in 1m24s
Validate Helm Charts / Install-test ${{ fromJSON(needs.detect-changed-charts.outputs.install-charts) }} (pull_request) Failing after 16m52s
The doc comments on the resources and defaultedDict helpers justified the copy-per-chart with "charts in this repo deliberately have no dependencies". That rule fell with #214: a dependency is admissible now, just expensive, and it sits in the README as guideline 14, not 13. The justification still holds, but its reason is a different one - sharing the helper would mean a library chart, a second artefact to publish, version and pull for something that changes about once a year. searxng got that wording in PR #38; this carries it to the remaining 22 charts, 41 occurrences in all. Comments only: every touched chart renders byte-identical against its ci/<chart>/test-values.yaml. Each published chart takes a patch bump, appVersion and +up suffix untouched; template-chart is never published and takes none, but is corrected because every new chart inherits from it. Two repo files carried the same claim at no version cost: validate-charts.yml explained the all-charts quantity render test with it, and change-app-version.yml still counted nine images for freesailarr - MediathekArr made it ten. |
||
|
|
e666cfed6c
|
rss-bridge: render byte counts as plain decimals (1.0.2+up2025.08.05)
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. |
||
|
|
bcbcc2c62f
|
rss-bridge: app update 2025-06-03 -> 2025-08-05
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 |
||
|
|
7e6b3beed5
|
rss-bridge: pin the unprivileged-port sysctl, quote env values
Follow-up to the template-chart hardening fixes in #133, which landed while this branch was open. The env block now quotes names, values and keyRef fields. Without it a value like "5" renders as a YAML number and the API server rejects the whole manifest. RSS-Bridge takes numeric settings that way (RSSBRIDGE_http_timeout), so this was reachable with the first env entry anyone adds. The port-80 question is settled by measurement rather than by the "it works in k3d" reasoning #133 warns about. Same pod spec in k3d (k3s v1.35.5), only ip_unprivileged_port_start changed: 1024, capabilities.drop [ALL] nginx: bind() to 0.0.0.0:80 failed (13: Permission denied) 1024, plus NET_BIND_SERVICE identical failure - for a non-root process the capability lands in the permitted but not the effective set, so it buys nothing 0 binds, HTTP 200 So the chart cannot buy safety with a capability the way samba does, and port 80 is not negotiable either: nginx is configured for it inside the image and the entrypoint's only lever is a sed against a read-only /etc/nginx. What it can do is stop depending on the node default - the pod securityContext now pins the sysctl to 0, so the bind no longer relies on cluster configuration. Verified: the chart-installed pod reports 0 and answers 200 through the Service. Worth recording how that failure looks without probes: the entrypoint backgrounds nginx and then execs php-fpm, so a failed bind leaves a container reporting Running with no web server at all. Both test pods above were Running. The probes on /?action=health are what turn it into a pod that never becomes Ready. trivy config still reports 0 to act on; the KSV-0117 statement is updated to the measured reasoning. |
||
|
|
e016650f91
|
rss-bridge: qualify the image registry, except the port-80 finding
Two findings from the Trivy config scan that landed on main in #129. AVD-KSV-0125 is fixed rather than excepted: writing the image as docker.io/rssbridge/rss-bridge puts a real registry in the registry position instead of "rssbridge", which is what ci/trivy/data/ksv0125.yaml asks for. Verified in k3d that the qualified reference resolves to the same digest (sha256:0eca99b2...) and still runs. AVD-KSV-0117 (containerPort below 1024) becomes a scoped, documented exception. nginx listens on 80 inside the image, and the entrypoint's only way to change that is a sed against /etc/nginx/sites-enabled/default which a read-only root filesystem rejects - so the alternative to port 80 is giving up readOnlyRootFilesystem. The premise of the check does not hold here anyway: the container binds 80 as uid 33 with all capabilities dropped and no NET_BIND_SERVICE. trivy config now reports 0 to act on for this chart. |
||
|
|
3fa67d55ef
|
rss-bridge: new chart
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 |