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, channel_to_urn
22 from sfa.planetlab.vlink import get_tc_rate
23 from sfa.planetlab.topology import Topology
30 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(
55 {'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)
70 def get_nodes(self, slice_xrn, slice=None, slivers=None, options=None):
75 # if we are dealing with a slice that has no node just return
78 if not slice or not slivers:
81 nodes = [slivers[sliver] for sliver in slivers]
83 nodes = self.driver.shell.getNodes({}, [])
85 # get the granularity in second for the reservation system
86 grain = self.driver.testbedInfo['grain']
91 rspec_node = NodeElement()
92 site_name = self.driver.testbedInfo['name']
93 rspec_node['component_id'] = hostname_to_urn(
94 self.driver.hrn, site_name, node['hostname'])
95 rspec_node['component_name'] = node['hostname']
96 rspec_node['component_manager_id'] = Xrn(
97 self.driver.hrn, 'authority+cm').get_urn()
98 rspec_node['authority_id'] = hrn_to_urn(
99 NitosXrn.site_hrn(self.driver.hrn, site_name), 'authority+sa')
100 # do not include boot state (<available> element) in the manifest rspec
102 # rspec_node['boot_state'] = node['boot_state']
103 rspec_node['exclusive'] = 'true'
105 longitude = self.driver.testbedInfo['longitude']
106 latitude = self.driver.testbedInfo['latitude']
107 if longitude and latitude:
109 {'longitude': longitude, 'latitude': latitude, 'country': 'unknown'})
110 rspec_node['location'] = location
112 position_3d = Position3D({'x': node['position']['X'], 'y': node[
113 'position']['Y'], 'z': node['position']['Z']})
114 #position_3d = Position3D({'x': 1, 'y': 2, 'z': 3})
115 rspec_node['position_3d'] = position_3d
117 granularity = Granularity({'grain': grain})
118 rspec_node['granularity'] = granularity
121 rspec_node['hardware_type'] = node['node_type']
122 #rspec_node['hardware_type'] = "orbit"
125 if node['node_id'] in slivers:
127 sliver = slivers[node['node_id']]
128 rspec_node['sliver_id'] = sliver['node_id']
129 rspec_node['client_id'] = node['hostname']
130 rspec_node['slivers'] = [sliver]
132 rspec_nodes.append(rspec_node)
135 def get_leases_and_channels(self, slice=None, slice_xrn=None, options=None):
139 slices = self.driver.shell.getSlices({}, [])
140 nodes = self.driver.shell.getNodes({}, [])
141 leases = self.driver.shell.getReservedNodes({}, [])
142 channels = self.driver.shell.getChannels({}, [])
143 reserved_channels = self.driver.shell.getReservedChannels()
144 grain = self.driver.testbedInfo['grain']
146 if slice_xrn and not slice:
151 all_leases.extend(leases)
152 all_reserved_channels = []
153 all_reserved_channels.extend(reserved_channels)
154 for lease in all_leases:
155 if lease['slice_id'] != slice['slice_id']:
157 for channel in all_reserved_channels:
158 if channel['slice_id'] != slice['slice_id']:
159 reserved_channels.remove(channel)
162 for channel in reserved_channels:
165 # retrieve channel number
167 if chl['channel_id'] == channel['channel_id']:
168 channel_number = chl['channel']
171 rspec_channel['channel_num'] = channel_number
172 rspec_channel['start_time'] = channel['start_time']
173 rspec_channel['duration'] = (
174 int(channel['end_time']) - int(channel['start_time'])) / int(grain)
175 rspec_channel['component_id'] = channel_to_urn(
176 self.driver.hrn, self.driver.testbedInfo['name'], channel_number)
180 if slc['slice_id'] == channel['slice_id']:
181 slicename = slc['slice_name']
185 slice_urn = slice_xrn
186 slice_hrn = urn_to_hrn(slice_urn)
188 slice_hrn = slicename_to_hrn(
189 self.driver.hrn, self.driver.testbedInfo['name'], slicename)
190 slice_urn = hrn_to_urn(slice_hrn, 'slice')
192 rspec_channel['slice_id'] = slice_urn
193 rspec_channels.append(rspec_channel)
198 rspec_lease = Lease()
200 rspec_lease['lease_id'] = lease['reservation_id']
203 if node['node_id'] == lease['node_id']:
204 nodename = node['hostname']
207 rspec_lease['component_id'] = hostname_to_urn(
208 self.driver.hrn, self.driver.testbedInfo['name'], nodename)
211 if slc['slice_id'] == lease['slice_id']:
212 slicename = slc['slice_name']
216 slice_urn = slice_xrn
217 slice_hrn = urn_to_hrn(slice_urn)
219 slice_hrn = slicename_to_hrn(
220 self.driver.hrn, self.driver.testbedInfo['name'], slicename)
221 slice_urn = hrn_to_urn(slice_hrn, 'slice')
223 rspec_lease['slice_id'] = slice_urn
224 rspec_lease['start_time'] = lease['start_time']
225 rspec_lease['duration'] = (
226 int(lease['end_time']) - int(lease['start_time'])) / int(grain)
227 rspec_leases.append(rspec_lease)
229 return (rspec_leases, rspec_channels)
231 def get_channels(self, slice=None, options=None):
235 all_channels = self.driver.shell.getChannels({}, [])
238 reserved_channels = self.driver.shell.getReservedChannels()
239 reserved_channel_ids = []
240 for channel in reserved_channels:
241 if channel['slice_id'] == slice['slice_id']:
242 reserved_channel_ids.append(channel['channel_id'])
244 for channel in all_channels:
245 if channel['channel_id'] in reserved_channel_ids:
246 channels.append(channel)
248 channels = all_channels
251 for channel in channels:
252 rspec_channel = Channel()
253 rspec_channel['channel_num'] = channel['channel']
254 rspec_channel['frequency'] = channel['frequency']
255 rspec_channel['standard'] = channel['modulation']
256 rspec_channel['component_id'] = channel_to_urn(
257 self.driver.hrn, self.driver.testbedInfo['name'], channel['channel'])
258 rspec_channels.append(rspec_channel)
259 return rspec_channels
261 def get_rspec(self, slice_xrn=None, version=None, options=None):
265 version_manager = VersionManager()
266 version = version_manager.get_version(version)
269 rspec_version = version_manager._get_version(
270 version.type, version.version, 'ad')
272 rspec_version = version_manager._get_version(
273 version.type, version.version, 'manifest')
275 slice, slivers = self.get_slice_and_slivers(slice_xrn)
277 rspec = RSpec(version=rspec_version, user_options=options)
279 if slice and 'expires' in slice:
280 rspec.xml.set('expires', datetime_to_string(
281 utcparse(slice['expires'])))
283 if not options.get('list_leases') or options.get('list_leases') and options['list_leases'] != 'leases':
284 nodes = self.get_nodes(slice_xrn, slice, slivers, options)
285 rspec.version.add_nodes(nodes)
286 # add sliver defaults
287 default_sliver = slivers.get(None, [])
289 default_sliver_attribs = default_sliver.get('tags', [])
290 for attrib in default_sliver_attribs:
292 rspec.version.add_default_sliver_attribute(
293 attrib['tagname'], attrib['value'])
295 channels = self.get_channels(slice, options)
296 rspec.version.add_channels(channels)
298 if not options.get('list_leases') or options.get('list_leases') and options['list_leases'] != 'resources':
299 leases_channels = self.get_leases_and_channels(slice, slice_xrn)
300 rspec.version.add_leases(leases_channels)