4 from sfa.util.faults import MissingSfaInfo, UnknownSfaType, \
5 RecordNotFound, SfaNotImplemented, SliverDoesNotExist
6 from sfa.util.sfalogging import logger
7 from sfa.util.defaultdict import defaultdict
8 from sfa.util.sfatime import utcparse, datetime_to_string, datetime_to_epoch
9 from sfa.util.xrn import hrn_to_urn, get_leaf, urn_to_sliver_id
10 from sfa.util.cache import Cache
12 # one would think the driver should not need to mess with the SFA db, but..
13 from sfa.storage.alchemy import dbsession
14 from sfa.storage.model import RegRecord
16 # used to be used in get_ticket
17 #from sfa.trust.sfaticket import SfaTicket
18 from sfa.rspecs.version_manager import VersionManager
19 from sfa.rspecs.rspec import RSpec
21 # the driver interface, mostly provides default behaviours
22 from sfa.managers.driver import Driver
23 from sfa.planetlab.plshell import PlShell
24 import sfa.planetlab.peers as peers
25 from sfa.planetlab.plaggregate import PlAggregate
26 from sfa.planetlab.plslices import PlSlices
27 from sfa.planetlab.plxrn import PlXrn, slicename_to_hrn, hostname_to_hrn, hrn_to_pl_slicename, xrn_to_hostname
30 def list_to_dict(recs, key):
32 convert a list of dictionaries into a dictionary keyed on the
33 specified dictionary key
35 return dict ( [ (rec[key],rec) for rec in recs ] )
38 # PlShell is just an xmlrpc serverproxy where methods
39 # can be sent as-is; it takes care of authentication
40 # from the global config
42 class PlDriver (Driver):
44 # the cache instance is a class member so it survives across incoming requests
47 def __init__ (self, config):
48 Driver.__init__ (self, config)
49 self.shell = PlShell (config)
51 if config.SFA_AGGREGATE_CACHING:
52 if PlDriver.cache is None:
53 PlDriver.cache = Cache()
54 self.cache = PlDriver.cache
56 ########################################
57 ########## registry oriented
58 ########################################
60 def augment_records_with_testbed_info (self, sfa_records):
61 return self.fill_record_info (sfa_records)
64 def register (self, sfa_record, hrn, pub_key):
65 type = sfa_record['type']
66 pl_record = self.sfa_fields_to_pl_fields(type, hrn, sfa_record)
68 if type == 'authority':
69 sites = self.shell.GetSites([pl_record['login_base']])
71 # xxx when a site gets registered through SFA we need to set its max_slices
72 if 'max_slices' not in pl_record:
73 pl_record['max_slices']=2
74 pointer = self.shell.AddSite(pl_record)
76 pointer = sites[0]['site_id']
79 acceptable_fields=['url', 'instantiation', 'name', 'description']
80 for key in pl_record.keys():
81 if key not in acceptable_fields:
83 slices = self.shell.GetSlices([pl_record['name']])
85 pointer = self.shell.AddSlice(pl_record)
87 pointer = slices[0]['slice_id']
90 persons = self.shell.GetPersons({'email':sfa_record['email']})
92 for key in ['first_name','last_name']:
93 if key not in sfa_record: sfa_record[key]='*from*sfa*'
94 pointer = self.shell.AddPerson(dict(sfa_record))
96 pointer = persons[0]['person_id']
98 if 'enabled' in sfa_record and sfa_record['enabled']:
99 self.shell.UpdatePerson(pointer, {'enabled': sfa_record['enabled']})
100 # add this person to the site only if she is being added for the first
101 # time by sfa and doesont already exist in plc
102 if not persons or not persons[0]['site_ids']:
103 login_base = get_leaf(sfa_record['authority'])
104 self.shell.AddPersonToSite(pointer, login_base)
106 # What roles should this user have?
108 if 'roles' in sfa_record:
109 # if specified in xml, but only low-level roles
110 roles = [ role for role in sfa_record['roles'] if role in ['user','tech'] ]
111 # at least user if no other cluse could be found
115 self.shell.AddRoleToPerson(role, pointer)
118 self.shell.AddPersonKey(pointer, {'key_type' : 'ssh', 'key' : pub_key})
121 login_base = PlXrn(xrn=sfa_record['authority'],type='node').pl_login_base()
122 nodes = self.shell.GetNodes([pl_record['hostname']])
124 pointer = self.shell.AddNode(login_base, pl_record)
126 pointer = nodes[0]['node_id']
131 # xxx actually old_sfa_record comes filled with plc stuff as well in the original code
132 def update (self, old_sfa_record, new_sfa_record, hrn, new_key):
133 pointer = old_sfa_record['pointer']
134 type = old_sfa_record['type']
136 # new_key implemented for users only
137 if new_key and type not in [ 'user' ]:
138 raise UnknownSfaType(type)
140 if (type == "authority"):
141 self.shell.UpdateSite(pointer, new_sfa_record)
143 elif type == "slice":
144 pl_record=self.sfa_fields_to_pl_fields(type, hrn, new_sfa_record)
145 if 'name' in pl_record:
146 pl_record.pop('name')
147 self.shell.UpdateSlice(pointer, pl_record)
150 # SMBAKER: UpdatePerson only allows a limited set of fields to be
151 # updated. Ideally we should have a more generic way of doing
152 # this. I copied the field names from UpdatePerson.py...
154 all_fields = new_sfa_record
155 for key in all_fields.keys():
156 if key in ['first_name', 'last_name', 'title', 'email',
157 'password', 'phone', 'url', 'bio', 'accepted_aup',
159 update_fields[key] = all_fields[key]
160 # when updating a user, we always get a 'email' field at this point
161 # this is because 'email' is a native field in the RegUser object...
162 if 'email' in update_fields and not update_fields['email']:
163 del update_fields['email']
164 self.shell.UpdatePerson(pointer, update_fields)
167 # must check this key against the previous one if it exists
168 persons = self.shell.GetPersons([pointer], ['key_ids'])
170 keys = person['key_ids']
171 keys = self.shell.GetKeys(person['key_ids'])
173 # Delete all stale keys
176 if new_key != key['key']:
177 self.shell.DeleteKey(key['key_id'])
181 self.shell.AddPersonKey(pointer, {'key_type': 'ssh', 'key': new_key})
184 self.shell.UpdateNode(pointer, new_sfa_record)
190 def remove (self, sfa_record):
191 type=sfa_record['type']
192 pointer=sfa_record['pointer']
194 persons = self.shell.GetPersons(pointer)
195 # only delete this person if he has site ids. if he doesnt, it probably means
196 # he was just removed from a site, not actually deleted
197 if persons and persons[0]['site_ids']:
198 self.shell.DeletePerson(pointer)
199 elif type == 'slice':
200 if self.shell.GetSlices(pointer):
201 self.shell.DeleteSlice(pointer)
203 if self.shell.GetNodes(pointer):
204 self.shell.DeleteNode(pointer)
205 elif type == 'authority':
206 if self.shell.GetSites(pointer):
207 self.shell.DeleteSite(pointer)
216 # Convert SFA fields to PLC fields for use when registering or updating
217 # registry record in the PLC database
220 def sfa_fields_to_pl_fields(self, type, hrn, sfa_record):
225 pl_record["name"] = hrn_to_pl_slicename(hrn)
226 if "instantiation" in sfa_record:
227 pl_record['instantiation']=sfa_record['instantiation']
229 pl_record["instantiation"] = "plc-instantiated"
230 if "url" in sfa_record:
231 pl_record["url"] = sfa_record["url"]
232 if "description" in sfa_record:
233 pl_record["description"] = sfa_record["description"]
234 if "expires" in sfa_record:
235 date = utcparse(sfa_record['expires'])
236 expires = datetime_to_epoch(date)
237 pl_record["expires"] = expires
240 if not "hostname" in pl_record:
241 # fetch from sfa_record
242 if "hostname" not in sfa_record:
243 raise MissingSfaInfo("hostname")
244 pl_record["hostname"] = sfa_record["hostname"]
245 if "model" in sfa_record:
246 pl_record["model"] = sfa_record["model"]
248 pl_record["model"] = "geni"
250 elif type == "authority":
251 pl_record["login_base"] = PlXrn(xrn=hrn,type='authority').pl_login_base()
252 if "name" not in sfa_record:
253 pl_record["name"] = hrn
254 if "abbreviated_name" not in sfa_record:
255 pl_record["abbreviated_name"] = hrn
256 if "enabled" not in sfa_record:
257 pl_record["enabled"] = True
258 if "is_public" not in sfa_record:
259 pl_record["is_public"] = True
264 def fill_record_info(self, records):
266 Given a (list of) SFA record, fill in the PLC specific
267 and SFA specific fields in the record.
269 if not isinstance(records, list):
272 self.fill_record_pl_info(records)
273 self.fill_record_hrns(records)
274 self.fill_record_sfa_info(records)
277 def fill_record_pl_info(self, records):
279 Fill in the planetlab specific fields of a SFA record. This
280 involves calling the appropriate PLC method to retrieve the
281 database record for the object.
283 @param record: record to fill in field (in/out param)
286 node_ids, site_ids, slice_ids = [], [], []
287 person_ids, key_ids = [], []
288 type_map = {'node': node_ids, 'authority': site_ids,
289 'slice': slice_ids, 'user': person_ids}
291 for record in records:
292 for type in type_map:
293 if type == record['type']:
294 type_map[type].append(record['pointer'])
297 nodes, sites, slices, persons, keys = {}, {}, {}, {}, {}
299 node_list = self.shell.GetNodes(node_ids)
300 nodes = list_to_dict(node_list, 'node_id')
302 site_list = self.shell.GetSites(site_ids)
303 sites = list_to_dict(site_list, 'site_id')
305 slice_list = self.shell.GetSlices(slice_ids)
306 slices = list_to_dict(slice_list, 'slice_id')
308 person_list = self.shell.GetPersons(person_ids)
309 persons = list_to_dict(person_list, 'person_id')
310 for person in persons:
311 key_ids.extend(persons[person]['key_ids'])
313 pl_records = {'node': nodes, 'authority': sites,
314 'slice': slices, 'user': persons}
317 key_list = self.shell.GetKeys(key_ids)
318 keys = list_to_dict(key_list, 'key_id')
321 for record in records:
322 # records with pointer==-1 do not have plc info.
323 # for example, the top level authority records which are
324 # authorities, but not PL "sites"
325 if record['pointer'] == -1:
328 for type in pl_records:
329 if record['type'] == type:
330 if record['pointer'] in pl_records[type]:
331 record.update(pl_records[type][record['pointer']])
334 if record['type'] == 'user':
335 if 'key_ids' not in record:
336 logger.info("user record has no 'key_ids' - need to import from myplc ?")
338 pubkeys = [keys[key_id]['key'] for key_id in record['key_ids'] if key_id in keys]
339 record['keys'] = pubkeys
343 def fill_record_hrns(self, records):
345 convert pl ids to hrns
349 slice_ids, person_ids, site_ids, node_ids = [], [], [], []
350 for record in records:
351 if 'site_id' in record:
352 site_ids.append(record['site_id'])
353 if 'site_ids' in record:
354 site_ids.extend(record['site_ids'])
355 if 'person_ids' in record:
356 person_ids.extend(record['person_ids'])
357 if 'slice_ids' in record:
358 slice_ids.extend(record['slice_ids'])
359 if 'node_ids' in record:
360 node_ids.extend(record['node_ids'])
363 slices, persons, sites, nodes = {}, {}, {}, {}
365 site_list = self.shell.GetSites(site_ids, ['site_id', 'login_base'])
366 sites = list_to_dict(site_list, 'site_id')
368 person_list = self.shell.GetPersons(person_ids, ['person_id', 'email'])
369 persons = list_to_dict(person_list, 'person_id')
371 slice_list = self.shell.GetSlices(slice_ids, ['slice_id', 'name'])
372 slices = list_to_dict(slice_list, 'slice_id')
374 node_list = self.shell.GetNodes(node_ids, ['node_id', 'hostname'])
375 nodes = list_to_dict(node_list, 'node_id')
377 # convert ids to hrns
378 for record in records:
379 # get all relevant data
380 type = record['type']
381 pointer = record['pointer']
387 if 'site_id' in record:
388 site = sites[record['site_id']]
389 login_base = site['login_base']
390 record['site'] = ".".join([auth_hrn, login_base])
391 if 'person_ids' in record:
392 emails = [persons[person_id]['email'] for person_id in record['person_ids'] \
393 if person_id in persons]
394 usernames = [email.split('@')[0] for email in emails]
395 person_hrns = [".".join([auth_hrn, login_base, username]) for username in usernames]
396 record['persons'] = person_hrns
397 if 'slice_ids' in record:
398 slicenames = [slices[slice_id]['name'] for slice_id in record['slice_ids'] \
399 if slice_id in slices]
400 slice_hrns = [slicename_to_hrn(auth_hrn, slicename) for slicename in slicenames]
401 record['slices'] = slice_hrns
402 if 'node_ids' in record:
403 hostnames = [nodes[node_id]['hostname'] for node_id in record['node_ids'] \
405 node_hrns = [hostname_to_hrn(auth_hrn, login_base, hostname) for hostname in hostnames]
406 record['nodes'] = node_hrns
407 if 'site_ids' in record:
408 login_bases = [sites[site_id]['login_base'] for site_id in record['site_ids'] \
410 site_hrns = [".".join([auth_hrn, lbase]) for lbase in login_bases]
411 record['sites'] = site_hrns
413 if 'expires' in record:
414 date = utcparse(record['expires'])
415 datestring = datetime_to_string(date)
416 record['expires'] = datestring
420 def fill_record_sfa_info(self, records):
422 def startswith(prefix, values):
423 return [value for value in values if value.startswith(prefix)]
428 for record in records:
429 person_ids.extend(record.get("person_ids", []))
430 site_ids.extend(record.get("site_ids", []))
431 if 'site_id' in record:
432 site_ids.append(record['site_id'])
434 # get all pis from the sites we've encountered
435 # and store them in a dictionary keyed on site_id
438 pi_filter = {'|roles': ['pi'], '|site_ids': site_ids}
439 pi_list = self.shell.GetPersons(pi_filter, ['person_id', 'site_ids'])
441 # we will need the pi's hrns also
442 person_ids.append(pi['person_id'])
444 # we also need to keep track of the sites these pis
446 for site_id in pi['site_ids']:
447 if site_id in site_pis:
448 site_pis[site_id].append(pi)
450 site_pis[site_id] = [pi]
452 # get sfa records for all records associated with these records.
453 # we'll replace pl ids (person_ids) with hrns from the sfa records
456 # get the registry records
457 person_list, persons = [], {}
458 person_list = dbsession.query (RegRecord).filter(RegRecord.pointer.in_(person_ids))
459 # create a hrns keyed on the sfa record's pointer.
460 # Its possible for multiple records to have the same pointer so
461 # the dict's value will be a list of hrns.
462 persons = defaultdict(list)
463 for person in person_list:
464 persons[person.pointer].append(person)
467 pl_person_list, pl_persons = [], {}
468 pl_person_list = self.shell.GetPersons(person_ids, ['person_id', 'roles'])
469 pl_persons = list_to_dict(pl_person_list, 'person_id')
472 for record in records:
473 # skip records with no pl info (top level authorities)
474 #if record['pointer'] == -1:
477 type = record['type']
478 logger.info("fill_record_sfa_info - incoming record typed %s"%type)
479 if (type == "slice"):
480 # all slice users are researchers
481 record['geni_urn'] = hrn_to_urn(record['hrn'], 'slice')
483 record['researcher'] = []
484 for person_id in record.get('person_ids', []):
485 hrns = [person.hrn for person in persons[person_id]]
486 record['researcher'].extend(hrns)
488 # pis at the slice's site
489 if 'site_id' in record and record['site_id'] in site_pis:
490 pl_pis = site_pis[record['site_id']]
491 pi_ids = [pi['person_id'] for pi in pl_pis]
492 for person_id in pi_ids:
493 hrns = [person.hrn for person in persons[person_id]]
494 record['PI'].extend(hrns)
495 record['geni_creator'] = record['PI']
497 elif (type.startswith("authority")):
499 logger.info("fill_record_sfa_info - authority xherex")
500 if record['pointer'] != -1:
502 record['operator'] = []
504 for pointer in record.get('person_ids', []):
505 if pointer not in persons or pointer not in pl_persons:
506 # this means there is not sfa or pl record for this user
508 hrns = [person.hrn for person in persons[pointer]]
509 roles = pl_persons[pointer]['roles']
511 record['PI'].extend(hrns)
513 record['operator'].extend(hrns)
515 record['owner'].extend(hrns)
516 # xxx TODO: OrganizationName
517 elif (type == "node"):
518 sfa_info['dns'] = record.get("hostname", "")
519 # xxx TODO: URI, LatLong, IP, DNS
521 elif (type == "user"):
522 logger.info('setting user.email')
523 sfa_info['email'] = record.get("email", "")
524 sfa_info['geni_urn'] = hrn_to_urn(record['hrn'], 'user')
525 sfa_info['geni_certificate'] = record['gid']
526 # xxx TODO: PostalAddress, Phone
527 record.update(sfa_info)
531 # plcapi works by changes, compute what needs to be added/deleted
532 def update_relation (self, subject_type, target_type, relation_name, subject_id, target_ids):
533 # hard-wire the code for slice/user for now, could be smarter if needed
534 if subject_type =='slice' and target_type == 'user' and relation_name == 'researcher':
535 subject=self.shell.GetSlices (subject_id)[0]
536 current_target_ids = subject['person_ids']
537 add_target_ids = list ( set (target_ids).difference(current_target_ids))
538 del_target_ids = list ( set (current_target_ids).difference(target_ids))
539 logger.debug ("subject_id = %s (type=%s)"%(subject_id,type(subject_id)))
540 for target_id in add_target_ids:
541 self.shell.AddPersonToSlice (target_id,subject_id)
542 logger.debug ("add_target_id = %s (type=%s)"%(target_id,type(target_id)))
543 for target_id in del_target_ids:
544 logger.debug ("del_target_id = %s (type=%s)"%(target_id,type(target_id)))
545 self.shell.DeletePersonFromSlice (target_id, subject_id)
546 elif subject_type == 'authority' and target_type == 'user' and relation_name == 'pi':
547 # due to the plcapi limitations this means essentially adding pi role to all people in the list
548 # it's tricky to remove any pi role here, although it might be desirable
549 persons = self.shell.GetPersons (target_ids)
550 for person in persons:
551 if 'pi' not in person['roles']:
552 self.shell.AddRoleToPerson('pi',person['person_id'])
554 logger.info('unexpected relation %s to maintain, %s -> %s'%(relation_name,subject_type,target_type))
557 ########################################
558 ########## aggregate oriented
559 ########################################
561 def testbed_name (self): return "myplc"
563 def aggregate_version (self):
566 def list_slices (self, creds, options):
568 slices = self.shell.GetSlices({'peer_id': None}, ['name'])
569 slice_hrns = [slicename_to_hrn(self.hrn, slice['name']) for slice in slices]
570 slice_urns = [hrn_to_urn(slice_hrn, 'slice') for slice_hrn in slice_hrns]
573 # first 2 args are None in case of resource discovery
574 def list_resources (self, creds, options):
575 aggregate = PlAggregate(self)
576 rspec = aggregate.list_resources(version=rspec_version, options=options)
579 def describe(self, creds, urns, options):
582 def sliver_status (self, slice_urn, slice_hrn):
583 # find out where this slice is currently running
584 slicename = hrn_to_pl_slicename(slice_hrn)
586 slices = self.shell.GetSlices([slicename], ['slice_id', 'node_ids','person_ids','name','expires'])
588 raise SliverDoesNotExist("%s (used %s as slicename internally)" % (slice_hrn, slicename))
591 # report about the local nodes only
592 nodes = self.shell.GetNodes({'node_id':slice['node_ids'],'peer_id':None},
593 ['node_id', 'hostname', 'site_id', 'boot_state', 'last_contact'])
596 raise SliverDoesNotExist("You have not allocated any slivers here")
600 if slice['person_ids']:
601 persons = self.shell.GetPersons(slice['person_ids'], ['key_ids'])
602 key_ids = [key_id for person in persons for key_id in person['key_ids']]
603 person_keys = self.shell.GetKeys(key_ids)
604 keys = [key['key'] for key in person_keys]
606 user.update({'urn': slice_urn,
607 'login': slice['name'],
612 site_ids = [node['site_id'] for node in nodes]
615 result['geni_urn'] = slice_urn
616 result['pl_login'] = slice['name']
617 result['pl_expires'] = datetime_to_string(utcparse(slice['expires']))
618 result['geni_expires'] = datetime_to_string(utcparse(slice['expires']))
623 res['pl_hostname'] = node['hostname']
624 res['pl_boot_state'] = node['boot_state']
625 res['pl_last_contact'] = node['last_contact']
626 res['geni_expires'] = datetime_to_string(utcparse(slice['expires']))
627 if node['last_contact'] is not None:
629 res['pl_last_contact'] = datetime_to_string(utcparse(node['last_contact']))
630 sliver_id = urn_to_sliver_id(slice_urn, slice['slice_id'], node['node_id'], authority=self.hrn)
631 res['geni_urn'] = sliver_id
632 if node['boot_state'] == 'boot':
633 res['geni_status'] = 'ready'
635 res['geni_status'] = 'failed'
636 res['geni_allocation_status'] = 'geni_provisioned'
638 res['geni_error'] = ''
639 res['users'] = [user]
640 resources.append(res)
642 result['geni_resources'] = resources
645 def create_sliver (self, slice_urn, slice_hrn, creds, rspec_string, users, options):
647 aggregate = PlAggregate(self)
648 slices = PlSlices(self)
649 peer = slices.get_peer(slice_hrn)
650 sfa_peer = slices.get_sfa_peer(slice_hrn)
653 slice_record = users[0].get('slice_record', {})
656 rspec = RSpec(rspec_string)
657 requested_attributes = rspec.version.get_slice_attributes()
659 # ensure site record exists
660 site = slices.verify_site(slice_hrn, slice_record, peer, sfa_peer, options=options)
661 # ensure slice record exists
662 slice = slices.verify_slice(slice_hrn, slice_record, peer, sfa_peer, options=options)
663 # ensure person records exists
664 persons = slices.verify_persons(slice_hrn, slice, users, peer, sfa_peer, options=options)
665 # ensure slice attributes exists
666 slices.verify_slice_attributes(slice, requested_attributes, options=options)
668 # add/remove slice from nodes
669 requested_slivers = []
670 for node in rspec.version.get_nodes_with_slivers():
672 if node.get('component_name'):
673 hostname = node.get('component_name').strip()
674 elif node.get('component_id'):
675 hostname = xrn_to_hostname(node.get('component_id').strip())
677 requested_slivers.append(hostname)
678 nodes = slices.verify_slice_nodes(slice, requested_slivers, peer)
680 # add/remove links links
681 slices.verify_slice_links(slice, rspec.version.get_link_requests(), nodes)
684 requested_leases = []
686 for lease in rspec.version.get_leases():
688 if not lease.get('lease_id'):
689 requested_lease['hostname'] = xrn_to_hostname(lease.get('component_id').strip())
690 requested_lease['start_time'] = lease.get('start_time')
691 requested_lease['duration'] = lease.get('duration')
693 kept_leases.append(int(lease['lease_id']))
694 if requested_lease.get('hostname'):
695 requested_leases.append(requested_lease)
697 leases = slices.verify_slice_leases(slice, requested_leases, kept_leases, peer)
699 # handle MyPLC peer association.
700 # only used by plc and ple.
701 slices.handle_peer(site, slice, persons, peer)
703 return aggregate.describe_rspec(slice_xrn=slice_urn, version=rspec.version)
705 def delete_sliver (self, slice_urn, slice_hrn, creds, options):
706 slicename = hrn_to_pl_slicename(slice_hrn)
707 slices = self.shell.GetSlices({'name': slicename})
712 # determine if this is a peer slice
713 # xxx I wonder if this would not need to use PlSlices.get_peer instead
714 # in which case plc.peers could be deprecated as this here
715 # is the only/last call to this last method in plc.peers
716 peer = peers.get_peer(self, slice_hrn)
719 self.shell.UnBindObjectFromPeer('slice', slice['slice_id'], peer)
720 self.shell.DeleteSliceFromNodes(slicename, slice['node_ids'])
723 self.shell.BindObjectToPeer('slice', slice['slice_id'], peer, slice['peer_slice_id'])
726 def renew_sliver (self, slice_urn, slice_hrn, creds, expiration_time, options):
727 slicename = hrn_to_pl_slicename(slice_hrn)
728 slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
730 raise RecordNotFound(slice_hrn)
732 requested_time = utcparse(expiration_time)
733 record = {'expires': int(datetime_to_epoch(requested_time))}
735 self.shell.UpdateSlice(slice['slice_id'], record)
740 # remove the 'enabled' tag
741 def start_slice (self, slice_urn, slice_hrn, creds):
742 slicename = hrn_to_pl_slicename(slice_hrn)
743 slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
745 raise RecordNotFound(slice_hrn)
746 slice_id = slices[0]['slice_id']
747 slice_tags = self.shell.GetSliceTags({'slice_id': slice_id, 'tagname': 'enabled'}, ['slice_tag_id'])
748 # just remove the tag if it exists
750 self.shell.DeleteSliceTag(slice_tags[0]['slice_tag_id'])
753 # set the 'enabled' tag to 0
754 def stop_slice (self, slice_urn, slice_hrn, creds):
755 slicename = hrn_to_pl_slicename(slice_hrn)
756 slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
758 raise RecordNotFound(slice_hrn)
759 slice_id = slices[0]['slice_id']
760 slice_tags = self.shell.GetSliceTags({'slice_id': slice_id, 'tagname': 'enabled'})
762 self.shell.AddSliceTag(slice_id, 'enabled', '0')
763 elif slice_tags[0]['value'] != "0":
764 tag_id = slice_tags[0]['slice_tag_id']
765 self.shell.UpdateSliceTag(tag_id, '0')
768 def reset_slice (self, slice_urn, slice_hrn, creds):
769 raise SfaNotImplemented ("reset_slice not available at this interface")
771 # xxx this code is quite old and has not run for ages
772 # it is obviously totally broken and needs a rewrite
773 def get_ticket (self, slice_urn, slice_hrn, creds, rspec_string, options):
774 raise SfaNotImplemented,"PlDriver.get_ticket needs a rewrite"
775 # please keep this code for future reference
776 # slices = PlSlices(self)
777 # peer = slices.get_peer(slice_hrn)
778 # sfa_peer = slices.get_sfa_peer(slice_hrn)
780 # # get the slice record
781 # credential = api.getCredential()
782 # interface = api.registries[api.hrn]
783 # registry = api.server_proxy(interface, credential)
784 # records = registry.Resolve(xrn, credential)
786 # # make sure we get a local slice record
788 # for tmp_record in records:
789 # if tmp_record['type'] == 'slice' and \
790 # not tmp_record['peer_authority']:
791 # #Error (E0602, GetTicket): Undefined variable 'SliceRecord'
792 # slice_record = SliceRecord(dict=tmp_record)
794 # raise RecordNotFound(slice_hrn)
796 # # similar to CreateSliver, we must verify that the required records exist
797 # # at this aggregate before we can issue a ticket
799 # rspec = RSpec(rspec_string)
800 # requested_attributes = rspec.version.get_slice_attributes()
802 # # ensure site record exists
803 # site = slices.verify_site(slice_hrn, slice_record, peer, sfa_peer)
804 # # ensure slice record exists
805 # slice = slices.verify_slice(slice_hrn, slice_record, peer, sfa_peer)
806 # # ensure person records exists
807 # # xxx users is undefined in this context
808 # persons = slices.verify_persons(slice_hrn, slice, users, peer, sfa_peer)
809 # # ensure slice attributes exists
810 # slices.verify_slice_attributes(slice, requested_attributes)
813 # slivers = slices.get_slivers(slice_hrn)
816 # raise SliverDoesNotExist(slice_hrn)
821 # 'timestamp': int(time.time()),
822 # 'initscripts': initscripts,
826 # # create the ticket
827 # object_gid = record.get_gid_object()
828 # new_ticket = SfaTicket(subject = object_gid.get_subject())
829 # new_ticket.set_gid_caller(api.auth.client_gid)
830 # new_ticket.set_gid_object(object_gid)
831 # new_ticket.set_issuer(key=api.key, subject=self.hrn)
832 # new_ticket.set_pubkey(object_gid.get_pubkey())
833 # new_ticket.set_attributes(data)
834 # new_ticket.set_rspec(rspec)
835 # #new_ticket.set_parent(api.auth.hierarchy.get_auth_ticket(auth_hrn))
836 # new_ticket.encode()
839 # return new_ticket.save_to_string(save_parents=True)