refactor progress

This commit is contained in:
Hampus Kraft
2026-02-17 12:22:36 +00:00
parent cb31608523
commit d5abd1a7e4
8257 changed files with 1190207 additions and 761040 deletions

View File

@@ -10,17 +10,17 @@ echo "Waiting for Cassandra to start..."
sleep 30
# 2. Extract backup and apply schema
docker exec cass bash -c 'apt-get update -qq && apt-get install -y -qq age'
docker exec cass sh -c 'apt-get update -qq && apt-get install -y -qq age'
docker cp ~/Downloads/backup.tar.age cass:/tmp/
docker cp ~/Downloads/key.txt cass:/tmp/
docker exec cass bash -c 'age -d -i /tmp/key.txt /tmp/backup.tar.age | tar -C /tmp -xf -'
docker exec cass bash -c 'sed "/^WARNING:/d" /tmp/cassandra-backup-*/schema.cql | cqlsh'
docker exec cass sh -c 'age -d -i /tmp/key.txt /tmp/backup.tar.age | tar -C /tmp -xf -'
docker exec cass sh -c 'sed "/^WARNING:/d" /tmp/cassandra-backup-*/schema.cql | cqlsh'
# 3. Copy backup to volume and stop Cassandra
docker exec cass bash -c 'cp -r /tmp/cassandra-backup-* /var/lib/cassandra/'
docker exec cass sh -c 'cp -r /tmp/cassandra-backup-* /var/lib/cassandra/'
docker stop cass
docker run -d --name cass-util -v cassandra_data:/var/lib/cassandra --entrypoint sleep cassandra:5.0 infinity
docker exec cass-util bash -c '
docker exec cass-util sh -c '
BACKUP_DIR=$(ls -d /var/lib/cassandra/cassandra-backup-* | head -1)
DATA_DIR=/var/lib/cassandra/data
for keyspace_dir in "$BACKUP_DIR"/*/; do
@@ -46,7 +46,7 @@ docker start cass
sleep 30
# 5. Run nodetool refresh on all tables
docker exec cass bash -c '
docker exec cass sh -c '
BACKUP_DIR=$(ls -d /var/lib/cassandra/cassandra-backup-* | head -1)
for keyspace_dir in "$BACKUP_DIR"/*/; do
keyspace=$(basename "$keyspace_dir")
@@ -89,16 +89,16 @@ docker cp "/tmp/${BACKUP_NAME}" ${CASSANDRA_CONTAINER}:/tmp/
docker cp /etc/cassandra/age_private_key.txt ${CASSANDRA_CONTAINER}:/tmp/key.txt
# 3. Stop Cassandra and prepare
docker exec ${CASSANDRA_CONTAINER} bash -c 'apt-get update -qq && apt-get install -y -qq age'
docker exec ${CASSANDRA_CONTAINER} sh -c 'apt-get update -qq && apt-get install -y -qq age'
docker stop ${CASSANDRA_CONTAINER}
# 4. Extract backup in utility container
docker run -d --name cass-restore-util --volumes-from ${CASSANDRA_CONTAINER} --entrypoint sleep cassandra:5.0 infinity
docker exec cass-restore-util bash -c 'age -d -i /tmp/key.txt /tmp/${BACKUP_NAME} | tar -C /tmp -xf -'
docker exec cass-restore-util bash -c 'cp -r /tmp/cassandra-backup-* /var/lib/cassandra/'
docker exec cass-restore-util sh -c 'age -d -i /tmp/key.txt /tmp/${BACKUP_NAME} | tar -C /tmp -xf -'
docker exec cass-restore-util sh -c 'cp -r /tmp/cassandra-backup-* /var/lib/cassandra/'
# 5. Copy SSTable files to existing schema directories
docker exec cass-restore-util bash -c '
docker exec cass-restore-util sh -c '
BACKUP_DIR=$(ls -d /var/lib/cassandra/cassandra-backup-* | head -1)
DATA_DIR=/var/lib/cassandra/data
for keyspace_dir in "$BACKUP_DIR"/*/; do
@@ -124,7 +124,7 @@ docker start ${CASSANDRA_CONTAINER}
sleep 30
# 7. Run nodetool refresh
docker exec ${CASSANDRA_CONTAINER} bash -c '
docker exec ${CASSANDRA_CONTAINER} sh -c '
BACKUP_DIR=$(ls -d /var/lib/cassandra/cassandra-backup-* | head -1)
for keyspace_dir in "$BACKUP_DIR"/*/; do
keyspace=$(basename "$keyspace_dir")

