changes to update commands to leverage either node_net_cmd/net_cmd
This commit is contained in:
parent
bc58693339
commit
f6cdeb23de
13 changed files with 67 additions and 37 deletions
|
@ -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
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Reference in a new issue