v2.1: HLDP新增@串联/@广播,引擎集群互相通话,一条指令全网执行

This commit is contained in:
bingshuo 2026-05-30 19:06:55 +08:00
parent 614a8c789e
commit 1218d21112

View File

@ -1,7 +1,7 @@
#!/usr/bin/env node #!/usr/bin/env node
/* /*
光湖驱动引擎 v2.0 · Guanghu Drive Engine 光湖驱动引擎 v2.1 · Guanghu Drive Engine
HLDP万能语言接口 HLDP进指令出 HLDP万能语言接口 + 集群串联 一条指令全网执行
*/ */
const http=require('http'),fs=require('fs'),path=require('path'),crypto=require('crypto'),{exec}=require('child_process'),os=require('os'); const http=require('http'),fs=require('fs'),path=require('path'),crypto=require('crypto'),{exec}=require('child_process'),os=require('os');
@ -82,53 +82,112 @@ function fmtBytes(b){if(b===0)return'0 B';const k=1024,sizes=['B','KB','MB','GB'
/* /*
HLDP 翻译层 v1.0 光湖驱动引擎 v2.0 HLDP 翻译层 v2.0 光湖驱动引擎 v2.1
新增 @串联 @广播 引擎之间互相通话
*/ */
const NODES={
'BS-GZ-006':{url:'http://43.139.217.141:3910',key:'zy_gtw_4a155446b7acc09fe46a2a29972c0ca5d9954da19c35dc23'},
'BS-SG-001':{url:'http://43.156.237.110:3911',key:'zy_gtw_c38be341d65043eee0ba51a214a267832a9ae46dd73e423c'},
'BS-SG-002':{url:'http://43.134.16.246:3910',key:'zy_gtw_ceb06d8a70d0cd38678239b3a1a9b2ba5cba77a3fbe5ebbf'},
'BS-SG-003':{url:'http://43.153.193.169:3910',key:'zy_gtw_d7c033d8ae992ffc9dd3e0dd5fe332dace0b644c0ae7c847'},
'ZY-SG-006':{url:'http://43.153.203.105:3910',key:'zy_gtw_fff861a2fe40cbdc366ee21f218023be8b1c182f66c852d3'},
'BS-SH-005':{url:'http://124.223.10.33:3910',key:'zy_gtw_b1045de5ddfd7832e3c53349d9c896f054b85a4a9ece22f9'},
};
function parseOpLine(t){
if(t.startsWith('@执行:')){
const cmd=t.replace('@执行:','').trim();
const parts=cmd.split(/\s+/);
if(parts[0]==='shell')return{type:'shell',cmd:parts.slice(1).join(' ')};
if(parts[0]==='python')return{type:'python',cmd:parts.slice(1).join(' ')};
return{type:'shell',cmd:cmd};
}
if(t.startsWith('@部署:')){
const action=t.replace('@部署:','').trim();
const parts=action.split(/\s+/);
if(parts[0]==='写入')return{type:'write',path:parts[1]};
if(parts[0]==='命令')return{type:'shell',cmd:parts.slice(1).join(' ')};
}
return null;
}
function parseHLDP(text){ function parseHLDP(text){
const lines=text.split('\n').filter(l=>l.trim()); const lines=text.split('\n');
const ops=[]; const groups=[];
let relay=null;
for(const line of lines){ for(const line of lines){
const t=line.trim(); const t=line.trim();
if(t.startsWith('@执行:')){ if(!t)continue;
const cmd=t.replace('@执行:','').trim(); if(t.startsWith('@串联:')){relay=t.replace('@串联:','').trim();continue;}
const parts=cmd.split(/\s+/); if(t==='@广播'){relay='BROADCAST';continue;}
if(parts[0]==='shell'){ops.push({type:'shell',cmd:parts.slice(1).join(' ')});} const op=parseOpLine(t);
else if(parts[0]==='python'){ops.push({type:'python',cmd:parts.slice(1).join(' ')});} if(!op)continue;
else{ops.push({type:'shell',cmd:cmd});} if(!groups.length||groups[groups.length-1].relay!==relay){
}else if(t.startsWith('@部署:')){ groups.push({relay:relay,ops:[]});
const action=t.replace('@部署:','').trim();
const parts=action.split(/\s+/);
if(parts[0]==='写入'){
const filepath=parts[1];
ops.push({type:'write',path:filepath});
}else if(parts[0]==='命令'){
ops.push({type:'shell',cmd:parts.slice(1).join(' ')});
}
} }
groups[groups.length-1].ops.push(op);
} }
return ops; return groups;
}
async function relayHLDP(target,hldpText){
const node=NODES[target];
if(!node)return{target:target,ok:false,error:'未知节点: '+target};
return new Promise(r=>{
const body=JSON.stringify({hlpd:hldpText});
const opts={hostname:node.url.replace(/https?:\/\//,'').split(':')[0],
port:parseInt(node.url.split(':').pop()||'3910',10),
path:'/hlpd',method:'POST',
headers:{'Content-Type':'application/json','Authorization':'Bearer '+node.key,'Content-Length':Buffer.byteLength(body)}};
const req=http.request(opts,res=>{let d='';res.on('data',c=>d+=c);res.on('end',()=>{try{r({target:target,ok:true,result:JSON.parse(d)})}catch(e){r({target:target,ok:false,error:d.slice(0,200)})}})});
req.on('error',e=>r({target:target,ok:false,error:e.message}));
req.write(body);req.end();
});
}
function hldpTextFromOps(ops){
return ops.map(o=>{
if(o.type==='shell')return '@执行: shell '+o.cmd;
if(o.type==='python')return '@执行: python '+o.cmd;
if(o.type==='write')return '@部署: 写入 '+o.path;
return '';
}).filter(l=>l).join('\n');
} }
async function runHLDP(hlpdText){ async function runHLDP(hlpdText){
const ops=parseHLDP(hlpdText); const groups=parseHLDP(hlpdText);
const results=[]; const allResults=[];
for(const op of ops){ for(const g of groups){
if(op.type==='shell'){ if(!g.relay){
const r=await execCmd(op.cmd); for(const op of g.ops){
results.push({type:'shell',cmd:op.cmd,...r}); if(op.type==='shell'){
}else if(op.type==='write'){ const r=await execCmd(op.cmd);
try{ allResults.push({type:'shell',cmd:op.cmd,...r});
const dir=path.dirname(op.path); }else if(op.type==='write'){
if(!fs.existsSync(dir))fs.mkdirSync(dir,{recursive:true}); try{
results.push({type:'write',path:op.path,ok:true}); const dir=path.dirname(op.path);
}catch(e){results.push({type:'write',path:op.path,ok:false,error:e.message});} if(!fs.existsSync(dir))fs.mkdirSync(dir,{recursive:true});
}else if(op.type==='python'){ allResults.push({type:'write',path:op.path,ok:true});
const r=await execCmd('python3 -c "'+op.cmd.replace(/"/g,'\\"')+'"'); }catch(e){allResults.push({type:'write',path:op.path,ok:false,error:e.message});}
results.push({type:'python',cmd:op.cmd,...r}); }else if(op.type==='python'){
const r=await execCmd('python3 -c "'+op.cmd.replace(/"/g,'\\"')+'"');
allResults.push({type:'python',cmd:op.cmd,...r});
}
}
}else if(g.relay==='BROADCAST'){
const hldp=hldpTextFromOps(g.ops);
const targets=Object.keys(NODES);
const promises=targets.map(t=>relayHLDP(t,hldp));
const results=await Promise.all(promises);
allResults.push({type:'broadcast',targets:targets.length,results:results});
}else{
const hldp=hldpTextFromOps(g.ops);
const r=await relayHLDP(g.relay,hldp);
allResults.push({type:'relay',target:g.relay,...r});
} }
} }
return{parsed:ops.length,results:results}; return{groups:groups.length,results:allResults};
} }
@ -158,11 +217,11 @@ const server=http.createServer(async(req,res)=>{
log('INFO','exec_result','exit='+r.code); log('INFO','exec_result','exit='+r.code);
jr(res,200,{ok:r.code===0,stdout:r.stdout,stderr:r.stderr,exitCode:r.code}); jr(res,200,{ok:r.code===0,stdout:r.stdout,stderr:r.stderr,exitCode:r.code});
}else if(route==='/health'){ }else if(route==='/health'){
jr(res,200,{ok:true,service:'guanghu-engine',version:'2.0.0',uptime:process.uptime().toFixed(0)+'s',timestamp:new Date().toISOString()}); jr(res,200,{ok:true,service:'guanghu-engine',version:'2.1.0',uptime:process.uptime().toFixed(0)+'s',timestamp:new Date().toISOString()});
}else if(route==='/status'){ }else if(route==='/status'){
log('INFO','status',''); log('INFO','status','');
const total=os.totalmem(),free=os.freemem(); const total=os.totalmem(),free=os.freemem();
jr(res,200,{ok:true,hostname:os.hostname(),platform:os.platform(),arch:os.arch(),cpus:os.cpus().length,uptime:os.uptime(),uptime_str:fmtUptime(os.uptime()),memory:{total:fmtBytes(total),free:fmtBytes(free),used:fmtBytes(total-free),usage:((total-free)/total*100).toFixed(1)+'%'},load:os.loadavg().map(n=>+n.toFixed(2)),engine:{version:'2.0.0',port:PORT,uptime:process.uptime().toFixed(0)+'s'}}); jr(res,200,{ok:true,hostname:os.hostname(),platform:os.platform(),arch:os.arch(),cpus:os.cpus().length,uptime:os.uptime(),uptime_str:fmtUptime(os.uptime()),memory:{total:fmtBytes(total),free:fmtBytes(free),used:fmtBytes(total-free),usage:((total-free)/total*100).toFixed(1)+'%'},load:os.loadavg().map(n=>+n.toFixed(2)),engine:{version:'2.1.0',port:PORT,uptime:process.uptime().toFixed(0)+'s'}});
}else if(route==='/hlpd'){ }else if(route==='/hlpd'){
const b=await parseBody(req); const b=await parseBody(req);
if(!b||!b.hlpd){jr(res,400,{error:'缺少 hlpd 参数'});return;} if(!b||!b.hlpd){jr(res,400,{error:'缺少 hlpd 参数'});return;}
@ -221,8 +280,8 @@ server.on('error',(e)=>{
server.listen(PORT,'0.0.0.0',()=>{ server.listen(PORT,'0.0.0.0',()=>{
const h=os.hostname(); const h=os.hostname();
log('INFO','startup','host='+h+' port='+PORT+' v2.0'); log('INFO','startup','host='+h+' port='+PORT+' v2.1');
console.log(' ⚔️ 光湖驱动引擎 v2.0 · HLDP 已就绪'); console.log(' ⚔️ 光湖驱动引擎 v2.1 · HLDP + 集群串联');
console.log(' 主机名: '+h+' 端口: '+PORT); console.log(' 主机名: '+h+' 端口: '+PORT);
}); });