import subprocess
import sioc
import re
+import vserver
+import os
dryrun=0
setup_link_cmd="/usr/share/vini/setup-egre-link"
teardown_link_cmd="/usr/share/vini/teardown-egre-link"
ifaces = {}
+old_ifaces = {}
def run(cmd):
if dryrun:
"""
def virtual_link(key, nodeid):
name = "d%sx%s" % (key, nodeid)
- # logger.log("Looking for iface %s" % name)
if name in ifaces:
return True
else:
The key is used to create the EGRE tunnel.
"""
def setup_virtual_link(slice, key, rate, myid, nodeid, ipaddr):
- logger.log("Set up virtual link to node %d" % nodeid)
+ logger.log("%s: Set up virtual link to node %d" % (slice, nodeid))
if myid < nodeid:
virtip = "10.%d.%d.2" % (myid, nodeid)
else:
"""
Tear down the "virtual link" for slice between here and nodeid.
"""
-def teardown_virtual_link(slice, key, nodeid):
- logger.log("Tear down virtual link to node %s" % nodeid)
- run(teardown_link_cmd + " %s %s %s" % (slice, nodeid, key))
+def teardown_virtual_link(key, nodeid):
+ logger.log("topo: Tear down virtual link %sx%s" % (key, nodeid))
+ run(teardown_link_cmd + " %s %s" % (nodeid, key))
return
+"""
+Called for all active virtual link interfaces, so they won't be cleaned up.
+"""
+def refresh_virtual_link(nodeid, key):
+ try:
+ name = "d%sx%s" % (key, nodeid)
+ del old_ifaces[name]
+ except:
+ pass
+
+
"""
Clean up old virtual links (e.g., to nodes that have been deleted
from the slice).
"""
-def clean_up_old_virtual_links(slice, key, nodelist):
- pattern = "d%sx(.*)" % key
- for iface in ifaces:
+def clean_up_old_virtual_links():
+ pattern = "d(.*)x(.*)"
+ for iface in old_ifaces:
m = re.match(pattern, iface)
if m:
- node = int(m.group(1))
- if not node in nodelist:
- logger.log("%s" % nodelist)
- teardown_virtual_link(slice, key, node)
+ key = int(m.group(1))
+ node = int(m.group(2))
+ teardown_virtual_link(key, node)
"""
"""
Update virtual links for the slice
"""
-def update(slice, myid, topospec, key):
+def update(slice, myid, topospec, key, netns):
topolist = convert_topospec_to_list(topospec)
- nodelist=[]
for (nodeid,ipaddr,rate) in topolist:
- nodelist.append(nodeid)
if not virtual_link(key, nodeid):
- setup_virtual_link(slice, key, rate, myid, nodeid, ipaddr)
+ if netns:
+ setup_virtual_link(slice, key, rate, myid, nodeid, ipaddr)
else:
- logger.log("Virtual link to node %s exists" % nodeid)
+ logger.log("%s: virtual link to node %s exists" % (slice, nodeid))
+ refresh_virtual_link(nodeid, key)
- clean_up_old_virtual_links(slice, key, nodelist)
+"""
+Write /etc/vservers/<slicename>/spaces/net
+"""
+def writeConf(slicename, value):
+ SLICEDIR="/etc/vservers/%s/" % slicename
+ SPACESDIR="%s/spaces/" % SLICEDIR
+ if os.path.exists(SLICEDIR):
+ if not os.path.exists(SPACESDIR):
+ try:
+ os.mkdir(SPACESDIR)
+ except os.error:
+ logger.log("netns: could not create %s\n" % SPACESDIR)
+ return
+ f = open("%s/net" % SPACESDIR, "w")
+ f.write("%s\n" % value)
+ f.close()
+ STATUS="OFF"
+ if int(value) >= 1:
+ STATUS="ON"
+ logger.log("%s: network namespace %s\n" % (slicename, STATUS))
def start(options, config):
"""
Update the virtual links for a sliver if it has a 'netns' attribute,
an 'egre_key' attribute, and a 'topo_rspec' attribute.
+
+Creating the virtual link depends on the contents of
+/etc/vservers/<slice>/spaces/net. Update this first.
"""
def GetSlivers(data):
- global ifaces
- ifaces = sioc.gifconf()
+ global ifaces, old_ifaces
+ ifaces = old_ifaces = sioc.gifconf()
for sliver in data['slivers']:
attrs = {}
for attribute in sliver['attributes']:
attrs[attribute['name']] = attribute['value']
- if 'netns' in attrs and 'egre_key' in attrs and 'topo_rspec' in attrs:
- if attrs['netns'] > 0:
- logger.log("Update topology for slice %s" % sliver['name'])
- update(sliver['name'], data['node_id'],
- attrs['topo_rspec'], attrs['egre_key'])
+ if 'netns' in attrs:
+ writeConf(sliver['name'], attrs['netns'])
+ netns = attrs['netns']
+ else:
+ netns = 0
+
+ try:
+ if vserver.VServer(sliver['name']).is_running():
+ if 'egre_key' in attrs and 'topo_rspec' in attrs:
+ logger.log("topo: Update topology for slice %s" % \
+ sliver['name'])
+ update(sliver['name'], data['node_id'],
+ attrs['topo_rspec'], attrs['egre_key'], netns)
+ except:
+ logger.log("topo: sliver %s not running yet. Deferring." % \
+ sliver['name'])
+
+ clean_up_old_virtual_links()
+