Example #1
0
    def _validate_apps(data):
        """
        Validate Apps configuration

        Parameters
            data: configuration (dict)
        """
        if not 'apps' in data:
            return

        # verify apps
        pids = set()
        app_ids = []

        for app in data['apps']:
            # id
            if app['id'] in app_ids:
                raise ValueError("App {}, multiple apps with same id.".format(
                    app['id']))
            app_ids.append(app['id'])

            # app's cores validation
            if 'cores' in app:
                for core in app['cores']:
                    if not common.PQOS_API.check_core(core):
                        raise ValueError("App {}, Invalid core {}.".format(
                            app['id'], core))

            # app's pool validation
            app_pool = None
            for pool in data['pools']:
                if 'apps' in pool and app['id'] in pool['apps']:
                    if app_pool:
                        raise ValueError("App {}, Assigned to more than one pool."\
                            .format(app['id']))
                    app_pool = pool

            if app_pool is None:
                raise ValueError("App {} not assigned to any pool.".format(
                    app['id']))

            if 'cores' in app:
                diff_cores = set(app['cores']).difference(app_pool['cores'])
                if diff_cores:
                    raise ValueError("App {}, cores {} does not match Pool {}."\
                        .format(app['id'], diff_cores, app_pool['id']))

            # app's pids validation
            for pid in app['pids']:
                if not pid_ops.is_pid_valid(pid):
                    raise ValueError("App {}, PID {} is not valid.".format(
                        app['id'], pid))

            if pids.intersection(app['pids']):
                raise ValueError("App {}, PIDs {} already assigned to another App."\
                    .format(app['id'], pids.intersection(app['pids'])))

            pids |= set(app['pids'])
Example #2
0
    def post():
        # pylint: disable=too-many-branches
        """
        Handles HTTP POST /apps request.
        Add a new App
        Raises NotFound, BadRequest

        Returns:
            response, status code
        """
        json_data = request.get_json()

        # validate app schema
        try:
            schema, resolver = ConfigStore.load_json_schema('add_app.json')
            jsonschema.validate(json_data, schema, resolver=resolver)
        except jsonschema.ValidationError as error:
            raise BadRequest("Request validation failed - %s" % (str(error)))

        data = deepcopy(common.CONFIG_STORE.get_config())

        if 'pools' not in data:
            raise NotFound("No pools in config file")

        json_data['id'] = common.CONFIG_STORE.get_new_app_id()

        if 'pids' in json_data:
            # validate pids
            for pid in json_data['pids']:
                if not pid_ops.is_pid_valid(pid):
                    raise BadRequest("New APP not added, invalid PID: " +
                                     str(pid))

        # if pool_id not provided on app creation
        if 'pool_id' not in json_data or not json_data['pool_id']:
            json_data['pool_id'] = None

            # if apps cores list is a subset of existing pool cores list,
            # make existing pool a destination pool for app
            if 'cores' in json_data and json_data['cores']:
                for core in json_data['cores']:
                    if not common.PQOS_API.check_core(core):
                        raise BadRequest("New APP not added, invalid core: " +
                                         str(core))
                for pool in data['pools']:
                    if set(json_data['cores']).issubset(pool['cores']):
                        json_data['pool_id'] = pool['id']
                        break

            # if it is not, make default pool a destination pool
            if json_data['pool_id'] is None:
                json_data['pool_id'] = 0
                if 'cores' in json_data:
                    json_data.pop('cores')

        try:
            pool = common.CONFIG_STORE.get_pool(data, json_data['pool_id'])
        except Exception as ex:
            raise BadRequest("New APP not added, " + str(ex))

        # update pool configuration to include new app
        if not 'apps' in pool:
            pool['apps'] = []
        pool['apps'].append(json_data['id'])

        json_data.pop('pool_id')
        data['apps'].append(json_data)

        try:
            common.CONFIG_STORE.validate(data)
        except AdmissionControlError:
            pass
        except Exception as ex:
            raise BadRequest("New APP not added, " + str(ex))

        common.CONFIG_STORE.set_config(data)

        res = {
            'id': json_data['id'],
            'message': "New APP added to pool {}".format(str(pool['id']))
        }
        return res, 201
