change the name of the exp-id in the OMF API for the EC one
[nepi.git] / src / nepi / resources / omf / interface.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 from nepi.execution.resource import ResourceManager, clsinit_copy, ResourceState, \
22         reschedule_delay
23 from nepi.execution.attribute import Attribute, Flags 
24
25 from nepi.resources.omf.node import OMFNode
26 from nepi.resources.omf.omf_resource import ResourceGateway, OMFResource
27 from nepi.resources.omf.channel import OMFChannel
28 from nepi.resources.omf.omf_api import OMFAPIFactory
29
30 @clsinit_copy
31 class OMFWifiInterface(OMFResource):
32     """
33     .. class:: Class Args :
34       
35         :param ec: The Experiment controller
36         :type ec: ExperimentController
37         :param guid: guid of the RM
38         :type guid: int
39         :param creds: Credentials to communicate with the rm (XmppClient for OMF)
40         :type creds: dict
41
42     .. note::
43
44        This class is used only by the Experiment Controller through the Resource 
45        Factory
46
47     """
48     _rtype = "OMFWifiInterface"
49     _authorized_connections = ["OMFNode" , "OMFChannel"]
50
51     #alias2name = dict({'w0':'wlan0', 'w1':'wlan1'})
52
53     @classmethod
54     def _register_attributes(cls):
55         """Register the attributes of an OMF interface 
56
57         """
58         alias = Attribute("alias","Alias of the interface", default = "w0")
59         mode = Attribute("mode","Mode of the interface")
60         type = Attribute("type","Type of the interface")
61         essid = Attribute("essid","Essid of the interface")
62         ip = Attribute("ip","IP of the interface")
63         cls._register_attribute(alias)
64         cls._register_attribute(mode)
65         cls._register_attribute(type)
66         cls._register_attribute(essid)
67         cls._register_attribute(ip)
68
69     def __init__(self, ec, guid):
70         """
71         :param ec: The Experiment controller
72         :type ec: ExperimentController
73         :param guid: guid of the RM
74         :type guid: int
75         :param creds: Credentials to communicate with the rm (XmppClient for OMF)
76         :type creds: dict
77
78         """
79         super(OMFWifiInterface, self).__init__(ec, guid)
80
81         self._omf_api = None
82         self._alias = self.get('alias')
83
84     def valid_connection(self, guid):
85         """ Check if the connection with the guid in parameter is possible. 
86         Only meaningful connections are allowed.
87
88         :param guid: Guid of the current RM
89         :type guid: int
90         :rtype:  Boolean
91
92         """
93         rm = self.ec.get_resource(guid)
94         if rm.rtype() in self._authorized_connections:
95             msg = "Connection between %s %s and %s %s accepted" % \
96                 (self.rtype(), self._guid, rm.rtype(), guid)
97             self.debug(msg)
98
99             return True
100
101         msg = "Connection between %s %s and %s %s refused" % \
102              (self.rtype(), self._guid, rm.rtype(), guid)
103         self.debug(msg)
104
105         return False
106
107     @property
108     def exp_id(self):
109         return self.ec.exp_id
110
111     @property
112     def node(self):
113         rm_list = self.get_connected(OMFNode.rtype())
114         if rm_list: return rm_list[0]
115         return None
116
117     @property
118     def channel(self):
119         rm_list = self.get_connected(OMFChannel.rtype())
120         if rm_list: return rm_list[0]
121         return None
122
123
124     def configure_iface(self):
125         """ Configure the interface without the ip
126
127         """
128         if self.node.state < ResourceState.READY:
129             self.ec.schedule(reschedule_delay, self.deploy)
130             return False
131
132         try :
133             for attrname in ["mode", "type", "essid"]:
134                 attrval = self.get(attrname)
135                 attrname = "net/%s/%s" % (self._alias, attrname)
136                 self._omf_api.configure(self.node.get('hostname'), attrname, 
137                         attrval)
138         except AttributeError:
139             self._state = ResourceState.FAILED
140             msg = "Credentials are not initialzed. XMPP Connections impossible"
141             self.debug(msg)
142             #raise
143         
144         super(OMFWifiInterface, self).provision()
145         return True
146
147     def configure_ip(self):
148         """ Configure the ip of the interface
149
150         """
151         if self.channel.state < ResourceState.READY:
152             self.ec.schedule(reschedule_delay, self.deploy)
153             return False
154
155         try :
156             attrval = self.get("ip")
157             attrname = "net/%s/%s" % (self._alias, "ip")
158             self._omf_api.configure(self.node.get('hostname'), attrname, 
159                     attrval)
160         except AttributeError:
161             msg = "Credentials are not initialzed. XMPP Connections impossible"
162             self.debug(msg)
163             self.fail()
164             #raise
165
166         return True
167
168     def deploy(self):
169         """ Deploy the RM. It means : Get the xmpp client and send messages 
170         using OMF 5.4 protocol to configure the interface.
171         It becomes DEPLOYED after sending messages to configure the interface
172         """
173         if not self._omf_api :
174             self._omf_api = OMFAPIFactory.get_api(self.get('xmppSlice'), 
175                 self.get('xmppHost'), self.get('xmppPort'), 
176                 self.get('xmppPassword'), exp_id = self.exp_id)
177
178         if not self._omf_api :
179             msg = "Credentials are not initialzed. XMPP Connections impossible"
180             self.error(msg)
181             self.fail()
182             return
183
184         if not (self.get('mode') and self.get('type') and self.get('essid') \
185                 and self.get('ip')):
186             msg = "Interface's variable are not initialized"
187             self.error(msg)
188             self.fail()
189             return False
190
191         if not self.node.get('hostname') :
192             msg = "The channel is connected with an undefined node"
193             self.error(msg)
194             self.fail()
195             return False
196
197         # Just for information
198         self.debug(" " + self.rtype() + " ( Guid : " + str(self._guid) +") : " + \
199             self.get('mode') + " : " + self.get('type') + " : " + \
200             self.get('essid') + " : " + self.get('ip'))
201     
202         # Check if the node is already deployed
203         chk1 = True
204         if self.state < ResourceState.PROVISIONED:
205             chk1 = self.configure_iface()
206         if chk1:
207             chk2 = self.configure_ip()
208
209         if not (chk1 and chk2) :
210             return False
211             
212         super(OMFWifiInterface, self).deploy()
213         return True
214
215     def release(self):
216         """ Clean the RM at the end of the experiment and release the API
217
218         """
219         if self._omf_api :
220             OMFAPIFactory.release_api(self.get('xmppSlice'), 
221                 self.get('xmppHost'), self.get('xmppPort'), 
222                 self.get('xmppPassword'), exp_id = self.exp_id)
223
224         super(OMFWifiInterface, self).release()
225