2 # NEPI, a framework to manage network experiments
3 # Copyright (C) 2013 INRIA
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
19 # Julien Tribino <julien.tribino@inria.fr>
21 from nepi.execution.resource import ResourceManager, clsinit_copy, ResourceState, \
23 from nepi.execution.attribute import Attribute, Flags
24 from nepi.resources.omf.omf_resource import ResourceGateway, OMFResource
25 from nepi.resources.omf.node import OMFNode
26 from nepi.resources.omf.omf_api import OMFAPIFactory
30 class OMFApplication(OMFResource):
32 .. class:: Class Args :
34 :param ec: The Experiment controller
35 :type ec: ExperimentController
36 :param guid: guid of the RM
38 :param creds: Credentials to communicate with the rm (XmppClient)
43 This class is used only by the Experiment Controller through the
47 _rtype = "OMFApplication"
48 _authorized_connections = ["OMFNode"]
51 def _register_attributes(cls):
52 """ Register the attributes of an OMF application
55 appid = Attribute("appid", "Name of the application")
56 path = Attribute("path", "Path of the application")
57 args = Attribute("args", "Argument of the application")
58 env = Attribute("env", "Environnement variable of the application")
59 stdin = Attribute("stdin", "Input of the application", default = "")
60 cls._register_attribute(appid)
61 cls._register_attribute(path)
62 cls._register_attribute(args)
63 cls._register_attribute(env)
64 cls._register_attribute(stdin)
66 def __init__(self, ec, guid):
68 :param ec: The Experiment controller
69 :type ec: ExperimentController
70 :param guid: guid of the RM
72 :param creds: Credentials to communicate with the rm (XmppClient for OMF)
76 super(OMFApplication, self).__init__(ec, guid)
95 rm_list = self.get_connected(OMFNode.rtype())
96 if rm_list: return rm_list[0]
99 def stdin_hook(self, old_value, new_value):
100 self._omf_api.send_stdin(self.node.get('hostname'), new_value, self.get('appid'))
103 def add_set_hook(self):
104 attr = self._attrs["stdin"]
105 attr.set_hook = self.stdin_hook
108 def valid_connection(self, guid):
109 """ Check if the connection with the guid in parameter is possible.
110 Only meaningful connections are allowed.
112 :param guid: Guid of RM it will be connected
117 rm = self.ec.get_resource(guid)
118 if rm.rtype() not in self._authorized_connections:
119 msg = ("Connection between %s %s and %s %s refused: "
120 "An Application can be connected only to a Node" ) % \
121 (self.rtype(), self._guid, rm.rtype(), guid)
126 elif len(self.connections) != 0 :
127 msg = ("Connection between %s %s and %s %s refused: "
128 "This Application is already connected" ) % \
129 (self.rtype(), self._guid, rm.rtype(), guid)
135 msg = "Connection between %s %s and %s %s accepted" % (
136 self.rtype(), self._guid, rm.rtype(), guid)
142 """ Deploy the RM. It means nothing special for an application
143 for now (later it will be upload sources, ...)
144 It becomes DEPLOYED after getting the xmpp client.
147 if not self._omf_api :
148 self._omf_api = OMFAPIFactory.get_api(self.get('xmppSlice'),
149 self.get('xmppHost'), self.get('xmppPort'),
150 self.get('xmppPassword'), exp_id = self.exp_id)
152 if not self._omf_api :
153 msg = "Credentials are not initialzed. XMPP Connections impossible"
158 super(OMFApplication, self).deploy()
161 """ Start the RM. It means : Send Xmpp Message Using OMF protocol
162 to execute the application.
163 It becomes STARTED before the messages are sent (for coordination)
166 if not (self.get('appid') and self.get('path')) :
167 msg = "Application's information are not initialized"
172 if not self.get('args'):
173 self.set('args', " ")
174 if not self.get('env'):
177 # Some information to check the information in parameter
178 msg = " " + self.rtype() + " ( Guid : " + str(self._guid) +") : " + \
179 self.get('appid') + " : " + self.get('path') + " : " + \
180 self.get('args') + " : " + self.get('env')
184 self._omf_api.execute(self.node.get('hostname'),self.get('appid'), \
185 self.get('args'), self.get('path'), self.get('env'))
186 except AttributeError:
187 msg = "Credentials are not initialzed. XMPP Connections impossible"
192 super(OMFApplication, self).start()
195 """ Stop the RM. It means : Send Xmpp Message Using OMF protocol to
196 kill the application.
197 State is set to STOPPED after the message is sent.
201 self._omf_api.exit(self.node.get('hostname'),self.get('appid'))
202 except AttributeError:
203 msg = "Credentials were not initialzed. XMPP Connections impossible"
208 super(OMFApplication, self).stop()
211 """ Clean the RM at the end of the experiment and release the API.
215 OMFAPIFactory.release_api(self.get('xmppSlice'),
216 self.get('xmppHost'), self.get('xmppPort'),
217 self.get('xmppPassword'), exp_id = self.exp_id)
219 super(OMFApplication, self).release()