X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fnepi%2Fresources%2Fplanetlab%2Fopenvswitch%2Fovs.py;h=171750fefdf3acd36e541c33a98c1c9c979853c9;hb=23d041fe2f0d9badf6d637009e2d42a4794325c1;hp=b3ce59d80fb90ccc32e133aade0b9c8e0123271f;hpb=d662dcbab5a504791e306489dde627dde9221fd1;p=nepi.git diff --git a/src/nepi/resources/planetlab/openvswitch/ovs.py b/src/nepi/resources/planetlab/openvswitch/ovs.py index b3ce59d8..171750fe 100644 --- a/src/nepi/resources/planetlab/openvswitch/ovs.py +++ b/src/nepi/resources/planetlab/openvswitch/ovs.py @@ -15,8 +15,9 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # -# Author: Alina Quereilhac +# Authors: Alina Quereilhac # Alexandros Kouvakas +# Julien Tribino from nepi.execution.resource import ResourceManager, clsinit_copy, \ @@ -26,30 +27,37 @@ from nepi.resources.planetlab.node import PlanetlabNode from nepi.resources.linux.application import LinuxApplication 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 = "planetlab::OVSSwitch" _help = "Runs an OpenVSwitch on a PlanetLab host" - _backend = "planetlab" + _platform = "planetlab" - _authorized_connections = ["PlanetlabNode", "OVSPort", "LinuxNode"] + _authorized_connections = ["planetlab::Node", "planetla::OVSPort", "linux::Node"] @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", - flags = Flags.ExecReadOnly) + flags = Flags.Design) virtual_ip_pref = Attribute("virtual_ip_pref", "Virtual IP/PREFIX of the switch", - flags = Flags.ExecReadOnly) + flags = Flags.Design) controller_ip = Attribute("controller_ip", "IP of the controller", - flags = Flags.ExecReadOnly) + flags = Flags.Design) controller_port = Attribute("controller_port", "Port of the controller", - flags = Flags.ExecReadOnly) + flags = Flags.Design) cls._register_attribute(bridge_name) cls._register_attribute(virtual_ip_pref) @@ -64,18 +72,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) @@ -84,49 +95,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): + """ 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(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() 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 = "" @@ -146,34 +168,14 @@ class OVSWitch(LinuxApplication): raise RuntimeError, msg msg = "Command sliver-ovs exists" - self.debug(msg) - - def do_deploy(self): - """ 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.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() + 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 """ - self.info("Starting the OVSWitch servers") - command = ("sliver-ovs start") - + + # 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", @@ -183,13 +185,13 @@ class OVSWitch(LinuxApplication): 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, @@ -199,42 +201,29 @@ class OVSWitch(LinuxApplication): sudo = True, stdout = "status_srv_stdout", stderr = "status_srv_stderr") - - # Check if the servers are running or not (out, err), proc = self.node.check_output(self.ovs_checks, 'status_srv_exitcode') if out != "0\n": - self.error("Servers are not running") + msg = "Servers are not running" + self.error(msg) raise RuntimeError, msg - self.info("Servers started") - - def del_old_br(self): - # TODO: Delete old bridges that might exist maybe by adding atribute - """ With ovs-vsctl list-br - """ - pass + self.info("Server OVS Started Correctly") 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" self.error(msg) - self.debug("Bridge name is %s and virtual_ip_pref is %s" %\ - (self.get("bridge_name"), self.get("virtual_ip_pref")) ) raise AttributeError, msg - - bridge_name = self.get("bridge_name") - virtual_ip_pref = self.get("virtual_ip_pref") - self.info(" Creating the bridge %s and assigning %s" %\ - (bridge_name, virtual_ip_pref) ) + cmd = "sliver-ovs create-bridge '%s' '%s'" %\ - (bridge_name, virtual_ip_pref) + (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", @@ -243,38 +232,45 @@ class OVSWitch(LinuxApplication): 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": msg = "No such pltap netdev\novs-appctl: ovs-vswitchd: server returned an error" - self.debug("Check again the virtual IP") + self.error(msg) raise RuntimeError, msg - self.info("Bridge %s created" % bridge_name) + 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 self.get("controller_ip") and self.get("controller_port"): - controller_ip = self.get("controller_ip") - controller_port = self.get("controller_port") - self.info("Assigning the controller to the %s" % self.get("bridge_name")) - cmd = "ovs-vsctl set-controller %s tcp:%s:%s" %\ - (self.get("bridge_name"), controller_ip, controller_port) - out = err = "" - (out, err), proc = self.node.run(cmd, self.ovs_checks, - sudo = True, - stdout = "stdout", - stderr = "stderr") - if err != "": - self.debug("SSH connection refusing in assign_contr") - raise RuntimeError, msg - self.info("Controller assigned") + + 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 != "": + msg = "SSH connection in the method assign_controller" + self.error(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 created 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, @@ -282,33 +278,44 @@ class OVSWitch(LinuxApplication): stdout = "show_stdout", stderr = "show_stderr") (out, err), proc = self.node.check_output(self.ovs_home, 'show_stdout') - self.info(out) + + if out == "": + msg = "Error when checking the status of the OpenVswitch" + self.error(msg) + raise RuntimeError, msg + + self.debug(out) def do_release(self): - """ Delete the bridge and - close the servers + """ 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 + """ - # Node needs to wait until all associated RMs are released - # to be released + from nepi.resources.planetlab.openvswitch.ovsport import OVSPort - rm = self.get_connected(OVSPort.get_rtype()) + rms = self.get_connected(OVSPort.get_rtype()) - if rm[0].state < ResourceState.STOPPED: - self.ec.schedule(reschedule_delay, self.release) - return + for rm in rms : + if rm.state < ResourceState.RELEASED: + self.ec.schedule(self.reschedule_delay, self.release) + return - msg = "Deleting the bridge %s" % self.get('bridge_name') - self.info(msg) 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(OVSWitch, self).do_release() + super(OVSSwitch, self).do_release()