View File

@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env sh
# Copyright (C) 2026 Fluxer Contributors
#
@@ -17,7 +17,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
set -euo pipefail
set -eu
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
BACKUP_NAME="cassandra-backup-${TIMESTAMP}"
@@ -50,9 +50,9 @@ echo "[$(date)] Collecting snapshot files"
mkdir -p "${TEMP_DIR}"
# Find all snapshot directories and copy to temp location
find "${DATA_DIR}" -type d -name "${SNAPSHOT_TAG}" | while read snapshot_dir; do
find "${DATA_DIR}" -type d -name "${SNAPSHOT_TAG}" | while IFS= read -r snapshot_dir; do
# Get relative path from data dir
rel_path=$(dirname $(echo "${snapshot_dir}" | sed "s|${DATA_DIR}/||"))
rel_path=$(dirname "${snapshot_dir#$DATA_DIR/}")
target_dir="${TEMP_DIR}/${rel_path}"
mkdir -p "${target_dir}"
cp -r "${snapshot_dir}" "${target_dir}/"
@@ -89,7 +89,7 @@ fi
# Step 4: Create tar archive and encrypt with age (streaming)
echo "[$(date)] Encrypting backup with age..."
if ! tar -C /tmp -cf - "${BACKUP_NAME}" | \
age -r "$(cat ${AGE_PUBLIC_KEY_FILE})" -o "/tmp/${ENCRYPTED_BACKUP}"; then
age -r "$(cat "${AGE_PUBLIC_KEY_FILE}")" -o "/tmp/${ENCRYPTED_BACKUP}"; then
echo "[$(date)] Error: Encryption failed"
rm -rf "${TEMP_DIR}"
nodetool -h "${CASSANDRA_HOST}" clearsnapshot -t "${SNAPSHOT_TAG}"
@@ -130,11 +130,11 @@ aws s3 ls "s3://${B2_BUCKET_NAME}/" --endpoint-url="${B2_ENDPOINT_URL}" | \
awk '{print $4}' | \
sort -r | \
tail -n +$((MAX_BACKUP_COUNT + 1)) | \
while read -r old_backup; do
while IFS= read -r old_backup; do
echo "[$(date)] Deleting old backup: ${old_backup}"
aws s3 rm "s3://${B2_BUCKET_NAME}/${old_backup}" --endpoint-url="${B2_ENDPOINT_URL}" || true
done
echo "[$(date)] Backup process completed successfully"
echo "[$(date)] Backup name: ${ENCRYPTED_BACKUP}"
echo "[$(date)] Backup size: ${BACKUP_SIZE}"
echo "[$(date)] Backup size: ${BACKUP_SIZE}"

View File

@@ -0,0 +1 @@
ALTER TABLE fluxer.users ADD traits set<text>;

View File

@@ -0,0 +1,2 @@
ALTER TABLE fluxer.user_settings ADD bot_default_guilds_restricted boolean;
ALTER TABLE fluxer.user_settings ADD bot_restricted_guilds set<bigint>;

View File

@@ -0,0 +1,20 @@
CREATE TABLE IF NOT EXISTS fluxer.system_dm_jobs (
job_type text,
job_id bigint,
admin_user_id bigint,
status text,
content text,
registration_start timestamp,
registration_end timestamp,
excluded_guild_ids set<text>,
target_count int,
sent_count int,
failed_count int,
last_error text,
worker_job_key text,
created_at timestamp,
updated_at timestamp,
approved_by bigint,
approved_at timestamp,
PRIMARY KEY ((job_type), job_id)
) WITH CLUSTERING ORDER BY (job_id DESC);

View File

