def handle_function_service_expiration(ctx, engine): """Clean up resources related to expired functions. If it's image function, we will rely on the orchestrator itself to do the image clean up, e.g. image collection feature in kubernetes. """ context.set_ctx(ctx) delta = timedelta(seconds=CONF.engine.function_service_expiration) expiry_time = datetime.utcnow() - delta results = db_api.get_functions(sort_keys=['updated_at'], insecure=True, updated_at={'lte': expiry_time}) if len(results) == 0: return for func_db in results: if not etcd_util.get_service_url(func_db.id): continue LOG.info('Deleting service mapping and workers for function %s', func_db.id) # Delete resources related to the function engine.delete_function(ctx, func_db.id) # Delete etcd keys etcd_util.delete_function(func_db.id)
def handle_function_service_expiration(ctx, engine_client, orchestrator): context.set_ctx(ctx) delta = timedelta(seconds=CONF.engine.function_service_expiration) expiry_time = datetime.utcnow() - delta results = db_api.get_functions(sort_keys=['updated_at'], insecure=True, updated_at={'lte': expiry_time}) if len(results) == 0: return for func_db in results: if not func_db.service: continue with db_api.transaction(): LOG.info('Deleting service mapping and workers for function %s', func_db.id) # Delete resources related to the function engine_client.delete_function(func_db.id) # Delete service mapping and worker records db_api.delete_function_service_mapping(func_db.id) db_api.delete_function_workers(func_db.id)
def get_all(self, all_projects=False, project_id=None): """Return a list of functions. :param project_id: Optional. Admin user can query other projects resources, the param is ignored for normal user. :param all_projects: Optional. Get resources of all projects. """ ctx = context.get_ctx() if project_id and not ctx.is_admin: project_id = context.ctx().projectid if project_id and ctx.is_admin: all_projects = True if all_projects: acl.enforce('function:get_all:all_projects', ctx) filters = rest_utils.get_filters(project_id=project_id, ) LOG.info("Get all functions. filters=%s", filters) db_functions = db_api.get_functions(insecure=all_projects, **filters) functions = [ resources.Function.from_dict(db_model.to_dict()) for db_model in db_functions ] return resources.Functions(functions=functions)
def get_all(self): LOG.info("Get all functions.") functions = [ resources.Function.from_dict(db_model.to_dict()) for db_model in db_api.get_functions() ] return resources.Functions(functions=functions)
def put(self, id, runtime): """Update runtime. Currently, we support update name, description, image. When updating image, send message to engine for asynchronous handling. """ acl.enforce('runtime:update', context.get_ctx()) values = {} for key in UPDATE_ALLOWED: if runtime.to_dict().get(key) is not None: values.update({key: runtime.to_dict()[key]}) LOG.info('Update resource, params: %s', values, resource={ 'type': self.type, 'id': id }) image = values.get('image') with db_api.transaction(): if image is not None: pre_runtime = db_api.get_runtime(id) if pre_runtime.status != status.AVAILABLE: raise exc.RuntimeNotAvailableException( 'Runtime %s is not available.' % id) pre_image = pre_runtime.image if pre_image != image: # Ensure there is no function running in the runtime. db_funcs = db_api.get_functions(insecure=True, fields=['id'], runtime_id=id) func_ids = [func.id for func in db_funcs] for id in func_ids: if etcd_util.get_service_url(id): raise exc.NotAllowedException( 'Runtime %s is still in use by functions.' % id) values['status'] = status.UPGRADING self.engine_client.update_runtime( id, image=image, pre_image=pre_image, ) runtime_db = db_api.update_runtime(id, values) return resources.Runtime.from_db_obj(runtime_db)
def put(self, id, runtime): """Update runtime. Currently, we only support update name, description, image. When updating image, send message to engine for asynchronous handling. """ values = {} for key in UPDATE_ALLOWED: if runtime.to_dict().get(key) is not None: values.update({key: runtime.to_dict()[key]}) LOG.info('Update resource, params: %s', values, resource={ 'type': self.type, 'id': id }) with db_api.transaction(): if 'image' in values: pre_runtime = db_api.get_runtime(id) if pre_runtime.status != status.AVAILABLE: raise exc.RuntimeNotAvailableException( 'Runtime %s is not available.' % id) pre_image = pre_runtime.image if pre_image != values['image']: # Ensure there is no function running in the runtime. db_funcs = db_api.get_functions(insecure=True, fields=['id'], runtime_id=id) func_ids = [func.id for func in db_funcs] mappings = db_api.get_function_service_mappings( insecure=True, function_id={'in': func_ids}) if mappings: raise exc.NotAllowedException( 'Runtime %s is still in use by functions.' % id) values['status'] = status.UPGRADING self.engine_client.update_runtime(id, image=values['image'], pre_image=pre_image) else: values.pop('image') runtime_db = db_api.update_runtime(id, values) return resources.Runtime.from_dict(runtime_db.to_dict())
def delete(self, id): LOG.info("Delete resource.", resource={'type': self.type, 'id': id}) with db_api.transaction(): runtime_db = db_api.get_runtime(id) # Runtime can not be deleted if still associate with functions. funcs = db_api.get_functions(runtime_id={'eq': id}) if len(funcs): raise exc.NotAllowedException('Runtime %s is still in use.' % id) runtime_db.status = status.DELETING # Clean related resources asynchronously self.engine_client.delete_runtime(id)
def delete(self, id): """Delete runtime.""" LOG.info("Delete runtime [id=%s]", id) with db_api.transaction(): runtime_db = db_api.get_runtime(id) # Runtime can not be deleted if still associate with functions. funcs = db_api.get_functions(runtime_id={'eq': id}) if len(funcs): raise exc.NotAllowedException( 'Runtime %s is still in use.' % id ) runtime_db.status = 'deleting' # Clean related resources asynchronously self.engine_client.delete_runtime(id)