def delete(self, id): """Delete the specified function.""" LOG.info("Delete function %s.", id) with db_api.transaction(): func_db = db_api.get_function(id) if len(func_db.jobs) > 0: raise exc.NotAllowedException( 'The function is still associated with running job(s).') if func_db.webhook: raise exc.NotAllowedException( 'The function is still associated with webhook.') # Even admin user can not delete other project's function because # the trust associated can only be removed by function owner. if func_db.project_id != context.get_ctx().projectid: raise exc.NotAllowedException( 'Function can only be deleted by its owner.') source = func_db.code['source'] if source == constants.PACKAGE_FUNCTION: self.storage_provider.delete(func_db.project_id, id) # Delete all resources created by orchestrator asynchronously. self.engine_client.delete_function(id) # Delete trust if needed if func_db.trust_id: keystone_util.delete_trust(func_db.trust_id) # Delete etcd keys etcd_util.delete_function(id) # This will also delete function service mapping as well. db_api.delete_function(id)
def delete(self, id): """Delete the specified function. Delete function will also delete all its versions. """ LOG.info("Delete function %s.", id) with db_api.transaction(): func_db = db_api.get_function(id) if len(func_db.jobs) > 0: raise exc.NotAllowedException( 'The function is still associated with running job(s).') if len(func_db.webhooks) > 0: raise exc.NotAllowedException( 'The function is still associated with webhook(s).') if len(func_db.aliases) > 0: raise exc.NotAllowedException( 'The function is still associated with function alias(es).' ) # Even admin user can not delete other project's function because # the trust associated can only be removed by function owner. if func_db.project_id != context.get_ctx().projectid: raise exc.NotAllowedException( 'Function can only be deleted by its owner.') # Delete trust if needed if func_db.trust_id: keystone_util.delete_trust(func_db.trust_id) for version_db in func_db.versions: # Delete all resources created by orchestrator asynchronously. self.engine_client.delete_function( id, version=version_db.version_number) # Delete etcd keys etcd_util.delete_function(id, version=version_db.version_number) # Delete function version packages. Versions is only supported # for package type function. self.storage_provider.delete(func_db.project_id, id, None, version=version_db.version_number) # Delete resources for function version 0(func_db.versions==[]) self.engine_client.delete_function(id) etcd_util.delete_function(id) source = func_db.code['source'] if source == constants.PACKAGE_FUNCTION: self.storage_provider.delete(func_db.project_id, id, func_db.code['md5sum']) # This will also delete function service mapping and function # versions as well. db_api.delete_function(id)
def delete_job(id, trust_id=None): if not trust_id: trust_id = db_api.get_job(id).trust_id modified_count = db_api.delete_job(id) if modified_count: # Delete trust only together with deleting trigger. keystone_utils.delete_trust(trust_id) return 0 != modified_count
def delete(self, id): """Delete the specified function.""" LOG.info("Delete resource.", resource={'type': self.type, 'id': id}) with db_api.transaction(): func_db = db_api.get_function(id) if len(func_db.jobs) > 0: raise exc.NotAllowedException( 'The function is still associated with running job(s).') source = func_db.code['source'] if source == 'package': self.storage_provider.delete(context.get_ctx().projectid, id) # Delete all resources created by orchestrator asynchronously. self.engine_client.delete_function(id) # Delete trust if needed if func_db.trust_id: keystone_util.delete_trust(func_db.trust_id) # This will also delete function service mapping as well. db_api.delete_function(id)
def post(self, job): """Creates a new job.""" params = job.to_dict() if not POST_REQUIRED.issubset(set(params.keys())): raise exc.InputException( 'Required param is missing. Required: %s' % POST_REQUIRED) # Check the input params. first_time, next_time, count = jobs.validate_job(params) LOG.info("Creating %s, params: %s", self.type, params) with db_api.transaction(): db_api.get_function(params['function_id']) values = { 'name': params.get('name'), 'pattern': params.get('pattern'), 'first_execution_time': first_time, 'next_execution_time': next_time, 'count': count, 'function_id': params['function_id'], 'function_input': params.get('function_input') or {}, 'status': status.RUNNING } if cfg.CONF.pecan.auth_enable: values['trust_id'] = keystone_util.create_trust().id try: db_job = db_api.create_job(values) except Exception: # Delete trust before raising exception. keystone_util.delete_trust(values.get('trust_id')) raise return resources.Job.from_dict(db_job.to_dict())
def post(self, **kwargs): # When using image to create function, runtime_id is not a required # param. if not POST_REQUIRED.issubset(set(kwargs.keys())): raise exc.InputException( 'Required param is missing. Required: %s' % POST_REQUIRED) LOG.info("Creating function, params: %s", kwargs) values = { 'name': kwargs.get('name'), 'description': kwargs.get('description'), 'runtime_id': kwargs.get('runtime_id'), 'code': json.loads(kwargs['code']), 'entry': kwargs.get('entry', 'main.main'), 'cpu': kwargs.get('cpu', CONF.resource_limits.default_cpu), 'memory_size': kwargs.get('memory_size', CONF.resource_limits.default_memory), 'timeout': kwargs.get('timeout', CONF.resource_limits.default_timeout), } common.validate_int_in_range('timeout', values['timeout'], CONF.resource_limits.min_timeout, CONF.resource_limits.max_timeout) common.validate_int_in_range('cpu', values['cpu'], CONF.resource_limits.min_cpu, CONF.resource_limits.max_cpu) common.validate_int_in_range('memory', values['memory_size'], CONF.resource_limits.min_memory, CONF.resource_limits.max_memory) source = values['code'].get('source') if not source or source not in CODE_SOURCE: raise exc.InputException( 'Invalid code source specified, available sources: %s' % ', '.join(CODE_SOURCE)) if source != constants.IMAGE_FUNCTION: if not kwargs.get('runtime_id'): raise exc.InputException('"runtime_id" must be specified.') runtime = db_api.get_runtime(kwargs['runtime_id']) if runtime.status != 'available': raise exc.InputException('Runtime %s is not available.' % kwargs['runtime_id']) store = False create_trust = True if source == constants.PACKAGE_FUNCTION: store = True md5sum = values['code'].get('md5sum') data = kwargs['package'].file.read() elif source == constants.SWIFT_FUNCTION: swift_info = values['code'].get('swift', {}) if not (swift_info.get('container') and swift_info.get('object')): raise exc.InputException("Both container and object must be " "provided for swift type function.") self._check_swift(swift_info.get('container'), swift_info.get('object')) else: create_trust = False values['entry'] = None if cfg.CONF.pecan.auth_enable and create_trust: try: values['trust_id'] = keystone_util.create_trust().id LOG.debug('Trust %s created', values['trust_id']) except Exception: raise exc.TrustFailedException( 'Trust creation failed for function.') # Create function and store the package data inside a db transaction so # that the function won't be created if any error happened during # package store. with db_api.transaction(): func_db = db_api.create_function(values) if store: try: ctx = context.get_ctx() _, actual_md5 = self.storage_provider.store(ctx.projectid, func_db.id, data, md5sum=md5sum) values['code'].update({"md5sum": actual_md5}) func_db = db_api.update_function(func_db.id, values) except Exception as e: LOG.exception("Failed to store function package.") keystone_util.delete_trust(values['trust_id']) raise e pecan.response.status = 201 return resources.Function.from_db_obj(func_db).to_dict()