@@ -0,0 +1,22 @@
CREATE TABLE IF NOT EXISTS fluxer.admin_api_keys (
key_id bigint,
key_hash text,
name text,
created_by_user_id bigint,
created_at timestamp,
last_used_at timestamp,
expires_at timestamp,
version int,
PRIMARY KEY (key_id)
);
CREATE TABLE IF NOT EXISTS fluxer.admin_api_keys_by_creator (
created_by_user_id bigint,
key_id bigint,
created_at timestamp,
name text,
expires_at timestamp,
last_used_at timestamp,
version int,
PRIMARY KEY (created_by_user_id, key_id)
) WITH CLUSTERING ORDER BY (key_id DESC);

View File

@@ -0,0 +1,2 @@
ALTER TABLE fluxer.admin_api_keys ADD acls set<text>;
ALTER TABLE fluxer.admin_api_keys_by_creator ADD acls set<text>;

View File

@@ -0,0 +1,9 @@
CREATE TABLE IF NOT EXISTS fluxer.relationships_by_target (
target_user_id bigint,
source_user_id bigint,
type int,
nickname text,
since timestamp,
version int,
PRIMARY KEY (target_user_id, source_user_id, type)
) WITH CLUSTERING ORDER BY (source_user_id ASC, type ASC);

View File

@@ -0,0 +1,6 @@
CREATE TABLE IF NOT EXISTS fluxer.messages_by_author_id_v2 (
author_id bigint,
message_id bigint,
channel_id bigint,
PRIMARY KEY ((author_id), message_id)
) WITH CLUSTERING ORDER BY (message_id DESC);

View File

@@ -0,0 +1,28 @@
CREATE TABLE IF NOT EXISTS fluxer.csam_evidence_packages (
report_id bigint PRIMARY KEY,
resource_type text,
bucket text,
key text,
cdn_url text,
filename text,
content_type text,
channel_id bigint,
message_id bigint,
guild_id bigint,
user_id bigint,
match_tracking_id text,
match_details text,
frames text,
hashes text,
context_snapshot text,
created_at timestamp,
expires_at timestamp,
integrity_sha256 text,
evidence_zip_key text
);
CREATE TABLE IF NOT EXISTS fluxer.csam_evidence_legal_holds (
report_id bigint PRIMARY KEY,
held_until timestamp,
created_at timestamp
);

View File

@@ -0,0 +1,21 @@
CREATE TABLE IF NOT EXISTS fluxer.csam_scan_jobs (
job_id text PRIMARY KEY,
resource_type text,
bucket text,
key text,
cdn_url text,
filename text,
content_type text,
channel_id bigint,
message_id bigint,
guild_id bigint,
user_id bigint,
status text,
enqueue_time timestamp,
last_updated timestamp,
match_tracking_id text,
match_details text,
hashes text,
error_message text,
expires_at timestamp
);

View File

@@ -0,0 +1,6 @@
CREATE TABLE IF NOT EXISTS fluxer.csam_evidence_expirations (
bucket text,
expires_at timestamp,
report_id bigint,
PRIMARY KEY ((bucket), expires_at, report_id)
) WITH CLUSTERING ORDER BY (expires_at ASC);

View File

@@ -0,0 +1,2 @@
ALTER TABLE fluxer.guild_stickers ADD animated boolean;
ALTER TABLE fluxer.guild_stickers_by_sticker_id ADD animated boolean;

View File

@@ -0,0 +1 @@
ALTER TYPE fluxer.message_sticker_item ADD animated boolean;

View File

@@ -0,0 +1,10 @@
CREATE TABLE IF NOT EXISTS fluxer.ncmec_submissions (
report_id bigint PRIMARY KEY,
status text,
ncmec_report_id text,
submitted_at timestamp,
submitted_by_admin_id bigint,
failure_reason text,
created_at timestamp,
updated_at timestamp
);

View File

@@ -0,0 +1,2 @@
ALTER TYPE fluxer.message_attachment ADD duration_secs int;
ALTER TYPE fluxer.message_attachment ADD waveform text;

View File

@@ -0,0 +1 @@
ALTER TABLE fluxer.favorite_memes ADD klipy_slug text;

View File

@@ -0,0 +1 @@
ALTER TABLE fluxer.user_settings ADD trusted_domains set<text>;

View File

