Add documentation to various OVS RM and change the RM name OVSWitch to OVSSwitch
authorJulien Tribino <julien.tribino@inria.fr>
Mon, 19 May 2014 14:56:45 +0000 (16:56 +0200)
committerJulien Tribino <julien.tribino@inria.fr>
Mon, 19 May 2014 14:56:45 +0000 (16:56 +0200)
examples/openvswitch/ovs_ping_2switches.py
examples/openvswitch/ovs_ping_3switches_line.py
examples/openvswitch/ovs_ping_3switches_loop.py
src/nepi/resources/planetlab/openvswitch/ovs.py
src/nepi/resources/planetlab/openvswitch/ovsport.py
src/nepi/resources/planetlab/openvswitch/tunnel.py
test/resources/planetlab/ovs.py

index a7110e6..7fbb74b 100644 (file)
@@ -47,7 +47,7 @@ def add_node(ec, host, user, pl_user, pl_password):
     return node
 
 def add_ovs(ec, bridge_name, virtual_ip_pref, controller_ip, controller_port, node):
-    ovs = ec.register_resource("OVSWitch")
+    ovs = ec.register_resource("OVSSwitch")
     ec.set(ovs, "bridge_name", bridge_name)
     ec.set(ovs, "virtual_ip_pref", virtual_ip_pref)
     ec.set(ovs, "controller_ip", controller_ip)
index 30909ff..ca1ebee 100644 (file)
@@ -46,7 +46,7 @@ def add_node(ec, host, user, pl_user, pl_password):
     return node
 
 def add_ovs(ec, bridge_name, virtual_ip_pref, controller_ip, controller_port, node):
-    ovs = ec.register_resource("OVSWitch")
+    ovs = ec.register_resource("OVSSwitch")
     ec.set(ovs, "bridge_name", bridge_name)
     ec.set(ovs, "virtual_ip_pref", virtual_ip_pref)
     ec.set(ovs, "controller_ip", controller_ip)
index 9caea39..54b2083 100644 (file)
@@ -55,7 +55,7 @@ def add_node(ec, host, user, pl_user, pl_password):
     return node
 
 def add_ovs(ec, bridge_name, virtual_ip_pref, controller_ip, controller_port, node):
-    ovs = ec.register_resource("OVSWitch")
+    ovs = ec.register_resource("OVSSwitch")
     ec.set(ovs, "bridge_name", bridge_name)
     ec.set(ovs, "virtual_ip_pref", virtual_ip_pref)
     ec.set(ovs, "controller_ip", controller_ip)
index 65a1ec5..a2111f4 100644 (file)
@@ -29,8 +29,18 @@ import os
 reschedule_delay = "0.5s"
 
 @clsinit_copy                    
-class OVSWitch(LinuxApplication):
-    _rtype = "OVSWitch"
+class OVSSwitch(LinuxApplication):
+    """
+    .. class:: Class Args :
+      
+        :param ec: The Experiment controller
+        :type ec: ExperimentController
+        :param guid: guid of the RM
+        :type guid: int
+
+    """
+
+    _rtype = "OVSSwitch"
     _help = "Runs an OpenVSwitch on a PlanetLab host"
     _backend = "planetlab"
 
@@ -38,7 +48,7 @@ class OVSWitch(LinuxApplication):
 
     @classmethod
     def _register_attributes(cls):
-        """ Register the attributes of OVSWitch RM 
+        """ Register the attributes of OVSSwitch RM 
 
         """
         bridge_name = Attribute("bridge_name", "Name of the switch/bridge",
@@ -63,18 +73,21 @@ class OVSWitch(LinuxApplication):
         :type guid: int
     
         """
-        super(OVSWitch, self).__init__(ec, guid)
-        self._pid = None
-        self._ppid = None
-        self._home = "ovswitch-%s" % self.guid
+        super(OVSSwitch, self).__init__(ec, guid)
+        self._home = "ovsswitch-%s" % self.guid
         self._checks = "ovsChecks-%s" % self.guid
 
     @property
     def node(self):
+        """ Node wthat run the switch
+        """
         node = self.get_connected(PlanetlabNode.get_rtype())
         if node: return node[0]
         return None
 
