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