quick pass for small cleanup within bsd nodes

This commit is contained in:
Blake J. Harnden 2017-08-03 12:44:08 -07:00
parent 1f9a8879c1
commit 78ff7f2189
4 changed files with 146 additions and 116 deletions

View file

@ -16,58 +16,82 @@ import subprocess
from core import constants from core import constants
from core.misc import utils from core.misc import utils
utils.checkexec([constants.NGCTL_BIN]) utils.check_executables([constants.NGCTL_BIN])
def createngnode(type, hookstr, name=None): def createngnode(node_type, hookstr, name=None):
""" """
Create a new Netgraph node of type and optionally assign name. The Create a new Netgraph node of type and optionally assign name. The
hook string hookstr should contain two names. This is a string so hook string hookstr should contain two names. This is a string so
other commands may be inserted after the two names. other commands may be inserted after the two names.
Return the name and netgraph ID of the new node. Return the name and netgraph ID of the new node.
:param node_type: node type to create
:param hookstr: hook string
:param name: name
:return: name and id
:rtype: tuple
""" """
hook1 = hookstr.split()[0] hook1 = hookstr.split()[0]
ngcmd = "mkpeer %s %s \n show .%s" % (type, hookstr, hook1) ngcmd = "mkpeer %s %s \n show .%s" % (node_type, hookstr, hook1)
cmd = [constants.NGCTL_BIN, "-f", "-"] cmd = [constants.NGCTL_BIN, "-f", "-"]
cmdid = subprocess.Popen(cmd, stdin=subprocess.PIPE, cmdid = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
# err will always be None # err will always be None
result, err = cmdid.communicate(input=ngcmd) result, err = cmdid.communicate(input=ngcmd)
status = cmdid.wait() status = cmdid.wait()
if status > 0: if status > 0:
raise Exception("error creating Netgraph node %s (%s): %s" % (type, ngcmd, result)) raise Exception("error creating Netgraph node %s (%s): %s" % (node_type, ngcmd, result))
results = result.split() results = result.split()
ngname = results[1] ngname = results[1]
ngid = results[5] ngid = results[5]
if name: if name:
utils.check_call([constants.NGCTL_BIN, "name", "[0x%s]:" % ngid, name]) subprocess.check_call([constants.NGCTL_BIN, "name", "[0x%s]:" % ngid, name])
return ngname, ngid return ngname, ngid
def destroyngnode(name): def destroyngnode(name):
""" Shutdown a Netgraph node having the given name.
""" """
utils.check_call([constants.NGCTL_BIN, "shutdown", "%s:" % name]) Shutdown a Netgraph node having the given name.
:param str name: node name
:return: nothing
"""
subprocess.check_call([constants.NGCTL_BIN, "shutdown", "%s:" % name])
def connectngnodes(name1, name2, hook1, hook2): def connectngnodes(name1, name2, hook1, hook2):
""" Connect two hooks of two Netgraph nodes given by their names. """
Connect two hooks of two Netgraph nodes given by their names.
:param str name1: name one
:param str name2: name two
:param str hook1: hook one
:param str hook2: hook two
:return: nothing
""" """
node1 = "%s:" % name1 node1 = "%s:" % name1
node2 = "%s:" % name2 node2 = "%s:" % name2
utils.check_call([constants.NGCTL_BIN, "connect", node1, node2, hook1, hook2]) subprocess.check_call([constants.NGCTL_BIN, "connect", node1, node2, hook1, hook2])
def ngmessage(name, msg): def ngmessage(name, msg):
""" Send a Netgraph message to the node named name. """
Send a Netgraph message to the node named name.
:param str name: node name
:param list msg: message
:return: nothing
""" """
cmd = [constants.NGCTL_BIN, "msg", "%s:" % name] + msg cmd = [constants.NGCTL_BIN, "msg", "%s:" % name] + msg
utils.check_call(cmd) subprocess.check_call(cmd)
def ngloadkernelmodule(name): def ngloadkernelmodule(name):
""" Load a kernel module by invoking kldstat. This is needed for the """
ng_ether module which automatically creates Netgraph nodes when loaded. Load a kernel module by invoking kldstat. This is needed for the
ng_ether module which automatically creates Netgraph nodes when loaded.
:param str name: module name
:return: nothing
""" """
utils.mutecall(["kldload", name]) utils.mutecall(["kldload", name])

View file

@ -12,6 +12,7 @@ from the CoreNode, implementing specific node types.
""" """
import socket import socket
import subprocess
from core import constants from core import constants
from core.api import coreapi from core.api import coreapi
@ -25,9 +26,12 @@ from core.enumerations import LinkTypes
from core.enumerations import NodeTypes from core.enumerations import NodeTypes
from core.enumerations import RegisterTlvs from core.enumerations import RegisterTlvs
from core.misc import ipaddress from core.misc import ipaddress
from core.misc import log
from core.misc import utils from core.misc import utils
utils.checkexec([constants.IFCONFIG_BIN]) logger = log.get_logger(__name__)
utils.check_executables([constants.IFCONFIG_BIN])
class CoreNode(JailNode): class CoreNode(JailNode):
@ -36,14 +40,16 @@ class CoreNode(JailNode):
class PtpNet(NetgraphPipeNet): class PtpNet(NetgraphPipeNet):
def tonodemsg(self, flags): def tonodemsg(self, flags):
""" Do not generate a Node Message for point-to-point links. They are """
built using a link message instead. Do not generate a Node Message for point-to-point links. They are
built using a link message instead.
""" """
pass pass
def tolinkmsgs(self, flags): def tolinkmsgs(self, flags):
""" Build CORE API TLVs for a point-to-point link. One Link message """
describes this network. Build CORE API TLVs for a point-to-point link. One Link message
describes this network.
""" """
tlvdata = "" tlvdata = ""
if len(self._netif) != 2: if len(self._netif) != 2:
@ -74,7 +80,7 @@ class PtpNet(NetgraphPipeNet):
if if1.hwaddr: if if1.hwaddr:
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE1_MAC.value, if1.hwaddr) tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE1_MAC.value, if1.hwaddr)
for addr in if1.addrlist: for addr in if1.addrlist:
(ip, sep, mask) = addr.partition("/") ip, sep, mask = addr.partition("/")
mask = int(mask) mask = int(mask)
if ipaddress.is_ipv4_address(ip): if ipaddress.is_ipv4_address(ip):
family = socket.AF_INET family = socket.AF_INET
@ -92,7 +98,7 @@ class PtpNet(NetgraphPipeNet):
if if2.hwaddr: if if2.hwaddr:
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_MAC.value, if2.hwaddr) tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_MAC.value, if2.hwaddr)
for addr in if2.addrlist: for addr in if2.addrlist:
(ip, sep, mask) = addr.partition("/") ip, sep, mask = addr.partition("/")
mask = int(mask) mask = int(mask)
if ipaddress.is_ipv4_address(ip): if ipaddress.is_ipv4_address(ip):
family = socket.AF_INET family = socket.AF_INET
@ -131,9 +137,8 @@ class WlanNode(NetgraphNet):
linktype = LinkTypes.WIRELESS.value linktype = LinkTypes.WIRELESS.value
policy = "DROP" policy = "DROP"
def __init__(self, session, objid=None, name=None, verbose=False, def __init__(self, session, objid=None, name=None, start=True, policy=None):
start=True, policy=None): NetgraphNet.__init__(self, session, objid, name, start, policy)
NetgraphNet.__init__(self, session, objid, name, verbose, start, policy)
# wireless model such as basic range # wireless model such as basic range
self.model = None self.model = None
# mobility model such as scripted # mobility model such as scripted
@ -142,40 +147,42 @@ class WlanNode(NetgraphNet):
def attach(self, netif): def attach(self, netif):
NetgraphNet.attach(self, netif) NetgraphNet.attach(self, netif)
if self.model: if self.model:
netif.poshook = self.model._positioncallback netif.poshook = self.model.position_callback
if netif.node is None: if netif.node is None:
return return
x, y, z = netif.node.position.get() x, y, z = netif.node.position.get()
netif.poshook(netif, x, y, z) netif.poshook(netif, x, y, z)
def setmodel(self, model, config): def setmodel(self, model, config):
""" Mobility and wireless model.
""" """
if self.verbose: Mobility and wireless model.
self.info("adding model %s" % model._name)
if model._type == RegisterTlvs.WIRELESS.value: :param core.mobility.WirelessModel.cls model: model to set
self.model = model(session=self.session, objid=self.objid, :param dict config: configuration for model
verbose=self.verbose, values=config) :return:
if self.model._positioncallback: """
logger.info("adding model %s" % model.name)
if model.config_type == RegisterTlvs.WIRELESS.value:
self.model = model(session=self.session, objid=self.objid, values=config)
if self.model.position_callback:
for netif in self.netifs(): for netif in self.netifs():
netif.poshook = self.model._positioncallback netif.poshook = self.model.position_callback
if netif.node is not None: if netif.node is not None:
(x, y, z) = netif.node.position.get() x, y, z = netif.node.position.get()
netif.poshook(netif, x, y, z) netif.poshook(netif, x, y, z)
self.model.setlinkparams() self.model.setlinkparams()
elif model._type == RegisterTlvs.MOBILITY.value: elif model.config_type == RegisterTlvs.MOBILITY.value:
self.mobility = model(session=self.session, objid=self.objid, self.mobility = model(session=self.session, objid=self.objid, values=config)
verbose=self.verbose, values=config)
class RJ45Node(NetgraphPipeNet): class RJ45Node(NetgraphPipeNet):
apitype = NodeTypes.RJ45.value apitype = NodeTypes.RJ45.value
policy = "ACCEPT" policy = "ACCEPT"
def __init__(self, session, objid, name, verbose, start=True): def __init__(self, session, objid, name, start=True):
if start: if start:
ngloadkernelmodule("ng_ether") ngloadkernelmodule("ng_ether")
NetgraphPipeNet.__init__(self, session, objid, name, verbose, start) NetgraphPipeNet.__init__(self, session, objid, name, start)
if start: if start:
self.setpromisc(True) self.setpromisc(True)
@ -187,12 +194,11 @@ class RJ45Node(NetgraphPipeNet):
p = "promisc" p = "promisc"
if not promisc: if not promisc:
p = "-" + p p = "-" + p
utils.check_call([constants.IFCONFIG_BIN, self.name, "up", p]) subprocess.check_call([constants.IFCONFIG_BIN, self.name, "up", p])
def attach(self, netif): def attach(self, netif):
if len(self._netif) > 0: if len(self._netif) > 0:
raise ValueError, \ raise ValueError("RJ45 networks support at most 1 network interface")
"RJ45 networks support at most 1 network interface"
NetgraphPipeNet.attach(self, netif) NetgraphPipeNet.attach(self, netif)
connectngnodes(self.ngname, self.name, self.gethook(), "lower") connectngnodes(self.ngname, self.name, self.gethook(), "lower")

