put attribute tag (that carries PL node tag) into planetlab namespace
[sfa.git] / sfa / rspecs / elements / versions / pgv2Node.py
1 from sfa.util.xrn import Xrn
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 from sfa.planetlab.plxrn import xrn_to_hostname
20
21 class PGv2Node:
22     @staticmethod
23     def add_nodes(xml, nodes):
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_to_hostname(node['component_id'])
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['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('boot_state'):
52                 if node.get('boot_state').lower() == 'boot':
53                     available_elem = node_elem.add_element('available', now='true')
54                 else:
55                     available_elem = node_elem.add_element('available', now='false')
56             # add services
57             PGv2Services.add_services(node_elem, node.get('services', [])) 
58             # add slivers
59             slivers = node.get('slivers', [])
60             if not slivers:
61                 # we must still advertise the available sliver types
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         return node_elems
78
79
80     @staticmethod
81     def get_nodes(xml, filter={}):
82         xpath = '//node%s | //default:node%s' % (XpathFilter.xpath(filter), XpathFilter.xpath(filter))
83         node_elems = xml.xpath(xpath)
84         return PGv2Node.get_node_objs(node_elems)
85
86     @staticmethod
87     def get_nodes_with_slivers(xml, filter={}):
88         xpath = '//node[count(sliver_type)>0] | //default:node[count(default:sliver_type) > 0]' 
89         node_elems = xml.xpath(xpath)        
90         return PGv2Node.get_node_objs(node_elems)
91
92     @staticmethod
93     def get_node_objs(node_elems):
94         nodes = []
95         for node_elem in node_elems:
96             node = Node(node_elem.attrib, node_elem)
97             nodes.append(node) 
98             if 'component_id' in node_elem.attrib:
99                 node['authority_id'] = Xrn(node_elem.attrib['component_id']).get_authority_urn()
100             
101             # get hardware types
102             hardware_type_elems = node_elem.xpath('./default:hardware_type | ./hardware_type')
103             node['hardware_types'] = [hw_type.get_instance(HardwareType) for hw_type in hardware_type_elems]
104             
105             # get location
106             location_elems = node_elem.xpath('./default:location | ./location')
107             locations = [location_elem.get_instance(Location) for location_elem in location_elems]
108             if len(locations) > 0:
109                 node['location'] = locations[0]
110
111             # get granularity
112             granularity_elems = node_elem.xpath('./default:granularity | ./granularity')
113             if len(granularity_elems) > 0:
114                 node['granularity'] = granularity_elems[0].get_instance(Granularity)
115
116             # get interfaces
117             iface_elems = node_elem.xpath('./default:interface | ./interface')
118             node['interfaces'] = [iface_elem.get_instance(Interface) for iface_elem in iface_elems]
119
120             # get services
121             node['services'] = PGv2Services.get_services(node_elem)
122             
123             # get slivers
124             node['slivers'] = PGv2SliverType.get_slivers(node_elem)    
125             available_elems = node_elem.xpath('./default:available | ./available')
126             if len(available_elems) > 0 and 'name' in available_elems[0].attrib:
127                 if available_elems[0].attrib.get('now', '').lower() == 'true': 
128                     node['boot_state'] = 'boot'
129                 else: 
130                     node['boot_state'] = 'disabled' 
131
132             # get node tags
133             tag_elems = node_elem.xpath('./planetlab:attribute | ./attribute')
134             node['tags'] = []
135             if len(tag_elems) > 0:
136                 for tag_elem in tag_elems:
137                     tag = tag_elem.get_instance(Attribute)
138                     tag['tagname'] = tag.pop('name')
139                     node['tags'].append(tag)
140         return nodes
141
142
143     @staticmethod
144     def add_slivers(xml, slivers):
145         component_ids = []
146         for sliver in slivers:
147             filter = {}
148             if isinstance(sliver, str):
149                 filter['component_id'] = '*%s*' % sliver
150                 sliver = {}
151             elif 'component_id' in sliver and sliver['component_id']:
152                 filter['component_id'] = '*%s*' % sliver['component_id']
153             if not filter: 
154                 continue
155             nodes = PGv2Node.get_nodes(xml, filter)
156             if not nodes:
157                 continue
158             node = nodes[0]
159             PGv2SliverType.add_slivers(node, sliver)
160
161     @staticmethod
162     def remove_slivers(xml, hostnames):
163         for hostname in hostnames:
164             nodes = PGv2Node.get_nodes(xml, {'component_id': '*%s*' % hostname})
165             for node in nodes:
166                 slivers = PGv2SliverType.get_slivers(node.element)
167                 for sliver in slivers:
168                     node.element.remove(sliver.element) 
169 if __name__ == '__main__':
170     from sfa.rspecs.rspec import RSpec
171     import pdb
172     r = RSpec('/tmp/emulab.rspec')
173     r2 = RSpec(version = 'ProtoGENI')
174     nodes = PGv2Node.get_nodes(r.xml)
175     PGv2Node.add_nodes(r2.xml.root, nodes)
176     #pdb.set_trace()
177         
178