(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
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):
dump = ""
count = 0
@ -243,3 +259,16 @@ def readfileintodict(filename, d):
d[key] = value.strip()
except ValueError:
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.api import coreapi
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
DEFAULT_MAXFD = 1024
@ -786,7 +786,8 @@ class CoreRequestHandler(SocketServer.BaseRequestHandler):
exectime = msg.gettlv(coreapi.CORE_TLV_EXEC_TIME)
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."
if execnum is None:
raise ValueError, "Execute Message is missing execution number."
@ -799,16 +800,23 @@ class CoreRequestHandler(SocketServer.BaseRequestHandler):
except KeyError:
# XXX wait and queue this message to try again later
# XXX maybe this should be done differently
time.sleep(0.125)
self.queuemsg(msg)
return ()
if not msg.flags & coreapi.CORE_API_LOC_FLAG:
time.sleep(0.125)
self.queuemsg(msg)
return ()
else:
pass
# build common TLV items for reply
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_CMD, cmd)
if msg.flags & coreapi.CORE_API_TTY_FLAG:
if nodenum is None:
raise NotImplementedError
# echo back exec message with cmd for spawning interactive terminal
if cmd == "bash":
cmd = "/bin/bash"
@ -825,7 +833,10 @@ class CoreRequestHandler(SocketServer.BaseRequestHandler):
if msg.flags & coreapi.CORE_API_STR_FLAG or \
msg.flags & coreapi.CORE_API_TXT_FLAG:
# 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:
self.info("done exec cmd='%s' with status=%d res=(%d bytes)"
% (cmd, status, len(res)))
@ -839,7 +850,10 @@ class CoreRequestHandler(SocketServer.BaseRequestHandler):
return (reply, )
# execute the command with no response
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 ()