T11: Mastodon 4.7.3 in the pasture

peers/mastodon.sh runs Mastodon's web and sidekiq containers on a shared Postgres and Redis
(peers/shared.sh). They trust Caddy's CA through SSL_CERT_FILE and reach private addresses
through ALLOWED_PRIVATE_ADDRESSES. Its users and tokens come from tootctl and rails runner.

scenarios/mastodon.sh adds 49 checks, as listed in docs/INTEROP.md: follows, posts,
replies, likes and boosts with undos, DMs, polls, FEP-044f quotes both ways, media through
the proxy, edits, deletes, locked follows, a circle request, reports, blocks and statistics.
Two are expected failures:
- inbound Block (P7);
- circle posts. Mastodon 4.7 loses the recipient of deliveries to its numeric
  /ap/users/<id>/inbox and then drops a post that names no local account. The fix on our
  side changes what a circle reveals, so it waits for the owner.

GoToSocial and Mastodon together: 86 passed, 0 failed.

The pasture now copies Caddy's root certificate reliably, readable by the peers, and
rebuilds the bundle each time. The CA directory is mounted shared (:z), because a private
:Z label locks out every container but the last. pfetch reaches PrivaPub's own https URIs
through Caddy. PRIVAPUB_ENV passes settings to PrivaPub, which scenarios/crawler.sh uses to
check the opt-in crawler against Mastodon: it visits, describes and reads the peers list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ELjqpznMFMNrJoJUj6K5p2
This commit is contained in:
thepraandClaude Opus 5.5 committed 2026-10-03 12:30:05 +02:00
1 parent d0a13d9cc2
commit e0f2eb7da7
9 files changed
+367 -28

No files matched your search

+2
View File
@@ -11,6 +11,8 @@ except Exception: d=None
$1" 2>/dev/null; }
until_true() { local tries=$1; shift; for _ in $(seq 1 "$tries"); do if eval "$@"; then return 0; fi; sleep 2; done; return 1; }
site() { curl -k --resolve "$1:6443:127.0.0.1" "${@:2}"; }
# fetches one of PrivaPub's own https URIs (ids, scribbles) from the workstation, through Caddy
pfetch() { curl -sk --connect-to privapub.test:443:127.0.0.1:6443 "$@"; }
ROOT_USER=pastureroot; ROOT_PASS='Pasture-Pass-1!'
privapub_root() {
+15 -4
View File
@@ -20,17 +20,28 @@ pasture_base_up() {
podman run -d --replace --name pasture-caddy --network $net $aliases \
-p 127.0.0.1:6443:443 --sysctl net.ipv4.ip_unprivileged_port_start=0 -v "$here/Caddyfile:/etc/caddy/Caddyfile:Z,ro" \
-v pasture-caddy-data:/data docker.io/library/caddy:2 >/dev/null
local extra=()
for setting in ${PRIVAPUB_ENV:-}; do extra+=(-e "$setting"); done
podman run -d --replace --name pasture-privapub --network $net -p 127.0.0.1:6971:80 \
--sysctl net.ipv4.ip_unprivileged_port_start=0 -e ASPNETCORE_ENVIRONMENT=Pasture -w /app -v "$publish:/app:Z,ro" \
--sysctl net.ipv4.ip_unprivileged_port_start=0 -e ASPNETCORE_ENVIRONMENT=Pasture "${extra[@]}" -w /app -v "$publish:/app:Z,ro" \
mcr.microsoft.com/dotnet/runtime-deps:10.0 /app/PrivaPub >/dev/null
wait_http http://127.0.0.1:6971/build.json
mkdir -p "$ca"
for _ in $(seq 1 30); do podman cp pasture-caddy:/data/caddy/pki/authorities/local/root.crt "$ca/root.crt" 2>/dev/null && break; sleep 1; done
rm -rf "$ca"; mkdir -p "$ca"
for _ in $(seq 1 60); do
podman cp pasture-caddy:/data/caddy/pki/authorities/local/root.crt "$ca/root.crt" 2>/dev/null && [ -s "$ca/root.crt" ] && break
curl -sk -o /dev/null --resolve privapub.test:6443:127.0.0.1 https://privapub.test:6443/build.json || true
sleep 1
done
[ -s "$ca/root.crt" ] || { echo "Caddy's root certificate could not be copied" >&2; return 1; }
chmod 644 "$ca/root.crt"
cat /etc/pki/tls/certs/ca-bundle.crt /etc/ssl/certs/ca-certificates.crt 2>/dev/null > "$ca/bundle.pem" || true
cat "$ca/root.crt" >> "$ca/bundle.pem"
chmod 644 "$ca/bundle.pem"
}
pasture_down() {
podman ps -a --format '{{.Names}}' | grep '^pasture-' | xargs -r podman rm -f >/dev/null 2>&1 || true
podman volume ls --format '{{.Name}}' | grep '^pasture-' | xargs -r podman volume rm -f >/dev/null 2>&1 || true
podman network rm $net >/dev/null 2>&1 || true
rm -rf "$here/.state"
rm -rf "$here/.state" "$ca"
}