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