import subprocess
from datetime import datetime
-from time import gmtime
from sfa.util.faults import SliverDoesNotExist, UnknownSfaType
from sfa.util.sfalogging import logger
from sfa.rspecs.version_manager import VersionManager
from sfa.rspecs.rspec import RSpec
-from sfa.util.xrn import hrn_to_urn, urn_to_sliver_id, get_leaf
+from sfa.util.xrn import hrn_to_urn
## thierry: everything that is API-related (i.e. handling incoming requests)
# GetNodes or GetSites sorts of calls directly
# and thus minimize the differences in the managers with the pl version
class SlabDriver(Driver):
-
+ """ Senslab Driver class inherited from Driver generic class.
+
+ Contains methods compliant with the SFA standard and the testbed
+ infrastructure (calls to LDAP and OAR).
+ """
def __init__(self, config):
Driver.__init__ (self, config)
self.config = config
self.hrn = config.SFA_INTERFACE_HRN
-
self.root_auth = config.SFA_REGISTRY_ROOT_AUTH
-
self.oar = OARrestapi()
self.ldap = LDAPapi()
self.time_format = "%Y-%m-%d %H:%M:%S"
- self.db = SlabDB(config,debug = True)
+ self.db = SlabDB(config, debug = True)
self.cache = None
"""
#First get the slice with the slice hrn
- sl = self.GetSlices(slice_filter = slice_hrn, \
+ slice_list = self.GetSlices(slice_filter = slice_hrn, \
slice_filter_type = 'slice_hrn')
- if len(sl) is 0:
+ if len(slice_list) is 0:
raise SliverDoesNotExist("%s slice_hrn" % (slice_hrn))
- if isinstance(sl,list):
- sl = sl[0]
-
-
- top_level_status = 'unknown'
- nodes_in_slice = sl['node_ids']
+ #Slice has the same slice hrn for each slice in the slice/lease list
+ #So fetch the info on the user once
+ one_slice = slice_list[0]
recuser = dbsession.query(RegRecord).filter_by(record_id = \
- sl['record_id_user']).first()
- sl.update({'user':recuser.hrn})
- if len(nodes_in_slice) is 0:
- raise SliverDoesNotExist("No slivers allocated ")
- else:
- top_level_status = 'ready'
+ one_slice['record_id_user']).first()
- logger.debug("Slabdriver - sliver_status Sliver status urn %s hrn %s sl\
- %s \r\n " %(slice_urn, slice_hrn, sl))
-
- if sl['oar_job_id'] is not []:
- #A job is running on Senslab for this slice
- # report about the local nodes that are in the slice only
-
- nodes_all = self.GetNodes({'hostname':nodes_in_slice},
- ['node_id', 'hostname','site','boot_state'])
- nodeall_byhostname = dict([(n['hostname'], n) for n in nodes_all])
+ #Make a list of all the nodes hostnames in use for this slice
+ slice_nodes_list = []
+ for sl in slice_list:
+ for node in sl['node_ids']:
+ slice_nodes_list.append(node['hostname'])
+ #Get all the corresponding nodes details
+ nodes_all = self.GetNodes({'hostname':slice_nodes_list},
+ ['node_id', 'hostname','site','boot_state'])
+ nodeall_byhostname = dict([(n['hostname'], n) for n in nodes_all])
+
+
+
+ for sl in slice_list:
+ #For compatibility
+ top_level_status = 'empty'
result = {}
+ result.fromkeys(['geni_urn','pl_login','geni_status','geni_resources'],None)
+ result['pl_login'] = recuser.hrn
+ logger.debug("Slabdriver - sliver_status Sliver status urn %s hrn %s sl\
+ %s \r\n " %(slice_urn, slice_hrn, sl))
+ try:
+ nodes_in_slice = sl['node_ids']
+ except KeyError:
+ #No job in the slice
+ result['geni_status'] = top_level_status
+ result['geni_resources'] = []
+ return result
+
+ top_level_status = 'ready'
+
+ #A job is running on Senslab for this slice
+ # report about the local nodes that are in the slice only
+
result['geni_urn'] = slice_urn
- result['pl_login'] = sl['user'] #For compatibility
+
#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)))
+ #gmtime(float(timestamp)))
resources = []
- for node in nodeall_byhostname:
+ for node in sl['node_ids']:
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_hostname'] = node['hostname']
+ res['pl_boot_state'] = nodeall_byhostname[node['hostname']]['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'])
+ sliver_id = Xrn(slice_urn, type='slice', \
+ id=nodeall_byhostname[node['hostname']]['node_id'], \
+ authority=self.hrn).urn
+
res['geni_urn'] = sliver_id
- if nodeall_byhostname[node]['boot_state'] == 'Alive':
+ if nodeall_byhostname[node['hostname']]['boot_state'] == 'Alive':
res['geni_status'] = 'ready'
else:
result['geni_status'] = top_level_status
result['geni_resources'] = resources
logger.debug("SLABDRIVER \tsliver_statusresources %s res %s "\
- %(resources,res))
+ %(resources,res))
return result
-
+
def create_sliver (self, slice_urn, slice_hrn, creds, rspec_string, \
users, options):
return slice_urns
- #No site or node register supported
+
def register (self, sfa_record, hrn, pub_key):
- record_type = sfa_record['type']
- slab_record = self.sfa_fields_to_slab_fields(record_type, hrn, \
- sfa_record)
-
-
- if record_type == 'slice':
- acceptable_fields = ['url', 'instantiation', 'name', 'description']
- for key in slab_record.keys():
- if key not in acceptable_fields:
- slab_record.pop(key)
- logger.debug("SLABDRIVER.PY register")
- slices = self.GetSlices(slice_filter =slab_record['hrn'], \
- slice_filter_type = 'slice_hrn')
- if not slices:
- pointer = self.AddSlice(slab_record)
- else:
- pointer = slices[0]['slice_id']
-
- elif record_type == 'user':
- persons = self.GetPersons([sfa_record])
- #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']})
-
- #TODO register Change this AddPersonToSite stuff 05/07/2012 SA
- # add this person to the site only if
- # she is being added for the first
- # time by sfa and doesnt 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?
- #TODO : DElete this AddRoleToPerson 04/07/2012 SA
- #Function prototype is :
- #AddRoleToPerson(self, auth, role_id_or_name, person_id_or_email)
- #what's the pointer doing here?
- 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
+ """
+ Adding new user, slice, node or site should not be handled
+ by SFA.
+
+ Adding nodes = OAR
+ Adding users = LDAP Senslab
+ Adding slice = Import from LDAP users
+ Adding site = OAR
+ """
+ return -1
#No site or node record update allowed
def update (self, old_sfa_record, new_sfa_record, hrn, new_key):
reqdict['method'] = "delete"
reqdict['strval'] = str(job_id)
- self.db.delete_job(slice_hrn, job_id)
+
answer = self.oar.POSTRequestToOARRestAPI('DELETE_jobs_id', \
reqdict,username)
logger.debug("SLABDRIVER \tDeleteJobs jobid %s \r\n answer %s \
#One slice can have multiple jobs
leases_list = self.GetReservedNodes(username = login)
+ #If no job is running or no job scheduled
+ if leases_list == [] :
+ return [fixed_slicerec_dict]
#Several jobs for one slice
-
for lease in leases_list :
slicerec_dict = {}
if jobid :
logger.debug("SLABDRIVER \tLaunchExperimentOnOAR jobid %s \
added_nodes %s slice_user %s" %(jobid, added_nodes, slice_user))
- self.db.add_job( slice_name, jobid, added_nodes)
+
__configure_experiment(jobid, added_nodes)
__launch_senslab_experiment(jobid)
record.update({'PI':[recuser.hrn],
'researcher': [recuser.hrn],
'name':record['hrn'],
- 'oar_job_id':[rec['oar_job_id'] for rec in recslice_list],
+ 'oar_job_id':[],
'node_ids': [],
'person_ids':[recslice_list[0]['record_id_user']],
'geni_urn':'', #For client_helper.py compatibility
'keys':'', #For client_helper.py compatibility
'key_ids':''}) #For client_helper.py compatibility
+
+ try:
+ for rec in recslice_list:
+ record['oar_job_id'].append(rec['oar_job_id'])
+ except KeyError:
+ pass
- #for rec in recslice_list:
- #record['oar_job_id'].append(rec['oar_job_id'])
logger.debug( "SLABDRIVER.PY \t fill_record_info SLICE \
recslice_list %s \r\n \t RECORD %s \r\n \r\n" %(recslice_list,record))
if str(record['type']) == 'user':
'researcher': [recuser.hrn],
'name':record['hrn'],
'node_ids': [],
- 'oar_job_id': [rec['oar_job_id'] for rec in recslice_list],
- 'person_ids':[recslice_list[0]['record_id_user']]})
+ 'oar_job_id': [],
+ 'person_ids':[recslice_list[0]['record_id_user']]})
+ try:
+ for rec in recslice_list:
+ recslice['oar_job_id'].append(rec['oar_job_id'])
+ except KeyError:
+ pass
+
recslice.update({'type':'slice', \
'hrn':recslice_list[0]['slice_hrn']})
- #for rec in recslice_list:
- #recslice['oar_job_id'].append(rec['oar_job_id'])
+
#GetPersons takes [] as filters
#user_slab = self.GetPersons([{'hrn':recuser.hrn}])
return
#TODO AddPerson 04/07/2012 SA
- def AddPerson(self, auth, person_fields=None):
- """Adds a new account. Any fields specified in person_fields are used,
+ #def AddPerson(self, auth, person_fields=None):
+ def AddPerson(self, record):#TODO fixing 28/08//2012 SA
+ """Adds a new account. Any fields specified in records are used,
otherwise defaults are used.
Accounts are disabled by default. To enable an account,
use UpdatePerson().
FROM PLC API DOC
"""
- logger.warning("SLABDRIVER AddPerson EMPTY - DO NOTHING \r\n ")
+ ret = self.ldap.LdapAddUser(record)
+ logger.warning("SLABDRIVER AddPerson return code %s \r\n ", ret)
return
#TODO AddPersonToSite 04/07/2012 SA