Merge branch 'master' of ssh://git.onelab.eu/git/sfa
[sfa.git] / sfa / rspecs / elements / versions / pgv2Node.py
1 from sfa.util.xrn import Xrn
2 from sfa.util.xml import XpathFilter
3
4 from sfa.rspecs.elements.node import Node
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.disk_image import DiskImage
9 from sfa.rspecs.elements.interface import Interface
10 from sfa.rspecs.elements.bwlimit import BWlimit
11 from sfa.rspecs.elements.pltag import PLTag
12 from sfa.rspecs.elements.versions.pgv2Services import PGv2Services     
13 from sfa.rspecs.elements.versions.pgv2SliverType import PGv2SliverType     
14 from sfa.rspecs.elements.versions.pgv2Interface import PGv2Interface     
15 from sfa.rspecs.elements.granularity import Granularity
16
17 from sfa.planetlab.plxrn import xrn_to_hostname
18
19 class PGv2Node:
20     @staticmethod
21     def add_nodes(xml, nodes):
22         node_elems = []
23         for node in nodes:
24             node_fields = ['component_manager_id', 'component_id', 'client_id', 'sliver_id', 'exclusive']
25             node_elem = xml.add_instance('node', node, node_fields)
26             node_elems.append(node_elem)
27             # set component name
28             if node.get('component_id'):
29                 component_name = xrn_to_hostname(node['component_id'])
30                 node_elem.set('component_name', component_name)
31             # set hardware types
32             if node.get('hardware_types'):
33                 for hardware_type in node.get('hardware_types', []): 
34                     node_elem.add_instance('hardware_type', hardware_type, HardwareType.fields)
35             # set location
36             if node.get('location'):
37                 node_elem.add_instance('location', node['location'], Location.fields)       
38
39             # set granularity
40             if node['exclusive'] == "true":
41                 granularity = node.get('granularity')
42                 node_elem.add_instance('granularity', granularity, granularity.fields)
43             # set interfaces
44             PGv2Interface.add_interfaces(node_elem, node.get('interfaces'))
45             #if node.get('interfaces'):
46             #    for interface in  node.get('interfaces', []):
47             #        node_elem.add_instance('interface', interface, ['component_id', 'client_id'])
48             # set available element
49             if node.get('boot_state'):
50                 if node.get('boot_state').lower() == 'boot':
51                     available_elem = node_elem.add_element('available', now='true')
52                 else:
53                     available_elem = node_elem.add_element('available', now='false')
54             # add services
55             PGv2Services.add_services(node_elem, node.get('services', [])) 
56             # add slivers
57             slivers = node.get('slivers', [])
58             if not slivers:
59                 # we must still advertise the available sliver types
60                 slivers = Sliver({'type': 'plab-vserver'})
61                 # we must also advertise the available initscripts
62                 slivers['tags'] = []
63                 if node.get('pl_initscripts'): 
64                     for initscript in node.get('pl_initscripts', []):
65                         slivers['tags'].append({'name': 'initscript', 'value': initscript['name']})
66             PGv2SliverType.add_slivers(node_elem, slivers)
67         return node_elems
68
69     @staticmethod
70     def get_nodes(xml, filter={}):
71         xpath = '//node%s | //default:node%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
72         node_elems = xml.xpath(xpath)
73         return PGv2Node.get_node_objs(node_elems)
74
75     @staticmethod
76     def get_nodes_with_slivers(xml, filter={}):
77         xpath = '//node[count(sliver_type)>0] | //default:node[count(default:sliver_type) > 0]' 
78         node_elems = xml.xpath(xpath)        
79         return PGv2Node.get_node_objs(node_elems)
80
81     @staticmethod
82     def get_node_objs(node_elems):
83         nodes = []
84         for node_elem in node_elems:
85             node = Node(node_elem.attrib, node_elem)
86             nodes.append(node) 
87             if 'component_id' in node_elem.attrib:
88                 node['authority_id'] = Xrn(node_elem.attrib['component_id']).get_authority_urn()
89             
90             # get hardware types
91             hardware_type_elems = node_elem.xpath('./default:hardware_type | ./hardware_type')
92             node['hardware_types'] = [hw_type.get_instance(HardwareType) for hw_type in hardware_type_elems]
93             
94             # get location
95             location_elems = node_elem.xpath('./default:location | ./location')
96             locations = [location_elem.get_instance(Location) for location_elem in location_elems]
97             if len(locations) > 0:
98                 node['location'] = locations[0]
99
100             # get granularity
101             granularity_elems = node_elem.xpath('./default:granularity | ./granularity')
102             if len(granularity_elems) > 0:
103                 node['granularity'] = granularity_elems[0].get_instance(Granularity)
104
105             # get interfaces
106             iface_elems = node_elem.xpath('./default:interface | ./interface')
107             node['interfaces'] = [iface_elem.get_instance(Interface) for iface_elem in iface_elems]
108
109             # get services
110             node['services'] = PGv2Services.get_services(node_elem)
111             
112             # get slivers
113             node['slivers'] = PGv2SliverType.get_slivers(node_elem)    
114             available_elems = node_elem.xpath('./default:available | ./available')
115             if len(available_elems) > 0 and 'name' in available_elems[0].attrib:
116                 if available_elems[0].attrib.get('now', '').lower() == 'true': 
117                     node['boot_state'] = 'boot'
118                 else: 
119                     node['boot_state'] = 'disabled' 
120         return nodes
121
122
123     @staticmethod
124     def add_slivers(xml, slivers):
125         component_ids = []
126         for sliver in slivers:
127             filter = {}
128             if isinstance(sliver, str):
129                 filter['component_id'] = '*%s*' % sliver
130                 sliver = {}
131             elif 'component_id' in sliver and sliver['component_id']:
132                 filter['component_id'] = '*%s*' % sliver['component_id']
133             if not filter: 
134                 continue
135             nodes = PGv2Node.get_nodes(xml, filter)
136             if not nodes:
137                 continue
138             node = nodes[0]
139             PGv2SliverType.add_slivers(node, sliver)
140
141     @staticmethod
142     def remove_slivers(xml, hostnames):
143         for hostname in hostnames:
144             nodes = PGv2Node.get_nodes(xml, {'component_id': '*%s*' % hostname})
145             for node in nodes:
146                 slivers = PGv2SliverType.get_slivers(node.element)
147                 for sliver in slivers:
148                     node.element.remove(sliver.element) 
149 if __name__ == '__main__':
150     from sfa.rspecs.rspec import RSpec
151     import pdb
152     r = RSpec('/tmp/emulab.rspec')
153     r2 = RSpec(version = 'ProtoGENI')
154     nodes = PGv2Node.get_nodes(r.xml)
155     PGv2Node.add_nodes(r2.xml.root, nodes)
156     #pdb.set_trace()
157         
158