Example #3
0
    def post():
        # pylint: disable=too-many-branches
        """
        Handles HTTP POST /apps request.
        Add a new App
        Raises NotFound, BadRequest, InternalError

        Returns:
            response, status code
        """

        def get_app_id():
            """
            Get ID for new App

            Returns:
                ID for new App
            """
            # put all ids into list
            app_ids = []
            for app in data['apps']:
                app_ids.append(app['id'])
            app_ids = sorted(app_ids)
            # no app found in config
            if not app_ids:
                return 1

            # add new app to apps
            # find an id
            new_ids = list(set(range(1, app_ids[-1])) - set(app_ids))
            if new_ids:
                return new_ids[0]

            return app_ids[-1] + 1

        json_data = request.get_json()

        # validate app schema
        try:
            schema, resolver = ConfigStore.load_json_schema('add_app.json')
            jsonschema.validate(json_data, schema, resolver=resolver)
        except jsonschema.ValidationError as error:
            raise BadRequest("Request validation failed - %s" % (str(error)))

        data = deepcopy(common.CONFIG_STORE.get_config())

        if 'pools' not in data:
            raise NotFound("No pools in config file")

        json_data['id'] = get_app_id()

        if 'pids' in json_data:
            # validate pids
            for pid in json_data['pids']:
                valid = pid_ops.is_pid_valid(pid)
                if not valid:
                    raise BadRequest("New APP not added, please provide valid pid's")

        # if pool_id not provided on app creation
        if 'pool_id' not in json_data or not json_data['pool_id']:
            json_data['pool_id'] = None

            # if apps cores list is a subset of existing pool cores list,
            # make existing pool a destination pool for app
            if 'cores' in json_data and json_data['cores']:
                for pool in data['pools']:
                    if set(json_data['cores']).issubset(pool['cores']):
                        json_data['pool_id'] = pool['id']
                        break

            # if it is not, make default pool a destination pool
            if json_data['pool_id'] is None:
                json_data['pool_id'] = 0
                if 'cores' in json_data:
                    json_data.pop('cores')

        # update pool configuration to include new app
        for pool in data['pools']:
            if pool['id'] == json_data['pool_id']:
                if not 'apps' in pool:
                    pool['apps'] = []
                pool['apps'].append(json_data['id'])
                break

        json_data.pop('pool_id')
        data['apps'].append(json_data)

        try:
            common.CONFIG_STORE.validate(data)
        except Exception as ex:
            raise BadRequest("New APP not added, " + str(ex))
        else:
            common.CONFIG_STORE.set_config(data)
            res = {'id': json_data['id']}
            return res, 201
Example #4
0
    def validate(data):
        #pylint: disable=too-many-branches
        """
        Validate configuration

        Parameters
            data: configuration (dict)
        """

        # validates config schema
        schema, resolver = ConfigStore.load_json_schema('appqos.json')
        jsonschema.validate(data, schema, resolver=resolver)

        cores = set()
        pool_ids = []

        # verify pools
        for pool in data['pools']:
            # id
            if pool['id'] in pool_ids:
                raise ValueError(
                    "Pool {}, multiple pools with same id.".format(pool['id']))
            pool_ids.append(pool['id'])

            # pool cores
            for core in pool['cores']:
                if not common.PQOS_API.check_core(core):
                    raise ValueError("Pool {}, Invalid core {}.".format(
                        pool['id'], core))

            if cores.intersection(pool['cores']):
                raise ValueError("Pool {}, Cores {} already assigned to another pool."\
                    .format(pool['id'], cores.intersection(pool['cores'])))

            cores |= set(pool['cores'])

            # check app reference
            if 'apps' in pool:
                for app_id in pool['apps']:
                    ConfigStore.get_app(data, app_id)

        # verify apps
        if 'apps' in data:
            pids = set()
            app_ids = []

            for app in data['apps']:
                # id
                if app['id'] in app_ids:
                    raise ValueError(
                        "App {}, multiple apps with same id.".format(
                            app['id']))
                app_ids.append(app['id'])

                # app's cores validation
                if 'cores' in app:
                    for core in app['cores']:
                        if not common.PQOS_API.check_core(core):
                            raise ValueError("App {}, Invalid core {}.".format(
                                app['id'], core))

                # app's pool validation
                app_pool = None
                for pool in data['pools']:
                    if 'apps' in pool and app['id'] in pool['apps']:
                        if app_pool:
                            raise ValueError("App {}, Assigned to more than one pool."\
                                .format(app['id']))
                        app_pool = pool

                if app_pool is None:
                    raise ValueError("App {} not assigned to any pool.".format(
                        app['id']))

                if 'cores' in app:
                    diff_cores = set(app['cores']).difference(
                        app_pool['cores'])
                    if diff_cores:
                        raise ValueError("App {}, cores {} does not match Pool {}."\
                            .format(app['id'], diff_cores, app_pool['id']))

                # app's pids validation
                for pid in app['pids']:
                    if not pid_ops.is_pid_valid(pid):
                        raise ValueError("App {}, PID {} is not valid.".format(
                            app['id'], pid))

                if pids.intersection(app['pids']):
                    raise ValueError("App {}, PIDs {} already assigned to another App."\
                        .format(app['id'], cores.intersection(app['pids'])))

                pids |= set(app['pids'])
