2 from sfa.util.xrn import Xrn, hrn_to_urn, urn_to_hrn, urn_to_sliver_id
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):
33 def get_sites(self, filter={}):
35 for site in self.driver.shell.GetSites(filter):
36 sites[site['site_id']] = site
39 def get_interfaces(self, filter={}):
41 for interface in self.driver.shell.GetInterfaces(filter):
43 if interface['bwlimit']:
44 interface['bwlimit'] = str(int(interface['bwlimit'])/1000)
45 interfaces[interface['interface_id']] = interface
48 def get_links(self, sites, nodes, interfaces):
52 for (site_id1, site_id2) in topology:
53 site_id1 = int(site_id1)
54 site_id2 = int(site_id2)
56 if not site_id1 in sites or site_id2 not in sites:
58 site1 = sites[site_id1]
59 site2 = sites[site_id2]
61 site1_hrn = self.driver.hrn + '.' + site1['login_base']
62 site2_hrn = self.driver.hrn + '.' + site2['login_base']
64 for s1_node_id in site1['node_ids']:
65 for s2_node_id in site2['node_ids']:
66 if s1_node_id not in nodes or s2_node_id not in nodes:
68 node1 = nodes[s1_node_id]
69 node2 = nodes[s2_node_id]
71 # just get first interface of the first node
72 if1_xrn = PlXrn(auth=self.driver.hrn, interface='node%s:eth0' % (node1['node_id']))
73 if1_ipv4 = interfaces[node1['interface_ids'][0]]['ip']
74 if2_xrn = PlXrn(auth=self.driver.hrn, interface='node%s:eth0' % (node2['node_id']))
75 if2_ipv4 = interfaces[node2['interface_ids'][0]]['ip']
77 if1 = Interface({'component_id': if1_xrn.urn, 'ipv4': if1_ipv4} )
78 if2 = Interface({'component_id': if2_xrn.urn, 'ipv4': if2_ipv4} )
81 link = Link({'capacity': '1000000', 'latency': '0', 'packet_loss': '0', 'type': 'ipv4'})
82 link['interface1'] = if1
83 link['interface2'] = if2
84 link['component_name'] = "%s:%s" % (site1['login_base'], site2['login_base'])
85 link['component_id'] = PlXrn(auth=self.driver.hrn, interface=link['component_name']).get_urn()
86 link['component_manager_id'] = hrn_to_urn(self.driver.hrn, 'authority+am')
91 def get_node_tags(self, filter={}):
93 for node_tag in self.driver.shell.GetNodeTags(filter):
94 node_tags[node_tag['node_tag_id']] = node_tag
97 def get_pl_initscripts(self, filter={}):
99 filter.update({'enabled': True})
100 for initscript in self.driver.shell.GetInitScripts(filter):
101 pl_initscripts[initscript['initscript_id']] = initscript
102 return pl_initscripts
105 def get_slice_and_slivers(self, slice_xrn):
107 Returns a dict of slivers keyed on the sliver's node_id
112 return (slice, slivers)
113 slice_urn = hrn_to_urn(slice_xrn, 'slice')
114 slice_hrn, _ = urn_to_hrn(slice_xrn)
115 slice_name = hrn_to_nitos_slicename(slice_hrn)
116 slices = self.driver.shell.getSlices()
119 if slc['slice_name'] == slice_name:
124 return (slice, slivers)
126 reserved_nodes = self.driver.shell.getReservedNodes()
128 for node in reserved_nodes:
129 if node['slice_id'] == slice['slice_id']:
130 slivers[node[node_id]] = node
132 return (slice, slivers)
136 def get_nodes_and_links(self, slice_xrn, slice=None,slivers={}, options={}):
137 # if we are dealing with a slice that has no node just return
140 if not slice or not slivers:
143 nodes = [slivers[sliver] for sliver in slivers]
145 nodes = self.driver.shell.getNodes()
147 # get the granularity in second for the reservation system
148 grain = self.driver.testbedInfo['grain']
156 site_name = self.driver.testbedInfo['name']
157 rspec_node['component_id'] = hostname_to_urn(self.driver.hrn, site_name, node['name'])
158 rspec_node['component_name'] = node['name']
159 rspec_node['component_manager_id'] = Xrn(self.driver.hrn, 'authority+cm').get_urn()
160 rspec_node['authority_id'] = hrn_to_urn(NitosXrn.site_hrn(self.driver.hrn, site_name), 'authority+sa')
161 # do not include boot state (<available> element) in the manifest rspec
163 # rspec_node['boot_state'] = node['boot_state']
164 rspec_node['exclusive'] = 'true'
166 longitude = self.driver.testbedInfo['longitude']
167 latitude = self.driver.testbedInfo['latitude']
168 if longitude and latitude:
169 location = Location({'longitude': longitude, 'latitude': latitude, 'country': 'unknown'})
170 rspec_node['location'] = location
172 position_3d = Position3D({'x': node['position']['X'], 'y': node['position']['Y'], 'z': node['position']['Z']})
173 #position_3d = Position3D({'x': 1, 'y': 2, 'z': 3})
174 rspec_node['position_3d'] = position_3d
176 granularity = Granularity({'grain': grain})
177 rspec_node['granularity'] = granularity
180 rspec_node['hardware_type'] = node['node_type']
181 #rspec_node['hardware_type'] = "orbit"
184 rspec_nodes.append(rspec_node)
185 return (rspec_nodes, [])
187 def get_leases_and_channels(self, slice=None, options={}):
189 slices = self.driver.shell.getSlices()
190 nodes = self.driver.shell.getNodes()
191 leases = self.driver.shell.getReservedNodes()
192 channels = self.driver.shell.getChannels()
193 reserved_channels = self.driver.shell.getReservedChannels()
194 grain = self.driver.testbedInfo['grain']
198 if lease['slice_id'] != slice['slice_id']:
200 for channel in reserved_channels:
201 if channel['slice_id'] != slice['slice_id']:
202 reserved_channels.remove(channel)
205 for channel in reserved_channels:
208 #retrieve channel number
210 if chl['channel_id'] == channel['channel_id']:
211 channel_number = chl['channel']
214 rspec_channel['channel_num'] = channel_number
215 rspec_channel['start_time'] = channel['start_time']
216 rspec_channel['duration'] = (int(channel['end_time']) - int(channel['start_time'])) / int(grain)
220 if slc['slice_id'] == channel['slice_id']:
221 slicename = slc['slice_name']
224 slice_hrn = slicename_to_hrn(self.driver.hrn, self.driver.testbedInfo['name'], slicename)
225 slice_urn = hrn_to_urn(slice_hrn, 'slice')
226 rspec_channel['slice_id'] = slice_urn
227 rspec_channels.append(rspec_channel)
233 rspec_lease = Lease()
235 rspec_lease['lease_id'] = lease['reservation_id']
238 if node['node_id'] == lease['node_id']:
239 nodename = node['name']
242 rspec_lease['component_id'] = hostname_to_urn(self.driver.hrn, self.driver.testbedInfo['name'], nodename)
245 if slc['slice_id'] == lease['slice_id']:
246 slicename = slc['slice_name']
249 slice_hrn = slicename_to_hrn(self.driver.hrn, self.driver.testbedInfo['name'], slicename)
250 slice_urn = hrn_to_urn(slice_hrn, 'slice')
251 rspec_lease['slice_id'] = slice_urn
252 rspec_lease['start_time'] = lease['start_time']
253 rspec_lease['duration'] = (int(lease['end_time']) - int(lease['start_time'])) / int(grain)
254 rspec_leases.append(rspec_lease)
256 return (rspec_leases, rspec_channels)
259 def get_channels(self, options={}):
262 channels = self.driver.shell.getChannels()
264 for channel in channels:
265 rspec_channel = Channel()
266 rspec_channel['channel_num'] = channel['channel']
267 rspec_channel['frequency'] = channel['frequency']
268 rspec_channel['standard'] = channel['modulation']
269 rspec_channels.append(rspec_channel)
270 return rspec_channels
274 def get_rspec(self, slice_xrn=None, version = None, options={}):
276 version_manager = VersionManager()
277 version = version_manager.get_version(version)
280 rspec_version = version_manager._get_version(version.type, version.version, 'ad')
282 rspec_version = version_manager._get_version(version.type, version.version, 'manifest')
284 slice, slivers = self.get_slice_and_slivers(slice_xrn)
286 rspec = RSpec(version=rspec_version, user_options=options)
288 if slice and 'expires' in slice:
289 rspec.xml.set('expires', datetime_to_string(utcparse(slice['expires'])))
291 if not options.get('list_leases') or options.get('list_leases') and options['list_leases'] != 'leases':
292 nodes, links = self.get_nodes_and_links(slice_xrn, slice, slivers, options)
293 rspec.version.add_nodes(nodes)
294 rspec.version.add_links(links)
295 # add sliver defaults
296 default_sliver = slivers.get(None, [])
298 default_sliver_attribs = default_sliver.get('tags', [])
299 for attrib in default_sliver_attribs:
301 rspec.version.add_default_sliver_attribute(attrib['tagname'], attrib['value'])
303 channels = self.get_channels()
304 rspec.version.add_channels(channels)
306 if not options.get('list_leases') or options.get('list_leases') and options['list_leases'] != 'resources':
307 leases, channels = self.get_leases_and_channels(slice)
308 rspec.version.add_leases(leases, channels)