~bigbes/sr-ht-ecore · config

dfgkb9igtm0i5ks5guh9rlihkmv6b4no · 14 rows

keyvalue
auto_compact_enabledfalse
compact_batch_size50
compact_parallel_workers5
compact_tier1_days30
compact_tier1_dep_levels2
compact_tier2_commits100
compact_tier2_days90
compact_tier2_dep_levels5
compaction_enabledfalse
issue_prefixsr-ht-ecore
kv.memory.ecore-architecture`sourcecraft.dev/bigbes/sr-ht-ecore` holds everything the six custom services of the self-hosted SourceHut instance share that is *ours* rather than upstream's, so the `sr-ht-core` fork stays a clean mirror of core-go. Thirteen packages as of 2026-08-09: `chrome` (nav, brand, page partials, listing partials), `grants`, `bearer` (+ `StatusFor`/`Challenge`/`IsRefusal`), `pages` (page sets, buffered render, error page, `FormValues`), `assets` (hashed assets, `DirFS`), `csrf`, `middleware` (cache policy, panic recovery, 499), `login` (unified-login cookie decode), `internalauth` (both ends of `Authorization: Internal`), `instconf` (origin canonicalisation, `Require`), `logging` (slog policy without the handler), `chimw` (chi-shaped helpers), `ecoretest`. **This reverses the family convention still written in the services' Russian SPEC/DESIGN docs** ("копируем, не выносим в общий модуль; единственная общая зависимость — sr-ht-core"). The user confirmed the reversal is deliberate and those documents are not to be corrected. There are two shared modules now: `sr-ht-ecore` and `go.bigb.es/auxilia`. Boundaries settled by argument, not taste: - ecore does **not** depend on auxilia. `logging` ships the mask policy and a stdlib `ReplaceAttr`; the service picks the handler (scribe's tint on this instance). - `middleware` stays dependency-free (net/http only); anything chi-shaped goes in `chimw`. - A general logging adapter belongs in auxilia, not ecore — ecore is SourceHut-specific. That is why `logrusbridge` landed in auxilia. - `middleware.RecoverPanics` logs through `slog.Default()`, which is what gives ecore a stake in every service calling `slog.SetDefault` — hence `logging` existing at all. `chrome.BuildNav` is only half of the instance's service switcher: the Python services render the same strip from `core.sr.ht/srht/app/flask.py`, which orders the non-canonical half by config-file order rather than alphabetically, and whose `nav.html` excludes hub from the loop exactly as `navExcluded` does. Changing the ordering or the exclusions here makes the two halves disagree — see [[srht-instance-deploy]] for why the config file is written alphabetically. The alphabetical tiebreak is forced, not chosen: `ini.File` is a `map[string]Section`, so core-go's parser has already thrown the file order away by the time `BuildNav` sees it, and matching upstream exactly would mean re-scanning the config for `[section]` lines. Two more divergences from `nav.html`, neither of them ordering: `BuildNav` skips a section with no `origin` (upstream lists it, with a broken href), and it resolves every origin once at startup where upstream calls `get_origin` per render. Upstream is readable locally — the whole fleet is checked out under `~/data/home/sourcehut/` (`core.sr.ht`, `git.sr.ht`, …) — so answer "what does upstream actually do" from the source rather than from the comments in our copies. `chrome.Page` embeds as the field name `Page`, so a view struct wanting `Page` for its own payload must rename it. Listing columns (`Updated`, `Meta`) are optional on purpose: bench and spec needed them, dolt has no timestamp in its schema, cover's table of sparklines fits no shared partial.
kv.memory.srht-instance-deployThe stack lives in `~/data/home/phoebe-lab/srht` and deploys with **`labng push srht`** (`lab` is blocked by a hook). Its `post_push` in `deploy.yml` builds `srht-base`, runs `docker compose build` and `up -d` on phoebe — so a push *is* a deploy. Order that works, from a service commit to a running container: 1. push the service repo → builds.sr.ht packages it 2. **wait for `apk-mirror` to re-index** — until then `apk add pkg=<ver>` inside `docker compose build` dies with "unable to select packages" and `labng push` fails halfway. Poll it the way the build will see it, i.e. against the signed index and from phoebe (`repo.bigb.es` is LAN-only behind Authelia; from the mac even `APKINDEX.tar.gz` is a 302): ssh phoebe.lab.local "docker run --rm -v /data/containers/srht/keys:/keys:ro alpine:3.22 sh -c \ 'cp /keys/*.rsa.pub /etc/apk/keys/; echo https://repo.bigb.es/alpine/v3.22/bigbes >> /etc/apk/repositories; \ apk update >/dev/null 2>&1; apk list 2>/dev/null | grep <pkg>-<ver>'" 3. set the pin in `versions.env`, commit, `labng push srht` **Restart everything after editing `config.ini.tmpl`.** A config change with no restart shows up as a nav that still lists the old service. `docker compose restart meta todo builds git hub paste pages diff cov bench dolt spec tokens`. There is only **one** config file: `config-init` renders the template into the named volume `srht-config`, mounted `:ro` into every container. So two services showing *different* navs never means different files — it means different snapshot generations in memory. The Go services freeze theirs in `chrome.NewService` at process start; the Python ones compute `_network` at module import, and `scripts/entrypoint.sh` execs gunicorn **without `--preload`**, so that import runs in each worker after fork — a respawned worker can hold a newer config than its siblings, and than the Go services. Diagnose a nav listing a removed service with the file first and the process age second: docker compose exec <svc> grep -n 'man.sr.ht' /etc/sr.ht/config.ini docker compose ps --format '{{.Service}}\t{{.Status}}' Custom-service sections in `config.ini.tmpl` are written **alphabetically on purpose**: the Python sort is stable with one key, so it emits them in file order, while `chrome.BuildNav` sorts them by name — alphabetical file order is what makes the two navs agree. A new service goes in at its alphabetical place. `labng diff srht` **errors out on a file that does not exist on the remote yet** ("sync: download …: file does not exist") — that is the diff path only; `labng push` is fine and creates the file. `docker compose config` re-escapes a literal `$` on output, so `$${1}` in a traefik label prints back as `$${1}` — it is not proof that interpolation is wrong. **phoebe-lab is a shared repository: another session is usually working in it.** Twice in one session a parallel `git commit -a` swept my uncommitted edits into its own commit (`srht: disable man.sr.ht`), and later commits appeared on top of mine between a push and a status check. Stage only your own paths, and check `git log @{u}..` before saying anything about what is published — most of what is unpushed there is not yours.
kv.memory.srht-service-releaseReleasing one of the six custom services (`sr-ht-{tokens,bench,cover,compare,dolt,spec}`) is **pushing a `vX.Y.Z` tag to the srht mirror**. There is no other step that produces a versioned apk. The chain: tag on `git.srht.bigb.es` → builds.sr.ht runs `.build.yml` → `abuild` → rclone to the Garage bucket → `apk-mirror` on phoebe re-indexes **every 15 minutes** (so a fresh apk is fetchable by exact URL immediately but invisible to `apk add` until the index lands). Three preconditions, all verified working as of 2026-08-09: - `.build.yml` `submitter.allow-refs` must list `"refs/tags/v*"` — without it a pushed tag starts no build at all. - The `version` task derives the version from one `git describe`: tag → `0.9.1`, tag plus commits → `0.9.1_git6` (sorts *after* the release in Alpine's grammar), no tag → `0.0.<commit count>`. - The version reaches `abuild` by **exported `PKGVER`**, never by `sed` of the tracked `APKBUILD` — see [[go-vcs-stamp-dirty]]. Tags push to `srht`, not only to `origin` (sourcecraft): gitsync mirrors branches, not tags. `compare` and `dolt` have no local `srht` remote — use `git@git.srht.bigb.es:~bigbes/sr-ht-<name>` directly. **dolt's tag has a deploy consequence**: the `dolt.sr.ht-hook` subpackage is built from the same APKBUILD, so the first tag renames it from `dolt.sr.ht-hook-0.0.<n>` to `dolt.sr.ht-hook-<tag>`. The git.sr.ht container pins it by exact version through `SRHT_DOLT_VER` in `phoebe-lab/srht/versions.env`; bump both in one change or `apk add` fails with "unsatisfiable constraints". Deployed versions live in `phoebe-lab/srht/versions.env` (`SRHT_<NAME>_VER`). Publishing is upload-only, never delete: a bad apk can only be superseded, not withdrawn.
kv.memory.srht-service-renameDone twice on 2026-08-09: `compare.sr.ht` → `diff.sr.ht`, `cover.sr.ht` → `cov.sr.ht`. The repository, the Go module path, the binary and the URL routes were deliberately left alone both times — renaming them rewrites an import path and a repository URL for a word. **Everything the name actually lives in:** - service repo: `service.ConfigSection` (or `configSection` in `web/`), `APKBUILD` pkgname, `Makefile` `SERVICE=`, `config.example.ini`, `contrib/<name>.sr.ht.conf` + `contrib/<name>-srht.service` (rename the files), `.build.yml` (its own origin env var), `scss/main.scss`, docs - `phoebe-lab/srht`: `[<name>.sr.ht]` section + origin + connection-string in `config/config.ini.tmpl`, `Dockerfile.<name>` (+ `ARG SRHT_<NAME>_VER` and the `apk add` package), `scripts/entrypoint-<name>.sh`, compose service + hostname + traefik routers, `versions.env` var, `deploy.yml` file list, `scripts/init-db.sh` service list, `scripts/{check-versions,changelog}.sh`, `[git.sr.ht] extra-repo-tabs` - `sr-ht-ecore`: `ecoretest.customSections` **The two that break things silently:** 1. **Grant vocabulary.** `cover:upload` → `cov:upload` invalidates every issued token — grants are compared literally. The CI secret is shared (`~/.srht-token` carries both `cov:upload` and `bench:upload`), and it cannot be edited in place, see [[builds-srht-secrets]]. The build fails on the upload task only, everything else stays green. 2. **The mint form's checkbox list is a copy inside tokens.sr.ht** (`sourcehut-tokens/web/tokens.go`, `grantVocabulary`). The daemon validates no vocabulary, so it keeps offering the old grant after the service stops accepting it — the resulting token mints fine and admits nobody. Renaming a grant means a tokens.sr.ht release too. Its free-text field can mint the new grant meanwhile. **Postgres** (when the DB is renamed with the service): stop the container first, dump, then `ALTER DATABASE "old" RENAME TO "new"; ALTER ROLE old RENAME TO new; ALTER ROLE new WITH PASSWORD '<same>';` — the password reset is cheap insurance against md5-derived verifiers. **Old host keeps answering** through a second traefik router on the same service with `redirectregex` (`replacement: https://new.$${1}` — `$$` is compose's escape). Good for badges and links; useless for uploads, because `curl -X POST` in `.build.yml` has no `-L`. So the CI manifest must name the new origin in the same commit. Renaming a compose service leaves the **old container running as an orphan**, labels and all — `docker compose up -d` does not remove it, and its traefik labels then fight the new redirect router for the old host. `docker rm -f srht-<old>-1` after the deploy. Section order in `config.ini.tmpl` is alphabetical and load-bearing — see [[srht-instance-deploy]].