X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fnepi%2Fresources%2Fplanetlab%2Fopenvswitch%2Fovsport.py;h=9bdc4153825c86d3f044e6fffc84f3faad392789;hb=d50ba1a08e541ded7a8b322493ebb1d0cc59c6ff;hp=74a8baa0b512683de505d1b39cd08d21d52e7145;hpb=c2acc774e82685942698b64e8ca7b4a27200e5dc;p=nepi.git diff --git a/src/nepi/resources/planetlab/openvswitch/ovsport.py b/src/nepi/resources/planetlab/openvswitch/ovsport.py index 74a8baa0..9bdc4153 100644 --- a/src/nepi/resources/planetlab/openvswitch/ovsport.py +++ b/src/nepi/resources/planetlab/openvswitch/ovsport.py @@ -15,17 +15,18 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # -# Author: Alina Quereilhac -# Alexandros Kouvakas +# Authors: Alina Quereilhac +# Alexandros Kouvakas +# Julien Tribino from nepi.execution.attribute import Attribute, Flags, Types from nepi.execution.resource import ResourceManager, clsinit_copy, \ ResourceState -from nepi.resources.planetlab.openvswitch.ovs import OVSWitch +from nepi.resources.planetlab.openvswitch.ovs import OVSSwitch from nepi.resources.planetlab.node import PlanetlabNode from nepi.resources.linux.application import LinuxApplication -reschedule_delay = "0.5s" +import os @clsinit_copy class OVSPort(LinuxApplication): @@ -39,11 +40,11 @@ class OVSPort(LinuxApplication): """ - _rtype = "OVSPort" + _rtype = "planetlab::OVSPort" _help = "Runs an OpenVSwitch on a PlanetLab host" _backend = "planetlab" - _authorized_connections = ["OVSWitch", "Tunnel"] + _authorized_connections = ["planetlab::OVSSwitch", "linux::UdpTunnel", "linux::Tunnel"] @classmethod def _register_attributes(cls): @@ -51,9 +52,17 @@ class OVSPort(LinuxApplication): """ port_name = Attribute("port_name", "Name of the port", - flags = Flags.ExecReadOnly) + flags = Flags.Design) + endpoint_ip = Attribute("endpoint_ip", "IP of the endpoint. This is the attribute " + "you should use to establish a tunnel or a remote " + "connection between endpoint", + flags = Flags.Design) + network = Attribute("network", "Network used by the port", + flags = Flags.Design) cls._register_attribute(port_name) + cls._register_attribute(endpoint_ip) + cls._register_attribute(network) def __init__(self, ec, guid): """ @@ -64,12 +73,20 @@ class OVSPort(LinuxApplication): """ super(OVSPort, self).__init__(ec, guid) + + self._port_number = None - self.port_info = [] + # in case of connection by tunnel + self._remote_ip = None + + def log_message(self, msg): + return " guid %d - OVSPort - %s " % (self.guid, msg) @property def node(self): - rm_list = self.get_connected(OVSWitch.get_rtype()) + """ Node that run the switch and the ports + """ + rm_list = self.get_connected(OVSSwitch.get_rtype()) if rm_list: for elt in rm_list: node = elt.get_connected(PlanetlabNode.get_rtype()) @@ -77,43 +94,37 @@ class OVSPort(LinuxApplication): return node[0] @property - def ovswitch(self): - ovswitch = self.get_connected(OVSWitch.get_rtype()) - if ovswitch: return ovswitch[0] + def ovsswitch(self): + """ Switch where the port is created + """ + ovsswitch = self.get_connected(OVSSwitch.get_rtype()) + if ovsswitch: return ovsswitch[0] return None + @property + def remote_ip(self): + return self._remote_ip + @property def port_number(self): return self._port_number def valid_connection(self, guid): - # TODO: Validate! - return True + """ Check if the connection is available. + + :param guid: Guid of the current RM + :type guid: int + :rtype: Boolean -# def valid_connection(self, guid): -# """ Check if the connection is available. - -# :param guid: Guid of the current RM -# :type guid: int -# :rtype: Boolean - -# """ -# rm = self.ec.get_resource(guid) -# if rm.get_rtype() in self._authorized_connections: -# msg = "Connection between %s %s and %s %s accepted" % (self.get_rtype(), self._guid, rm.get_rtype(), guid) -# self.debug(msg) -# return True -# msg = "Connection between %s %s and %s %s refused" % (self.get_rtype(), self._guid, rm.get_rtype(), guid) -# self.debug(msg) - - def get_ip(self): - """ Return the ip of the node. This data is necessary to - create the tunnel. """ + rm = self.ec.get_resource(guid) + if rm.get_rtype() in self._authorized_connections: + msg = "Connection between %s %s and %s %s accepted" % (self.get_rtype(), self._guid, rm.get_rtype(), guid) + self.debug(msg) + return True + msg = "Connection between %s %s and %s %s refused" % (self.get_rtype(), self._guid, rm.get_rtype(), guid) + self.debug(msg) - import socket - return socket.gethostbyname(self.node.get('hostname')) - def create_port(self): """ Create the desired port """ @@ -125,32 +136,35 @@ class OVSPort(LinuxApplication): self.error(msg) raise AttributeError, msg - if not self.ovswitch: + if not self.ovsswitch: msg = "The OVSwitch RM is not running" self.error(msg) raise AttributeError, msg - cmd = "sliver-ovs create-port %s %s" % (self.ovswitch.get('bridge_name'), + cmd = "sliver-ovs create-port %s %s" % (self.ovsswitch.get('bridge_name'), self.get('port_name')) - self.node.run(cmd, self.ovswitch.ovs_checks, + self.node.run(cmd, self.ovsswitch.ovs_checks, stderr = "stdout-%s" % self.get('port_name'), stdout = "stderr-%s" % self.get('port_name'), sudo = True) self.info("Created the port %s on switch %s" % (self.get('port_name'), - self.ovswitch.get('bridge_name'))) + self.ovsswitch.get('bridge_name'))) - def get_local_end(self): + def initiate_udp_connection(self, remote_endpoint, connection_app_home, + connection_run_home, cipher, cipher_key, bwlimit, txqueuelen): """ Get the local_endpoint of the port """ + self._remote_ip = remote_endpoint.node.get("ip") + msg = "Discovering the number of the port %s" % self.get('port_name') - self.debug(msg) + self.info(msg) command = "sliver-ovs get-local-endpoint %s" % self.get('port_name') out = err = "" (out, err), proc = self.node.run_and_wait(command, - self.ovswitch.ovs_checks, + self.ovsswitch.ovs_checks, shfile = "port_number-%s.sh" % self.get('port_name'), pidfile = "port_number_pidfile-%s" % self.get('port_name'), ecodefile = "port_number_exitcode-%s" % self.get('port_name'), @@ -168,46 +182,106 @@ class OVSPort(LinuxApplication): self.info("The number of the %s is %s" % (self.get('port_name'), self.port_number)) - - def set_port_info(self, ip): - info = [] - info.append(self.node.get('hostname')) - info.append(ip) - info.append(self.get('port_name')) - info.append(self.ovswitch.get('virtual_ip_pref')) - info.append(self.port_number) - return info - - def switch_connect_command(self, local_port_name, - remote_ip, remote_port_num): - """ Script for switch links + + if remote_endpoint.is_rm_instance("planetlab::Tap"): + self._vroute = self.ec.register_resource("planetlab::Vroute") + self.ec.set(self._vroute, "action", "add") + self.ec.set(self._vroute, "network", self.get("network")) + + print "Vroute Guid :" + str(self._vroute) + + self.ec.register_connection(self._vroute, remote_endpoint.guid) + self.ec.deploy(guids=[self._vroute], group = self.deployment_group) + + # For debugging + msg = "Route for the tap configured" + self.debug(msg) + + return self.port_number + + + def establish_udp_connection(self,remote_endpoint, port): + establish_connection_command = self._establish_connection_command(port) + + # upload command to connect.sh script + shfile = os.path.join(self.app_home, "sw-connect.sh") + self.node.upload_command(establish_connection_command, + shfile = shfile, + overwrite = False) + + # invoke connect script + cmd = "bash %s" % shfile + (out, err), proc = self.node.run(cmd, self.run_home, + sudo = True, + stdout = "sw_stdout", + stderr = "sw_stderr") + + # check if execution errors occurred + msg = "Failed to connect endpoints " + if proc.poll(): + self.error(msg, out, err) + raise RuntimeError, msg + + # Wait for pid file to be generated + self._pid, self._ppid = self.node.wait_pid(self.run_home) + + # If the process is not running, check for error information + # on the remote machine + if not self._pid or not self._ppid: + (out, err), proc = self.node.check_errors(self.run_home) + # Out is what was written in the stderr file + if err: + msg = " Failed to start command '%s' " % command + self.error(msg, out, err) + raise RuntimeError, msg + + # For debugging + msg = "Connection on port configured" + self.debug(msg) + + + def _establish_connection_command(self, port): + """ Script to create the connection from a switch to a + remote endpoint """ + local_port_name = self.get('port_name') + command = ["sliver-ovs"] command.append("set-remote-endpoint ") command.append("%s " % local_port_name) - command.append("%s " % remote_ip) - command.append("%s " % remote_port_num) + command.append("%s " % self.remote_ip) + command.append("%s " % port) command = " ".join(command) command = self.replace_paths(command) return command + def verify_connection(self): + self.ovsswitch.ovs_status() + + def terminate_connection(self): + return True + + def check_status(self): + return self.node.status(self._pid, self._ppid) + def do_deploy(self): - """ Wait until ovswitch is started + """ Deploy the OVS port after the OVS Switch """ - if not self.ovswitch or self.ovswitch.state < ResourceState.READY: - self.debug("---- RESCHEDULING DEPLOY ---- OVSwitch state %s " % self.ovswitch.state ) - self.ec.schedule(reschedule_delay, self.deploy) + if not self.ovsswitch or self.ovsswitch.state < ResourceState.READY: + self.debug("---- RESCHEDULING DEPLOY ---- OVSwitch state %s " % self.ovsswitch.state ) + self.ec.schedule(self.reschedule_delay, self.deploy) return self.do_discover() self.do_provision() - ip = self.get_ip() + self.create_port() - self.get_local_end() - self.ovswitch.ovs_status() + end_ip = self.ovsswitch.get('virtual_ip_pref').split('/') + self.set("endpoint_ip", end_ip[0]) - self.port_info = self.set_port_info(ip) + #Check the status of the OVS Switch + self.ovsswitch.ovs_status() super(OVSPort, self).do_deploy() @@ -215,16 +289,15 @@ class OVSPort(LinuxApplication): """ Delete the port on the OVSwitch. It needs to wait for the tunnel to be released. """ + from nepi.resources.linux.udptunnel import LinuxUdpTunnel + rm = self.get_connected(LinuxUdpTunnel.get_rtype()) - from nepi.resources.planetlab.openvswitch.tunnel import OVSTunnel - rm = self.get_connected(OVSTunnel.get_rtype()) - - if rm and rm[0].state < ResourceState.RELEASED: - self.ec.schedule(reschedule_delay, self.release) + if rm and rm[0].state < ResourceState.STOPPED: + self.ec.schedule(self.reschedule_delay, self.release) return cmd = "sliver-ovs del_port %s" % self.get('port_name') - (out, err), proc = self.node.run(cmd, self.ovswitch.ovs_checks, + (out, err), proc = self.node.run(cmd, self.ovsswitch.ovs_checks, sudo = True) msg = "Deleting the port %s" % self.get('port_name')