Example #5
0
    def post():
        """
        Handles HTTP POST /apps request.
        Add a new App
        Raises NotFound, BadRequest, InternalError

        Returns:
            response, status code
        """
        def get_app_id():
            """
            Get ID for new App

            Returns:
                ID for new App
            """
            # put all ids into list
            app_ids = []
            for app in data['apps']:
                app_ids.append(app['id'])
            app_ids = sorted(app_ids)
            # no app found in config
            if not app_ids:
                return 1

            # add new app to apps
            # find an id
            new_ids = list(set(range(1, app_ids[-1])) - set(app_ids))
            if new_ids:
                return new_ids[0]

            return app_ids[-1] + 1

        json_data = request.get_json()

        # validate app schema
        try:
            schema, resolver = ConfigStore.load_json_schema('add_app.json')
            jsonschema.validate(json_data, schema, resolver=resolver)
        except jsonschema.ValidationError as error:
            raise BadRequest("Request validation failed - %s" % (str(error)))

        data = deepcopy(common.CONFIG_STORE.get_config())

        if 'pools' not in data:
            raise NotFound("No pools in config file")

        json_data['id'] = get_app_id()

        if 'pids' in json_data:
            # validate pids
            for pid in json_data['pids']:
                valid = pid_ops.is_pid_valid(pid)
                if not valid:
                    raise BadRequest(
                        "New APP not added, please provide valid pid's")

        for pool in data['pools']:
            if pool['id'] == json_data['pool_id']:
                if not 'apps' in pool:
                    pool['apps'] = []
                pool['apps'].append(json_data['id'])
                break

        json_data.pop('pool_id')
        data['apps'].append(json_data)

        try:
            common.CONFIG_STORE.validate(data)
        except Exception as ex:
            raise BadRequest("New APP not added, " + str(ex))
        else:
            common.CONFIG_STORE.set_config(data)
            res = {'id': json_data['id']}
            return res, 201
