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)
91 if self.ec.exp_id.startswith('exp-'):
97 rm_list = self.get_connected(OMFNode.rtype())
98 if rm_list: return rm_list[0]
101 def stdin_hook(self, old_value, new_value):
102 self._omf_api.send_stdin(self.node.get('hostname'), new_value, self.get('appid'))
105 def add_set_hook(self):
106 attr = self._attrs["stdin"]
107 attr.set_hook = self.stdin_hook
110 def valid_connection(self, guid):
111 """ Check if the connection with the guid in parameter is possible.
112 Only meaningful connections are allowed.
114 :param guid: Guid of RM it will be connected
119 rm = self.ec.get_resource(guid)
120 if rm.rtype() not in self._authorized_connections:
121 msg = ("Connection between %s %s and %s %s refused: "
122 "An Application can be connected only to a Node" ) % \
123 (self.rtype(), self._guid, rm.rtype(), guid)
128 elif len(self.connections) != 0 :
129 msg = ("Connection between %s %s and %s %s refused: "
130 "This Application is already connected" ) % \
131 (self.rtype(), self._guid, rm.rtype(), guid)
137 msg = "Connection between %s %s and %s %s accepted" % (
138 self.rtype(), self._guid, rm.rtype(), guid)
144 """ Deploy the RM. It means nothing special for an application
145 for now (later it will be upload sources, ...)
146 It becomes DEPLOYED after getting the xmpp client.
149 if not self._omf_api :
150 self._omf_api = OMFAPIFactory.get_api(self.get('xmppSlice'),
151 self.get('xmppHost'), self.get('xmppPort'),
152 self.get('xmppPassword'), exp_id = self.exp_id)
154 if not self._omf_api :
155 msg = "Credentials are not initialzed. XMPP Connections impossible"
160 super(OMFApplication, self).deploy()
163 """ Start the RM. It means : Send Xmpp Message Using OMF protocol
164 to execute the application.
165 It becomes STARTED before the messages are sent (for coordination)
168 if not (self.get('appid') and self.get('path')) :
169 msg = "Application's information are not initialized"
174 if not self.get('args'):
175 self.set('args', " ")
176 if not self.get('env'):
179 # Some information to check the information in parameter
180 msg = " " + self.rtype() + " ( Guid : " + str(self._guid) +") : " + \
181 self.get('appid') + " : " + self.get('path') + " : " + \
182 self.get('args') + " : " + self.get('env')
186 self._omf_api.execute(self.node.get('hostname'),self.get('appid'), \
187 self.get('args'), self.get('path'), self.get('env'))
188 except AttributeError:
189 msg = "Credentials are not initialzed. XMPP Connections impossible"
194 super(OMFApplication, self).start()
197 """ Stop the RM. It means : Send Xmpp Message Using OMF protocol to
198 kill the application.
199 State is set to STOPPED after the message is sent.
203 self._omf_api.exit(self.node.get('hostname'),self.get('appid'))
204 except AttributeError:
205 msg = "Credentials were not initialzed. XMPP Connections impossible"
210 super(OMFApplication, self).stop()
213 """ Clean the RM at the end of the experiment and release the API.
217 OMFAPIFactory.release_api(self.get('xmppSlice'),
218 self.get('xmppHost'), self.get('xmppPort'),
219 self.get('xmppPassword'), exp_id = self.exp_id)
221 super(OMFApplication, self).release()