Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 51 additions & 11 deletions BACKLOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6016,25 +6016,65 @@ them.
Scope, checked 2026-08-27: **the Windows copy has no `actions-runner/` and no nested
`HomeLab/`**, so sweeps run there are clean. This bites sweeps run on the H4.

- [ ] **`ansible/playbooks/sandbox-vm-update.yml` references `bootstrap-lldap.yml`** in a
comment (1 hit, confirmed still present 2026-08-27). That playbook was deleted on
08-03. Cosmetic, but it is the kind of stale pointer that sends someone looking for a
file that has not existed for weeks.
- [x] **Already fixed — verified 2026-10-12.** The comment at
`sandbox-vm-update.yml:400` no longer points at a live file; it explains the deletion:

- [ ] **`Makefile:2` still lists `ldap` in `.PHONY`** though the target was removed on
08-09 and the file carries a comment explaining the removal. Harmless; finish the job.
# lldap_admin_pass comes from Ansible Vault. (bootstrap-lldap.yml, which
# previously shared this var, was deleted 2026-08-02 with the ldap-1 VM.)

So it is a historical note rather than a stale pointer, and nobody would go looking.
Somebody fixed it and never ticked this. One small discrepancy left standing: this item
says the playbook was deleted **08-03**, the comment says **08-02**. Not worth chasing,
recorded so the next reader does not treat the mismatch as a finding.

- [x] **Done 2026-10-12.** `ldap` removed from `.PHONY`; `make -n help` still parses.
`.PHONY` names a non-existent target without complaining, which is precisely why it
survived three months after the `ldap:` target went with the ldap-1 VM.

- [x] **`FETCH_HEAD` is tracked in git** — a git internal committed by accident.
Removed 2026-10-03.
- [x] **Duplicated, drifted CI config under `ansible/`** — `ansible/.gitlab-ci.yml`,
`ansible/.github/workflows/*`, `ansible/.claude/settings.json`. Only the root copies
are read; these are dead weight diverging silently. Moved to
`archive/ansible-stale-ci/` 2026-10-03.
- [ ] **Mixed ArgoCD `repoURL` schemes** — 12 files use `git@github.com:`, but
`gitops/apps/gitlab-runner.yaml:18,22` uses `https://`. Argo treats these as two
repos needing two credentials.
- [ ] **`.gitignore` path bug in `ansible/`** (C7) — and note this working copy lives in
`Downloads`, so `LAB-URLS.md` and similar travel with any zip or sync of the folder.
- [x] **Done 2026-10-12 — and the count had grown since this was written.** Thirteen
sources used `git@github.com:`, not twelve, and *two* lines in
`gitops/apps/gitlab-runner.yaml` used `https://`, not one. Both normalised to `git@`;
all **fifteen** references to this repo are now one spelling.

Argo keys repository credentials by the URL string, so the two spellings were two
repositories to it — and the `https` one had no credential, working only because the
repo is public. Normalised *toward* `git@` because that deploy key demonstrably works
for the other thirteen. The reverse (https everywhere, no key needed now the repo is
public) is defensible but is a design choice, not a cleanup, so it was not made here.
- [x] **Fixed 2026-10-12, and it was worse than "path bug" suggests.** `ansible/.gitignore`
carried three rules copied from the root file, prefix and all:

