Add remote fix script for bridge configs
This commit is contained in:
123
remote_fix.sh
Normal file
123
remote_fix.sh
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
#!/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."
|
||||||
Reference in New Issue
Block a user