aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/tools/test/topos/onos.py
diff options
context:
space:
mode:
authorAshlee Young <ashlee@onosfw.com>2015-09-09 22:15:21 -0700
committerAshlee Young <ashlee@onosfw.com>2015-09-09 22:15:21 -0700
commit13d05bc8458758ee39cb829098241e89616717ee (patch)
tree22a4d1ce65f15952f07a3df5af4b462b4697cb3a /framework/src/onos/tools/test/topos/onos.py
parent6139282e1e93c2322076de4b91b1c85d0bc4a8b3 (diff)
ONOS checkin based on commit tag e796610b1f721d02f9b0e213cf6f7790c10ecd60
Change-Id: Ife8810491034fe7becdba75dda20de4267bd15cd
Diffstat (limited to 'framework/src/onos/tools/test/topos/onos.py')
-rwxr-xr-xframework/src/onos/tools/test/topos/onos.py225
1 files changed, 225 insertions, 0 deletions
diff --git a/framework/src/onos/tools/test/topos/onos.py b/framework/src/onos/tools/test/topos/onos.py
new file mode 100755
index 00000000..3e5bff7c
--- /dev/null
+++ b/framework/src/onos/tools/test/topos/onos.py
@@ -0,0 +1,225 @@
+#!/usr/bin/env python
+
+# TODO add onos-app-fwd to features
+# TODO check if service is running... i think this might already be done by mn
+
+from mininet.node import Controller, OVSSwitch, CPULimitedHost, RemoteController
+from mininet.net import Mininet
+from mininet.cli import CLI
+from mininet.topo import LinearTopo, Topo
+from mininet.log import setLogLevel, info, warn
+from mininet.util import quietRun, numCores
+
+from shutil import copyfile
+from os import environ, path
+from functools import partial
+import time
+from sys import argv
+from time import sleep
+from sets import Set
+
+class ONOS( Controller ):
+ "TODO"
+
+ onosDir = '/opt/onos/'
+
+ def __init__( self, name, onosDir=onosDir,
+ reactive=True, features=[ 'onos-app-tvue' ],
+ **kwargs ):
+ '''TODO'''
+
+ Controller.__init__( self, name, **kwargs )
+ # the following have been done for us:
+ #self.ip = ip ('127.0.0.1')
+ #self.port = port (6633)
+ #self.protocol = protocol ('tcp')
+ #self.checkListening()
+
+ self.onosDir = onosDir
+ self.karafDir = onosDir + 'apache-karaf-3.0.3/'
+ self.instanceDir = self.karafDir
+
+ # add default modules
+ # TODO: consider an ordered set
+ self.features = Set([ 'webconsole',
+ 'onos-rest',
+ 'onos-api',
+ 'onos-cli',
+ 'onos-openflow' ])
+ self.features.update( features )
+ # add reactive forwarding modules
+ if reactive:
+ self.features.update( ['onos-app-fwd',
+ 'onos-app-proxyarp',
+ 'onos-app-mobility' ] )
+ # add the distributed core if we are in a namespace with no trivial core
+ if self.inNamespace and 'onos-core-trivial' not in self.features:
+ self.features.add( 'onos-core' )
+ # if there is no core, add the trivial one
+ if 'onos-core' not in self.features:
+ self.features.add( 'onos-core-trivial' )
+ print self.features
+
+ def start( self ):
+ if self.inNamespace:
+ instanceOpts = ( '-furl mvn:org.onosproject/onos-features/1.3.0-SNAPSHOT/xml/features '
+ '-s 8101' )
+ if self.ip is not None:
+ instanceOpts += (' -a %s' % self.IP() )
+ self.userCmd( self.karafDir + 'bin/instance create %s %s' % ( instanceOpts, self.name ) )
+ self.instanceDir = self.karafDir + 'instances/%s/' % self.name
+ else:
+ # we are running in the root namespace, so let's use the root instance
+ # clean up the data directory
+ #self.userCmd( 'rm -rf '+ self.karafDir + 'data/' )
+ pass
+
+ self.userCmd( 'rm -rf '+ self.instanceDir + 'data/' )
+
+ # Update etc/org.apache.karaf.features.cfg
+ self.updateFeatures()
+
+ # TODO 2. Update etc/hazelcast.xml : interface lines
+ #cp etc/hazelcast.xml instances/c1/etc/
+ self.updateHazelcast()
+
+ # TODO 3. Update etc/system.properties : onos.ip
+ # TODO 4. Update config/cluster.json : with all nodes
+
+ # start onos
+ self.userCmd( '%sbin/instance start -d %s' % ( self.karafDir, self.name ) )
+ #TODO we should wait for startup...
+
+ def stop( self ):
+ self.userCmd( self.instanceDir + 'bin/stop' )
+ #if self.inNamespace:
+ # self.userCmd( self.karafDir + 'bin/instance destroy %s' % self.name )
+ self.terminate()
+
+ def updateHazelcast( self ):
+ hz = '192.168.123.*'
+ if self.ip is not None:
+ hz = '.'.join(self.ip.split('.')[:-1]) + '.*'
+
+ readfile = self.karafDir + 'etc/hazelcast.xml'
+ writefile = self.instanceDir + 'etc/hazelcast.xml'
+ with open( readfile, 'r' ) as r:
+ with open( writefile, 'w' ) as w:
+ for line in r.readlines():
+ if '<interface>' in line:
+ line = '<interface>' + hz + '</interface>\n'
+ w.write( line )
+
+ def updateFeatures( self ):
+ filename = self.instanceDir + 'etc/org.apache.karaf.features.cfg'
+ with open( filename, 'r+' ) as f:
+ lines = f.readlines()
+ f.seek(0)
+ f.truncate()
+ for line in lines:
+ #print '?', line,
+ if 'featuresBoot=' in line:
+ # parse the features from the line
+ features = line.rstrip().split('=')[1].split(',')
+ # add the features to our features set
+ self.features.update( features )
+ # generate the new features line
+ line = 'featuresBoot=' + ','.join( self.features ) + '\n'
+ #print '!', line,
+ f.write( line )
+
+
+ @classmethod
+ def isAvailable( self ):
+ return quietRun( 'ls %s' % self.onosDir )
+
+ def userCmd( self, cmd ):
+ # switch to the non-root user because karaf gets upset otherwise
+ # because the .m2repo is not stored with root
+ cmd = 'sudo -u %s %s' % ( self.findUser(), cmd )
+ return self.cmd( cmd )
+
+ @staticmethod
+ def findUser():
+ "Try to return logged-in (usually non-root) user"
+ try:
+ # If we're running sudo
+ return os.environ[ 'SUDO_USER' ]
+ except:
+ try:
+ # Logged-in user (if we have a tty)
+ return quietRun( 'who am i' ).split()[ 0 ]
+ except:
+ # Give up and return effective user
+ return quietRun( 'whoami' )
+
+
+class ControlNetwork( Topo ):
+ "Control Network Topology"
+ def __init__( self, n, dataController=ONOS, **kwargs ):
+ """n: number of data network controller nodes
+ dataController: class for data network controllers"""
+ Topo.__init__( self, **kwargs )
+ # Connect everything to a single switch
+ cs0 = self.addSwitch( 'cs0' )
+ # Add hosts which will serve as data network controllers
+ for i in range( 1, n+1 ):
+ c = self.addHost( 'c%s' % i, cls=dataController,
+ inNamespace=True )
+ self.addLink( c, cs0 )
+ # Connect switch to root namespace so that data network
+ # switches will be able to talk to us
+ root = self.addHost( 'root', inNamespace=False )
+ self.addLink( root, cs0 )
+
+class ONOSCluster( Controller ):
+ # TODO
+ n = 3
+
+ def start( self ):
+ ctopo = ControlNetwork( n=self.n, dataController=ONOS )
+ self.cnet = Mininet( topo=ctopo, ipBase='192.168.123.0/24', controller=None )
+ self.cnet.addController( 'cc0', controller=Controller )
+ self.cnet.start()
+
+ self.ctrls = []
+ for host in self.cnet.hosts:
+ if isinstance( host, Controller ):
+ self.ctrls.append( host )
+ host.start()
+
+ def stop( self ):
+ for host in self.cnet.hosts:
+ if isinstance( host, Controller ):
+ host.stop()
+ self.cnet.stop()
+
+ def clist( self ):
+ "Return list of Controller proxies for this ONOS cluster"
+ print 'controllers:', self.ctrls
+ return self.ctrls
+
+class OVSSwitchONOS( OVSSwitch ):
+ "OVS switch which connects to multiple controllers"
+ def start( self, controllers ):
+ assert len( controllers ) == 1
+ c0 = controllers[ 0 ]
+ assert type( c0 ) == ONOSCluster
+ controllers = c0.clist()
+ OVSSwitch.start( self, controllers )
+
+controllers = { 'onos': ONOS }
+switches = { 'ovso': OVSSwitchONOS }
+
+if __name__ == '__main__':
+ # Simple test for ONOS() controller class
+ setLogLevel( 'info' ) #TODO info
+ size = 2 if len( argv ) != 2 else int( argv[ 1 ] )
+ net = Mininet( topo=LinearTopo( size ),
+ #controller=ONOS,
+ controller=partial( ONOSCluster, n=3 ), #TODO
+ switch=OVSSwitchONOS )
+ net.start()
+ #waitConnected( net.switches )
+ CLI( net )
+ net.stop()