Files
gitlab-instance-0a899031_cn…/scripts/ssh-restore-lounge.py
2026-06-08 06:05:31 -05:00

134 lines
4.1 KiB
Python

#!/usr/bin/env python3
"""Restore corrupted The Lounge config.js on production VPS."""
from __future__ import annotations
import paramiko
import os
from load_dev_env import ssh_config
HOST, USER, SSH_PASSWORD = ssh_config()
INSPECT = [
"cat /var/lib/thelounge/config.js 2>&1 | head -20",
"ls -la /var/lib/thelounge/ 2>&1",
"ls -la /var/lib/thelounge/*.bak /var/lib/thelounge/config.js.* 2>&1 || true",
"cat /etc/systemd/system/thelounge.service 2>&1",
"sudo ls -la /var/lib/thelounge/ 2>&1",
]
LOUNGE_CONFIG = r"""'use strict';
module.exports = {
host: '127.0.0.1',
port: 9000,
public: true,
theme: 'morning',
prefetch: false,
disableLog: false,
fileUpload: false,
transports: ['websocket', 'polling'],
defaults: {
name: 'NomadCNA',
username: 'nomad',
realname: 'NomadCNA Community',
join: '#nomadcna,#online-events',
},
lockNetwork: true,
messageStorage: [],
useHexIp: false,
maxHistory: 10000,
displayNetwork: true,
networks: [
{
name: 'NomadCNA',
host: '127.0.0.1',
port: 6667,
tls: false,
rejectUnauthorized: false,
nick: 'nomad',
username: 'nomad',
realname: 'NomadCNA Community',
join: '#nomadcna,#online-events',
commands: [],
},
],
};
"""
def run(commands: list[str]) -> None:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(HOST, username=USER, password=PASSWORD, timeout=25)
try:
for cmd in commands:
print(f"\n=== {cmd} ===")
_, stdout, stderr = client.exec_command(cmd, timeout=60, get_pty=True)
out = stdout.read().decode("utf-8", errors="replace")
err = stderr.read().decode("utf-8", errors="replace")
if out:
print(out.rstrip())
if err:
print("ERR:", err.rstrip())
finally:
client.close()
def restore() -> None:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(HOST, username=USER, password=PASSWORD, timeout=25)
try:
sftp = client.open_sftp()
remote_tmp = "/tmp/thelounge-config.js"
with sftp.file(remote_tmp, "w") as f:
f.write(LOUNGE_CONFIG)
sftp.close()
cmds = [
f"echo '{PASSWORD}' | sudo -S cp /var/lib/thelounge/config.js /var/lib/thelounge/config.js.broken-$(date +%Y%m%d%H%M%S) 2>/dev/null || true",
f"echo '{PASSWORD}' | sudo -S cp {remote_tmp} /var/lib/thelounge/config.js",
f"echo '{PASSWORD}' | sudo -S chown thelounge:thelounge /var/lib/thelounge/config.js",
f"echo '{PASSWORD}' | sudo -S chmod 640 /var/lib/thelounge/config.js",
f"echo '{PASSWORD}' | sudo -S systemctl restart thelounge.service",
"sleep 3",
"systemctl is-active thelounge.service",
"curl -sI http://127.0.0.1:9000/ | head -8",
"curl -sI https://lounge.nomadro.cn/ | head -8",
"journalctl -u thelounge.service -n 15 --no-pager",
]
for cmd in cmds:
print(f"\n=== {cmd.replace(PASSWORD, '***')} ===")
_, stdout, stderr = client.exec_command(cmd, timeout=60, get_pty=True)
out = stdout.read().decode("utf-8", errors="replace")
err = stderr.read().decode("utf-8", errors="replace")
if out:
print(out.rstrip())
if err:
print("ERR:", err.rstrip())
finally:
client.close()
VERIFY = [
"systemctl is-active thelounge.service ergo.service",
"curl -s 'https://lounge.nomadro.cn/socket.io/?EIO=4&transport=polling&t=health' | cut -c1-120",
"{ printf 'NICK health\\r\\nUSER health 0 * :NomadCNA Health\\r\\nJOIN #nomadcna\\r\\nQUIT :healthcheck\\r\\n'; sleep 1; } | timeout 5s nc 127.0.0.1 6667 2>&1 | head -5",
"curl -sI 'https://lounge.nomadro.cn/' | head -3",
]
if __name__ == "__main__":
import sys
if len(sys.argv) > 1 and sys.argv[1] == "restore":
restore()
elif len(sys.argv) > 1 and sys.argv[1] == "verify":
run(VERIFY)
else:
run(INSPECT)