@@ -0,0 +1 @@
ALTER TABLE fluxer.user_settings ADD default_hide_muted_channels boolean;

View File

@@ -0,0 +1,2 @@
ALTER TYPE fluxer.guild_folder ADD flags int;
ALTER TYPE fluxer.guild_folder ADD icon text;

View File

@@ -0,0 +1,17 @@
CREATE TYPE IF NOT EXISTS fluxer.message_embed_child (
type text,
title text,
description text,
url text,
timestamp timestamp,
color int,
author frozen<message_embed_author>,
provider frozen<message_embed_provider>,
thumbnail frozen<message_embed_media>,
image frozen<message_embed_media>,
video frozen<message_embed_media>,
footer frozen<message_embed_footer>,
fields frozen<list<message_embed_field>>,
nsfw boolean
);
ALTER TYPE fluxer.message_embed ADD children frozen<list<message_embed_child>>;

View File

@@ -0,0 +1 @@
ALTER TABLE fluxer.guilds ADD message_history_cutoff timestamp;

View File

@@ -0,0 +1 @@
ALTER TABLE fluxer.guilds ADD members_indexed_at timestamp;

View File

@@ -0,0 +1,16 @@
CREATE TABLE IF NOT EXISTS fluxer.user_connections (
user_id bigint,
connection_type text,
connection_id text,
identifier text,
name text,
verified boolean,
visibility_flags int,
sort_order int,
verification_token text,
verified_at timestamp,
last_verified_at timestamp,
created_at timestamp,
version int,
PRIMARY KEY ((user_id), connection_type, connection_id)
) WITH CLUSTERING ORDER BY (connection_type ASC, connection_id DESC);

View File

@@ -0,0 +1,46 @@
CREATE TABLE IF NOT EXISTS fluxer.donors (
email text,
stripe_customer_id text,
business_name text,
tax_id text,
tax_id_type text,
stripe_subscription_id text,
subscription_amount_cents int,
subscription_currency text,
subscription_interval text,
subscription_current_period_end timestamp,
subscription_cancel_at timestamp,
created_at timestamp,
updated_at timestamp,
version int,
PRIMARY KEY ((email))
);
CREATE TABLE IF NOT EXISTS fluxer.donors_by_stripe_customer_id (
stripe_customer_id text,
email text,
PRIMARY KEY ((stripe_customer_id), email)
);
CREATE TABLE IF NOT EXISTS fluxer.donors_by_stripe_subscription_id (
stripe_subscription_id text,
email text,
PRIMARY KEY ((stripe_subscription_id), email)
);
CREATE TABLE IF NOT EXISTS fluxer.donor_magic_link_tokens (
token_ text,
donor_email text,
expires_at timestamp,
used_at timestamp,
PRIMARY KEY ((token_))
) WITH default_time_to_live = 900;
CREATE TABLE IF NOT EXISTS fluxer.donor_magic_link_tokens_by_email (
donor_email text,
token_ text,
PRIMARY KEY ((donor_email), token_)
) WITH default_time_to_live = 900;

View File

@@ -0,0 +1,12 @@
CREATE TABLE IF NOT EXISTS fluxer.password_change_tickets (
ticket text PRIMARY KEY,
user_id bigint,
code text,
code_sent_at timestamp,
code_expires_at timestamp,
verified boolean,
verification_proof text,
status text,
created_at timestamp,
updated_at timestamp
);

View File

@@ -0,0 +1 @@
ALTER TABLE fluxer.applications ADD bot_require_code_grant boolean;

View File

@@ -0,0 +1,21 @@
CREATE TABLE IF NOT EXISTS fluxer.guild_discovery (
guild_id bigint,
status text,
category_id int,
description text,
applied_at timestamp,
reviewed_at timestamp,
reviewed_by bigint,
review_reason text,
removed_at timestamp,
removed_by bigint,
removal_reason text,
PRIMARY KEY ((guild_id))
);
CREATE TABLE IF NOT EXISTS fluxer.guild_discovery_by_status (
status text,
applied_at timestamp,
guild_id bigint,
PRIMARY KEY ((status), applied_at, guild_id)
) WITH CLUSTERING ORDER BY (applied_at DESC, guild_id DESC);