installer v1.23.0 — publishing becomes an act, not a side-effect (R-110, R-183)
gates / gates (push) Successful in 8s

Two channels moved off main in the same change, because either one left behind
makes the other cosmetic.

Channel 1 — the served script. webpage.yaml git-synced /scripts/ from
--branch=main every 30s and nginx served that tree, so pushing this file WAS
publishing it: within half a minute it was what every new machine downloaded and
ran as root, with no staging and no rollback but another push. The sync is now
SPLIT: the website keeps tracking main at the same cadence (a copy edit must
never need a release) and /scripts/ tracks the tag installer-v<SCRIPT_VERSION>.

PROVEN before the manifest was touched: git-sync v4.4.0 follows a tag AND
notices a MOVED one — measured on a throwaway sync against this repo,
"update required ... local:<old> remote:<new>" -> "updated successfully",
within one period. The moved-tag half is what the publish model rests on.

Channel 2 — the sixteen files fetched at run time. fetch_raw pulled from
$AGENT_REPO/raw/branch/main; it now pulls raw/tag/v$ART_AGENT_VER. That is a
correctness fix, not only a channel one (R-183): a fresh install fetched the
vouched agent BINARY while taking its unit file, sudoers and guarded wrappers
from whatever main held. Two refs, one install, nothing compared them. Their
correct ref was never SCRIPT_VERSION — they do not live in this repo.

No fallback to a branch: a vouched version whose tag is missing fails loudly
rather than quietly serving main.

Channel 3 — the URL — needed no change, recorded rather than left silent:
https://felhom.eu/scripts/felhom-host-install.sh never carried a ref, so both
producers follow the tag with no edit. No hub change, no hub version bump.

Gate 6 in hostinstall_gates.py pins all three structurally with no network, so
it stays in --fast and runs in CI. It deliberately does NOT assert "a tag exists
for the current SCRIPT_VERSION": that would go red on the very push that bumps
the version, before publishing — and publishing being separate is the ruling.
This commit is contained in:
2026-08-03 12:08:37 +02:00
parent 8360f940bf
commit bee6848458
4 changed files with 209 additions and 6 deletions
+83 -3
View File
@@ -71,8 +71,12 @@ data:
# Host-install script. It lives at the repo's /scripts (outside the website doc-root),
# synced into .../current/scripts by git-sync (see the sparse-checkout ConfigMap). Served
# as text/plain so operators can inspect it in a browser before download-then-run.
# R-110: served from the INSTALLER TAG's tree, not the website's. The URL is unchanged
# (https://felhom.eu/scripts/felhom-host-install.sh) — it never carried a ref, so every
# producer of it (the bootstrap script, the hub's day-0 command) follows the tag with no
# edit. What changed is which tree this root points at.
location /scripts/ {
root /usr/share/nginx/html/current;
root /usr/share/nginx/scripts/current;
default_type text/plain;
}
@@ -213,8 +217,12 @@ metadata:
name: git-sync-sparse-checkout
namespace: felhom-system
data:
# R-110: TWO sparse-checkouts, because there are now two syncs with two different refs.
# The website tracks `main` (a copy edit must never need a release); /scripts/ tracks the
# installer TAG (pushing the installer must never publish it).
sparse-checkout: |
/website/
sparse-checkout-scripts: |
/scripts/
---
# ===================
@@ -246,6 +254,9 @@ spec:
- name: git-data
mountPath: /usr/share/nginx/html
readOnly: true
- name: git-data-scripts
mountPath: /usr/share/nginx/scripts
readOnly: true
- name: nginx-config
mountPath: /etc/nginx/conf.d/default.conf
subPath: default.conf
@@ -269,11 +280,14 @@ spec:
initialDelaySeconds: 3
periodSeconds: 10
# ── The WEBSITE sync — tracks `main`, unchanged cadence ──────────────────────────────
# Deliberately still a branch: the site is content, and a typo fix must reach felhom.eu in
# thirty seconds without cutting a release. Only /scripts/ moved to a tag (R-110).
- name: git-sync
image: registry.k8s.io/git-sync/git-sync:v4.4.0
args:
- --repo=https://gitea.dooplex.hu/admin/felhom.eu.git
- --branch=main
- --ref=main
- --root=/git
- --link=current
- --period=30s
@@ -294,13 +308,52 @@ spec:
securityContext:
runAsUser: 65534 # nobody
# ── The INSTALLER sync — tracks a TAG (R-110, operator ruling 2026-08-03) ─────────────
# felhom-host-install.sh runs as root on a virgin machine. Before this it was served
# straight from `main`, so pushing it WAS publishing it: within thirty seconds it was what
# every new machine downloaded and ran, with no staging and no rollback but another push.
#
# Publishing is now moving this tag; rolling back is moving it back. PROVEN, not assumed:
# git-sync v4.4.0 follows a tag AND notices a moved one — measured 2026-08-03 on a
# throwaway sync against this very repo (`update required … local:<old> remote:<new>` →
# `updated successfully`, one period, ~20 s).
#
# Bump this ref when the installer's published version changes. `hostinstall_gates.py`
# gate 6 fails if this sync stops naming an `installer-v…` tag.
- name: git-sync-scripts
image: registry.k8s.io/git-sync/git-sync:v4.4.0
args:
- --repo=https://gitea.dooplex.hu/admin/felhom.eu.git
- --ref=installer-v1.23.0
- --root=/git-scripts
- --link=current
- --period=30s
- --sparse-checkout-file=/etc/git-sync-scripts/sparse-checkout
volumeMounts:
- name: git-data-scripts
mountPath: /git-scripts
- name: sparse-checkout-scripts
mountPath: /etc/git-sync-scripts
resources:
requests:
memory: "32Mi"
cpu: "10m"
limits:
memory: "128Mi"
cpu: "100m"
securityContext:
runAsUser: 65534 # nobody
# Init container: wait for first sync before nginx starts
initContainers:
# BOTH trees are seeded before nginx accepts traffic. The second one is why /scripts/ has
# no 404 window across this change: a fresh pod does not become ready until the installer
# tag has been checked out, exactly as the website already worked.
- name: git-sync-init
image: registry.k8s.io/git-sync/git-sync:v4.4.0
args:
- --repo=https://gitea.dooplex.hu/admin/felhom.eu.git
- --branch=main
- --ref=main
- --root=/git
- --link=current
- --one-time
@@ -312,16 +365,43 @@ spec:
mountPath: /etc/git-sync
securityContext:
runAsUser: 65534
- name: git-sync-scripts-init
image: registry.k8s.io/git-sync/git-sync:v4.4.0
args:
- --repo=https://gitea.dooplex.hu/admin/felhom.eu.git
- --ref=installer-v1.23.0
- --root=/git-scripts
- --link=current
- --one-time
- --sparse-checkout-file=/etc/git-sync-scripts/sparse-checkout
volumeMounts:
- name: git-data-scripts
mountPath: /git-scripts
- name: sparse-checkout-scripts
mountPath: /etc/git-sync-scripts
securityContext:
runAsUser: 65534
volumes:
- name: git-data
emptyDir: {}
- name: git-data-scripts
emptyDir: {}
- name: nginx-config
configMap:
name: nginx-config
- name: sparse-checkout
configMap:
name: git-sync-sparse-checkout
items:
- key: sparse-checkout
path: sparse-checkout
- name: sparse-checkout-scripts
configMap:
name: git-sync-sparse-checkout
items:
- key: sparse-checkout-scripts
path: sparse-checkout
---
apiVersion: v1
kind: Service