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

View file

@ -772,7 +772,8 @@ class EmaneManager(ModelManager):
Kill the appropriate EMANE daemons. 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 # 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 stop_emane_on_host = False
for node in self.getnodes(): for node in self.getnodes():
if hasattr(node, "transport_type") and node.transport_type == "raw": if hasattr(node, "transport_type") and node.transport_type == "raw":
@ -780,13 +781,19 @@ class EmaneManager(ModelManager):
continue continue
if node.up: if node.up:
node.cmd(args, wait=False) node.node_net_cmd(kill_emaned, wait=False)
# TODO: RJ45 node # TODO: RJ45 node
if stop_emane_on_host: if stop_emane_on_host:
try: try:
utils.check_cmd(args) utils.check_cmd(kill_emaned)
utils.check_cmd(["killall", "-q", "emanetransportd"]) 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: except CoreCommandError:
logging.exception("error shutting down emane daemons") 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. Return True if an EMANE process associated with the given node is running, False otherwise.
""" """
args = ["pkill", "-0", "-x", "emane"] args = ["pkill", "-0", "-x", "emane"]
status = node.cmd(args) try:
return status == 0 node.node_net_cmd(args)
result = True
except CoreCommandError:
result = False
return result
class EmaneGlobalModel(EmaneModel): class EmaneGlobalModel(EmaneModel):

View file

@ -10,7 +10,7 @@ from core.errors import CoreCommandError
LOCK = threading.Lock() 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. 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 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 :param str cwd: directory to run command in, defaults to None, which is the user's
home directory home directory
:param bool wait: True to wait for status, False to background process
:return: stdout when success :return: stdout when success
:rtype: str :rtype: str
:raises CoreCommandError: when a non-zero exit status occurs :raises CoreCommandError: when a non-zero exit status occurs
""" """
logging.info("remote cmd server(%s): %s", server, cmd)
replace_env = env is not None 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: try:
with LOCK: with LOCK:
if cwd is None: if cwd is None:

View file

@ -2044,4 +2044,5 @@ class Session(object):
utils.mute_detach(data) utils.mute_detach(data)
else: else:
node = self.get_node(node_id) 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): 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): class CoreError(Exception):

View file

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

View file

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

View file

@ -94,7 +94,7 @@ class PhysicalNode(CoreNodeBase):
return output.strip() return output.strip()
def shcmd(self, cmdstr, sh="/bin/sh"): 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): def sethwaddr(self, ifindex, addr):
""" """

View file

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

View file

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

View file

@ -47,11 +47,11 @@ def example(options):
last_node = session.get_node(options.nodes + 1) last_node = session.get_node(options.nodes + 1)
print("starting iperf server on node: %s" % first_node.name) 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) address = prefixes.ip4_address(first_node)
print("node %s connecting to %s" % (last_node.name, address)) print("node %s connecting to %s" % (last_node.name, address))
last_node.client.icmd(["iperf", "-t", str(options.time), "-c", address]) last_node.node_net_cmd(["iperf", "-t", str(options.time), "-c", address])
first_node.cmd(["killall", "-9", "iperf"]) first_node.node_net_cmd(["killall", "-9", "iperf"])
# shutdown session # shutdown session
coreemu.shutdown() 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): def ping(from_node, to_node, ip_prefixes, count=3):
address = ip_prefixes.ip4_address(to_node) 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: class TestEmane:

View file

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