You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

206 lines
6.3 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using Sog;
using Google.Protobuf.WellKnownTypes;
namespace SMCenter
{
//
public class ShellAgentResult
{
public ResResultCode ResultCode;
public string Result;
public string Message;
}
//执行shell命令
//调用的是bash
//请不要执行不会退出的命令,比如top之类的,没处理这样情况,会挂掉的
public class ShellCmdProc : BaseCmdProc
{
private Dictionary<string, ShellAgentResult> m_agents = new Dictionary<string, ShellAgentResult>();
private long m_startCancelTime = 0;
public override void ClearData()
{
m_nowCmd = null;
m_agents.Clear();
m_startCancelTime = 0;
}
public override int DoCmd(out string msg)
{
try
{
if (CmdUtils.CheckValidServerId(m_nowCmd.CmdParams[0], out string fixSvrId) == false)
{
msg = "invalid server id";
return -1;
}
if (fixSvrId != null)
{
m_nowCmd.CmdParams[0] = fixSvrId;
}
SMProcAppMgr.Instance.GetAllMatchingProc(m_nowCmd.CmdParams[0], m_nowCmd.m_procs);
var req = new SMAgentDoCommandReq();
req.Command = m_nowCmd.CMD;
req.SeqNum = m_nowCmd.SeqNum;
req.ExeFileName = "bash";
req.CmdArgs = string.Empty;
for (int i = 1; i < m_nowCmd.CmdParams.Count; i++)
{
req.CmdArgs += m_nowCmd.CmdParams[i];
if (i != m_nowCmd.CmdParams.Count - 1)
{
req.CmdArgs += " ";
}
}
foreach (var name in m_nowCmd.m_procs.Values.Select(p => p.SMApp.HostName).Distinct())
{
m_agents.Add(name, new ShellAgentResult() );
var client = SMCenterNet.Instance.GetClientInfoByName(name);
if (client == null)
{
TraceLog.Error("ShellCmdProc.DoCmd agent {0} not register", name);
m_agents[name].Result = "failed";
m_agents[name].Message = "no connected agent";
continue;
}
SMCenterNet.Instance.SendMsg(client, SMMsgID.AgentDoCommandReq, req);
}
}
catch (Exception e)
{
TraceLog.Exception(e);
msg = "ShellCmdProc.DoCmd throw a exception ...";
return -1;
}
msg = string.Empty;
return 0;
}
public override int UpdateCmd(long tMs)
{
if(m_startCancelTime > 0 && tMs - m_startCancelTime > 5000)
{
//超时退出
return 0;
}
bool allFinish = true;
int successCount = 0;
int failedCount = 0;
foreach(var agent in m_agents)
{
if(agent.Value.ResultCode == ResResultCode.Success)
{
successCount++;
}
else
{
failedCount++;
}
if(agent.Value.ResultCode == ResResultCode.Running)
{
allFinish = false;
break;
}
if(agent.Value.ResultCode == ResResultCode.NoRes)
{
allFinish = false;
break;
}
}
if(allFinish)
{
var res = new SMConsoleCommandRes();
res.Command = m_nowCmd.CMD;
res.Message = string.Format("shell cmd {0} finish. succ {1} failed {2}", m_nowCmd.ConsoleInput, successCount, failedCount);
SMCenterNet.Instance.SendMsg(m_nowCmd.SessionId, SMMsgID.ConsoleCommandRes, res);
return 0;
}
return 1;
}
public override void OnAgentDoCommandRes(ClientInfo client, SMAgentDoCommandRes res)
{
TraceLog.Trace("ShellCmdProc.OnAgentDoCommandRes cmd {0} res from {1}",
m_nowCmd.CMD, client.HostName);
if(m_agents.ContainsKey(res.HostName) == false)
{
TraceLog.Error("ShellCmdProc.OnAgentDoCommandRes cmd {0} res no agent {1}",
m_nowCmd.CMD, client.HostName);
return;
}
var info = m_agents[res.HostName];
info.ResultCode = res.ResultCode;
info.Result = res.Result;
info.Message = res.AddInfo;
var consoleres = new SMConsoleCommandRes();
consoleres.Nonewline = 1;
consoleres.Command = m_nowCmd.ConsoleInput;
if(res.ResultCode == ResResultCode.Running)
{
consoleres.Message = string.Format("host {0} ack \n{1} {2}", res.HostName, res.Result, res.AddInfo);
}
else
{
consoleres.Message = string.Format("shell cmd host {0} finish. Msg: \n{1} {2}", res.HostName, res.Result, res.AddInfo);
}
SMCenterNet.Instance.SendMsg(m_nowCmd.SessionId, SMMsgID.ConsoleCommandRes, consoleres);
}
public int DoCancel(out string msg)
{
msg = "success";
var req = new SMAgentDoCommandReq();
req.Command = "cancelshell";
req.SeqNum = m_nowCmd.SeqNum;
req.CmdArgs = string.Empty;
foreach (var agent in m_agents)
{
var client = SMCenterNet.Instance.GetClientInfoByName(agent.Key);
if (client == null)
{
TraceLog.Error("ShellCmdProc.DoCancel agent {0} not register", agent.Key);
agent.Value.ResultCode = ResResultCode.Fail;
agent.Value.Result = "failed";
agent.Value.Message = "no connected agent";
continue;
}
SMCenterNet.Instance.SendMsg(client, SMMsgID.AgentDoCommandReq, req);
}
return 0;
}
}
}