Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
6.8 KiB
name, description
| name | description |
|---|---|
| felhom-build-deploy | Build, deploy, publish, or verify ANY Felhom artifact — felhom-controller image (guest 9201 bootstrap deploy), felhom-agent binary (felhom-pve), felhom-hub (GitOps/ArgoCD), the felhom.eu website (git-sync), or the app catalog. Use whenever the task says build, deploy, ship, release, publish, bump version, restart the controller/agent/hub, or verify what version is live. Contains the exact verified commands and the gotchas that silently break deploys. |
Felhom build & deploy runbooks
All repos live in E:\git\ (Git Bash: /e/git/). Trunk-based: commit+push to main first, always.
Update the repo's CHANGELOG.md (+ REUSE.md if a shared helper changed) in the same commit.
Session invariants (set once, every session)
SSH=/c/Windows/System32/OpenSSH/ssh.exe # Git Bash's /usr/bin/ssh can't reach the Windows agent — fails silently
export MSYS_NO_PATHCONV=1 # before any ssh felhom-pve command with absolute paths (pct etc.)
| Host | Access | Role |
|---|---|---|
| Build server (k3s) | $SSH kisfenyo@192.168.0.180 |
build+push images/binaries (~/build/felhom-{controller,hub,agent}), sudo kubectl |
| Demo Proxmox host | $SSH felhom-pve (root@192.168.0.162) |
agent deploy, pct into guests |
| Demo guest 9201 | via pct exec 9201 -- bash -c '...' on felhom-pve |
the live controller |
| felhotest (legacy) | $SSH -p 33022 kisfenyo@router.abonet.hu |
OLD /opt/docker compose mechanism — not the 9201 flow |
Version bumps are ldflags-only (-X main.version / -X main.Version) — build scripts inject them; no source edit.
Controller (felhom-controller → guest 9201)
9201 is golden/bootstrap-managed — NO compose file. felhom-controller-bootstrap.service docker-runs
the tag written in /etc/felhom-controller-image (anonymous Gitea pull). Data volume + encryption key persist.
# 1. commit+push the repo
# 2. build+push image (build.sh does NOT git-pull — the explicit pull is load-bearing)
$SSH kisfenyo@192.168.0.180 "cd ~/build/felhom-controller && git -C ~/git/felhom-controller pull && ./build.sh <VER> --push"
# 3. deploy in the guest
$SSH felhom-pve "pct exec 9201 -- bash -c 'docker pull gitea.dooplex.hu/admin/felhom-controller:<VER> && echo gitea.dooplex.hu/admin/felhom-controller:<VER> > /etc/felhom-controller-image && systemctl restart felhom-controller-bootstrap.service'"
# 4. verify
$SSH felhom-pve "pct exec 9201 -- docker ps --filter name=felhom-controller --format '{{.Image}} {{.Status}}'"
Check current live version first: same docker ps command, or cat /etc/felhom-controller-image.
Agent (felhom-agent → felhom-pve)
Runs as the NON-ROOT felhom-agent user: /usr/local/bin/felhom-agent --config /etc/felhom-agent/agent.json
(systemd felhom-agent.service). Sudoers allowlist at /etc/sudoers.d/felhom-agent.
# build on 180 (pull first!)
$SSH kisfenyo@192.168.0.180 "cd ~/git/felhom-agent && git pull && go build -ldflags '-X main.version=<VER>' -o /tmp/felhom-agent-<VER> ./cmd/felhom-agent"
# fetch to local, then push to the PVE host (Windows scp needs cygpath -w for the LOCAL path)
scp kisfenyo@192.168.0.180:/tmp/felhom-agent-<VER> "$(cygpath -w /tmp/felhom-agent-<VER>)"
scp "$(cygpath -w /tmp/felhom-agent-<VER>)" felhom-pve:/tmp/
# install with backup + restart
$SSH felhom-pve "cp /usr/local/bin/felhom-agent /usr/local/bin/felhom-agent.bak-\$(/usr/local/bin/felhom-agent --version | awk '{print \$2}') && install -m0755 /tmp/felhom-agent-<VER> /usr/local/bin/felhom-agent && systemctl restart felhom-agent && sleep 3 && /usr/local/bin/felhom-agent --version && journalctl -u felhom-agent -n 20 --no-pager"
Ship the sudoers + guarded-mkfs wrapper WITH the binary whenever configs/ changed — several Go
guards exist only if the deployed sudoers/wrapper match the binary (globs must match stageTemp
patterns). Beware CRLF when scp-ing config files through Windows. After restart, check the journal
for a clean ReassertGuestBinds and no capability-probe degradations.
Publish to Gitea (so Day-0 self-install can fetch it): scripts/publish-agent.sh <ver> <binary> with
REGISTRY_* creds. The hub's Day-0 artifact manifest must then vouch the new version — that UI is
operator-password-gated (CC cannot); flag it as an operator follow-up.
Hub (felhom.eu/hub → k3s, GitOps via ArgoCD app felhom)
The manifest is the truth. A code push + image build deploys NOTHING until manifests/hub.yaml's
image: tag changes in git AND the app is synced (auto-sync is OFF). Never kubectl set image
(reverted on next sync), never :latest. The live image can lag the CHANGELOG — reconcile via the manifest.
# 1. commit+push code 2. build+push image
$SSH kisfenyo@192.168.0.180 "cd ~/build/felhom-hub && ./build.sh <VER> --push"
# 3. bump manifests/hub.yaml image tag → <VER>, commit, push
# 4. hard-refresh + sync (argocd CLI on 180 is not logged in — drive the Application CR)
$SSH kisfenyo@192.168.0.180 "sudo kubectl -n argocd annotate application felhom argocd.argoproj.io/refresh=hard --overwrite; sleep 8; sudo kubectl -n argocd get application felhom -o jsonpath='{.status.sync.status} {.status.sync.revision}{\"\n\"}'"
$SSH kisfenyo@192.168.0.180 "sudo kubectl -n argocd patch application felhom --type merge -p '{\"operation\":{\"initiatedBy\":{\"username\":\"cc\"},\"sync\":{\"syncStrategy\":{\"apply\":{}}}}}'"
# 5. verify: Synced/Healthy + rollout + image tag + startup log
$SSH kisfenyo@192.168.0.180 "sudo kubectl -n argocd get application felhom -o jsonpath='sync={.status.sync.status} health={.status.health.status}{\"\n\"}'; sudo kubectl -n felhom-system rollout status deploy/hub --timeout=90s; sudo kubectl -n felhom-system get deploy hub -o jsonpath='{.spec.template.spec.containers[0].image}'; echo; sudo kubectl -n felhom-system logs -l app=hub --tail 10"
Green gate before any hub commit: go build ./... && go vet ./... && go test ./... in hub/.
Website (felhom.eu/website)
Push to main = deployed (git-sync sidecar, live in ~1–2 min). Run python scripts/site_gates.py
first, after ANY website change (BOM, emoji, nav parity, cache-bust ?v=N — bump it when css/svg
change). New pages must be added to the script's PAGES list. Emergency edits: https://files.felhom.eu.
App catalog (app-catalog-felhom.eu)
Push to main = deploy: the controller's git-sync picks it up within 15 min, or trigger via the
dashboard "Sablonok frissítése" button / POST /api/sync (30s debounce). Only docker-compose.yml +
.felhom.yml sync; deployed app.yaml is never overwritten. Conventions: <repo>/REUSE.md.
Other k8s manifests (felhom.eu/manifests)
Same GitOps rule as the hub: edit in git, push, deliberate ArgoCD sync of app felhom. Never
kubectl apply directly. Secrets: out-of-band kubectl create secret + secretKeyRef — never inline
stringData (see felhom.eu/REUSE.md §3).