~bigbes/sr-ht-compare

ref: 19f0585714695aa711b0a70e601ded7770118bd6 sr-ht-compare/cmd/comparesrht/main.go -rw-r--r-- 10.6 KiB
e01e9ed0 — bigbes 9 days ago
chimw: the request line in the journal, HEAD routes, and a 405 page

Three things at once, all of them the chi half of the shared middleware.

RequestLogger replaces chi's Logger, which wrote an unstructured line to
stdout — the highest-volume record this daemon emits and the only one not
beside the rest on stderr. RequestID goes above it so the request line
and a panic report share an id, Recoverer below it so its own report goes
through the entry instead of to stdout, and /healthz is skipped.

GetHead registers every read route under HEAD as well. Until now `curl
-I` and every uptime probe were answered 405 plus a kilobyte of rendered
error page by pages whose whole job is to be cheap to ask about.

RenderRefusals installs both routing failures against renderError; this
service had the 404 alone and left the 405 to net/http's plain text. The
new test that pins it also corrects what TestUnsafeMethodRefused claimed:
the group's middleware runs before either refusal, so an unsafe method on
a GET-only path is a 403 from the same-origin guard, not a 405.
aca0674e — bigbes 9 days ago
instconf: the origin ladder and the one-pass config check

validateConfig kept its shape and lost its body. instconf.Require is the
same decision — every missing key in one record, one exit, so an operator
edits config.ini once instead of restarting per gap — and firstConfigured
was this service's copy of the four-key API-origin ladder core-go panics
at the end of. NeedAny is handed APIOriginKeys() rather than the four
names written out, so the startup check and InternalAPIOrigin cannot
drift apart the way two literal lists eventually do.
07736d95 — bigbes 9 days ago
logging: the instance's log policy instead of forty local lines

initLogging held compare's own copy of the level choice, the colour probe
and the mask list, and the mask list was the drifted one: three keys and
a four-word pattern, against an instance whose services between them
redact ten. logging.Defaults answers all of it, and the handler stays
here — scribe is auxilia's and does not belong in the library every
service links for its chrome.

isTerminal goes to logging.ColorEnabled, which also honours NO_COLOR, and
the level now reads $LOG_LEVEL after -d. Defaults(nil, "") because the
handler is installed before LoadConfig: a daemon that became verbose only
after startup is silent for the window -d was passed to watch.
5719e51e — bigbes 9 days ago
login: ecore's cookie decoder, which validates the name ours did not

authz/identity.go was the fifth copy of a decode the instance has one of,
and it was one of the two that validated nothing: whatever name a sealed
payload carried went on to the GraphQL viewer field, the chrome's nav and
every log line the request produced. login.ValidName refuses it, and
there is no spelling of the API that turns the check off.

Gone with it: CookieName, UsernameFromRequest, Middleware, ForContext and
the ctxKey, plus identity_test.go, whose round-trip, tilde-stripping and
garbage-cookie cases are ecore's tests now. The Middleware becomes
login.Optional() — this service refuses nobody, git.sr.ht decides what an
anonymous viewer may see — and the default validator is kept rather than
core.ValidOwner, which is lowercase-only and would log a real account out
of compare alone.

The one behaviour change a viewer could notice: a cookie whose name
carries a '/', a control byte or a non-ASCII letter now reads as
anonymous instead of as that name.
65ffb96c — bigbes 10 days ago
log: slog through auxilia's scribe, not logrus

This was the last service on the instance still logging through logrus,
and the ecore bump made it a correctness question rather than a
consistency one: the recovery middleware reports a panic through slog's
DEFAULT logger, so without a SetDefault the one record carrying a stack
trace would have gone to Go's plain handler while every other line went
through logrus.

initLogging installs a scribe tint handler on stderr — source on, colour
only when stderr is a terminal, and the mask rules for token, cookie and
authorization. It reads -d out of the argument vector rather than
waiting for core-go's parse, because a daemon that only became verbose
after it had finished starting would be silent for exactly the part of
its life an operator passes -d to watch. Terminal detection is a stdlib
Stat rather than golang.org/x/term, which would be a new dependency for
one predicate.

The startup config check keeps its shape deliberately: it still
accumulates every missing key and reports them in ONE record before ONE
exit, so an operator fixes the config in a single pass. The keys go in
as a slice attribute rather than a joined string, so the structured
sinks keep them as a list.

culpa goes in at the one boundary where it pays: the errors web.New
returns, which are the only errors this package produces and all of
which arrive at that single startup record. Each carries a hint naming
the config key or the build step that fixes it, and scribe.Err unfolds
message, code, hint and stacktrace into fields of their own. The failing
request path logs the same way, with ErrorContext so a cancelled request
reads as cancelled rather than as an unexplained 500.

TestPanicIsAnErrorPage covers the wiring end to end through Register: a
panicking authorizer yields the chrome-wrapped 500, the panic value does
not reach the viewer, and the report reaches slog's default logger.
1e111cf4 — bigbes 10 days ago
cmd: ecoretest keys in the startup smoke test

The synthesized config.ini takes ecore's fixed keyset and origins rather
than generating a keypair per run; a constant cannot be malformed by
accident, which matters for a subprocess whose only way of complaining
is a log.Fatal. Also notes the three middlewares Register now installs
inside its own group, and why chi's Recoverer stays out here.
a4853d05 — Eugene Blikh a month ago
rename module to sourcecraft.dev/bigbes/sr-ht-compare; depend on sourcecraft sr-ht-core
6db8684c — bigbes a month ago
cmd/comparesrht: daemon entry point, startup validation, dev stub

Wire the compare.sr.ht daemon on core-go's server.New: it runs
crypto.InitCrypto, parses -b/-d/-m/-p, and drives the standard SourceHut
warm-shutdown loop (SIGINT). We deliberately skip WithDefaultMiddleware
(it demands Postgres/Redis and 401s anonymous viewers) and instead
install the web package's documented middleware chain — RealIP, Recoverer,
Logger, config.Middleware, authz.Middleware — inside a Group on the
anonymous router.

validateConfig checks every required key up front (network-key, webhook
key, repos root, a git.sr.ht API origin candidate, meta and compare
origins) with a single clear fatal, so a misconfiguration fails loudly at
startup rather than as a deep panic in config.GetAPI on the first request.

A build-and-exec smoke test proves the binary starts against a synthesized
config, answers /healthz 200, and exits cleanly on SIGINT in under 15s.

Makefile: build ./comparesrht from ./cmd/comparesrht, run-dev binds
localhost:5090 against a local config.ini, install ships the binary and
static assets. contrib/dev-stub is a stdlib-only fake git.sr.ht GraphQL
API returning fixed public repos for local development, and the systemd
unit now stops with KillSignal=SIGINT to hit the warm-shutdown path.