ytdlp-web-player: new chart with an optional oauth2-proxy subchart (1.0.0+upv1.2.0)

Deploys matszwe02/ytdlp_web_player, a Flask app that fetches videos with
yt-dlp, transcodes them with ffmpeg and serves them as HLS. It ships no
authentication of any kind, so the chart carries a preconfigured oauth2-proxy
as an optional subchart, in the data path in front of the app.

This is the first chart in the repo with a dependency, so the rule "charts
have no dependencies" falls here. It is replaced in CLAUDE.md and README.md by
a bar: a dependency has to be optional and off by default, upstream's chart is
consumed as it comes (documented where it falls short of our conventions,
never patched), and the price is written down - above all that a subchart is
invisible to everything downstream watching Helm release versions, so a new
proxy release only reaches a cluster when this chart is republished.

CI learns the dependency in five places, not the three the plan expected:
helm lint, package, template and install all exit 1 while charts/ is unfilled,
so ci/helm-dependencies.sh runs before lint and package in validate-charts.yml,
before package in publish-helm-chart.yml, and inside run-install-test.sh,
run-trivy-config.sh and run-quantity-render-test.sh - the last of which renders
every chart on every PR and would have gone red first.

Notable chart decisions, each measured rather than assumed:

- The image has no USER and runs as root by default, but not by necessity: it
  runs under an arbitrary uid with readOnlyRootFilesystem and the full
  hardening baseline. Only the pinned uid is a deviation, and it is documented.
- Two emptyDirs, each justified separately. /data holds the video cache
  (DATA_PATH). /tmp is NOT mounted - measured across metadata extraction, HLS
  transcoding, sprite generation and audio extraction, the image never writes
  there. What it does write is $HOME/.cache, so /cache is mounted with HOME and
  XDG_CACHE_HOME pointed at it; without it yt-dlp re-downloads its JavaScript
  challenge-solver from github.com on every extraction.
- The proxy is wired through config.configFile, the only value the subchart
  passes through tpl - config.upstreams is emitted with toJson and would carry
  a literal {{ .Release.Name }} into the manifest.
- Rendering aborts when this chart's Ingress and the proxy's claim the same
  host: ingress-nginx rejects the second one and a Fleet bundle then sits in
  ErrApplied until forceSyncGeneration is bumped.

Fixes #214
This commit is contained in:
jklein committed 2026-08-30 17:34:49 +02:00
1 parent 3e1088410e
commit 6b0d8c9232
23 files changed
+1706 -8

No files matched your search

+47
View File
@@ -97,6 +97,27 @@
matchDepTypes: ["app-version"],
addLabels: ["app-version"],
},
{
description: [
"Helm subchart dependencies (the `dependencies:` block of a Chart.yaml). Handled by",
"the BUILT-IN helmv3 manager - no customManager needed, and none would help: the",
"repository URL and the version sit next to each other in one file, which is the",
"case the built-in manager exists for. It is enabled by config:recommended and this",
"config sets no enabledManagers, so nothing has to switch it on. Verified by dry-run",
"for #214: with ytdlp-web-player pinned one release back, the lookup returns",
"oauth2-proxy 10.6.2 -> 10.7.0 as a manager=helmv3 minor update.",
"",
"This rule adds only a label. It exists because the update matters more here than",
"its size suggests: a subchart is invisible to everything downstream that watches",
"Helm release versions, so this PR is the ONLY way a new proxy version - a security",
"fix included - ever reaches a cluster. Under the automerge rule above, patch and",
"minor updates do that on their own once the pipeline is green, and",
"ci/renovate-bump-chart.sh bumps the chart patch that publishes it (appVersion is",
"unchanged, so it takes the patch branch). A major arrives as a PR to merge by hand.",
],
matchManagers: ["helmv3"],
addLabels: ["subchart"],
},
{
description: [
"nginx numbers its release branches by minor: even is the stable branch, odd is",
@@ -396,6 +417,32 @@
datasourceTemplate: "docker",
depTypeTemplate: "app-version",
},
{
description: [
"ytdlp-web-player: the registry carries exactly two kinds of tag - four versioned",
"ones (v1.0.0, v1.0.1, v1.1.0, v1.2.0) and the two floating ones, 'latest' and",
"'stable'. Both floating tags MOVE: 'stable' was republished at the same minute as",
"v1.2.0 and 'latest' days later, so either of them as an appVersion would pin",
"nothing and change the running image without a single commit.",
"The anchored regex versioning below is what keeps them out - it requires the v",
"prefix and three numeric parts, which neither 'latest' nor 'stable' can satisfy.",
"docker versioning alone would probably have dropped them too, but 'probably' is",
"the wrong basis for the value that selects the image.",
],
customType: "regex",
managerFilePatterns: ["ytdlp-web-player/Chart.yaml"],
matchStrings: ["(?m)^appVersion:\\s*\"?(?<currentValue>[^\"\\s]+)\"?"],
depNameTemplate: "docker.io/matszwe02/ytdlp_web_player",
datasourceTemplate: "docker",
depTypeTemplate: "app-version",
// The "v" stays outside every capture group: it is part of the tag and
// carries no ordering, and the same rule the searxng block documents
// applies - a group is a claim about how the value is compared. The
// anchors are what exclude latest/stable. Precedent for keeping the v in
// appVersion at all: calibre-web-automated (+upv4.0.6) and matrix-synapse
// (+upv1.159.0) - it is part of the tag, so it is part of appVersion.
versioningTemplate: "regex:^v(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)$",
},
{
customType: "regex",
managerFilePatterns: ["zipline/Chart.yaml"],