Code cleanup. Setting resource state through specific functions
[nepi.git] / src / nepi / resources / omf / node.py
1 #
2 #    NEPI, a framework to manage network experiments
3 #    Copyright (C) 2013 INRIA
4 #
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.
9 #
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.
14 #
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/>.
17 #
18 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
19 #         Julien Tribino <julien.tribino@inria.fr>
20
21
22 from nepi.execution.resource import ResourceManager, clsinit, ResourceState, \
23         reschedule_delay
24 from nepi.execution.attribute import Attribute, Flags 
25
26 from nepi.resources.omf.omf_api import OMFAPIFactory
27
28 import time
29
30
31 @clsinit
32 class OMFNode(ResourceManager):
33     """
34     .. class:: Class Args :
35       
36         :param ec: The Experiment controller
37         :type ec: ExperimentController
38         :param guid: guid of the RM
39         :type guid: int
40         :param creds: Credentials to communicate with the rm (XmppClient for OMF)
41         :type creds: dict
42
43     .. note::
44
45        This class is used only by the Experiment Controller through the Resource Factory
46
47     """
48     _rtype = "OMFNode"
49     _authorized_connections = ["OMFApplication" , "OMFWifiInterface"]
50
51     @classmethod
52     def _register_attributes(cls):
53         """Register the attributes of an OMF Node
54
55         """
56         hostname = Attribute("hostname", "Hostname of the machine")
57         cpu = Attribute("cpu", "CPU of the node")
58         ram = Attribute("ram", "RAM of the node")
59         xmppSlice = Attribute("xmppSlice","Name of the slice",
60                 flags = Flags.Credential)
61         xmppHost = Attribute("xmppHost", "Xmpp Server",
62                 flags = Flags.Credential)
63         xmppPort = Attribute("xmppPort", "Xmpp Port",
64                 flags = Flags.Credential)
65         xmppPassword = Attribute("xmppPassword", "Xmpp Port",
66                 flags = Flags.Credential)
67
68         host = Attribute("host", "Hostname of the machine",
69                 flags = Flags.Filter)
70         gateway = Attribute("gateway", "Gateway",
71                 flags = Flags.Filter)
72         granularity = Attribute("granularity", "Granularity of the reservation time",
73                 flags = Flags.Filter)
74         hardware_type = Attribute("hardware_type", "Hardware type of the machine",
75                 flags = Flags.Filter)
76
77         cls._register_attribute(hostname)
78         cls._register_attribute(ram)
79         cls._register_attribute(cpu)
80         cls._register_attribute(xmppSlice)
81         cls._register_attribute(xmppHost)
82         cls._register_attribute(xmppPort)
83         cls._register_attribute(xmppPassword)
84
85         cls._register_attribute(host)
86         cls._register_attribute(gateway)
87         cls._register_attribute(granularity)
88         cls._register_attribute(hardware_type)
89
90     # XXX: We don't necessary need to have the credentials at the 
91     # moment we create the RM
92     def __init__(self, ec, guid):
93         """
94         :param ec: The Experiment controller
95         :type ec: ExperimentController
96         :param guid: guid of the RM
97         :type guid: int
98
99         """
100         super(OMFNode, self).__init__(ec, guid)
101
102         self._omf_api = None 
103
104     def valid_connection(self, guid):
105         """ Check if the connection with the guid in parameter is possible. 
106         Only meaningful connections are allowed.
107
108         :param guid: Guid of the current RM
109         :type guid: int
110         :rtype:  Boolean
111
112         """
113         rm = self.ec.get_resource(guid)
114         if rm.rtype() in self._authorized_connections:
115             msg = "Connection between %s %s and %s %s accepted" % (
116                     self.rtype(), self._guid, rm.rtype(), guid)
117             self.debug(msg)
118
119             return True
120
121         msg = "Connection between %s %s and %s %s refused" % (
122                 self.rtype(), self._guid, rm.rtype(), guid)
123         self.debug(msg)
124
125         return False
126
127     def deploy(self):
128         """ Deploy the RM. It means : Send Xmpp Message Using OMF protocol 
129             to enroll the node into the experiment.
130             It becomes DEPLOYED after sending messages to enroll the node
131
132         """ 
133         if not self._omf_api :
134             self._omf_api = OMFAPIFactory.get_api(self.get('xmppSlice'), 
135                 self.get('xmppHost'), self.get('xmppPort'), 
136                 self.get('xmppPassword'), exp_id = self.ec.exp_id)
137
138         if not self._omf_api :
139             msg = "Credentials are not initialzed. XMPP Connections impossible"
140             self.error(msg)
141             self.fail()
142             return
143
144         if not self.get('hostname') :
145             msg = "Hostname's value is not initialized"
146             self.error(msg)
147             self.fail()
148             return False
149
150         try:
151             self._omf_api.enroll_host(self.get('hostname'))
152         except AttributeError:
153             msg = "Credentials are not initialzed. XMPP Connections impossible"
154             self.error(msg)
155             self.fail()
156             #raise AttributeError, msg
157
158         super(OMFNode, self).deploy()
159
160     def discover(self):
161         """ Discover the availables nodes
162
163         """
164         pass
165      
166     def provision(self):
167         """ Provision some availables nodes
168
169         """
170         pass
171
172     def start(self):
173         """Start the RM. It means nothing special for an interface for now
174            It becomes STARTED as soon as this method starts.
175
176         """
177
178         super(OMFNode, self).start()
179
180     def stop(self):
181         """Stop the RM. It means nothing special for an interface for now
182            It becomes STOPPED as soon as this method stops
183
184         """
185         super(OMFNode, self).stop()
186
187     def release(self):
188         """Clean the RM at the end of the experiment
189
190         """
191         if self._omf_api :
192             self._omf_api.release(self.get('hostname'))
193
194             OMFAPIFactory.release_api(self.get('xmppSlice'), 
195                 self.get('xmppHost'), self.get('xmppPort'), 
196                 self.get('xmppPassword'), exp_id = self.ec.exp_id)
197
198         super(OMFNode, self).release()
199