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