further cleanup in regards the commands that are being used within core
This commit is contained in:
parent
870d87804b
commit
6211b09585
15 changed files with 322 additions and 316 deletions
|
@ -412,33 +412,33 @@ class PyCoreNode(PyCoreObj):
|
|||
|
||||
return common
|
||||
|
||||
def check_cmd(self, cmd):
|
||||
def check_cmd(self, args):
|
||||
"""
|
||||
Runs shell command on node.
|
||||
|
||||
:param list[str]/str cmd: command to run
|
||||
:param list[str]|str args: command to run
|
||||
:return: exist status and combined stdout and stderr
|
||||
:rtype: tuple[int, str]
|
||||
:raises subprocess.CalledProcessError: when a non-zero exit status occurs
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def cmd(self, cmd, wait=True):
|
||||
def cmd(self, args, wait=True):
|
||||
"""
|
||||
Runs shell command on node, with option to not wait for a result.
|
||||
|
||||
:param list[str]/str cmd: command to run
|
||||
:param list[str]|str args: command to run
|
||||
:param bool wait: wait for command to exit, defaults to True
|
||||
:return: exit status for command
|
||||
:rtype: int
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def cmd_output(self, cmd):
|
||||
def cmd_output(self, args):
|
||||
"""
|
||||
Runs shell command on node and get exit status and output.
|
||||
|
||||
:param list[str]/str cmd: command to run
|
||||
:param list[str]|str args: command to run
|
||||
:return: exit status and combined stdout and stderr
|
||||
:rtype: tuple[int, str]
|
||||
"""
|
||||
|
|
|
@ -21,11 +21,11 @@ def emane_version():
|
|||
"""
|
||||
global VERSION
|
||||
global VERSIONSTR
|
||||
cmd = ("emane", "--version")
|
||||
args = ("emane", "--version")
|
||||
|
||||
try:
|
||||
status, result = utils.cmd_output(cmd)
|
||||
except (OSError, subprocess.CalledProcessError):
|
||||
status, result = utils.check_cmd(args)
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("error checking emane version")
|
||||
status = -1
|
||||
result = ""
|
||||
|
|
|
@ -788,7 +788,7 @@ class EmaneManager(ConfigurableManager):
|
|||
the transportdaemon*.xml.
|
||||
"""
|
||||
try:
|
||||
subprocess.check_call(["emanegentransportxml", "platform.xml"], cwd=self.session.session_dir)
|
||||
utils.check_cmd(["emanegentransportxml", "platform.xml"], cwd=self.session.session_dir)
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("error running emanegentransportxml")
|
||||
|
||||
|
@ -845,23 +845,23 @@ class EmaneManager(ConfigurableManager):
|
|||
if realtime:
|
||||
emanecmd += "-r",
|
||||
try:
|
||||
cmd = emanecmd + [os.path.join(path, "platform.xml")]
|
||||
logger.info("Emane.startdaemons() running %s" % str(cmd))
|
||||
subprocess.check_call(cmd, cwd=path)
|
||||
args = emanecmd + [os.path.join(path, "platform.xml")]
|
||||
logger.info("Emane.startdaemons() running %s" % str(args))
|
||||
utils.check_cmd(args, cwd=path)
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("error starting emane")
|
||||
|
||||
# start one transport daemon per transportdaemon*.xml file
|
||||
transcmd = ["emanetransportd", "-d", "--logl", loglevel, "-f", os.path.join(path, "emanetransportd.log")]
|
||||
args = ["emanetransportd", "-d", "--logl", loglevel, "-f", os.path.join(path, "emanetransportd.log")]
|
||||
if realtime:
|
||||
transcmd += "-r",
|
||||
args += "-r",
|
||||
files = os.listdir(path)
|
||||
for file in files:
|
||||
if file[-3:] == "xml" and file[:15] == "transportdaemon":
|
||||
cmd = transcmd + [os.path.join(path, file)]
|
||||
args = args + [os.path.join(path, file)]
|
||||
try:
|
||||
logger.info("Emane.startdaemons() running %s" % str(cmd))
|
||||
subprocess.check_call(cmd, cwd=path)
|
||||
logger.info("Emane.startdaemons() running %s" % str(args))
|
||||
utils.check_cmd(args, cwd=path)
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("error starting emanetransportd")
|
||||
|
||||
|
@ -910,24 +910,24 @@ class EmaneManager(ConfigurableManager):
|
|||
self.session.add_remove_control_interface(node, eventservicenetidx, remove=False, conf_required=False)
|
||||
|
||||
# multicast route is needed for OTA data
|
||||
cmd = [constants.IP_BIN, "route", "add", otagroup, "dev", otadev]
|
||||
args = [constants.IP_BIN, "route", "add", otagroup, "dev", otadev]
|
||||
try:
|
||||
node.check_cmd(cmd)
|
||||
node.check_cmd(args)
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("error adding route for OTA data")
|
||||
|
||||
# multicast route is also needed for event data if on control network
|
||||
if eventservicenetidx >= 0 and eventgroup != otagroup:
|
||||
cmd = [constants.IP_BIN, "route", "add", eventgroup, "dev", eventdev]
|
||||
args = [constants.IP_BIN, "route", "add", eventgroup, "dev", eventdev]
|
||||
try:
|
||||
node.check_cmd(cmd)
|
||||
node.check_cmd(args)
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("error adding route for event data")
|
||||
|
||||
try:
|
||||
cmd = emanecmd + ["-f", os.path.join(path, "emane%d.log" % n), os.path.join(path, "platform%d.xml" % n)]
|
||||
logger.info("Emane.startdaemons2() running %s" % str(cmd))
|
||||
status, output = node.check_cmd(cmd)
|
||||
args = emanecmd + ["-f", os.path.join(path, "emane%d.log" % n), os.path.join(path, "platform%d.xml" % n)]
|
||||
logger.info("Emane.startdaemons2() running %s" % str(args))
|
||||
status, output = node.check_cmd(args)
|
||||
logger.info("Emane.startdaemons2() return code %d" % status)
|
||||
logger.info("Emane.startdaemons2() output: %s" % output)
|
||||
except subprocess.CalledProcessError:
|
||||
|
@ -939,9 +939,9 @@ class EmaneManager(ConfigurableManager):
|
|||
path = self.session.session_dir
|
||||
try:
|
||||
emanecmd += ["-f", os.path.join(path, "emane.log")]
|
||||
cmd = emanecmd + [os.path.join(path, "platform.xml")]
|
||||
logger.info("Emane.startdaemons2() running %s" % cmd)
|
||||
utils.check_cmd(cmd, cwd=path)
|
||||
args = emanecmd + [os.path.join(path, "platform.xml")]
|
||||
logger.info("Emane.startdaemons2() running %s" % args)
|
||||
utils.check_cmd(args, cwd=path)
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("error starting emane")
|
||||
|
||||
|
@ -951,7 +951,7 @@ class EmaneManager(ConfigurableManager):
|
|||
"""
|
||||
# TODO: we may want to improve this if we had the PIDs from the
|
||||
# specific EMANE daemons that we"ve started
|
||||
cmd = ["killall", "-q", "emane"]
|
||||
args = ["killall", "-q", "emane"]
|
||||
stop_emane_on_host = False
|
||||
if emane.VERSION > emane.EMANE091:
|
||||
for node in self.getnodes():
|
||||
|
@ -960,13 +960,17 @@ class EmaneManager(ConfigurableManager):
|
|||
stop_emane_on_host = True
|
||||
continue
|
||||
if node.up:
|
||||
node.cmd(cmd, wait=False)
|
||||
node.cmd(args, wait=False)
|
||||
# TODO: RJ45 node
|
||||
else:
|
||||
stop_emane_on_host = True
|
||||
|
||||
if stop_emane_on_host:
|
||||
subprocess.call(cmd)
|
||||
subprocess.call(["killall", "-q", "emanetransportd"])
|
||||
try:
|
||||
utils.check_cmd(args)
|
||||
utils.check_cmd(["killall", "-q", "emanetransportd"])
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("error shutting down emane daemons")
|
||||
|
||||
def installnetifs(self, do_netns=True):
|
||||
"""
|
||||
|
@ -1160,13 +1164,13 @@ class EmaneManager(ConfigurableManager):
|
|||
is running, False otherwise.
|
||||
"""
|
||||
status = -1
|
||||
cmd = ["pkill", "-0", "-x", "emane"]
|
||||
args = ["pkill", "-0", "-x", "emane"]
|
||||
|
||||
try:
|
||||
if emane.VERSION < emane.EMANE092:
|
||||
status = subprocess.check_call(cmd)
|
||||
status = utils.check_cmd(args)
|
||||
else:
|
||||
status, _ = node.check_cmd(cmd)
|
||||
status, _ = node.check_cmd(args)
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("error checking if emane is running")
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@ import resource
|
|||
|
||||
from core import logger
|
||||
|
||||
DEVNULL = open(os.devnull, "wb")
|
||||
|
||||
|
||||
def closeonexec(fd):
|
||||
"""
|
||||
|
@ -112,18 +114,18 @@ def maketuplefromstr(s, value_type):
|
|||
return tuple(value_type(i) for i in values)
|
||||
|
||||
|
||||
def split_cmd(cmd):
|
||||
def split_args(args):
|
||||
"""
|
||||
Convenience method for splitting potential string commands into a shell-like syntax list.
|
||||
|
||||
:param list/str cmd: command list or string
|
||||
:param list/str args: command list or string
|
||||
:return: shell-like syntax list
|
||||
:rtype: list
|
||||
"""
|
||||
# split shell string to shell array for convenience
|
||||
if type(cmd) == str:
|
||||
cmd = shlex.split(cmd)
|
||||
return cmd
|
||||
if type(args) == str:
|
||||
args = shlex.split(args)
|
||||
return args
|
||||
|
||||
|
||||
def mutecall(*args, **kwargs):
|
||||
|
@ -135,25 +137,11 @@ def mutecall(*args, **kwargs):
|
|||
:return: command result
|
||||
:rtype: int
|
||||
"""
|
||||
kwargs["stdout"] = open(os.devnull, "w")
|
||||
kwargs["stdout"] = DEVNULL
|
||||
kwargs["stderr"] = subprocess.STDOUT
|
||||
return subprocess.call(*args, **kwargs)
|
||||
|
||||
|
||||
def check_alloutput(cmd, **kwargs):
|
||||
"""
|
||||
Convenience wrapper to run subprocess.check_output and include stderr as well.
|
||||
|
||||
:param list[str]/str cmd: command arguments to run
|
||||
:param dict kwargs: option for running subprocess.check_output, beyond setting stderr to stdout
|
||||
:return: combined stdout and stderr
|
||||
:raises subprocess.CalledProcessError: when a non-zero exit status is encountered
|
||||
"""
|
||||
cmd = split_cmd(cmd)
|
||||
kwargs["stderr"] = subprocess.STDOUT
|
||||
return subprocess.check_output(cmd, **kwargs)
|
||||
|
||||
|
||||
def mutecheck_call(*args, **kwargs):
|
||||
"""
|
||||
Run a muted check call command.
|
||||
|
@ -163,7 +151,7 @@ def mutecheck_call(*args, **kwargs):
|
|||
:return: command result
|
||||
:rtype: int
|
||||
"""
|
||||
kwargs["stdout"] = open(os.devnull, "w")
|
||||
kwargs["stdout"] = DEVNULL
|
||||
kwargs["stderr"] = subprocess.STDOUT
|
||||
return subprocess.check_call(*args, **kwargs)
|
||||
|
||||
|
@ -189,7 +177,7 @@ def mutespawn(*args, **kwargs):
|
|||
:return: process id of the command
|
||||
:rtype: int
|
||||
"""
|
||||
kwargs["stdout"] = open(os.devnull, "w")
|
||||
kwargs["stdout"] = DEVNULL
|
||||
kwargs["stderr"] = subprocess.STDOUT
|
||||
return subprocess.Popen(*args, **kwargs).pid
|
||||
|
||||
|
@ -229,48 +217,73 @@ def mutedetach(*args, **kwargs):
|
|||
:rtype: int
|
||||
"""
|
||||
kwargs["preexec_fn"] = detachinit
|
||||
kwargs["stdout"] = open(os.devnull, "w")
|
||||
kwargs["stdout"] = DEVNULL
|
||||
kwargs["stderr"] = subprocess.STDOUT
|
||||
return subprocess.Popen(*args, **kwargs).pid
|
||||
|
||||
|
||||
def cmd_output(cmd):
|
||||
def cmd(args, wait=True):
|
||||
"""
|
||||
Runs a command on and returns the exit status.
|
||||
|
||||
:param list[str]|str args: command arguments
|
||||
:param bool wait: wait for command to end or not
|
||||
:return: command status
|
||||
:rtype: int
|
||||
"""
|
||||
args = split_args(args)
|
||||
try:
|
||||
p = subprocess.Popen(args)
|
||||
if not wait:
|
||||
return 0
|
||||
return p.wait()
|
||||
except OSError:
|
||||
raise subprocess.CalledProcessError(-1, args)
|
||||
|
||||
|
||||
def cmd_output(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.
|
||||
|
||||
:param list[str]/str cmd: command arguments
|
||||
:param list[str]|str args: command arguments
|
||||
:return: command status and stdout
|
||||
:rtype: tuple[int, str]
|
||||
:raises subprocess.CalledProcessError: when the file to execute is not found
|
||||
"""
|
||||
# split shell string to shell array for convenience
|
||||
cmd = split_cmd(cmd)
|
||||
p = subprocess.Popen(cmd, stdin=open(os.devnull, "r"), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
stdout, _ = p.communicate()
|
||||
status = p.wait()
|
||||
return status, stdout
|
||||
args = split_args(args)
|
||||
try:
|
||||
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
stdout, _ = p.communicate()
|
||||
status = p.wait()
|
||||
return status, stdout
|
||||
except OSError:
|
||||
raise subprocess.CalledProcessError(-1, args)
|
||||
|
||||
|
||||
def check_cmd(cmd, **kwargs):
|
||||
def check_cmd(args, **kwargs):
|
||||
"""
|
||||
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.
|
||||
|
||||
:param list[str]/str cmd: command arguments
|
||||
:param list[str]|str args: command arguments
|
||||
:param dict kwargs: keyword arguments to pass to subprocess.Popen
|
||||
:return: command status and stdout
|
||||
:rtype: tuple[int, str]
|
||||
:raises subprocess.CalledProcessError: when there is a non-zero exit status
|
||||
:raises subprocess.CalledProcessError: when there is a non-zero exit status or the file to execute is not found
|
||||
"""
|
||||
kwargs["stdout"] = subprocess.PIPE
|
||||
kwargs["stderr"] = subprocess.STDOUT
|
||||
cmd = split_cmd(cmd)
|
||||
p = subprocess.Popen(cmd, **kwargs)
|
||||
stdout, _ = p.communicate()
|
||||
status = p.wait()
|
||||
if status:
|
||||
raise subprocess.CalledProcessError(status, cmd, stdout)
|
||||
return status, stdout
|
||||
args = split_args(args)
|
||||
try:
|
||||
p = subprocess.Popen(args, **kwargs)
|
||||
stdout, _ = p.communicate()
|
||||
status = p.wait()
|
||||
if status:
|
||||
raise subprocess.CalledProcessError(status, args, stdout)
|
||||
return status, stdout
|
||||
except OSError:
|
||||
raise subprocess.CalledProcessError(-1, args)
|
||||
|
||||
|
||||
def hexdump(s, bytes_per_word=2, words_per_line=8):
|
||||
|
|
|
@ -21,6 +21,7 @@ from core.enumerations import MessageFlags
|
|||
from core.enumerations import MessageTypes
|
||||
from core.enumerations import NodeTlvs
|
||||
from core.enumerations import RegisterTlvs
|
||||
from core.misc import utils
|
||||
from core.misc.ipaddress import IpAddress
|
||||
|
||||
|
||||
|
@ -1238,10 +1239,7 @@ class Ns2ScriptedMobility(WayPointMobility):
|
|||
return
|
||||
filename = self.findfile(filename)
|
||||
try:
|
||||
subprocess.check_call(
|
||||
["/bin/sh", filename, typestr],
|
||||
cwd=self.session.sessiondir,
|
||||
env=self.session.get_environment()
|
||||
)
|
||||
args = ["/bin/sh", filename, typestr]
|
||||
utils.check_cmd(args, cwd=self.session.sessiondir, env=self.session.get_environment())
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("Error running script '%s' for WLAN state %s", filename, typestr)
|
||||
|
|
|
@ -73,26 +73,31 @@ class CtrlNet(LxBrNet):
|
|||
return
|
||||
|
||||
LxBrNet.startup(self)
|
||||
|
||||
if self.hostid:
|
||||
addr = self.prefix.addr(self.hostid)
|
||||
else:
|
||||
addr = self.prefix.max_addr()
|
||||
|
||||
msg = "Added control network bridge: %s %s" % (self.brname, self.prefix)
|
||||
addrlist = ["%s/%s" % (addr, self.prefix.prefixlen)]
|
||||
|
||||
if self.assign_address:
|
||||
self.addrconfig(addrlist=addrlist)
|
||||
msg += " address %s" % addr
|
||||
logger.info(msg)
|
||||
|
||||
if self.updown_script is not None:
|
||||
logger.info("interface %s updown script (%s startup) called",
|
||||
self.brname, self.updown_script)
|
||||
subprocess.check_call([self.updown_script, self.brname, "startup"])
|
||||
utils.check_cmd([self.updown_script, self.brname, "startup"])
|
||||
|
||||
if self.serverintf is not None:
|
||||
try:
|
||||
subprocess.check_call([constants.BRCTL_BIN, "addif", self.brname, self.serverintf])
|
||||
subprocess.check_call([constants.IP_BIN, "link", "set", self.serverintf, "up"])
|
||||
utils.check_cmd([constants.BRCTL_BIN, "addif", self.brname, self.serverintf])
|
||||
utils.check_cmd([constants.IP_BIN, "link", "set", self.serverintf, "up"])
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("Error joining server interface %s to controlnet bridge %s",
|
||||
logger.exception("error joining server interface %s to controlnet bridge %s",
|
||||
self.serverintf, self.brname)
|
||||
|
||||
def detectoldbridge(self):
|
||||
|
@ -103,32 +108,24 @@ class CtrlNet(LxBrNet):
|
|||
:return: True if an old bridge was detected, False otherwise
|
||||
:rtype: bool
|
||||
"""
|
||||
retstat, retstr = utils.cmd_output([constants.BRCTL_BIN, "show"])
|
||||
if retstat != 0:
|
||||
status, output = utils.cmd_output([constants.BRCTL_BIN, "show"])
|
||||
if status != 0:
|
||||
logger.error("Unable to retrieve list of installed bridges")
|
||||
lines = retstr.split("\n")
|
||||
for line in lines[1:]:
|
||||
cols = line.split("\t")
|
||||
oldbr = cols[0]
|
||||
flds = cols[0].split(".")
|
||||
if len(flds) == 3:
|
||||
if flds[0] == "b" and flds[1] == self.objid:
|
||||
logger.error(
|
||||
"Error: An active control net bridge (%s) found. " \
|
||||
"An older session might still be running. " \
|
||||
"Stop all sessions and, if needed, delete %s to continue." % \
|
||||
(oldbr, oldbr)
|
||||
)
|
||||
return True
|
||||
"""
|
||||
# Do this if we want to delete the old bridge
|
||||
logger.warn("Warning: Old %s bridge found: %s" % (self.objid, oldbr))
|
||||
try:
|
||||
check_call([BRCTL_BIN, "delbr", oldbr])
|
||||
except subprocess.CalledProcessError as e:
|
||||
logger.exception("Error deleting old bridge %s", oldbr, e)
|
||||
logger.info("Deleted %s", oldbr)
|
||||
"""
|
||||
else:
|
||||
lines = output.split("\n")
|
||||
for line in lines[1:]:
|
||||
cols = line.split("\t")
|
||||
oldbr = cols[0]
|
||||
flds = cols[0].split(".")
|
||||
if len(flds) == 3:
|
||||
if flds[0] == "b" and flds[1] == self.objid:
|
||||
logger.error(
|
||||
"Error: An active control net bridge (%s) found. "
|
||||
"An older session might still be running. "
|
||||
"Stop all sessions and, if needed, delete %s to continue." %
|
||||
(oldbr, oldbr)
|
||||
)
|
||||
return True
|
||||
return False
|
||||
|
||||
def shutdown(self):
|
||||
|
@ -139,14 +136,14 @@ class CtrlNet(LxBrNet):
|
|||
"""
|
||||
if self.serverintf is not None:
|
||||
try:
|
||||
subprocess.check_call([constants.BRCTL_BIN, "delif", self.brname, self.serverintf])
|
||||
utils.check_cmd([constants.BRCTL_BIN, "delif", self.brname, self.serverintf])
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("Error deleting server interface %s to controlnet bridge %s",
|
||||
logger.exception("error deleting server interface %s to controlnet bridge %s",
|
||||
self.serverintf, self.brname)
|
||||
|
||||
if self.updown_script is not None:
|
||||
logger.info("interface %s updown script (%s shutdown) called" % (self.brname, self.updown_script))
|
||||
subprocess.check_call([self.updown_script, self.brname, "shutdown"])
|
||||
utils.check_cmd([self.updown_script, self.brname, "shutdown"])
|
||||
LxBrNet.shutdown(self)
|
||||
|
||||
def all_link_data(self, flags):
|
||||
|
@ -324,7 +321,7 @@ class HubNode(LxBrNet):
|
|||
"""
|
||||
LxBrNet.__init__(self, session, objid, name, start)
|
||||
if start:
|
||||
subprocess.check_call([constants.BRCTL_BIN, "setageing", self.brname, "0"])
|
||||
utils.check_cmd([constants.BRCTL_BIN, "setageing", self.brname, "0"])
|
||||
|
||||
|
||||
class WlanNode(LxBrNet):
|
||||
|
@ -457,6 +454,8 @@ class RJ45Node(PyCoreNode, PyCoreNetIf):
|
|||
# the following are PyCoreNetIf attributes
|
||||
self.transport_type = "raw"
|
||||
self.localname = name
|
||||
self.old_up = False
|
||||
self.old_addrs = []
|
||||
if start:
|
||||
self.startup()
|
||||
|
||||
|
@ -470,7 +469,7 @@ class RJ45Node(PyCoreNode, PyCoreNetIf):
|
|||
self.savestate()
|
||||
|
||||
try:
|
||||
subprocess.check_call([constants.IP_BIN, "link", "set", self.localname, "up"])
|
||||
utils.check_cmd([constants.IP_BIN, "link", "set", self.localname, "up"])
|
||||
self.up = True
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("failed to run command: %s link set %s up", constants.IP_BIN, self.localname)
|
||||
|
@ -484,9 +483,14 @@ class RJ45Node(PyCoreNode, PyCoreNetIf):
|
|||
"""
|
||||
if not self.up:
|
||||
return
|
||||
subprocess.check_call([constants.IP_BIN, "link", "set", self.localname, "down"])
|
||||
subprocess.check_call([constants.IP_BIN, "addr", "flush", "dev", self.localname])
|
||||
utils.mutecall([constants.TC_BIN, "qdisc", "del", "dev", self.localname, "root"])
|
||||
|
||||
try:
|
||||
utils.check_cmd([constants.IP_BIN, "link", "set", self.localname, "down"])
|
||||
utils.check_cmd([constants.IP_BIN, "addr", "flush", "dev", self.localname])
|
||||
utils.mutecall([constants.TC_BIN, "qdisc", "del", "dev", self.localname, "root"])
|
||||
except subprocess.CalledProcessError as e:
|
||||
logger.exception("error shutting down: %s", e.output)
|
||||
|
||||
self.up = False
|
||||
self.restorestate()
|
||||
|
||||
|
@ -604,7 +608,7 @@ class RJ45Node(PyCoreNode, PyCoreNetIf):
|
|||
:return: nothing
|
||||
"""
|
||||
if self.up:
|
||||
subprocess.check_call([constants.IP_BIN, "addr", "add", str(addr), "dev", self.name])
|
||||
utils.check_cmd([constants.IP_BIN, "addr", "add", str(addr), "dev", self.name])
|
||||
PyCoreNetIf.addaddr(self, addr)
|
||||
|
||||
def deladdr(self, addr):
|
||||
|
@ -615,7 +619,7 @@ class RJ45Node(PyCoreNode, PyCoreNetIf):
|
|||
:return: nothing
|
||||
"""
|
||||
if self.up:
|
||||
subprocess.check_call([constants.IP_BIN, "addr", "del", str(addr), "dev", self.name])
|
||||
utils.check_cmd([constants.IP_BIN, "addr", "del", str(addr), "dev", self.name])
|
||||
PyCoreNetIf.deladdr(self, addr)
|
||||
|
||||
def savestate(self):
|
||||
|
@ -627,30 +631,26 @@ class RJ45Node(PyCoreNode, PyCoreNetIf):
|
|||
"""
|
||||
self.old_up = False
|
||||
self.old_addrs = []
|
||||
cmd = [constants.IP_BIN, "addr", "show", "dev", self.localname]
|
||||
args = [constants.IP_BIN, "addr", "show", "dev", self.localname]
|
||||
try:
|
||||
tmp = subprocess.Popen(cmd, stdout=subprocess.PIPE)
|
||||
except OSError:
|
||||
logger.exception("Failed to run %s command: %s", constants.IP_BIN, cmd)
|
||||
if tmp.wait():
|
||||
logger.warn("Command failed: %s", cmd)
|
||||
return
|
||||
lines = tmp.stdout.read()
|
||||
tmp.stdout.close()
|
||||
for l in lines.split("\n"):
|
||||
items = l.split()
|
||||
if len(items) < 2:
|
||||
continue
|
||||
if items[1] == "%s:" % self.localname:
|
||||
flags = items[2][1:-1].split(",")
|
||||
if "UP" in flags:
|
||||
self.old_up = True
|
||||
elif items[0] == "inet":
|
||||
self.old_addrs.append((items[1], items[3]))
|
||||
elif items[0] == "inet6":
|
||||
if items[1][:4] == "fe80":
|
||||
_, output = utils.check_cmd(args)
|
||||
for line in output.split("\n"):
|
||||
items = line.split()
|
||||
if len(items) < 2:
|
||||
continue
|
||||
self.old_addrs.append((items[1], None))
|
||||
|
||||
if items[1] == "%s:" % self.localname:
|
||||
flags = items[2][1:-1].split(",")
|
||||
if "UP" in flags:
|
||||
self.old_up = True
|
||||
elif items[0] == "inet":
|
||||
self.old_addrs.append((items[1], items[3]))
|
||||
elif items[0] == "inet6":
|
||||
if items[1][:4] == "fe80":
|
||||
continue
|
||||
self.old_addrs.append((items[1], None))
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("error during save state")
|
||||
|
||||
def restorestate(self):
|
||||
"""
|
||||
|
@ -660,11 +660,12 @@ class RJ45Node(PyCoreNode, PyCoreNetIf):
|
|||
"""
|
||||
for addr in self.old_addrs:
|
||||
if addr[1] is None:
|
||||
subprocess.check_call([constants.IP_BIN, "addr", "add", addr[0], "dev", self.localname])
|
||||
utils.check_cmd([constants.IP_BIN, "addr", "add", addr[0], "dev", self.localname])
|
||||
else:
|
||||
subprocess.check_call([constants.IP_BIN, "addr", "add", addr[0], "brd", addr[1], "dev", self.localname])
|
||||
utils.check_cmd([constants.IP_BIN, "addr", "add", addr[0], "brd", addr[1], "dev", self.localname])
|
||||
|
||||
if self.old_up:
|
||||
subprocess.check_call([constants.IP_BIN, "link", "set", self.localname, "up"])
|
||||
utils.check_cmd([constants.IP_BIN, "link", "set", self.localname, "up"])
|
||||
|
||||
def setposition(self, x=None, y=None, z=None):
|
||||
"""
|
||||
|
|
|
@ -82,18 +82,18 @@ class OvsNet(PyCoreNet):
|
|||
|
||||
def startup(self):
|
||||
try:
|
||||
subprocess.check_call([constants.OVS_BIN, "add-br", self.bridge_name])
|
||||
utils.check_cmd([constants.OVS_BIN, "add-br", self.bridge_name])
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("error adding bridge")
|
||||
|
||||
try:
|
||||
# turn off spanning tree protocol and forwarding delay
|
||||
# TODO: appears stp and rstp are off by default, make sure this always holds true
|
||||
# TODO: apears ovs only supports rstp forward delay and again it"s off by default
|
||||
subprocess.check_call([constants.IP_BIN, "link", "set", self.bridge_name, "up"])
|
||||
# TODO: apears ovs only supports rstp forward delay and again it's off by default
|
||||
utils.check_cmd([constants.IP_BIN, "link", "set", self.bridge_name, "up"])
|
||||
|
||||
# create a new ebtables chain for this bridge
|
||||
ebtables_commands(subprocess.check_call, [
|
||||
ebtables_commands(utils.check_cmd, [
|
||||
[constants.EBTABLES_BIN, "-N", self.bridge_name, "-P", self.policy],
|
||||
[constants.EBTABLES_BIN, "-A", "FORWARD", "--logical-in", self.bridge_name, "-j", self.bridge_name]
|
||||
])
|
||||
|
@ -129,8 +129,8 @@ class OvsNet(PyCoreNet):
|
|||
def attach(self, interface):
|
||||
if self.up:
|
||||
try:
|
||||
subprocess.check_call([constants.OVS_BIN, "add-port", self.bridge_name, interface.localname])
|
||||
subprocess.check_call([constants.IP_BIN, "link", "set", interface.localname, "up"])
|
||||
utils.check_cmd([constants.OVS_BIN, "add-port", self.bridge_name, interface.localname])
|
||||
utils.check_cmd([constants.IP_BIN, "link", "set", interface.localname, "up"])
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("error joining interface %s to bridge %s", interface.localname, self.bridge_name)
|
||||
return
|
||||
|
@ -140,7 +140,7 @@ class OvsNet(PyCoreNet):
|
|||
def detach(self, interface):
|
||||
if self.up:
|
||||
try:
|
||||
subprocess.check_call([constants.OVS_BIN, "del-port", self.bridge_name, interface.localname])
|
||||
utils.check_cmd([constants.OVS_BIN, "del-port", self.bridge_name, interface.localname])
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("error removing interface %s from bridge %s", interface.localname, self.bridge_name)
|
||||
return
|
||||
|
@ -217,14 +217,14 @@ class OvsNet(PyCoreNet):
|
|||
limit = 0xffff # max IP payload
|
||||
tbf = ["tbf", "rate", str(bw), "burst", str(burst), "limit", str(limit)]
|
||||
logger.info("linkconfig: %s" % [tc + parent + ["handle", "1:"] + tbf])
|
||||
subprocess.check_call(tc + parent + ["handle", "1:"] + tbf)
|
||||
utils.check_cmd(tc + parent + ["handle", "1:"] + tbf)
|
||||
interface.setparam("has_tbf", True)
|
||||
elif interface.getparam("has_tbf") and bw <= 0:
|
||||
tcd = [] + tc
|
||||
tcd[2] = "delete"
|
||||
|
||||
if self.up:
|
||||
subprocess.check_call(tcd + parent)
|
||||
utils.check_cmd(tcd + parent)
|
||||
|
||||
interface.setparam("has_tbf", False)
|
||||
# removing the parent removes the child
|
||||
|
@ -273,12 +273,12 @@ class OvsNet(PyCoreNet):
|
|||
|
||||
if self.up:
|
||||
logger.info("linkconfig: %s" % ([tc + parent + ["handle", "10:"]],))
|
||||
subprocess.check_call(tc + parent + ["handle", "10:"])
|
||||
utils.check_cmd(tc + parent + ["handle", "10:"])
|
||||
interface.setparam("has_netem", False)
|
||||
elif len(netem) > 1:
|
||||
if self.up:
|
||||
logger.info("linkconfig: %s" % ([tc + parent + ["handle", "10:"] + netem],))
|
||||
subprocess.check_call(tc + parent + ["handle", "10:"] + netem)
|
||||
utils.check_cmd(tc + parent + ["handle", "10:"] + netem)
|
||||
interface.setparam("has_netem", True)
|
||||
|
||||
def linknet(self, network):
|
||||
|
@ -312,8 +312,8 @@ class OvsNet(PyCoreNet):
|
|||
if network.up:
|
||||
# this is similar to net.attach() but uses netif.name instead
|
||||
# of localname
|
||||
subprocess.check_call([constants.OVS_BIN, "add-port", network.bridge_name, interface.name])
|
||||
subprocess.check_call([constants.IP_BIN, "link", "set", interface.name, "up"])
|
||||
utils.check_cmd([constants.OVS_BIN, "add-port", network.bridge_name, interface.name])
|
||||
utils.check_cmd([constants.IP_BIN, "link", "set", interface.name, "up"])
|
||||
|
||||
# TODO: is there a native method for this? see if this causes issues
|
||||
# i = network.newifindex()
|
||||
|
@ -347,7 +347,7 @@ class OvsNet(PyCoreNet):
|
|||
|
||||
for address in addresses:
|
||||
try:
|
||||
subprocess.check_call([constants.IP_BIN, "addr", "add", str(address), "dev", self.bridge_name])
|
||||
utils.check_cmd([constants.IP_BIN, "addr", "add", str(address), "dev", self.bridge_name])
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("error adding IP address")
|
||||
|
||||
|
@ -390,12 +390,12 @@ class OvsCtrlNet(OvsNet):
|
|||
|
||||
if self.updown_script:
|
||||
logger.info("interface %s updown script %s startup called" % (self.bridge_name, self.updown_script))
|
||||
subprocess.check_call([self.updown_script, self.bridge_name, "startup"])
|
||||
utils.check_cmd([self.updown_script, self.bridge_name, "startup"])
|
||||
|
||||
if self.serverintf:
|
||||
try:
|
||||
subprocess.check_call([constants.OVS_BIN, "add-port", self.bridge_name, self.serverintf])
|
||||
subprocess.check_call([constants.IP_BIN, "link", "set", self.serverintf, "up"])
|
||||
utils.check_cmd([constants.OVS_BIN, "add-port", self.bridge_name, self.serverintf])
|
||||
utils.check_cmd([constants.IP_BIN, "link", "set", self.serverintf, "up"])
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("error joining server interface %s to controlnet bridge %s",
|
||||
self.serverintf, self.bridge_name)
|
||||
|
@ -420,14 +420,14 @@ class OvsCtrlNet(OvsNet):
|
|||
def shutdown(self):
|
||||
if self.serverintf:
|
||||
try:
|
||||
subprocess.check_call([constants.OVS_BIN, "del-port", self.bridge_name, self.serverintf])
|
||||
utils.check_cmd([constants.OVS_BIN, "del-port", self.bridge_name, self.serverintf])
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("Error deleting server interface %s to controlnet bridge %s",
|
||||
self.serverintf, self.bridge_name)
|
||||
|
||||
if self.updown_script:
|
||||
logger.info("interface %s updown script (%s shutdown) called", self.bridge_name, self.updown_script)
|
||||
subprocess.check_call([self.updown_script, self.bridge_name, "shutdown"])
|
||||
utils.check_cmd([self.updown_script, self.bridge_name, "shutdown"])
|
||||
|
||||
OvsNet.shutdown(self)
|
||||
|
||||
|
@ -576,7 +576,7 @@ class OvsHubNode(OvsNet):
|
|||
if start:
|
||||
# TODO: verify that the below flow accomplishes what is desired for a "HUB"
|
||||
# TODO: replace "brctl setageing 0"
|
||||
subprocess.check_call([constants.OVS_FLOW_BIN, "add-flow", self.bridge_name, "action=flood"])
|
||||
utils.check_cmd([constants.OVS_FLOW_BIN, "add-flow", self.bridge_name, "action=flood"])
|
||||
|
||||
|
||||
class OvsWlanNode(OvsNet):
|
||||
|
|
|
@ -46,9 +46,9 @@ class VEth(PyCoreNetIf):
|
|||
|
||||
:return: nothing
|
||||
"""
|
||||
subprocess.check_call([constants.IP_BIN, "link", "add", "name", self.localname,
|
||||
"type", "veth", "peer", "name", self.name])
|
||||
subprocess.check_call([constants.IP_BIN, "link", "set", self.localname, "up"])
|
||||
utils.check_cmd([constants.IP_BIN, "link", "add", "name", self.localname,
|
||||
"type", "veth", "peer", "name", self.name])
|
||||
utils.check_cmd([constants.IP_BIN, "link", "set", self.localname, "up"])
|
||||
self.up = True
|
||||
|
||||
def shutdown(self):
|
||||
|
@ -164,8 +164,8 @@ class TunTap(PyCoreNetIf):
|
|||
"""
|
||||
|
||||
def localdevexists():
|
||||
cmd = (constants.IP_BIN, "link", "show", self.localname)
|
||||
return utils.mutecall(cmd)
|
||||
args = (constants.IP_BIN, "link", "show", self.localname)
|
||||
return utils.mutecall(args)
|
||||
|
||||
self.waitfor(localdevexists)
|
||||
|
||||
|
@ -177,8 +177,8 @@ class TunTap(PyCoreNetIf):
|
|||
"""
|
||||
|
||||
def nodedevexists():
|
||||
cmd = [constants.IP_BIN, "link", "show", self.name]
|
||||
return self.node.cmd(cmd)
|
||||
args = [constants.IP_BIN, "link", "show", self.name]
|
||||
return self.node.cmd(args)
|
||||
|
||||
count = 0
|
||||
while True:
|
||||
|
@ -268,17 +268,17 @@ class GreTap(PyCoreNetIf):
|
|||
|
||||
if remoteip is None:
|
||||
raise ValueError, "missing remote IP required for GRE TAP device"
|
||||
cmd = ("ip", "link", "add", self.localname, "type", "gretap",
|
||||
args = ("ip", "link", "add", self.localname, "type", "gretap",
|
||||
"remote", str(remoteip))
|
||||
if localip:
|
||||
cmd += ("local", str(localip))
|
||||
args += ("local", str(localip))
|
||||
if ttl:
|
||||
cmd += ("ttl", str(ttl))
|
||||
args += ("ttl", str(ttl))
|
||||
if key:
|
||||
cmd += ("key", str(key))
|
||||
subprocess.check_call(cmd)
|
||||
cmd = ("ip", "link", "set", self.localname, "up")
|
||||
subprocess.check_call(cmd)
|
||||
args += ("key", str(key))
|
||||
utils.check_cmd(args)
|
||||
args = ("ip", "link", "set", self.localname, "up")
|
||||
utils.check_cmd(args)
|
||||
self.up = True
|
||||
|
||||
def shutdown(self):
|
||||
|
@ -288,10 +288,10 @@ class GreTap(PyCoreNetIf):
|
|||
:return: nothing
|
||||
"""
|
||||
if self.localname:
|
||||
cmd = ("ip", "link", "set", self.localname, "down")
|
||||
subprocess.check_call(cmd)
|
||||
cmd = ("ip", "link", "del", self.localname)
|
||||
subprocess.check_call(cmd)
|
||||
args = ("ip", "link", "set", self.localname, "down")
|
||||
utils.check_cmd(args)
|
||||
args = ("ip", "link", "del", self.localname)
|
||||
utils.check_cmd(args)
|
||||
self.localname = None
|
||||
|
||||
def data(self, message_type):
|
||||
|
|
|
@ -165,30 +165,30 @@ class EbtablesQueue(object):
|
|||
:return: nothing
|
||||
"""
|
||||
# save kernel ebtables snapshot to a file
|
||||
cmd = self.ebatomiccmd(["--atomic-save", ])
|
||||
args = self.ebatomiccmd(["--atomic-save", ])
|
||||
try:
|
||||
subprocess.check_call(cmd)
|
||||
utils.check_cmd(args)
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("atomic-save (%s)", cmd)
|
||||
logger.exception("atomic-save (%s)", args)
|
||||
# no atomic file, exit
|
||||
return
|
||||
# modify the table file using queued ebtables commands
|
||||
for c in self.cmds:
|
||||
cmd = self.ebatomiccmd(c)
|
||||
args = self.ebatomiccmd(c)
|
||||
try:
|
||||
subprocess.check_call(cmd)
|
||||
utils.check_cmd(args)
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("cmd=%s", cmd)
|
||||
logger.exception("cmd=%s", args)
|
||||
|
||||
self.cmds = []
|
||||
# commit the table file to the kernel
|
||||
cmd = self.ebatomiccmd(["--atomic-commit", ])
|
||||
args = self.ebatomiccmd(["--atomic-commit", ])
|
||||
|
||||
try:
|
||||
subprocess.check_call(cmd)
|
||||
utils.check_cmd(args)
|
||||
os.unlink(self.atomic_file)
|
||||
except OSError:
|
||||
logger.exception("atomic-commit (%s)", cmd)
|
||||
logger.exception("atomic-commit (%s)", args)
|
||||
|
||||
def ebchange(self, wlan):
|
||||
"""
|
||||
|
@ -241,8 +241,8 @@ def ebtablescmds(call, cmds):
|
|||
:return: nothing
|
||||
"""
|
||||
with ebtables_lock:
|
||||
for cmd in cmds:
|
||||
call(cmd)
|
||||
for args in cmds:
|
||||
call(args)
|
||||
|
||||
|
||||
class LxBrNet(PyCoreNet):
|
||||
|
@ -281,17 +281,17 @@ class LxBrNet(PyCoreNet):
|
|||
:return: nothing
|
||||
"""
|
||||
try:
|
||||
subprocess.check_call([constants.BRCTL_BIN, "addbr", self.brname])
|
||||
utils.check_cmd([constants.BRCTL_BIN, "addbr", self.brname])
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("Error adding bridge")
|
||||
|
||||
try:
|
||||
# turn off spanning tree protocol and forwarding delay
|
||||
subprocess.check_call([constants.BRCTL_BIN, "stp", self.brname, "off"])
|
||||
subprocess.check_call([constants.BRCTL_BIN, "setfd", self.brname, "0"])
|
||||
subprocess.check_call([constants.IP_BIN, "link", "set", self.brname, "up"])
|
||||
utils.check_cmd([constants.BRCTL_BIN, "stp", self.brname, "off"])
|
||||
utils.check_cmd([constants.BRCTL_BIN, "setfd", self.brname, "0"])
|
||||
utils.check_cmd([constants.IP_BIN, "link", "set", self.brname, "up"])
|
||||
# create a new ebtables chain for this bridge
|
||||
ebtablescmds(subprocess.check_call, [
|
||||
ebtablescmds(utils.check_cmd, [
|
||||
[constants.EBTABLES_BIN, "-N", self.brname, "-P", self.policy],
|
||||
[constants.EBTABLES_BIN, "-A", "FORWARD", "--logical-in", self.brname, "-j", self.brname]
|
||||
])
|
||||
|
@ -336,8 +336,8 @@ class LxBrNet(PyCoreNet):
|
|||
"""
|
||||
if self.up:
|
||||
try:
|
||||
subprocess.check_call([constants.BRCTL_BIN, "addif", self.brname, netif.localname])
|
||||
subprocess.check_call([constants.IP_BIN, "link", "set", netif.localname, "up"])
|
||||
utils.check_cmd([constants.BRCTL_BIN, "addif", self.brname, netif.localname])
|
||||
utils.check_cmd([constants.IP_BIN, "link", "set", netif.localname, "up"])
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("Error joining interface %s to bridge %s", netif.localname, self.brname)
|
||||
return
|
||||
|
@ -352,7 +352,7 @@ class LxBrNet(PyCoreNet):
|
|||
"""
|
||||
if self.up:
|
||||
try:
|
||||
subprocess.check_call([constants.BRCTL_BIN, "delif", self.brname, netif.localname])
|
||||
utils.check_cmd([constants.BRCTL_BIN, "delif", self.brname, netif.localname])
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("Error removing interface %s from bridge %s", netif.localname, self.brname)
|
||||
return
|
||||
|
@ -452,14 +452,14 @@ class LxBrNet(PyCoreNet):
|
|||
if bw > 0:
|
||||
if self.up:
|
||||
logger.info("linkconfig: %s" % ([tc + parent + ["handle", "1:"] + tbf],))
|
||||
subprocess.check_call(tc + parent + ["handle", "1:"] + tbf)
|
||||
utils.check_cmd(tc + parent + ["handle", "1:"] + tbf)
|
||||
netif.setparam("has_tbf", True)
|
||||
changed = True
|
||||
elif netif.getparam("has_tbf") and bw <= 0:
|
||||
tcd = [] + tc
|
||||
tcd[2] = "delete"
|
||||
if self.up:
|
||||
subprocess.check_call(tcd + parent)
|
||||
utils.check_cmd(tcd + parent)
|
||||
netif.setparam("has_tbf", False)
|
||||
# removing the parent removes the child
|
||||
netif.setparam("has_netem", False)
|
||||
|
@ -497,12 +497,12 @@ class LxBrNet(PyCoreNet):
|
|||
tc[2] = "delete"
|
||||
if self.up:
|
||||
logger.info("linkconfig: %s" % ([tc + parent + ["handle", "10:"]],))
|
||||
subprocess.check_call(tc + parent + ["handle", "10:"])
|
||||
utils.check_cmd(tc + parent + ["handle", "10:"])
|
||||
netif.setparam("has_netem", False)
|
||||
elif len(netem) > 1:
|
||||
if self.up:
|
||||
logger.info("linkconfig: %s" % ([tc + parent + ["handle", "10:"] + netem],))
|
||||
subprocess.check_call(tc + parent + ["handle", "10:"] + netem)
|
||||
utils.check_cmd(tc + parent + ["handle", "10:"] + netem)
|
||||
netif.setparam("has_netem", True)
|
||||
|
||||
def linknet(self, net):
|
||||
|
@ -535,8 +535,8 @@ class LxBrNet(PyCoreNet):
|
|||
if net.up:
|
||||
# this is similar to net.attach() but uses netif.name instead
|
||||
# of localname
|
||||
subprocess.check_call([constants.BRCTL_BIN, "addif", net.brname, netif.name])
|
||||
subprocess.check_call([constants.IP_BIN, "link", "set", netif.name, "up"])
|
||||
utils.check_cmd([constants.BRCTL_BIN, "addif", net.brname, netif.name])
|
||||
utils.check_cmd([constants.IP_BIN, "link", "set", netif.name, "up"])
|
||||
i = net.newifindex()
|
||||
net._netif[i] = netif
|
||||
with net._linked_lock:
|
||||
|
@ -570,7 +570,7 @@ class LxBrNet(PyCoreNet):
|
|||
return
|
||||
for addr in addrlist:
|
||||
try:
|
||||
subprocess.check_call([constants.IP_BIN, "addr", "add", str(addr), "dev", self.brname])
|
||||
utils.check_cmd([constants.IP_BIN, "addr", "add", str(addr), "dev", self.brname])
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("Error adding IP address")
|
||||
|
||||
|
|
|
@ -99,11 +99,7 @@ class SimpleLxcNode(PyCoreNode):
|
|||
env["NODE_NAME"] = str(self.name)
|
||||
|
||||
try:
|
||||
output = utils.check_alloutput(vnoded, env=env)
|
||||
# p = subprocess.Popen(vnoded, stdout=subprocess.PIPE, env=env)
|
||||
# stdout, _ = p.communicate()
|
||||
# if p.returncode:
|
||||
# raise IOError("vnoded command failed: %s" % vnoded)
|
||||
_, output = utils.check_cmd(vnoded, env=env)
|
||||
self.pid = int(output)
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("vnoded failed to create a namespace; check kernel support and user privileges")
|
||||
|
@ -171,37 +167,37 @@ class SimpleLxcNode(PyCoreNode):
|
|||
"""
|
||||
pass
|
||||
|
||||
def cmd(self, cmd, wait=True):
|
||||
def cmd(self, args, wait=True):
|
||||
"""
|
||||
Runs shell command on node, with option to not wait for a result.
|
||||
|
||||
:param list[str]/str cmd: command to run
|
||||
:param list[str]|str args: command to run
|
||||
:param bool wait: wait for command to exit, defaults to True
|
||||
:return: exit status for command
|
||||
:rtype: int
|
||||
"""
|
||||
return self.client.cmd(cmd, wait)
|
||||
return self.client.cmd(args, wait)
|
||||
|
||||
def cmd_output(self, cmd):
|
||||
def cmd_output(self, args):
|
||||
"""
|
||||
Runs shell command on node and get exit status and output.
|
||||
|
||||
:param list[str]/str cmd: command to run
|
||||
:param list[str]|str args: command to run
|
||||
:return: exit status and combined stdout and stderr
|
||||
:rtype: tuple[int, str]
|
||||
"""
|
||||
return self.client.cmd_output(cmd)
|
||||
return self.client.cmd_output(args)
|
||||
|
||||
def check_cmd(self, cmd):
|
||||
def check_cmd(self, args):
|
||||
"""
|
||||
Runs shell command on node.
|
||||
|
||||
:param list[str]/str cmd: command to run
|
||||
:param list[str]|str args: command to run
|
||||
:return: exist status and combined stdout and stderr
|
||||
:rtype: tuple[int, str]
|
||||
:raises subprocess.CalledProcessError: when a non-zero exit status occurs
|
||||
"""
|
||||
return self.client.check_cmd(cmd)
|
||||
return self.client.check_cmd(args)
|
||||
|
||||
def termcmdstring(self, sh="/bin/sh"):
|
||||
"""
|
||||
|
@ -359,9 +355,9 @@ class SimpleLxcNode(PyCoreNode):
|
|||
"""
|
||||
self._netif[ifindex].sethwaddr(addr)
|
||||
if self.up:
|
||||
cmd = [constants.IP_BIN, "link", "set", "dev", self.ifname(ifindex), "address", str(addr)]
|
||||
args = [constants.IP_BIN, "link", "set", "dev", self.ifname(ifindex), "address", str(addr)]
|
||||
try:
|
||||
self.check_cmd(cmd)
|
||||
self.check_cmd(args)
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("error setting MAC address %s: %s", addr)
|
||||
|
||||
|
@ -377,11 +373,11 @@ class SimpleLxcNode(PyCoreNode):
|
|||
try:
|
||||
# check if addr is ipv6
|
||||
if ":" in str(addr):
|
||||
cmd = [constants.IP_BIN, "addr", "add", str(addr), "dev", self.ifname(ifindex)]
|
||||
self.check_cmd(cmd)
|
||||
args = [constants.IP_BIN, "addr", "add", str(addr), "dev", self.ifname(ifindex)]
|
||||
self.check_cmd(args)
|
||||
else:
|
||||
cmd = [constants.IP_BIN, "addr", "add", str(addr), "broadcast", "+", "dev", self.ifname(ifindex)]
|
||||
self.check_cmd(cmd)
|
||||
args = [constants.IP_BIN, "addr", "add", str(addr), "broadcast", "+", "dev", self.ifname(ifindex)]
|
||||
self.check_cmd(args)
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("failure adding interface address")
|
||||
|
||||
|
|
|
@ -61,41 +61,37 @@ class VnodeClient(object):
|
|||
"""
|
||||
self.cmdchnl.close()
|
||||
|
||||
def cmd(self, cmd, wait=True):
|
||||
def cmd(self, args, wait=True):
|
||||
"""
|
||||
Execute a command on a node and return the status (return code).
|
||||
|
||||
:param list[str]/str cmd: command arguments
|
||||
:param list[str]|str args: command arguments
|
||||
:param bool wait: wait for command to end or not
|
||||
:return: command status
|
||||
:rtype: int
|
||||
"""
|
||||
self._verify_connection()
|
||||
cmd = utils.split_cmd(cmd)
|
||||
args = utils.split_args(args)
|
||||
|
||||
# run command, return process when not waiting
|
||||
p = self.cmdchnl.qcmd(cmd)
|
||||
p = self.cmdchnl.qcmd(args)
|
||||
if not wait:
|
||||
return 0
|
||||
|
||||
# wait for and return exit status
|
||||
status = p.wait()
|
||||
if status:
|
||||
logger.warn("cmd exited with status %s: %s", status, cmd)
|
||||
return p.wait()
|
||||
|
||||
return status
|
||||
|
||||
def cmd_output(self, cmd):
|
||||
def cmd_output(self, args):
|
||||
"""
|
||||
Execute a command on a node and return a tuple containing the
|
||||
exit status and result string. stderr output
|
||||
is folded into the stdout result string.
|
||||
|
||||
:param list[str]/str cmd: command to run
|
||||
:param list[str]|str args: command to run
|
||||
:return: command status and combined stdout and stderr output
|
||||
:rtype: tuple[int, str]
|
||||
"""
|
||||
p, stdin, stdout, stderr = self.popen(cmd)
|
||||
p, stdin, stdout, stderr = self.popen(args)
|
||||
stdin.close()
|
||||
output = stdout.read() + stderr.read()
|
||||
stdout.close()
|
||||
|
@ -103,44 +99,44 @@ class VnodeClient(object):
|
|||
status = p.wait()
|
||||
return status, output.strip()
|
||||
|
||||
def check_cmd(self, cmd):
|
||||
def check_cmd(self, args):
|
||||
"""
|
||||
Run command and return exit status and combined stdout and stderr.
|
||||
|
||||
:param list[str]/str cmd: command to run
|
||||
:param list[str]|str args: command to run
|
||||
:return: exit status and combined stdout and stderr
|
||||
:rtype: tuple[int, str]
|
||||
:raises subprocess.CalledProcessError: when there is a non-zero exit status
|
||||
"""
|
||||
status, output = self.cmd_output(cmd)
|
||||
status, output = self.cmd_output(args)
|
||||
if status:
|
||||
raise subprocess.CalledProcessError(status, cmd, output)
|
||||
raise subprocess.CalledProcessError(status, args, output)
|
||||
return status, output.strip()
|
||||
|
||||
def popen(self, cmd):
|
||||
def popen(self, args):
|
||||
"""
|
||||
Execute a popen command against the node.
|
||||
|
||||
:param list[str]/str cmd: command arguments
|
||||
:param list[str]|str args: command arguments
|
||||
:return: popen object, stdin, stdout, and stderr
|
||||
:rtype: tuple
|
||||
"""
|
||||
self._verify_connection()
|
||||
cmd = utils.split_cmd(cmd)
|
||||
return self.cmdchnl.popen(cmd)
|
||||
args = utils.split_args(args)
|
||||
return self.cmdchnl.popen(args)
|
||||
|
||||
def icmd(self, cmd):
|
||||
def icmd(self, args):
|
||||
"""
|
||||
Execute an icmd against a node.
|
||||
|
||||
:param list[str]/str cmd: command arguments
|
||||
:param list[str]|str args: command arguments
|
||||
:return: command result
|
||||
:rtype: int
|
||||
"""
|
||||
cmd = utils.split_cmd(cmd)
|
||||
return os.spawnlp(os.P_WAIT, VCMD, VCMD, "-c", self.ctrlchnlname, "--", *cmd)
|
||||
args = utils.split_args(args)
|
||||
return os.spawnlp(os.P_WAIT, VCMD, VCMD, "-c", self.ctrlchnlname, "--", *args)
|
||||
|
||||
def redircmd(self, infd, outfd, errfd, cmd, wait=True):
|
||||
def redircmd(self, infd, outfd, errfd, args, wait=True):
|
||||
"""
|
||||
Execute a command on a node with standard input, output, and
|
||||
error redirected according to the given file descriptors.
|
||||
|
@ -148,7 +144,7 @@ class VnodeClient(object):
|
|||
:param infd: stdin file descriptor
|
||||
:param outfd: stdout file descriptor
|
||||
:param errfd: stderr file descriptor
|
||||
:param list[str]/str cmd: command arguments
|
||||
:param list[str]|str args: command arguments
|
||||
:param bool wait: wait flag
|
||||
:return: command status
|
||||
:rtype: int
|
||||
|
@ -156,15 +152,15 @@ class VnodeClient(object):
|
|||
self._verify_connection()
|
||||
|
||||
# run command, return process when not waiting
|
||||
cmd = utils.split_cmd(cmd)
|
||||
p = self.cmdchnl.redircmd(infd, outfd, errfd, cmd)
|
||||
args = utils.split_args(args)
|
||||
p = self.cmdchnl.redircmd(infd, outfd, errfd, args)
|
||||
if not wait:
|
||||
return p
|
||||
|
||||
# wait for and return exit status
|
||||
status = p.wait()
|
||||
if status:
|
||||
logger.warn("cmd exited with status %s: %s", status, cmd)
|
||||
logger.warn("cmd exited with status %s: %s", status, args)
|
||||
return status
|
||||
|
||||
def term(self, sh="/bin/sh"):
|
||||
|
@ -175,12 +171,12 @@ class VnodeClient(object):
|
|||
:return: terminal command result
|
||||
:rtype: int
|
||||
"""
|
||||
cmd = ("xterm", "-ut", "-title", self.name, "-e", VCMD, "-c", self.ctrlchnlname, "--", sh)
|
||||
args = ("xterm", "-ut", "-title", self.name, "-e", VCMD, "-c", self.ctrlchnlname, "--", sh)
|
||||
if "SUDO_USER" in os.environ:
|
||||
cmd = ("su", "-s", "/bin/sh", "-c",
|
||||
"exec " + " ".join(map(lambda x: "'%s'" % x, cmd)),
|
||||
args = ("su", "-s", "/bin/sh", "-c",
|
||||
"exec " + " ".join(map(lambda x: "'%s'" % x, args)),
|
||||
os.environ["SUDO_USER"])
|
||||
return os.spawnvp(os.P_NOWAIT, cmd[0], cmd)
|
||||
return os.spawnvp(os.P_NOWAIT, args[0], args)
|
||||
|
||||
def termcmdstring(self, sh="/bin/sh"):
|
||||
"""
|
||||
|
@ -226,8 +222,8 @@ class VnodeClient(object):
|
|||
return self._addr[ifname]
|
||||
|
||||
interface = {"ether": [], "inet": [], "inet6": [], "inet6link": []}
|
||||
cmd = [constants.IP_BIN, "addr", "show", "dev", ifname]
|
||||
p, stdin, stdout, stderr = self.popen(cmd)
|
||||
args = [constants.IP_BIN, "addr", "show", "dev", ifname]
|
||||
p, stdin, stdout, stderr = self.popen(args)
|
||||
stdin.close()
|
||||
|
||||
for line in stdout:
|
||||
|
@ -249,7 +245,7 @@ class VnodeClient(object):
|
|||
stderr.close()
|
||||
status = p.wait()
|
||||
if status:
|
||||
logger.warn("nonzero exist status (%s) for cmd: %s", status, cmd)
|
||||
logger.warn("nonzero exist status (%s) for cmd: %s", status, args)
|
||||
if err:
|
||||
logger.warn("error output: %s", err)
|
||||
self._addr[ifname] = interface
|
||||
|
@ -264,8 +260,8 @@ class VnodeClient(object):
|
|||
:rtype: dict
|
||||
"""
|
||||
stats = {}
|
||||
cmd = ["cat", "/proc/net/dev"]
|
||||
p, stdin, stdout, stderr = self.popen(cmd)
|
||||
args = ["cat", "/proc/net/dev"]
|
||||
p, stdin, stdout, stderr = self.popen(args)
|
||||
stdin.close()
|
||||
# ignore first line
|
||||
stdout.readline()
|
||||
|
@ -291,7 +287,7 @@ class VnodeClient(object):
|
|||
stderr.close()
|
||||
status = p.wait()
|
||||
if status:
|
||||
logger.warn("nonzero exist status (%s) for cmd: %s", status, cmd)
|
||||
logger.warn("nonzero exist status (%s) for cmd: %s", status, args)
|
||||
if err:
|
||||
logger.warn("error output: %s", err)
|
||||
if ifname is not None:
|
||||
|
|
|
@ -55,34 +55,33 @@ class PhysicalNode(PyCoreNode):
|
|||
|
||||
def termcmdstring(self, sh="/bin/sh"):
|
||||
"""
|
||||
The broker will add the appropriate SSH command to open a terminal
|
||||
on this physical node.
|
||||
Create a terminal command string.
|
||||
|
||||
:param str sh: shell to execute command in
|
||||
:return: str
|
||||
"""
|
||||
return sh
|
||||
|
||||
def cmd(self, args, wait=True):
|
||||
"""
|
||||
run a command on the physical node
|
||||
Runs shell command on node, with option to not wait for a result.
|
||||
|
||||
:param list[str]|str args: command to run
|
||||
:param bool wait: wait for command to exit, defaults to True
|
||||
:return: exit status for command
|
||||
:rtype: int
|
||||
"""
|
||||
os.chdir(self.nodedir)
|
||||
status = -1
|
||||
|
||||
try:
|
||||
if wait:
|
||||
# os.spawnlp(os.P_WAIT, args)
|
||||
status = subprocess.call(args)
|
||||
else:
|
||||
# os.spawnlp(os.P_NOWAIT, args)
|
||||
subprocess.Popen(args)
|
||||
status = 0
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("cmd exited with status: %s", args)
|
||||
|
||||
status = utils.cmd(args, wait)
|
||||
return status
|
||||
|
||||
def cmd_output(self, args):
|
||||
"""
|
||||
run a command on the physical node and get the result
|
||||
Runs shell command on node and get exit status and output.
|
||||
|
||||
:param list[str]|str args: command to run
|
||||
:return: exit status and combined stdout and stderr
|
||||
:rtype: tuple[int, str]
|
||||
"""
|
||||
os.chdir(self.nodedir)
|
||||
# in Python 2.7 we can use subprocess.check_output() here
|
||||
|
@ -92,18 +91,18 @@ class PhysicalNode(PyCoreNode):
|
|||
status = p.wait()
|
||||
return status, stdout.strip()
|
||||
|
||||
def check_cmd(self, cmd):
|
||||
def check_cmd(self, args):
|
||||
"""
|
||||
Runs shell command on node.
|
||||
|
||||
:param list[str]/str cmd: command to run
|
||||
:param list[str]|str args: command to run
|
||||
:return: exist status and combined stdout and stderr
|
||||
:rtype: tuple[int, str]
|
||||
:raises subprocess.CalledProcessError: when a non-zero exit status occurs
|
||||
"""
|
||||
status, output = self.cmd_output(cmd)
|
||||
status, output = self.cmd_output(args)
|
||||
if status:
|
||||
raise subprocess.CalledProcessError(status, cmd, output)
|
||||
raise subprocess.CalledProcessError(status, args, output)
|
||||
return status, output.strip()
|
||||
|
||||
def shcmd(self, cmdstr, sh="/bin/sh"):
|
||||
|
|
|
@ -304,12 +304,12 @@ class CoreServices(ConfigurableManager):
|
|||
if use_startup_service and not self.is_startup_service(service):
|
||||
return
|
||||
|
||||
for cmd in service.getstartup(node, services):
|
||||
for args in service.getstartup(node, services):
|
||||
try:
|
||||
# TODO: this wait=False can be problematic!
|
||||
node.cmd(cmd, wait=False)
|
||||
node.cmd(args, wait=False)
|
||||
except:
|
||||
logger.exception("error starting command %s", cmd)
|
||||
logger.exception("error starting command %s", args)
|
||||
|
||||
def bootnodecustomservice(self, node, service, services, use_startup_service):
|
||||
"""
|
||||
|
@ -350,12 +350,12 @@ class CoreServices(ConfigurableManager):
|
|||
if use_startup_service and not self.is_startup_service(service):
|
||||
return
|
||||
|
||||
for cmd in service._startup:
|
||||
for args in service._startup:
|
||||
try:
|
||||
# TODO: this wait=False can be problematic!
|
||||
node.cmd(cmd, wait=False)
|
||||
node.cmd(args, wait=False)
|
||||
except:
|
||||
logger.exception("error starting command %s", cmd)
|
||||
logger.exception("error starting command %s", args)
|
||||
|
||||
def copyservicefile(self, node, filename, cfg):
|
||||
"""
|
||||
|
@ -409,10 +409,10 @@ class CoreServices(ConfigurableManager):
|
|||
status = 0
|
||||
# has validate commands
|
||||
if len(validate_cmds) > 0:
|
||||
for cmd in validate_cmds:
|
||||
logger.info("validating service %s using: %s", service._name, cmd)
|
||||
for args in validate_cmds:
|
||||
logger.info("validating service %s using: %s", service._name, args)
|
||||
try:
|
||||
status, _ = node.check_cmd(cmd)
|
||||
status, _ = node.check_cmd(args)
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("validate command failed")
|
||||
status = -1
|
||||
|
@ -444,12 +444,12 @@ class CoreServices(ConfigurableManager):
|
|||
# doesn't have a shutdown command
|
||||
status += "0"
|
||||
else:
|
||||
for cmd in service._shutdown:
|
||||
for args in service._shutdown:
|
||||
try:
|
||||
status, _ = node.check_cmd(cmd)
|
||||
status, _ = node.check_cmd(args)
|
||||
status = str(status)
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("error running stop command %s", cmd)
|
||||
logger.exception("error running stop command %s", args)
|
||||
# TODO: determine if its ok to just return the bad exit status
|
||||
status = "-1"
|
||||
return status
|
||||
|
@ -757,12 +757,12 @@ class CoreServices(ConfigurableManager):
|
|||
else:
|
||||
cmds = s.getstartup(node, services)
|
||||
if len(cmds) > 0:
|
||||
for cmd in cmds:
|
||||
for args in cmds:
|
||||
try:
|
||||
node.check_cmd(cmd)
|
||||
node.check_cmd(args)
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("error starting command %s", cmd)
|
||||
fail += "Start %s(%s)," % (s._name, cmd)
|
||||
logger.exception("error starting command %s", args)
|
||||
fail += "Start %s(%s)," % (s._name, args)
|
||||
if event_type == EventTypes.PAUSE.value:
|
||||
status = self.validatenodeservice(node, s, services)
|
||||
if status != 0:
|
||||
|
|
|
@ -429,11 +429,11 @@ class Session(object):
|
|||
|
||||
# execute hook file
|
||||
try:
|
||||
subprocess.check_call(["/bin/sh", file_name], stdin=open(os.devnull, 'r'),
|
||||
stdout=stdout, stderr=stderr, close_fds=True,
|
||||
cwd=self.session_dir, env=self.get_environment())
|
||||
except subprocess.CalledProcessError:
|
||||
logger.exception("error running hook '%s'", file_name)
|
||||
args = ["/bin/sh", file_name]
|
||||
subprocess.check_call(args, stdout=stdout, stderr=stderr,
|
||||
close_fds=True, cwd=self.session_dir, env=self.get_environment())
|
||||
except (OSError, subprocess.CalledProcessError):
|
||||
logger.exception("error running hook: %s", file_name)
|
||||
|
||||
def run_state_hooks(self, state):
|
||||
"""
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import os
|
||||
import socket
|
||||
import subprocess
|
||||
|
||||
from core import constants
|
||||
from core import emane
|
||||
from core import logger
|
||||
from core.enumerations import NodeTypes
|
||||
from core.misc import ipaddress
|
||||
from core.misc import ipaddress, utils
|
||||
from core.misc import nodeutils
|
||||
from core.netns import nodes
|
||||
from core.xml import xmlutils
|
||||
|
@ -26,8 +25,8 @@ class CoreDeploymentWriter(object):
|
|||
def get_ipv4_addresses(hostname):
|
||||
if hostname == 'localhost':
|
||||
addr_list = []
|
||||
cmd = (constants.IP_BIN, '-o', '-f', 'inet', 'addr', 'show')
|
||||
output = subprocess.check_output(cmd)
|
||||
args = (constants.IP_BIN, '-o', '-f', 'inet', 'addr', 'show')
|
||||
_, output = utils.check_cmd(args)
|
||||
for line in output.split(os.linesep):
|
||||
split = line.split()
|
||||
if not split:
|
||||
|
@ -48,8 +47,8 @@ class CoreDeploymentWriter(object):
|
|||
"""
|
||||
if hostname == 'localhost':
|
||||
iface_list = []
|
||||
cmd = (constants.IP_BIN, '-o', '-f', 'inet', 'addr', 'show')
|
||||
output = subprocess.check_output(cmd)
|
||||
args = (constants.IP_BIN, '-o', '-f', 'inet', 'addr', 'show')
|
||||
_, output = utils.check_cmd(args)
|
||||
for line in output.split(os.linesep):
|
||||
split = line.split()
|
||||
if not split:
|
||||
|
|
Loading…
Reference in a new issue