(Boeing r1784,1785)

implement local flag when receiving Execute Message, for running host commands
added checkforkernelmodule helper
This commit is contained in:
ahrenholz 2013-10-22 14:32:42 +00:00
parent d676a9fd59
commit 0fc51e38bf
2 changed files with 51 additions and 8 deletions

View file

@ -100,6 +100,22 @@ def mutedetach(*args, **kwds):
kwds["stderr"] = subprocess.STDOUT kwds["stderr"] = subprocess.STDOUT
return subprocess.Popen(*args, **kwds).pid return subprocess.Popen(*args, **kwds).pid
def cmdresult(args):
''' Execute a command on the host and return a tuple containing the
exit status and result string. stderr output
is folded into the stdout result string.
'''
cmdid = subprocess.Popen(args, stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
cmdid.stdin.close()
result = cmdid.stdout.read()
result += cmdid.stderr.read()
cmdid.stdout.close()
cmdid.stderr.close()
status = cmdid.wait()
return (status, result)
def hexdump(s, bytes_per_word = 2, words_per_line = 8): def hexdump(s, bytes_per_word = 2, words_per_line = 8):
dump = "" dump = ""
count = 0 count = 0
@ -243,3 +259,16 @@ def readfileintodict(filename, d):
d[key] = value.strip() d[key] = value.strip()
except ValueError: except ValueError:
pass pass
def checkforkernelmodule(name):
''' Return a string if a Linux kernel module is loaded, None otherwise.
The string is the line from /proc/modules containing the module name,
memory size (bytes), number of loaded instances, dependencies, state,
and kernel memory offset.
'''
with open('/proc/modules', 'r') as f:
for line in f:
if line[:len(name)] == name:
return line
return None

View file

@ -34,7 +34,7 @@ except ImportError:
from core.constants import * from core.constants import *
from core.api import coreapi from core.api import coreapi
from core.coreobj import PyCoreNet from core.coreobj import PyCoreNet
from core.misc.utils import hexdump, daemonize from core.misc.utils import hexdump, daemonize, cmdresult, mutedetach
from core.misc.xmlutils import opensessionxml, savesessionxml from core.misc.xmlutils import opensessionxml, savesessionxml
DEFAULT_MAXFD = 1024 DEFAULT_MAXFD = 1024
@ -786,7 +786,8 @@ class CoreRequestHandler(SocketServer.BaseRequestHandler):
exectime = msg.gettlv(coreapi.CORE_TLV_EXEC_TIME) exectime = msg.gettlv(coreapi.CORE_TLV_EXEC_TIME)
cmd = msg.gettlv(coreapi.CORE_TLV_EXEC_CMD) cmd = msg.gettlv(coreapi.CORE_TLV_EXEC_CMD)
if nodenum is None: # local flag indicates command executed locally, not on a node
if nodenum is None and not msg.flags & coreapi.CORE_API_LOC_FLAG:
raise ValueError, "Execute Message is missing node number." raise ValueError, "Execute Message is missing node number."
if execnum is None: if execnum is None:
raise ValueError, "Execute Message is missing execution number." raise ValueError, "Execute Message is missing execution number."
@ -799,16 +800,23 @@ class CoreRequestHandler(SocketServer.BaseRequestHandler):
except KeyError: except KeyError:
# XXX wait and queue this message to try again later # XXX wait and queue this message to try again later
# XXX maybe this should be done differently # XXX maybe this should be done differently
time.sleep(0.125) if not msg.flags & coreapi.CORE_API_LOC_FLAG:
self.queuemsg(msg) time.sleep(0.125)
return () self.queuemsg(msg)
return ()
else:
pass
# build common TLV items for reply # build common TLV items for reply
tlvdata = "" tlvdata = ""
tlvdata += coreapi.CoreExecTlv.pack(coreapi.CORE_TLV_EXEC_NODE, nodenum) if nodenum is not None:
tlvdata += coreapi.CoreExecTlv.pack(coreapi.CORE_TLV_EXEC_NODE,
nodenum)
tlvdata += coreapi.CoreExecTlv.pack(coreapi.CORE_TLV_EXEC_NUM, execnum) tlvdata += coreapi.CoreExecTlv.pack(coreapi.CORE_TLV_EXEC_NUM, execnum)
tlvdata += coreapi.CoreExecTlv.pack(coreapi.CORE_TLV_EXEC_CMD, cmd) tlvdata += coreapi.CoreExecTlv.pack(coreapi.CORE_TLV_EXEC_CMD, cmd)
if msg.flags & coreapi.CORE_API_TTY_FLAG: if msg.flags & coreapi.CORE_API_TTY_FLAG:
if nodenum is None:
raise NotImplementedError
# echo back exec message with cmd for spawning interactive terminal # echo back exec message with cmd for spawning interactive terminal
if cmd == "bash": if cmd == "bash":
cmd = "/bin/bash" cmd = "/bin/bash"
@ -825,7 +833,10 @@ class CoreRequestHandler(SocketServer.BaseRequestHandler):
if msg.flags & coreapi.CORE_API_STR_FLAG or \ if msg.flags & coreapi.CORE_API_STR_FLAG or \
msg.flags & coreapi.CORE_API_TXT_FLAG: msg.flags & coreapi.CORE_API_TXT_FLAG:
# shlex.split() handles quotes within the string # shlex.split() handles quotes within the string
status, res = n.cmdresult(shlex.split(cmd)) if msg.flags & coreapi.CORE_API_LOC_FLAG:
status, res = cmdresult(shlex.split(cmd))
else:
status, res = n.cmdresult(shlex.split(cmd))
if self.verbose: if self.verbose:
self.info("done exec cmd='%s' with status=%d res=(%d bytes)" self.info("done exec cmd='%s' with status=%d res=(%d bytes)"
% (cmd, status, len(res))) % (cmd, status, len(res)))
@ -839,7 +850,10 @@ class CoreRequestHandler(SocketServer.BaseRequestHandler):
return (reply, ) return (reply, )
# execute the command with no response # execute the command with no response
else: else:
n.cmd(shlex.split(cmd), wait=False) if msg.flags & coreapi.CORE_API_LOC_FLAG:
mutedetach(shlex.split(cmd))
else:
n.cmd(shlex.split(cmd), wait=False)
return () return ()