228 lines
7.4 KiB
Bash
228 lines
7.4 KiB
Bash
export DISCORD_BRIDGE_YAML_VERSION=v2
|
|
export ENTRYPOINT_CONF_VERSION=v3
|
|
export HOMESERVER_YAML_VERSION=v35
|
|
export LOG_CONFIG_VERSION=v2
|
|
export SHARED_SECRET_AUTH_VERSION=v2
|
|
export SIGNAL_BRIDGE_YAML_VERSION=v6
|
|
export TELEGRAM_BRIDGE_YAML_VERSION=v6
|
|
export NGINX_CONFIG_VERSION=v12
|
|
export WK_SERVER_VERSION=v1
|
|
export WK_CLIENT_VERSION=v1
|
|
export PG_BACKUP_VERSION=v2
|
|
export ADMIN_CONFIG_VERSION=v1
|
|
export COMPRESS_STATE_ENTRYPOINT_VERSION=v5
|
|
|
|
# See https://levans.fr/shrink-synapse-database.html
|
|
db_size() {
|
|
echo "=== Database size ==="
|
|
psql -U synapse -d synapse -c "SELECT pg_size_pretty(pg_database_size('synapse')) AS db_size;"
|
|
echo ""
|
|
echo "=== Top 10 largest tables ==="
|
|
psql -U synapse -d synapse -c "
|
|
SELECT nspname || '.' || relname AS table,
|
|
pg_size_pretty(pg_total_relation_size(C.oid)) AS total_size
|
|
FROM pg_class C
|
|
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
|
|
WHERE nspname NOT IN ('pg_catalog', 'information_schema')
|
|
ORDER BY pg_total_relation_size(C.oid) DESC
|
|
LIMIT 10;"
|
|
}
|
|
|
|
state_bloat() {
|
|
echo "=== Rooms with most state bloat ==="
|
|
psql -U synapse -d synapse -c "
|
|
SELECT room_id, count(*) AS state_entries
|
|
FROM state_groups_state
|
|
GROUP BY room_id
|
|
ORDER BY state_entries DESC
|
|
LIMIT 20;"
|
|
}
|
|
|
|
empty_rooms() {
|
|
echo "=== Rooms with no local members ==="
|
|
psql -U synapse -d synapse -c "
|
|
SELECT room_id, room_version
|
|
FROM rooms
|
|
WHERE room_id NOT IN (
|
|
SELECT room_id FROM local_current_membership WHERE membership = 'join'
|
|
);"
|
|
}
|
|
|
|
reindex() {
|
|
echo "WARNING: REINDEX locks tables. Synapse should be stopped before running this."
|
|
echo "Running REINDEX on synapse database..."
|
|
psql -U synapse -d synapse -c "REINDEX (VERBOSE) DATABASE synapse;"
|
|
echo "REINDEX complete."
|
|
psql -U synapse -d synapse -c "SELECT pg_size_pretty(pg_database_size('synapse')) AS db_size;"
|
|
}
|
|
|
|
# Run via: abra app cmd <domain> compress-state run_compressor
|
|
run_compressor() {
|
|
CHUNK_SIZE="${1:-${STATE_COMPRESS_CHUNK_SIZE:-500}}"
|
|
CHUNKS="${2:-${STATE_COMPRESS_CHUNKS:-100}}"
|
|
DB_PASS=$(cat /run/secrets/db_password)
|
|
echo "Running synapse_auto_compressor (chunk_size=$CHUNK_SIZE, chunks=$CHUNKS)..."
|
|
/build/synapse_auto_compressor \
|
|
-p "postgresql://synapse:${DB_PASS}@db:5432/synapse" \
|
|
-c "$CHUNK_SIZE" -n "$CHUNKS"
|
|
}
|
|
|
|
vacuum_full() {
|
|
echo "WARNING: VACUUM FULL locks tables and requires temporary disk space."
|
|
echo "Synapse should be stopped before running this."
|
|
echo "Running VACUUM FULL on synapse database..."
|
|
psql -U synapse -d synapse -c "VACUUM FULL;"
|
|
echo "VACUUM FULL complete."
|
|
psql -U synapse -d synapse -c "SELECT pg_size_pretty(pg_database_size('synapse')) AS db_size;"
|
|
}
|
|
|
|
# Purge commands — run via: abra app cmd <domain> app <command>
|
|
# These use the Synapse admin API and require an admin access token.
|
|
|
|
register_admin() {
|
|
USER="${1}"
|
|
PASS="${2}"
|
|
if [ -z "$USER" ] || [ -z "$PASS" ]; then
|
|
echo "Usage: register_admin <username> <password>"
|
|
return 1
|
|
fi
|
|
register_new_matrix_user -u "$USER" -p "$PASS" -a -c /data/homeserver.yaml http://localhost:8008
|
|
}
|
|
|
|
get_token() {
|
|
USER="${1}"
|
|
PASS="${2}"
|
|
if [ -z "$USER" ] || [ -z "$PASS" ]; then
|
|
echo "Usage: get_token <username> <password>"
|
|
echo "Returns an admin access token for use with purge commands."
|
|
return 1
|
|
fi
|
|
curl -s -X POST "http://localhost:8008/_matrix/client/r0/login" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"type\":\"m.login.password\",\"user\":\"$USER\",\"password\":\"$PASS\"}" \
|
|
| python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('access_token', d.get('error', 'unknown error')))"
|
|
}
|
|
|
|
purge_remote_media() {
|
|
DAYS="${1:-30}"
|
|
TOKEN="${2}"
|
|
if [ -z "$TOKEN" ]; then
|
|
echo "Usage: purge_remote_media <days> <admin_token>"
|
|
return 1
|
|
fi
|
|
BEFORE_TS=$(( $(date +%s) * 1000 - DAYS * 86400000 ))
|
|
echo "Purging remote media older than $DAYS days..."
|
|
curl -s -X POST "http://localhost:8008/_synapse/admin/v1/purge_media_cache?before_ts=$BEFORE_TS" \
|
|
-H "Authorization: Bearer $TOKEN"
|
|
echo ""
|
|
}
|
|
|
|
purge_room() {
|
|
ROOM_ID="${1}"
|
|
TOKEN="${2}"
|
|
if [ -z "$ROOM_ID" ] || [ -z "$TOKEN" ]; then
|
|
echo "Usage: purge_room <room_id> <admin_token>"
|
|
return 1
|
|
fi
|
|
echo "Purging room $ROOM_ID..."
|
|
curl -s -X DELETE "http://localhost:8008/_synapse/admin/v1/rooms/$ROOM_ID" \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"purge": true}'
|
|
echo ""
|
|
}
|
|
|
|
purge_history() {
|
|
ROOM_ID="${1}"
|
|
DAYS="${2:-90}"
|
|
TOKEN="${3}"
|
|
if [ -z "$ROOM_ID" ] || [ -z "$TOKEN" ]; then
|
|
echo "Usage: purge_history <room_id> <days> <admin_token>"
|
|
return 1
|
|
fi
|
|
BEFORE_TS=$(( $(date +%s) * 1000 - DAYS * 86400000 ))
|
|
echo "Purging history older than $DAYS days from $ROOM_ID..."
|
|
curl -s -X POST "http://localhost:8008/_synapse/admin/v1/purge_history/$ROOM_ID" \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"purge_up_to_ts\": $BEFORE_TS}"
|
|
echo ""
|
|
}
|
|
|
|
purge_empty_rooms() {
|
|
TOKEN="${1}"
|
|
if [ -z "$TOKEN" ]; then
|
|
echo "Usage: purge_empty_rooms <admin_token>"
|
|
return 1
|
|
fi
|
|
echo "Fetching rooms with no local members..."
|
|
ROOMS=$(curl -s "http://localhost:8008/_synapse/admin/v1/rooms?limit=1000" \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
| python3 -c "
|
|
import sys, json
|
|
data = json.load(sys.stdin)
|
|
for r in data.get('rooms', []):
|
|
if r.get('joined_local_members', 0) == 0:
|
|
print(r['room_id'])
|
|
")
|
|
COUNT=$(echo "$ROOMS" | grep -c '.' || true)
|
|
echo "Found $COUNT empty rooms."
|
|
if [ "$COUNT" -eq 0 ]; then
|
|
echo "Nothing to purge."
|
|
return 0
|
|
fi
|
|
echo "$ROOMS"
|
|
echo ""
|
|
echo "Purging..."
|
|
for ROOM_ID in $ROOMS; do
|
|
echo " Purging $ROOM_ID"
|
|
curl -s -X DELETE "http://localhost:8008/_synapse/admin/v1/rooms/$ROOM_ID" \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"purge": true}' > /dev/null
|
|
done
|
|
echo "Done."
|
|
}
|
|
|
|
set_admin () {
|
|
admin=akadmin
|
|
if [ -n "$1" ]
|
|
then
|
|
admin=$1
|
|
fi
|
|
psql -U synapse -c "UPDATE users SET admin = 1 WHERE name = '@$admin:$DOMAIN'";
|
|
}
|
|
|
|
set_bridge_tokens() {
|
|
if [ -z "$1" ]; then
|
|
echo "Error: Missing parameter. Usage: set_bridge_tokens <BRIDGETYPE>"
|
|
return 1
|
|
fi
|
|
|
|
BRIDGETYPE=$1
|
|
echo "retrieve tokens from registration.yaml..."
|
|
output=$(abra app run $DOMAIN app cat /${BRIDGETYPE}-data/registration.yaml)
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: Failed to retrieve registration.yaml for ${BRIDGETYPE} bridge:"
|
|
echo "$output"
|
|
return 1
|
|
fi
|
|
|
|
hs_token=$(echo "$output" | sed -n 's/^hs_token:[[:space:]]*\(.*\)$/\1/p')
|
|
as_token=$(echo "$output" | sed -n 's/^as_token:[[:space:]]*\(.*\)$/\1/p')
|
|
|
|
echo "HS Token: $hs_token"
|
|
echo "AS Token: $as_token"
|
|
echo "UNDEPLOY $DOMAIN?"
|
|
abra app undeploy $DOMAIN
|
|
|
|
echo "Replacing tokens:"
|
|
abra app secret rm $DOMAIN ${BRIDGETYPE}_as_token
|
|
abra app secret insert $DOMAIN ${BRIDGETYPE}_as_token v1 $as_token
|
|
abra app secret rm $DOMAIN ${BRIDGETYPE}_hs_token
|
|
abra app secret insert $DOMAIN ${BRIDGETYPE}_hs_token v1 $hs_token
|
|
|
|
echo "Redeploying $DOMAIN..."
|
|
abra app deploy -n $DOMAIN
|
|
}
|