From e6c42da235404a54fb708af63781e6d918635c88 Mon Sep 17 00:00:00 2001 From: Julien Tribino Date: Mon, 1 Apr 2013 19:24:13 +0200 Subject: [PATCH] Merge with comments --- src/neco/resources/omf/omf_api.py | 139 ++++++++++++++++++++- src/neco/resources/omf/omf_application.py | 54 +++++++- src/neco/resources/omf/omf_channel.py | 58 ++++++++- src/neco/resources/omf/omf_client.py | 14 +++ src/neco/resources/omf/omf_interface.py | 50 +++++++- src/neco/resources/omf/omf_messages_5_4.py | 54 ++++---- src/neco/resources/omf/omf_node.py | 49 ++++++++ 7 files changed, 388 insertions(+), 30 deletions(-) diff --git a/src/neco/resources/omf/omf_api.py b/src/neco/resources/omf/omf_api.py index 412e735d..38aa72a1 100644 --- a/src/neco/resources/omf/omf_api.py +++ b/src/neco/resources/omf/omf_api.py @@ -8,6 +8,25 @@ from neco.resources.omf.omf_client import OMFClient from neco.resources.omf.omf_messages_5_4 import MessageHandler class OMFAPI(object): + """ + .. class:: Class Args : + + :param slice: Xmpp Slice + :type slice: Str + :param host: Xmpp Server + :type host: Str + :param port: Xmpp Port + :type port: Str + :param password: Xmpp password + :type password: Str + :param xmpp_root: Root of the Xmpp Topic Architecture + :type xmpp_root: Str + + .. note:: + + This class is the implementation of an OMF 5.4 API. Since the version 5.4.1, the Topic Architecture start with OMF_5.4 instead of OMF used for OMF5.3 + + """ def __init__(self, slice, host, port, password, xmpp_root = None): date = datetime.datetime.now().strftime("%Y-%m-%dt%H.%M.%S") tz = -time.altzone if time.daylight != 0 else -time.timezone @@ -42,6 +61,9 @@ class OMFAPI(object): self._enroll_logger() def _init_client(self): + """ Initialize XMPP Client + + """ jid = "%s@%s" % (self._user, self._host) xmpp = OMFClient(jid, self._password) # PROTOCOL_SSLv3 required for compatibility with OpenFire @@ -59,6 +81,9 @@ class OMFAPI(object): raise RuntimeError(msg) def _enroll_experiment(self): + """ Create and Subscribe to the Session Topic + + """ xmpp_node = self._exp_session_id self._client.create(xmpp_node) #print "Create experiment sesion id topics !!" @@ -67,6 +92,9 @@ class OMFAPI(object): def _enroll_newexperiment(self): + """ Publish New Experiment Message + + """ address = "/%s/%s/%s/%s" % (self._host, self._xmpp_root, self._slice, self._user) print address payload = self._message.newexpfunction(self._user, address) @@ -74,6 +102,9 @@ class OMFAPI(object): self._client.publish(payload, slice_sid) def _enroll_logger(self): + """ Create and Subscribe to the Logger Topic + + """ xmpp_node = self._logger_session_id self._client.create(xmpp_node) self._client.subscribe(xmpp_node) @@ -85,20 +116,44 @@ class OMFAPI(object): self._client.publish(payload, xmpp_node) def _host_session_id(self, hostname): + """ Return the Topic Name as /xmpp_root/slice/user/hostname + + :param hostname: Full hrn of the node + :type hostname: str + + """ return "/%s/%s/%s/%s" % (self._xmpp_root, self._slice, self._user, hostname) def _host_resource_id(self, hostname): + """ Return the Topic Name as /xmpp_root/slice/resources/hostname + + :param hostname: Full hrn of the node + :type hostname: str + + """ return "/%s/%s/resources/%s" % (self._xmpp_root, self._slice, hostname) @property def _exp_session_id(self): + """ Return the Topic Name as /xmpp_root/slice/user + + """ return "/%s/%s/%s" % (self._xmpp_root, self._slice, self._user) @property def _logger_session_id(self): + """ Return the Topic Name as /xmpp_root/slice/LOGGER + + """ return "/%s/%s/%s/LOGGER" % (self._xmpp_root, self._slice, self._user) def delete(self, hostname): + """ Delete the topic corresponding to the hostname for this session + + :param hostname: Full hrn of the node + :type hostname: str + + """ if not hostname in self._hostnames: return @@ -108,6 +163,12 @@ class OMFAPI(object): self._client.delete(xmpp_node) def enroll_host(self, hostname): + """ Create and Subscribe to the session topic and the resources corresponding to the hostname + + :param hostname: Full hrn of the node + :type hostname: str + + """ if hostname in self._hostnames: return @@ -123,22 +184,57 @@ class OMFAPI(object): payload = self._message.enrollfunction("1", "*", "1", hostname) self._client.publish(payload, xmpp_node) - def configure(self, hostname, attribute, value): + def configure(self, hostname, attribute, value): + """ Configure attribute on the node + + :param hostname: Full hrn of the node + :type hostname: str + :param attribute: Attribute that need to be configured (often written as /net/wX/attribute, with X the interface number) + :type attribute: str + :param value: Value of the attribute + :type value: str + + """ payload = self._message.configurefunction(hostname, value, attribute) xmpp_node = self._host_session_id(hostname) self._client.publish(payload, xmpp_node) def execute(self, hostname, app_id, arguments, path, env): + """ Execute command on the node + + :param hostname: Full hrn of the node + :type hostname: str + :param app_id: Application Id (Any id that represents in a unique way the application) + :type app_id: str + :param arguments: Arguments of the application + :type arguments: str + :param path: Path of the application + :type path: str + :param env: Environnement values for the application + :type env: str + + """ payload = self._message.executefunction(hostname, app_id, arguments, path, env) xmpp_node = self._host_session_id(hostname) self._client.publish(payload, xmpp_node) def exit(self, hostname, app_id): + """ Kill an application started with OMF + + :param hostname: Full hrn of the node + :type hostname: str + :param app_id: Application Id of the application you want to stop + :type app_id: str + + """ payload = self._message.exitfunction(hostname, app_id) xmpp_node = self._host_session_id(hostname) self._client.publish(payload, xmpp_node) def disconnect(self): + """ Delete the sesion and logger topic and disconnect + + """ self._client.delete(self._exp_session_id) self._client.delete(self._logger_session_id) @@ -150,11 +246,30 @@ class OMFAPI(object): class OMFAPIFactory(object): + """ + .. note:: + + It allows the different RM to use the same xmpp client if they use the same credentials. For the moment, it is focused on Xmpp. + + """ + # XXX: put '_apis' instead of '_Api' _Api = dict() @classmethod def get_api(cls, slice, host, port, password): + """ Get an Api + + :param slice: Xmpp Slice Name + :type slice: str + :param host: Xmpp Server Adress + :type host: str + :param port: Xmpp Port (Default : 5222) + :type port: str + :param password: Xmpp Password + :type password: str + + """ if slice and host and port and password: key = cls._hash_api(slice, host, port) if key in cls._Api: @@ -165,6 +280,18 @@ class OMFAPIFactory(object): @classmethod def create_api(cls, slice, host, port, password): + """ Create an API if this one doesn't exist yet with this credentials + + :param slice: Xmpp Slice Name + :type slice: str + :param host: Xmpp Server Adress + :type host: str + :param port: Xmpp Port (Default : 5222) + :type port: str + :param password: Xmpp Password + :type password: str + + """ OmfApi = OMFAPI(slice, host, port, password) key = cls._hash_api(slice, host, port) cls._Api[key] = OmfApi @@ -182,6 +309,16 @@ class OMFAPIFactory(object): # XXX: change method name for 'make_key' @classmethod def _hash_api(cls, slice, host, port): + """ Hash the credentials in order to create a key + + :param slice: Xmpp Slice Name + :type slice: str + :param host: Xmpp Server Adress + :type host: str + :param port: Xmpp Port (Default : 5222) + :type port: str + + """ res = slice + "_" + host + "_" + port return res diff --git a/src/neco/resources/omf/omf_application.py b/src/neco/resources/omf/omf_application.py index 19ef22d9..2ffe809b 100644 --- a/src/neco/resources/omf/omf_application.py +++ b/src/neco/resources/omf/omf_application.py @@ -1,5 +1,6 @@ #!/usr/bin/env python -from neco.execution.resource import ResourceManager, clsinit + +from neco.execution.resource import Resource, clsinit from neco.execution.attribute import Attribute from neco.resources.omf.omf_api import OMFAPIFactory @@ -7,12 +8,30 @@ import neco import logging @clsinit -class OMFApplication(ResourceManager): +class OMFApplication(Resource): + """ + .. class:: Class Args : + + :param ec: The Experiment controller + :type ec: ExperimentController + :param guid: guid of the RM + :type guid: int + :param creds: Credentials to communicate with the rm (XmppClient for OMF) + :type creds: dict + + .. note:: + + This class is used only by the Experiment Controller through the Resource Factory + + """ _rtype = "OMFApplication" _authorized_connections = ["OMFNode"] @classmethod def _register_attributes(cls): + """Register the attributes of an OMF application + """ + appid = Attribute("appid", "Name of the application") path = Attribute("path", "Path of the application") args = Attribute("args", "Argument of the application") @@ -32,6 +51,16 @@ class OMFApplication(ResourceManager): def __init__(self, ec, guid, creds): + """ + :param ec: The Experiment controller + :type ec: ExperimentController + :param guid: guid of the RM + :type guid: int + :param creds: Credentials to communicate with the rm (XmppClient for OMF) + :type creds: dict + + """ + super(OMFApplication, self).__init__(ec, guid) self.set('xmppSlice', creds['xmppSlice']) self.set('xmppHost', creds['xmppHost']) @@ -50,7 +79,15 @@ class OMFApplication(ResourceManager): self._logger = logging.getLogger("neco.omf.omfApp ") self._logger.setLevel(neco.LOGLEVEL) + def _validate_connection(self, guid): + """Check if the connection is available. + + :param guid: Guid of the current RM + :type guid: int + :rtype: Boolean + + """ rm = self.ec.resource(guid) if rm.rtype() not in self._authorized_connections: self._logger.debug("Connection between %s %s and %s %s refused : An Application can be connected only to a Node" % (self.rtype(), self._guid, rm.rtype(), guid)) @@ -63,6 +100,13 @@ class OMFApplication(ResourceManager): return True def _get_nodes(self, conn_set): + """Get the RM of the node to which the application is connected + + :param conn_set: Connections of the current Guid + :type conn_set: set + :rtype: ResourceManager + """ + for elt in conn_set: rm = self.ec.resource(elt) if rm.rtype() == "OMFNode": @@ -70,6 +114,9 @@ class OMFApplication(ResourceManager): return None def start(self): + """Send Xmpp Message Using OMF protocol to execute the application + + """ self._logger.debug(" " + self.rtype() + " ( Guid : " + str(self._guid) +") : " + self.get('appid') + " : " + self.get('path') + " : " + self.get('args') + " : " + self.get('env')) #try: if self.get('appid') and self.get('path') and self.get('args') and self.get('env'): @@ -77,6 +124,9 @@ class OMFApplication(ResourceManager): self._omf_api.execute(rm_node.get('hostname'),self.get('appid'), self.get('args'), self.get('path'), self.get('env')) def stop(self): + """Send Xmpp Message Using OMF protocol to kill the application + + """ rm_node = self._get_nodes(self._connections) self._omf_api.exit(rm_node.get('hostname'),self.get('appid')) diff --git a/src/neco/resources/omf/omf_channel.py b/src/neco/resources/omf/omf_channel.py index 026b4aa5..d9da3ed7 100644 --- a/src/neco/resources/omf/omf_channel.py +++ b/src/neco/resources/omf/omf_channel.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -from neco.execution.resource import ResourceManager, clsinit +from neco.execution.resource import Resource, clsinit from neco.execution.attribute import Attribute from neco.resources.omf.omf_api import OMFAPIFactory @@ -8,12 +8,29 @@ import neco import logging @clsinit -class OMFChannel(ResourceManager): +class OMFChannel(Resource): + """ + .. class:: Class Args : + + :param ec: The Experiment controller + :type ec: ExperimentController + :param guid: guid of the RM + :type guid: int + :param creds: Credentials to communicate with the rm (XmppClient for OMF) + :type creds: dict + + .. note:: + + This class is used only by the Experiment Controller through the Resource Factory + + """ _rtype = "OMFChannel" _authorized_connections = ["OMFWifiInterface"] @classmethod def _register_attributes(cls): + """Register the attributes of an OMF channel + """ channel = Attribute("channel", "Name of the application") xmppSlice = Attribute("xmppSlice","Name of the slice", flags = "0x02") xmppHost = Attribute("xmppHost", "Xmpp Server",flags = "0x02") @@ -26,6 +43,15 @@ class OMFChannel(ResourceManager): cls._register_attribute(xmppPassword) def __init__(self, ec, guid, creds): + """ + :param ec: The Experiment controller + :type ec: ExperimentController + :param guid: guid of the RM + :type guid: int + :param creds: Credentials to communicate with the rm (XmppClient for OMF) + :type creds: dict + + """ super(OMFChannel, self).__init__(ec, guid) self.set('xmppSlice', creds['xmppSlice']) self.set('xmppHost', creds['xmppHost']) @@ -40,6 +66,13 @@ class OMFChannel(ResourceManager): self._logger.setLevel(neco.LOGLEVEL) def _validate_connection(self, guid): + """Check if the connection is available. + + :param guid: Guid of the current RM + :type guid: int + :rtype: Boolean + + """ rm = self.ec.resource(guid) if rm.rtype() in self._authorized_connections: self._logger.debug("Connection between %s %s and %s %s accepted" % (self.rtype(), self._guid, rm.rtype(), guid)) @@ -47,7 +80,15 @@ class OMFChannel(ResourceManager): self._logger.debug("Connection between %s %s and %s %s refused" % (self.rtype(), self._guid, rm.rtype(), guid)) return False - def _get_nodes(self, conn_set): + def _get_target(self, conn_set): + """ + Get the couples (host, interface) that used this channel + + :param conn_set: Connections of the current Guid + :type conn_set: set + :rtype: list + :return: self._nodes_guid + """ for elt in conn_set: rm_iface = self.ec.resource(elt) for conn in rm_iface._connections: @@ -59,14 +100,23 @@ class OMFChannel(ResourceManager): return self._nodes_guid def discover(self): + """ Discover the availables channels + + """ pass def provision(self, credential): + """ Provision some availables channels + + """ pass def start(self): + """Send Xmpp Message Using OMF protocol to configure Channel + + """ if self.get('channel'): - set_nodes = self._get_nodes(self._connections) + set_nodes = self._get_target(self._connections) #print set_nodes for couple in set_nodes: #print "Couple node/alias : " + couple[0] + " , " + couple[1] diff --git a/src/neco/resources/omf/omf_client.py b/src/neco/resources/omf/omf_client.py index 7557a2c6..3764f657 100644 --- a/src/neco/resources/omf/omf_client.py +++ b/src/neco/resources/omf/omf_client.py @@ -7,6 +7,20 @@ import xml.etree.ElementTree as ET import neco class OMFClient(sleekxmpp.ClientXMPP): + """ + .. class:: Class Args : + + :param jid: Jabber Id (= Xmpp Slice + Date) + :type jid: Str + :param password: Jabber Password (= Xmpp Password) + :type password: Str + + .. note:: + + This class is an XMPP Client with customized method + + """ + def __init__(self, jid, password): sleekxmpp.ClientXMPP.__init__(self, jid, password) self._ready = False diff --git a/src/neco/resources/omf/omf_interface.py b/src/neco/resources/omf/omf_interface.py index 40a650cf..982d8cdd 100644 --- a/src/neco/resources/omf/omf_interface.py +++ b/src/neco/resources/omf/omf_interface.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -from neco.execution.resource import ResourceManager, clsinit +from neco.execution.resource import Resource, clsinit from neco.execution.attribute import Attribute from neco.resources.omf.omf_api import OMFAPIFactory @@ -8,7 +8,22 @@ import neco import logging @clsinit -class OMFWifiInterface(ResourceManager): +class OMFWifiInterface(Resource): + """ + .. class:: Class Args : + + :param ec: The Experiment controller + :type ec: ExperimentController + :param guid: guid of the RM + :type guid: int + :param creds: Credentials to communicate with the rm (XmppClient for OMF) + :type creds: dict + + .. note:: + + This class is used only by the Experiment Controller through the Resource Factory + + """ _rtype = "OMFWifiInterface" _authorized_connections = ["OMFNode" , "OMFChannel"] @@ -16,6 +31,8 @@ class OMFWifiInterface(ResourceManager): @classmethod def _register_attributes(cls): + """Register the attributes of an OMF interface + """ alias = Attribute("alias","Alias of the interface", default_value = "w0") mode = Attribute("mode","Mode of the interface") type = Attribute("type","Type of the interface") @@ -36,6 +53,15 @@ class OMFWifiInterface(ResourceManager): cls._register_attribute(ip) def __init__(self, ec, guid, creds): + """ + :param ec: The Experiment controller + :type ec: ExperimentController + :param guid: guid of the RM + :type guid: int + :param creds: Credentials to communicate with the rm (XmppClient for OMF) + :type creds: dict + + """ super(OMFWifiInterface, self).__init__(ec, guid) self.set('xmppSlice', creds['xmppSlice']) self.set('xmppHost', creds['xmppHost']) @@ -49,6 +75,13 @@ class OMFWifiInterface(ResourceManager): self._logger.setLevel(neco.LOGLEVEL) def _validate_connection(self, guid): + """Check if the connection is available. + + :param guid: Guid of the current RM + :type guid: int + :rtype: Boolean + + """ rm = self.ec.resource(guid) if rm.rtype() in self._authorized_connections: self._logger.debug("Connection between %s %s and %s %s accepted" % (self.rtype(), self._guid, rm.rtype(), guid)) @@ -57,6 +90,13 @@ class OMFWifiInterface(ResourceManager): return False def _get_nodes(self, conn_set): + """ + Get the RM of the node to which the application is connected + + :param conn_set: Connections of the current Guid + :type conn_set: set + :rtype: ResourceManager + """ for elt in conn_set: rm = self.ec.resource(elt) if rm.rtype() == "OMFNode": @@ -65,6 +105,9 @@ class OMFWifiInterface(ResourceManager): def start(self): + """Send Xmpp Messages Using OMF protocol to configure Interface + + """ self._logger.debug(self.rtype() + " ( Guid : " + str(self._guid) +") : " + self.get('mode') + " : " + self.get('type') + " : " + self.get('essid') + " : " + self.get('ip')) #try: if self.get('mode') and self.get('type') and self.get('essid') and self.get('ip'): @@ -76,6 +119,9 @@ class OMFWifiInterface(ResourceManager): self._omf_api.configure(rm_node.get('hostname'), attrname, attrval) def stop(self): + """Send Xmpp Message Using OMF protocol to put down the interface + + """ self._omf_api.disconnect() diff --git a/src/neco/resources/omf/omf_messages_5_4.py b/src/neco/resources/omf/omf_messages_5_4.py index 77c53dc0..4b072651 100644 --- a/src/neco/resources/omf/omf_messages_5_4.py +++ b/src/neco/resources/omf/omf_messages_5_4.py @@ -22,13 +22,25 @@ ENROLL = "ENROLL" EXIT = "EXIT" class MessageHandler(): - SliceID = "" - ExpID = "" + """ + .. class:: Class Args : + + :param sliceid: Slice Name (= Xmpp Slice) + :type expid: Str + :param expid: Experiment ID (= Xmpp User) + :type expid: Str + + .. note:: + + This class is used only for OMF 5.4 Protocol and is going to become unused + + """ + def __init__(self, sliceid, expid ): - self.SliceID = sliceid - self.ExpID = expid - print "init" + self.ExpID +" "+ self.SliceID + self._slice_id = sliceid + self._exp_id = expid + print "init" + self._exp_id +" "+ self._slice_id pass def Mid(self, parent, keyword): @@ -45,8 +57,8 @@ class MessageHandler(): payload = ET.Element("omf-message") execute = self.Mid(payload,"EXECUTE") env = self.Mtext(execute, "ENV", env) - sliceid = self.Mtext(execute,"SLICEID",self.SliceID) - expid = self.Mtext(execute,"EXPID",self.ExpID) + sliceid = self.Mtext(execute,"SLICEID",self._slice_id) + expid = self.Mtext(execute,"EXPID",self._exp_id) target = self.Mtext(execute,"TARGET",target) appid = self.Mtext(execute,"APPID",appid) cmdlineargs = self.Mtext(execute,"CMDLINEARGS",cmdlineargs) @@ -56,8 +68,8 @@ class MessageHandler(): def exitfunction(self, target, appid): payload = ET.Element("omf-message") execute = self.Mid(payload,"EXIT") - sliceid = self.Mtext(execute,"SLICEID",self.SliceID) - expid = self.Mtext(execute,"EXPID",self.ExpID) + sliceid = self.Mtext(execute,"SLICEID",self._slice_id) + expid = self.Mtext(execute,"EXPID",self._exp_id) target = self.Mtext(execute,"TARGET",target) appid = self.Mtext(execute,"APPID",appid) return payload @@ -65,8 +77,8 @@ class MessageHandler(): def configurefunction(self, target, value, path): payload = ET.Element("omf-message") config = self.Mid(payload, "CONFIGURE") - sliceid = self.Mtext(config,"SLICEID",self.SliceID) - expid = self.Mtext(config,"EXPID",self.ExpID) + sliceid = self.Mtext(config,"SLICEID",self._slice_id) + expid = self.Mtext(config,"EXPID",self._exp_id) target = self.Mtext(config,"TARGET",target) value = self.Mtext(config,"VALUE",value) path = self.Mtext(config,"PATH",path) @@ -76,9 +88,9 @@ class MessageHandler(): payload = ET.Element("omf-message") log = self.Mid(payload, "LOGGING") level = self.Mtext(log,"LEVEL",level) - sliceid = self.Mtext(log,"SLICEID",self.SliceID) + sliceid = self.Mtext(log,"SLICEID",self._slice_id) logger = self.Mtext(log,"LOGGER",logger) - expid = self.Mtext(log,"EXPID",self.ExpID) + expid = self.Mtext(log,"EXPID",self._exp_id) level_name = self.Mtext(log,"LEVEL_NAME",level_name) data = self.Mtext(log,"DATA",data) return payload @@ -86,8 +98,8 @@ class MessageHandler(): def aliasfunction(self, name, target): payload = ET.Element("omf-message") alias = self.Mid(payload,"ALIAS") - sliceid = self.Mtext(alias,"SLICEID",self.SliceID) - expid = self.Mtext(alias,"EXPID",self.ExpID) + sliceid = self.Mtext(alias,"SLICEID",self._slice_id) + expid = self.Mtext(alias,"EXPID",self._exp_id) name = self.Mtext(alias,"NAME",name) target = self.Mtext(alias,"TARGET",target) return payload @@ -96,9 +108,9 @@ class MessageHandler(): payload = ET.Element("omf-message") enroll = self.Mid(payload,"ENROLL") enrollkey = self.Mtext(enroll,"ENROLLKEY",enrollkey) - sliceid = self.Mtext(enroll,"SLICEID",self.SliceID) + sliceid = self.Mtext(enroll,"SLICEID",self._slice_id) image = self.Mtext(enroll,"IMAGE",image) - expid = self.Mtext(enroll,"EXPID",self.ExpID) + expid = self.Mtext(enroll,"EXPID",self._exp_id) index = self.Mtext(enroll,"INDEX",index) target = self.Mtext(enroll,"TARGET",target) return payload @@ -106,8 +118,8 @@ class MessageHandler(): def noopfunction(self,target): payload = ET.Element("omf-message") noop = self.Mid(payload,"NOOP") - sliceid = self.Mtext(noop,"SLICEID",self.SliceID) - expid = self.Mtext(noop,"EXPID",self.ExpID) + sliceid = self.Mtext(noop,"SLICEID",self._slice_id) + expid = self.Mtext(noop,"EXPID",self._exp_id) target = self.Mtext(noop,"TARGET",target) return payload @@ -115,8 +127,8 @@ class MessageHandler(): payload = ET.Element("omf-message") newexp = self.Mid(payload,"EXPERIMENT_NEW") experimentid = self.Mtext(newexp,"EXPERIMENT_ID",experimentid) - sliceid = self.Mtext(newexp,"SLICEID",self.SliceID) - expid = self.Mtext(newexp,"EXPID",self.ExpID) + sliceid = self.Mtext(newexp,"SLICEID",self._slice_id) + expid = self.Mtext(newexp,"EXPID",self._exp_id) address = self.Mtext(newexp,"ADDRESS",address) return payload diff --git a/src/neco/resources/omf/omf_node.py b/src/neco/resources/omf/omf_node.py index 064da473..becc4006 100644 --- a/src/neco/resources/omf/omf_node.py +++ b/src/neco/resources/omf/omf_node.py @@ -9,11 +9,29 @@ import logging @clsinit class OMFNode(ResourceManager): + """ + .. class:: Class Args : + + :param ec: The Experiment controller + :type ec: ExperimentController + :param guid: guid of the RM + :type guid: int + :param creds: Credentials to communicate with the rm (XmppClient for OMF) + :type creds: dict + + .. note:: + + This class is used only by the Experiment Controller through the Resource Factory + + """ _rtype = "OMFNode" _authorized_connections = ["OMFApplication" , "OMFWifiInterface"] @classmethod def _register_attributes(cls): + """Register the attributes of an OMF Node + + """ hostname = Attribute("hostname", "Hostname of the machine") cpu = Attribute("cpu", "CPU of the node") ram = Attribute("ram", "RAM of the node") @@ -35,6 +53,9 @@ class OMFNode(ResourceManager): @classmethod def _register_filters(cls): + """Register the filters of an OMF Node + + """ hostname = Attribute("hostname", "Hostname of the machine") gateway = Attribute("gateway", "Gateway") granularity = Attribute("granularity", "Granularity of the reservation time") @@ -49,6 +70,15 @@ class OMFNode(ResourceManager): # THE OMF API SHOULD BE CREATED ON THE DEPLOY METHOD, NOT NOW # THIS FORCES MORE CONSTRAINES ON THE WAY WE WILL AUTHOMATE DEPLOYMENT! def __init__(self, ec, guid, creds): + """ + :param ec: The Experiment controller + :type ec: ExperimentController + :param guid: guid of the RM + :type guid: int + :param creds: Credentials to communicate with the rm (XmppClient for OMF) + :type creds: dict + + """ super(OMFNode, self).__init__(ec, guid) self.set('xmppSlice', creds['xmppSlice']) self.set('xmppHost', creds['xmppHost']) @@ -64,6 +94,13 @@ class OMFNode(ResourceManager): self._logger.setLevel(neco.LOGLEVEL) def _validate_connection(self, guid): + """Check if the connection is available. + + :param guid: Guid of the current RM + :type guid: int + :rtype: Boolean + + """ rm = self.ec.resource(guid) if rm.rtype() in self._authorized_connections: self._logger.debug("Connection between %s %s and %s %s accepted" % (self.rtype(), self._guid, rm.rtype(), guid)) @@ -72,15 +109,27 @@ class OMFNode(ResourceManager): return False def discover(self): + """ Discover the availables nodes + + """ pass def provision(self, credential): + """ Provision some availables nodes + + """ pass def start(self): + """Send Xmpp Message Using OMF protocol to enroll the node into the experiment + + """ self._omf_api.enroll_host(self.get('hostname')) def stop(self): + """Send Xmpp Message Using OMF protocol to disconnect the node + + """ self._omf_api.disconnect() def configure(self): -- 2.47.0