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