import logging
import site
+import time
from subprocess import Popen
import os
from mininet.net import Dockernet
-from mininet.node import Controller, OVSSwitch, OVSKernelSwitch, Switch, Docker, Host, RemoteController
+from mininet.node import Controller, DefaultController, OVSSwitch, OVSKernelSwitch, Docker, RemoteController
from mininet.cli import CLI
-from mininet.log import setLogLevel, info, debug
-from mininet.link import TCLink, Link
+from mininet.link import TCLink
import networkx as nx
from emuvim.dcemulator.monitoring import DCNetworkMonitor
-
from emuvim.dcemulator.node import Datacenter, EmulatorCompute
+from emuvim.dcemulator.resourcemodel import ResourceModelRegistrar
class DCNetwork(Dockernet):
This class is used by topology definition scripts.
"""
- def __init__(self, **kwargs):
+ def __init__(self, controller=RemoteController,
+ dc_emulation_max_cpu=1.0, # fraction of overall CPU time for emulation
+ dc_emulation_max_mem=512, # emulation max mem in MB
+ **kwargs):
+ """
+ Create an extended version of a Dockernet network
+ :param dc_emulation_max_cpu: max. CPU time used by containers in data centers
+ :param kwargs: path through for Mininet parameters
+ :return:
+ """
self.dcs = {}
- # create a Mininet/Dockernet network
+
# call original Docker.__init__ and setup default controller
- #Dockernet.__init__(
- # self, controller=RemoteController, switch=OVSKernelSwitch, **kwargs)
Dockernet.__init__(
- self, controller=RemoteController, switch=OVSKernelSwitch, **kwargs)
- self.addController('c0', controller=RemoteController)
+ self, switch=OVSKernelSwitch, **kwargs)
+
+ # Ryu management
+ self.ryu_process = None
+ if controller == RemoteController:
+ # start Ryu controller
+ self.startRyu()
+
+ # add the specified controller
+ self.addController('c0', controller=controller)
# graph of the complete DC network
- self.DCNetwork_graph=nx.DiGraph()
+ self.DCNetwork_graph = nx.DiGraph()
# monitoring agent
self.monitor_agent = DCNetworkMonitor(self)
- # start Ryu controller
- self.startRyu()
-
+ # initialize resource model registrar
+ self.rm_registrar = ResourceModelRegistrar(
+ dc_emulation_max_cpu, dc_emulation_max_mem)
def addDatacenter(self, label, metadata={}):
"""
node2 = node2.switch
# try to give containers a default IP
if isinstance( node1, Docker ):
- if not "params1" in params:
+ if "params1" not in params:
params["params1"] = {}
- if not "ip" in params["params1"]:
+ if "ip" not in params["params1"]:
params["params1"]["ip"] = self.getNextIp()
if isinstance( node2, Docker ):
- if not "params2" in params:
+ if "params2" not in params:
params["params2"] = {}
- if not "ip" in params["params2"]:
+ if "ip" not in params["params2"]:
params["params2"]["ip"] = self.getNextIp()
+ # ensure that we allow TCLinks between data centers
+ # TODO this is not optimal, we use cls=Link for containers and TCLink for data centers
+ # see Dockernet issue: https://github.com/mpeuster/dockernet/issues/3
+ if "cls" not in params:
+ params["cls"] = TCLink
- link = Dockernet.addLink(self, node1, node2, **params) # TODO we need TCLinks with user defined performance here
+ link = Dockernet.addLink(self, node1, node2, **params)
# add edge and assigned port number to graph in both directions between node1 and node2
self.DCNetwork_graph.add_edge(node1.name, node2.name, \
def stop(self):
# stop Ryu controller
- self.ryu_process.terminate()
- #self.ryu_process.kill()
Dockernet.stop(self)
+ self.stopRyu()
def CLI(self):
CLI(self)
# start Ryu controller with rest-API
python_install_path = site.getsitepackages()[0]
ryu_path = python_install_path + '/ryu/app/simple_switch_13.py'
- ryu_path2 = python_install_path + '/ryu/app/ofctl_rest.py'
+ ryu_path2 = python_install_path + '/ryu/app/ofctl_rest.py'
# change the default Openflow controller port to 6653 (official IANA-assigned port number), as used by Mininet
# Ryu still uses 6633 as default
ryu_option = '--ofp-tcp-listen-port'
ryu_of_port = '6653'
- ryu_cmd = 'ryu-manager'
- FNULL = open(os.devnull, 'w')
- self.ryu_process = Popen([ryu_cmd, ryu_path, ryu_path2, ryu_option, ryu_of_port], stdout=FNULL, stderr=FNULL)
\ No newline at end of file
+ ryu_cmd = 'ryu-manager'
+ FNULL = open("/tmp/ryu.log", 'w')
+ self.ryu_process = Popen([ryu_cmd, ryu_path, ryu_path2, ryu_option, ryu_of_port], stdout=FNULL, stderr=FNULL)
+ time.sleep(1)
+
+ def stopRyu(self):
+ if self.ryu_process is not None:
+ self.ryu_process.terminate()
+ self.ryu_process.kill()
+