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