9 from types import StringTypes
10 from sfa.util.misc import *
11 from sfa.util.rspec import *
12 from sfa.util.specdict import *
13 from sfa.util.faults import *
14 from sfa.util.storage import *
15 from sfa.util.record import GeniRecord
16 from sfa.util.policy import Policy
17 from sfa.util.prefixTree import prefixTree
18 from sfa.util.debug import log
19 from sfa.server.aggregate import Aggregates
20 from sfa.server.registry import Registries
24 class Slices(SimpleStorage):
26 rspec_to_slice_tag = {'max_rate':'net_max_rate'}
28 def __init__(self, api, ttl = .5, origin_hrn=None):
32 path = self.api.config.SFA_DATA_DIR
33 filename = ".".join([self.api.interface, self.api.hrn, "slices"])
34 filepath = path + os.sep + filename
35 self.slices_file = filepath
36 SimpleStorage.__init__(self, self.slices_file)
37 self.policy = Policy(self.api)
39 self.origin_hrn=origin_hrn
41 def get_slivers(self, hrn, node=None):
43 slice_name = hrn_to_pl_slicename(hrn)
44 # XX Should we just call PLCAPI.GetSliceTicket(slice_name) instead
45 # of doing all of this?
46 #return self.api.GetSliceTicket(self.auth, slice_name)
48 # from PLCAPI.GetSlivers.get_slivers()
49 slice_fields = ['slice_id', 'name', 'instantiation', 'expires', 'person_ids', 'slice_tag_ids']
50 slices = self.api.plshell.GetSlices(self.api.plauth, slice_name, slice_fields)
51 # Build up list of users and slice attributes
53 all_slice_tag_ids = set()
55 person_ids.update(slice['person_ids'])
56 all_slice_tag_ids.update(slice['slice_tag_ids'])
57 person_ids = list(person_ids)
58 all_slice_tag_ids = list(all_slice_tag_ids)
59 # Get user information
60 all_persons_list = self.api.plshell.GetPersons(self.api.plauth, {'person_id':person_ids,'enabled':True}, ['person_id', 'enabled', 'key_ids'])
62 for person in all_persons_list:
63 all_persons[person['person_id']] = person
65 # Build up list of keys
67 for person in all_persons.values():
68 key_ids.update(person['key_ids'])
69 key_ids = list(key_ids)
70 # Get user account keys
71 all_keys_list = self.api.plshell.GetKeys(self.api.plauth, key_ids, ['key_id', 'key', 'key_type'])
73 for key in all_keys_list:
74 all_keys[key['key_id']] = key
75 # Get slice attributes
76 all_slice_tags_list = self.api.plshell.GetSliceTags(self.api.plauth, all_slice_tag_ids)
78 for slice_tag in all_slice_tags_list:
79 all_slice_tags[slice_tag['slice_tag_id']] = slice_tag
84 for person_id in slice['person_ids']:
85 if person_id in all_persons:
86 person = all_persons[person_id]
87 if not person['enabled']:
89 for key_id in person['key_ids']:
90 if key_id in all_keys:
91 key = all_keys[key_id]
92 keys += [{'key_type': key['key_type'],
95 # All (per-node and global) attributes for this slice
97 for slice_tag_id in slice['slice_tag_ids']:
98 if slice_tag_id in all_slice_tags:
99 slice_tags.append(all_slice_tags[slice_tag_id])
100 # Per-node sliver attributes take precedence over global
101 # slice attributes, so set them first.
102 # Then comes nodegroup slice attributes
103 # Followed by global slice attributes
104 sliver_attributes = []
107 for sliver_attribute in filter(lambda a: a['node_id'] == node['node_id'], slice_tags):
108 sliver_attributes.append(sliver_attribute['tagname'])
109 attributes.append({'tagname': sliver_attribute['tagname'],
110 'value': sliver_attribute['value']})
112 # set nodegroup slice attributes
113 for slice_tag in filter(lambda a: a['nodegroup_id'] in node['nodegroup_ids'], slice_tags):
114 # Do not set any nodegroup slice attributes for
115 # which there is at least one sliver attribute
117 if slice_tag not in slice_tags:
118 attributes.append({'tagname': slice_tag['tagname'],
119 'value': slice_tag['value']})
121 for slice_tag in filter(lambda a: a['node_id'] is None, slice_tags):
122 # Do not set any global slice attributes for
123 # which there is at least one sliver attribute
125 if slice_tag['tagname'] not in sliver_attributes:
126 attributes.append({'tagname': slice_tag['tagname'],
127 'value': slice_tag['value']})
129 # XXX Sanity check; though technically this should be a system invariant
130 # checked with an assertion
131 if slice['expires'] > MAXINT: slice['expires']= MAXINT
135 'name': slice['name'],
136 'slice_id': slice['slice_id'],
137 'instantiation': slice['instantiation'],
138 'expires': slice['expires'],
140 'attributes': attributes
145 def get_peer(self, hrn):
146 # Becaues of myplc federation, we first need to determine if this
147 # slice belongs to out local plc or a myplc peer. We will assume it
148 # is a local site, unless we find out otherwise
151 # get this slice's authority (site)
152 slice_authority = get_authority(hrn)
154 # get this site's authority (sfa root authority or sub authority)
155 site_authority = get_authority(slice_authority).lower()
157 # check if we are already peered with this site_authority, if so
158 peers = self.api.plshell.GetPeers(self.api.plauth, {}, ['peer_id', 'peername', 'shortname', 'hrn_root'])
159 for peer_record in peers:
160 names = [name.lower() for name in peer_record.values() if isinstance(name, StringTypes)]
161 if site_authority in names:
162 peer = peer_record['shortname']
166 def get_sfa_peer(self, hrn):
167 # return the authority for this hrn or None if we are the authority
169 slice_authority = get_authority(hrn)
170 site_authority = get_authority(slice_authority)
172 if site_authority != self.api.hrn:
173 sfa_peer = site_authority
179 Update the cached list of slices
181 # Reload components list
182 now = datetime.datetime.now()
183 if not self.has_key('threshold') or not self.has_key('timestamp') or \
184 now > datetime.datetime.fromtimestamp(time.mktime(time.strptime(self['threshold'], self.api.time_format))):
185 if self.api.interface in ['aggregate']:
186 self.refresh_slices_aggregate()
187 elif self.api.interface in ['slicemgr']:
188 self.refresh_slices_smgr()
190 def refresh_slices_aggregate(self):
191 slices = self.api.plshell.GetSlices(self.api.plauth, {'peer_id': None}, ['name'])
192 slice_hrns = [slicename_to_hrn(self.api.hrn, slice['name']) for slice in slices]
194 # update timestamp and threshold
195 timestamp = datetime.datetime.now()
196 hr_timestamp = timestamp.strftime(self.api.time_format)
197 delta = datetime.timedelta(hours=self.ttl)
198 threshold = timestamp + delta
199 hr_threshold = threshold.strftime(self.api.time_format)
201 slice_details = {'hrn': slice_hrns,
202 'timestamp': hr_timestamp,
203 'threshold': hr_threshold
205 self.update(slice_details)
209 def refresh_slices_smgr(self):
211 aggregates = Aggregates(self.api)
212 credential = self.api.getCredential()
213 for aggregate in aggregates:
215 # request hash is optional so lets try the call without it
218 slices = aggregates[aggregate].get_slices(credential, request_hash)
219 slice_hrns.extend(slices)
222 print >> log, "%s" % (traceback.format_exc())
223 print >> log, "Error calling slices at aggregate %(aggregate)s" % locals()
225 # try sending the request hash if the previous call failed
227 arg_list = [credential]
228 request_hash = self.api.key.compute_hash(arg_list)
230 slices = aggregates[aggregate].get_slices(credential, request_hash)
231 slice_hrns.extend(slices)
234 print >> log, "%s" % (traceback.format_exc())
235 print >> log, "Error calling slices at aggregate %(aggregate)s" % locals()
237 # update timestamp and threshold
238 timestamp = datetime.datetime.now()
239 hr_timestamp = timestamp.strftime(self.api.time_format)
240 delta = datetime.timedelta(hours=self.ttl)
241 threshold = timestamp + delta
242 hr_threshold = threshold.strftime(self.api.time_format)
244 slice_details = {'hrn': slice_hrns,
245 'timestamp': hr_timestamp,
246 'threshold': hr_threshold
248 self.update(slice_details)
252 def delete_slice(self, hrn):
253 if self.api.interface in ['aggregate']:
254 self.delete_slice_aggregate(hrn)
255 elif self.api.interface in ['slicemgr']:
256 self.delete_slice_smgr(hrn)
258 def delete_slice_aggregate(self, hrn):
260 slicename = hrn_to_pl_slicename(hrn)
261 slices = self.api.plshell.GetSlices(self.api.plauth, {'name': slicename})
266 # determine if this is a peer slice
267 peer = self.get_peer(hrn)
269 self.api.plshell.UnBindObjectFromPeer(self.api.plauth, 'slice', slice['slice_id'], peer)
270 self.api.plshell.DeleteSliceFromNodes(self.api.plauth, slicename, slice['node_ids'])
272 self.api.plshell.BindObjectToPeer(self.api.plauth, 'slice', slice['slice_id'], peer, slice['peer_slice_id'])
275 def delete_slice_smgr(self, hrn):
276 credential = self.api.getCredential()
277 origin_hrn = self.origin_hrn
278 aggregates = Aggregates(self.api)
279 for aggregate in aggregates:
281 # request hash is optional so lets try the call without it
284 aggregates[aggregate].delete_slice(credential, hrn, request_hash, origin_hrn)
287 print >> log, "%s" % (traceback.format_exc())
288 print >> log, "Error calling list nodes at aggregate %s" % aggregate
290 # try sending the request hash if the previous call failed
293 arg_list = [credential, hrn]
294 request_hash = self.api.key.compute_hash(arg_list)
295 aggregates[aggregate].delete_slice(credential, hrn, request_hash, origin_hrn)
298 print >> log, "%s" % (traceback.format_exc())
299 print >> log, "Error calling list nodes at aggregate %s" % aggregate
301 def create_slice(self, hrn, rspec):
303 # check our slice policy before we procede
304 whitelist = self.policy['slice_whitelist']
305 blacklist = self.policy['slice_blacklist']
307 if whitelist and hrn not in whitelist or \
308 blacklist and hrn in blacklist:
309 policy_file = self.policy.policy_file
310 print >> log, "Slice %(hrn)s not allowed by policy %(policy_file)s" % locals()
313 if self.api.interface in ['aggregate']:
314 self.create_slice_aggregate(hrn, rspec)
315 elif self.api.interface in ['slicemgr']:
316 self.create_slice_smgr(hrn, rspec)
318 def verify_site(self, registry, credential, slice_hrn, peer, sfa_peer):
319 authority = get_authority(slice_hrn)
321 site_records = registry.resolve(credential, authority)
323 arg_list = [credential, authority]
324 request_hash = self.api.key.compute_hash(arg_list)
325 site_records = registry.resolve(credential, authority, request_hash)
328 for site_record in site_records:
329 if site_record['type'] == 'authority':
332 raise RecordNotFound(authority)
333 remote_site_id = site.pop('site_id')
335 login_base = get_leaf(authority)
336 sites = self.api.plshell.GetSites(self.api.plauth, login_base)
338 site_id = self.api.plshell.AddSite(self.api.plauth, site)
340 self.api.plshell.BindObjectToPeer(self.api.plauth, 'site', site_id, peer, remote_site_id)
341 # mark this site as an sfa peer record
343 peer_dict = {'type': 'authority', 'hrn': authority, 'peer_authority': sfa_peer, 'pointer': site_id}
345 registry.register_peer_object(credential, peer_dict)
347 arg_list = [credential]
348 request_hash = self.api.key.compute_hash(arg_list)
349 registry.register_peer_object(credential, peer_dict, request_hash)
351 site_id = sites[0]['site_id']
352 remote_site_id = sites[0]['peer_site_id']
355 return (site_id, remote_site_id)
357 def verify_slice(self, registry, credential, slice_hrn, site_id, remote_site_id, peer, sfa_peer):
360 authority = get_authority(slice_hrn)
362 slice_records = registry.resolve(credential, slice_hrn)
364 arg_list = [credential, slice_hrn]
365 request_hash = self.api.key.compute_hash(arg_list)
366 slice_records = registry.resolve(credential, slice_hrn, request_hash)
368 for record in slice_records:
369 if record['type'] in ['slice']:
370 slice_record = record
372 raise RecordNotFound(hrn)
373 slicename = hrn_to_pl_slicename(slice_hrn)
374 parts = slicename.split("_")
375 login_base = parts[0]
376 slices = self.api.plshell.GetSlices(self.api.plauth, [slicename])
379 slice_keys = ['name', 'url', 'description']
380 for key in slice_keys:
381 if key in slice_record and slice_record[key]:
382 slice_fields[key] = slice_record[key]
385 slice_id = self.api.plshell.AddSlice(self.api.plauth, slice_fields)
387 slice['slice_id'] = slice_id
389 # mark this slice as an sfa peer record
391 peer_dict = {'type': 'slice', 'hrn': slice_hrn, 'peer_authority': sfa_peer, 'pointer': slice_id}
393 registry.register_peer_object(credential, peer_dict)
395 arg_list = [credential]
396 request_hash = self.api.key.compute_hash(arg_list)
397 registry.register_peer_object(credential, peer_dict, request_hash)
399 #this belongs to a peer
401 self.api.plshell.BindObjectToPeer(self.api.plauth, 'slice', slice_id, peer, slice_record['pointer'])
402 slice['node_ids'] = []
405 slice_id = slice['slice_id']
406 site_id = slice['site_id']
407 #the slice is alredy on the remote agg. Let us update(e.g. expires field) it with the latest info.
408 self.sync_slice(slice, slice_record, peer)
410 slice['peer_slice_id'] = slice_record['pointer']
411 self.verify_persons(registry, credential, slice_record, site_id, remote_site_id, peer, sfa_peer)
415 def verify_persons(self, registry, credential, slice_record, site_id, remote_site_id, peer, sfa_peer):
416 # get the list of valid slice users from the registry and make
417 # sure they are added to the slice
418 slicename = hrn_to_pl_slicename(slice_record['hrn'])
419 researchers = slice_record.get('researcher', [])
420 for researcher in researchers:
423 person_records = registry.resolve(credential, researcher)
425 arg_list = [credential, researcher]
426 request_hash = self.api.key.compute_hash(arg_list)
427 person_records = registry.resolve(credential, researcher, request_hash)
428 for record in person_records:
429 if record['type'] in ['user']:
430 person_record = record
431 if not person_record:
433 person_dict = person_record
436 peer_id = self.api.plshell.GetPeers(self.api.plauth, {'shortname': peer}, ['peer_id'])[0]['peer_id']
437 persons = self.api.plshell.GetPersons(self.api.plauth, {'email': [person_dict['email']], 'peer_id': peer_id}, ['person_id', 'key_ids'])
439 persons = self.api.plshell.GetPersons(self.api.plauth, [person_dict['email']], ['person_id', 'key_ids'])
444 persons = self.api.plshell.GetPersons(self.api.plauth, [person_dict['email']], ['person_id', 'key_ids'])
447 person_id=self.api.plshell.AddPerson(self.api.plauth, person_dict)
448 self.api.plshell.UpdatePerson(self.api.plauth, person_id, {'enabled' : True})
450 # mark this person as an sfa peer record
452 peer_dict = {'type': 'user', 'hrn': researcher, 'peer_authority': sfa_peer, 'pointer': person_id}
454 registry.register_peer_object(credential, peer_dict)
456 arg_list = [credential]
457 request_hash = self.api.key.compute_hash(arg_list)
458 registry.register_peer_object(credential, peer_dict, request_hash)
461 self.api.plshell.BindObjectToPeer(self.api.plauth, 'person', person_id, peer, person_dict['pointer'])
464 person_id = persons[0]['person_id']
465 key_ids = persons[0]['key_ids']
468 # if this is a peer person, we must unbind them from the peer or PLCAPI will throw
471 self.api.plshell.UnBindObjectFromPeer(self.api.plauth, 'person', person_id, peer)
472 self.api.plshell.UnBindObjectFromPeer(self.api.plauth, 'site', site_id, peer)
474 self.api.plshell.AddPersonToSlice(self.api.plauth, person_dict['email'], slicename)
475 self.api.plshell.AddPersonToSite(self.api.plauth, person_dict['email'], site_id)
476 if peer and not local_person:
477 self.api.plshell.BindObjectToPeer(self.api.plauth, 'person', person_id, peer, person_dict['pointer'])
479 self.api.plshell.BindObjectToPeer(self.api.plauth, 'site', site_id, peer, remote_site_id)
481 self.verify_keys(registry, credential, person_dict, key_ids, person_id, peer, local_person)
483 def verify_keys(self, registry, credential, person_dict, key_ids, person_id, peer, local_person):
484 keylist = self.api.plshell.GetKeys(self.api.plauth, key_ids, ['key'])
485 keys = [key['key'] for key in keylist]
487 #add keys that arent already there
488 key_ids = person_dict['key_ids']
489 for personkey in person_dict['keys']:
490 if personkey not in keys:
491 key = {'key_type': 'ssh', 'key': personkey}
493 self.api.plshell.UnBindObjectFromPeer(self.api.plauth, 'person', person_id, peer)
494 key_id = self.api.plshell.AddPersonKey(self.api.plauth, person_dict['email'], key)
495 if peer and not local_person:
496 self.api.plshell.BindObjectToPeer(self.api.plauth, 'person', person_id, peer, person_dict['pointer'])
498 try: self.api.plshell.BindObjectToPeer(self.api.plauth, 'key', key_id, peer, key_ids.pop(0))
502 def create_slice_aggregate(self, hrn, rspec):
504 # Determine if this is a peer slice
505 peer = self.get_peer(hrn)
506 sfa_peer = self.get_sfa_peer(hrn)
509 # Get the slice record from sfa
510 slicename = hrn_to_pl_slicename(hrn)
513 registries = Registries(self.api)
514 registry = registries[self.api.hrn]
515 credential = self.api.getCredential()
517 site_id, remote_site_id = self.verify_site(registry, credential, hrn, peer, sfa_peer)
518 slice = self.verify_slice(registry, credential, hrn, site_id, remote_site_id, peer, sfa_peer)
520 # find out where this slice is currently running
521 nodelist = self.api.plshell.GetNodes(self.api.plauth, slice['node_ids'], ['hostname'])
522 hostnames = [node['hostname'] for node in nodelist]
524 # get netspec details
525 nodespecs = spec.getDictsByTagName('NodeSpec')
527 # dict in which to store slice attributes to set for the nodes
529 for nodespec in nodespecs:
530 if isinstance(nodespec['name'], list):
531 for nodename in nodespec['name']:
533 for k in nodespec.keys():
534 rspec_attribute_value = nodespec[k]
535 if (self.rspec_to_slice_tag.has_key(k)):
536 slice_tag_name = self.rspec_to_slice_tag[k]
537 nodes[nodename][slice_tag_name] = rspec_attribute_value
538 elif isinstance(nodespec['name'], StringTypes):
539 nodename = nodespec['name']
541 for k in nodespec.keys():
542 rspec_attribute_value = nodespec[k]
543 if (self.rspec_to_slice_tag.has_key(k)):
544 slice_tag_name = self.rspec_to_slice_tag[k]
545 nodes[nodename][slice_tag_name] = rspec_attribute_value
547 for k in nodespec.keys():
548 rspec_attribute_value = nodespec[k]
549 if (self.rspec_to_slice_tag.has_key(k)):
550 slice_tag_name = self.rspec_to_slice_tag[k]
551 nodes[nodename][slice_tag_name] = rspec_attribute_value
553 node_names = nodes.keys()
554 # remove nodes not in rspec
555 deleted_nodes = list(set(hostnames).difference(node_names))
556 # add nodes from rspec
557 added_nodes = list(set(node_names).difference(hostnames))
560 self.api.plshell.UnBindObjectFromPeer(self.api.plauth, 'slice', slice['slice_id'], peer)
562 self.api.plshell.AddSliceToNodes(self.api.plauth, slicename, added_nodes)
564 # Add recognized slice tags
565 for node_name in node_names:
566 node = nodes[node_name]
567 for slice_tag in node.keys():
568 value = node[slice_tag]
569 if (isinstance(value, list)):
572 self.api.plshell.AddSliceTag(self.api.plauth, slicename, slice_tag, value, node_name)
574 self.api.plshell.DeleteSliceFromNodes(self.api.plauth, slicename, deleted_nodes)
576 self.api.plshell.BindObjectToPeer(self.api.plauth, 'slice', slice['slice_id'], peer, slice['peer_slice_id'])
580 def create_slice_smgr(self, hrn, rspec):
583 spec.parseString(rspec)
584 slicename = hrn_to_pl_slicename(hrn)
585 specDict = spec.toDict()
586 if specDict.has_key('RSpec'): specDict = specDict['RSpec']
587 if specDict.has_key('start_time'): start_time = specDict['start_time']
589 if specDict.has_key('end_time'): end_time = specDict['end_time']
593 aggregates = Aggregates(self.api)
594 credential = self.api.getCredential()
596 # split the netspecs into individual rspecs
597 netspecs = spec.getDictsByTagName('NetSpec')
598 for netspec in netspecs:
599 net_hrn = netspec['name']
600 resources = {'start_time': start_time, 'end_time': end_time, 'networks': netspec}
601 resourceDict = {'RSpec': resources}
602 tempspec.parseDict(resourceDict)
603 rspecs[net_hrn] = tempspec.toxml()
605 # send each rspec to the appropriate aggregate/sm
606 origin_hrn = self.origin_hrn
607 for net_hrn in rspecs:
609 # if we are directly connected to the aggregate then we can just send them the rspec
610 # if not, then we may be connected to an sm thats connected to the aggregate
611 if net_hrn in aggregates:
612 # send the whloe rspec to the local aggregate
613 if net_hrn in [self.api.hrn]:
616 aggregates[net_hrn].create_slice(credential, hrn, rspec, request_hash, origin_hrn)
618 arg_list = [credential,hrn,rspec]
619 request_hash = self.api.key.compute_hash(arg_list)
620 aggregates[net_hrn].create_slice(credential, hrn, rspec, request_hash, origin_hrn)
624 aggregates[net_hrn].create_slice(credential, hrn, rspecs[net_hrn], request_hash, origin_hrn)
626 arg_list = [credential,hrn,rspecs[net_hrn]]
627 request_hash = self.api.key.compute_hash(arg_list)
628 aggregates[net_hrn].create_slice(credential, hrn, rspecs[net_hrn], request_hash, origin_hrn)
630 # lets forward this rspec to a sm that knows about the network
631 arg_list = [credential, net_hrn]
632 request_hash = self.api.compute_hash(arg_list)
633 for aggregate in aggregates:
635 network_found = aggregates[aggregate].get_aggregates(credential, net_hrn)
637 network_found = aggregates[aggregate].get_aggregates(credential, net_hrn, request_hash)
641 aggregates[aggregate].create_slice(credential, hrn, rspecs[net_hrn], request_hash, origin_hrn)
643 arg_list = [credential, hrn, rspecs[net_hrn]]
644 request_hash = self.api.key.compute_hash(arg_list)
645 aggregates[aggregate].create_slice(credential, hrn, rspecs[net_hrn], request_hash, origin_hrn)
648 print >> log, "Error creating slice %(hrn)s at aggregate %(net_hrn)s" % locals()
649 traceback.print_exc()
653 def start_slice(self, hrn):
654 if self.api.interface in ['aggregate']:
655 self.start_slice_aggregate(hrn)
656 elif self.api.interface in ['slicemgr']:
657 self.start_slice_smgr(hrn)
659 def start_slice_aggregate(self, hrn):
660 slicename = hrn_to_pl_slicename(hrn)
661 slices = self.api.plshell.GetSlices(self.api.plauth, {'name': slicename}, ['slice_id'])
663 raise RecordNotFound(hrn)
665 attributes = self.api.plshell.GetSliceAttributes(self.api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
666 attribute_id = attreibutes[0]['slice_attribute_id']
667 self.api.plshell.UpdateSliceAttribute(self.api.plauth, attribute_id, "1" )
670 def start_slice_smgr(self, hrn):
671 credential = self.api.getCredential()
672 aggregates = Aggregates(self.api)
673 for aggregate in aggregates:
674 aggregates[aggregate].start_slice(credential, hrn)
678 def stop_slice(self, hrn):
679 if self.api.interface in ['aggregate']:
680 self.stop_slice_aggregate(hrn)
681 elif self.api.interface in ['slicemgr']:
682 self.stop_slice_smgr(hrn)
684 def stop_slice_aggregate(self, hrn):
685 slicename = hrn_to_pl_slicename(hrn)
686 slices = self.api.plshell.GetSlices(self.api.plauth, {'name': slicename}, ['slice_id'])
688 raise RecordNotFound(hrn)
689 slice_id = slices[0]['slice_id']
690 attributes = self.api.plshell.GetSliceAttributes(self.api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
691 attribute_id = attributes[0]['slice_attribute_id']
692 self.api.plshell.UpdateSliceAttribute(self.api.plauth, attribute_id, "0")
695 def stop_slice_smgr(self, hrn):
696 credential = self.api.getCredential()
697 aggregates = Aggregates(self.api)
698 arg_list = [credential, hrn]
699 request_hash = self.api.key.compute_hash(arg_list)
700 for aggregate in aggregates:
702 aggregates[aggregate].stop_slice(credential, hrn)
704 aggregates[aggregate].stop_slice(credential, hrn, request_hash)
706 def sync_slice(self, old_record, new_record, peer):
707 if old_record['expires'] != new_record['expires']:
709 self.api.plshell.UnBindObjectFromPeer(self.api.plauth, 'slice', old_record['slice_id'], peer)
710 self.api.plshell.UpdateSlice(self.api.plauth, old_record['slice_id'], {'expires' : new_record['expires']})
712 self.api.plshell.BindObjectToPeer(self.api.plauth, 'slice', old_record['slice_id'], peer, old_record['peer_slice_id'])