+    def log_message(self, msg):
+        return " guid %d - OVSSwitch - %s " % (self.guid, msg)
+
     @property
     def ovs_home(self):
         return os.path.join(self.node.exp_home, self._home)
@@ -83,66 +96,60 @@ class OVSWitch(LinuxApplication):
     def ovs_checks(self):
         return os.path.join(self.ovs_home, self._checks)
 
-    @property
-    def pid(self):
-        return self._pid
+    def valid_connection(self, guid):
+        """ Check if the connection with the guid in parameter is possible. Only meaningful connections are allowed.
 
-    @property
-    def ppid(self):
-        return self._ppid
-
-#    def valid_connection(self, guid):
-#        """ Check if the connection with the guid in parameter is possible. Only meaningful connections are allowed.
-
-#        :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)
-#        return False
+        :param guid: Guid of the current RM
+        :type guid: int
+        :rtype:  Boolean
 
-    def valid_connection(self, guid):
-        # TODO: Validate!
-        return True
+        """
+        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)
+        return False
 
     def do_provision(self):
+        """ Create the different OVS folder.
+        """
+
         # create home dir for ovs
         self.node.mkdir(self.ovs_home)
         # create dir for ovs checks
         self.node.mkdir(self.ovs_checks)
         
-        super(OVSWitch, self).do_provision()
+        super(OVSSwitch, self).do_provision()
                                
     def do_deploy(self):
-        """ Wait until node is associated and deployed
+        """ Deploy the OVS Switch : Turn on the server, create the bridges
+            and assign the controller
         """
+
         if not self.node or self.node.state < ResourceState.READY:
             self.ec.schedule(reschedule_delay, self.deploy)
             return
 
         self.do_discover()
         self.do_provision()
+
         self.check_sliver_ovs()
         self.servers_on()
         self.create_bridge()
         self.assign_controller()
         self.ovs_status()
             
-        super(OVSWitch, self).do_deploy()
+        super(OVSSwitch, self).do_deploy()
 
     def check_sliver_ovs(self):  
-        """ Check if sliver-ovs exists. If it does not exist, we interrupt
-        the execution immediately. 
+        """ Check if sliver-ovs exists. If it does not exist, the execution is stopped
         """
+
         cmd = "compgen -c | grep sliver-ovs"                   
         out = err = ""
 
@@ -165,8 +172,7 @@ class OVSWitch(LinuxApplication):
         self.debug(msg)
 
     def servers_on(self):
-        """ Start the openvswitch servers and also checking 
-            if they started successfully 
+        """ Start the openvswitch servers and check it
         """
 
         # Start the server
@@ -205,18 +211,12 @@ class OVSWitch(LinuxApplication):
         
         self.info("Server OVS Started Correctly")  
 
-#   def del_old_br(self):
-#        # TODO: Delete old bridges that might exist maybe by adding atribute
-#        """ With ovs-vsctl list-br
-#        """
-#        pass
-
     def create_bridge(self):
-        """ Create the bridge/switch and we check if we have any 
-            error during the SSH connection         
+        """ Create the bridge/switch and check error during SSH connection
         """
+        # TODO: Check if previous bridge exist and delete them. Use ovs-vsctl list-br
         # TODO: Add check for virtual_ip belonging to vsys_tag
-        #self.del_old_br()
+
        
         if not (self.get("bridge_name") and self.get("virtual_ip_pref")):
             msg = "No assignment in one or both attributes"
@@ -269,8 +269,9 @@ class OVSWitch(LinuxApplication):
         self.info("Controller assigned to the bridge %s" % self.get("bridge_name"))
            
     def ovs_status(self):
-        """ Print the status of the bridge                                     
+        """ Print the status of the bridge                             
         """
