2 """ driver class management """
4 from sfa.util.sfalogging import logger
5 from sfa.util.xrn import Xrn, urn_to_hrn
6 from sfa.rspecs.version_manager import VersionManager
7 from sfa.rspecs.rspec import RSpec
8 from sfa.managers.driver import Driver
9 from sfa.iotlab.iotlabshell import IotLABShell
10 from sfa.iotlab.iotlabaggregate import IotLABAggregate
11 from sfa.iotlab.iotlablease import LeaseTable
13 class IotLabDriver(Driver):
15 SFA driver for Iot-LAB testbed
18 def __init__(self, api):
19 Driver.__init__(self, api)
22 self.root_auth = config.SFA_REGISTRY_ROOT_AUTH
23 self.shell = IotLABShell()
27 def check_sliver_credentials(self, creds, urns):
28 """ Not used and need by SFA """
31 ########################################
32 ########## registry oriented
33 ########################################
36 def register(self, sfa_record, hrn, pub_key):
37 logger.warning("iotlabdriver register : not implemented")
42 def update(self, old_sfa_record, new_sfa_record, hrn, new_key):
43 logger.warning("iotlabdriver update : not implemented")
48 def remove(self, sfa_record):
49 logger.warning("iotlabdriver remove : not implemented")
53 ########################################
54 ########## aggregate oriented
55 ########################################
57 def provision(self, urns, options=None):
58 logger.warning("iotlabdriver provision : not implemented")
59 version_manager = VersionManager()
60 opt = options['geni_rspec_version']
61 rspec_version = version_manager.get_version(opt)
62 return self.describe(urns, rspec_version, options=options)
65 def delete(self, urns, options=None):
66 logger.warning("iotlabdriver delete : not implemented")
71 def aggregate_version(self):
72 logger.warning("iotlabdriver aggregate_version")
73 version_manager = VersionManager()
74 ad_rspec_versions = []
75 request_rspec_versions = []
76 for rspec_version in version_manager.versions:
77 if rspec_version.content_type in ['*', 'ad']:
78 ad_rspec_versions.append(rspec_version.to_dict())
79 if rspec_version.content_type in ['*', 'request']:
80 request_rspec_versions.append(rspec_version.to_dict())
83 'geni_request_rspec_versions': request_rspec_versions,
84 'geni_ad_rspec_versions': ad_rspec_versions}
87 def list_resources(self, version=None, options=None):
88 logger.warning("iotlabdriver list_resources")
91 aggregate = IotLABAggregate(self)
92 rspec = aggregate.list_resources(version=version, options=options)
96 def describe(self, urns, version, options=None):
97 logger.warning("iotlabdriver describe")
100 aggregate = IotLABAggregate(self)
101 return aggregate.describe(urns, version=version, options=options)
104 def status(self, urns, options=None):
105 logger.warning("iotlabdriver status")
106 aggregate = IotLABAggregate(self)
107 desc = aggregate.describe(urns, version='GENI 3')
108 status = {'geni_urn': desc['geni_urn'],
109 'geni_slivers': desc['geni_slivers']}
113 def _get_users(self):
114 """ Get all users """
115 ret = self.shell.get_users()
121 def _get_user_login(self, caller_user):
122 """ Get user login with email """
123 email = caller_user['email']
124 # ensure user exist in LDAP tree
125 users = self._get_users()
126 if users and not email in users:
127 self.shell.add_user(caller_user)
128 users = self._get_users()
129 if users and email in users:
130 return users[email]['login']
136 def _get_experiment(cls, rspec):
138 Find in RSpec leases the experiment start time, duration and nodes list.
143 <lease slice_id="urn:publicid:IDN+onelab:inria+slice+test_iotlab"
144 start_time="1427792400" duration="30">
146 "urn:publicid:IDN+iotlab+node+m3-10.grenoble.iot-lab.info"/>
148 <lease slice_id="urn:publicid:IDN+onelab:inria+slice+test_iotlab"
149 start_time="1427792600" duration="50">
151 "urn:publicid:IDN+iotlab+node+m3-15.grenoble.iot-lab.info"/>
156 leases = rspec.version.get_leases()
157 start_time = min([int(lease['start_time'])
158 for lease in leases])
159 end_time = max([int(lease['start_time']) +
160 int(lease['duration'])
161 for lease in leases])
162 nodes_list = [Xrn.unescape(Xrn(lease['component_id'].strip(),
163 type='node').get_leaf())
166 nodes_list = list(set(nodes_list))
167 from math import floor
168 duration = floor((end_time - start_time)/60) # minutes
169 return nodes_list, start_time, duration
172 def _save_db_lease(self, job_id, slice_hrn):
173 """ Save lease table row in SFA database """
174 lease_row = LeaseTable(job_id,
176 logger.warning("iotlabdriver _save_db_lease lease row : %s" %
178 self.api.dbsession().add(lease_row)
179 self.api.dbsession().commit()
182 def allocate(self, urn, rspec_string, expiration, options=None):
184 Allocate method submit an experiment on Iot-LAB testbed with :
185 * user : get the slice user which launch request (caller_hrn)
186 * reservation : get the start time and duration in RSpec leases
187 * nodes : get the nodes list in RSpec leases
188 If we have a request success on Iot-LAB testbed we store in SFA
189 database the assocation OAR scheduler job id and slice hrn
191 :param urn : slice urn
192 :param rspec_string : RSpec received
193 :param options : options with slice users (geni_users)
195 # pylint:disable=R0914
197 logger.warning("iotlabdriver allocate")
199 aggregate = IotLABAggregate(self)
201 rspec = RSpec(rspec_string)
203 caller_hrn = options.get('actual_caller_hrn', [])
204 geni_users = options.get('geni_users', [])
205 caller_user = [user for user in geni_users if
206 urn_to_hrn(user['urn'])[0] == caller_hrn][0]
207 logger.warning("iotlabdriver allocate caller : %s" %
208 caller_user['email'])
210 login = self._get_user_login(caller_user)
211 # only if we have a user
213 nodes_list, start_time, duration = \
214 self._get_experiment(rspec)
215 logger.warning("iotlabdriver allocate submit OAR job :"
217 (xrn.hrn, start_time, duration, nodes_list))
218 # [0-9A-Za-z_] with onelab.inria.test_iotlab
219 exp_name = '_'.join((xrn.hrn).split('.'))
221 ret = self.shell.reserve_nodes(login,
227 # in case of job submission success save slice and lease job
228 # id association in database
230 self._save_db_lease(int(ret['id']),
233 return aggregate.describe([xrn.get_urn()], version=rspec.version)