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 NodeElement
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.pltag import PLTag
16 from sfa.rspecs.elements.lease import Lease
17 from sfa.rspecs.elements.granularity import Granularity
18 from sfa.rspecs.elements.channel import Channel
19 from sfa.rspecs.version_manager import VersionManager
21 from sfa.nitos.nitosxrn import NitosXrn, hostname_to_urn, hrn_to_nitos_slicename, slicename_to_hrn
22 from sfa.planetlab.vlink import get_tc_rate
23 from sfa.planetlab.topology import Topology
29 def __init__(self, driver):
33 def get_slice_and_slivers(self, slice_xrn):
35 Returns a dict of slivers keyed on the sliver's node_id
40 return (slice, slivers)
41 slice_urn = hrn_to_urn(slice_xrn, 'slice')
42 slice_hrn, _ = urn_to_hrn(slice_xrn)
43 slice_name = hrn_to_nitos_slicename(slice_hrn)
44 slices = self.driver.shell.getSlices({'slice_name': slice_name}, [])
47 if slc['slice_name'] == slice_name:
52 return (slice, slivers)
54 reserved_nodes = self.driver.shell.getReservedNodes({'slice_id': slice['slice_id']}, [])
55 reserved_node_ids = []
57 for node in reserved_nodes:
58 if node['slice_id'] == slice['slice_id']:
59 reserved_node_ids.append(node['node_id'])
61 all_nodes = self.driver.shell.getNodes({}, [])
63 for node in all_nodes:
64 if node['node_id'] in reserved_node_ids:
65 slivers[node['node_id']] = node
67 return (slice, slivers)
71 def get_nodes(self, slice_xrn, slice=None,slivers={}, options={}):
72 # if we are dealing with a slice that has no node just return
75 if not slice or not slivers:
78 nodes = [slivers[sliver] for sliver in slivers]
80 nodes = self.driver.shell.getNodes({}, [])
82 # get the granularity in second for the reservation system
83 grain = self.driver.testbedInfo['grain']
90 site_name = self.driver.testbedInfo['name']
91 rspec_node['component_id'] = hostname_to_urn(self.driver.hrn, site_name, node['hostname'])
92 rspec_node['component_name'] = node['hostname']
93 rspec_node['component_manager_id'] = Xrn(self.driver.hrn, 'authority+cm').get_urn()
94 rspec_node['authority_id'] = hrn_to_urn(NitosXrn.site_hrn(self.driver.hrn, site_name), 'authority+sa')
95 # do not include boot state (<available> element) in the manifest rspec
97 # rspec_node['boot_state'] = node['boot_state']
98 rspec_node['exclusive'] = 'true'
100 longitude = self.driver.testbedInfo['longitude']
101 latitude = self.driver.testbedInfo['latitude']
102 if longitude and latitude:
103 location = Location({'longitude': longitude, 'latitude': latitude, 'country': 'unknown'})
104 rspec_node['location'] = location
106 position_3d = Position3D({'x': node['position']['X'], 'y': node['position']['Y'], 'z': node['position']['Z']})
107 #position_3d = Position3D({'x': 1, 'y': 2, 'z': 3})
108 rspec_node['position_3d'] = position_3d
110 granularity = Granularity({'grain': grain})
111 rspec_node['granularity'] = granularity
114 rspec_node['hardware_type'] = node['node_type']
115 #rspec_node['hardware_type'] = "orbit"
118 if node['node_id'] in slivers:
120 sliver = slivers[node['node_id']]
121 rspec_node['sliver_id'] = sliver['node_id']
122 rspec_node['client_id'] = node['hostname']
123 rspec_node['slivers'] = [sliver]
126 rspec_nodes.append(rspec_node)
129 def get_leases_and_channels(self, slice=None, slice_xrn=None, options={}):
131 slices = self.driver.shell.getSlices({}, [])
132 nodes = self.driver.shell.getNodes({}, [])
133 leases = self.driver.shell.getReservedNodes({}, [])
134 channels = self.driver.shell.getChannels({}, [])
135 reserved_channels = self.driver.shell.getReservedChannels()
136 grain = self.driver.testbedInfo['grain']
138 if slice_xrn and not slice:
143 all_leases.extend(leases)
144 all_reserved_channels = []
145 all_reserved_channels.extend(reserved_channels)
146 for lease in all_leases:
147 if lease['slice_id'] != slice['slice_id']:
149 for channel in all_reserved_channels:
150 if channel['slice_id'] != slice['slice_id']:
151 reserved_channels.remove(channel)
154 for channel in reserved_channels:
157 #retrieve channel number
159 if chl['channel_id'] == channel['channel_id']:
160 channel_number = chl['channel']
163 rspec_channel['channel_num'] = channel_number
164 rspec_channel['start_time'] = channel['start_time']
165 rspec_channel['duration'] = (int(channel['end_time']) - int(channel['start_time'])) / int(grain)
169 if slc['slice_id'] == channel['slice_id']:
170 slicename = slc['slice_name']
174 slice_urn = slice_xrn
175 slice_hrn = urn_to_hrn(slice_urn)
177 slice_hrn = slicename_to_hrn(self.driver.hrn, self.driver.testbedInfo['name'], slicename)
178 slice_urn = hrn_to_urn(slice_hrn, 'slice')
180 rspec_channel['slice_id'] = slice_urn
181 rspec_channels.append(rspec_channel)
187 rspec_lease = Lease()
189 rspec_lease['lease_id'] = lease['reservation_id']
192 if node['node_id'] == lease['node_id']:
193 nodename = node['hostname']
196 rspec_lease['component_id'] = hostname_to_urn(self.driver.hrn, self.driver.testbedInfo['name'], nodename)
199 if slc['slice_id'] == lease['slice_id']:
200 slicename = slc['slice_name']
204 slice_urn = slice_xrn
205 slice_hrn = urn_to_hrn(slice_urn)
207 slice_hrn = slicename_to_hrn(self.driver.hrn, self.driver.testbedInfo['name'], slicename)
208 slice_urn = hrn_to_urn(slice_hrn, 'slice')
210 rspec_lease['slice_id'] = slice_urn
211 rspec_lease['start_time'] = lease['start_time']
212 rspec_lease['duration'] = (int(lease['end_time']) - int(lease['start_time'])) / int(grain)
213 rspec_leases.append(rspec_lease)
215 return (rspec_leases, rspec_channels)
218 def get_channels(self, slice=None, options={}):
220 all_channels = self.driver.shell.getChannels({}, [])
223 reserved_channels = self.driver.shell.getReservedChannels()
224 reserved_channel_ids = []
225 for channel in reserved_channels:
226 if channel['slice_id'] == slice['slice_id']:
227 reserved_channel_ids.append(channel['channel_id'])
229 for channel in all_channels:
230 if channel['channel_id'] in reserved_channel_ids:
231 channels.append(channel)
233 channels = all_channels
236 for channel in channels:
237 rspec_channel = Channel()
238 rspec_channel['channel_num'] = channel['channel']
239 rspec_channel['frequency'] = channel['frequency']
240 rspec_channel['standard'] = channel['modulation']
241 rspec_channels.append(rspec_channel)
242 return rspec_channels
246 def get_rspec(self, slice_xrn=None, version = None, options={}):
248 version_manager = VersionManager()
249 version = version_manager.get_version(version)
252 rspec_version = version_manager._get_version(version.type, version.version, 'ad')
254 rspec_version = version_manager._get_version(version.type, version.version, 'manifest')
256 slice, slivers = self.get_slice_and_slivers(slice_xrn)
258 rspec = RSpec(version=rspec_version, user_options=options)
260 if slice and 'expires' in slice:
261 rspec.xml.set('expires', datetime_to_string(utcparse(slice['expires'])))
263 if not options.get('list_leases') or options.get('list_leases') and options['list_leases'] != 'leases':
264 nodes = self.get_nodes(slice_xrn, slice, slivers, options)
265 rspec.version.add_nodes(nodes)
266 # add sliver defaults
267 default_sliver = slivers.get(None, [])
269 default_sliver_attribs = default_sliver.get('tags', [])
270 for attrib in default_sliver_attribs:
272 rspec.version.add_default_sliver_attribute(attrib['tagname'], attrib['value'])
274 channels = self.get_channels(slice, options)
275 rspec.version.add_channels(channels)
277 if not options.get('list_leases') or options.get('list_leases') and options['list_leases'] != 'resources':
278 leases, channels = self.get_leases_and_channels(slice, slice_xrn)
279 rspec.version.add_leases(leases, channels)