553f1c0943e80234004541f71e7b67ecb306c9e1
[sfa.git] / sfa / rspecs / elements / versions / iotlabv1Node.py
1
2 from sfa.util.xrn import Xrn
3 from sfa.util.xml import XpathFilter
4 from sfa.rspecs.elements.node import NodeElement
5 from sfa.rspecs.elements.sliver import Sliver
6 from sfa.rspecs.elements.location import Location
7 from sfa.rspecs.elements.hardware_type import HardwareType
8 from sfa.rspecs.elements.element import Element
9 from sfa.rspecs.elements.interface import Interface
10 from sfa.rspecs.elements.versions.iotlabv1Sliver import Iotlabv1Sliver
11 from sfa.util.sfalogging import logger
12
13 class IotlabNode(NodeElement):
14     #First get the fields already defined in the class Node
15     fields = list(NodeElement.fields)
16     #Extend it with iotlab's specific fields
17     fields.extend (['archi', 'radio', 'mobile','position'])
18
19
20 class IotlabPosition(Element):
21     fields = ['x', 'y','z']
22
23 class IotlabLocation(Location):
24     fields = list(Location.fields)
25     fields.extend (['site'])
26
27
28 class IotlabMobility(Element):
29     """ Class to give information of a node's mobility, and what kind of
30     mobility it is (train, roomba robot ...) """
31     fields = ['mobile', 'mobility_type']
32
33
34
35 class Iotlabv1Node:
36
37     @staticmethod
38     def add_connection_information(xml, ldap_username, sites_set):
39         """ Adds login and ssh connection info in the network item in
40         the xml. Does not create the network element, therefore
41         should be used after add_nodes, which creates the network item.
42
43         """
44         logger.debug(" add_connection_information ")
45         #Get network item in the xml
46         network_elems = xml.xpath('//network')
47         if len(network_elems) > 0:
48             network_elem = network_elems[0]
49
50             iotlab_network_dict = {}
51             iotlab_network_dict['login'] = ldap_username
52
53             iotlab_network_dict['ssh'] = \
54                 ['ssh ' + ldap_username + '@'+site+'.iotlab.info'
55                  for site in sites_set]
56             network_elem.set('ssh',
57                              unicode(iotlab_network_dict['ssh']))
58             network_elem.set('login', unicode(iotlab_network_dict['login']))
59
60     @staticmethod
61     def add_nodes(xml, nodes,rspec_content_type=None):
62         """Adds the nodes to the xml.
63
64         Adds the nodes as well as dedicated iotlab fields to the node xml
65         element.
66
67         :param xml: the xml being constructed.
68         :type xml: xml
69         :param nodes: list of node dict
70         :type nodes: list
71         :returns: a list of node elements.
72         :rtype: list
73
74         """
75         #Add network item in the xml
76         network_elems = xml.xpath('//network')
77         if len(network_elems) > 0:
78             network_elem = network_elems[0]
79         elif len(nodes) > 0 and nodes[0].get('component_manager_id'):
80             network_urn = nodes[0]['component_manager_id']
81             network_elem = xml.add_element('network',
82                                            name=Xrn(network_urn).get_hrn())
83         else:
84             network_elem = xml
85
86         node_elems = []
87         #Then add nodes items to the network item in the xml
88         for node in nodes:
89             #Attach this node to the network element
90             node_fields = ['component_manager_id', 'component_id', 'exclusive',
91                            'boot_state', 'mobile']
92             node_elem = network_elem.add_instance('node', node, node_fields)
93             node_elems.append(node_elem)
94
95             #Set the attibutes of this node element
96             for attribute in node:
97             # set component name
98                 if attribute is 'component_name':
99                     component_name = node['component_name']
100                     node_elem.set('component_name', component_name)
101
102             # set hardware types, extend fields to add Iotlab's architecture
103             #and radio type
104
105                 if attribute is 'hardware_types':
106                     for hardware_type in node.get('hardware_types', []):
107                         fields = HardwareType.fields
108                         fields.extend(['archi', 'radio'])
109                         node_elem.add_instance('hardware_types', node, fields)
110
111             # set mobility
112                 if attribute is 'mobility':
113                     node_elem.add_instance('mobility', node['mobility'],
114                                            IotlabMobility.fields)
115             # set location
116                 if attribute is 'location':
117                     node_elem.add_instance('location', node['location'],
118                                             IotlabLocation.fields)
119
120              # add granularity of the reservation system
121              #TODO put the granularity in network instead SA 18/07/12
122                 if attribute is 'granularity':
123                     granularity = node['granularity']
124                     if granularity:
125                         node_elem.add_instance('granularity',
126                                                granularity, granularity.fields)
127
128             # set available element
129                 if attribute is 'boot_state':
130                     if node.get('boot_state').lower() == 'alive':
131                         available_elem = node_elem.add_element('available',
132                                                                now='true')
133                     else:
134                         available_elem = node_elem.add_element('available',
135                                                                now='false')
136
137             #set position
138                 if attribute is 'position':
139                     node_elem.add_instance('position', node['position'],
140                                            IotlabPosition.fields)
141             ## add services
142             #PGv2Services.add_services(node_elem, node.get('services', []))
143             # add slivers
144                 if attribute is 'slivers':
145                     slivers = node.get('slivers', [])
146                     if not slivers:
147                     # we must still advertise the available sliver types
148                         slivers = Sliver({'type': 'iotlab-node'})
149                     # we must also advertise the available initscripts
150                     #slivers['tags'] = []
151                     #if node.get('pl_initscripts'):
152                         #for initscript in node.get('pl_initscripts', []):
153                             #slivers['tags'].append({'name': 'initscript', \
154                                                     #'value': initscript['name']})
155
156                     Iotlabv1Sliver.add_slivers(node_elem, slivers)
157                 # add sliver tag in Request Rspec
158             if rspec_content_type == "request":
159                 node_elem.add_instance('sliver', '', [])
160         return node_elems
161
162     @staticmethod
163     def get_nodes(xml, filter=None):
164         if filter is None: filter={}
165         xpath = '//node%s | //default:node%s' % (XpathFilter.xpath(filter), \
166                                                     XpathFilter.xpath(filter))
167         node_elems = xml.xpath(xpath)
168         return Iotlabv1Node.get_node_objs(node_elems)
169
170     @staticmethod
171     def get_nodes_with_slivers(xml, sliver_filter=None):
172         if sliver_filter is None: sliver_filter={}
173
174         xpath = '//node[count(sliver)>0] | \
175                                 //default:node[count(default:sliver) > 0]'
176         node_elems = xml.xpath(xpath)
177         logger.debug("SLABV1NODE \tget_nodes_with_slivers  \
178                                 node_elems %s"%(node_elems))
179         return Iotlabv1Node.get_node_objs(node_elems)
180
181     @staticmethod
182     def get_node_objs(node_elems):
183         nodes = []
184         for node_elem in node_elems:
185             node = NodeElement(node_elem.attrib, node_elem)
186             nodes.append(node)
187             if 'component_id' in node_elem.attrib:
188                 node['authority_id'] = \
189                     Xrn(node_elem.attrib['component_id']).get_authority_urn()
190
191             # get hardware types
192             hardware_type_elems = node_elem.xpath('./default:hardware_type | \
193                                                             ./hardware_type')
194             node['hardware_types'] = [hw_type.get_instance(HardwareType) \
195                                             for hw_type in hardware_type_elems]
196
197             # get location
198             location_elems = node_elem.xpath('./default:location | ./location')
199             locations = [location_elem.get_instance(Location) \
200                                             for location_elem in location_elems]
201             if len(locations) > 0:
202                 node['location'] = locations[0]
203
204
205             # get interfaces
206             iface_elems = node_elem.xpath('./default:interface | ./interface')
207             node['interfaces'] = [iface_elem.get_instance(Interface) \
208                                             for iface_elem in iface_elems]
209
210             # get position
211             position_elems = node_elem.xpath('./default:position | ./position')
212             if position_elems:
213                 position_elem = position_elems[0]
214                 node['position'] = position_elem.get_instance(IotlabPosition)
215
216             # get services
217             #node['services'] = PGv2Services.get_services(node_elem)
218
219             # get slivers
220             node['slivers'] = Iotlabv1Sliver.get_slivers(node_elem)
221             available_elems = node_elem.xpath('./default:available | \
222                                                                 ./available')
223             if len(available_elems) > 0 and 'name' in available_elems[0].attrib:
224                 if available_elems[0].attrib.get('now', '').lower() == 'true':
225                     node['boot_state'] = 'boot'
226                 else:
227                     node['boot_state'] = 'disabled'
228
229         logger.debug("SLABV1NODE \tget_nodes_objs  \
230                                 #nodes %s"%(nodes))
231         return nodes
232
233
234     @staticmethod
235     def add_slivers(xml, slivers):
236         logger.debug("Iotlabv1NODE \tadd_slivers ")
237         component_ids = []
238         for sliver in slivers:
239             filter_sliver = {}
240             if isinstance(sliver, str):
241                 filter_sliver['component_id'] = '*%s*' % sliver
242                 sliver = {}
243             elif 'component_id' in sliver and sliver['component_id']:
244                 filter_sliver['component_id'] = '*%s*' % sliver['component_id']
245             if not filter_sliver:
246                 continue
247             nodes = Iotlabv1Node.get_nodes(xml, filter_sliver)
248             if not nodes:
249                 continue
250             node = nodes[0]
251             Iotlabv1Sliver.add_slivers(node, sliver)
252
253     @staticmethod
254     def remove_slivers(xml, hostnames):
255         for hostname in hostnames:
256             nodes = Iotlabv1Node.get_nodes(xml, \
257                                     {'component_id': '*%s*' % hostname})
258             for node in nodes:
259                 slivers = Iotlabv1Sliver.get_slivers(node.element)
260                 for sliver in slivers:
261                     node.element.remove(sliver.element)
262
263
264