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):
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, 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']
141 all_leases.extend(leases)
142 all_reserved_channels = []
143 all_reserved_channels.extend(reserved_channels)
144 for lease in all_leases:
145 if lease['slice_id'] != slice['slice_id']:
147 for channel in all_reserved_channels:
148 if channel['slice_id'] != slice['slice_id']:
149 reserved_channels.remove(channel)
152 for channel in reserved_channels:
155 #retrieve channel number
157 if chl['channel_id'] == channel['channel_id']:
158 channel_number = chl['channel']
161 rspec_channel['channel_num'] = channel_number
162 rspec_channel['start_time'] = channel['start_time']
163 rspec_channel['duration'] = (int(channel['end_time']) - int(channel['start_time'])) / int(grain)
167 if slc['slice_id'] == channel['slice_id']:
168 slicename = slc['slice_name']
171 slice_hrn = slicename_to_hrn(self.driver.hrn, self.driver.testbedInfo['name'], slicename)
172 slice_urn = hrn_to_urn(slice_hrn, 'slice')
173 rspec_channel['slice_id'] = slice_urn
174 rspec_channels.append(rspec_channel)
180 rspec_lease = Lease()
182 rspec_lease['lease_id'] = lease['reservation_id']
185 if node['node_id'] == lease['node_id']:
186 nodename = node['hostname']
189 rspec_lease['component_id'] = hostname_to_urn(self.driver.hrn, self.driver.testbedInfo['name'], nodename)
192 if slc['slice_id'] == lease['slice_id']:
193 slicename = slc['slice_name']
196 slice_hrn = slicename_to_hrn(self.driver.hrn, self.driver.testbedInfo['name'], slicename)
197 slice_urn = hrn_to_urn(slice_hrn, 'slice')
198 rspec_lease['slice_id'] = slice_urn
199 rspec_lease['start_time'] = lease['start_time']
200 rspec_lease['duration'] = (int(lease['end_time']) - int(lease['start_time'])) / int(grain)
201 rspec_leases.append(rspec_lease)
203 return (rspec_leases, rspec_channels)
206 def get_channels(self, slice=None, options={}):
208 all_channels = self.driver.shell.getChannels({}, [])
211 reserved_channels = self.driver.shell.getReservedChannels()
212 reserved_channel_ids = []
213 for channel in reserved_channels:
214 if channel['slice_id'] == slice['slice_id']:
215 reserved_channel_ids.append(channel['channel_id'])
217 for channel in all_channels:
218 if channel['channel_id'] in reserved_channel_ids:
219 channels.append(channel)
221 channels = all_channels
224 for channel in channels:
225 rspec_channel = Channel()
226 rspec_channel['channel_num'] = channel['channel']
227 rspec_channel['frequency'] = channel['frequency']
228 rspec_channel['standard'] = channel['modulation']
229 rspec_channels.append(rspec_channel)
230 return rspec_channels
234 def get_rspec(self, slice_xrn=None, version = None, options={}):
236 version_manager = VersionManager()
237 version = version_manager.get_version(version)
240 rspec_version = version_manager._get_version(version.type, version.version, 'ad')
242 rspec_version = version_manager._get_version(version.type, version.version, 'manifest')
244 slice, slivers = self.get_slice_and_slivers(slice_xrn)
246 rspec = RSpec(version=rspec_version, user_options=options)
248 if slice and 'expires' in slice:
249 rspec.xml.set('expires', datetime_to_string(utcparse(slice['expires'])))
251 if not options.get('list_leases') or options.get('list_leases') and options['list_leases'] != 'leases':
252 nodes = self.get_nodes(slice_xrn, slice, slivers, options)
253 rspec.version.add_nodes(nodes)
254 # add sliver defaults
255 default_sliver = slivers.get(None, [])
257 default_sliver_attribs = default_sliver.get('tags', [])
258 for attrib in default_sliver_attribs:
260 rspec.version.add_default_sliver_attribute(attrib['tagname'], attrib['value'])
262 channels = self.get_channels(slice, options)
263 rspec.version.add_channels(channels)
265 if not options.get('list_leases') or options.get('list_leases') and options['list_leases'] != 'resources':
266 leases, channels = self.get_leases_and_channels(slice)
267 rspec.version.add_leases(leases, channels)