ee62607e2e16879daccb077e1c44c09b147ea89d
7
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ee62607e2e
|
sure: fix the readiness probe, the ephemeral-storage budget and HOME
Validate Helm Charts / Detect changed charts (pull_request) Successful in 3s
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 4s
Validate Helm Charts / Trivy config ${{ fromJSON(needs.detect-changed-charts.outputs.scan-charts) }} (pull_request) Successful in 10s
Validate Helm Charts / Install-test ${{ fromJSON(needs.detect-changed-charts.outputs.install-charts) }} (pull_request) Successful in 2m37s
Second install-test run, three findings, all measured: - Readiness on "/" failed with "http: server gave HTTP response to HTTPS client" on a pod that was answering correctly. The kubelet's HTTP prober follows redirects to the same host, and with RAILS_ASSUME_SSL=true the app builds its redirect as https://<pod-ip>:3000/registration/new, which Puma does not speak. The probe now runs curl without -L and accepts 2xx-3xx itself. The same log also proves what the probe is for: against an empty database the redirect target was /registration/new, the branch User.count decides, so the path really does reach Postgres. - The pod was evicted within two minutes of every start: "ephemeral local storage usage exceeds the total limit of containers 60Mi". emptyDirs and the stdout log both count there, and the image rebuilds its Bootsnap cache under /rails/tmp on every start because the emptyDir hides the one baked into the image. The request is now 256Mi (limit 768Mi) per app container - headroom, not a measurement. - /home/rails is read-only, so Bundler created a throwaway home under TMPDIR on every invocation, worker probe included. HOME now points at a directory the init container creates. The CI postgres fixture gets -d sure on its readiness probe, so the server stops logging a missing database that nothing asked for. |
||
|
|
e92286b420
|
sure: give Ruby a temporary directory it accepts
Validate Helm Charts / Detect changed charts (pull_request) Successful in 3s
Validate Helm Charts / Resource quantities (pull_request) Successful in 7s
Validate Helm Charts / Build ${{ fromJSON(needs.detect-changed-charts.outputs.charts) }} (pull_request) Successful in 4s
Validate Helm Charts / Trivy config ${{ fromJSON(needs.detect-changed-charts.outputs.scan-charts) }} (pull_request) Successful in 10s
Validate Helm Charts / Install-test ${{ fromJSON(needs.detect-changed-charts.outputs.install-charts) }} (pull_request) Failing after 16m0s
The first install-test run failed with both containers crash-looping during boot: system temporary path is world-writable: /tmp /tmp is world-writable: /tmp . is not writable: /rails ArgumentError: could not find a temporary directory raised from MiniMagick, which Active Storage loads while Rails boots. Ruby's Dir.tmpdir skips a candidate that is world-writable without a sticky bit, and a Kubernetes emptyDir is created mode 0777 with no sticky bit - so with a read-only root filesystem there was no candidate left. A tiny init container, the app's own image running as the same non-root uid and with no capability added, now creates one private subdirectory (mode 0700) inside each tmp emptyDir, and both containers run with TMPDIR pointing at it. Creating an entry in a 0777 directory and chmod'ing what one just created needs no privilege, so the hardening standard holds unchanged. |
||
|
|
0b36d91275
|
sure: new chart for the we-promise Sure app (1.0.0+up0.7.4)
Validate Helm Charts / Detect changed charts (pull_request) Successful in 3s
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 4s
Validate Helm Charts / Trivy config ${{ fromJSON(needs.detect-changed-charts.outputs.scan-charts) }} (pull_request) Successful in 10s
Validate Helm Charts / Install-test ${{ fromJSON(needs.detect-changed-charts.outputs.install-charts) }} (pull_request) Failing after 15m54s
One StatefulSet with two containers - the Puma web process and a Sidekiq worker - sharing one ReadWriteOnce PVC at /rails/storage. That shared volume is the reason they live in one pod: splitting them would need an RWX volume. Only the web container migrates, because the image entrypoint runs db:prepare solely for the './bin/rails server' command; the worker is started through args: so the entrypoint (and its jemalloc preload) stays in place and the two can never race. Probes are chosen for what they prove: liveness and startup use Rails' /up, which is a boot check and touches no database, while readiness uses '/', which runs User.count through authenticate_user! in self-hosted mode and therefore fails while Postgres is unreachable. The worker speaks no HTTP, so all three of its probes ask sidekiqmon whether this pod still holds a Sidekiq heartbeat in Redis. Three OnePasswordItem CRs (app, database, redis), ingress.domain kept required outside the Ingress because APP_DOMAIN and the WebAuthn relying party read it, strict values.schema.json, CI fixtures with throwaway Postgres 16 and Redis, and a Renovate manager on semver so the -alpha/-rc/-hotfix channel and the moving tags are never selected. |
||
|
|
02b3c3ce75
|
renovate: align the config with cluster-config
Validate Helm Charts / Detect changed charts (pull_request) Successful in 3s
Validate Helm Charts / Build ${{ fromJSON(needs.detect-changed-charts.outputs.charts) }} (pull_request) Skipped
Validate Helm Charts / Trivy config ${{ fromJSON(needs.detect-changed-charts.outputs.scan-charts) }} (pull_request) Skipped
Validate Helm Charts / Install-test ${{ fromJSON(needs.detect-changed-charts.outputs.install-charts) }} (pull_request) Skipped
Validate Helm Charts / Resource quantities (pull_request) Successful in 8s
The shared jlab-renovate-bot instance serves this repo and cluster-config,
and two repos behaving differently under one bot is a source of surprises
rather than of safety. This adopts cluster-config's configuration:
config:best-practices in extends, labels ["renovate"], no PR caps
(prHourlyLimit 0, prConcurrentLimit 100), separateMinorPatch, an explicit
dependencyDashboard, and global automerge with platformAutomerge.
Two of those choices were previously wrong here and are now right, because
the branch protection on main has caught up: a review requirement and
validate-charts as a required check are both active. platformAutomerge
therefore arms the PR on the forge and Gitea merges it when the check
passes AND the review exists - the review is the gate, which is what makes
automerging majors something other than unattended merging.
Comments that asserted the opposite are rewritten rather than left to rot:
the platformAutomerge: false comment ("not (yet) a required check on either
side"), the "Majors stay manual" rule, the README PR policy bullets and the
required-check paragraph, and the CLAUDE.md forge notes.
config:best-practices pulls in docker:pinDigests, which is switched off
again for custom.regex and helm-values: an appVersion: is a tag by
construction and has nowhere to put a digest. Kept deliberately:
minimumReleaseAge of three days on the routine updates (every merge here
publishes a chart), the ignorePaths and ci/** opt-outs, every per-chart
manager, the nginx and qbittorrent constraints, and postUpgradeTasks.
Fixes #34
|
||
|
|
5b13569948
|
docs: the Coder workspace is the normal case, so tea runs without op
Validate Helm Charts / Detect changed charts (pull_request) Successful in 3s
Validate Helm Charts / Build ${{ fromJSON(needs.detect-changed-charts.outputs.charts) }} (pull_request) Skipped
Validate Helm Charts / Trivy config ${{ fromJSON(needs.detect-changed-charts.outputs.scan-charts) }} (pull_request) Skipped
Validate Helm Charts / Install-test ${{ fromJSON(needs.detect-changed-charts.outputs.install-charts) }} (pull_request) Skipped
Validate Helm Charts / Resource quantities (pull_request) Successful in 7s
Work on this repo happens in a Coder workspace that has no 1Password CLI. The rule that tea may only be called as 'op plugin run -- tea' therefore described an environment that no longer exists here, and following it meant either waiting for a tool that is not coming or ending with a pushed branch and no PR. tea is now called directly. It carries the workspace's stored login, so what it opens is authored by the bot account - accepted, and named in the report when it happens. The older instruction is kept for machines that do have op. Signing needed the same correction: it runs through the workspace's own SSH signer, not op-ssh-sign, and the check is 'git log --format=%G?' printing G. |
||
|
|
feb70cf1e4
|
docs: order the wiki step before the merge, not after it
Validate Helm Charts / Detect changed charts (pull_request) Successful in 3s
Validate Helm Charts / Build ${{ fromJSON(needs.detect-changed-charts.outputs.charts) }} (pull_request) Skipped
Validate Helm Charts / Trivy config ${{ fromJSON(needs.detect-changed-charts.outputs.scan-charts) }} (pull_request) Skipped
Validate Helm Charts / Install-test ${{ fromJSON(needs.detect-changed-charts.outputs.install-charts) }} (pull_request) Skipped
Validate Helm Charts / Resource quantities (pull_request) Successful in 8s
|
||
|
|
03bb454eb7
|
docs: make the wiki the knowledge base and its upkeep a required step
The wiki now carries one page per chart (prerequisites, installation, the required 1Password fields, the complete values reference and the chart's traps) plus the workflow, the pipelines, versioning, Renovate, the style guide and the incidents behind each rule. README points at it and keeps its own role: the overview for someone reading the code, while anything an operator needs lives in the wiki. CLAUDE.md gains the wiki edit as step 7 of the mandatory workflow, with a table of what obliges an edit - and the one thing that does not, a plain app-version bump, since Renovate automerges those and never touches the wiki. Also corrects the patchmon row: the 2.x server serves frontend and /api/* from one process, so the chart renders one Deployment plus an optional guacd sidecar, not two Deployments. |