blob: 83ac619e3676925496b6ff2528833075ed8ad957 [file] [log] [blame]
peustermcbcd4c22015-12-28 11:33:42 +01001"""
2Distributed Cloud Emulator (dcemulator)
3(c) 2015 by Manuel Peuster <manuel.peuster@upb.de>
4"""
5import logging
6
peusterm58310762016-01-12 17:09:20 +01007from mininet.net import Dockernet
peusterme6092692016-01-11 16:32:58 +01008from mininet.node import Controller, OVSKernelSwitch, Switch, Docker, Host
peustermcbcd4c22015-12-28 11:33:42 +01009from mininet.cli import CLI
10from mininet.log import setLogLevel, info
11from mininet.link import TCLink, Link
12
peusterm7aae6852016-01-12 14:53:18 +010013from node import Datacenter, EmulatorCompute
peustermcbcd4c22015-12-28 11:33:42 +010014
15
16class DCNetwork(object):
peusterme4e89d32016-01-07 09:14:54 +010017 """
18 Wraps the original Mininet class and provides
19 methods to add data centers, switches, etc.
20
21 This class is used by topology definition scripts.
22 """
peustermcbcd4c22015-12-28 11:33:42 +010023
24 def __init__(self):
25 self.dcs = {}
26 self.switches = {}
27 self.links = []
28
29 # create a Mininet/Dockernet network
30 setLogLevel('info') # set Mininet loglevel
peusterm58310762016-01-12 17:09:20 +010031 self.mnet = Dockernet(controller=Controller, switch=OVSKernelSwitch)
peustermcbcd4c22015-12-28 11:33:42 +010032 self.mnet.addController('c0')
33
34 def addDatacenter(self, name):
35 """
36 Create and add a logical cloud data center to the network.
37 """
38 if name in self.dcs:
39 raise Exception("Data center name already exists: %s" % name)
40 dc = Datacenter(name)
41 dc.net = self # set reference to network
42 self.dcs[name] = dc
43 dc.create() # finally create the data center in our Mininet instance
44 logging.info("added data center: %s" % name)
45 return dc
46
47 def addSwitch(self, name):
48 """
49 We can also add additional SDN switches between data centers.
50 """
51 s = self.mnet.addSwitch(name)
52 self.switches[name] = s
53 logging.info("added switch: %s" % name)
54 return s
55
peusterme6092692016-01-11 16:32:58 +010056 def addLink(self, node1, node2, **params):
peusterm5b844a12016-01-11 15:58:15 +010057 """
58 Able to handle Datacenter objects as link
59 end points.
60 """
peustermcbcd4c22015-12-28 11:33:42 +010061 assert node1 is not None
62 assert node2 is not None
peusterme6092692016-01-11 16:32:58 +010063 logging.debug("addLink: n1=%s n2=%s" % (str(node1), str(node2)))
peustermcbcd4c22015-12-28 11:33:42 +010064 # ensure type of node1
65 if isinstance( node1, basestring ):
66 if node1 in self.dcs:
67 node1 = self.dcs[node1].switch
68 elif node1 in self.switches:
69 node1 = self.switches[node1]
70 if isinstance( node1, Datacenter ):
71 node1 = node1.switch
72 # ensure type of node2
73 if isinstance( node2, basestring ):
74 if node2 in self.dcs:
75 node2 = self.dcs[node2].switch
76 elif node2 in self.switches:
77 node2 = self.switches[node2]
78 if isinstance( node2, Datacenter ):
79 node2 = node2.switch
peustermc3b977e2016-01-12 10:09:35 +010080 # try to give containers a default IP
81 if isinstance( node1, Docker ):
82 if not "params1" in params:
83 params["params1"] = {}
84 if not "ip" in params["params1"]:
85 params["params1"]["ip"] = self.getNextIp()
86 if isinstance( node2, Docker ):
87 if not "params2" in params:
88 params["params2"] = {}
89 if not "ip" in params["params2"]:
90 params["params2"]["ip"] = self.getNextIp()
91
peusterma2ad9ff2016-01-11 17:10:07 +010092 return self.mnet.addLink(node1, node2, **params) # TODO we need TCLinks with user defined performance here
93
94 def removeLink(self, link=None, node1=None, node2=None):
95 """
96 Removes a link. Can either be specified by link object,
97 or the nodes the link connects. Wraps Dockernet method.
98 """
99 logging.debug("removeLink: n1=%s n2=%s" % (str(node1), str(node2)))
100 return self.mnet.removeLink(link=link, node1=node1, node2=node2)
peustermcbcd4c22015-12-28 11:33:42 +0100101
peusterm5b844a12016-01-11 15:58:15 +0100102 def addDocker( self, name, **params ):
103 """
104 Wrapper for addDocker method provided by Dockernet.
105 """
peusterm7aae6852016-01-12 14:53:18 +0100106 return self.mnet.addDocker( name, cls=EmulatorCompute, **params)
peusterm5b844a12016-01-11 15:58:15 +0100107
108 def removeDocker( self, name, **params):
109 """
110 Wrapper for removeHost. Just to be complete.
111 """
112 return self.mnet.removeDocker(name, **params)
113
peustermc3b977e2016-01-12 10:09:35 +0100114 def getNextIp(self):
115 return self.mnet.getNextIp()
116
peustermbd44f4a2016-01-13 14:53:30 +0100117 def getAllContainers(self):
118 """
119 Returns a list with all containers within all data centers.
120 """
121 all_containers = []
122 for dc in self.dcs.itervalues():
123 all_containers += dc.listCompute()
124 return all_containers
125
peustermcbcd4c22015-12-28 11:33:42 +0100126 def start(self):
127 # start
128 for dc in self.dcs.itervalues():
129 dc.start()
130 self.mnet.start()
131
132 def stop(self):
133 self.mnet.stop()
134
135 def CLI(self):
136 CLI(self.mnet)