#!/bin/bash # Mastodon upgrade verifier. # --------------------------------------------------------------------------- # Mastodon runs Rails migrations on boot and expects releases to be applied in # order. The web process answers /health once Puma is listening — which happens # BEFORE migrations necessarily finish — so /health alone is not proof. The # authoritative check is that no migration is still pending, which # `rails db:migrate:status` reports (any row marked "down" means outstanding). # # Version is confirmed from the instance API rather than the image tag, so we # are reading what the app says about itself, not what we asked for. # mastodon_upgrade_verify # 0 only when the app serves, reports the expected version, and has no # migration outstanding. mastodon_upgrade_verify() { local app="$1" expected="$2" deadline="$3" # "v4.6" -> "4.6"; the API reports "4.6.5", so this is a prefix comparison. local want; want="$(printf '%s' "$expected" | sed 's/^v//')" local last="" while [ "$(date +%s)" -lt "$deadline" ]; do # 1. Serving at all? local health health="$(runFileOp docker exec mastodon-service curl -fsS --max-time 5 \ http://localhost:3000/health 2>/dev/null | tr -d '\r\n')" if [ -n "$health" ]; then # 2. Migrations finished? Any "down" row means Rails still has work. local pending pending="$(runFileOp docker exec mastodon-service bin/rails db:migrate:status 2>/dev/null \ | awk '$1 == "down" { n++ } END { print n+0 }')" # 3. Which version does it actually report? local ver ver="$(runFileOp docker exec mastodon-service curl -fsS --max-time 5 \ http://localhost:3000/api/v1/instance 2>/dev/null \ | grep -oE '"version":"[^"]+"' | head -1 | cut -d'"' -f4)" last="health=$health pendingMigrations=${pending:-?} version=${ver:-?}" if [ "${pending:-1}" = "0" ] && [ -n "$ver" ] && [[ "$ver" == "$want"* ]]; then isSuccessful "Mastodon reports $ver with no pending migrations." return 0 fi isNotice "Mastodon not ready yet: $last" fi sleep 10 done isError "Mastodon did not reach a verified state for $expected before the deadline.${last:+ Last status: $last}" return 1 }