debugSvc.py (8890B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\script\sys\debugSvc.py 2 from __future__ import print_function 3 import cStringIO 4 import code 5 import marshal 6 import pprint 7 import random 8 import sys 9 import traceback 10 from collections import OrderedDict 11 import log 12 import blue 13 import evecrypto.crypto as Crypto 14 from carbon.common.script.net import machoNet 15 from carbon.common.script.sys import sessions 16 from carbon.common.script.sys.service import Service 17 from carbon.common.script.sys.serviceConst import ROLE_PROGRAMMER 18 from eveprefs import boot 19 20 class Utf8IO(object): 21 encoding = 'utf-8' 22 23 def __init__(self): 24 self._sio = cStringIO.StringIO() 25 26 def __getattr__(self, attr): 27 return getattr(self._sio, attr) 28 29 30 class debugSvc(Service): 31 __guid__ = 'svc.debug' 32 __displayname__ = 'Debug Service' 33 __exportedcalls__ = {'Exec': [ROLE_PROGRAMMER], 34 'Eval': [ROLE_PROGRAMMER], 35 'Log': [ROLE_PROGRAMMER], 36 'GetLogEvents': [ROLE_PROGRAMMER]} 37 __notifyevents__ = ['OnDebugLog'] 38 __dependencies__ = ['machoNet'] 39 40 def Run(self, memStream = None): 41 self.logEvents = {} 42 43 def GetOptions(self): 44 ret = OrderedDict() 45 if boot.role == 'server': 46 ret.update({'all': 'All Proxy and Sol Servers', 47 'remote': 'Any Proxy', 48 'local': 'Locally', 49 'proxies': 'All Proxies', 50 'servers': 'All Sol Servers'}) 51 for nodeID in sm.services['machoNet'].GetConnectedProxyNodes(): 52 transport = sm.services['machoNet'].GetTransportOfNode(nodeID) 53 ret[nodeID] = 'Proxy %d (%s)' % (nodeID, transport.transport.address) 54 55 for nodeID in sm.services['machoNet'].GetConnectedSolNodes(): 56 transport = sm.services['machoNet'].GetTransportOfNode(nodeID) 57 ret[nodeID] = 'Sol %d (%s)' % (nodeID, transport.transport.address) 58 59 else: 60 ret.update({'all': 'All Proxy and Sol Servers', 61 'remote': 'Any Proxy', 62 'local': 'Locally', 63 'proxies': 'All Proxies', 64 'servers': 'All Sol Servers'}) 65 for nodeID in sm.services['machoNet'].GetConnectedProxyNodes(): 66 transport = sm.services['machoNet'].GetTransportOfNode(nodeID) 67 ret[nodeID] = 'Proxy %d (%s)' % (nodeID, transport.transport.address) 68 69 for nodeID in sm.services['machoNet'].GetConnectedSolNodes(): 70 transport = sm.services['machoNet'].GetTransportOfNode(nodeID) 71 ret[nodeID] = 'Sol %d (%s)' % (nodeID, transport.transport.address) 72 73 for s in sessions.GetSessions(): 74 clientID = getattr(s, 'clientID', None) 75 if clientID and clientID / 10000000000L: 76 charID = getattr(s, 'charid', None) 77 userID = getattr(s, 'userid', None) 78 if charID: 79 ret[-clientID] = self.GetClientDisplayString(clientID, charID) 80 elif userID: 81 ret[-clientID] = 'Client #%d (user #%d)' % (clientID, userID) 82 else: 83 ret[-clientID] = 'Client #%d' % clientID 84 85 return ret 86 87 def GetClientDisplayString(self, clientID, charID): 88 return 'Client #%d (char #%d)' % (clientID, charID) 89 90 def Eval(self, code = None, signedCode = None, marshaledCode = None, **params): 91 if machoNet.mode == 'client': 92 return 93 if machoNet.mode == 'client' and signedCode is None: 94 raise RuntimeError('Eval Failed - Must sign code for clients') 95 if marshaledCode is not None: 96 code = marshal.loads(marshaledCode) 97 if signedCode is not None: 98 marshaledCode, verified = Crypto.Verify(signedCode) 99 if not verified: 100 raise RuntimeError('Eval Failed - Signature Verification Failure') 101 code = marshal.loads(marshaledCode) 102 if not hasattr(session, 'debugContext'): 103 session.__dict__['debugContext'] = {'__name__': 'debugContext', 104 '__builtins__': __builtins__} 105 session.debugContext.update(params) 106 return eval(code, session.debugContext) 107 108 def OnDebugLog(self, txt, lvl, isClient): 109 if isClient and not machoNet.mode == 'client': 110 return 111 self.Log(txt, lvl) 112 113 def Exec(self, code = None, signedCode = None, node = None, console = False, noprompt = False, **params): 114 if machoNet.mode == 'client': 115 return 116 svc = None 117 if node is not None: 118 try: 119 lnode = node.lower() 120 except AttributeError: 121 pass 122 else: 123 if lnode == 'remote': 124 if boot.role == 'server': 125 svc, many = self.session.ConnectToRemoteService('debug', random.choice(sm.services['machoNet'].GetConnectedProxyNodes())), False 126 else: 127 svc, many = self.session.ConnectToRemoteService('debug'), False 128 elif lnode == 'proxies': 129 svc, many = self.session.ConnectToAllProxyServerServices('debug'), True 130 elif lnode == 'servers': 131 svc, many = self.session.ConnectToAllSolServerServices('debug'), True 132 elif lnode == 'all': 133 svc, many = self.session.ConnectToAllServices('debug'), True 134 elif lnode == 'local': 135 svc = 0 136 137 try: 138 lnode = long(node) 139 except ValueError: 140 pass 141 else: 142 if lnode < 0: 143 svc, many = self.session.ConnectToClientService('debug', 'clientID', -lnode), False 144 else: 145 svc, many = self.session.ConnectToRemoteService('debug', lnode), False 146 147 if svc is None: 148 raise RuntimeError('Exec failed: Invalid node %s' % repr(node)) 149 if not svc: 150 if machoNet.mode == 'client' and signedCode is None: 151 raise RuntimeError('Exec Failed - Must sign code for clients') 152 if signedCode is not None: 153 code, verified = Crypto.Verify(signedCode) 154 if not verified: 155 raise RuntimeError('Exec Failed - Signature Verification Failure') 156 if console: 157 return self._ExecConsole(code, noprompt) 158 else: 159 return self._Exec(code, params) 160 else: 161 noprompt = many 162 ret = svc.Exec(code, signedCode, None, console, noprompt, **params) 163 if many: 164 ret2 = dict([ (each[1], each[2]) for each in ret ]) 165 return pprint.pformat(ret2) + '\n' 166 return ret 167 168 def _Exec(self, code, params): 169 buffdude = cStringIO.StringIO() 170 temp = (sys.stdout, sys.stderr) 171 sys.stdout = buffdude 172 sys.stderr = buffdude 173 try: 174 if not hasattr(session, 'debugContext'): 175 session.__dict__['debugContext'] = {'__name__': 'debugContext', 176 '__builtins__': __builtins__} 177 session.debugContext.update(params) 178 exec code in session.debugContext 179 except: 180 traceback.print_exc() 181 sys.exc_clear() 182 finally: 183 sys.stdout, sys.stderr = temp 184 185 return buffdude.getvalue() 186 187 def Log(self, txt, lvl): 188 txt = str(txt) 189 lvl = int(lvl) 190 pst = '' 191 if machoNet.mode == 'client': 192 pre = '[ Debug ]' 193 pst = repr(session) 194 else: 195 nodeID = sm.GetService('machoNet').GetNodeID() 196 pre = '[ Debug ] - Node %s - ' % nodeID 197 log.general.Log('%s %s' % (pre, txt), lvl) 198 if pst: 199 log.general.Log(pst, lvl) 200 self.logEvents[blue.os.GetWallclockTimeNow()] = txt 201 202 def GetLogEvents(self): 203 return self.logEvents 204 205 def _ExecConsole(self, text, noprompt): 206 buffdude = Utf8IO() 207 temp = (sys.stdout, sys.stderr) 208 sys.stdout = sys.stderr = buffdude 209 try: 210 if not hasattr(session, 'debugConsole'): 211 session.debugConsole = code.InteractiveConsole() 212 console = session.debugConsole 213 if '\n' in text: 214 symbol = 'exec' 215 if not text.endswith('\n'): 216 text += '\n' 217 else: 218 symbol = 'single' 219 if noprompt: 220 console.push(text, symbol) 221 else: 222 print(text) 223 incomplete = console.push(text, symbol) 224 print('...' if incomplete else '>>>', end=' ') 225 if not noprompt: 226 print('', end=' ') 227 finally: 228 sys.stdout, sys.stderr = temp 229 230 return buffdude.getvalue()