Add the receiver that files error reports as Gitea issues

server/report-receiver/receiver.py takes what report sends to
federated.sh/report, behind Caddy, and files each report as an issue in
the private Federated_Computer/coredesktop-reports repository with the
full log attached. It saves each report before replying and tries Gitea
again later if it's down, limits how many reports one address can send,
and refuses oversized logs, gzip bombs included. Standard library only.

The README has the deployment steps: a Gitea user that can only file
issues there, the systemd unit, and the Caddy route. make test runs its
tests, which send reports with the real report client.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-08 11:36:43 -07:00
co-authored by Claude Opus 5.5
parent 1cd56f7a90
commit ce7cf08d60
6 changed files with 681 additions and 0 deletions
+61
View File
@@ -0,0 +1,61 @@
# Report receiver
Takes the error reports CoreDesktop machines send with `report` (see the top of
`../../report` for the request format) at `https://federated.sh/report`, and
files each as an issue in the private Gitea repository
`Federated_Computer/coredesktop-reports`, with the full log attached.
- `receiver.py` listens on 127.0.0.1:8650, behind Caddy. Standard library only.
- It saves each report in `/var/lib/coredesktop-reports/<ID>/` before replying,
so a report isn't lost if Gitea is down, and tries again every 10 minutes.
Saved reports are deleted after 90 days; the Gitea issues stay.
- It turns away more than 5 reports an hour or 20 a day from one address, and
more than 500 a day in all, and logs bigger than 10 MB compressed or 64 MB
uncompressed.
- `make test` in the repository runs `test_receiver.py`, which sends reports
with the real `report` client to the receiver and a fake Gitea.
## Deploying on federated.sh
1. **A Gitea user that can only file issues there.** Gitea tokens can't be
limited to one repository, so make a separate user (say
`coredesktop-reports-bot`), add it to `Federated_Computer/coredesktop-reports`
as a collaborator with write access, and make it a token with only the
`write:issue` permission. Nothing else should be shared with that user.
2. **Install the receiver** (as root):
```
install -d -m 755 /opt/coredesktop-reports
install -m 644 receiver.py /opt/coredesktop-reports/receiver.py
install -m 644 coredesktop-reports.service /etc/systemd/system/coredesktop-reports.service
install -m 600 /dev/null /etc/coredesktop-reports.env
```
Then put the settings in `/etc/coredesktop-reports.env`:
```
GITEA_URL=https://gitea.federated.computer
GITEA_REPO=Federated_Computer/coredesktop-reports
GITEA_TOKEN=<the bot's token>
```
```
systemctl daemon-reload
systemctl enable --now coredesktop-reports
curl -s http://127.0.0.1:8650/report/health # prints ok
```
3. **Route /report to it in Caddy.** See `Caddyfile.example`: `/report` goes
in its own `handle` block, and the site's existing directives go in a
catch-all `handle`, so the installer redirect keeps working. Check with
`caddy validate`, then `systemctl reload caddy`.
4. **Check it end to end.** `curl -s https://federated.sh/report/health`
prints ok, `wget -qO- https://federated.sh | head -3` still shows
install.sh, and from a CoreDesktop machine `report` sends its newest log
and prints an ID, which appears as a new issue in the repository.
To update it later, install the new `receiver.py` the same way and run
`systemctl restart coredesktop-reports`. `journalctl -u coredesktop-reports`
shows each report it receives and files.