130 lines
4.0 KiB
Bash
Executable File
130 lines
4.0 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
set -e
|
|
|
|
# guide: https://levans.fr/shrink-synapse-database.html
|
|
# doc: https://matrix-org.github.io/synapse/develop/admin_api/purge_history_api.html
|
|
|
|
host='localhost'
|
|
port='8008'
|
|
synapse_log='/var/log/matrix-synapse/homeserver.log'
|
|
db_conf_file='/etc/matrix-synapse/conf.d/database.yaml'
|
|
rooms_query_limit=6666
|
|
|
|
# purge parameters:
|
|
room_history_range="2months"
|
|
media_range="1month"
|
|
|
|
# compression parameters:
|
|
chunk_size=500
|
|
chunks_to_compress=10000
|
|
|
|
debug=0
|
|
|
|
|
|
debug () {
|
|
if [ "$debug" = 1 ]; then
|
|
echo $* 1>&2
|
|
fi
|
|
}
|
|
get_obsolete_rooms () {
|
|
curl --silent -H "Authorization: Bearer $token" \
|
|
"${host}:${port}/_synapse/admin/v1/rooms?limit=${rooms_query_limit}" \
|
|
| jq -r '.rooms[] | select(.joined_local_members == 0) | .room_id'
|
|
}
|
|
|
|
get_synapse_version () {
|
|
curl --silent --ssl -H "Authorization: Bearer $token" \
|
|
"${host}:${port}/_synapse/admin/v1/server_version"
|
|
}
|
|
|
|
get_all_rooms () {
|
|
curl --silent -H "Authorization: Bearer $token" \
|
|
"${host}:${port}/_synapse/admin/v1/rooms?limit=${rooms_query_limit}" \
|
|
| jq -r '.rooms[].room_id'
|
|
}
|
|
|
|
purge_obsolete_rooms () {
|
|
for room_id in $(get_obsolete_rooms); do
|
|
curl --silent --ssl -X POST --header "Content-Type: application/json" \
|
|
--header "Authorization: Bearer $token" \
|
|
-d "{ \"room_id\": \"$room_id\" }" \
|
|
"${host}:${port}/_synapse/admin/v1/purge_room" \
|
|
| jq
|
|
done
|
|
}
|
|
|
|
purge_history () {
|
|
# note: to delete local events as well, do:
|
|
# -d "{ \"delete_local_events\": true, ... }"
|
|
for room_id ; do
|
|
json=$(curl --silent --ssl -X POST \
|
|
--header "Content-Type: application/json" \
|
|
--header "Authorization: Bearer $token" \
|
|
-d "{ \"delete_local_events\": false, \"purge_up_to_ts\": $room_history_range_ts }" \
|
|
"${host}:${port}/_synapse/admin/v1/purge_history/${room_id}")
|
|
|
|
if echo $json | grep -q 'purge_id'; then
|
|
debug "waiting for purge to complete..."
|
|
tail -n 0 -f $synapse_log \
|
|
| sed '/\[purge\] complete/q' > /dev/null
|
|
debug "purge completed."
|
|
fi
|
|
done
|
|
}
|
|
|
|
purge_media_cache () {
|
|
curl --silent -X POST --ssl \
|
|
--header "Authorization: Bearer $token" -d '' \
|
|
"${host}:${port}/_synapse/admin/v1/purge_media_cache?before_ts=${media_range_ts}" \
|
|
| jq
|
|
}
|
|
|
|
compress_state () {
|
|
synapse_auto_compressor -c "${chunk_size}" -n "${chunks_to_compress}" \
|
|
-p "postgresql://${db_user}:${db_password}@${host}/${db_name}"
|
|
}
|
|
|
|
main () {
|
|
echo "Purging obsolete rooms (rooms with no local members)"
|
|
purge_obsolete_rooms
|
|
# FIXME: Only purge large rooms
|
|
echo "Purging room history older than ${room_history_range}"
|
|
purge_history $(get_all_rooms)
|
|
echo "Purging media cache older than ${media_range}"
|
|
purge_media_cache
|
|
echo "Compressing room state"
|
|
compress_state
|
|
echo "Reindexing and vacuuming the database"
|
|
psql -q -c "REINDEX DATABASE synapse;" -c "VACUUM FULL;" -d synapse -U synapse
|
|
}
|
|
|
|
if test -r /etc/matrix-synapse/access_token ; then
|
|
token="$(cat /etc/matrix-synapse/access_token)"
|
|
elif ! [ -t 1 ]; then
|
|
echo "Error: Access token file is not readable and cannot prompt for token." >&2
|
|
exit 1
|
|
else
|
|
read -p "synapse admin API access_token: " token
|
|
fi
|
|
|
|
if test -r $db_conf_file; then
|
|
# FIXME: script should abort if these vars are somehow empty
|
|
db_name="$(grep '^\s*database: ' $db_conf_file | awk '{print $2}')"
|
|
db_user="$(grep '^\s*user: ' $db_conf_file | awk '{print $2}')"
|
|
db_password="$(grep '^\s*password: ' $db_conf_file | awk '{print $2}')"
|
|
elif ! [ -t 1 ]; then
|
|
echo "Error: Database config file is not readable and cannot prompt for database config." >&2
|
|
exit 1
|
|
else
|
|
read -p "synapse database name: " db_name
|
|
read -p "synapse database user: " db_user
|
|
read -p "synapse database password: " db_password
|
|
fi
|
|
|
|
# synapse wants timestamps in milliseconds since the epoch
|
|
room_history_range_ts="$(date -d-${room_history_range} +%s)000"
|
|
media_range_ts="$(date -d-${media_range} +%s)000"
|
|
|
|
main
|