X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fnepi%2Fresources%2Fplanetlab%2Fopenvswitch%2Fovs.py;h=a3cf2faeeaa2cbc64f7bca88fb6e1b3e7d56e3fc;hb=6285ca51026efb69642eea9dfc7c480e722d84a9;hp=178b501370ec79d2e51c11112a273f509b06303d;hpb=741b99fe027fe6b54846a0703d26510d9b40a135;p=nepi.git diff --git a/src/nepi/resources/planetlab/openvswitch/ovs.py b/src/nepi/resources/planetlab/openvswitch/ovs.py index 178b5013..a3cf2fae 100644 --- a/src/nepi/resources/planetlab/openvswitch/ovs.py +++ b/src/nepi/resources/planetlab/openvswitch/ovs.py @@ -3,9 +3,8 @@ # Copyright (C) 2013 INRIA # # This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation; # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -28,7 +27,7 @@ from nepi.resources.linux.application import LinuxApplication import os @clsinit_copy -class OVSSwitch(LinuxApplication): +class PlanetlabOVSSwitch(LinuxApplication): """ .. class:: Class Args : @@ -41,7 +40,7 @@ class OVSSwitch(LinuxApplication): _rtype = "planetlab::OVSSwitch" _help = "Runs an OpenVSwitch on a PlanetLab host" - _backend = "planetlab" + _platform = "planetlab" _authorized_connections = ["planetlab::Node", "planetla::OVSPort", "linux::Node"] @@ -50,13 +49,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 +75,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 +103,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,160 +124,162 @@ 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) + raise RuntimeError(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) - raise RuntimeError, 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 + 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) - raise RuntimeError, 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) - raise RuntimeError, msg + self.debug(msg) + raise RuntimeError(msg) self.info("Controller assigned to the bridge %s" % self.get("bridge_name")) 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) - raise RuntimeError, msg - - self.debug(out) + self.debug(msg) + raise RuntimeError(msg) def do_release(self): """ Delete the bridge and close the server. @@ -294,28 +289,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()