3a261ae3c0afbf7c639f844f3099eb2b5621e57f
[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             node['pl_initscripts'] = []
139             initscript_elems = node_elem.xpath('./default:sliver_type/planetlab:initscript | ./sliver_type/initscript')
140             if len(initscript_elems) > 0:
141                 for initscript_elem in initscript_elems:
142                     if 'name' in initscript_elem.attrib:
143                         node['pl_initscripts'].append(dict(initscript_elem.attrib))
144
145             # get node tags
146             tag_elems = node_elem.xpath('./planetlab:attribute | ./attribute')
147             node['tags'] = []
148             if len(tag_elems) > 0:
149                 for tag_elem in tag_elems:
150                     tag = dict(tag_elem.get_instance(Attribute))
151                     tag['tagname'] = tag.pop('name')
152                     node['tags'].append(tag)
153         return nodes
154
155
156     @staticmethod
157     def add_slivers(xml, slivers):
158         component_ids = []
159         for sliver in slivers:
160             filter = {}
161             if isinstance(sliver, str):
162                 filter['component_id'] = '*%s*' % sliver
163                 sliver = {}
164             elif 'component_id' in sliver and sliver['component_id']:
165                 filter['component_id'] = '*%s*' % sliver['component_id']
166             if not filter: 
167                 continue
168             nodes = PGv2Node.get_nodes(xml, filter)
169             if not nodes:
170                 continue
171             node = nodes[0]
172             PGv2SliverType.add_slivers(node, sliver)
173
174     @staticmethod
175     def remove_slivers(xml, hostnames):
176         for hostname in hostnames:
177             nodes = PGv2Node.get_nodes(xml, {'component_id': '*%s*' % hostname})
178             for node in nodes:
179                 slivers = PGv2SliverType.get_slivers(node.element)
180                 for sliver in slivers:
181                     node.element.remove(sliver.element) 
182 if __name__ == '__main__':
183     from sfa.rspecs.rspec import RSpec
184     import pdb
185     r = RSpec('/tmp/emulab.rspec')
186     r2 = RSpec(version = 'ProtoGENI')
187     nodes = PGv2Node.get_nodes(r.xml)
188     PGv2Node.add_nodes(r2.xml.root, nodes)
189     #pdb.set_trace()
190         
191