def release_resources(username, experiment_id): experiments_to_delete = find_by_element_value(entities.Experiment, entities.Experiment.id, experiment_id) if len(experiments_to_delete) == 0: logger.error("No experiment to be deleted....") raise ExperimentNotFound("No experiment to be deleted....") experiment_to_delete = experiments_to_delete[0] _release_all_experiment_resources(experiment_to_delete, username) logger.info("deleting %s" % experiment_to_delete.name) delete(experiment_to_delete)
def refresh_resources(username, manager_name=None): managers = [] if manager_name is None: for man in find(ManagerEndpoint): managers.append(man.name) else: managers.append(manager_name) user_info = get_user_info(username) result = [] if user_info: for manager in managers: stub = get_stub_from_manager_name(manager) request_message = user_info try: response = stub.refresh_resources(request_message) except _Rendezvous: traceback.print_exc() logger.error( "Exception while calling gRPC, maybe %s Manager is down?" % manager) raise RpcFailedCall( "Exception while calling gRPC, maybe %s Manager is down?" % manager) if response.result != 0: logger.error("list resources returned %d: %s" % (response.result, response.error_message)) raise RpcFailedCall("list resources returned %d: %s" % (response.result, response.error_message)) result.extend(response.list_resource.resources) logger.debug("Saving %d resources" % len(result)) for rm in find(entities.ResourceMetadata): if rm.node_type in REFRESH_RES_NODE_TYPES: delete(rm) for rm in result: resource_metadata = ResourceMetadata() if rm.resource_id and (not hasattr(rm, 'user') or rm.user == username): resource_metadata.id = rm.resource_id resource_metadata.description = rm.description resource_metadata.cardinality = rm.cardinality resource_metadata.node_type = rm.node_type if hasattr(rm, 'user') and rm.user: resource_metadata.user = rm.user else: resource_metadata.user = '' resource_metadata.testbed = list(TESTBED_MAPPING.keys())[list( TESTBED_MAPPING.values()).index(rm.testbed)] save(resource_metadata, ResourceMetadata) return result
def _terminate_expired_resource(res: entities.UsedResource): resource_to_delete = find(entities.UsedResource, _id=res.id) exp_id = resource_to_delete.parent_id if resource_to_delete and res == resource_to_delete: _release_used_resource(res) delete(resource_to_delete) else: logger.debug("The initial experiment was removed") return exp = find(entities.Experiment, _id=exp_id) if not len(exp.resources): delete(exp)
def unregister_endpoint(manager_endpoint_name: str) -> bool: deleted = False for manager_endpoint in find(ManagerEndpoint): if manager_endpoint.name == manager_endpoint_name: for resource_type in get_mapping_managers().get( manager_endpoint.name): for rm in [ rm for rm in find(ResourceMetadata) if rm.node_type.lower() == resource_type.lower() ]: delete(rm) delete(manager_endpoint) deleted = True return deleted
def reserve(self): used_resources = [] for node in self.topology_template.nodetemplates: used_resource = _get_used_resource_from_node(node, self.username) used_resources.append(used_resource) CalendarManager.check_availability_for_node(used_resource) try: CalendarManager.check_overlapping_resources(used_resources) except ExperimentValidationError as e: delete(self.experiment) raise e # all node have been granted for us in self.experiment.resources: us.status = ResourceStatus.RESERVED.value save(self.experiment)
def register(self, request, context): logger.info("registering %s" % request.name) old_managers = find_by_element_value(ManagerEndpoint, ManagerEndpoint.name, request.name) for old_man in old_managers: delete(old_man) logger.debug("Removed old manager endpoint: %s:%s" % (old_man.name, old_man.endpoint)) manager_endpoint = ManagerEndpoint() manager_endpoint.name = request.name manager_endpoint.endpoint = request.endpoint save(manager_endpoint, ManagerEndpoint) list_resources() response_message = messages_pb2.ResponseMessage() response_message.result = 0 return response_message
def list_resources(username='', manager_name=None): managers = [] if manager_name is None: for man in find(ManagerEndpoint): managers.append(man.name) else: managers.append(manager_name) result = [] # List resources can be done in parallel max_workers = len(managers) tpe = ThreadPoolExecutor(max_workers=max_workers) threads = [] for manager in managers: threads.append(tpe.submit(_execute_rpc_list_res, manager)) for t in threads: result.extend(t.result()) logger.debug("Saving %d resources" % len(result)) for rm in find(entities.ResourceMetadata): for rm_to_del in result: if rm.id == rm_to_del.resource_id: delete(rm) for rm in result: if username == '' or rm.user == username: resource_metadata = ResourceMetadata() if not username is None: resource_metadata.user = username resource_metadata.id = rm.resource_id resource_metadata.description = rm.description resource_metadata.cardinality = rm.cardinality resource_metadata.node_type = rm.node_type resource_metadata.testbed = _get_testbed_string(rm.testbed) save(resource_metadata, ResourceMetadata) return result
def delete_user(username): for experimenter in find(Experimenter): if experimenter.username == username: for experiment in find(entities.Experiment): if experiment.username == username: try: release_resources(username, experiment.id) except ExperimentNotFound as e: pass except Exception as e: logger.error( 'Exception while trying to delete experiment {} of user {}: {}' .format(experiment.id, username, str(e))) traceback.print_exc() logger.warning( 'Removing the resources and experiment {} of user {} from the database so they might actually not be removed!' .format(experiment.id, username)) try: for ur in find(UsedResource): if ur.parent_id == experiment.id: logger.debug( 'Removing used resource {} ({}) from the database.' .format(ur.id, ur.name)) try: delete(ur) except Exception as e: logger.error( 'Exception while removing used resource {} ({}) from the database: {}' .format(ur.id, ur.name, e)) traceback.print_exc() logger.debug( 'Removing experiment {} from the database.'. format(experiment.id)) try: delete(experiment) except Exception as e: logger.error( 'Exception while removing experiment {} from the database: {}' .format(experiment.id, e)) traceback.print_exc() except Exception as e: logger.error( 'Exception while removing the resources and experiment {} of user {} from the database.' .format(experiment.id, username)) user_info = _create_user_info_from_experimenter(experimenter) for man in MANAGERS_CREATE_USER: try: get_stub_from_manager_name(man).delete_user(user_info) logger.info("Manager {} delete user {} finished".format( man, experimenter.username)) except ManagerNotFound: traceback.print_exc() logger.error( "Manager {} is not register and needs to delete user {}" .format(man, experimenter.username)) delete(experimenter)
def __init__(self, file_path, username): self.username = username self.file_path = file_path zf = zipfile.ZipFile(self.file_path) for info in zf.infolist(): filename = info.filename logger.debug("Filename: %s" % filename) if filename.endswith(".yaml") and filename.startswith( "Definitions/"): logger.debug("parsing %s..." % filename) try: tpl = ToscaTemplate( yaml_dict_tpl=yaml.load(zf.read(filename))) except Exception as e: if hasattr(e, 'message'): raise ExperimentValidationError(e.message) elif isinstance(e.args, list): raise ExperimentValidationError(e.args[0]) elif isinstance(e.args, str): raise ExperimentValidationError(e.args) else: raise ExperimentValidationError( "no message available", e) for node in tpl.nodetemplates: logger.debug( "Found node: %s of type %s with properties: %s" % (node.name, node.type, list(node.get_properties().keys()))) self.topology_template = tpl if filename == 'TOSCA-Metadata/Metadata.yaml': metadata = yaml.load(zf.read(filename)) self.name = metadata.get('name') if find(entities.Experiment, '{}_{}'.format(self.username, self.name)) is not None: raise ExperimentValidationError( 'There is already an experiment with this name, please choose a different one.' ) # 12/12/12 10:55 self.start_date = self.get_start_date(metadata) # 12/12/12 11:55 self.end_date = self.get_end_date(metadata) today = datetime.today().date() logger.info("End date: date: %s" % self.end_date.date()) if self.end_date.date() < today: logger.error( 'For the experiment {} the end date({}) is in the past.' .format(self.name, self.end_date.date())) raise ExperimentValidationError( 'For the experiment {} the end date({}) is in the past.' .format(self.name, self.end_date.date())) self.duration = self.end_date - self.start_date logger.debug("Experiment duration %s" % self.duration) if filename.startswith("Files/") and filename.endswith('.csar'): experiment_nsd_csar_location = get_config( 'system', 'temp-csar-location', '/etc/softfire/experiment-nsd-csar') experiment_nsd_csar_location = '{}/{}'.format( experiment_nsd_csar_location.rstrip('/'), username) if not os.path.exists(experiment_nsd_csar_location): os.makedirs(experiment_nsd_csar_location) data = zf.read(filename) nsd_file_location = "%s/%s" % (experiment_nsd_csar_location, filename.split('/')[-1]) with open(nsd_file_location, 'wb+') as f: f.write(data) temp_ids = [] for node in self.topology_template.nodetemplates: if node.type == 'NfvResource': file_name = node.get_properties().get('file_name') if file_name: file_name = file_name.value if file_name and file_name.startswith( "Files/") and file_name.endswith(".csar"): real_file_name = file_name[6:] tmp_file_location = '{}/{}/{}'.format( get_config( 'system', 'temp-csar-location', '/etc/softfire/experiment-nsd-csar').rstrip('/'), username, real_file_name) # get the description try: zf = zipfile.ZipFile(tmp_file_location) except FileNotFoundError: logger.error( "Please check that the file_name property is correctly set to the file name passed." ) raise ExperimentValidationError( "Please check that the file_name property is correctly set to the file name passed." ) try: filenames = [ zipinfo.filename for zipinfo in zf.filelist ] if 'TOSCA-Metadata/Metadata.yaml' in filenames: logger.debug( "Found 'TOSCA-Metadata/Metadata.yaml'") yaml_file = zf.read('TOSCA-Metadata/Metadata.yaml') elif 'tosca-metadata/Metadata.yaml' in filenames: # just for legacy support # the correct file name following the specification is 'TOSCA-Metadata' # to support experiments that were created before this fix we still check for 'tosca-metadata' though logger.warning( "'TOSCA-Metadata/Metadata.yaml' not found. Will try 'tosca-metadata/Metadata.yaml' to support older experiments." ) yaml_file = zf.read('tosca-metadata/Metadata.yaml') else: raise ExperimentValidationError( 'The TOSCA-Metadata/Metadata.yaml file is missing in {}.' .format(file_name)) except KeyError as e: traceback.print_exc() if hasattr(e, 'message'): raise ExperimentValidationError(e.message) else: raise ExperimentValidationError(e.args) if yaml_file: yaml_content = yaml.load(yaml_file) description = yaml_content.get('description') else: description = 'No description available' testbeds = node.get_properties().get('testbeds').value temp_ids.append( add_resource( username, node.get_properties().get('resource_id').value, "NfvResource", -1, description, list(testbeds.keys())[0], real_file_name)) try: self._validate() except Exception as e: for id in temp_ids: delete(find(ResourceMetadata, _id=id)) raise ExperimentValidationError(e.args) exp = entities.Experiment() exp.id = '{}_{}'.format(self.username, self.name) exp.username = self.username exp.name = self.name exp.start_date = self.start_date exp.end_date = self.end_date exp.resources = [] for node in self.topology_template.nodetemplates: exp.resources.append(self._get_used_resource_by_node(node)) element_value = find_by_element_value(entities.Experiment, entities.Experiment.username, self.username) max_no_experiment = get_config("System", "max-number-experiments", 3) if len(element_value) >= max_no_experiment: raise ExperimentValidationError( "You cannot have more than %s experiments at the same time!" % max_no_experiment) logger.info("Saving experiment %s" % exp.name) save(exp) self.experiment = exp for res in exp.resources: _start_termination_thread_for_res(res)