2 from sfa.util.xrn import Xrn, hrn_to_urn, urn_to_hrn
3 from sfa.util.sfatime import utcparse, datetime_to_string
4 from sfa.util.sfalogging import logger
6 from sfa.rspecs.rspec import RSpec
7 from sfa.rspecs.elements.hardware_type import HardwareType
8 from sfa.rspecs.elements.node import Node
9 from sfa.rspecs.elements.link import Link
10 from sfa.rspecs.elements.sliver import Sliver
11 from sfa.rspecs.elements.login import Login
12 from sfa.rspecs.elements.location import Location
13 from sfa.rspecs.elements.position_3d import Position3D
14 from sfa.rspecs.elements.interface import Interface
15 from sfa.rspecs.elements.services import Services
16 from sfa.rspecs.elements.pltag import PLTag
17 from sfa.rspecs.elements.lease import Lease
18 from sfa.rspecs.elements.granularity import Granularity
19 from sfa.rspecs.elements.channel import Channel
20 from sfa.rspecs.version_manager import VersionManager
22 from sfa.nitos.nitosxrn import NitosXrn, hostname_to_urn, hrn_to_nitos_slicename, slicename_to_hrn
23 from sfa.planetlab.vlink import get_tc_rate
24 from sfa.planetlab.topology import Topology
30 def __init__(self, driver):
33 def get_sites(self, filter={}):
35 for site in self.driver.shell.GetSites(filter):
36 sites[site['site_id']] = site
39 def get_interfaces(self, filter={}):
41 for interface in self.driver.shell.GetInterfaces(filter):
43 if interface['bwlimit']:
44 interface['bwlimit'] = str(int(interface['bwlimit'])/1000)
45 interfaces[interface['interface_id']] = interface
48 def get_links(self, sites, nodes, interfaces):
52 for (site_id1, site_id2) in topology:
53 site_id1 = int(site_id1)
54 site_id2 = int(site_id2)
56 if not site_id1 in sites or site_id2 not in sites:
58 site1 = sites[site_id1]
59 site2 = sites[site_id2]
61 site1_hrn = self.driver.hrn + '.' + site1['login_base']
62 site2_hrn = self.driver.hrn + '.' + site2['login_base']
64 for s1_node_id in site1['node_ids']:
65 for s2_node_id in site2['node_ids']:
66 if s1_node_id not in nodes or s2_node_id not in nodes:
68 node1 = nodes[s1_node_id]
69 node2 = nodes[s2_node_id]
71 # just get first interface of the first node
72 if1_xrn = PlXrn(auth=self.driver.hrn, interface='node%s:eth0' % (node1['node_id']))
73 if1_ipv4 = interfaces[node1['interface_ids'][0]]['ip']
74 if2_xrn = PlXrn(auth=self.driver.hrn, interface='node%s:eth0' % (node2['node_id']))
75 if2_ipv4 = interfaces[node2['interface_ids'][0]]['ip']
77 if1 = Interface({'component_id': if1_xrn.urn, 'ipv4': if1_ipv4} )
78 if2 = Interface({'component_id': if2_xrn.urn, 'ipv4': if2_ipv4} )
81 link = Link({'capacity': '1000000', 'latency': '0', 'packet_loss': '0', 'type': 'ipv4'})
82 link['interface1'] = if1
83 link['interface2'] = if2
84 link['component_name'] = "%s:%s" % (site1['login_base'], site2['login_base'])
85 link['component_id'] = PlXrn(auth=self.driver.hrn, interface=link['component_name']).get_urn()
86 link['component_manager_id'] = hrn_to_urn(self.driver.hrn, 'authority+am')
91 def get_node_tags(self, filter={}):
93 for node_tag in self.driver.shell.GetNodeTags(filter):
94 node_tags[node_tag['node_tag_id']] = node_tag
97 def get_pl_initscripts(self, filter={}):
99 filter.update({'enabled': True})
100 for initscript in self.driver.shell.GetInitScripts(filter):
101 pl_initscripts[initscript['initscript_id']] = initscript
102 return pl_initscripts
105 def get_slice_and_slivers(self, slice_xrn):
107 Returns a dict of slivers keyed on the sliver's node_id
112 return (slice, slivers)
113 slice_urn = hrn_to_urn(slice_xrn, 'slice')
114 slice_hrn, _ = urn_to_hrn(slice_xrn)
115 slice_name = hrn_to_nitos_slicename(slice_hrn)
116 slices = self.driver.shell.getSlices({'slice_name': slice_name}, [])
119 # if slc['slice_name'] == slice_name:
124 return (slice, slivers)
126 reserved_nodes = self.driver.shell.getReservedNodes({'slice_id': slice['slice_id']}, [])
128 for node in reserved_nodes:
129 slivers[node['id']] = node
131 return (slice, slivers)
135 def get_nodes_and_links(self, slice_xrn, slice=None,slivers={}, options={}):
136 # if we are dealing with a slice that has no node just return
139 if not slice or not slivers:
142 nodes = [slivers[sliver] for sliver in slivers]
144 nodes = self.driver.shell.getNodes({}, [])
146 # get the granularity in second for the reservation system
147 grain = self.driver.testbedInfo['grain']
155 site_name = self.driver.testbedInfo['name']
156 rspec_node['component_id'] = hostname_to_urn(self.driver.hrn, site_name, node['name'])
157 rspec_node['component_name'] = node['name']
158 rspec_node['component_manager_id'] = Xrn(self.driver.hrn, 'authority+cm').get_urn()
159 rspec_node['authority_id'] = hrn_to_urn(NitosXrn.site_hrn(self.driver.hrn, site_name), 'authority+sa')
160 # do not include boot state (<available> element) in the manifest rspec
162 # rspec_node['boot_state'] = node['boot_state']
163 rspec_node['exclusive'] = 'true'
165 longitude = self.driver.testbedInfo['longitude']
166 latitude = self.driver.testbedInfo['latitude']
167 if longitude and latitude:
168 location = Location({'longitude': longitude, 'latitude': latitude, 'country': 'unknown'})
169 rspec_node['location'] = location
171 position_3d = Position3D({'x': node['X'], 'y': node['Y'], 'z': node['Z']})
172 #position_3d = Position3D({'x': 1, 'y': 2, 'z': 3})
173 rspec_node['position_3d'] = position_3d
175 granularity = Granularity({'grain': grain})
176 rspec_node['granularity'] = granularity
179 rspec_node['hardware_type'] = node['type']
180 #rspec_node['hardware_type'] = "orbit"
183 rspec_nodes.append(rspec_node)
184 return (rspec_nodes, [])
186 def get_leases_and_channels(self, slice=None, options={}):
188 slices = self.driver.shell.getSlices({}, [])
189 nodes = self.driver.shell.getNodes({}, [])
190 leases = self.driver.shell.getReservedNodes({}, [])
191 channels = self.driver.shell.getChannels({}, [])
192 reserved_channels = self.driver.shell.getReservedChannels()
193 grain = self.driver.testbedInfo['grain']
197 if lease['slice_id'] != slice['slice_id']:
199 for channel in reserved_channels:
200 if channel['slice_id'] != slice['slice_id']:
201 reserved_channels.remove(channel)
204 for channel in reserved_channels:
207 #retrieve channel number
209 if chl['channel_id'] == channel['channel_id']:
210 channel_number = chl['channel']
213 rspec_channel['channel_num'] = channel_number
214 rspec_channel['start_time'] = channel['start_time']
215 rspec_channel['duration'] = (int(channel['end_time']) - int(channel['start_time'])) / int(grain)
219 if slc['slice_id'] == channel['slice_id']:
220 slicename = slc['slice_name']
223 slice_hrn = slicename_to_hrn(self.driver.hrn, self.driver.testbedInfo['name'], slicename)
224 slice_urn = hrn_to_urn(slice_hrn, 'slice')
225 rspec_channel['slice_id'] = slice_urn
226 rspec_channels.append(rspec_channel)
232 rspec_lease = Lease()
234 rspec_lease['lease_id'] = lease['reservation_id']
237 if node['id'] == lease['node_id']:
238 nodename = node['name']
241 rspec_lease['component_id'] = hostname_to_urn(self.driver.hrn, self.driver.testbedInfo['name'], nodename)
244 if slc['slice_id'] == lease['slice_id']:
245 slicename = slc['slice_name']
248 slice_hrn = slicename_to_hrn(self.driver.hrn, self.driver.testbedInfo['name'], slicename)
249 slice_urn = hrn_to_urn(slice_hrn, 'slice')
250 rspec_lease['slice_id'] = slice_urn
251 rspec_lease['start_time'] = lease['start_time']
252 rspec_lease['duration'] = (int(lease['end_time']) - int(lease['start_time'])) / int(grain)
253 rspec_leases.append(rspec_lease)
255 return (rspec_leases, rspec_channels)
258 def get_channels(self, options={}):
261 channels = self.driver.shell.getChannels({}, [])
263 for channel in channels:
264 rspec_channel = Channel()
265 rspec_channel['channel_num'] = channel['channel']
266 rspec_channel['frequency'] = channel['frequency']
267 rspec_channel['standard'] = channel['modulation']
268 rspec_channels.append(rspec_channel)
269 return rspec_channels
273 def get_rspec(self, slice_xrn=None, version = None, options={}):
275 version_manager = VersionManager()
276 version = version_manager.get_version(version)
279 rspec_version = version_manager._get_version(version.type, version.version, 'ad')
281 rspec_version = version_manager._get_version(version.type, version.version, 'manifest')
283 slice, slivers = self.get_slice_and_slivers(slice_xrn)
285 rspec = RSpec(version=rspec_version, user_options=options)
287 if slice and 'expires' in slice:
288 rspec.xml.set('expires', datetime_to_string(utcparse(slice['expires'])))
290 if not options.get('list_leases') or options.get('list_leases') and options['list_leases'] != 'leases':
291 nodes, links = self.get_nodes_and_links(slice_xrn, slice, slivers, options)
292 rspec.version.add_nodes(nodes)
293 rspec.version.add_links(links)
294 # add sliver defaults
295 default_sliver = slivers.get(None, [])
297 default_sliver_attribs = default_sliver.get('tags', [])
298 for attrib in default_sliver_attribs:
300 rspec.version.add_default_sliver_attribute(attrib['tagname'], attrib['value'])
302 channels = self.get_channels()
303 rspec.version.add_channels(channels)
305 if not options.get('list_leases') or options.get('list_leases') and options['list_leases'] != 'resources':
306 leases, channels = self.get_leases_and_channels(slice)
307 rspec.version.add_leases(leases, channels)