guanghulab/scripts/deploy-signin-team.js
铸渊 ICE-GL-ZY001 cbcb80ff53 feat: Awen团队服务器签到脚本部署器
- deploy-signin-team.js: 批量部署persona-signin到AW-GZ-001/002/003
- 已执行: 3台企业服务器签到脚本就绪
- HL-SG-001/HL-CN-001需手动(无Gatekeeper)
2026-05-26 03:12:59 +08:00

88 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 铸渊 · 部署签到脚本到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); });