Example #6
0
    def post():
        # pylint: disable=too-many-branches
        """
        Handles HTTP POST /apps request.
        Add a new App
        Raises NotFound, BadRequest, InternalError

        Returns:
            response, status code
        """
        def get_app_id():
            """
            Get ID for new App

            Returns:
                ID for new App
            """
            # put all ids into list
            app_ids = []
            for app in data['apps']:
                app_ids.append(app['id'])
            app_ids = sorted(app_ids)
            # no app found in config
            if not app_ids:
                return 1

            # add new app to apps
            # find an id
            new_ids = list(set(range(1, app_ids[-1])) - set(app_ids))
            if new_ids:
                return new_ids[0]

            return app_ids[-1] + 1

        json_data = request.get_json()

        # validate app schema
        try:
            schema, resolver = ConfigStore.load_json_schema('add_app.json')
            jsonschema.validate(json_data, schema, resolver=resolver)
        except jsonschema.ValidationError as error:
            raise BadRequest("Request validation failed - %s" % (str(error)))

        data = deepcopy(common.CONFIG_STORE.get_config())

        if 'pools' not in data:
            raise NotFound("No pools in config file")

        json_data['id'] = get_app_id()

        if 'pids' in json_data:
            # validate pids
            for pid in json_data['pids']:
                valid = pid_ops.is_pid_valid(pid)
                if not valid:
                    raise BadRequest(
                        "New APP not added, please provide valid pid's")

        # if pool_id not provided on app creation
        if 'pool_id' not in json_data or not json_data['pool_id']:
            json_data['pool_id'] = None

            # if apps cores list is a subset of existing pool cores list,
            # make existing pool a destination pool for app
            if 'cores' in json_data and json_data['cores']:
                for pool in data['pools']:
                    if set(json_data['cores']).issubset(pool['cores']):
                        json_data['pool_id'] = pool['id']
                        break

            # if it is not, make default pool a destination pool
            if json_data['pool_id'] is None:
                json_data['pool_id'] = 0
                if 'cores' in json_data:
                    json_data.pop('cores')

        # update pool configuration to include new app
        for pool in data['pools']:
            if pool['id'] == json_data['pool_id']:
                if not 'apps' in pool:
                    pool['apps'] = []
                pool['apps'].append(json_data['id'])
                break

        json_data.pop('pool_id')
        data['apps'].append(json_data)

        try:
            common.CONFIG_STORE.validate(data)
        except Exception as ex:
            raise BadRequest("New APP not added, " + str(ex))
        else:
            common.CONFIG_STORE.set_config(data)
            res = {'id': json_data['id']}
            return res, 201
Example #7
0
    def validate(data):
        #pylint: disable=too-many-branches
        """
        Validate configuration

        Parameters
            data: configuration (dict)
        """

        # validates config schema
        schema, resolver = ConfigStore.load_json_schema('appqos.json')
        jsonschema.validate(data, schema, resolver=resolver)

        cores = set()
        pool_ids = []

        # verify pools
        for pool in data['pools']:
            # id
            if pool['id'] in pool_ids:
                raise ValueError("Pool {}, multiple pools with same id.".format(pool['id']))
            pool_ids.append(pool['id'])

            # pool cores
            for core in pool['cores']:
                if not common.PQOS_API.check_core(core):
                    raise ValueError("Pool {}, Invalid core {}.".format(pool['id'], core))

            if cores.intersection(pool['cores']):
                raise ValueError("Pool {}, Cores {} already assigned to another pool."\
                    .format(pool['id'], cores.intersection(pool['cores'])))

            cores |= set(pool['cores'])

            # check app reference
            if 'apps' in pool:
                for app_id in pool['apps']:
                    ConfigStore.get_app(data, app_id)

        # verify apps
        if 'apps' in data:
            pids = set()
            app_ids = []

            for app in data['apps']:
                # id
                if app['id'] in app_ids:
                    raise ValueError("App {}, multiple apps with same id.".format(app['id']))
                app_ids.append(app['id'])

                # app's cores validation
                if 'cores' in app:
                    for core in app['cores']:
                        if not common.PQOS_API.check_core(core):
                            raise ValueError("App {}, Invalid core {}.".format(app['id'], core))

                # app's pool validation
                app_pool = None
                for pool in data['pools']:
                    if 'apps' in pool and app['id'] in pool['apps']:
                        if app_pool:
                            raise ValueError("App {}, Assigned to more than one pool."\
                                .format(app['id']))
                        app_pool = pool

                if app_pool is None:
                    raise ValueError("App {} not assigned to any pool.".format(app['id']))

                if 'cores' in app:
                    diff_cores = set(app['cores']).difference(app_pool['cores'])
                    if diff_cores:
                        raise ValueError("App {}, cores {} does not match Pool {}."\
                            .format(app['id'], diff_cores, app_pool['id']))

                # app's pids validation
                for pid in app['pids']:
                    if not pid_ops.is_pid_valid(pid):
                        raise ValueError("App {}, PID {} is not valid.".format(app['id'], pid))

                if pids.intersection(app['pids']):
                    raise ValueError("App {}, PIDs {} already assigned to another App."\
                        .format(app['id'], cores.intersection(app['pids'])))

                pids |= set(app['pids'])