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