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