change PlanetLab to planetlab for the PlanetLab node
[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 from nepi.execution.attribute import Attribute, Flags 
24
25 from nepi.resources.omf.omf_api import OMFAPIFactory
26
27 import time
28
29 reschedule_delay = "0.5s"
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. Only meaningful connections are allowed.
106
107         :param guid: Guid of the current RM
108         :type guid: int
109         :rtype:  Boolean
110
111         """
112         rm = self.ec.get_resource(guid)
113         if rm.rtype() in self._authorized_connections:
114             msg = "Connection between %s %s and %s %s accepted" % (self.rtype(), self._guid, rm.rtype(), guid)
115             self.debug(msg)
116             return True
117         msg = "Connection between %s %s and %s %s refused" % (self.rtype(), self._guid, rm.rtype(), guid)
118         self.debug(msg)
119         return False
120
121     def deploy(self):
122         """Deploy the RM. It means : Send Xmpp Message Using OMF protocol to enroll the node into the experiment
123            It becomes DEPLOYED after sending messages to enroll the node
124
125         """ 
126         if not self._omf_api :
127             self._omf_api = OMFAPIFactory.get_api(self.get('xmppSlice'), 
128                self.get('xmppHost'), self.get('xmppPort'), self.get('xmppPassword'))
129
130         if self.get('hostname') :
131             try:
132                 self._omf_api.enroll_host(self.get('hostname'))
133             except AttributeError:
134                 self._state = ResourceState.FAILED
135                 msg = "Credentials are not initialzed. XMPP Connections impossible"
136                 self.debug(msg)
137                 raise AttributeError, msg
138
139         super(OMFNode, self).deploy()
140
141     def discover(self):
142         """ Discover the availables nodes
143
144         """
145         pass
146      
147     def provision(self):
148         """ Provision some availables nodes
149
150         """
151         pass
152
153     def start(self):
154         """Start the RM. It means nothing special for an interface for now
155            It becomes STARTED as soon as this method starts.
156
157         """
158
159         super(OMFNode, self).start()
160
161     def stop(self):
162         """Stop the RM. It means nothing special for an interface for now
163            It becomes STOPPED as soon as this method stops
164
165         """
166         super(OMFNode, self).stop()
167
168     def release(self):
169         """Clean the RM at the end of the experiment
170
171         """
172         if self._omf_api :
173             self._omf_api.release(self.get('hostname'))
174             OMFAPIFactory.release_api(self.get('xmppSlice'), 
175                 self.get('xmppHost'), self.get('xmppPort'), self.get('xmppPassword'))
176