from sfa.rspecs.elements.granularity import Granularity
from sfa.rspecs.version_manager import VersionManager
-from sfa.rspecs.elements.versions.cortexlabv1Node import IotlabPosition, \
+from sfa.rspecs.elements.versions.iotlabv1Node import IotlabPosition, \
IotlabNode, IotlabLocation, IotlabMobility
from sfa.util.sfalogging import logger
is to be consistent with the SFA standard.
"""
+
+
slivers = {}
sfa_slice = None
if slice_xrn is None:
slice_hrn, _ = urn_to_hrn(slice_xrn)
slice_name = slice_hrn
+ # GetSlices always returns a list, even if there is only one element
slices = self.driver.cortexlab_api.GetSlices(slice_filter=str(slice_name),
slice_filter_type='slice_hrn',
login=login)
- logger.debug("CortexlabAggregate api \tget_slice_and_slivers \
+ logger.debug("IotlabAggregate api \tget_slice_and_slivers \
slice_hrn %s \r\n slices %s self.driver.hrn %s"
% (slice_hrn, slices, self.driver.hrn))
-
if slices == []:
return (sfa_slice, slivers)
# sort slivers by node id , if there is a job
#and therefore, node allocated to this slice
- for sfa_slice in slices:
- try:
- node_ids_list = sfa_slice['node_ids']
- except KeyError:
- logger.log_exc("CortexlabAggregate \t \
- get_slice_and_slivers No nodes in the slice \
- - KeyError ")
- node_ids_list = []
- continue
-
- for node in node_ids_list:
- sliver_xrn = Xrn(slice_urn, type='sliver', id=node)
- sliver_xrn.set_authority(self.driver.hrn)
- sliver = Sliver({'sliver_id': sliver_xrn.urn,
- 'name': sfa_slice['hrn'],
- 'type': 'cortexlab-node',
- 'tags': []})
-
- slivers[node] = sliver
+ # for sfa_slice in slices:
+ sfa_slice = slices[0]
+ try:
+ node_ids_list = sfa_slice['node_ids']
+ except KeyError:
+ logger.log_exc("CORTEXLABAGGREGATE \t \
+ get_slice_and_slivers No nodes in the slice \
+ - KeyError ")
+ node_ids_list = []
+ # continue
+
+ for node in node_ids_list:
+ sliver_xrn = Xrn(slice_urn, type='sliver', id=node)
+ sliver_xrn.set_authority(self.driver.hrn)
+ sliver = Sliver({'sliver_id': sliver_xrn.urn,
+ 'name': sfa_slice['hrn'],
+ 'type': 'cortexlab-node',
+ 'tags': []})
+
+ slivers[node] = sliver
#Add default sliver attribute :
- #connection information for cortexlab
- if get_authority(sfa_slice['hrn']) == self.driver.cortexlab_api.root_auth:
- tmp = sfa_slice['hrn'].split('.')
- ldap_username = tmp[1].split('_')[0]
+ #connection information for cortexlab, assuming it is the same ssh
+ # connection process
+ # look in ldap:
+ ldap_username = self.find_ldap_username_from_slice(sfa_slice)
+
+ if ldap_username is not None:
ssh_access = None
slivers['default_sliver'] = {'ssh': ssh_access,
- 'login': ldap_username}
+ 'login': ldap_username}
- #TODO get_slice_and_slivers Find the login of the external user
- logger.debug("CortexlabAggregate api get_slice_and_slivers slivers %s "
+ logger.debug("CORTEXLABAGGREGATE api get_slice_and_slivers slivers %s "
% (slivers))
return (slices, slivers)
+ def find_ldap_username_from_slice(self, sfa_slice):
+ researchers = [sfa_slice['reg_researchers'][0].__dict__]
+ # look in ldap:
+ ldap_username = None
+ ret = self.driver.iotlab_api.GetPersons(researchers)
+ if len(ret) != 0:
+ ldap_username = ret[0]['uid']
+
+ return ldap_username
+
+
+
def get_nodes(self, slices=None, slivers=[], options=None):
"""Returns the nodes in the slice using the rspec format, with all the
nodes' properties.
nodes_dict[node['node_id']] = node
if slice_nodes_list == [] or node['hostname'] in slice_nodes_list:
- rspec_node = IotlabNode()
- # xxx how to retrieve site['login_base']
- #site_id=node['site_id']
- #site=sites_dict[site_id]
+ rspec_node = Node()
+
- # rspec_node['mobile'] = node['mobile']
- rspec_node['archi'] = node['archi']
- rspec_node['radio'] = node['radio']
cortexlab_xrn = cortexlab_xrn_object(self.driver.cortexlab_api.root_auth,
node['hostname'])
# in authority_id SA 27/07/12
rspec_node['authority_id'] = rspec_node['component_manager_id']
- # do not include boot state (<available> element)
- #in the manifest rspec
- rspec_node['boot_state'] = node['boot_state']
- if node['hostname'] in reserved_nodes:
- rspec_node['boot_state'] = "Reserved"
+ # boot state removed if you need it uncomment
+ # rspec_node['boot_state'] = node['boot_state']
+ # if node['hostname'] in reserved_nodes:
+ # rspec_node['boot_state'] = "Reserved"
+
rspec_node['exclusive'] = 'true'
rspec_node['hardware_types'] = [HardwareType({'name':
'cortexlab-node'})]
- location = IotlabLocation({'country':'France', 'site':
- node['site']})
- rspec_node['location'] = location
-
- # Adding mobility of the node in the rspec
- mobility = IotlabMobility()
- for field in mobility:
- try:
- mobility[field] = node[field]
- except KeyError, error:
- logger.log_exc("CortexlabAggregate\t get_nodes \
- mobility %s " % (error))
- rspec_node['mobility'] = mobility
-
- position = IotlabPosition()
- for field in position:
- try:
- position[field] = node[field]
- except KeyError, error:
- logger.log_exc("CortexlabAggregate\t get_nodes \
- position %s " % (error))
-
- rspec_node['position'] = position
- #rspec_node['interfaces'] = []
+ # Location, mobility and position removed. If you need it go check
+ # get_nodes in iotlabaggregate.py
# Granularity
granularity = Granularity({'grain': grain})
#now = int(time.time())
#lease_filter = {'clip': now }
- #if slice_record:
- #lease_filter.update({'name': slice_record['name']})
- #leases = self.driver.cortexlab_api.GetLeases(lease_filter)
logger.debug("CortexlabAggregate get_all_leases ldap_username %s "
% (ldap_username))
for node in lease['reserved_nodes']:
rspec_lease = Lease()
rspec_lease['lease_id'] = lease['lease_id']
- #site = node['site_id']
- cortexlab_xrn = cortexlab_xrn_object(self.driver.cortexlab_api.root_auth,
- node)
+
+ cortexlab_xrn = cortexlab_xrn_object(
+ self.driver.cortexlab_api.root_auth, node)
rspec_lease['component_id'] = cortexlab_xrn.urn
#rspec_lease['component_id'] = hostname_to_urn(self.driver.hrn,\
#site, node['hostname'])
if slice_xrn and slices is not None:
#Get user associated with this slice
#for one_slice in slices :
- ldap_username = slices[0]['reg_researchers'][0].__dict__['hrn']
- # ldap_username = slices[0]['user']
- tmp = ldap_username.split('.')
- ldap_username = tmp[1]
+ ldap_username = self.find_ldap_username_from_slice(slices[0])
+ # ldap_username = slices[0]['reg_researchers'][0].__dict__['hrn']
+ # # ldap_username = slices[0]['user']
+ # tmp = ldap_username.split('.')
+ # ldap_username = tmp[1]
logger.debug("CortexlabAggregate \tget_rspec **** \
LDAP USERNAME %s \r\n" \
% (ldap_username))
from sfa.util.xrn import Xrn, hrn_to_urn, get_authority
-from sfa.iotlab.iotlabaggregate import IotlabAggregate, iotlab_xrn_to_hostname
-from sfa.iotlab.iotlabslices import IotlabSlices
+from sfa.cortexlab.cortexlabaggregate import CortexlabAggregate, \
+ cortexlab_xrn_to_hostname
+from sfa.iotlab.iotlabslices import CortexlabSlices
-from sfa.iotlab.iotlabapi import IotlabTestbedAPI
+from sfa.cortexlab.cortexlabapi import CortexlabTestbedAPI
class CortexlabDriver(Driver):
"""
Driver.__init__(self, config)
self.config = config
- self.iotlab_api = IotlabTestbedAPI(config)
+ self.cortexlab_api = CortexlabTestbedAPI(config)
self.cache = None
def augment_records_with_testbed_info(self, record_list):
"""
- logger.debug("IOTLABDRIVER \tfill_record_info records %s "
+ logger.debug("CORTEXLABDRIVER \tfill_record_info records %s "
% (record_list))
if not isinstance(record_list, list):
record_list = [record_list]
# look for node info using GetNodes
# the record is about one node only
filter_dict = {'hrn': [record['hrn']]}
- node_info = self.iotlab_api.GetNodes(filter_dict)
+ node_info = self.cortexlab_api.GetNodes(filter_dict)
# the node_info is about one node only, but it is formatted
# as a list
record.update(node_info[0])
- logger.debug("IOTLABDRIVER.PY \t \
+ logger.debug("CORTEXLABDRIVER.PY \t \
fill_record_info NODE" % (record))
#If the record is a SFA slice record, then add information
{'PI': [record['reg_researchers']['hrn']],
'researcher': [record['reg_researchers']['hrn']],
'name': record['hrn'],
- 'oar_job_id': [],
+ 'experiment_id': [],
'node_ids': [],
'person_ids': [record['reg_researchers']
['record_id']],
'key_ids': ''})
#Get iotlab slice record and oar job id if any.
- recslice_list = self.iotlab_api.GetSlices(
+ recslice_list = self.cortexlab_api.GetSlices(
slice_filter=str(record['hrn']),
slice_filter_type='slice_hrn')
- logger.debug("IOTLABDRIVER \tfill_record_info \
- TYPE SLICE RECUSER record['hrn'] %s record['oar_job_id']\
- %s " % (record['hrn'], record['oar_job_id']))
+ logger.debug("CORTEXLABDRIVER \tfill_record_info \
+ TYPE SLICE RECUSER record['hrn'] %s record['experiment_id']\
+ %s " % (record['hrn'], record['experiment_id']))
del record['reg_researchers']
try:
for rec in recslice_list:
- logger.debug("IOTLABDRIVER\r\n \t \
- fill_record_info oar_job_id %s "
- % (rec['oar_job_id']))
+ logger.debug("CORTEXLABDRIVER\r\n \t \
+ fill_record_info experiment_id %s "
+ % (rec['experiment_id']))
- record['node_ids'] = [self.iotlab_api.root_auth +
+ record['node_ids'] = [self.cortexlab_api.root_auth +
'.' + hostname for hostname
in rec['node_ids']]
except KeyError:
pass
- logger.debug("IOTLABDRIVER.PY \t fill_record_info SLICE \
+ logger.debug("CORTEXLABDRIVER.PY \t fill_record_info SLICE \
recslice_list %s \r\n \t RECORD %s \r\n \
\r\n" % (recslice_list, record))
#The record is a SFA user record.
#Get the information about his slice from Iotlab's DB
#and add it to the user record.
- recslice_list = self.iotlab_api.GetSlices(
+ recslice_list = self.cortexlab_api.GetSlices(
slice_filter=record['record_id'],
slice_filter_type='record_id_user')
- logger.debug("IOTLABDRIVER.PY \t fill_record_info \
+ logger.debug("CORTEXLABDRIVER.PY \t fill_record_info \
TYPE USER recslice_list %s \r\n \t RECORD %s \r\n"
% (recslice_list, record))
#Append slice record in records list,
#Will update PIs and researcher for the slice
recuser = recslice_list[0]['reg_researchers']
- logger.debug("IOTLABDRIVER.PY \t fill_record_info USER \
+ logger.debug("CORTEXLABDRIVER.PY \t fill_record_info USER \
recuser %s \r\n \r\n" % (recuser))
recslice = {}
recslice = recslice_list[0]
'researcher': [recuser['hrn']],
'name': record['hrn'],
'node_ids': [],
- 'oar_job_id': [],
+ 'experiment_id': [],
'person_ids': [recuser['record_id']]})
try:
for rec in recslice_list:
- recslice['oar_job_id'].append(rec['oar_job_id'])
+ recslice['experiment_id'].append(rec['experiment_id'])
except KeyError:
pass
'hrn': recslice_list[0]['hrn']})
#GetPersons takes [] as filters
- user_iotlab = self.iotlab_api.GetPersons([record])
+ user_cortexlab = self.cortexlab_api.GetPersons([record])
- record.update(user_iotlab[0])
+ record.update(user_cortexlab[0])
#For client_helper.py compatibility
record.update(
{'geni_urn': '',
'key_ids': ''})
record_list.append(recslice)
- logger.debug("IOTLABDRIVER.PY \t \
+ logger.debug("CORTEXLABDRIVER.PY \t \
fill_record_info ADDING SLICE\
INFO TO USER records %s" % (record_list))
except TypeError, error:
- logger.log_exc("IOTLABDRIVER \t fill_record_info EXCEPTION %s"
+ logger.log_exc("CORTEXLABDRIVER \t fill_record_info EXCEPTION %s"
% (error))
return record_list
"""
#First get the slice with the slice hrn
- slice_list = self.iotlab_api.GetSlices(slice_filter=slice_hrn,
+ slice_list = self.cortexlab_api.GetSlices(slice_filter=slice_hrn,
slice_filter_type='slice_hrn')
if len(slice_list) == 0:
slice_nodes_list = []
slice_nodes_list = one_slice['node_ids']
#Get all the corresponding nodes details
- nodes_all = self.iotlab_api.GetNodes(
+ nodes_all = self.cortexlab_api.GetNodes(
{'hostname': slice_nodes_list},
['node_id', 'hostname', 'site', 'boot_state'])
nodeall_byhostname = dict([(one_node['hostname'], one_node)
top_level_status = 'empty'
result = {}
result.fromkeys(
- ['geni_urn', 'geni_error', 'iotlab_login', 'geni_status',
+ ['geni_urn', 'geni_error', 'cortexlab_login', 'geni_status',
'geni_resources'], None)
# result.fromkeys(\
# ['geni_urn','geni_error', 'pl_login','geni_status',
# 'geni_resources'], None)
# result['pl_login'] = one_slice['reg_researchers'][0].hrn
- result['iotlab_login'] = one_slice['user']
+ result['cortexlab_login'] = one_slice['user']
logger.debug("Slabdriver - sliver_status Sliver status \
urn %s hrn %s single_slice %s \r\n "
% (slice_urn, slice_hrn, single_slice))
resources = []
for node_hostname in single_slice['node_ids']:
res = {}
- res['iotlab_hostname'] = node_hostname
- res['iotlab_boot_state'] = \
+ res['cortexlab_hostname'] = node_hostname
+ res['cortexlab_boot_state'] = \
nodeall_byhostname[node_hostname]['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 = Xrn(
slice_urn, type='slice',
id=nodeall_byhostname[node_hostname]['node_id']).urn
result['geni_status'] = top_level_status
result['geni_resources'] = resources
- logger.debug("IOTLABDRIVER \tsliver_statusresources %s res %s "
+ logger.debug("CORTEXLABDRIVER \tsliver_statusresources %s res %s "
% (resources, res))
return result
requested_lease_list = []
for lease in rspec.version.get_leases():
single_requested_lease = {}
- logger.debug("IOTLABDRIVER.PY \t \
+ logger.debug("CORTEXLABDRIVER.PY \t \
_get_requested_leases_list lease %s " % (lease))
if not lease.get('lease_id'):
if get_authority(lease['component_id']) == \
- self.iotlab_api.root_auth:
+ self.cortexlab_api.root_auth:
single_requested_lease['hostname'] = \
- iotlab_xrn_to_hostname(\
+ cortexlab_xrn_to_hostname(\
lease.get('component_id').strip())
single_requested_lease['start_time'] = \
lease.get('start_time')
#the lease to the requested leases list
duration_in_seconds = \
int(single_requested_lease['duration'])
- if duration_in_seconds >= self.iotlab_api.GetMinExperimentDurationInGranularity():
+ if duration_in_seconds >= self.cortexlab_api.GetMinExperimentDurationInGranularity():
requested_lease_list.append(single_requested_lease)
return requested_lease_list
"""
- requested_job_dict = {}
+ requested_xp_dict = {}
for lease in requested_lease_list:
#In case it is an asap experiment start_time is empty
if lease['start_time'] == '':
lease['start_time'] = '0'
- if lease['start_time'] not in requested_job_dict:
+ if lease['start_time'] not in requested_xp_dict:
if isinstance(lease['hostname'], str):
lease['hostname'] = [lease['hostname']]
- requested_job_dict[lease['start_time']] = lease
+ requested_xp_dict[lease['start_time']] = lease
else:
- job_lease = requested_job_dict[lease['start_time']]
+ job_lease = requested_xp_dict[lease['start_time']]
if lease['duration'] == job_lease['duration']:
job_lease['hostname'].append(lease['hostname'])
- return requested_job_dict
+ return requested_xp_dict
- def _process_requested_jobs(self, rspec):
+ def _process_requested_xp_dict(self, rspec):
"""
Turns the requested leases and information into a dictionary
of requested jobs, grouped by starting time.
"""
requested_lease_list = self._get_requested_leases_list(rspec)
- logger.debug("IOTLABDRIVER _process_requested_jobs \
+ logger.debug("CORTEXLABDRIVER _process_requested_xp_dict \
requested_lease_list %s" % (requested_lease_list))
- job_dict = self._group_leases_by_start_time(requested_lease_list)
- logger.debug("IOTLABDRIVER _process_requested_jobs job_dict\
- %s" % (job_dict))
+ xp_dict = self._group_leases_by_start_time(requested_lease_list)
+ logger.debug("CORTEXLABDRIVER _process_requested_xp_dict xp_dict\
+ %s" % (xp_dict))
- return job_dict
+ return xp_dict
def create_sliver(self, slice_urn, slice_hrn, creds, rspec_string,
users, options):
"""
- aggregate = IotlabAggregate(self)
+ aggregate = CortexlabAggregate(self)
- slices = IotlabSlices(self)
+ slices = CortexlabSlices(self)
peer = slices.get_peer(slice_hrn)
sfa_peer = slices.get_sfa_peer(slice_hrn)
slice_record = None
if users:
slice_record = users[0].get('slice_record', {})
- logger.debug("IOTLABDRIVER.PY \t ===============create_sliver \t\
+ logger.debug("CORTEXLABDRIVER.PY \t ===============create_sliver \t\
creds %s \r\n \r\n users %s"
% (creds, users))
slice_record['user'] = {'keys': users[0]['keys'],
'hrn': slice_record['reg-researchers'][0]}
# parse rspec
rspec = RSpec(rspec_string)
- logger.debug("IOTLABDRIVER.PY \t create_sliver \trspec.version \
+ logger.debug("CORTEXLABDRIVER.PY \t create_sliver \trspec.version \
%s slice_record %s users %s"
% (rspec.version, slice_record, users))
#unused, removed SA 13/08/12
#rspec.version.get_slice_attributes()
- logger.debug("IOTLABDRIVER.PY create_sliver slice %s " % (sfa_slice))
+ logger.debug("CORTEXLABDRIVER.PY create_sliver slice %s " % (sfa_slice))
# add/remove slice from nodes
#requested_slivers = [node.get('component_id') \
#for node in rspec.version.get_nodes_with_slivers()\
- #if node.get('authority_id') is self.iotlab_api.root_auth]
+ #if node.get('authority_id') is self.cortexlab_api.root_auth]
#l = [ node for node in rspec.version.get_nodes_with_slivers() ]
#logger.debug("SLADRIVER \tcreate_sliver requested_slivers \
#requested_slivers %s listnodes %s" \
#verify_slice_nodes returns nodes, but unused here. Removed SA 13/08/12.
#slices.verify_slice_nodes(sfa_slice, requested_slivers, peer)
- requested_job_dict = self._process_requested_jobs(rspec)
+ requested_xp_dict = self._process_requested_xp_dict(rspec)
- logger.debug("IOTLABDRIVER.PY \tcreate_sliver requested_job_dict %s "
- % (requested_job_dict))
+ logger.debug("CORTEXLABDRIVER.PY \tcreate_sliver requested_xp_dict %s "
+ % (requested_xp_dict))
#verify_slice_leases returns the leases , but the return value is unused
#here. Removed SA 13/08/12
slices.verify_slice_leases(sfa_slice,
- requested_job_dict, peer)
+ requested_xp_dict, peer)
return aggregate.get_rspec(slice_xrn=slice_urn,
login=sfa_slice['login'],
delete_sliver .
"""
- sfa_slice_list = self.iotlab_api.GetSlices(
+ sfa_slice_list = self.cortexlab_api.GetSlices(
slice_filter=slice_hrn,
slice_filter_type='slice_hrn')
#Delete all leases in the slice
for sfa_slice in sfa_slice_list:
- logger.debug("IOTLABDRIVER.PY delete_sliver slice %s" % (sfa_slice))
- slices = IotlabSlices(self)
+ logger.debug("CORTEXLABDRIVER.PY delete_sliver slice %s" % (sfa_slice))
+ slices = CortexlabSlices(self)
# determine if this is a peer slice
peer = slices.get_peer(slice_hrn)
- logger.debug("IOTLABDRIVER.PY delete_sliver peer %s \
+ logger.debug("CORTEXLABDRIVER.PY delete_sliver peer %s \
\r\n \t sfa_slice %s " % (peer, sfa_slice))
try:
- self.iotlab_api.DeleteSliceFromNodes(sfa_slice)
+ self.cortexlab_api.DeleteSliceFromNodes(sfa_slice)
return True
except:
return False
#return rspec
#panos: passing user-defined options
- aggregate = IotlabAggregate(self)
+ aggregate = CortexlabAggregate(self)
rspec = aggregate.get_rspec(slice_xrn=slice_urn,
version=rspec_version, options=options)
# get data from db
- slices = self.iotlab_api.GetSlices()
- logger.debug("IOTLABDRIVER.PY \tlist_slices hrn %s \r\n \r\n"
+ slices = self.cortexlab_api.GetSlices()
+ logger.debug("CORTEXLABDRIVER.PY \tlist_slices hrn %s \r\n \r\n"
% (slices))
slice_hrns = [iotlab_slice['hrn'] for iotlab_slice in slices]
def update(self, old_sfa_record, new_sfa_record, hrn, new_key):
"""
- No site or node record update allowed in Iotlab. The only modifications
+ No site or node record update allowed in Cortexlab. The only modifications
authorized here are key deletion/addition on an existing user and
password change. On an existing user, CAN NOT BE MODIFIED: 'first_name',
- 'last_name', 'email'. DOES NOT EXIST IN SENSLAB: 'phone', 'url', 'bio',
+ 'last_name', 'email'. DOES NOT EXIST IN LDAP: 'phone', 'url', 'bio',
'title', 'accepted_aup'. A slice is bound to its user, so modifying the
user's ssh key should nmodify the slice's GID after an import procedure.
if new_key:
# must check this key against the previous one if it exists
- persons = self.iotlab_api.GetPersons([old_sfa_record])
+ persons = self.cortexlab_api.GetPersons([old_sfa_record])
person = persons[0]
keys = [person['pkey']]
#Get all the person's keys
- keys_dict = self.iotlab_api.GetKeys(keys)
+ keys_dict = self.cortexlab_api.GetKeys(keys)
# Delete all stale keys, meaning the user has only one key
#at a time
else:
#remove all the other keys
for key in keys_dict:
- self.iotlab_api.DeleteKey(person, key)
- self.iotlab_api.AddPersonKey(
+ self.cortexlab_api.DeleteKey(person, key)
+ self.cortexlab_api.AddPersonKey(
person, {'sshPublicKey': person['pkey']},
{'sshPublicKey': new_key})
return True
if sfa_record_type == 'user':
#get user from iotlab ldap
- person = self.iotlab_api.GetPersons(sfa_record)
+ person = self.cortexlab_api.GetPersons(sfa_record)
#No registering at a given site in Iotlab.
#Once registered to the LDAP, all iotlab sites are
#accesible.
if person:
#Mark account as disabled in ldap
- return self.iotlab_api.DeletePerson(sfa_record)
+ return self.cortexlab_api.DeletePerson(sfa_record)
elif sfa_record_type == 'slice':
- if self.iotlab_api.GetSlices(slice_filter=hrn,
+ if self.cortexlab_api.GetSlices(slice_filter=hrn,
slice_filter_type='slice_hrn'):
- ret = self.iotlab_api.DeleteSlice(sfa_record)
+ ret = self.cortexlab_api.DeleteSlice(sfa_record)
return True