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, channel_to_urn
23 from sfa.planetlab.vlink import get_tc_rate
24 from sfa.planetlab.topology import Topology
30 def __init__(self, driver):
34 def get_slice_and_slivers(self, slice_xrn):
36 Returns a dict of slivers keyed on the sliver's node_id
41 return (slice, slivers)
42 slice_urn = hrn_to_urn(slice_xrn, 'slice')
43 slice_hrn, _ = urn_to_hrn(slice_xrn)
44 slice_name = hrn_to_nitos_slicename(slice_hrn)
45 slices = self.driver.shell.getSlices({'slice_name': slice_name}, [])
48 if slc['slice_name'] == slice_name:
53 return (slice, slivers)
55 reserved_nodes = self.driver.shell.getReservedNodes({'slice_id': slice['slice_id']}, [])
56 reserved_node_ids = []
58 for node in reserved_nodes:
59 if node['slice_id'] == slice['slice_id']:
60 reserved_node_ids.append(node['node_id'])
62 all_nodes = self.driver.shell.getNodes({}, [])
64 for node in all_nodes:
65 if node['node_id'] in reserved_node_ids:
66 slivers[node['node_id']] = node
68 return (slice, slivers)
72 def get_nodes(self, slice_xrn, slice=None,slivers={}, options={}):
73 # if we are dealing with a slice that has no node just return
76 if not slice or not slivers:
79 nodes = [slivers[sliver] for sliver in slivers]
81 nodes = self.driver.shell.getNodes({}, [])
83 # get the granularity in second for the reservation system
84 grain = self.driver.testbedInfo['grain']
91 site_name = self.driver.testbedInfo['name']
92 rspec_node['component_id'] = hostname_to_urn(self.driver.hrn, site_name, node['hostname'])
93 rspec_node['component_name'] = node['hostname']
94 rspec_node['component_manager_id'] = Xrn(self.driver.hrn, 'authority+cm').get_urn()
95 rspec_node['authority_id'] = hrn_to_urn(NitosXrn.site_hrn(self.driver.hrn, site_name), 'authority+sa')
96 # do not include boot state (<available> element) in the manifest rspec
98 # rspec_node['boot_state'] = node['boot_state']
99 rspec_node['exclusive'] = 'true'
101 longitude = self.driver.testbedInfo['longitude']
102 latitude = self.driver.testbedInfo['latitude']
103 if longitude and latitude:
104 location = Location({'longitude': longitude, 'latitude': latitude, 'country': 'unknown'})
105 rspec_node['location'] = location
107 position_3d = Position3D({'x': node['position']['X'], 'y': node['position']['Y'], 'z': node['position']['Z']})
108 #position_3d = Position3D({'x': 1, 'y': 2, 'z': 3})
109 rspec_node['position_3d'] = position_3d
111 granularity = Granularity({'grain': grain})
112 rspec_node['granularity'] = granularity
115 rspec_node['hardware_type'] = node['node_type']
116 #rspec_node['hardware_type'] = "orbit"
119 if node['node_id'] in slivers:
121 sliver = slivers[node['node_id']]
122 rspec_node['sliver_id'] = sliver['node_id']
123 rspec_node['client_id'] = node['hostname']
124 rspec_node['slivers'] = [sliver]
127 rspec_nodes.append(rspec_node)
130 def get_leases_and_channels(self, slice=None, slice_xrn=None, options={}):
132 slices = self.driver.shell.getSlices({}, [])
133 nodes = self.driver.shell.getNodes({}, [])
134 leases = self.driver.shell.getReservedNodes({}, [])
135 channels = self.driver.shell.getChannels({}, [])
136 reserved_channels = self.driver.shell.getReservedChannels()
137 grain = self.driver.testbedInfo['grain']
139 if slice_xrn and not slice:
144 all_leases.extend(leases)
145 all_reserved_channels = []
146 all_reserved_channels.extend(reserved_channels)
147 for lease in all_leases:
148 if lease['slice_id'] != slice['slice_id']:
150 for channel in all_reserved_channels:
151 if channel['slice_id'] != slice['slice_id']:
152 reserved_channels.remove(channel)
155 for channel in reserved_channels:
158 #retrieve channel number
160 if chl['channel_id'] == channel['channel_id']:
161 channel_number = chl['channel']
164 rspec_channel['channel_num'] = channel_number
165 rspec_channel['start_time'] = channel['start_time']
166 rspec_channel['duration'] = (int(channel['end_time']) - int(channel['start_time'])) / int(grain)
167 rspec_channel['component_id'] = channel_to_urn(self.driver.hrn, self.driver.testbedInfo['name'], channel_number)
171 if slc['slice_id'] == channel['slice_id']:
172 slicename = slc['slice_name']
176 slice_urn = slice_xrn
177 slice_hrn = urn_to_hrn(slice_urn)
179 slice_hrn = slicename_to_hrn(self.driver.hrn, self.driver.testbedInfo['name'], slicename)
180 slice_urn = hrn_to_urn(slice_hrn, 'slice')
182 rspec_channel['slice_id'] = slice_urn
183 rspec_channels.append(rspec_channel)
189 rspec_lease = Lease()
191 rspec_lease['lease_id'] = lease['reservation_id']
194 if node['node_id'] == lease['node_id']:
195 nodename = node['hostname']
198 rspec_lease['component_id'] = hostname_to_urn(self.driver.hrn, self.driver.testbedInfo['name'], nodename)
201 if slc['slice_id'] == lease['slice_id']:
202 slicename = slc['slice_name']
206 slice_urn = slice_xrn
207 slice_hrn = urn_to_hrn(slice_urn)
209 slice_hrn = slicename_to_hrn(self.driver.hrn, self.driver.testbedInfo['name'], slicename)
210 slice_urn = hrn_to_urn(slice_hrn, 'slice')
212 rspec_lease['slice_id'] = slice_urn
213 rspec_lease['start_time'] = lease['start_time']
214 rspec_lease['duration'] = (int(lease['end_time']) - int(lease['start_time'])) / int(grain)
215 rspec_leases.append(rspec_lease)
217 return (rspec_leases, rspec_channels)
220 def get_channels(self, slice=None, options={}):
222 all_channels = self.driver.shell.getChannels({}, [])
225 reserved_channels = self.driver.shell.getReservedChannels()
226 reserved_channel_ids = []
227 for channel in reserved_channels:
228 if channel['slice_id'] == slice['slice_id']:
229 reserved_channel_ids.append(channel['channel_id'])
231 for channel in all_channels:
232 if channel['channel_id'] in reserved_channel_ids:
233 channels.append(channel)
235 channels = all_channels
238 for channel in channels:
239 rspec_channel = Channel()
240 rspec_channel['channel_num'] = channel['channel']
241 rspec_channel['frequency'] = channel['frequency']
242 rspec_channel['standard'] = channel['modulation']
243 rspec_channel['component_id'] = channel_to_urn(self.driver.hrn, self.driver.testbedInfo['name'], channel['channel'])
244 rspec_channels.append(rspec_channel)
245 return rspec_channels
249 def get_rspec(self, slice_xrn=None, version = None, options={}):
251 version_manager = VersionManager()
252 version = version_manager.get_version(version)
255 rspec_version = version_manager._get_version(version.type, version.version, 'ad')
257 rspec_version = version_manager._get_version(version.type, version.version, 'manifest')
259 slice, slivers = self.get_slice_and_slivers(slice_xrn)
261 rspec = RSpec(version=rspec_version, user_options=options)
263 if slice and 'expires' in slice:
264 rspec.xml.set('expires', datetime_to_string(utcparse(slice['expires'])))
266 if not options.get('list_leases') or options.get('list_leases') and options['list_leases'] != 'leases':
267 nodes = self.get_nodes(slice_xrn, slice, slivers, options)
268 rspec.version.add_nodes(nodes)
269 # add sliver defaults
270 default_sliver = slivers.get(None, [])
272 default_sliver_attribs = default_sliver.get('tags', [])
273 for attrib in default_sliver_attribs:
275 rspec.version.add_default_sliver_attribute(attrib['tagname'], attrib['value'])
277 channels = self.get_channels(slice, options)
278 rspec.version.add_channels(channels)
280 if not options.get('list_leases') or options.get('list_leases') and options['list_leases'] != 'resources':
281 leases_channels = self.get_leases_and_channels(slice, slice_xrn)
282 rspec.version.add_leases(leases_channels)