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