Commit Graph
14 Commits
Author SHA1 Message Date
forust 11e92fdf4e fix(deploy): bound ssh hangs and retry the stage on transport loss
A connection that died silently used to hang until the job timeout, and
the stage was never re-run. One flaky TCP session cost a whole
45-minute apply, and the symptom - a job that stops mid-output with no
error - is what made the last few deploy failures expensive to read.

ServerAliveInterval/CountMax cap how long a dead peer goes unnoticed at
~60s, ConnectTimeout caps setup. Only exit 255 - ssh's own transport
failures - is retried, up to three attempts with a growing gap. A stage
that fails on its own merits exits with the remote's status, so a real
failure surfaces its own log immediately instead of being repeated three
times over 45 minutes. The stages are declarative applies, so re-running
one that had already committed is harmless.

The stage environment now goes through `env` as separate argv entries
rather than one interpolated string, so nothing in REPO, DEPLOY_SHA or
DEPLOY_SNAPSHOT_DIR is re-split by the remote shell.

Verified against a stubbed ssh: clean run attempts once, a single
transport failure recovers on attempt 2 and exits 0, three failures give
up preserving 255, and a stage failing with 1 or 7 attempts once and
passes the code through unchanged.

Also records why USERBOT_IMAGE stays on the prod tag: render_pinned
rewrites only plain `image:` lines, and this ref is what the panel
injects into the per-instance Deployments it creates, so those instances
track the tag rather than the panel's own resolved digest. The two
panel-created instances currently in the cluster are digest-pinned, so
the panel does accept one either way; the tag is the choice, not a
limitation.
2026-09-27 18:26:25 +02:00
forust ac0f845da6 fix(deploy): stop the panel from pointing at a tag the build dropped
ci / lint-compose (push) Successful in 3s
ci / lint-actionlint (push) Successful in 1s
ci / lint-shellcheck (push) Successful in 2s
ci / lint-prettier (push) Successful in 3s
ci / lint-ruff (push) Successful in 1s
ci / lint-yaml (push) Successful in 2s
ci / lint-dockerfiles (push) Successful in 1s
ci / scan-deps (push) Successful in 15s
ci / test-backend (push) Successful in 7s
ci / test-frontend (push) Successful in 11s
renovate-ci / validate-renovate (push) Successful in 12s
ci / validate (push) Successful in 3s
ci / build (push) Successful in 37s
USERBOT_IMAGE named userbot:latest, but the build stopped pushing latest when
images became :prod. render_pinned resolves every gcr.forust.xyz reference it
finds in a manifest, not just the ones it rewrites, so that env var made the
whole apply abort with "cannot resolve userbot:latest; applying nothing".

Naming it :prod also makes the build job rebuild userbot, which is what
restores forust/userbot:prod - the tag is listed in the registry but its
manifest 404s, so the image: field in userbots.yaml had nothing to resolve
either.

Found by resolving every digest apply-k8s will need before spending a run on
it: 6 of 8 resolved, and both failures were userbot.
2026-09-27 16:14:43 +02:00
forustandClaude Opus 4.8 0691536f28 fix(deploy): roll out our images by digest instead of a moving tag
`kubectl rollout undo` restores the previous ReplicaSet's pod template
verbatim. While that template names a tag, the rollback does not roll back
the image: the tag has already moved, so the reverted pod pulls the very
build that just failed and the cluster stays broken. The safety net added
in 1505b63 therefore could not recover from a bad image.

Pin the digest at apply time. A digest is not knowable when a manifest is
written, so render_pinned resolves it on the way into the cluster and the
digest is never committed. Git keeps a readable `:prod`, Renovate keeps
seeing exactly the manifests it saw before, and the previous revision of
each workload now holds the digest that was actually serving, so undo
restores those exact bytes.

imagePullPolicy is dropped from the manifests rather than set to
IfNotPresent: a reference that is not `:latest` already defaults to it, and
that is what the Kubernetes docs ask for alongside a digest.

An unresolvable image is fatal instead of a warning, because carrying on
would quietly apply a mutable tag again.

restart_stale_images keeps its comparison but is no longer how a rebuild
reaches the cluster -- the pinned template rolls out on its own now. What
is left is a drift check for hand-run `kubectl set image`, so it matches
the container by repository: a pod's status now reports `repo@sha256:...`
while the manifest still says `:prod`.

The build job stops pushing `:latest` altogether, which removes the tag
that a dev branch could otherwise move under a prod deploy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-09-27 10:09:06 +02:00
forust a9eabfba02 fix(userbot): include internal-certificate in kustomize base 2026-09-23 15:52:32 +02:00
forust bc1e69ebe0 feat(tls): internal CA wildcard for *.internal routes
ci / lint-prettier (push) Successful in 2s
ci / lint-ruff (push) Successful in 0s
ci / lint-yaml (push) Successful in 2s
ci / lint-dockerfiles (push) Successful in 1s
ci / validate (push) Successful in 1s
ci / build (push) Skipped
ci / deploy-userbot-panel (push) Skipped
Selfsigned root (10y) + internal-ca issuer; per-namespace
internal-wildcard-tls certs referenced by all -local routers.
Root public cert committed for client trust stores.
2026-09-23 14:45:05 +02:00
forust 71cddd6a91 feat(userbot): add Kubernetes control panel
Manage Telegram instances through Kubernetes with legacy adoption for forust and anna. Build and deploy the panel image alongside the runtime.
2026-09-06 20:39:12 +02:00
forust 9364392bc0 Merge commit '3eaef5dc90b716cc0fa391cbe2394be56d5f6041' as 'userbot'
Deploy to Server / deploy (push) Has been cancelled
2026-06-19 23:20:23 +02:00
forust 69ffd3682e refactor: userbot to subtree 2026-06-19 23:20:13 +02:00
forust 1930600c40 Revert "refactor: extract userbot to standalone repo, add as git submodule"
This reverts commit 3c383db9a7.
2026-06-19 23:11:27 +02:00
forust 3c383db9a7 refactor: extract userbot to standalone repo, add as git submodule
Deploy to Server / deploy (push) Has been cancelled
userbot now lives at ssh://git@gitssh.forust.xyz:2221/forust/userbot.git
and is included in homelab as a submodule at userbot/
2026-06-19 15:39:00 +02:00
forust 5f88ecf02b chore(k8s): make dockmon statefulset
+ adjusted userbot sys reqs
2026-06-10 19:40:45 +02:00
forust 1ea669220b chore(k8): adjusted system resources requests and limits based on manual monitoring 2026-06-10 19:37:16 +02:00
forust 7a3708f70c lint: yaml spaces and tabs 2026-06-09 12:59:36 +02:00
forust 0c5cf29f83 feat: add userbot k8s deployment method
Deploy to Server / deploy (push) Has been cancelled
- Kustomize: base + overlays/dev + overlays/prod
2026-06-07 19:41:28 +02:00