adding onos.py, a work in progress
Change-Id: Idfc2087fd8be2ffa24e7e93c2744fa8b1d46811b
Showing
1 changed file
with
169 additions
and
0 deletions
tools/test/topos/onos.py
0 → 100755
1 | +#!/usr/bin/env python | ||
2 | + | ||
3 | +# TODO add onos-app-fwd to features | ||
4 | +# TODO check if service is running... i think this might already be done by mn | ||
5 | + | ||
6 | +from mininet.node import Controller, OVSSwitch, CPULimitedHost, RemoteController | ||
7 | +from mininet.net import Mininet | ||
8 | +from mininet.cli import CLI | ||
9 | +from mininet.topo import LinearTopo, Topo | ||
10 | +from mininet.log import setLogLevel, info, warn | ||
11 | +from mininet.util import quietRun, numCores | ||
12 | + | ||
13 | +from shutil import copyfile | ||
14 | +from os import environ, path | ||
15 | +from functools import partial | ||
16 | +import time | ||
17 | +from sys import argv | ||
18 | +from time import sleep | ||
19 | + | ||
20 | +class ONOS( Controller ): | ||
21 | + #def __init__( self, name, command='/opt/onos/bin/onos-service', **kwargs ): | ||
22 | + # Controller.__init__( self, name, command=command, inNamespace=True, **kwargs ) | ||
23 | + #def __init__( self, name, inNamespace=False, command='controller', | ||
24 | + # cargs='-v ptcp:%d', cdir=None, ip="127.0.0.1", | ||
25 | + # port=6633, protocol='tcp', **params ): | ||
26 | + #self.command = command | ||
27 | + #self.cargs = cargs | ||
28 | + #self.cdir = cdir | ||
29 | + #self.ip = ip | ||
30 | + #self.port = port | ||
31 | + #self.protocol = protocol | ||
32 | + #Node.__init__( self, name, inNamespace=inNamespace, | ||
33 | + # ip=ip, **params ) | ||
34 | + #self.checkListening() | ||
35 | + | ||
36 | + ONOS_DIR = '/opt/onos/' | ||
37 | + KARAF_DIR = ONOS_DIR + 'apache-karaf-3.0.1/' | ||
38 | + reactive = True | ||
39 | + | ||
40 | + def start( self ): | ||
41 | + # switch to the non-root user because karaf gets upset otherwise | ||
42 | + # TODO we should look into why.... | ||
43 | + self.sendCmd( 'sudo su - %s' % self.findUser() ) | ||
44 | + self.waiting = False | ||
45 | + | ||
46 | + if self.inNamespace: | ||
47 | + self.cmd( self.KARAF_DIR + 'bin/instance create %s' % self.name ) | ||
48 | + src = self.KARAF_DIR + 'etc/org.apache.karaf.features.cfg' | ||
49 | + dst = self.KARAF_DIR + 'instances/%s/etc/org.apache.karaf.features.cfg' % self.name | ||
50 | + self.cmd( 'cp %s %s' % (src, dst) ) | ||
51 | + self.updateProperties( dst ) | ||
52 | + self.cmd( self.KARAF_DIR + 'bin/instance start %s' % self.name ) | ||
53 | + else: | ||
54 | + # we are running in the root namespace, so let's use the root instance | ||
55 | + self.cmd( 'rm -rf '+ self.KARAF_DIR + 'data/' ) | ||
56 | + filename = self.KARAF_DIR + 'etc/org.apache.karaf.features.cfg' | ||
57 | + self.updateProperties( filename ) | ||
58 | + self.cmd( self.KARAF_DIR + 'bin/start' ) | ||
59 | + | ||
60 | + #TODO we should wait for startup... | ||
61 | + | ||
62 | + def stop( self ): | ||
63 | + if self.inNamespace: | ||
64 | + self.cmd( '/opt/onos/apache-karaf-3.0.1/bin/instance stop %s' % self.name ) | ||
65 | + self.cmd( '/opt/onos/apache-karaf-3.0.1/bin/instance destroy %s' % self.name ) | ||
66 | + else: | ||
67 | + self.cmd( self.ONOS_DIR + 'apache-karaf-3.0.1/bin/stop' ) | ||
68 | + self.terminate() | ||
69 | + | ||
70 | + def updateProperties( self, filename ): | ||
71 | + with open( filename, 'r+' ) as f: | ||
72 | + lines = f.readlines() | ||
73 | + f.seek(0) | ||
74 | + f.truncate() | ||
75 | + for line in lines: | ||
76 | + #print '?', line, | ||
77 | + if 'featuresBoot=' in line: | ||
78 | + line = line.rstrip() | ||
79 | + #print ord(line[-1]), ord(line[-2]), ord(line[-3]) | ||
80 | + if self.reactive: | ||
81 | + line += ',onos-app-fwd' | ||
82 | + line += '\n' | ||
83 | + #print '!', line, | ||
84 | + f.write( line ) | ||
85 | + | ||
86 | + @classmethod | ||
87 | + def isAvailable( self ): | ||
88 | + return quietRun( 'ls /opt/onos' ) | ||
89 | + | ||
90 | + @staticmethod | ||
91 | + def findUser(): | ||
92 | + "Try to return logged-in (usually non-root) user" | ||
93 | + try: | ||
94 | + # If we're running sudo | ||
95 | + return os.environ[ 'SUDO_USER' ] | ||
96 | + except: | ||
97 | + try: | ||
98 | + # Logged-in user (if we have a tty) | ||
99 | + return quietRun( 'who am i' ).split()[ 0 ] | ||
100 | + except: | ||
101 | + # Give up and return effective user | ||
102 | + return quietRun( 'whoami' ) | ||
103 | + | ||
104 | + | ||
105 | +class ControlNetwork( Topo ): | ||
106 | + "Control Network Topology" | ||
107 | + def __init__( self, n, dataController=ONOS, **kwargs ): | ||
108 | + """n: number of data network controller nodes | ||
109 | + dataController: class for data network controllers""" | ||
110 | + Topo.__init__( self, **kwargs ) | ||
111 | + # Connect everything to a single switch | ||
112 | + cs0 = self.addSwitch( 'cs0' ) | ||
113 | + # Add hosts which will serve as data network controllers | ||
114 | + for i in range( 0, n ): | ||
115 | + c = self.addHost( 'c%s' % i, cls=dataController, | ||
116 | + inNamespace=True ) | ||
117 | + self.addLink( c, cs0 ) | ||
118 | + # Connect switch to root namespace so that data network | ||
119 | + # switches will be able to talk to us | ||
120 | + root = self.addHost( 'root', inNamespace=False ) | ||
121 | + self.addLink( root, cs0 ) | ||
122 | + | ||
123 | +class ONOSCluster( Controller ): | ||
124 | + # TODO | ||
125 | + n = 4 | ||
126 | + | ||
127 | + def start( self ): | ||
128 | + ctopo = ControlNetwork( n=self.n, dataController=ONOS ) | ||
129 | + self.cnet = Mininet( topo=ctopo, ipBase='192.168.123.0/24', controller=None ) | ||
130 | + self.cnet.addController( 'cc0', controller=Controller ) | ||
131 | + self.cnet.start() | ||
132 | + | ||
133 | + self.ctrls = [] | ||
134 | + for host in self.cnet.hosts: | ||
135 | + if isinstance( host, Controller ): | ||
136 | + self.ctrls.append( host ) | ||
137 | + host.start() | ||
138 | + | ||
139 | + def stop( self ): | ||
140 | + self.cnet.stop() | ||
141 | + | ||
142 | + def clist( self ): | ||
143 | + "Return list of Controller proxies for this ONOS cluster" | ||
144 | + print 'controllers:', self.ctrls | ||
145 | + return self.ctrls | ||
146 | + | ||
147 | +class OVSSwitchONOS( OVSSwitch ): | ||
148 | + "OVS switch which connects to multiple controllers" | ||
149 | + def start( self, controllers ): | ||
150 | + assert len( controllers ) == 1 | ||
151 | + c0 = controllers[ 0 ] | ||
152 | + assert type( c0 ) == ONOSCluster | ||
153 | + controllers = c0.clist() | ||
154 | + OVSSwitch.start( self, controllers ) | ||
155 | + | ||
156 | +controllers = { 'onos': ONOS } | ||
157 | +switches = { 'ovso': OVSSwitchONOS } | ||
158 | + | ||
159 | +if __name__ == '__main__': | ||
160 | + # Simple test for ONOS() controller class | ||
161 | + setLogLevel( 'info' ) | ||
162 | + size = 2 if len( argv ) != 2 else int( argv[ 1 ] ) | ||
163 | + net = Mininet( topo=LinearTopo( size ), | ||
164 | + controller=partial( ONOSCluster, n=4 ), | ||
165 | + switch=OVSSwitchONOS ) | ||
166 | + net.start() | ||
167 | + #waitConnected( net.switches ) | ||
168 | + CLI( net ) | ||
169 | + net.stop() |
-
Please register or login to post a comment