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