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
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=None, options=None):
72 if slivers is None: slivers={}
73 if options is None: options={}
74 # if we are dealing with a slice that has no node just return
77 if not slice or not slivers:
80 nodes = [slivers[sliver] for sliver in slivers]
82 nodes = self.driver.shell.getNodes({}, [])
84 # get the granularity in second for the reservation system
85 grain = self.driver.testbedInfo['grain']
91 rspec_node = NodeElement()
92 site_name = self.driver.testbedInfo['name']
93 rspec_node['component_id'] = hostname_to_urn(self.driver.hrn, site_name, node['hostname'])
94 rspec_node['component_name'] = node['hostname']
95 rspec_node['component_manager_id'] = Xrn(self.driver.hrn, 'authority+cm').get_urn()
96 rspec_node['authority_id'] = hrn_to_urn(NitosXrn.site_hrn(self.driver.hrn, site_name), 'authority+sa')
97 # do not include boot state (<available> element) in the manifest rspec
99 # rspec_node['boot_state'] = node['boot_state']
100 rspec_node['exclusive'] = 'true'
102 longitude = self.driver.testbedInfo['longitude']
103 latitude = self.driver.testbedInfo['latitude']
104 if longitude and latitude:
105 location = Location({'longitude': longitude, 'latitude': latitude, 'country': 'unknown'})
106 rspec_node['location'] = location
108 position_3d = Position3D({'x': node['position']['X'], 'y': node['position']['Y'], 'z': node['position']['Z']})
109 #position_3d = Position3D({'x': 1, 'y': 2, 'z': 3})
110 rspec_node['position_3d'] = position_3d
112 granularity = Granularity({'grain': grain})
113 rspec_node['granularity'] = granularity
116 rspec_node['hardware_type'] = node['node_type']
117 #rspec_node['hardware_type'] = "orbit"
120 if node['node_id'] in slivers:
122 sliver = slivers[node['node_id']]
123 rspec_node['sliver_id'] = sliver['node_id']
124 rspec_node['client_id'] = node['hostname']
125 rspec_node['slivers'] = [sliver]
128 rspec_nodes.append(rspec_node)
131 def get_leases_and_channels(self, slice=None, slice_xrn=None, options=None):
133 if options is None: options={}
134 slices = self.driver.shell.getSlices({}, [])
135 nodes = self.driver.shell.getNodes({}, [])
136 leases = self.driver.shell.getReservedNodes({}, [])
137 channels = self.driver.shell.getChannels({}, [])
138 reserved_channels = self.driver.shell.getReservedChannels()
139 grain = self.driver.testbedInfo['grain']
141 if slice_xrn and not slice:
146 all_leases.extend(leases)
147 all_reserved_channels = []
148 all_reserved_channels.extend(reserved_channels)
149 for lease in all_leases:
150 if lease['slice_id'] != slice['slice_id']:
152 for channel in all_reserved_channels:
153 if channel['slice_id'] != slice['slice_id']:
154 reserved_channels.remove(channel)
157 for channel in reserved_channels:
160 #retrieve channel number
162 if chl['channel_id'] == channel['channel_id']:
163 channel_number = chl['channel']
166 rspec_channel['channel_num'] = channel_number
167 rspec_channel['start_time'] = channel['start_time']
168 rspec_channel['duration'] = (int(channel['end_time']) - int(channel['start_time'])) / int(grain)
169 rspec_channel['component_id'] = channel_to_urn(self.driver.hrn, self.driver.testbedInfo['name'], channel_number)
173 if slc['slice_id'] == channel['slice_id']:
174 slicename = slc['slice_name']
178 slice_urn = slice_xrn
179 slice_hrn = urn_to_hrn(slice_urn)
181 slice_hrn = slicename_to_hrn(self.driver.hrn, self.driver.testbedInfo['name'], slicename)
182 slice_urn = hrn_to_urn(slice_hrn, 'slice')
184 rspec_channel['slice_id'] = slice_urn
185 rspec_channels.append(rspec_channel)
191 rspec_lease = Lease()
193 rspec_lease['lease_id'] = lease['reservation_id']
196 if node['node_id'] == lease['node_id']:
197 nodename = node['hostname']
200 rspec_lease['component_id'] = hostname_to_urn(self.driver.hrn, self.driver.testbedInfo['name'], nodename)
203 if slc['slice_id'] == lease['slice_id']:
204 slicename = slc['slice_name']
208 slice_urn = slice_xrn
209 slice_hrn = urn_to_hrn(slice_urn)
211 slice_hrn = slicename_to_hrn(self.driver.hrn, self.driver.testbedInfo['name'], slicename)
212 slice_urn = hrn_to_urn(slice_hrn, 'slice')
214 rspec_lease['slice_id'] = slice_urn
215 rspec_lease['start_time'] = lease['start_time']
216 rspec_lease['duration'] = (int(lease['end_time']) - int(lease['start_time'])) / int(grain)
217 rspec_leases.append(rspec_lease)
219 return (rspec_leases, rspec_channels)
222 def get_channels(self, slice=None, options=None):
223 if options is None: options={}
225 all_channels = self.driver.shell.getChannels({}, [])
228 reserved_channels = self.driver.shell.getReservedChannels()
229 reserved_channel_ids = []
230 for channel in reserved_channels:
231 if channel['slice_id'] == slice['slice_id']:
232 reserved_channel_ids.append(channel['channel_id'])
234 for channel in all_channels:
235 if channel['channel_id'] in reserved_channel_ids:
236 channels.append(channel)
238 channels = all_channels
241 for channel in channels:
242 rspec_channel = Channel()
243 rspec_channel['channel_num'] = channel['channel']
244 rspec_channel['frequency'] = channel['frequency']
245 rspec_channel['standard'] = channel['modulation']
246 rspec_channel['component_id'] = channel_to_urn(self.driver.hrn, self.driver.testbedInfo['name'], channel['channel'])
247 rspec_channels.append(rspec_channel)
248 return rspec_channels
252 def get_rspec(self, slice_xrn=None, version = None, options=None):
253 if options is None: options={}
255 version_manager = VersionManager()
256 version = version_manager.get_version(version)
259 rspec_version = version_manager._get_version(version.type, version.version, 'ad')
261 rspec_version = version_manager._get_version(version.type, version.version, 'manifest')
263 slice, slivers = self.get_slice_and_slivers(slice_xrn)
265 rspec = RSpec(version=rspec_version, user_options=options)
267 if slice and 'expires' in slice:
268 rspec.xml.set('expires', datetime_to_string(utcparse(slice['expires'])))
270 if not options.get('list_leases') or options.get('list_leases') and options['list_leases'] != 'leases':
271 nodes = self.get_nodes(slice_xrn, slice, slivers, options)
272 rspec.version.add_nodes(nodes)
273 # add sliver defaults
274 default_sliver = slivers.get(None, [])
276 default_sliver_attribs = default_sliver.get('tags', [])
277 for attrib in default_sliver_attribs:
279 rspec.version.add_default_sliver_attribute(attrib['tagname'], attrib['value'])
281 channels = self.get_channels(slice, options)
282 rspec.version.add_channels(channels)
284 if not options.get('list_leases') or options.get('list_leases') and options['list_leases'] != 'resources':
285 leases_channels = self.get_leases_and_channels(slice, slice_xrn)
286 rspec.version.add_leases(leases_channels)