Files
bigwo/mcp-server-ssh/_deploy_kb_protection.cjs

102 lines
3.3 KiB
JavaScript
Raw Permalink Normal View History

const { Client } = require('ssh2');
const fs = require('fs');
const path = require('path');
const SSH_CONFIG = { host: '119.45.10.34', port: 22, username: 'root', password: '#xyzh%CS#2512@28' };
const REMOTE_DIR = '/www/wwwroot/demo.tensorgrove.com.cn/server/services';
const LOCAL_DIR = path.join(__dirname, '..', 'test2', 'server', 'services');
const FILES = [
'assistantProfileConfig.js',
'nativeVoiceGateway.js',
'contextKeywordTracker.js',
'toolExecutor.js',
'realtimeDialogRouting.js',
];
function sshExec(conn, cmd) {
return new Promise((resolve, reject) => {
conn.exec(cmd, (err, s) => {
if (err) return reject(err);
let o = '';
s.on('data', d => o += d);
s.stderr.on('data', d => o += d);
s.on('close', () => resolve(o));
});
});
}
function sftpUpload(conn, localPath, remotePath) {
return new Promise((resolve, reject) => {
conn.sftp((err, sftp) => {
if (err) return reject(err);
const rs = fs.createReadStream(localPath);
const ws = sftp.createWriteStream(remotePath);
ws.on('close', () => resolve());
ws.on('error', reject);
rs.pipe(ws);
});
});
}
async function main() {
const conn = new Client();
await new Promise((resolve, reject) => {
conn.on('ready', resolve).on('error', reject).connect(SSH_CONFIG);
});
console.log('SSH connected\n');
// 1. Backup all files
console.log('=== Step 1: Backup ===');
for (const f of FILES) {
const r = await sshExec(conn, `cp ${REMOTE_DIR}/${f} ${REMOTE_DIR}/${f}.bak.$(date +%Y%m%d_%H%M%S) && echo " Backed up ${f}"`);
console.log(r);
}
// 2. Upload all files
console.log('\n=== Step 2: Upload ===');
for (const f of FILES) {
await sftpUpload(conn, path.join(LOCAL_DIR, f), `${REMOTE_DIR}/${f}`);
console.log(` Uploaded ${f}`);
}
// 3. Syntax check each file
console.log('\n=== Step 3: Syntax check ===');
for (const f of FILES) {
const result = await sshExec(conn, `node -c ${REMOTE_DIR}/${f} 2>&1 && echo "SYNTAX_OK ${f}" || echo "SYNTAX_FAIL ${f}"`);
console.log(result);
if (result.includes('SYNTAX_FAIL')) {
console.error(`SYNTAX CHECK FAILED for ${f}! Rolling back ALL...`);
for (const rf of FILES) {
await sshExec(conn, `ls -t ${REMOTE_DIR}/${rf}.bak.* 2>/dev/null | head -1 | xargs -I{} cp {} ${REMOTE_DIR}/${rf}`);
}
console.log('Rolled back.');
conn.end();
process.exit(1);
}
}
// 4. Restart PM2
console.log('\n=== Step 4: Restart PM2 ===');
console.log(await sshExec(conn, 'cd /www/wwwroot/demo.tensorgrove.com.cn/server && pm2 restart bigwo-server --update-env'));
await new Promise(r => setTimeout(r, 3000));
// 5. Check PM2 status
console.log('\n=== Step 5: PM2 status ===');
console.log(await sshExec(conn, 'pm2 status bigwo-server'));
// 6. Check recent logs for errors
console.log('\n=== Step 6: Recent logs ===');
console.log(await sshExec(conn, 'tail -15 /var/log/bigwo/server-out.log'));
// 7. Check error log
console.log('\n=== Step 7: Error log ===');
console.log(await sshExec(conn, 'tail -5 /var/log/bigwo/server-error.log'));
conn.end();
console.log('\n=== Deploy KB Protection Window Complete! ===');
console.log('Changes: KB topic memory + 60s protection window + honest fallback + session passthrough');
}
main().catch(e => { console.error('DEPLOY FAILED:', e.message); process.exit(1); });