// 铸渊 · 部署签到脚本到Awen团队服务器 // 将 persona-signin.js 部署到有Gatekeeper的团队服务器 // 用法: node scripts/deploy-signin-team.js const http = require('http'); const fs = require('fs'); const path = require('path'); const ROOT = path.resolve(__dirname, '..'); const SIGNIN_SCRIPT = fs.readFileSync(path.join(ROOT, 'scripts', 'persona-signin.js'), 'utf8'); // Awen团队服务器(有Gatekeeper的) const TEAM_SERVERS = [ { code: "AW-GZ-001", name: "企业主服务器 · 广州", ip: "43.139.251.175", key: "zy_gtw_cab20e8c1b957aaad7507bf542231521bba30665461aa540", port: 3910 }, { code: "AW-SH-002", name: "企业灾备 · 上海", ip: "124.222.54.198", key: "zy_gtw_242f1dd3b14c1260fb01196083abde3dcb85e53532d27666", port: 3910 }, { code: "AW-GZ-003", name: "企业灾备 · 广州", ip: "119.29.181.132", key: "zy_gtw_8c9a8b439af823690ae6ad57f52734771ff39493ab986032", port: 3910 }, ]; function gkExec(srv, cmd, timeoutMs) { timeoutMs = timeoutMs || 15000; const d = JSON.stringify({ cmd }); const opts = { hostname: srv.ip, port: srv.port, path: '/exec', method: 'POST', headers: { 'Authorization': 'Bearer ' + srv.key, 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(d) }, timeout: timeoutMs }; return new Promise((resolve) => { const req = http.request(opts, (res) => { let b = ''; res.on('data', c => b += c); res.on('end', () => { try { resolve({ ok: res.statusCode === 200, body: JSON.parse(b) }); } catch(e) { resolve({ ok: false, error: e.message }); } }); }); req.on('error', (e) => resolve({ ok: false, error: e.message })); req.on('timeout', () => { req.destroy(); resolve({ ok: false, error: 'timeout' }); }); req.write(d); req.end(); }); } async function deployOne(srv) { process.stdout.write(`[${srv.code}] ${srv.name} ... `); // 1. 创建目录并写入脚本(base64编码避免转义问题) const b64 = Buffer.from(SIGNIN_SCRIPT).toString('base64'); const cmd = `mkdir -p /opt/zhuyuan && echo ${b64} | base64 -d > /opt/zhuyuan/persona-signin.js && chmod +x /opt/zhuyuan/persona-signin.js && echo "DEPLOYED"`; const r = await gkExec(srv, cmd); if (!r.ok) { console.log('❌ 部署失败: ' + (r.error || 'unknown')); return false; } // 2. 测试运行 const testCmd = `node /opt/zhuyuan/persona-signin.js --server=${srv.code} --json 2>&1`; const r2 = await gkExec(srv, testCmd, 10000); if (r2.ok && r2.body && r2.body.stdout) { try { const testData = JSON.parse(r2.body.stdout); console.log(`✅ persona=${testData.persona_id} server=${testData.server_code} cpu=${testData.hardware?.cpu_cores}核`); return true; } catch(e) { console.log('⚠️ 部署OK但测试解析失败: ' + e.message); return true; } } else { console.log('⚠️ 部署OK但测试执行异常: ' + (r2.error || r2.body?.stderr || '')); return true; } } async function main() { console.log('铸渊 · 部署签到脚本到Awen团队服务器'); console.log(`目标: ${TEAM_SERVERS.length}台\n`); let ok = 0; for (const srv of TEAM_SERVERS) { if (await deployOne(srv)) ok++; } console.log(`\n完成: ${ok}/${TEAM_SERVERS.length}台`); console.log('\n📋 使用方式(在服务器上):'); console.log(' node /opt/zhuyuan/persona-signin.js --server=<编号>'); console.log(' 在人格体fast-wake CK-007完成后调用一次即可'); console.log('\n⚠️ HL-SG-001/HL-CN-001 需手动部署(无Gatekeeper):'); console.log(' scp scripts/persona-signin.js awen@hl-sg-001:/opt/zhuyuan/'); } main().catch(e => { console.error(e.message); process.exit(1); });