Esempio n. 1
0
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)
Esempio n. 2
0
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)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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)
Esempio n. 5
0
    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)
Esempio n. 6
0
    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())
Esempio n. 7
0
    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)
Esempio n. 8
0
    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)