View file

@ -16,14 +16,16 @@ from core.bsd.netgraph import createngnode
from core.bsd.netgraph import destroyngnode from core.bsd.netgraph import destroyngnode
from core.bsd.netgraph import ngmessage from core.bsd.netgraph import ngmessage
from core.coreobj import PyCoreNet from core.coreobj import PyCoreNet
from core.misc import log
logger = log.get_logger(__name__)
class NetgraphNet(PyCoreNet): class NetgraphNet(PyCoreNet):
ngtype = None ngtype = None
nghooks = () nghooks = ()
def __init__(self, session, objid=None, name=None, verbose=False, def __init__(self, session, objid=None, name=None, start=True, policy=None):
start=True, policy=None):
PyCoreNet.__init__(self, session, objid, name) PyCoreNet.__init__(self, session, objid, name)
if name is None: if name is None:
name = str(self.objid) name = str(self.objid)
@ -32,7 +34,6 @@ class NetgraphNet(PyCoreNet):
self.name = name self.name = name
self.ngname = "n_%s_%s" % (str(self.objid), self.session.session_id) self.ngname = "n_%s_%s" % (str(self.objid), self.session.session_id)
self.ngid = None self.ngid = None
self.verbose = verbose
self._netif = {} self._netif = {}
self._linked = {} self._linked = {}
self.up = False self.up = False
@ -40,7 +41,7 @@ class NetgraphNet(PyCoreNet):
self.startup() self.startup()
def startup(self): def startup(self):
tmp, self.ngid = createngnode(type=self.ngtype, hookstr=self.nghooks, name=self.ngname) tmp, self.ngid = createngnode(node_type=self.ngtype, hookstr=self.nghooks, name=self.ngname)
self.up = True self.up = True
def shutdown(self): def shutdown(self):
@ -61,12 +62,13 @@ class NetgraphNet(PyCoreNet):
destroyngnode(self.ngname) destroyngnode(self.ngname)
def attach(self, netif): def attach(self, netif):
""" Attach an interface to this netgraph node. Create a pipe between """
the interface and the hub/switch/wlan node. Attach an interface to this netgraph node. Create a pipe between
(Note that the PtpNet subclass overrides this method.) the interface and the hub/switch/wlan node.
(Note that the PtpNet subclass overrides this method.)
""" """
if self.up: if self.up:
pipe = self.session.addobj(cls=NetgraphPipeNet, verbose=self.verbose, start=True) pipe = self.session.addobj(cls=NetgraphPipeNet, start=True)
pipe.attach(netif) pipe.attach(netif)
hook = "link%d" % len(self._netif) hook = "link%d" % len(self._netif)
pipe.attachnet(self, hook) pipe.attachnet(self, hook)
@ -107,17 +109,19 @@ class NetgraphNet(PyCoreNet):
self._linked[netif1][netif2] = True self._linked[netif1][netif2] = True
def linknet(self, net): def linknet(self, net):
""" Link this bridge with another by creating a veth pair and installing """
each device into each bridge. Link this bridge with another by creating a veth pair and installing
each device into each bridge.
""" """
raise NotImplementedError raise NotImplementedError
def linkconfig(self, netif, bw=None, delay=None, def linkconfig(self, netif, bw=None, delay=None,
loss=None, duplicate=None, jitter=None, netif2=None): loss=None, duplicate=None, jitter=None, netif2=None):
""" Set link effects by modifying the pipe connected to an interface. """
Set link effects by modifying the pipe connected to an interface.
""" """
if not netif.pipe: if not netif.pipe:
self.warn("linkconfig for %s but interface %s has no pipe" % (self.name, netif.name)) logger.warn("linkconfig for %s but interface %s has no pipe", self.name, netif.name)
return return
return netif.pipe.linkconfig(netif, bw, delay, loss, duplicate, jitter, netif2) return netif.pipe.linkconfig(netif, bw, delay, loss, duplicate, jitter, netif2)
@ -126,41 +130,40 @@ class NetgraphPipeNet(NetgraphNet):
ngtype = "pipe" ngtype = "pipe"
nghooks = "upper lower" nghooks = "upper lower"
def __init__(self, session, objid=None, name=None, verbose=False, def __init__(self, session, objid=None, name=None, start=True, policy=None):
start=True, policy=None): NetgraphNet.__init__(self, session, objid, name, start, policy)
NetgraphNet.__init__(self, session, objid, name, verbose, start, policy)
if start: if start:
# account for Ethernet header # account for Ethernet header
ngmessage(self.ngname, ["setcfg", "{", "header_offset=14", "}"]) ngmessage(self.ngname, ["setcfg", "{", "header_offset=14", "}"])
def attach(self, netif): def attach(self, netif):
""" Attach an interface to this pipe node. """
The first interface is connected to the "upper" hook, the second Attach an interface to this pipe node.
connected to the "lower" hook. The first interface is connected to the "upper" hook, the second
connected to the "lower" hook.
""" """
if len(self._netif) > 1: if len(self._netif) > 1:
raise ValueError, \ raise ValueError("Netgraph pipes support at most 2 network interfaces")
"Netgraph pipes support at most 2 network interfaces"
if self.up: if self.up:
hook = self.gethook() hook = self.gethook()
connectngnodes(self.ngname, netif.localname, hook, netif.hook) connectngnodes(self.ngname, netif.localname, hook, netif.hook)
if netif.pipe: if netif.pipe:
raise ValueError, \ raise ValueError("Interface %s already attached to pipe %s" % (netif.name, netif.pipe.name))
"Interface %s already attached to pipe %s" % \
(netif.name, netif.pipe.name)
netif.pipe = self netif.pipe = self
self._netif[netif] = netif self._netif[netif] = netif
self._linked[netif] = {} self._linked[netif] = {}
def attachnet(self, net, hook): def attachnet(self, net, hook):
""" Attach another NetgraphNet to this pipe node. """
Attach another NetgraphNet to this pipe node.
""" """
localhook = self.gethook() localhook = self.gethook()
connectngnodes(self.ngname, net.ngname, localhook, hook) connectngnodes(self.ngname, net.ngname, localhook, hook)
def gethook(self): def gethook(self):
""" Returns the first hook (e.g. "upper") then the second hook """
(e.g. "lower") based on the number of connections. Returns the first hook (e.g. "upper") then the second hook
(e.g. "lower") based on the number of connections.
""" """
hooks = self.nghooks.split() hooks = self.nghooks.split()
if len(self._netif) == 0: if len(self._netif) == 0:
@ -170,7 +173,8 @@ class NetgraphPipeNet(NetgraphNet):
def linkconfig(self, netif, bw=None, delay=None, def linkconfig(self, netif, bw=None, delay=None,
loss=None, duplicate=None, jitter=None, netif2=None): loss=None, duplicate=None, jitter=None, netif2=None):
""" Set link effects by sending a Netgraph setcfg message to the pipe. """
Set link effects by sending a Netgraph setcfg message to the pipe.
""" """
netif.setparam("bw", bw) netif.setparam("bw", bw)
netif.setparam("delay", delay) netif.setparam("delay", delay)
@ -201,7 +205,7 @@ class NetgraphPipeNet(NetgraphNet):
upstream += ["duplicate=%s" % duplicate, ] upstream += ["duplicate=%s" % duplicate, ]
downstream += ["duplicate=%s" % duplicate, ] downstream += ["duplicate=%s" % duplicate, ]
if jitter: if jitter:
self.warn("jitter parameter ignored for link %s" % self.name) logger.warn("jitter parameter ignored for link %s", self.name)
if len(params) > 0 or len(upstream) > 0 or len(downstream) > 0: if len(params) > 0 or len(upstream) > 0 or len(downstream) > 0:
setcfg = ["setcfg", "{", ] + params setcfg = ["setcfg", "{", ] + params
if len(upstream) > 0: if len(upstream) > 0:

