log: bridge dolt's remotesrv logger into slog
remotesrv takes a *logrus.Entry and nothing else, so passing nil left it
writing through logrus' standard logger: its own format, its own stream,
and no mask between a field named token and the journal. It is the half
of this process that serves clones and pushes — the likeliest place for
a credential to reach a log field, and the one that was logging around
everything the previous commit configured.
internal/logrusbridge hands it an entry whose only exit is a
logrus.Hook: output to io.Discard, a formatter that produces nothing,
and the logrus level left wide open so the slog handler does the
filtering from the one setting in config.ini. Fields cross as attributes
rather than a formatted blob, which is what lets a mask keyed on the
attribute path fire at all.
Verified against logrus v1.9.3 rather than assumed: Entry.log fires
hooks before it writes, before Logger.Exit and before the panic, so a
Fatal or Panic record reaches slog before the process ends. Both arms
are tested.
The package takes nothing from this service and belongs beside scribe in
auxilia; it is here because it was needed here first.
log: replace logrus with slog behind auxilia's scribe handler
Every logger field this service owned was a *logrus.Entry threaded
through a constructor, which is what logrus costs for want of a usable
default. They are slog.Default().With("component", ...) now, and the
threading is gone with them; the shared middleware's panic reports land
in the same handler, which is why the daemon sets the default before
anything that can fail.
The handler is scribe's tint handler: level from [dolt.sr.ht]log-level,
source positions, and masks keyed on the attribute path for the three
credentials this service handles — the unified-login cookie, the
Internal fernet token and the Authorization header the remotesapi reads
a PAT or a keypair JWT out of. Errors go through scribe.Err, so a culpa
error's hint reaches the operator on its own line.
logrus stays in go.mod: dolt's remotesrv.ServerArgs takes a
*logrus.Entry and nothing else. It is now confined to Config.DoltLogger,
which is the only place this service names it.
dolt-git-hook is deliberately untouched: what it writes to stderr is the
notice a pushing user reads through git, not a log.
test: build the fixture config and the keyset with ecoretest
The hand-built ini in web_test.go, the random fernet key in authn's
TestMain and the same seeding copied into the git-hook test are one call
to ecoretest now. The keys are fixed rather than generated on purpose:
they secure nothing inside a test process, and a constant keyset is what
lets two packages of this service initialise without the second rotating
what the first sealed with.
The synthetic instance runs in production mode, so the environment
banner is off in tests unless one asks for it.
web: mirror the git twin's description onto companion databases
The internal create endpoint accepts a description, but its only caller
— dolt-git-hook — never sends one: git.sr.ht's push context does not
carry it. Companion databases therefore all sat descriptionless on the
dashboard while their git twins had perfectly good descriptions.
Resolve the description server-side instead: a GitDescriber dependency
(internal GraphQL query to git.sr.ht in the owner's name, the same
network-key trust the hook uses to reach us, pointed the other way) is
consulted on every /internal/repos call. A fresh companion is created
with the twin's description; for an existing one the push doubles as the
sync point — a changed, non-empty git description overwrites the stored
one. An empty git description never clobbers one set in dolt's own
settings, and every failure mode (no twin, git.sr.ht down, no resolver
wired) degrades to no mirroring. The lookup is capped at 3s so the
hook's own 5s POST timeout is never exceeded.
Adds testify as a direct dependency for the new tests.
feat: auto-provision companion Dolt DBs from git.sr.ht pushes
Add a service-to-service path so pushing a git.sr.ht repo creates a matching
Dolt database at ~owner/name, ready before the user's first `dolt push`.
- web: POST /internal/repos, guarded by internal-IP + network-key `Internal`
auth (not the browser cookie/CSRF). Resolves/mirrors the owner via
auth.LookupUser, then CreateRepo + InitStore, rolling back the row if the
store init fails. Idempotent: an existing companion returns 200, a fresh one
201 — safe to call on every push.
- cmd/dolt-git-hook: the git.sr.ht post-update-script. Delegates every hook
stage to the stock /usr/bin/git.sr.ht-update-hook unchanged (argv[0], stdin,
env, exit code preserved; fail-closed if the delegate is missing), then on
post-update POSTs the companion create and prints a one-time clone notice.
Best-effort: never fails a push, degrades to a warning on any misconfig.
Tests cover the endpoint (provision/idempotent/rollback/bad-input) and the hook
(signed request round-trips through the guard's decryption, notice only on 201).
doltsrht: pass full os.Args to server.New so -b binds the web listener
getopt skips argv[0] as the program name, so os.Args[1:] made it swallow the
first real flag (-b) and silently fall back to defaultWebAddr (localhost),
leaving the web UI unreachable from Traefik. Match compare/upstream: pass os.Args.
rename module to sourcecraft.dev/bigbes/sr-ht-dolt; depend on sourcecraft sr-ht-core
cmd: doltsrht and doltsrht-migrate binaries, module tidy