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