From: Alina Quereilhac Date: Tue, 20 Jan 2015 19:41:32 +0000 (+0100) Subject: Bug fixing and ordering openvswitch code X-Git-Tag: nepi-3.2.0~15 X-Git-Url: http://git.onelab.eu/?p=nepi.git;a=commitdiff_plain;h=7fed767f9f18ee81807950771145969cbb27b8a7 Bug fixing and ordering openvswitch code --- diff --git a/examples/openvswitch/ovs_ping.py b/examples/openvswitch/ovs_ping.py index e33e8dbf..40d6cb1e 100644 --- a/examples/openvswitch/ovs_ping.py +++ b/examples/openvswitch/ovs_ping.py @@ -62,8 +62,7 @@ def parse_args(): help="Overlay network address of the form x.x.x.x/yy. " "Must correspond to the vsys_vnet tag on the PlanetLab slice") parser.add_option("-C", "--controller", dest="controller", - help="IP address for the OpenFlow controller, if one has been deployed", - default="1.1.1.1") + help="IP address for the OpenFlow controller, if one has been deployed") parser.add_option("-s", "--slicename", dest="slicename", help="Name of PlanetLab slice", default=pl_slice) diff --git a/examples/openvswitch/ovs_ping_2_switches.py b/examples/openvswitch/ovs_ping_2_switches.py index 6519dd24..155fcbb7 100644 --- a/examples/openvswitch/ovs_ping_2_switches.py +++ b/examples/openvswitch/ovs_ping_2_switches.py @@ -20,13 +20,14 @@ # Alina Quereilhac # # Topology : -# +# +# x.x.x.1 x.x.x.2 # Switch1 -------- Switch2 # / \ # / \ # / \ # Host1 Host2 -# +# x.x.x.3 x.x.x.4 # # Execution example: # @@ -190,90 +191,18 @@ tunnel1 = add_tunnel(ec, port1, tap1) tunnel2 = add_tunnel(ec, port2, tap2) tunnel3 = add_tunnel(ec, port3, port4) -### Add Pings -# Ping switch 1 to switch2 -app1 = add_app(ec, "ping -c5 %s" % ip2, s1_node) -# Ping switch 1 to host1 -app2 = add_app(ec, "ping -c5 %s" % ip3, s1_node) -# Ping switch 1 to host2 -app3 = add_app(ec, "ping -c5 %s" % ip4, s1_node) - -# Ping switch 2 to switch1 -app4 = add_app(ec, "ping -c5 %s" % ip1, s2_node) -# Ping switch 2 to host1 -app5 = add_app(ec, "ping -c5 %s" % ip3, s2_node) -# Ping switch 2 to host2 -app6 = add_app(ec, "ping -c5 %s" % ip4, s2_node) - -# Ping host 1 to switch 1 -app7 = add_app(ec, "ping -c5 %s" % ip1, h1_node) -# Ping host 1 to switch 2 -app8 = add_app(ec, "ping -c5 %s" % ip2, h1_node) -# Ping host 1 to host 2 -app9 = add_app(ec, "ping -c5 %s" % ip4, h1_node) - -# Ping host 2 to switch 1 -app10 = add_app(ec, "ping -c5 %s" % ip1, h2_node) -# Ping host 2 to switch 2 -app11 = add_app(ec, "ping -c5 %s" % ip2, h2_node) -# Ping host 2 to host1 -app12 = add_app(ec, "ping -c5 %s" % ip3, h2_node) +### Add Ping +app = add_app(ec, "ping -c5 %s" % ip4, h1_node) ec.deploy() -ec.wait_finished([app1, app2, app3, app4, app5, app6, - app7, app8, app9, app10, app11, app12]) +ec.wait_finished([app]) # Retreive ping results and save them in a file -ping1 = ec.trace(app1, "stdout") -ping2 = ec.trace(app2, "stdout") -ping3 = ec.trace(app3, "stdout") -ping4 = ec.trace(app4, "stdout") -ping5 = ec.trace(app5, "stdout") -ping6 = ec.trace(app6, "stdout") -ping7 = ec.trace(app7, "stdout") -ping8 = ec.trace(app8, "stdout") -ping9 = ec.trace(app9, "stdout") -ping10 = ec.trace(app10, "stdout") -ping11 = ec.trace(app11, "stdout") -ping12 = ec.trace(app12, "stdout") - -if not ping12: - ec.shutdown() - sys.exit("No ping found") - -f = open("ovs_ping_2_switches.txt", 'w') -f.write("************ Ping From Switch 1 : %s ********************\n\n\n" % ip1) -f.write(ping1) -f.write("----------------------------------------\n\n") -f.write(ping2) -f.write("----------------------------------------\n\n") -f.write(ping3) - -f.write("************ Ping From Switch 2 : %s ********************\n\n\n" % ip2) -f.write(ping4) -f.write("----------------------------------------\n\n") -f.write(ping5) -f.write("----------------------------------------\n\n") -f.write(ping6) - -f.write("************ Ping From Host 1 : %s ********************\n\n\n" % ip3) -f.write(ping7) -f.write("----------------------------------------\n\n") -f.write(ping8) -f.write("----------------------------------------\n\n") -f.write(ping9) - -f.write("************ Ping From Host 2 : %s ********************\n\n\n" % ip4) -f.write(ping10) -f.write("----------------------------------------\n\n") -f.write(ping11) -f.write("----------------------------------------\n\n") -f.write(ping12) - -f.close() +stdout = ec.trace(app, "stdout") # Delete the overlay network ec.shutdown() +print stdout diff --git a/src/nepi/resources/linux/application.py b/src/nepi/resources/linux/application.py index 89a9cfb1..90345b73 100644 --- a/src/nepi/resources/linux/application.py +++ b/src/nepi/resources/linux/application.py @@ -355,7 +355,6 @@ class LinuxApplication(ResourceManager): # replace application specific paths in the command command = self.replace_paths(command) - # replace application specific paths in the environment env = self.get("env") env = env and self.replace_paths(env) @@ -526,7 +525,7 @@ class LinuxApplication(ResourceManager): # Wait until node is associated and deployed node = self.node if not node or node.state < ResourceState.READY: - self.debug("---- RESCHEDULING DEPLOY ---- node state %s " % self.node.state ) + self.debug("---- RESCHEDULING DEPLOY ---- node state %s " % self.node.state) self.ec.schedule(self.reschedule_delay, self.deploy) else: command = self.get("command") or "" diff --git a/src/nepi/resources/linux/node.py b/src/nepi/resources/linux/node.py index 14aab1ad..0bef4ada 100644 --- a/src/nepi/resources/linux/node.py +++ b/src/nepi/resources/linux/node.py @@ -423,6 +423,7 @@ class LinuxNode(ResourceManager): if self.get("username") != 'root': cmd = ("sudo -S killall tcpdump || /bin/true ; " + + "sudo -S kill -9 $(ps aux | grep '[.]nepi' | awk '{print $2}') || /bin/true ; " + "sudo -S killall -u %s || /bin/true ; " % self.get("username")) else: if self.state >= ResourceState.READY: @@ -439,14 +440,14 @@ class LinuxNode(ResourceManager): kill_pids = ' '.join(dict(kill_pids).keys()) cmd = ("killall tcpdump || /bin/true ; " + - "kill $(ps aux | grep '[n]epi' | awk '{print $2}') || /bin/true ; " + + "kill $(ps aux | grep '[.]nepi' | awk '{print $2}') || /bin/true ; " + "kill %s || /bin/true ; " % kill_pids) else: cmd = ("killall tcpdump || /bin/true ; " + - "kill $(ps aux | grep '[n]epi' | awk '{print $2}') || /bin/true ; ") + "kill $(ps aux | grep '[.]nepi' | awk '{print $2}') || /bin/true ; ") else: cmd = ("killall tcpdump || /bin/true ; " + - "kill $(ps aux | grep '[n]epi' | awk '{print $2}') || /bin/true ; ") + "kill $(ps aux | grep '[.]nepi' | awk '{print $2}') || /bin/true ; ") (out, err), proc = self.execute(cmd, retry = 1, with_lock = True) diff --git a/src/nepi/resources/linux/ns3/fdtunnel.py b/src/nepi/resources/linux/ns3/p2pfdudptunnel.py similarity index 100% rename from src/nepi/resources/linux/ns3/fdtunnel.py rename to src/nepi/resources/linux/ns3/p2pfdudptunnel.py diff --git a/src/nepi/resources/linux/ns3/tun_tap_fd_link.py b/src/nepi/resources/linux/ns3/tun_tap_fd_link.py index 5a3a77b4..ed4158b4 100644 --- a/src/nepi/resources/linux/ns3/tun_tap_fd_link.py +++ b/src/nepi/resources/linux/ns3/tun_tap_fd_link.py @@ -123,6 +123,7 @@ class LinuxTunTapFdLink(LinuxApplication): def do_deploy(self): if self.tap.state < ResourceState.READY or \ self.fdnetdevice.state < ResourceState.READY: + self.debug("---- RESCHEDULING DEPLOY ---- ") self.ec.schedule(self.reschedule_delay, self.deploy) else: self.do_discover() diff --git a/src/nepi/resources/linux/tap.py b/src/nepi/resources/linux/tap.py index d5c3d619..2a78e605 100644 --- a/src/nepi/resources/linux/tap.py +++ b/src/nepi/resources/linux/tap.py @@ -406,7 +406,10 @@ class LinuxTap(LinuxApplication): return command - def establish_udp_connection(self, remote_endpoint, port): + def establish_udp_connection(self, remote_endpoint, + connection_app_home, + connection_run_home, + port): # upload remote port number to file rem_port = "%s\n" % port self.node.upload(rem_port, diff --git a/src/nepi/resources/linux/udptunnel.py b/src/nepi/resources/linux/udptunnel.py index e0755bd1..c00459c8 100644 --- a/src/nepi/resources/linux/udptunnel.py +++ b/src/nepi/resources/linux/udptunnel.py @@ -104,7 +104,13 @@ class LinuxUdpTunnel(LinuxTunnel): return port def establish_connection(self, endpoint, remote_endpoint, port): - endpoint.establish_udp_connection(remote_endpoint, port) + connection_app_home = self.app_home(endpoint) + connection_run_home = self.run_home(endpoint) + + endpoint.establish_udp_connection(remote_endpoint, + connection_app_home, + connection_run_home, + port) def verify_connection(self, endpoint, remote_endpoint): endpoint.verify_connection() diff --git a/src/nepi/resources/planetlab/openvswitch/ovs.py b/src/nepi/resources/planetlab/openvswitch/ovs.py index 171750fe..b81de274 100644 --- a/src/nepi/resources/planetlab/openvswitch/ovs.py +++ b/src/nepi/resources/planetlab/openvswitch/ovs.py @@ -28,7 +28,7 @@ from nepi.resources.linux.application import LinuxApplication import os @clsinit_copy -class OVSSwitch(LinuxApplication): +class PlanetlabOVSSwitch(LinuxApplication): """ .. class:: Class Args : @@ -50,13 +50,17 @@ class OVSSwitch(LinuxApplication): """ Register the attributes of OVSSwitch RM """ - bridge_name = Attribute("bridge_name", "Name of the switch/bridge", + bridge_name = Attribute("bridge_name", + "Name of the switch/bridge", flags = Flags.Design) - virtual_ip_pref = Attribute("virtual_ip_pref", "Virtual IP/PREFIX of the switch", + virtual_ip_pref = Attribute("virtual_ip_pref", + "Virtual IP/PREFIX of the switch", flags = Flags.Design) - controller_ip = Attribute("controller_ip", "IP of the controller", + controller_ip = Attribute("controller_ip", + "IP of the controller", flags = Flags.Design) - controller_port = Attribute("controller_port", "Port of the controller", + controller_port = Attribute("controller_port", + "Port of the controller", flags = Flags.Design) cls._register_attribute(bridge_name) @@ -72,28 +76,24 @@ class OVSSwitch(LinuxApplication): :type guid: int """ - super(OVSSwitch, self).__init__(ec, guid) + super(PlanetlabOVSSwitch, self).__init__(ec, guid) self._home = "ovsswitch-%s" % self.guid - self._checks = "ovsChecks-%s" % self.guid + self._node = None @property def node(self): """ Node wthat run the switch """ - node = self.get_connected(PlanetlabNode.get_rtype()) - if node: return node[0] - return None + if not self._node: + nodes = self.get_connected(PlanetlabNode.get_rtype()) + if not nodes or len(nodes) != 1: + msg = "PlanetlabOVSSwitch must be connected to exactly one PlanetlabNode" + #self.error(msg) + raise RuntimeError, msg - def log_message(self, msg): - return " guid %d - OVSSwitch - %s " % (self.guid, msg) + self._node = nodes[0] - @property - def ovs_home(self): - return os.path.join(self.node.exp_home, self._home) - - @property - def ovs_checks(self): - return os.path.join(self.ovs_home, self._checks) + return self._node def valid_connection(self, guid): """ Check if the connection with the guid in parameter is possible. Only meaningful connections are allowed. @@ -104,26 +104,20 @@ class OVSSwitch(LinuxApplication): """ 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 + if rm.get_rtype() not in self._authorized_connections: + return False + return True def do_provision(self): - """ Create the different OVS folder. - """ + self.node.mkdir(self.run_home) - # create home dir for ovs - self.node.mkdir(self.ovs_home) - # create dir for ovs checks - self.node.mkdir(self.ovs_checks) + self.check_sliver_ovs() + self.servers_on() + self.create_bridge() + self.assign_controller() + self.ovs_status() - super(OVSSwitch, self).do_provision() + self.set_provisioned() def do_deploy(self): """ Deploy the OVS Switch : Turn on the server, create the bridges @@ -131,138 +125,141 @@ class OVSSwitch(LinuxApplication): """ if not self.node or self.node.state < ResourceState.READY: + self.debug("---- RESCHEDULING DEPLOY ---- node state %s " % self.node.state) self.ec.schedule(self.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(OVSSwitch, self).do_deploy() + else: + self.do_discover() + self.do_provision() + + self.set_ready() def check_sliver_ovs(self): """ Check if sliver-ovs exists. If it does not exist, the execution is stopped """ - - cmd = "compgen -c | grep sliver-ovs" - out = err = "" - - (out,err), proc = self.node.run_and_wait(cmd, self.ovs_checks, - shfile = "check_cmd.sh", - pidfile = "check_cmd_pidfile", - ecodefile = "check_cmd_exitcode", - sudo = True, - stdout = "check_cmd_stdout", - stderr = "check_cmd_stderr") - - (out, err), proc = self.node.check_output(self.ovs_checks, 'check_cmd_exitcode') - - if out != "0\n": + command = "compgen -c | grep sliver-ovs" + shfile = os.path.join(self.app_home, "check_ovs_cmd.sh") + try: + self.node.run_and_wait(command, self.run_home, + shfile=shfile, + sudo = True, + pidfile="check_ovs_cmd_pidfile", + ecodefile="check_ovs_cmd_exitcode", + stdout="check_ovs_cmd_stdout", + stderr="check_ovs_cmd_stderr") + except RuntimeError: msg = "Command sliver-ovs does not exist on the VM" self.debug(msg) raise RuntimeError, msg - msg = "Command sliver-ovs exists" - self.debug(msg) - def servers_on(self): """ Start the openvswitch servers and check it """ - - # Start the server + # Make sure the server is not running + command = "sliver-ovs del-bridge %s; sliver-ovs stop" % self.get('bridge_name') + shfile = os.path.join(self.app_home, "clean.sh") + self.node.run_and_wait(command, self.run_home, + shfile=shfile, + sudo=True, + raise_on_error=False, + pidfile="clean_pidfile", + ecodefile="clean_exitcode", + stdout="clean_stdout", + stderr="clean_stderr") + + # start the server command = "sliver-ovs start" - out = err = "" - (out, err), proc = self.node.run_and_wait(command, self.ovs_checks, - shfile = "start_srv.sh", - pidfile = "start_srv_pidfile", - ecodefile = "start_srv_exitcode", - sudo = True, - raise_on_error = True, - stdout = "start_srv_stdout", - stderr = "start_srv_stderr") - (out, err), proc = self.node.check_output(self.ovs_checks, 'start_srv_exitcode') - - if out != "0\n": - self.error("Servers have not started") - raise RuntimeError, msg - - # Check if the servers are running or not - cmd = "ps -A | grep ovsdb-server" - out = err = "" - (out, err), proc = self.node.run_and_wait(cmd, self.ovs_checks, - shfile = "status_srv.sh", - pidfile = "status_srv_pidfile", - ecodefile = "status_srv_exitcode", - sudo = True, - stdout = "status_srv_stdout", - stderr = "status_srv_stderr") - (out, err), proc = self.node.check_output(self.ovs_checks, 'status_srv_exitcode') - - if out != "0\n": - msg = "Servers are not running" - self.error(msg) + shfile = os.path.join(self.app_home, "start.sh") + try: + self.node.run_and_wait(command, self.run_home, + shfile=shfile, + sudo=True, + pidfile="start_pidfile", + ecodefile="start_exitcode", + stdout="start_stdout", + stderr="start_stderr") + except RuntimeError: + msg = "Failed to start ovs-server on VM" + self.debug(msg) + raise RuntimeError, msg + + command = "ps -A | grep ovsdb-server" + shfile = os.path.join(self.app_home, "ovsdb_status.sh") + try: + self.node.run_and_wait(command, self.run_home, + shfile=shfile, + sudo=True, + pidfile="ovsdb_status_pidfile", + ecodefile="ovsdb_status_exitcode", + stdout="ovsdb_status_stdout", + stderr="ovsdb_status_stderr") + except RuntimeError: + msg = "ovsdb-server not running on VM" + self.debug(msg) raise RuntimeError, msg - self.info("Server OVS Started Correctly") + self.info("Server OVS Started...") def create_bridge(self): """ 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 - - if not (self.get("bridge_name") and self.get("virtual_ip_pref")): msg = "No assignment in one or both attributes" self.error(msg) raise AttributeError, msg - cmd = "sliver-ovs create-bridge '%s' '%s'" %\ - (self.get("bridge_name"), self.get("virtual_ip_pref")) - out = err = "" - (out, err), proc = self.node.run_and_wait(cmd, self.ovs_checks, - shfile = "create_br.sh", - pidfile = "create_br_pidfile", - ecodefile = "create_br_exitcode", - sudo = True, - stdout = "create_br_stdout", - stderr = "create_br_stderr") - (out, err), proc = self.node.check_output(self.ovs_checks, 'create_br_exitcode') - - if out != "0\n": + command = "sliver-ovs create-bridge '%s' '%s'" % ( + self.get("bridge_name"), + self.get("virtual_ip_pref")) + + shfile = os.path.join(self.app_home, "bridge_create.sh") + try: + self.node.run_and_wait(command, self.run_home, + shfile=shfile, + sudo=True, + pidfile="bridge_create_pidfile", + ecodefile="bridge_create_exitcode", + stdout="bridge_create_stdout", + stderr="bridge_create_stderr") + except RuntimeError: msg = "No such pltap netdev\novs-appctl: ovs-vswitchd: server returned an error" - self.error(msg) + self.debug(msg) raise RuntimeError, msg self.info(" Bridge %s Created and Assigned to %s" %\ (self.get("bridge_name"), self.get("virtual_ip_pref")) ) - def assign_controller(self): """ Set the controller IP """ + if not (self.get("controller_ip") and self.get("controller_port")): + return + + """ if not (self.get("controller_ip") and self.get("controller_port")): msg = "No assignment in one or both attributes" self.error(msg) raise AttributeError, msg - - cmd = "ovs-vsctl set-controller %s tcp:%s:%s" %\ - (self.get("bridge_name"), self.get("controller_ip"), self.get("controller_port")) - out = err = "" - (out, err), proc = self.node.run(cmd, self.ovs_checks, - sudo = True, - stdout = "stdout", - stderr = "stderr") - - if err != "": + """ + command = "ovs-vsctl set-controller %s tcp:%s:%s" % \ + (self.get("bridge_name"), + self.get("controller_ip"), + self.get("controller_port")) + + shfile = os.path.join(self.app_home, "set_controller.sh") + try: + self.node.run_and_wait(command, self.run_home, + shfile=shfile, + sudo=True, + pidfile="set_controller_pidfile", + ecodefile="set_controller_exitcode", + stdout="set_controller_stdout", + stderr="set_controller_stderr") + except RuntimeError: msg = "SSH connection in the method assign_controller" - self.error(msg) + self.debug(msg) raise RuntimeError, msg self.info("Controller assigned to the bridge %s" % self.get("bridge_name")) @@ -270,21 +267,20 @@ class OVSSwitch(LinuxApplication): def ovs_status(self): """ 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, - sudo = True, - stdout = "show_stdout", - stderr = "show_stderr") - (out, err), proc = self.node.check_output(self.ovs_home, 'show_stdout') - - if out == "": + command = "sliver-ovs show | tail -n +2" + shfile = os.path.join(self.app_home, "ovs_status.sh") + try: + self.node.run_and_wait(command, self.run_home, + shfile=shfile, + sudo=True, + pidfile="ovs_status_pidfile", + ecodefile="ovs_status_exitcode", + stdout="ovs_status_stdout", + stderr="ovs_status_stderr") + except RuntimeError: msg = "Error when checking the status of the OpenVswitch" - self.error(msg) + self.debug(msg) raise RuntimeError, msg - - self.debug(out) def do_release(self): """ Delete the bridge and close the server. @@ -294,28 +290,27 @@ class OVSSwitch(LinuxApplication): """ - from nepi.resources.planetlab.openvswitch.ovsport import OVSPort - rms = self.get_connected(OVSPort.get_rtype()) + from nepi.resources.planetlab.openvswitch.ovsport import PlanetlabOVSPort + rms = self.get_connected(PlanetlabOVSPort.get_rtype()) - for rm in rms : + for rm in rms: if rm.state < ResourceState.RELEASED: self.ec.schedule(self.reschedule_delay, self.release) return - cmd = "sliver-ovs del-bridge %s" % self.get('bridge_name') - (out, err), proc = self.node.run(cmd, self.ovs_checks, - sudo = True) - - cmd = "sliver-ovs stop" - (out, err), proc = self.node.run(cmd, self.ovs_checks, - sudo = True) - msg = "Deleting the bridge %s" % self.get('bridge_name') self.info(msg) - if proc.poll(): - self.error(msg, out, err) - raise RuntimeError, msg - - super(OVSSwitch, self).do_release() + command = "sliver-ovs del-bridge %s; sliver-ovs stop" % self.get('bridge_name') + shfile = os.path.join(self.app_home, "stop.sh") + + self.node.run_and_wait(command, self.run_home, + shfile=shfile, + sudo=True, + pidfile="stop_pidfile", + ecodefile="stop_exitcode", + stdout="stop_stdout", + stderr="stop_stderr") + + super(PlanetlabOVSSwitch, self).do_release() diff --git a/src/nepi/resources/planetlab/openvswitch/ovsport.py b/src/nepi/resources/planetlab/openvswitch/ovsport.py index f4f7c7a9..f2cfb3eb 100644 --- a/src/nepi/resources/planetlab/openvswitch/ovsport.py +++ b/src/nepi/resources/planetlab/openvswitch/ovsport.py @@ -22,14 +22,14 @@ from nepi.execution.attribute import Attribute, Flags, Types from nepi.execution.resource import ResourceManager, clsinit_copy, \ ResourceState -from nepi.resources.planetlab.openvswitch.ovs import OVSSwitch +from nepi.resources.planetlab.openvswitch.ovs import PlanetlabOVSSwitch from nepi.resources.planetlab.node import PlanetlabNode from nepi.resources.linux.application import LinuxApplication import os @clsinit_copy -class OVSPort(LinuxApplication): +class PlanetlabOVSPort(LinuxApplication): """ .. class:: Class Args : @@ -72,39 +72,24 @@ class OVSPort(LinuxApplication): :type guid: int """ - super(OVSPort, self).__init__(ec, guid) - - + super(PlanetlabOVSPort, self).__init__(ec, guid) + self._home = "ovsport-%s" % self.guid self._port_number = None - # 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): """ 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()) - if node: return node[0] - return node[0] + return self.ovsswitch.node @property def ovsswitch(self): """ Switch where the port is created """ - ovsswitch = self.get_connected(OVSSwitch.get_rtype()) + ovsswitch = self.get_connected(PlanetlabOVSSwitch.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 @@ -118,12 +103,10 @@ class OVSPort(LinuxApplication): """ 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) + if rm.get_rtype() not in self._authorized_connections: + return False + + return True def create_port(self): """ Create the desired port @@ -141,48 +124,60 @@ class OVSPort(LinuxApplication): self.error(msg) raise AttributeError, msg - cmd = "sliver-ovs create-port %s %s" % (self.ovsswitch.get('bridge_name'), - self.get('port_name')) - self.node.run(cmd, self.ovsswitch.ovs_checks, - stderr = "stdout-%s" % self.get('port_name'), - stdout = "stderr-%s" % self.get('port_name'), - sudo = True) + command = "sliver-ovs create-port %s %s" % ( + self.ovsswitch.get('bridge_name'), + self.get('port_name')) + + shfile = os.path.join(self.app_home, "create_port.sh") + try: + self.node.run_and_wait(command, self.run_home, + shfile=shfile, + sudo = True, + stderr="port_stdout", + stdout="port_stderr", + pidfile="port_pidfile", + ecodefile="port_exitcode") + except RuntimeError: + msg = "Could not create ovs-port" + self.debug(msg) + raise RuntimeError, msg - self.info("Created the port %s on switch %s" % (self.get('port_name'), - self.ovsswitch.get('bridge_name'))) + self.info("Created port %s on switch %s" % ( + self.get('port_name'), + self.ovsswitch.get('bridge_name'))) 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') + msg = "Discovering the port number for %s" % self.get('port_name') 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.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'), - sudo = True, - stdout = "stdout-%s" % self.get('port_name'), - stderr = "stderr-%s" % self.get('port_name')) + + shfile = os.path.join(connection_app_home, "get_port.sh") + (out, err), proc = self.node.run_and_wait(command, connection_run_home, + shfile=shfile, + sudo=True, + overwrite = True, + pidfile="get_port_pidfile", + ecodefile="get_port_exitcode", + stdout="get_port_stdout", + stderr="get_port_stderr") if err != "": msg = "Error retrieving the local endpoint of the port" self.error(msg) - raise AttributeError, msg + raise RuntimeError, msg if out: - self._port_number = int(out) + self._port_number = out.strip() self.info("The number of the %s is %s" % (self.get('port_name'), self.port_number)) + # Must set a routing rule in the ovs client nodes so they know + # that the LAN can be found through the switch if remote_endpoint.is_rm_instance("planetlab::Tap"): self._vroute = self.ec.register_resource("planetlab::Vroute") self.ec.set(self._vroute, "action", "add") @@ -199,58 +194,38 @@ class OVSPort(LinuxApplication): 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 + def establish_udp_connection(self, remote_endpoint, + connection_app_home, + connection_run_home, + port): + remote_ip = remote_endpoint.node.get("ip") + command = self._establish_connection_command(port, remote_ip) + + shfile = os.path.join(connection_app_home, "connect_port.sh") + (out, err), proc = self.node.run_and_wait(command, connection_run_home, + shfile=shfile, + sudo=True, + overwrite = True, + pidfile="connect_port_pidfile", + ecodefile="connect_port_exitcode", + stdout="connect_port_stdout", + stderr="connect_port_stderr") # For debugging msg = "Connection on port configured" self.debug(msg) - - def _establish_connection_command(self, port): + def _establish_connection_command(self, port, remote_ip): """ 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 " % self.remote_ip) - command.append("%s " % port) + command.append("set-remote-endpoint") + command.append(local_port_name) + command.append(remote_ip) + command.append(port) command = " ".join(command) command = self.replace_paths(command) return command @@ -264,17 +239,8 @@ class OVSPort(LinuxApplication): def check_status(self): return self.node.status(self._pid, self._ppid) - def do_deploy(self): - """ Deploy the OVS port after the OVS Switch - """ - - 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() + def do_provision(self): + self.node.mkdir(self.run_home) self.create_port() end_ip = self.ovsswitch.get('virtual_ip_pref').split('/') @@ -282,8 +248,20 @@ class OVSPort(LinuxApplication): #Check the status of the OVS Switch self.ovsswitch.ovs_status() + + self.set_provisioned() + + def do_deploy(self): + """ Deploy the OVS port after the OVS Switch + """ + 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) + else: + self.do_discover() + self.do_provision() - super(OVSPort, self).do_deploy() + self.set_ready() def do_release(self): """ Delete the port on the OVSwitch. It needs to wait for the tunnel @@ -296,16 +274,19 @@ class OVSPort(LinuxApplication): 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.ovsswitch.ovs_checks, - sudo = True) - msg = "Deleting the port %s" % self.get('port_name') self.info(msg) - if proc.poll(): - self.error(msg, out, err) - raise RuntimeError, msg + command = "sliver-ovs del_port %s" % self.get('port_name') + + shfile = os.path.join(self.app_home, "stop.sh") + self.node.run_and_wait(command, self.run_home, + shfile=shfile, + sudo=True, + pidfile="stop_pidfile", + ecodefile="stop_exitcode", + stdout="stop_stdout", + stderr="stop_stderr") - super(OVSPort, self).do_release() + super(PlanetlabOVSPort, self).do_release() diff --git a/src/nepi/resources/planetlab/tap.py b/src/nepi/resources/planetlab/tap.py index 26277a27..5df36c4b 100644 --- a/src/nepi/resources/planetlab/tap.py +++ b/src/nepi/resources/planetlab/tap.py @@ -439,7 +439,10 @@ class PlanetlabTap(LinuxApplication): return command - def establish_udp_connection(self, remote_endpoint, port): + def establish_udp_connection(self, remote_endpoint, + connection_app_home, + connection_run_home, + port): # upload remote port number to file rem_port = "%s\n" % port self.node.upload(rem_port, diff --git a/test/resources/linux/ns3/cross_tunnel_ns3_linux_ping.py b/test/resources/linux/ns3/cross_ns3_linux_fdtunnel_ping.py similarity index 100% rename from test/resources/linux/ns3/cross_tunnel_ns3_linux_ping.py rename to test/resources/linux/ns3/cross_ns3_linux_fdtunnel_ping.py diff --git a/test/resources/planetlab/ns3/cross_ns3_linux_ping.py b/test/resources/planetlab/ns3/cross_ns3_planetlab_ping.py similarity index 100% rename from test/resources/planetlab/ns3/cross_ns3_linux_ping.py rename to test/resources/planetlab/ns3/cross_ns3_planetlab_ping.py