ansible/.vault_pass <- inside ansible/, resolves to ansible/ansible/…
ansible/files/pull-secret.json
ansible/files/*.secret

**Patterns in a `.gitignore` are relative to that file**, so all three matched nothing.
Corrected to `.vault_pass`, `files/pull-secret.json`, `files/*.secret`, and verified —
`git check-ignore -v` now names `ansible/.gitignore` as the matching rule where it
previously named the root.

**No secret was ever exposed**: the root `.gitignore` has the same three lines, in the
one place that prefix is correct, and it was doing the work the whole time. The defect
is subtler than an exposure — it was a second layer that *looked* like protection and
provided none, which is worse than no second layer, because a reader checking
`ansible/.gitignore` would stop looking.

**A note on how this was verified, because the first attempt was careless.** Testing
the patterns by `touch`-ing `ansible/.vault_pass` and friends put empty files named
after real secrets into the authoritative checkout — in a repo whose first rule is
never to commit those names — and an empty `.vault_pass` there is its own hazard, since
a run using `--vault-password-file` would get an empty password and fail as though the
vault were corrupt. `git check-ignore -v --no-index <path>` evaluates paths that **do
not exist** and was available from the start. Test ignore rules that way.

Still true and unaddressed: this working copy lives in `Downloads`, so `LAB-URLS.md`
and similar travel with any zip or sync of the folder.
- [x] **Archive `TODO-2026-07-14.md`** (25/26 done) and collapse `README.md`'s TODO to a
pointer at this file. Done 2026-10-03: all three dated TODO files moved to `archive/`
unedited, and the README section is now a pointer.
Expand Down
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Convenience targets. All Ansible runs target the host(s) in inventory/hosts.yml.
.PHONY: help check storage microshift backup argocd all dns ai-nodes vault ldap mqtt k3s-vms \
#
# `ldap` removed from .PHONY 2026-10-12 (BACKLOG §7.1): the target went when the
# ldap-1 VM was decommissioned on 2026-07-04 and lldap moved into k3s, but the
# .PHONY entry stayed. Harmless — .PHONY names a non-existent target without
# complaint — which is exactly why it survived three months.
.PHONY: help check storage microshift backup argocd all dns ai-nodes vault mqtt k3s-vms \
k3s-registry update-containers update-vms bake-image validate-rollout ansible-deps bootstrap \
push-m5stack

Expand Down
20 changes: 17 additions & 3 deletions ansible/.gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
# Secrets -- never commit
ansible/.vault_pass
ansible/files/pull-secret.json
ansible/files/*.secret
#
# PATHS ARE RELATIVE TO THIS FILE, i.e. to ansible/. Until 2026-10-12 the three
# lines below read `ansible/.vault_pass`, `ansible/files/pull-secret.json` and
# `ansible/files/*.secret` — copied from the root .gitignore, where that prefix is
# correct. Inside ansible/ they resolve to ansible/ansible/… and matched nothing.
#
# The secrets were never actually exposed: the ROOT .gitignore carries the same
# three lines and is in the right place for them, and `git check-ignore -v` names
# that file as the one doing the work. So this file was a second layer that looked
# like protection and provided none — which is worse than no second layer, because
# anyone reading it would stop looking.
#
# BACKLOG §7.1 (C7). Verify with:
# git check-ignore -v ansible/.vault_pass
.vault_pass
files/pull-secret.json
files/*.secret
**/*.key
**/*.pem
kubeconfig
Expand Down
17 changes: 15 additions & 2 deletions gitops/apps/gitlab-runner.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,24 @@ spec:
valueFiles:
- $values/gitops/workloads/gitlab-runner/values.yaml
# Source 2: values file from this repo (ref-only — used by source 1 valueFiles)
- repoURL: https://github.com/swares/HomeLab.git
#
# SCHEME NORMALISED 2026-10-12 (BACKLOG §7.1). These two were the only
# `https://github.com/swares/HomeLab.git` in the tree; thirteen other sources use
# `git@github.com:swares/HomeLab.git`. Argo CD keys its repository credentials by
# the URL string, so the two spellings are two repositories to it — one of which
# had no credential and worked only because the repo is public. Matching the
# thirteen means one credential, one cache entry, and `argocd repo list` showing
# one entry instead of two for the same thing.
#
# Deliberately normalised TOWARD git@ rather than away from it: that deploy key
# demonstrably works for thirteen Applications. Going the other way — https
# everywhere, no key needed now the repo is public — is a defensible design
# choice, but it is a choice, not a cleanup, so it is not made here.
- repoURL: git@github.com:swares/HomeLab.git
targetRevision: main
ref: values
# Source 3: kustomize manifests (ExternalSecret for runner token)
- repoURL: https://github.com/swares/HomeLab.git
- repoURL: git@github.com:swares/HomeLab.git
targetRevision: main
path: gitops/workloads/gitlab-runner
destination:
Expand Down
Loading