-import Pyro4
import time
+import zerorpc
def main():
# create connection to remote Mininet instance
- rmn = Pyro4.Proxy("PYRONAME:remote.mininet")
+ c = zerorpc.Client()
+ c.connect("tcp://127.0.0.1:4242")
# do some API tests
- h1 = rmn.addHost('h1')
- h2 = rmn.addHost('h2')
- d1 = rmn.addDocker('d1', ip='10.0.0.253', dimage="ubuntu")
+ h1 = c.addHost('h1')
+ h2 = c.addHost('h2')
+ d1 = c.addDocker('d1', "ubuntu", "10.0.0.253")
- s1 = rmn.addSwitch("s1")
+ s1 = c.addSwitch("s1")
- rmn.addLink(h1, s1)
- rmn.addLink(h2, s1)
- rmn.addLink(d1, s1)
+ c.addLink(h1, s1)
+ c.addLink(h2, s1)
+ c.addLink(d1, s1)
- rmn.start()
+ c.start_net()
+ c.CLI()
# check functionality at runtime
"""
- d2 = rmn.addDocker('d2', dimage="ubuntu")
- h3 = rmn.addHost('h3', ip='10.0.0.200')
- rmn.addLink(d2, s1, params1={"ip": "10.0.0.251/8"})
+ d2 = c.addDocker('d2', dimage="ubuntu")
+ h3 = c.addHost('h3', ip='10.0.0.200')
+ c.addLink(d2, s1, params1={"ip": "10.0.0.251/8"})
time.sleep(2)
- rmn.removeLink(node1="h1", node2="s1")
- rmn.removeHost('h1')
- #rmn.removeHost('d1')
+ c.removeLink(node1="h1", node2="s1")
+ c.removeHost('h1')
+ #c.removeHost('d1')
"""
time.sleep(2)
- rmn.stop()
+ c.stop_net()
if __name__ == '__main__':
import mininet.log
import logging
import os
-import Pyro4
+import zerorpc
class RemoteMininetNetwork(object):
def __init__(self):
- mininet.log.setLogLevel( 'debug' )
+ # set mininet loglevel
+ mininet.log.setLogLevel( 'info' )
self.net = Mininet( controller=Controller )
self.net.addController( 'c0' )
- def start(self):
+ def start_net(self):
self.net.start()
def CLI(self):
CLI(self.net)
- def stop(self):
+ def stop_net(self):
try:
self.net.stop()
except Exception as e:
print e
+ def addHost(self, name, ip=None):
+ return str(self.net.addHost(name, ip=ip))
- def addHost(self, name, cls=None, **params):
- return str(self.net.addHost(name, cls=cls, **params))
+ def addDocker(self, name, dimage, ip):
+ return str(self.net.addDocker(name, dimage=dimage, ip=ip))
- def addDocker(self, name, **params):
- return str(self.net.addDocker(name, **params))
-
- def addSwitch(self, name, **params):
+ def addSwitch(self, name):
# we have to use OVSSwitch to be able to do link attachments
# at runtime (switch.attach) method
- return str(self.net.addSwitch(name, cls=OVSSwitch, **params))
+ return str(self.net.addSwitch(name, cls=OVSSwitch))
- def addLink(self, node1, node2, port1=None, port2=None,
- cls=None, **params):
+ def addLink(self, node1, node2, port1=None, port2=None):
return str(self.net.addLink(node1, node2,
- port1, port2, cls=cls, **params))
+ port1, port2))
- def removeHost(self, name, **params):
- return self.net.removeHost(name, **params)
+ def removeHost(self, name):
+ return self.net.removeHost(name)
def removeLink(self, link=None, node1=None, node2=None):
n1, n2 = self.net.get(node1), self.net.get(node2)
def start_server():
- daemon = Pyro4.Daemon()
- # ATTENTION:
- # we need a PyroNS instance to be running: pyro4-ns (in new terminal)
- ns = Pyro4.locateNS()
- uri = daemon.register(RemoteMininetNetwork())
- # map object URI to a nice name
- ns.register("remote.mininet", uri)
-
- logging.info("Server URI is: %s", uri)
-
- # Start the server...
- daemon.requestLoop()
+ s = zerorpc.Server(RemoteMininetNetwork())
+ s.bind("tcp://0.0.0.0:4242")
+ s.run()
--- /dev/null
+"""
+Distributed Cloud Emulator (dcemulator)
+(c) 2015 by Manuel Peuster <manuel.peuster@upb.de>
+"""
\ No newline at end of file
--- /dev/null
+"""
+Distributed Cloud Emulator (dcemulator)
+(c) 2015 by Manuel Peuster <manuel.peuster@upb.de>
+"""
+import logging
+
+from mininet.net import Mininet
+from mininet.node import Controller, OVSKernelSwitch, Switch
+from mininet.cli import CLI
+from mininet.log import setLogLevel, info
+from mininet.link import TCLink, Link
+
+from node import Datacenter
+
+
+class DCNetwork(object):
+
+ def __init__(self):
+ self.dcs = {}
+ self.switches = {}
+ self.links = []
+
+ # create a Mininet/Dockernet network
+ setLogLevel('info') # set Mininet loglevel
+ self.mnet = Mininet(controller=Controller, switch=OVSKernelSwitch)
+ self.mnet.addController('c0')
+
+ def addDatacenter(self, name):
+ """
+ Create and add a logical cloud data center to the network.
+ """
+ if name in self.dcs:
+ raise Exception("Data center name already exists: %s" % name)
+ dc = Datacenter(name)
+ dc.net = self # set reference to network
+ self.dcs[name] = dc
+ dc.create() # finally create the data center in our Mininet instance
+ logging.info("added data center: %s" % name)
+ return dc
+
+ def addSwitch(self, name):
+ """
+ We can also add additional SDN switches between data centers.
+ """
+ s = self.mnet.addSwitch(name)
+ self.switches[name] = s
+ logging.info("added switch: %s" % name)
+ return s
+
+ def addLink(self, node1, node2):
+ assert node1 is not None
+ assert node2 is not None
+ # ensure type of node1
+ if isinstance( node1, basestring ):
+ if node1 in self.dcs:
+ node1 = self.dcs[node1].switch
+ elif node1 in self.switches:
+ node1 = self.switches[node1]
+ if isinstance( node1, Datacenter ):
+ node1 = node1.switch
+ # ensure type of node2
+ if isinstance( node2, basestring ):
+ if node2 in self.dcs:
+ node2 = self.dcs[node2].switch
+ elif node2 in self.switches:
+ node2 = self.switches[node2]
+ if isinstance( node2, Datacenter ):
+ node2 = node2.switch
+ # create link if everything is correct
+ if (node1 is not None and isinstance(node1, OVSKernelSwitch)
+ and node2 is not None and isinstance(node2, OVSKernelSwitch)):
+ self.mnet.addLink(node1, node2) # TODO we need TCLinks with user defined performance her
+ else:
+ raise Exception(
+ "one of the given nodes is not a Mininet switch or None")
+
+ def start(self):
+ # start
+ for dc in self.dcs.itervalues():
+ dc.start()
+ self.mnet.start()
+
+ def stop(self):
+ self.mnet.stop()
+
+ def CLI(self):
+ CLI(self.mnet)
+
--- /dev/null
+"""
+Distributed Cloud Emulator (dcemulator)
+(c) 2015 by Manuel Peuster <manuel.peuster@upb.de>
+"""
+import logging
+
+
+DCDPID_BASE = 1000 # start of switch dpid's used for data center switches
+
+
+class Datacenter(object):
+ """
+ Represents a logical data center to which compute resources
+ (Docker containers) can be added at runtime.
+ """
+
+ def __init__(self, name):
+ self.net = None # DCNetwork to which we belong
+ self.name = name
+ self.switch = None # first prototype assumes one "bigswitch" per DC
+
+ def _get_next_dc_dpid(self):
+ global DCDPID_BASE
+ DCDPID_BASE += 1
+ return DCDPID_BASE
+
+ def create(self):
+ """
+ Each data center is represented by a single switch to which
+ compute resources can be connected at run time.
+
+ TODO: This will be changes in the future to support multiple networks
+ per data center
+ """
+ self.switch = self.net.mnet.addSwitch(
+ "%s.s1" % self.name, dpid=hex(self._get_next_dc_dpid())[2:])
+ logging.debug("created data center switch: %s" % str(self.switch))
+
+ def start(self):
+ pass
+
+ def addCompute(self):
+ pass
+
+ def removeCompute(self):
+ pass
--- /dev/null
+"""
+This is an example topology for the distributed cloud emulator (dcemulator).
+(c) 2015 by Manuel Peuster <manuel.peuster@upb.de>
+
+The original Mininet API has to be completely hidden and not be used by this
+script.
+"""
+import logging
+from dcemulator.net import DCNetwork
+
+logging.basicConfig(level=logging.DEBUG)
+
+
+def create_topology1():
+ # initialize network
+ net = DCNetwork()
+
+ # add data centers
+ dc1 = net.addDatacenter("dc1")
+ dc2 = net.addDatacenter("dc2")
+ dc3 = net.addDatacenter("dc3")
+ dc4 = net.addDatacenter("dc4")
+ # add additional SDN switches to our topology
+ s1 = net.addSwitch("s1")
+ # add links between data centers
+ net.addLink(dc1, dc2)
+ net.addLink("dc1", s1)
+ net.addLink(s1, "dc3")
+ net.addLink(s1, dc4)
+ # start network
+ net.start()
+ net.CLI() # TODO remove this when we integrate APIs?
+ net.stop() # TODO remove this when we integrate APIs?
+ # start APIs (to access emulated cloud data centers)
+ pass # TODO: how to reflect one API endpoint per DC?
+
+
+def main():
+ create_topology1()
+
+
+if __name__ == '__main__':
+ main()