2 # NEPI, a framework to manage network experiments
3 # Copyright (C) 2013 INRIA
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
19 # Alexandros Kouvakas <alexandros.kouvakas@gmail.com>
21 from nepi.execution.attribute import Attribute, Flags, Types
22 from nepi.execution.resource import ResourceManager, clsinit_copy, ResourceState
23 from nepi.resources.planetlab.openvswitch.ovs import OVSWitch
24 from nepi.resources.planetlab.node import PlanetlabNode
25 from nepi.resources.linux.application import LinuxApplication
27 reschedule_delay = "0.5s"
30 class OVSPort(LinuxApplication):
32 .. class:: Class Args :
34 :param ec: The Experiment controller
35 :type ec: ExperimentController
36 :param guid: guid of the RM
42 _help = "Runs an OpenVSwitch on a PlanetLab host"
43 _backend = "planetlab"
45 _authorized_connections = ["OVSWitch", "Tunnel"]
48 def _register_attributes(cls):
49 """ Register the attributes of OVSPort RM
52 port_name = Attribute("port_name", "Name of the port",
53 flags = Flags.ExecReadOnly)
55 cls._register_attribute(port_name)
57 def __init__(self, ec, guid):
59 :param ec: The Experiment controller
60 :type ec: ExperimentController
61 :param guid: guid of the RM
65 super(OVSPort, self).__init__(ec, guid)
66 self._port_number = None
71 rm_list = self.get_connected(OVSWitch.rtype())
74 node = elt.get_connected(PlanetlabNode.rtype())
75 if node: return node[0]
80 ovswitch = self.get_connected(OVSWitch.rtype())
81 if ovswitch: return ovswitch[0]
85 def port_number(self):
86 return self._port_number
88 def valid_connection(self, guid):
92 # def valid_connection(self, guid):
93 # """ Check if the connection is available.
95 # :param guid: Guid of the current RM
100 # rm = self.ec.get_resource(guid)
101 # if rm.rtype() in self._authorized_connections:
102 # msg = "Connection between %s %s and %s %s accepted" % (self.rtype(), self._guid, rm.rtype(), guid)
105 # msg = "Connection between %s %s and %s %s refused" % (self.rtype(), self._guid, rm.rtype(), guid)
108 def get_host_ip(self):
109 """ Get the hostname of the node that
110 the port belongs to. We use it for tunnel.
112 get_host_ip = self.node
114 msg = "info_list is empty"
116 raise RuntimeError, msg
118 self.port_info.append(get_host_ip.get('hostname'))
119 self.port_info.append(socket.gethostbyname(self.port_info[0]))
121 def create_port(self):
122 """ Create the desired port
124 port_name = self.get('port_name')
125 if not (port_name or self.ovswitch):
126 msg = "The rm_list is empty or the port name is not assigned\n Failed to create port"
128 self.debug("ovswitch_list = %s and port_name = %s" % (self.ovswitch, port_name) )
129 raise AttributeError, msg
131 self.info("Create the port %s on switch %s" % (port_name, self.ovswitch.get('bridge_name')))
132 self.port_info.append(port_name)
133 self.port_info.append(self.ovswitch.get('virtual_ip_pref'))
134 cmd = "sliver-ovs create-port %s %s" % (self.ovswitch.get('bridge_name'), port_name)
135 self.node.run(cmd, self.ovswitch.ovs_checks,
136 stderr = "stdout-%s" % port_name,
137 stdout = "stderr-%s" % port_name,
140 def get_local_end(self):
141 """ Get the local_endpoint of the port
143 msg = "Discovering the number of the port %s"\
144 % self.get('port_name')
147 command = "sliver-ovs get-local-endpoint %s"\
148 % self.get('port_name')
150 (out, err), proc = self.node.run_and_wait(command, self.ovswitch.ovs_checks,
151 shfile = "port_number-%s.sh" % self.get('port_name'),
152 pidfile = "port_number_pidfile-%s" % self.get('port_name'),
153 ecodefile = "port_number_exitcode-%s" % self.get('port_name'),
155 stdout = "stdout-%s" % self.get('port_name'),
156 stderr = "stderr-%s" % self.get('port_name'))
159 msg = "No assignment in attribute port_name"
161 self.debug("You are in the method get_local_end and the port_name = %s" % self.get('port_name'))
162 raise AttributeError, msg
163 self._port_number = None
164 self._port_number = int(out)
165 self.port_info.append(self._port_number)
166 self.info("The number of the %s is %s" % (self.get('port_name'), self._port_number))
168 def switch_connect_command(self, local_port_name,
169 remote_ip, remote_port_num):
170 """ Script for switch links
172 command = ["sliver-ovs"]
173 command.append("set-remote-endpoint ")
174 command.append("%s " % local_port_name)
175 command.append("%s " % remote_ip)
176 command.append("%s " % remote_port_num)
177 command = " ".join(command)
178 command = self.replace_paths(command)
182 """ Provision the ports.No meaning.
187 """ Discover the ports.No meaning
192 """ Wait until ovswitch is started
194 ovswitch = self.ovswitch
195 if not ovswitch or ovswitch.state < ResourceState.READY:
196 self.debug("---- RESCHEDULING DEPLOY ---- node state %s " % self.ovswitch.state )
197 self.ec.schedule(reschedule_delay, self.deploy)
206 self.ovswitch.ovs_status()
207 self._state = ResourceState.READY
209 self._state = ResourceState.FAILED
213 """ Start the RM. It means nothing special for
219 """ Stop the RM. It means nothing special for
225 """ Release the port RM means delete the ports
227 # OVS needs to wait until all associated RMs are released
229 from nepi.resources.planetlab.openvswitch.tunnel import Tunnel
230 rm = self.get_connected(Tunnel.rtype())
231 if rm and rm[0].state < ResourceState.FINISHED:
232 self.ec.schedule(reschedule_delay, self.release)
235 msg = "Deleting the port %s" % self.get('port_name')
237 cmd = "sliver-ovs del_port %s" % self.get('port_name')
238 (out, err), proc = self.node.run(cmd, self.ovswitch.ovs_checks,
243 self.error(msg, out, err)
244 raise RuntimeError, msg
246 self._state = ResourceState.RELEASED