changes to update commands to leverage either node_net_cmd/net_cmd

This commit is contained in:
Blake Harnden 2019-10-10 15:25:12 -07:00
parent bc58693339
commit f6cdeb23de
13 changed files with 67 additions and 37 deletions

View file

@ -37,7 +37,7 @@ from core.emulator.enumerations import (
RegisterTlvs,
SessionTlvs,
)
from core.errors import CoreError
from core.errors import CoreCommandError, CoreError
from core.location.mobility import BasicRangeModel
from core.nodes.network import WlanNode
from core.services.coreservices import ServiceManager, ServiceShim
@ -882,16 +882,21 @@ class CoreHandler(socketserver.BaseRequestHandler):
return (reply,)
else:
logging.info("execute message with cmd=%s", command)
command = utils.split_args(command)
# execute command and send a response
if (
message.flags & MessageFlags.STRING.value
or message.flags & MessageFlags.TEXT.value
):
# shlex.split() handles quotes within the string
if message.flags & MessageFlags.LOCAL.value:
status, res = utils.cmd_output(command)
else:
status, res = node.cmd_output(command)
try:
res = node.node_net_cmd(command)
status = 0
except CoreCommandError as e:
res = e.stderr
status = e.returncode
logging.info(
"done exec cmd=%s with status=%d res=(%d bytes)",
command,
@ -913,7 +918,7 @@ class CoreHandler(socketserver.BaseRequestHandler):
if message.flags & MessageFlags.LOCAL.value:
utils.mute_detach(command)
else:
node.cmd(command, wait=False)
node.node_net_cmd(command, wait=False)
except CoreError:
logging.exception("error getting object: %s", node_num)
# XXX wait and queue this message to try again later

View file

@ -772,7 +772,8 @@ class EmaneManager(ModelManager):
Kill the appropriate EMANE daemons.
"""
# TODO: we may want to improve this if we had the PIDs from the specific EMANE daemons that we"ve started
args = ["killall", "-q", "emane"]
kill_emaned = ["killall", "-q", "emane"]
kill_transortd = ["killall", "-q", "emanetransportd"]
stop_emane_on_host = False
for node in self.getnodes():
if hasattr(node, "transport_type") and node.transport_type == "raw":
@ -780,13 +781,19 @@ class EmaneManager(ModelManager):
continue
if node.up:
node.cmd(args, wait=False)
node.node_net_cmd(kill_emaned, wait=False)
# TODO: RJ45 node
if stop_emane_on_host:
try:
utils.check_cmd(args)
utils.check_cmd(["killall", "-q", "emanetransportd"])
utils.check_cmd(kill_emaned)
utils.check_cmd(kill_transortd)
kill_emaned = " ".join(kill_emaned)
kill_transortd = " ".join(kill_transortd)
for server in self.session.servers:
conn = self.session[server]
distributed.remote_cmd(conn, kill_emaned)
distributed.remote_cmd(conn, kill_transortd)
except CoreCommandError:
logging.exception("error shutting down emane daemons")
@ -976,8 +983,13 @@ class EmaneManager(ModelManager):
Return True if an EMANE process associated with the given node is running, False otherwise.
"""
args = ["pkill", "-0", "-x", "emane"]
status = node.cmd(args)
return status == 0
try:
node.node_net_cmd(args)
result = True
except CoreCommandError:
result = False
return result
class EmaneGlobalModel(EmaneModel):

View file

@ -10,7 +10,7 @@ from core.errors import CoreCommandError
LOCK = threading.Lock()
def remote_cmd(server, cmd, env=None, cwd=None):
def remote_cmd(server, cmd, env=None, cwd=None, wait=True):
"""
Run command remotely using server connection.
@ -20,12 +20,18 @@ def remote_cmd(server, cmd, env=None, cwd=None):
:param dict env: environment for remote command, default is None
:param str cwd: directory to run command in, defaults to None, which is the user's
home directory
:param bool wait: True to wait for status, False to background process
:return: stdout when success
:rtype: str
:raises CoreCommandError: when a non-zero exit status occurs
"""
logging.info("remote cmd server(%s): %s", server, cmd)
replace_env = env is not None
if not wait:
cmd += " &"
logging.info(
"remote cmd server(%s) cwd(%s) wait(%s): %s", server.host, cwd, wait, cmd
)
try:
with LOCK:
if cwd is None:

View file

@ -2044,4 +2044,5 @@ class Session(object):
utils.mute_detach(data)
else:
node = self.get_node(node_id)
node.cmd(data, wait=False)
data = utils.split_args(data)
node.node_net_cmd(data, wait=False)

View file

@ -10,7 +10,12 @@ class CoreCommandError(subprocess.CalledProcessError):
"""
def __str__(self):
return "Command(%s), Status(%s):\n%s" % (self.cmd, self.returncode, self.output)
return "Command(%s), Status(%s):\nstdout: %s\nstderr: %s" % (
self.cmd,
self.returncode,
self.output,
self.stderr,
)
class CoreError(Exception):

View file

@ -630,29 +630,31 @@ class CoreNode(CoreNodeBase):
"""
return self.client.cmd_output(args)
def node_net_cmd(self, args):
def node_net_cmd(self, args, wait=True):
"""
Runs a command that is used to configure and setup the network within a
node.
:param list[str]|str args: command to run
:param list[str] args: command to run
:param bool wait: True to wait for status, False otherwise
:return: combined stdout and stderr
:rtype: str
:raises CoreCommandError: when a non-zero exit status occurs
"""
if self.server is None:
logging.info("node(%s) cmd: %s", self.name, args)
return self.check_cmd(args)
return self.client.check_cmd(args, wait=wait)
else:
args = self.client._cmd_args() + args
args = " ".join(args)
return distributed.remote_cmd(self.server, args)
return distributed.remote_cmd(self.server, args, wait=wait)
def check_cmd(self, args):
"""
Runs shell command on node.
:param list[str]|str args: command to run
:param bool wait: True to wait for status, False otherwise
:return: combined stdout and stderr
:rtype: str
:raises CoreCommandError: when a non-zero exit status occurs

View file

@ -97,17 +97,18 @@ class VnodeClient(object):
status = p.wait()
return status, output.decode("utf-8").strip()
def check_cmd(self, args):
def check_cmd(self, args, wait=True):
"""
Run command and return exit status and combined stdout and stderr.
:param list[str]|str args: command to run
:param bool wait: True to wait for command status, False otherwise
:return: combined stdout and stderr
:rtype: str
:raises core.CoreCommandError: when there is a non-zero exit status
"""
status, output = self.cmd_output(args)
if status != 0:
if wait and status != 0:
raise CoreCommandError(status, args, output)
return output.strip()

View file

@ -94,7 +94,7 @@ class PhysicalNode(CoreNodeBase):
return output.strip()
def shcmd(self, cmdstr, sh="/bin/sh"):
return self.cmd([sh, "-c", cmdstr])
return self.node_net_cmd([sh, "-c", cmdstr])
def sethwaddr(self, ifindex, addr):
"""

View file

@ -9,7 +9,6 @@ services.
import enum
import logging
import shlex
import time
from multiprocessing.pool import ThreadPool
@ -598,7 +597,7 @@ class CoreServices(object):
status = 0
for cmd in cmds:
logging.debug("validating service(%s) using: %s", service.name, cmd)
cmd = shlex.split(cmd)
cmd = utils.split_args(cmd)
try:
node.node_net_cmd(cmd)
except CoreCommandError as e:
@ -730,11 +729,9 @@ class CoreServices(object):
status = 0
for cmd in cmds:
cmd = shlex.split(cmd)
cmd = utils.split_args(cmd)
try:
if wait:
cmd.append("&")
node.node_net_cmd(cmd)
node.node_net_cmd(cmd, wait)
except CoreCommandError:
logging.exception("error starting command")
status = -1

View file

@ -43,11 +43,14 @@ def example(options):
last_node = session.get_node(options.nodes + 1)
print("starting iperf server on node: %s" % first_node.name)
first_node.cmd(["iperf", "-s", "-D"])
first_node.node_net_cmd(["iperf", "-s", "-D"])
first_node_address = prefixes.ip4_address(first_node)
print("node %s connecting to %s" % (last_node.name, first_node_address))
last_node.client.icmd(["iperf", "-t", str(options.time), "-c", first_node_address])
first_node.cmd(["killall", "-9", "iperf"])
output = last_node.node_net_cmd(
["iperf", "-t", str(options.time), "-c", first_node_address]
)
print(output)
first_node.node_net_cmd(["killall", "-9", "iperf"])
# shutdown session
coreemu.shutdown()

View file

@ -47,11 +47,11 @@ def example(options):
last_node = session.get_node(options.nodes + 1)
print("starting iperf server on node: %s" % first_node.name)
first_node.cmd(["iperf", "-s", "-D"])
first_node.node_net_cmd(["iperf", "-s", "-D"])
address = prefixes.ip4_address(first_node)
print("node %s connecting to %s" % (last_node.name, address))
last_node.client.icmd(["iperf", "-t", str(options.time), "-c", address])
first_node.cmd(["killall", "-9", "iperf"])
last_node.node_net_cmd(["iperf", "-t", str(options.time), "-c", address])
first_node.node_net_cmd(["killall", "-9", "iperf"])
# shutdown session
coreemu.shutdown()

View file

@ -26,7 +26,7 @@ _DIR = os.path.dirname(os.path.abspath(__file__))
def ping(from_node, to_node, ip_prefixes, count=3):
address = ip_prefixes.ip4_address(to_node)
return from_node.cmd(["ping", "-c", str(count), address])
return from_node.node_net_cmd(["ping", "-c", str(count), address])
class TestEmane:

View file

@ -38,7 +38,7 @@ def createclients(sessiondir, clientcls=VnodeClient, cmdchnlfilterfunc=None):
def ping(from_node, to_node, ip_prefixes):
address = ip_prefixes.ip4_address(to_node)
return from_node.cmd(["ping", "-c", "3", address])
return from_node.node_net_cmd(["ping", "-c", "3", address])
class TestCore:
@ -102,7 +102,6 @@ class TestCore:
# check various command using vcmd module
command = ["ls"]
assert not client.cmd(command)
status, output = client.cmd_output(command)
assert not status
p, stdin, stdout, stderr = client.popen(command)
@ -110,7 +109,6 @@ class TestCore:
assert not client.icmd(command)
# check various command using command line
assert not client.cmd(command)
status, output = client.cmd_output(command)
assert not status
p, stdin, stdout, stderr = client.popen(command)