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