Virtual topology plugin for NodeManager
[nodemanager-topo.git] / topo.py
1 # $Id$
2 # $URL$
3
4 """ 
5 VINI/Trellis NodeManager plugin.
6 Create virtual links from the topo_rspec slice attribute. 
7 """
8
9 import logger
10 import subprocess
11 import sioc
12 import re
13
14 dryrun=0
15 setup_link_cmd="/usr/share/vini/setup-egre-link"
16 teardown_link_cmd="/usr/share/vini/teardown-egre-link"
17 ifaces = {}
18
19 def run(cmd):
20     if dryrun:
21         logger.log(cmd)
22         return -1
23     else:
24         return subprocess.call(cmd, shell=True);
25
26
27 """
28 Check for existence of interface a<key>x<nodeid>
29 """
30 def virtual_link(key, nodeid):
31     name = "d%sx%s" % (key, nodeid)
32     if name in ifaces:
33         return True
34     else:
35         return False
36
37
38 """
39 Create a "virtual link" for slice between here and nodeid.
40 The key is used to create the EGRE tunnel.
41 """
42 def setup_virtual_link(slice, key, rate, myid, nodeid, ipaddr):
43     if myid < nodeid:
44         virtip = "10.%d.%d.2" % (myid, nodeid)
45     else:
46         virtip = "10.%d.%d.3" % (nodeid, myid)
47         
48     run(setup_link_cmd + " %s %s %s %s %s %s" % (slice, nodeid, ipaddr, 
49                                                  key, rate, virtip))
50     return
51
52
53 """
54 Tear down the "virtual link" for slice between here and nodeid.
55 """
56 def teardown_virtual_link(slice, key, nodeid):
57     logger.log("Tear down virtual link to node %d" % nodeid)
58     run(teardown_link_cmd + " %s %s %s" % (slice, nodeid, key))
59     return
60
61
62 """
63 Clean up old virtual links (e.g., to nodes that have been deleted 
64 from the slice).
65 """
66 def clean_up_old_virtual_links(slice, key, nodelist):
67     pattern = "d%sx(.*)" % key
68     for iface in ifaces:
69         m = re.match(pattern, iface)
70         if m:
71             node = m.group(1)
72             if not node in nodelist:
73                 teardown_virtual_link(slice, key, node)
74
75
76 """
77 Not the safest thing to do, probably should use pickle() or something.
78 """
79 def convert_topospec_to_list(rspec):
80     return eval(rspec)
81
82
83 """
84 Update virtual links for the slice
85 """
86 def update(slice, myid, topospec, key):
87     topolist = convert_topospec_to_list(topospec)
88     nodelist=[]
89     for (nodeid,ipaddr,rate) in topolist:
90         nodelist.append(nodeid)
91         if not virtual_link(key, nodeid):
92             setup_virtual_link(slice, key, rate, myid, nodeid, ipaddr)
93         else:
94             logger.log("Virtual link to node %s exists" % nodeid)
95
96     clean_up_old_virtual_links(slice, key, nodelist)
97
98
99 def start(options, config):
100     pass
101
102
103 """
104 Update the virtual links for a sliver if it has a 'netns' attribute,
105 an 'egre_key' attribute, and a 'topo_rspec' attribute.
106 """
107 def GetSlivers(data):
108     global ifaces
109     ifaces = sioc.gifconf()
110
111     for sliver in data['slivers']:
112         attrs = {}
113         for attribute in sliver['attributes']:
114             attrs[attribute['name']] = attribute['value']
115         if 'netns' in attrs and 'egre_key' in attrs and 'topo_rspec' in attrs:
116             if attrs['netns'] > 0:
117                 logger.log("Update topology for slice %s" % sliver['name'])
118                 update(sliver['name'], data['node_id'], 
119                        attrs['topo_rspec'], attrs['egre_key'])
120