+ self.db = SlabDB(config)
+ self.cache=None
+
+
+ def sliver_status(self,slice_urn,slice_hrn):
+ # receive a status request for slice named urn/hrn urn:publicid:IDN+senslab+nturro_slice hrn senslab.nturro_slice
+ # shall return a structure as described in
+ # http://groups.geni.net/geni/wiki/GAPI_AM_API_V2#SliverStatus
+ # NT : not sure if we should implement this or not, but used by sface.
+
+
+ sl = self.GetSlices(slice_filter= slice_hrn, filter_type = 'slice_hrn')
+ if len(sl) is 0:
+ raise SliverDoesNotExist("%s slice_hrn" % (slice_hrn))
+
+ print >>sys.stderr, "\r\n \r\n_____________ Sliver status urn %s hrn %s sl %s \r\n " %(slice_urn,slice_hrn,sl)
+ if sl['oar_job_id'] is not -1:
+
+ # report about the local nodes only
+ nodes_all = self.GetNodes({'hostname':sl['node_ids']},
+ ['node_id', 'hostname','site','boot_state'])
+ nodeall_byhostname = dict([(n['hostname'], n) for n in nodes_all])
+ nodes = sl['node_ids']
+ if len(nodes) is 0:
+ raise SliverDoesNotExist("No slivers allocated ")
+
+
+ result = {}
+ top_level_status = 'unknown'
+ if nodes:
+ top_level_status = 'ready'
+ result['geni_urn'] = slice_urn
+ result['pl_login'] = sl['job_user']
+ #result['slab_login'] = sl['job_user']
+
+ timestamp = float(sl['startTime']) + float(sl['walltime'])
+ result['pl_expires'] = strftime(self.time_format, gmtime(float(timestamp)))
+ #result['slab_expires'] = strftime(self.time_format, gmtime(float(timestamp)))
+
+ resources = []
+ for node in nodes:
+ res = {}
+ #res['slab_hostname'] = node['hostname']
+ #res['slab_boot_state'] = node['boot_state']
+
+ res['pl_hostname'] = nodeall_byhostname[node]['hostname']
+ res['pl_boot_state'] = nodeall_byhostname[node]['boot_state']
+ res['pl_last_contact'] = strftime(self.time_format, gmtime(float(timestamp)))
+ sliver_id = urn_to_sliver_id(slice_urn, sl['record_id_slice'],nodeall_byhostname[node]['node_id'] )
+ res['geni_urn'] = sliver_id
+ if nodeall_byhostname[node]['boot_state'] == 'Alive':
+
+ res['geni_status'] = 'ready'
+ else:
+ res['geni_status'] = 'failed'
+ top_level_status = 'failed'
+
+ res['geni_error'] = ''
+
+ resources.append(res)
+
+ result['geni_status'] = top_level_status
+ result['geni_resources'] = resources
+ print >>sys.stderr, "\r\n \r\n_____________ Sliver status resources %s res %s \r\n " %(resources,res)
+ return result
+
+
+ def create_sliver (self, slice_urn, slice_hrn, creds, rspec_string, users, options):
+ print>>sys.stderr, "\r\n \r\n \t=============================== SLABDRIVER.PY create_sliver "
+ aggregate = SlabAggregate(self)
+
+ slices = SlabSlices(self)
+ peer = slices.get_peer(slice_hrn)
+ sfa_peer = slices.get_sfa_peer(slice_hrn)
+ slice_record=None
+
+ if not isinstance(creds, list):
+ creds = [creds]
+
+ if users:
+ slice_record = users[0].get('slice_record', {})
+
+ # parse rspec
+ rspec = RSpec(rspec_string)
+ print>>sys.stderr, "\r\n \r\n \t=============================== SLABDRIVER.PY create_sliver ============================rspec.version %s " %(rspec.version)
+
+
+ # ensure site record exists?
+ # ensure slice record exists
+ slice = slices.verify_slice(slice_hrn, slice_record, peer, sfa_peer, options=options)
+ requested_attributes = rspec.version.get_slice_attributes()
+
+ if requested_attributes:
+ for attrib_dict in requested_attributes:
+ if 'timeslot' in attrib_dict and attrib_dict['timeslot'] is not None:
+ slice.update({'timeslot':attrib_dict['timeslot']})
+ print >>sys.stderr, "\r\n \r\n \t=============================== SLABDRIVER.PY create_sliver ..... slice %s " %(slice)
+ # ensure person records exists
+ persons = slices.verify_persons(slice_hrn, slice, users, peer, sfa_peer, options=options)
+ # ensure slice attributes exists?
+
+
+ # add/remove slice from nodes
+ print >>sys.stderr, "\r\n \r\n \t=============================== SLABDRIVER.PY create_sliver ..... "
+
+ requested_slivers = [node.get('component_name') for node in rspec.version.get_nodes_with_slivers()]
+ print >>sys.stderr, "\r\n \r\n \t=============================== ........... requested_slivers ============================requested_slivers %s " %(requested_slivers)
+ nodes = slices.verify_slice_nodes(slice, requested_slivers, peer)
+
+
+ return aggregate.get_rspec(slice_xrn=slice_urn, version=rspec.version)
+
+
+ def delete_sliver (self, slice_urn, slice_hrn, creds, options):
+
+ slice = self.GetSlices(slice_filter= slice_hrn, filter_type = 'slice_hrn')
+ print>>sys.stderr, "\r\n \r\n \t\t SLABDRIVER.PY delete_sliver slice %s" %(slice)
+ if not slice:
+ return 1
+
+ slices = SlabSlices(self)
+ # determine if this is a peer slice
+ # xxx I wonder if this would not need to use PlSlices.get_peer instead
+ # in which case plc.peers could be deprecated as this here
+ # is the only/last call to this last method in plc.peers
+ peer = slices.get_peer(slice_hrn)
+ try:
+ if peer:
+ self.UnBindObjectFromPeer('slice', slice['record_id_slice'], peer)
+ self.DeleteSliceFromNodes(slice)
+ finally:
+ if peer:
+ self.BindObjectToPeer('slice', slice['slice_id'], peer, slice['peer_slice_id'])
+ return 1
+
+
+ def AddSlice(self, slice_record):
+ slab_slice = SliceSenslab( slice_hrn = slice_record['slice_hrn'], record_id_slice= slice_record['record_id_slice'] , record_id_user= slice_record['record_id_user'], peer_authority = slice_record['peer_authority'])
+ print>>sys.stderr, "\r\n \r\n \t\t\t =======SLABDRIVER.PY AddSlice slice_record %s slab_slice %s" %(slice_record,slab_slice)
+ slab_dbsession.add(slab_slice)
+ slab_dbsession.commit()
+ return
+
+ # first 2 args are None in case of resource discovery
+ def list_resources (self, slice_urn, slice_hrn, creds, options):
+ #cached_requested = options.get('cached', True)
+
+ version_manager = VersionManager()
+ # get the rspec's return format from options
+ rspec_version = version_manager.get_version(options.get('geni_rspec_version'))
+ version_string = "rspec_%s" % (rspec_version)
+
+ #panos adding the info option to the caching key (can be improved)
+ if options.get('info'):
+ version_string = version_string + "_"+options.get('info', 'default')
+
+ # look in cache first
+ #if cached_requested and self.cache and not slice_hrn:
+ #rspec = self.cache.get(version_string)
+ #if rspec:
+ #logger.debug("SlabDriver.ListResources: returning cached advertisement")
+ #return rspec
+
+ #panos: passing user-defined options
+
+ aggregate = SlabAggregate(self)
+ origin_hrn = Credential(string=creds[0]).get_gid_caller().get_hrn()
+ options.update({'origin_hrn':origin_hrn})
+ rspec = aggregate.get_rspec(slice_xrn=slice_urn, version=rspec_version,
+ options=options)
+ print>>sys.stderr, " \r\n \r\n \t SLABDRIVER list_resources rspec "
+ # cache the result
+ #if self.cache and not slice_hrn:
+ #logger.debug("Slab.ListResources: stores advertisement in cache")
+ #self.cache.add(version_string, rspec)
+
+ return rspec
+
+
+ def list_slices (self, creds, options):
+ # look in cache first
+ #if self.cache:
+ #slices = self.cache.get('slices')
+ #if slices:
+ #logger.debug("PlDriver.list_slices returns from cache")
+ #return slices
+
+ # get data from db
+ print>>sys.stderr, " \r\n \t\t SLABDRIVER.PY list_slices"
+ slices = self.GetSlices()
+ slice_hrns = [slicename_to_hrn(self.hrn, slice['slice_hrn']) for slice in slices]
+ slice_urns = [hrn_to_urn(slice_hrn, 'slice') for slice_hrn in slice_hrns]
+
+ # cache the result
+ #if self.cache:
+ #logger.debug ("SlabDriver.list_slices stores value in cache")
+ #self.cache.add('slices', slice_urns)
+
+ return slice_urns
+
+ #No site or node register supported
+ def register (self, sfa_record, hrn, pub_key):
+ type = sfa_record['type']
+ slab_record = self.sfa_fields_to_slab_fields(type, hrn, sfa_record)
+
+
+ if type == 'slice':
+ acceptable_fields=['url', 'instantiation', 'name', 'description']
+ for key in slab_record.keys():
+ if key not in acceptable_fields:
+ slab_record.pop(key)
+ print>>sys.stderr, " \r\n \t\t SLABDRIVER.PY register"
+ slices = self.GetSlices(slice_filter =slab_record['hrn'], filter_type = 'slice_hrn')
+ if not slices:
+ pointer = self.AddSlice(slab_record)
+ else:
+ pointer = slices[0]['slice_id']
+
+ elif type == 'user':
+ persons = self.GetPersons([sfa_record['hrn']])
+ if not persons:
+ pointer = self.AddPerson(dict(sfa_record))
+ #add in LDAP
+ else:
+ pointer = persons[0]['person_id']
+
+ #Does this make sense to senslab ?
+ #if 'enabled' in sfa_record and sfa_record['enabled']:
+ #self.UpdatePerson(pointer, {'enabled': sfa_record['enabled']})
+
+ # add this person to the site only if she is being added for the first
+ # time by sfa and doesont already exist in plc
+ if not persons or not persons[0]['site_ids']:
+ login_base = get_leaf(sfa_record['authority'])
+ self.AddPersonToSite(pointer, login_base)
+
+ # What roles should this user have?
+ self.AddRoleToPerson('user', pointer)
+ # Add the user's key
+ if pub_key:
+ self.AddPersonKey(pointer, {'key_type' : 'ssh', 'key' : pub_key})
+
+ #No node adding outside OAR
+
+ return pointer
+
+ #No site or node record update allowed
+ def update (self, old_sfa_record, new_sfa_record, hrn, new_key):
+ pointer = old_sfa_record['pointer']
+ type = old_sfa_record['type']
+
+ # new_key implemented for users only
+ if new_key and type not in [ 'user' ]:
+ raise UnknownSfaType(type)
+
+ #if (type == "authority"):
+ #self.shell.UpdateSite(pointer, new_sfa_record)
+
+ if type == "slice":
+ slab_record=self.sfa_fields_to_slab_fields(type, hrn, new_sfa_record)
+ if 'name' in slab_record:
+ slab_record.pop('name')
+ self.UpdateSlice(pointer, slab_record)
+
+ elif type == "user":
+ update_fields = {}
+ all_fields = new_sfa_record
+ for key in all_fields.keys():
+ if key in ['first_name', 'last_name', 'title', 'email',
+ 'password', 'phone', 'url', 'bio', 'accepted_aup',
+ 'enabled']:
+ update_fields[key] = all_fields[key]
+ self.UpdatePerson(pointer, update_fields)
+
+ if new_key:
+ # must check this key against the previous one if it exists
+ persons = self.GetPersons([pointer], ['key_ids'])
+ person = persons[0]
+ keys = person['key_ids']
+ keys = self.GetKeys(person['key_ids'])
+
+ # Delete all stale keys
+ key_exists = False
+ for key in keys:
+ if new_key != key['key']:
+ self.DeleteKey(key['key_id'])
+ else:
+ key_exists = True
+ if not key_exists:
+ self.AddPersonKey(pointer, {'key_type': 'ssh', 'key': new_key})
+
+
+ return True
+
+
+ def remove (self, sfa_record):
+ type=sfa_record['type']
+ hrn=sfa_record['hrn']
+ record_id= sfa_record['record_id']
+ if type == 'user':
+ username = hrn.split(".")[len(hrn.split(".")) -1]
+ #get user in ldap
+ persons = self.GetPersons(username)
+ # only delete this person if he has site ids. if he doesnt, it probably means
+ # he was just removed from a site, not actually deleted
+ if persons and persons[0]['site_ids']:
+ self.DeletePerson(username)
+ elif type == 'slice':
+ if self.GetSlices(slice_filter = hrn, filter_type = 'slice_hrn'):
+ self.DeleteSlice(hrn)
+
+ #elif type == 'authority':
+ #if self.GetSites(pointer):
+ #self.DeleteSite(pointer)
+
+ return True
+
+ def GetPeers (self,auth = None, peer_filter=None, return_fields=None):
+
+ existing_records = {}
+ existing_hrns_by_types= {}
+ print >>sys.stderr, "\r\n \r\n SLABDRIVER GetPeers auth = %s, peer_filter %s, return_field %s " %(auth , peer_filter, return_fields)
+ all_records = dbsession.query(RegRecord).filter(RegRecord.type.like('%authority%')).all()
+ for record in all_records:
+ existing_records[(record.hrn,record.type)] = record
+ if record.type not in existing_hrns_by_types:
+ existing_hrns_by_types[record.type] = [record.hrn]
+ print >>sys.stderr, "\r\n \r\n SLABDRIVER GetPeers \t NOT IN existing_hrns_by_types %s " %( existing_hrns_by_types)
+ else:
+
+ print >>sys.stderr, "\r\n \r\n SLABDRIVER GetPeers \t INNN type %s hrn %s " %( record.type,record.hrn )
+ existing_hrns_by_types[record.type].append(record.hrn)
+ print >>sys.stderr, "\r\n \r\n SLABDRIVER GetPeers \t INNN existing_hrns_by_types %s " %( existing_hrns_by_types)
+ #existing_hrns_by_types.update({record.type:(existing_hrns_by_types[record.type].append(record.hrn))})
+
+ print >>sys.stderr, "\r\n \r\n SLABDRIVER GetPeers existing_hrns_by_types %s " %( existing_hrns_by_types)
+ records_list= []