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