blob: 83ac619e3676925496b6ff2528833075ed8ad957 [file] [log] [blame]
"""
Distributed Cloud Emulator (dcemulator)
(c) 2015 by Manuel Peuster <manuel.peuster@upb.de>
"""
import logging
from mininet.net import Dockernet
from mininet.node import Controller, OVSKernelSwitch, Switch, Docker, Host
from mininet.cli import CLI
from mininet.log import setLogLevel, info
from mininet.link import TCLink, Link
from node import Datacenter, EmulatorCompute
class DCNetwork(object):
"""
Wraps the original Mininet class and provides
methods to add data centers, switches, etc.
This class is used by topology definition scripts.
"""
def __init__(self):
self.dcs = {}
self.switches = {}
self.links = []
# create a Mininet/Dockernet network
setLogLevel('info') # set Mininet loglevel
self.mnet = Dockernet(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, **params):
"""
Able to handle Datacenter objects as link
end points.
"""
assert node1 is not None
assert node2 is not None
logging.debug("addLink: n1=%s n2=%s" % (str(node1), str(node2)))
# 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
# try to give containers a default IP
if isinstance( node1, Docker ):
if not "params1" in params:
params["params1"] = {}
if not "ip" in params["params1"]:
params["params1"]["ip"] = self.getNextIp()
if isinstance( node2, Docker ):
if not "params2" in params:
params["params2"] = {}
if not "ip" in params["params2"]:
params["params2"]["ip"] = self.getNextIp()
return self.mnet.addLink(node1, node2, **params) # TODO we need TCLinks with user defined performance here
def removeLink(self, link=None, node1=None, node2=None):
"""
Removes a link. Can either be specified by link object,
or the nodes the link connects. Wraps Dockernet method.
"""
logging.debug("removeLink: n1=%s n2=%s" % (str(node1), str(node2)))
return self.mnet.removeLink(link=link, node1=node1, node2=node2)
def addDocker( self, name, **params ):
"""
Wrapper for addDocker method provided by Dockernet.
"""
return self.mnet.addDocker( name, cls=EmulatorCompute, **params)
def removeDocker( self, name, **params):
"""
Wrapper for removeHost. Just to be complete.
"""
return self.mnet.removeDocker(name, **params)
def getNextIp(self):
return self.mnet.getNextIp()
def getAllContainers(self):
"""
Returns a list with all containers within all data centers.
"""
all_containers = []
for dc in self.dcs.itervalues():
all_containers += dc.listCompute()
return all_containers
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)