Files
beeper-bridge-docker/remote_fix.sh
2025-12-06 02:53:50 +00:00

124 lines
4.0 KiB
Bash

#!/bin/bash
echo "=== Beeper Bridge Remote Fix Tool ==="
echo "Run this script ON THE REMOTE MACHINE where Docker is running."
# Create the python repair script
cat << 'PYTHON_SCRIPT' > fix_configs.py
import sys
import os
import shutil
# Install ruamel.yaml if missing
try:
from ruamel.yaml import YAML, YAMLError
except ImportError:
print("Installing ruamel.yaml...")
import subprocess
subprocess.check_call([sys.executable, "-m", "pip", "install", "ruamel.yaml"])
from ruamel.yaml import YAML, YAMLError
yaml = YAML()
yaml.preserve_quotes = True
services = ["whatsapp", "telegram", "signal", "googlechat"]
base_dir = "data"
# Docker-friendly logging config (Stdout/Stderr)
logging_config = {
"version": 1,
"formatters": {
"colored": {
"format": "[%(asctime)s] [%(levelname)s@%(name)s] %(message)s",
"datefmt": "%b %d %H:%M:%S"
}
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"formatter": "colored",
"stream": "ext://sys.stdout"
}
},
"root": {
"level": "INFO",
"handlers": ["console"]
}
}
def fix_config(service):
config_path = os.path.join(base_dir, service, "config.yaml")
if not os.path.exists(config_path):
print(f"[{service}] Config not found at {config_path}. Skipping.")
return
print(f"[{service}] Checking config...")
try:
with open(config_path, 'r') as f:
data = yaml.load(f)
# If we reached here, YAML is valid. Apply patches.
modified = False
# 1. Fix Database URI
if 'appservice' in data and 'database' in data['appservice']:
db_conf = data['appservice']['database']
if isinstance(db_conf, str) and db_conf != "sqlite:////data/bridge.db":
data['appservice']['database'] = "sqlite:////data/bridge.db"
modified = True
elif isinstance(db_conf, dict) and db_conf.get('uri') != "sqlite:////data/bridge.db":
data['appservice']['database']['uri'] = "sqlite:////data/bridge.db"
modified = True
if 'database' in data and isinstance(data['database'], dict):
if data['database'].get('uri') != "sqlite:////data/bridge.db":
data['database']['uri'] = "sqlite:////data/bridge.db"
modified = True
# 2. Fix Logging (Always apply to ensure stdout is used)
# We check if it looks different to avoid unnecessary writes,
# but simplistic check is: is it using stream handler?
current_logging = data.get('logging', {})
# Just overwrite it to be safe and ensure Docker compatibility
data['logging'] = logging_config
modified = True
if modified:
print(f"[{service}] Applying fixes (Logging/Database)...")
with open(config_path, 'w') as f:
yaml.dump(data, f)
else:
print(f"[{service}] Config looked OK.")
except (YAMLError, Exception) as e:
print(f"[{service}] ERROR: Config file is corrupt or invalid YAML.")
print(f" -> {e}")
backup_path = config_path + ".corrupt.bak"
print(f"[{service}] ACTION: Moving corrupt config to {backup_path}")
print(f"[{service}] ACTION: The container will regenerate a fresh valid config on next start.")
shutil.move(config_path, backup_path)
# Main execution
if __name__ == "__main__":
for service in services:
fix_config(service)
PYTHON_SCRIPT
echo "[*] Executing fix script using python:3.11-slim container..."
# We use a docker container to run the python script so we don't mess with host python
docker run --rm \
-v "$(pwd):/work" \
-w /work \
python:3.11-slim \
sh -c "pip install ruamel.yaml && python fix_configs.py"
# Cleanup
rm fix_configs.py
echo "=== Fix Complete ==="
echo "1. If Google Chat config was corrupt, it was backed up."
echo "2. Run 'docker compose restart' (or 'up -d') now."
echo "3. The bridges should generate fresh configs or use the fixed ones."