zustand auf server wiederhergestellt

This commit is contained in:
2026-01-09 08:43:18 +01:00
parent 1010fe7d11
commit f2f9e02fb2
30 changed files with 6403 additions and 139 deletions

View File

@@ -82,6 +82,18 @@ export async function getServerStatus(server) {
if (status === 'activating' || status === 'reloading') return 'starting';
if (status === 'deactivating') return 'stopping';
return 'offline';
} else if (server.runtime === 'pm2') {
const nvmPrefix = "source ~/.nvm/nvm.sh && ";
const result = await ssh.execCommand(nvmPrefix + "pm2 jlist");
try {
const processes = JSON.parse(result.stdout);
const proc = processes.find(p => p.name === server.serviceName);
if (!proc) return "offline";
if (proc.pm2_env.status === "online") return "online";
if (proc.pm2_env.status === "launching") return "starting";
if (proc.pm2_env.status === "stopping") return "stopping";
return "offline";
} catch { return "offline"; }
} else {
const result = await ssh.execCommand(`screen -ls | grep -E "\\.${server.screenName}[[:space:]]"`);
if (result.code === 0) {
@@ -126,7 +138,10 @@ export async function startServer(server, options = {}) {
await ssh.execCommand(`docker start ${server.containerName}`);
}
} else if (server.runtime === 'systemd') {
await ssh.execCommand(`systemctl start ${server.serviceName}`);
const sudoCmd = server.external ? "sudo " : ""; await ssh.execCommand(`${sudoCmd}systemctl start ${server.serviceName}`);
} else if (server.runtime === 'pm2') {
const nvmPrefix = "source ~/.nvm/nvm.sh && ";
await ssh.execCommand(nvmPrefix + "pm2 start " + server.serviceName);
} else {
await ssh.execCommand(`screen -S ${server.screenName} -X quit 2>/dev/null`);
await new Promise(resolve => setTimeout(resolve, 1000));
@@ -140,7 +155,10 @@ export async function stopServer(server) {
if (server.runtime === 'docker') {
await ssh.execCommand(`docker stop ${server.containerName}`);
} else if (server.runtime === 'systemd') {
await ssh.execCommand(`systemctl stop ${server.serviceName}`);
const sudoCmd2 = server.external ? "sudo " : ""; await ssh.execCommand(`${sudoCmd2}systemctl stop ${server.serviceName}`);
} else if (server.runtime === 'pm2') {
const nvmPrefix = "source ~/.nvm/nvm.sh && ";
await ssh.execCommand(nvmPrefix + "pm2 stop " + server.serviceName);
} else {
// Different stop commands per server type
const stopCmd = server.type === 'zomboid' ? 'quit' : 'stop';
@@ -176,6 +194,10 @@ export async function getConsoleLog(server, lines = 50) {
} else if (server.runtime === 'systemd') {
const result = await ssh.execCommand(`tail -n ${lines} ${server.workDir}/logs/VRisingServer.log 2>/dev/null || journalctl -u ${server.serviceName} -n ${lines} --no-pager`);
return result.stdout || result.stderr;
} else if (server.runtime === 'pm2') {
const nvmPrefix = "source ~/.nvm/nvm.sh && ";
const result = await ssh.execCommand(nvmPrefix + "pm2 logs " + server.serviceName + " --lines " + lines + " --nostream");
return result.stdout || result.stderr;
} else if (server.logFile) {
const result = await ssh.execCommand(`tail -n ${lines} ${server.logFile} 2>/dev/null || echo No log file found`);
return result.stdout;
@@ -203,6 +225,17 @@ export async function getProcessUptime(server) {
if (!isNaN(startEpoch)) {
return Math.floor(Date.now() / 1000) - startEpoch;
}
} else if (server.runtime === "pm2") {
const nvmPrefix = "source ~/.nvm/nvm.sh && ";
const result = await ssh.execCommand(nvmPrefix + "pm2 jlist");
try {
const processes = JSON.parse(result.stdout);
const proc = processes.find(p => p.name === server.serviceName);
if (proc && proc.pm2_env.pm_uptime) {
return Math.floor((Date.now() - proc.pm2_env.pm_uptime) / 1000);
}
} catch {}
return 0;
} else {
const result = await ssh.execCommand(`ps -o etimes= -p $(pgrep -f "SCREEN.*${server.screenName}") 2>/dev/null | head -1`);
const uptime = parseInt(result.stdout.trim());
@@ -491,3 +524,67 @@ export async function writePalworldConfig(server, filename, content) {
return true;
}
// ============ TERRARIA CONFIG ============
const TERRARIA_CONFIG_PATH = "/home/terraria/serverconfig.txt";
export async function readTerrariaConfig(server) {
const ssh = await getConnection(server.host, server.sshUser);
const result = await ssh.execCommand(`cat ${TERRARIA_CONFIG_PATH}`);
if (result.code !== 0) {
throw new Error(result.stderr || "Failed to read config file");
}
return result.stdout;
}
export async function writeTerrariaConfig(server, content) {
const ssh = await getConnection(server.host, server.sshUser);
// Create backup
const backupName = `serverconfig.txt.backup.${Date.now()}`;
await ssh.execCommand(`cp ${TERRARIA_CONFIG_PATH} /home/terraria/${backupName} 2>/dev/null || true`);
// Write file using sftp
const sftp = await ssh.requestSFTP();
await new Promise((resolve, reject) => {
sftp.writeFile(TERRARIA_CONFIG_PATH, content, (err) => {
if (err) reject(err);
else resolve();
});
});
// Clean up old backups (keep last 5)
await ssh.execCommand(`ls -t /home/terraria/serverconfig.txt.backup.* 2>/dev/null | tail -n +6 | xargs rm -f 2>/dev/null || true`);
return true;
}
// OpenTTD Config
const OPENTTD_CONFIG_PATH = "/opt/openttd/.openttd/openttd.cfg";
export async function readOpenTTDConfig(server) {
const ssh = await getConnection(server.host, server.sshUser);
const result = await ssh.execCommand(`cat ${OPENTTD_CONFIG_PATH}`);
if (result.code !== 0) {
throw new Error(result.stderr || "Failed to read config file");
}
return result.stdout;
}
export async function writeOpenTTDConfig(server, content) {
const ssh = await getConnection(server.host, server.sshUser);
const backupName = `openttd.cfg.backup.${Date.now()}`;
await ssh.execCommand(`cp ${OPENTTD_CONFIG_PATH} /opt/openttd/.openttd/${backupName} 2>/dev/null || true`);
const sftp = await ssh.requestSFTP();
await new Promise((resolve, reject) => {
sftp.writeFile(OPENTTD_CONFIG_PATH, content, (err) => {
if (err) reject(err);
else resolve();
});
});
await ssh.execCommand(`ls -t /opt/openttd/.openttd/openttd.cfg.backup.* 2>/dev/null | tail -n +6 | xargs rm -f 2>/dev/null || true`);
return true;
}