Merge pull request 'docs: konairius/homelab on main in runbooks and READMEs' (#1380) from claude/docs-konairius-main into main

Reviewed-on: #1380
This commit was merged in pull request #1380.
This commit is contained in:
2026-10-19 09:25:51 +00:00
5 changed files with 21 additions and 21 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
# homelab # homelab
GitOps source for the Renner homelab cluster. Flux applies `master` to GitOps source for the Renner homelab cluster. Flux applies `main` to
production, so every merge is a production change. Changes go in by pull production, so every merge is a production change. Changes go in by pull
request only; see [CONTRIBUTING.md](CONTRIBUTING.md) for YAML conventions. request only; see [CONTRIBUTING.md](CONTRIBUTING.md) for YAML conventions.
@@ -112,8 +112,8 @@
- [ ] **Step 1:** `flux suspend image update homelab`. - [ ] **Step 1:** `flux suspend image update homelab`.
- [ ] **Step 2 (owner):** merge the Task 5 PR into `master`. Flux now points at `main`, which does not exist yet; the cluster keeps its last applied state. - [ ] **Step 2 (owner):** merge the Task 5 PR into `master`. Flux now points at `main`, which does not exist yet; the cluster keeps its last applied state.
- [ ] **Step 3 (owner, immediately):** `tea api --login renner.uno -X PATCH /repos/konairius/homelab/branches/master -f name=main`. Expect: default branch `main`, protection rule now named `main` (`GET /repos/konairius/homelab/branches/main` → `protected: true, required_approvals: 1`), open PRs based on `main`. - [ ] **Step 3 (owner, immediately):** `tea api --login renner.uno -X PATCH /repos/konairius/homelab/branches/master -f name=main`. Expect: default branch `main`, protection rule now named `main` (`GET /repos/konairius/homelab/branches/main` → `protected: true, required_approvals: 1`), open PRs based on `main`.
- [ ] **Step 4:** `flux reconcile source git flux-system` → Ready on `main@<merge commit>`; `flux get kustomizations` all Ready. - [ ] **Step 4:** the live GitRepository still has `ref.branch: master` and cannot fetch the commit that changes it (`couldn't find remote ref "refs/heads/master"`). `flux suspend kustomization flux-system`, `kubectl -n flux-system patch gitrepository flux-system --type merge -p '{"spec":{"ref":{"branch":"main"}}}'`, `flux resume kustomization flux-system` → Ready on `main`; `flux get kustomizations` all Ready.
- [ ] **Step 5:** Crons: for each of `alert-monitor`(4), `ci-claude-refresh`(7), `daily-security-scan`(2), `issue-fix`(5), `update-audit`(3), `weekly-update`(1): `woodpecker repo cron update --repository konairius/homelab --id <id> --branch main`. Delete `wiki-maintenance`(8): no pipeline filters on it (`git grep wiki-maintenance -- .woodpecker` is empty), it starts nothing. `cron ls` shows six crons, all on `main`. - [ ] **Step 5:** Crons: for each of `alert-monitor`(4), `ci-claude-refresh`(7), `daily-security-scan`(2), `issue-fix`(5), `update-audit`(3), `weekly-update`(1), `uptime-kuma-token-renew`(10): `PATCH $WOODPECKER_SERVER/api/repos/1/cron/<id>` with `{"branch":"main"}` (woodpecker-cli 3.18.0 `repo cron update` returns 404 against server 3.19.0). Delete `wiki-maintenance`(8): no pipeline filters on it (`git grep wiki-maintenance -- .woodpecker` is empty), it starts nothing. `cron ls` shows seven crons, all on `main`.
- [ ] **Step 6:** `woodpecker repo repair konairius/homelab`; `woodpecker repo show` shows branch `main`. - [ ] **Step 6:** `woodpecker repo repair konairius/homelab`; `woodpecker repo show` shows branch `main`.
- [ ] **Step 7:** `flux resume image update homelab`; next IUA commit lands on `main`. - [ ] **Step 7:** `flux resume image update homelab`; next IUA commit lands on `main`.
- [ ] **Step 8:** Verify: a small PR into `main` gets reviewed and its merge triggers the push pipelines; the deploy pipelines' `when: branch: main` fire. - [ ] **Step 8:** Verify: a small PR into `main` gets reviewed and its merge triggers the push pipelines; the deploy pipelines' `when: branch: main` fire.
+12 -12
View File
@@ -23,7 +23,7 @@ bare-metal conversions were driven. Find the leases on the UDM.
## The circular-bootstrap problem this runbook exists to break ## The circular-bootstrap problem this runbook exists to break
In steady state Flux's `GitRepository flux-system` pulls manifests from the In steady state Flux's `GitRepository flux-system` pulls manifests from the
**in-cluster** Gitea (`https://gitea.renner.uno/gitea_admin/homelab.git`, **in-cluster** Gitea (`https://gitea.renner.uno/konairius/homelab.git`,
`kubernetes/clusters/homelab/flux-system/gotk-sync.yaml`). But that Gitea is `kubernetes/clusters/homelab/flux-system/gotk-sync.yaml`). But that Gitea is
itself Flux-managed: itself Flux-managed:
@@ -37,9 +37,9 @@ entry point.
**The exit:** bootstrap Flux from the external **GitHub break-glass mirror** **The exit:** bootstrap Flux from the external **GitHub break-glass mirror**
`github.com/konairius/Homelab` instead of Gitea. That mirror already exists and `github.com/konairius/Homelab` instead of Gitea. That mirror already exists and
stays current on its own: Gitea has a **native push-mirror** configured on the stays current on its own: Gitea has a **native push-mirror** configured on the
`gitea_admin/homelab` repo (`sync_on_commit=true`, 8h interval fallback), so it `konairius/homelab` repo (`sync_on_commit=true`, 8h interval fallback), so it
holds last-good `master` with no cluster involvement — it is server-side inside holds last-good `main` with no cluster involvement — it is server-side inside
Gitea, so it keeps tracking `master` independent of Woodpecker/agents. Nothing Gitea, so it keeps tracking `main` independent of Woodpecker/agents. Nothing
to set up; just confirm it before relying on it (Prerequisites). Once the to set up; just confirm it before relying on it (Prerequisites). Once the
cluster (and its in-cluster Gitea) is healthy again, switch the Flux source back cluster (and its in-cluster Gitea) is healthy again, switch the Flux source back
to Gitea (Step 6). to Gitea (Step 6).
@@ -54,9 +54,9 @@ These must exist outside the cluster or the rebuild cannot complete:
- [ ] **This repo**, checked out locally. - [ ] **This repo**, checked out locally.
- [ ] **GitHub mirror is current** — `github.com/konairius/Homelab` at the - [ ] **GitHub mirror is current** — `github.com/konairius/Homelab` at the
`master` you intend to restore. Gitea's native push-mirror keeps it there `main` you intend to restore. Gitea's native push-mirror keeps it there
on every push while Gitea is up; confirm the latest commit matches your on every push while Gitea is up; confirm the latest commit matches your
intended recovery point (`git ls-remote https://github.com/konairius/Homelab.git master`, intended recovery point (`git ls-remote https://github.com/konairius/Homelab.git main`,
or the repo's Settings → Mirror Settings last-sync time in Gitea). or the repo's Settings → Mirror Settings last-sync time in Gitea).
- [ ] **GitHub PAT** for `flux bootstrap github`, exported as `GITHUB_TOKEN`. - [ ] **GitHub PAT** for `flux bootstrap github`, exported as `GITHUB_TOKEN`.
`flux bootstrap` commits its sync manifests into the repo, so this needs `flux bootstrap` commits its sync manifests into the repo, so this needs
@@ -279,7 +279,7 @@ FLUX_SOURCE=github kubernetes/bootstrap.sh flux
``` ```
This runs `flux bootstrap github --owner=konairius --repository=Homelab This runs `flux bootstrap github --owner=konairius --repository=Homelab
--branch=master --path=kubernetes/clusters/homelab --token-auth` (see --branch=main --path=kubernetes/clusters/homelab --token-auth` (see
`bootstrap.sh`). Flux then: `bootstrap.sh`). Flux then:
1. installs its controllers + the `sops-age` Secret, 1. installs its controllers + the `sops-age` Secret,
@@ -401,21 +401,21 @@ kubernetes/bootstrap.sh flux # FLUX_SOURCE defaults to gitea; re-runs
Confirm `kubectl -n flux-system get gitrepository flux-system` again shows the Confirm `kubectl -n flux-system get gitrepository flux-system` again shows the
`gitea.renner.uno` URL and reconciles. Gitea's push-mirror then resumes tracking `gitea.renner.uno` URL and reconciles. Gitea's push-mirror then resumes tracking
`master` on the next push automatically — nothing to re-enable. `main` on the next push automatically — nothing to re-enable.
## Mirror maintenance — none required ## Mirror maintenance — none required
Keeping the break-glass source current is **already handled by Gitea itself**, Keeping the break-glass source current is **already handled by Gitea itself**,
not by any cluster workload. A native push-mirror is configured on the not by any cluster workload. A native push-mirror is configured on the
`gitea_admin/homelab` repo (remote `https://github.com/konairius/Homelab.git`, `konairius/homelab` repo (remote `https://github.com/konairius/Homelab.git`,
`sync_on_commit=true`, 8h interval fallback), so Gitea pushes `master` to GitHub `sync_on_commit=true`, 8h interval fallback), so Gitea pushes `main` to GitHub
on every `git receive` for as long as Gitea is up — which is also the only time on every `git receive` for as long as Gitea is up — which is also the only time
`master` advances. It runs server-side inside Gitea, so it survives Woodpecker / `main` advances. It runs server-side inside Gitea, so it survives Woodpecker /
agent outages, and it predates and survived the in-cluster migration. agent outages, and it predates and survived the in-cluster migration.
There is no setup step and no credential to provision here. To inspect or audit There is no setup step and no credential to provision here. To inspect or audit
it: repo → **Settings → Repository → Mirror Settings** in Gitea, or it: repo → **Settings → Repository → Mirror Settings** in Gitea, or
`GET /api/v1/repos/gitea_admin/homelab/push_mirrors` (admin token) — check `GET /api/v1/repos/konairius/homelab/push_mirrors` (admin token) — check
`last_error` is empty and `last_update` is recent. `last_error` is empty and `last_update` is recent.
## Recovery-point & known gaps ## Recovery-point & known gaps
@@ -2,7 +2,7 @@
Use when an automatic Home Assistant update (a Use when an automatic Home Assistant update (a
`chore(image-automation): bump ghcr.io/home-assistant/home-assistant:<new>` `chore(image-automation): bump ghcr.io/home-assistant/home-assistant:<new>`
commit on `master`) breaks Home Assistant. The owner approves the rollback commit on `main`) breaks Home Assistant. The owner approves the rollback
and its timing. Atlas writes the PR; Argus merges it. and its timing. Atlas writes the PR; Argus merges it.
## Why a plain `git revert` is not enough ## Why a plain `git revert` is not enough
@@ -22,7 +22,7 @@ automation.
1. Find the bump commit: 1. Find the bump commit:
```sh ```sh
git log --oneline -5 origin/master -- kubernetes/apps/home-assistant/deployment.yaml git log --oneline -5 origin/main -- kubernetes/apps/home-assistant/deployment.yaml
``` ```
2. Check the release notes of the broken version for a **database schema** 2. Check the release notes of the broken version for a **database schema**
change. Home Assistant migrates the recorder schema (CNPG cluster change. Home Assistant migrates the recorder schema (CNPG cluster
@@ -35,7 +35,7 @@ automation.
## Roll back (one commit, one PR) ## Roll back (one commit, one PR)
```sh ```sh
git worktree add -b atlas/ha-rollback-<old> "$WT" origin/master && cd "$WT" git worktree add -b atlas/ha-rollback-<old> "$WT" origin/main && cd "$WT"
git revert --no-commit <bump-sha> git revert --no-commit <bump-sha>
# In kubernetes/apps/home-assistant/deployment.yaml, delete the trailing # In kubernetes/apps/home-assistant/deployment.yaml, delete the trailing
# # {"$imagepolicy": "flux-system:home-assistant"} # # {"$imagepolicy": "flux-system:home-assistant"}
@@ -9,7 +9,7 @@ existing `flux-system` GitRepository whose Secret was created by
- `update-automation.yaml` — single `ImageUpdateAutomation` CR. Walks - `update-automation.yaml` — single `ImageUpdateAutomation` CR. Walks
manifests under `./kubernetes`, applies `Setters` strategy from manifests under `./kubernetes`, applies `Setters` strategy from
`# {"$imagepolicy": "..."}` markers, commits direct to `master`. `# {"$imagepolicy": "..."}` markers, commits direct to `main`.
Push uses the bootstrap token's identity; commit author is set to Push uses the bootstrap token's identity; commit author is set to
`Flux Image Automation <security-bot@renner.uno>` for visibility. `Flux Image Automation <security-bot@renner.uno>` for visibility.
- `paperless-ngx.yaml`, etc. — one `ImageRepository` + `ImagePolicy` - `paperless-ngx.yaml`, etc. — one `ImageRepository` + `ImagePolicy`
@@ -119,8 +119,8 @@ unaffected.
## Important ## Important
- Strategy is **direct push to master**, not a PR branch. Bad upstream - Strategy is **direct push to main**, not a PR branch. Bad upstream
releases land in master immediately. Mitigation: ImagePolicy ranges releases land in main immediately. Mitigation: ImagePolicy ranges
must be tight (`semver: range: "2.x"` not `"*"`) so a major bump must be tight (`semver: range: "2.x"` not `"*"`) so a major bump
requires manual policy widening. requires manual policy widening.
- **`extract` must produce a total order over the tags `pattern` - **`extract` must produce a total order over the tags `pattern`