View file

@ -20,9 +20,12 @@ from core.bsd.netgraph import createngnode
from core.bsd.netgraph import destroyngnode from core.bsd.netgraph import destroyngnode
from core.coreobj import PyCoreNetIf from core.coreobj import PyCoreNetIf
from core.coreobj import PyCoreNode from core.coreobj import PyCoreNode
from core.misc import log
from core.misc import utils from core.misc import utils
utils.checkexec([constants.IFCONFIG_BIN, constants.VIMAGE_BIN]) logger = log.get_logger(__name__)
utils.check_executables([constants.IFCONFIG_BIN, constants.VIMAGE_BIN])
class VEth(PyCoreNetIf): class VEth(PyCoreNetIf):
@ -46,11 +49,10 @@ class VEth(PyCoreNetIf):
def startup(self): def startup(self):
hookstr = "%s %s" % (self.hook, self.hook) hookstr = "%s %s" % (self.hook, self.hook)
ngname, ngid = createngnode(type="eiface", hookstr=hookstr, ngname, ngid = createngnode(node_type="eiface", hookstr=hookstr, name=self.localname)
name=self.localname)
self.name = ngname self.name = ngname
self.ngid = ngid self.ngid = ngid
utils.check_call([constants.IFCONFIG_BIN, ngname, "up"]) subprocess.check_call([constants.IFCONFIG_BIN, ngname, "up"])
self.up = True self.up = True
def shutdown(self): def shutdown(self):
@ -81,19 +83,18 @@ class VEth(PyCoreNetIf):
class TunTap(PyCoreNetIf): class TunTap(PyCoreNetIf):
"""TUN/TAP virtual device in TAP mode""" """
TUN/TAP virtual device in TAP mode
"""
def __init__(self, node, name, localname, mtu=None, net=None, def __init__(self, node, name, localname, mtu=None, net=None, start=True):
start=True):
raise NotImplementedError raise NotImplementedError
class SimpleJailNode(PyCoreNode): class SimpleJailNode(PyCoreNode):
def __init__(self, session, objid=None, name=None, nodedir=None, def __init__(self, session, objid=None, name=None, nodedir=None):
verbose=False):
PyCoreNode.__init__(self, session, objid, name) PyCoreNode.__init__(self, session, objid, name)
self.nodedir = nodedir self.nodedir = nodedir
self.verbose = verbose
self.pid = None self.pid = None
self.up = False self.up = False
self.lock = threading.RLock() self.lock = threading.RLock()
@ -101,16 +102,15 @@ class SimpleJailNode(PyCoreNode):
def startup(self): def startup(self):
if self.up: if self.up:
raise Exception, "already up" raise Exception("already up")
vimg = [constants.VIMAGE_BIN, "-c", self.name] vimg = [constants.VIMAGE_BIN, "-c", self.name]
try: try:
os.spawnlp(os.P_WAIT, constants.VIMAGE_BIN, *vimg) os.spawnlp(os.P_WAIT, constants.VIMAGE_BIN, *vimg)
except OSError: except OSError:
raise Exception, ("vimage command not found while running: %s" % \ raise Exception("vimage command not found while running: %s" % vimg)
vimg) logger.info("bringing up loopback interface")
self.info("bringing up loopback interface")
self.cmd([constants.IFCONFIG_BIN, "lo0", "127.0.0.1"]) self.cmd([constants.IFCONFIG_BIN, "lo0", "127.0.0.1"])
self.info("setting hostname: %s" % self.name) logger.info("setting hostname: %s", self.name)
self.cmd(["hostname", self.name]) self.cmd(["hostname", self.name])
self.cmd([constants.SYSCTL_BIN, "vfs.morphing_symlinks=1"]) self.cmd([constants.SYSCTL_BIN, "vfs.morphing_symlinks=1"])
self.up = True self.up = True
@ -134,11 +134,11 @@ class SimpleJailNode(PyCoreNode):
mode = os.P_WAIT mode = os.P_WAIT
else: else:
mode = os.P_NOWAIT mode = os.P_NOWAIT
tmp = utils.call([constants.VIMAGE_BIN, self.name] + args, cwd=self.nodedir) tmp = subprocess.call([constants.VIMAGE_BIN, self.name] + args, cwd=self.nodedir)
if not wait: if not wait:
tmp = None tmp = None
if tmp: if tmp:
self.warn("cmd exited with status %s: %s" % (tmp, str(args))) logger.warn("cmd exited with status %s: %s", tmp, str(args))
return tmp return tmp
def cmdresult(self, args, wait=True): def cmdresult(self, args, wait=True):
@ -170,8 +170,9 @@ class SimpleJailNode(PyCoreNode):
"-title", self.name, "-e", constants.VIMAGE_BIN, self.name, sh) "-title", self.name, "-e", constants.VIMAGE_BIN, self.name, sh)
def termcmdstring(self, sh="/bin/sh"): def termcmdstring(self, sh="/bin/sh"):
""" We add "sudo" to the command string because the GUI runs as a """
normal user. We add "sudo" to the command string because the GUI runs as a
normal user.
""" """
return "cd %s && sudo %s %s %s" % (self.nodedir, constants.VIMAGE_BIN, self.name, sh) return "cd %s && sudo %s %s %s" % (self.nodedir, constants.VIMAGE_BIN, self.name, sh)
@ -183,11 +184,11 @@ class SimpleJailNode(PyCoreNode):
def mount(self, source, target): def mount(self, source, target):
source = os.path.abspath(source) source = os.path.abspath(source)
self.info("mounting %s at %s" % (source, target)) logger.info("mounting %s at %s", source, target)
self.addsymlink(path=target, file=None) self.addsymlink(path=target, file=None)
def umount(self, target): def umount(self, target):
self.info("unmounting %s" % target) logger.info("unmounting %s", target)
def newveth(self, ifindex=None, ifname=None, net=None): def newveth(self, ifindex=None, ifname=None, net=None):
self.lock.acquire() self.lock.acquire()
@ -204,7 +205,7 @@ class SimpleJailNode(PyCoreNode):
mtu=1500, net=net, start=self.up) mtu=1500, net=net, start=self.up)
if self.up: if self.up:
# install into jail # install into jail
utils.check_call([constants.IFCONFIG_BIN, veth.name, "vnet", self.name]) subprocess.check_call([constants.IFCONFIG_BIN, veth.name, "vnet", self.name])
# rename from "ngeth0" to "eth0" # rename from "ngeth0" to "eth0"
self.cmd([constants.IFCONFIG_BIN, veth.name, "name", ifname]) self.cmd([constants.IFCONFIG_BIN, veth.name, "name", ifname])
@ -223,8 +224,7 @@ class SimpleJailNode(PyCoreNode):
def sethwaddr(self, ifindex, addr): def sethwaddr(self, ifindex, addr):
self._netif[ifindex].sethwaddr(addr) self._netif[ifindex].sethwaddr(addr)
if self.up: if self.up:
self.cmd([constants.IFCONFIG_BIN, self.ifname(ifindex), "link", self.cmd([constants.IFCONFIG_BIN, self.ifname(ifindex), "link", str(addr)])
str(addr)])
def addaddr(self, ifindex, addr): def addaddr(self, ifindex, addr):
if self.up: if self.up:
@ -232,15 +232,14 @@ class SimpleJailNode(PyCoreNode):
family = "inet6" family = "inet6"
else: else:
family = "inet" family = "inet"
self.cmd([constants.IFCONFIG_BIN, self.ifname(ifindex), family, "alias", self.cmd([constants.IFCONFIG_BIN, self.ifname(ifindex), family, "alias", str(addr)])
str(addr)])
self._netif[ifindex].addaddr(addr) self._netif[ifindex].addaddr(addr)
def deladdr(self, ifindex, addr): def deladdr(self, ifindex, addr):
try: try:
self._netif[ifindex].deladdr(addr) self._netif[ifindex].deladdr(addr)
except ValueError: except ValueError:
self.warn("trying to delete unknown address: %s" % addr) logger.warn("trying to delete unknown address: %s", addr)
if self.up: if self.up:
if ":" in addr: if ":" in addr:
family = "inet6" family = "inet6"
@ -255,8 +254,7 @@ class SimpleJailNode(PyCoreNode):
addr = self.getaddr(self.ifname(ifindex), rescan=True) addr = self.getaddr(self.ifname(ifindex), rescan=True)
for t in addrtypes: for t in addrtypes:
if t not in self.valid_deladdrtype: if t not in self.valid_deladdrtype:
raise ValueError, "addr type must be in: " + \ raise ValueError("addr type must be in: " + " ".join(self.valid_deladdrtype))
" ".join(self.valid_deladdrtype)
for a in addr[t]: for a in addr[t]:
self.deladdr(ifindex, a) self.deladdr(ifindex, a)
# update cached information # update cached information
@ -297,8 +295,9 @@ class SimpleJailNode(PyCoreNode):
# return self.vnodeclient.getaddr(ifname = ifname, rescan = rescan) # return self.vnodeclient.getaddr(ifname = ifname, rescan = rescan)
def addsymlink(self, path, file): def addsymlink(self, path, file):
""" Create a symbolic link from /path/name/file -> """
/tmp/pycore.nnnnn/@.conf/path.name/file Create a symbolic link from /path/name/file ->
/tmp/pycore.nnnnn/@.conf/path.name/file
""" """
dirname = path dirname = path
if dirname and dirname[0] == "/": if dirname and dirname[0] == "/":
@ -318,20 +317,15 @@ class SimpleJailNode(PyCoreNode):
os.unlink(pathname) os.unlink(pathname)
else: else:
if os.path.exists(pathname): if os.path.exists(pathname):
self.warn("did not create symlink for %s since path " \ logger.warn("did not create symlink for %s since path exists on host", pathname)
"exists on host" % pathname)
return return
self.info("creating symlink %s -> %s" % (pathname, sym)) logger.info("creating symlink %s -> %s", pathname, sym)
os.symlink(sym, pathname) os.symlink(sym, pathname)
class JailNode(SimpleJailNode): class JailNode(SimpleJailNode):
def __init__(self, session, objid=None, name=None, def __init__(self, session, objid=None, name=None, nodedir=None, bootsh="boot.sh", start=True):
nodedir=None, bootsh="boot.sh", verbose=False, super(JailNode, self).__init__(session=session, objid=objid, name=name, nodedir=nodedir)
start=True):
super(JailNode, self).__init__(session=session, objid=objid,
name=name, nodedir=nodedir,
verbose=verbose)
self.bootsh = bootsh self.bootsh = bootsh
if not start: if not start:
return return
@ -369,8 +363,10 @@ class JailNode(SimpleJailNode):
def privatedir(self, path): def privatedir(self, path):
if path[0] != "/": if path[0] != "/":
raise ValueError, "path not fully qualified: " + path raise ValueError, "path not fully qualified: " + path
hostpath = os.path.join(self.nodedir, hostpath = os.path.join(
os.path.normpath(path).strip("/").replace("/", ".")) self.nodedir,
os.path.normpath(path).strip("/").replace("/", ".")
)
try: try:
os.mkdir(hostpath) os.mkdir(hostpath)
except OSError: except OSError:
@ -383,7 +379,7 @@ class JailNode(SimpleJailNode):
dirname, basename = os.path.split(filename) dirname, basename = os.path.split(filename)
# self.addsymlink(path=dirname, file=basename) # self.addsymlink(path=dirname, file=basename)
if not basename: if not basename:
raise ValueError, "no basename for filename: " + filename raise ValueError("no basename for filename: %s" % filename)
if dirname and dirname[0] == "/": if dirname and dirname[0] == "/":
dirname = dirname[1:] dirname = dirname[1:]
dirname = dirname.replace("/", ".") dirname = dirname.replace("/", ".")
@ -398,4 +394,4 @@ class JailNode(SimpleJailNode):
f.write(contents) f.write(contents)
os.chmod(f.name, mode) os.chmod(f.name, mode)
f.close() f.close()
self.info("created nodefile: %s; mode: 0%o" % (f.name, mode)) logger.info("created nodefile: %s; mode: 0%o", f.name, mode)