further cleanup in regards the commands that are being used within core

This commit is contained in:
Blake J. Harnden 2018-03-01 16:23:58 -08:00
parent 870d87804b
commit 6211b09585
15 changed files with 322 additions and 316 deletions

View file

@ -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):
"""

View file

@ -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):

View file

@ -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):

View file

@ -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")

View file

@ -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")

View file

@ -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: