diff --git a/scripts/deploy-signin-team.js b/scripts/deploy-signin-team.js new file mode 100644 index 0000000..2d299ba --- /dev/null +++ b/scripts/deploy-signin-team.js @@ -0,0 +1,87 @@ +// 铸渊 · 部署签到脚本到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); });