+
         cmd = "sliver-ovs show | tail -n +2"
         out = err = ""
         (out, err), proc = self.node.run_and_wait(cmd, self.ovs_home,
@@ -284,11 +285,12 @@ class OVSWitch(LinuxApplication):
             self.error(msg)
             raise RuntimeError, msg
         
-        self.info(out)
+        self.debug(out)
 
     def do_release(self):
-        """ Delete the bridge and close the servers.  
-        It need to wait for the others RM (OVSPort and OVSTunnel)
+        """ Delete the bridge and close the server.  
+
+          .. note : It need to wait for the others RM (OVSPort and OVSTunnel)
         to be released before releasing itself
 
         """
@@ -315,5 +317,5 @@ class OVSWitch(LinuxApplication):
             self.error(msg, out, err)
             raise RuntimeError, msg
 
-        super(OVSWitch, self).do_release()
+        super(OVSSwitch, self).do_release()
 
index 74a8baa..554a116 100644 (file)
@@ -21,7 +21,7 @@
 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
 
@@ -43,7 +43,7 @@ class OVSPort(LinuxApplication):
     _help = "Runs an OpenVSwitch on a PlanetLab host"
     _backend = "planetlab"
 
-    _authorized_connections = ["OVSWitch", "Tunnel"]      
+    _authorized_connections = ["OVSSwitch", "OVSTunnel"]      
 
     @classmethod
     def _register_attributes(cls):
@@ -67,9 +67,14 @@ class OVSPort(LinuxApplication):
         self._port_number = None
         self.port_info = []         
 
+    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,9 +82,11 @@ 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
@@ -87,33 +94,21 @@ class OVSPort(LinuxApplication):
         return self._port_number
 
     def valid_connection(self, guid):
-        # TODO: Validate!
-        return True
-
-#    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.
+        """ 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)
 
-        import socket
-        return socket.gethostbyname(self.node.get('hostname'))
-    
     def create_port(self):
         """ Create the desired port
         """
@@ -125,20 +120,20 @@ 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):
         """ Get the local_endpoint of the port
@@ -150,7 +145,7 @@ class OVSPort(LinuxApplication):
         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'), 
@@ -169,19 +164,29 @@ 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):
+    def set_port_info(self):
+        """ Set all the information about the port inside a list
+        """
+
         info = []
         info.append(self.node.get('hostname'))
+
+        #Return the ip of the node
+        import socket
+        ip = socket.gethostbyname(self.node.get('hostname'))
         info.append(ip)
+
         info.append(self.get('port_name'))
-        info.append(self.ovswitch.get('virtual_ip_pref'))
+        info.append(self.ovsswitch.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
+        """ Script to create the connection from a switch to a 
+             remote endpoint
         """
+
         command = ["sliver-ovs"]
         command.append("set-remote-endpoint ")
         command.append("%s " % local_port_name)
@@ -192,22 +197,25 @@ class OVSPort(LinuxApplication):
         return command
         
     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 )  
+        if not self.ovsswitch or self.ovsswitch.state < ResourceState.READY:       
+            self.debug("---- RESCHEDULING DEPLOY ---- OVSwitch state %s " % self.ovsswitch.state )  
             self.ec.schedule(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()
 
-        self.port_info = self.set_port_info(ip)
+        #Check the status of the OVS Switch
+        self.ovsswitch.ovs_status()
+
+        # Save all the information inside a list
+        self.port_info = self.set_port_info()
 
         super(OVSPort, self).do_deploy()
 
@@ -224,7 +232,7 @@ class OVSPort(LinuxApplication):
             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')
index c9c2711..23b0846 100644 (file)
@@ -24,7 +24,7 @@ from nepi.execution.resource import ResourceManager, ResourceFactory, clsinit_co
         ResourceState
 from nepi.resources.linux.application import LinuxApplication
 from nepi.resources.planetlab.node import PlanetlabNode            
-from nepi.resources.planetlab.openvswitch.ovs import OVSWitch   
+from nepi.resources.planetlab.openvswitch.ovs import OVSSwitch   
 from nepi.util.timefuncs import tnow, tdiffsec    
 from nepi.resources.planetlab.vroute import PlanetlabVroute
 from nepi.resources.planetlab.tap import PlanetlabTap
@@ -54,7 +54,7 @@ class OVSTunnel(LinuxApplication):
 
     @classmethod
     def _register_attributes(cls):
-        """ Register the attributes of Connection RM 
+        """ Register the attributes of OVSTunnel RM 
 
         """
         network = Attribute("network", "IPv4 Network Address",
@@ -120,7 +120,7 @@ class OVSTunnel(LinuxApplication):
 
     @property
     def tap(self):
-        ''' Return the Tap RM if it exists '''
+        """ Return the Tap RM if it exists """
         rclass = ResourceFactory.get_resource_type(PlanetlabTap.get_rtype())
         for guid in self.connections:
             rm = self.ec.get_resource(guid)
@@ -128,29 +128,29 @@ class OVSTunnel(LinuxApplication):
                 return rm
 
     @property
-    def ovswitch(self):
-        ''' Return the 1st switch '''
+    def ovsswitch(self):
+        """ Return the 1st switch """
         for guid in self.connections:
             rm_port = self.ec.get_resource(guid)
             if hasattr(rm_port, "create_port"):
-                rm_list = rm_port.get_connected(OVSWitch.get_rtype())
+                rm_list = rm_port.get_connected(OVSSwitch.get_rtype())
                 if rm_list:
                     return rm_list[0]
 
     @property         
     def check_switch_host_link(self):
-        ''' Check if the links are between switches
-            or switch-host. Return False for latter.
-        '''
+        """ Check if the links are between switches
+            or switch-host. Return False for the latter.
+        """
         if self.tap :
             return True
         return False
 
 
     def endpoints(self):
-        ''' Return the list with the two connected elements.
+        """ Return the list with the two connected elements.
         Either Switch-Switch or Switch-Host
-        '''
+        """
         connected = [1, 1]
         position = 0
         for guid in self.connections:
@@ -162,32 +162,12 @@ class OVSTunnel(LinuxApplication):
                 connected[1] = rm
         return connected
 
-#    def port_endpoints(self):
-#        # Switch-Switch connection
-#        connected = []
-#        for guid in self.connections:
-#            rm = self.ec.get_resource(guid)
-#            if hasattr(rm, "create_port"):
-#                connected.append(rm)
-#        return connected
-
-#    
-#    def mixed_endpoints(self):
-#        # Switch-Host connection
-#        connected = [1, 2]
-#        for guid in self.connections:
-#            rm = self.ec.get_resource(guid)
-#            if hasattr(rm, "create_port"):
-#                connected[0] = rm
-#            elif hasattr(rm, "udp_connect_command"):
-#                connected[1] = rm
-#        return connected
-
     def get_node(self, endpoint):
-        # Get connected to the nodes
+        """ Get the nodes of the endpoint
+        """
         rm = []
         if hasattr(endpoint, "create_port"):
-            rm_list = endpoint.get_connected(OVSWitch.get_rtype())
+            rm_list = endpoint.get_connected(OVSSwitch.get_rtype())
             if rm_list:
                 rm = rm_list[0].get_connected(PlanetlabNode.get_rtype())
         else:
@@ -198,26 +178,20 @@ class OVSTunnel(LinuxApplication):
 
     @property
     def endpoint1(self):
-            endpoint = self.endpoints()
-            return endpoint[0]
+        """ Return the first endpoint : Always a Switch
+        """
+        endpoint = self.endpoints()
+        return endpoint[0]
 
     @property
     def endpoint2(self):
-            endpoint = self.endpoints()
-            return endpoint[1]
-
-#    @property          
-#    def check_endpoints(self):
-#        """ Check if the links are between switches
-#            or switch-host. Return False for latter.
-#        """
-#        port_endpoints = self.port_endpoints()
-#        if len(port_endpoints) == 2:
-#            return True
-#        return False
+        """ Return the second endpoint : Either a Switch or a TAP
+        """
+        endpoint = self.endpoints()
+        return endpoint[1]
 
     def get_port_info(self, endpoint1, endpoint2):
-        # Need to change it. Not good to have method that return different type of things !!!!!
+        #TODO : Need to change it. Really bad to have method that return different type of things !!!!!
         """ Retrieve the port_info list for each port
        
         """
@@ -230,111 +204,17 @@ class OVSTunnel(LinuxApplication):
 
         return pname0, ip1, pnumber1
     
-    def host_to_switch_connect(self, tap_endpoint, sw_endpoint):     
-        # Collect info from rem_endpoint
-        remote_ip = socket.gethostbyname(self.node_endpoint1.get("hostname"))
-
-        # Collect info from endpoint
-        local_port_file = os.path.join(self.run_home(self.node_endpoint2), "local_port")
-        rem_port_file = os.path.join(self.run_home(self.node_endpoint2), "remote_port")
-        ret_file = os.path.join(self.run_home(self.node_endpoint2), "ret_file")
-        cipher = self.get("cipher")
-        cipher_key = self.get("cipherKey")
-        bwlimit = self.get("bwLimit")
-        txqueuelen = self.get("txQueueLen")
-
-        rem_port = str(self.get_port_info( sw_endpoint,tap_endpoint))
-
-        # Upload the remote port in a file
-        self.node_endpoint2.upload(rem_port, rem_port_file,
-                text = True,
-                overwrite = False)
-       
-        udp_connect_command = tap_endpoint.udp_connect_command(
-                remote_ip, local_port_file, rem_port_file,
-                ret_file, cipher, cipher_key, bwlimit, txqueuelen) 
-
-        # upload command to host_connect.sh script
-        shfile = os.path.join(self.app_home(self.node_endpoint2), "host_connect.sh")
-        self.node_endpoint2.upload(udp_connect_command, shfile,
-                text = True,
-                overwrite = False)
-
-        # invoke connect script
-        cmd = "bash %s" % shfile
-        (out, err), proc = self.node_endpoint2.run(cmd, self.run_home(self.node_endpoint2),
-                sudo  = True,
-                stdout = "udp_stdout",
-                stderr = "udp_stderr")
-
-        # check if execution errors
-        if proc.poll():
-            msg = "Failed to connect endpoints"
-            self.error(msg, out, err)
-            raise RuntimeError, msg
-
-        msg = "Connection on host %s configured" % self.node_endpoint2.get("hostname")
-        self.debug(msg)
-         
-        # Wait for pid file to be generated
-        pid, ppid = self.node_endpoint2.wait_pid(self.run_home(self.node_endpoint2))
-        
-        # If the process is not running, check for error information
-        # on the remote machine
-        if not pid or not ppid:
-            (out, err), proc = self.node_endpoint2.check_errors(self.run_home(self.node_endpoint2))
-            # 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
-                
-        return (pid, ppid)
-
-    def switch_to_switch_connect(self, endpoint, rem_endpoint):
-        """ Get switch connect command
-        """
-        # Get and configure switch connection command
-
-        local_port_name, remote_ip, remote_port_num = self.get_port_info(endpoint, rem_endpoint)
-
-
-        switch_connect_command = endpoint.switch_connect_command(
-                local_port_name, remote_ip, remote_port_num)
-        node_endpoint = self.get_node(endpoint)        
-
-        # Upload command to the file sw_connect.sh
-        shfile = os.path.join(self.app_home(node_endpoint), "sw_connect.sh")
-        node_endpoint.upload(switch_connect_command,
-                shfile,
-                text = True,
-                overwrite = False)
-
-        #invoke connect script
-        cmd = "bash %s" % shfile
-        (out, err), proc = node_endpoint.run(cmd, self.run_home(node_endpoint),
-                sudo  = True,
-                stdout = "sw_stdout",
-                stderr = "sw_stderr")
-        
-        # check if execution errors occured
-        if proc.poll():
-            msg = "Failed to connect endpoints"
-            self.error(msg, out, err)
-            raise RuntimeError, msg
-
-        # For debugging
-        msg = "Connection on port %s configured" % local_port_name
-        self.info(msg)
-
-    def wait_local_port(self):
+    def wait_local_port(self, node_endpoint):
         """ Waits until the if_name file for the command is generated, 
             and returns the if_name for the device """
+
         local_port = None
         delay = 1.0
 
+        #TODO : Need to change it with reschedule to avoid the problem 
+        #        of the order of connection
         for i in xrange(10):
-            (out, err), proc = self.node_endpoint2.check_output(self.run_home(self.node_endpoint2), 'local_port')
+            (out, err), proc = node_endpoint.check_output(self.run_home(node_endpoint), 'local_port')
             if out:
                 local_port = int(out)
                 break
@@ -348,28 +228,86 @@ class OVSTunnel(LinuxApplication):
 
         return local_port
 
-    def switch_to_host_connect(self, sw_endpoint, host_endpoint):
-        """Link switch--> host
+    def connection(self, local_endpoint, rm_endpoint):
+        """ Create the connect command for each case : 
+              - Host - Switch,  
+              - Switch - Switch,  
+              - Switch - Host
+        """
+        local_node = self.get_node(local_endpoint)
+        local_node.mkdir(self.run_home(local_node))
+
+        rm_node = self.get_node(rm_endpoint)
+        rm_node.mkdir(self.run_home(rm_node))
+
+        # Host to switch
+        if self.check_switch_host_link and local_endpoint == self.endpoint2 :
+        # Collect info from rem_endpoint
+            remote_ip = socket.gethostbyname(rm_node.get("hostname"))
+
+        # Collect info from endpoint
+            local_port_file = os.path.join(self.run_home(local_node), "local_port")
+            rem_port_file = os.path.join(self.run_home(local_node), "remote_port")
+            ret_file = os.path.join(self.run_home(local_node), "ret_file")
+            cipher = self.get("cipher")
+            cipher_key = self.get("cipherKey")
+            bwlimit = self.get("bwLimit")
+            txqueuelen = self.get("txQueueLen")
+
+            rem_port = str(self.get_port_info(rm_endpoint,local_endpoint))
+   
+        # Upload the remote port in a file
+            local_node.upload(rem_port, rem_port_file,
+                 text = True,
+                 overwrite = False)
+       
+            connect_command = local_endpoint.udp_connect_command(
+                 remote_ip, local_port_file, rem_port_file,
+                 ret_file, cipher, cipher_key, bwlimit, txqueuelen) 
+
+            self.connection_command(connect_command, local_node, rm_node)
+
+        # Wait for pid file to be generated
+            self._pid, self._ppid = local_node.wait_pid(self.run_home(local_node))
+
+            if not self._pid or not self._ppid:
+                (out, err), proc = local_node.check_errors(self.run_home(local_node))
+                # Out is what was written in the stderr file
+                if err:
+                    msg = " Failed to start connection of the OVS Tunnel "
+                    self.error(msg, out, err)
+                    raise RuntimeError, msg
+            return
+
+        # Switch to Host
+        if self.check_switch_host_link and local_endpoint == self.endpoint1:
+            local_port_name = local_endpoint.get('port_name')
+            remote_port_num = self.wait_local_port(rm_node)
+            remote_ip = socket.gethostbyname(rm_node.get("hostname"))
+  
+        # Switch to Switch
+        if not self.check_switch_host_link :
+            local_port_name, remote_ip, remote_port_num = self.get_port_info(local_endpoint, rm_endpoint)
+
+        connect_command = local_endpoint.switch_connect_command(
+                    local_port_name, remote_ip, remote_port_num)
+
+        self.connection_command(connect_command, local_node, rm_node)       
+
+    def connection_command(self, command, node_endpoint, rm_node_endpoint):
+        """ Execute the connection command on the node and check if the processus is
+            correctly running on the node.
         """
-        # Retrieve remote port number from sw_endpoint
-        local_port_name = sw_endpoint.get('port_name')
-
-        out = err= ''
-        remote_port_num = self.wait_local_port()
-        remote_ip = socket.gethostbyname(self.node_endpoint2.get("hostname"))
-        switch_connect_command = sw_endpoint.switch_connect_command(
-                local_port_name, remote_ip, remote_port_num)
-
-        # Upload command to the file sw_connect.sh
-        shfile = os.path.join(self.app_home(self.node_endpoint1), "sw_connect.sh")
-        self.node_endpoint1.upload(switch_connect_command,
+        shfile = os.path.join(self.app_home(node_endpoint), "sw_connect.sh")
+        node_endpoint.upload(command,
                 shfile,
                 text = True,
                 overwrite = False)
 
         # Invoke connect script
+        out = err= ''       
         cmd = "bash %s" % shfile
-        (out, err), proc = self.node_endpoint1.run(cmd, self.run_home(self.node_endpoint1),
+        (out, err), proc = node_endpoint.run(cmd, self.run_home(node_endpoint),
                 sudo  = True,
                 stdout = "sw_stdout",
                 stderr = "sw_stderr")
@@ -382,44 +320,37 @@ class OVSTunnel(LinuxApplication):
             raise RuntimeError, msg
 
         # For debugging
-        msg = "Connection on port %s configured" % local_port_name
-        self.debug(msg)                                                   
+        msg = "Connection on port configured"
+        self.debug(msg)
 
     def do_provision(self):
         """ Provision the tunnel
-
-           ..note : Endpoint 1 is always a OVSPort. 
-                    Endpoint 2 can be either a OVSPort or a Tap
-                     
         """
-        self.node_endpoint1 = self.get_node(self.endpoint1)
-        self.node_endpoint1.mkdir(self.run_home(self.node_endpoint1))
-
-        self.node_endpoint2 = self.get_node(self.endpoint2)
-        self.node_endpoint2.mkdir(self.run_home(self.node_endpoint2))
+        
+        #TODO : The order of the connection is important for now ! 
+        # Need to change the code of wait local port
+        self.connection(self.endpoint2, self.endpoint1)
+        self.connection(self.endpoint1, self.endpoint2)
 
-        if not self.check_switch_host_link:
-            # Invoke connect script between switches
-            self.switch_to_switch_connect(self.endpoint1, self.endpoint2)
-            self.switch_to_switch_connect(self.endpoint2, self.endpoint1)
-        else: 
-            # Invoke connect script between switch & host
-            (self._pid, self._ppid) = self.host_to_switch_connect(self.endpoint2, self.endpoint1)
-            self.switch_to_host_connect(self.endpoint1, self.endpoint2)
+    def configure_route(self):
+        """ Configure the route for the tap device
 
-        #super(OVSTunnel, self).do_provision()
+            .. note : In case of a conection between a switch and a host, a route
+                      was missing on the node with the Tap Device. This method create
+                      the missing route. 
+        """
 
-    def configure(self):
         if  self.check_switch_host_link:
             self._vroute = self.ec.register_resource("PlanetlabVroute")
             self.ec.set(self._vroute, "action", "add")
             self.ec.set(self._vroute, "network", self.get("network"))
 
             self.ec.register_connection(self._vroute, self.tap.guid)
-            # schedule deploy
             self.ec.deploy(guids=[self._vroute], group = self.deployment_group)
 
     def do_deploy(self):
+        """ Deploy the tunnel after the endpoint get ready
+        """
         if (not self.endpoint1 or self.endpoint1.state < ResourceState.READY) or \
             (not self.endpoint2 or self.endpoint2.state < ResourceState.READY):
             self.ec.schedule(reschedule_delay, self.deploy)
@@ -427,20 +358,23 @@ class OVSTunnel(LinuxApplication):
 
         self.do_discover()
         self.do_provision()
-        self.configure()
+        self.configure_route()
 
+        # Cannot call the deploy of the linux application 
+        #         because of a log error.
+        # Need to investigate if it is right that the tunnel 
+        #    inherits from the linux application
+        #  super(OVSTunnel, self).do_deploy()
         self.set_ready()
-        #super(OVSTunnel, self).do_deploy()
  
     def do_release(self):
-        """ Release the udp_tunnel on endpoint2.
-            On endpoint1 means nothing special.        
+        """ Release the tunnel by releasing the Tap Device if exists
         """
-        if not self.check_switch_host_link:
-            # Kill the TAP devices
+        if self.check_switch_host_link:
             # TODO: Make more generic Release method of PLTAP
+            tap_node = self.get_node(self.endpoint2)
             if self._pid and self._ppid:
-                (out, err), proc = self.node_enpoint2.kill(self._pid,
+                (out, err), proc = tap_node.kill(self._pid,
                         self._ppid, sudo = True)
 
                 if err or proc.poll():
index d072074..e76a6e6 100644 (file)
@@ -52,7 +52,7 @@ class OvsTestCase(unittest.TestCase):
         ec.set(node1, "cleanHome", True)
         ec.set(node1, "cleanProcesses", True)  
 
-        ovs1 = ec.register_resource("OVSWitch")
+        ovs1 = ec.register_resource("OVSSwitch")
         ec.set(ovs1, "bridge_name", "nepi_bridge")
         ec.set(ovs1, "virtual_ip_pref", "192.168.3.1/24")
         ec.set(ovs1, "controller_ip", "85.23.168.77")
@@ -73,7 +73,7 @@ class OvsTestCase(unittest.TestCase):
         ec.set(node2, "cleanHome", True)
         ec.set(node2, "cleanProcesses", True) 
 
-        ovs2 = ec.register_resource("OVSWitch")
+        ovs2 = ec.register_resource("OVSSwitch")
         ec.set(ovs2, "bridge_name", "nepi_bridge")
         ec.set(ovs2, "virtual_ip_pref", "192.168.3.2/24")
         ec.set(ovs2, "controller_ip", "85.23.168.77")