Example #1
0
    def put():
        """
        Handles PUT /caps/mba_ctrl request.
        Raises BadRequest, InternalError

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

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

        if not caps.mba_bw_supported():
            return {'message': "MBA CTRL not supported!"}, 409

        if common.CONFIG_STORE.is_any_pool_defined():
            return {'message': "Please remove all Pools first!"}, 409

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

        CapsMbaCtrl.set_mba_ctrl_enabled(data, json_data['enabled'])

        common.CONFIG_STORE.set_config(data)

        return {'message': "MBA CTRL status changed."}, 200
Example #2
0
    def put():
        """
        Handles HTTP PUT /caps/sstbf request.
        Raises BadRequest, InternalError

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

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

        if not sstbf.configure_sstbf(json_data['configured']) == 0:
            raise InternalError("Failed to change SST-BF configured state.")

        # update power profile configuration
        power.configure_power()

        res = {'message': "SST-BF caps modified"}
        return res, 200
Example #3
0
    def put():
        """
        Handles PUT /caps/rdt_iface request.
        Raises BadRequest, InternalError

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

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

        if not json_data['interface'] in common.PQOS_API.supported_iface():
            raise BadRequest("RDT interface '%s' not supported!" % (json_data['interface']))

        if common.CONFIG_STORE.is_any_pool_defined():
            return {'message': "Please remove all Pools first!"}, 409

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

        if 'rdt_iface' not in data:
            data['rdt_iface'] = {}

        data['rdt_iface']['interface'] = json_data['interface']
        CapsMbaCtrl.set_mba_ctrl_enabled(data, False)

        common.CONFIG_STORE.set_config(data)

        res = {'message': "RDT Interface modified"}
        return res, 200
Example #4
0
    def post():
        """
        Handles HTTP POST /pools request.
        Add a new Pool
        Raises NotFound, BadRequest, InternalError

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

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

        admission_control_check = json_data.pop('verify', True) and\
            ('cores' in json_data or 'power_profile' in json_data)

        post_data = json_data.copy()
        post_data['id'] = common.CONFIG_STORE.get_new_pool_id(post_data)
        if post_data['id'] is None:
            raise InternalError("New POOL not added, maximum number of POOLS"\
                " reached for requested allocation combination")

        # convert cbm from string to int
        if 'cbm' in post_data:
            cbm = post_data['cbm']
            if not isinstance(cbm, int):
                cbm = int(cbm, 16)

            post_data['cbm'] = cbm

        # ignore 'power_profile' if SST-BF is enabled
        if sstbf.is_sstbf_configured():
            post_data.pop('power_profile', None)

        data = deepcopy(common.CONFIG_STORE.get_config())
        data['pools'].append(post_data)

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

        common.CONFIG_STORE.set_config(data)

        res = {
            'id': post_data['id'],
            'message': "New POOL {} added".format(post_data['id'])
        }
        return res, 201
Example #5
0
    def post():
        """
        Handles HTTP POST /pools request.
        Add a new Pool
        Raises NotFound, BadRequest, InternalError

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

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

        post_data = json_data.copy()
        post_data['id'] = common.CONFIG_STORE.get_new_pool_id(post_data)
        if post_data['id'] is None:
            raise InternalError("New POOL not added, maximum number of POOLS"\
                " reached for requested allocation combination")

        # convert cbm from string to int
        if 'cbm' in post_data:
            cbm = post_data['cbm']
            if not isinstance(cbm, int):
                cbm = int(cbm, 16)

            post_data['cbm'] = cbm

        data = common.CONFIG_STORE.get_config().copy()
        data['pools'].append(post_data)

        try:
            common.CONFIG_STORE.validate(data)
        except Exception as ex:
            raise BadRequest("New POOL not added, " + str(ex))
        else:
            common.CONFIG_STORE.set_config(data)
            res = {'id': post_data['id']}
            return res, 201
Example #6
0
    def post():
        """
        Handles HTTP POST /pools request.
        Add a new Pool
        Raises NotFound, BadRequest, InternalError

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

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

        post_data = json_data.copy()
        post_data['id'] = common.CONFIG_STORE.get_new_pool_id(post_data)
        if post_data['id'] is None:
            raise InternalError("New POOL not added, maximum number of POOLS"\
                " reached for requested allocation combination")

        # convert cbm from string to int
        if 'cbm' in post_data:
            cbm = post_data['cbm']
            if not isinstance(cbm, int):
                cbm = int(cbm, 16)

            post_data['cbm'] = cbm

        data = common.CONFIG_STORE.get_config().copy()
        data['pools'].append(post_data)

        try:
            common.CONFIG_STORE.validate(data)
        except Exception as ex:
            raise BadRequest("New POOL not added, " + str(ex))
        else:
            common.CONFIG_STORE.set_config(data)
            res = {'id': post_data['id']}
            return res, 201
Example #7
0
    def put(pool_id):
        # pylint: disable=too-many-branches
        """
        Handles HTTP PUT /pools/<pool_id> request.
        Modifies a Pool
        Raises NotFound, BadRequest, InternalError

        Parameters:
            pool_id: Id of pool

        Returns:
            response, status code
        """
        def check_alloc_tech(pool_id, json_data):
            alloc_tech = []
            if 'cbm' in json_data:
                alloc_tech.append(common.CAT_CAP)
            if 'mba' in json_data:
                alloc_tech.append(common.MBA_CAP)

            if not alloc_tech:
                return True

            return pool_id <= common.PQOS_API.get_max_cos_id(alloc_tech)

        json_data = request.get_json()

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

        data = common.CONFIG_STORE.get_config().copy()
        if 'pools' not in data:
            raise NotFound("No pools in config file")

        for pool in data['pools']:
            if pool['id'] != int(pool_id):
                continue

            if not check_alloc_tech(int(pool_id), json_data):
                raise BadRequest("Pool {} does not support requested technologies!"\
                    .format(pool_id))

            # set new cbm
            if 'cbm' in json_data:
                cbm = json_data['cbm']
                if not isinstance(cbm, int):
                    cbm = int(cbm, 16)

                pool['cbm'] = cbm

            # set new mba
            if 'mba' in json_data:
                pool['mba'] = json_data['mba']

            # set new cores
            if 'cores' in json_data:
                pool['cores'] = json_data['cores']

            if 'apps' in pool and pool['apps']:
                for app_id in pool['apps']:
                    for app in data['apps']:
                        if app['id'] != app_id or 'cores' not in app:
                            continue
                        if not set(app['cores']).issubset(pool['cores']):
                            app.pop('cores')

            # set new name
            if 'name' in json_data:
                pool['name'] = json_data['name']

            try:
                common.CONFIG_STORE.validate(data)
            except Exception as ex:
                raise BadRequest("POOL " + str(pool_id) + " not updated, " + str(ex))
            else:
                common.CONFIG_STORE.set_config(data)
                return "POOL " + str(pool_id) + " updated", 200

        raise NotFound("POOL " + str(pool_id) + " not found in config")
Example #8
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 #9
0
    def put(app_id):
        """
        Handles HTTP PUT /apps/<app_id> request.
        Modifies an App (e.g.: moves to different pool)
        Raises NotFound, InternalError

        Parameters:
            app_id: Id of app to modify

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

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

        pool_id = json_data["pool_id"]

        data = deepcopy(common.CONFIG_STORE.get_config())
        if 'apps' not in data or 'pools' not in data:
            raise NotFound("No apps or pools in config file")

        for app in data['apps']:
            if app['id'] != int(app_id):
                continue

            # remove app id from pool
            for pool in data['pools']:
                if 'apps' in pool:
                    if app['id'] in pool['apps']:
                        pool['apps'].remove(app['id'])
                        break
            # add app id to new pool
            for pool in data['pools']:
                if pool['id'] == int(pool_id):
                    if 'apps' in pool:
                        pool['apps'].append(app['id'])
                        break
                    else:
                        pool['apps'] = [app['id']]
                        break
            # set new cores
            if 'cores' in json_data:
                app['cores'] = json_data['cores']
            elif 'cores' in app:
                app.pop('cores')

            try:
                common.CONFIG_STORE.validate(data)
            except Exception as ex:
                raise BadRequest("APP not updated, " + str(ex))
            else:
                common.CONFIG_STORE.set_config(data)
                common.STATS_STORE.general_stats_inc_apps_moves()
                return "APP " + str(app_id) + " moved to new pool", 200

        raise NotFound("APP " + str(app_id) + " not found in config")
Example #10
0
    def put(pool_id):
        # pylint: disable=too-many-branches
        """
        Handles HTTP PUT /pools/<pool_id> request.
        Modifies a Pool
        Raises NotFound, BadRequest

        Parameters:
            pool_id: Id of pool

        Returns:
            response, status code
        """
        def check_alloc_tech(pool_id, json_data):
            if 'cbm' in json_data:
                if not caps.cat_supported():
                    raise BadRequest("System does not support CAT!")
                if pool_id > common.PQOS_API.get_max_cos_id([common.CAT_CAP]):
                    raise BadRequest(
                        "Pool {} does not support CAT".format(pool_id))

            if 'mba' in json_data:
                if not caps.mba_supported():
                    raise BadRequest("System does not support MBA!")
                if pool_id > common.PQOS_API.get_max_cos_id([common.MBA_CAP]):
                    raise BadRequest(
                        "Pool {} does not support MBA".format(pool_id))

        if not validate_str_int(pool_id):
            raise BadRequest("POOL index {} is invalid.".format(str(pool_id)))

        json_data = request.get_json()

        # validate app schema
        try:
            schema, resolver = ConfigStore.load_json_schema('modify_pool.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")

        for pool in data['pools']:
            if pool['id'] != int(pool_id):
                continue

            check_alloc_tech(int(pool_id), json_data)

            # set new cbm
            if 'cbm' in json_data:
                cbm = json_data['cbm']
                if not isinstance(cbm, int):
                    cbm = int(cbm, 16)

                pool['cbm'] = cbm

            # set new mba
            if 'mba' in json_data:
                pool['mba'] = json_data['mba']

            # set new cores
            if 'cores' in json_data:
                pool['cores'] = json_data['cores']

            if 'apps' in pool and pool['apps']:
                for app_id in pool['apps']:
                    for app in data['apps']:
                        if app['id'] != app_id or 'cores' not in app:
                            continue
                        if not set(app['cores']).issubset(pool['cores']):
                            app.pop('cores')

            # set new name
            if 'name' in json_data:
                pool['name'] = json_data['name']

            try:
                common.CONFIG_STORE.validate(data)
            except Exception as ex:
                raise BadRequest("POOL " + str(pool_id) + " not updated, " +
                                 str(ex))
            else:
                common.CONFIG_STORE.set_config(data)

                res = {'message': "POOL " + str(pool_id) + " updated"}
                return res, 200

        raise NotFound("POOL " + str(pool_id) + " not found in config")
Example #11
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 #12
0
    def put(app_id):
        """
        Handles HTTP PUT /apps/<app_id> request.
        Modifies an App (e.g.: moves to different pool)
        Raises NotFound, InternalError

        Parameters:
            app_id: Id of app to modify

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

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

        pool_id = json_data["pool_id"]

        data = deepcopy(common.CONFIG_STORE.get_config())
        if 'apps' not in data or 'pools' not in data:
            raise NotFound("No apps or pools in config file")

        for app in data['apps']:
            if app['id'] != int(app_id):
                continue

            # remove app id from pool
            for pool in data['pools']:
                if 'apps' in pool:
                    if app['id'] in pool['apps']:
                        pool['apps'].remove(app['id'])
                        break
            # add app id to new pool
            for pool in data['pools']:
                if pool['id'] == int(pool_id):
                    if 'apps' in pool:
                        pool['apps'].append(app['id'])
                        break
                    else:
                        pool['apps'] = [app['id']]
                        break
            # set new cores
            if 'cores' in json_data:
                app['cores'] = json_data['cores']
            elif 'cores' in app:
                app.pop('cores')

            try:
                common.CONFIG_STORE.validate(data)
            except Exception as ex:
                raise BadRequest("APP not updated, " + str(ex))
            else:
                common.CONFIG_STORE.set_config(data)
                common.STATS_STORE.general_stats_inc_apps_moves()
                return "APP " + str(app_id) + " moved to new pool", 200

        raise NotFound("APP " + str(app_id) + " not found in config")
Example #13
0
    def put(pool_id):
        # pylint: disable=too-many-branches
        """
        Handles HTTP PUT /pools/<pool_id> request.
        Modifies a Pool
        Raises NotFound, BadRequest

        Parameters:
            pool_id: Id of pool

        Returns:
            response, status code
        """
        def check_alloc_tech(pool_id, json_data):
            if 'cbm' in json_data:
                if not caps.cat_supported():
                    raise BadRequest("System does not support CAT!")
                if pool_id > common.PQOS_API.get_max_cos_id([common.CAT_CAP]):
                    raise BadRequest(
                        "Pool {} does not support CAT".format(pool_id))

            if 'mba' in json_data or 'mba_bw' in json_data:
                if not caps.mba_supported():
                    raise BadRequest("System does not support MBA!")
                if pool_id > common.PQOS_API.get_max_cos_id([common.MBA_CAP]):
                    raise BadRequest(
                        "Pool {} does not support MBA".format(pool_id))

            if 'mba_bw' in json_data and not caps.mba_bw_enabled():
                raise BadRequest("MBA CTRL is not {}!"\
                    .format("enabled" if caps.mba_bw_supported() else "supported"))

            if 'mba' in json_data and caps.mba_bw_enabled():
                raise BadRequest(
                    "MBA RATE is disabled! Disable MBA CTRL and try again.")

        json_data = request.get_json()

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

        admission_control_check = json_data.pop('verify', True) and\
            ('cores' in json_data or 'power_profile' in json_data)

        data = deepcopy(common.CONFIG_STORE.get_config())
        if 'pools' not in data:
            raise NotFound("No pools in config file")

        for pool in data['pools']:
            if pool['id'] != int(pool_id):
                continue

            check_alloc_tech(int(pool_id), json_data)

            # set new cbm
            if 'cbm' in json_data:
                cbm = json_data['cbm']
                if not isinstance(cbm, int):
                    cbm = int(cbm, 16)

                pool['cbm'] = cbm

            for feature in ['mba', 'mba_bw', 'cores']:
                if feature in json_data:
                    pool[feature] = json_data[feature]

            if 'apps' in pool and pool['apps']:
                for app_id in pool['apps']:
                    for app in data['apps']:
                        if app['id'] != app_id or 'cores' not in app:
                            continue
                        if not set(app['cores']).issubset(pool['cores']):
                            app.pop('cores')

            # set new name
            if 'name' in json_data:
                pool['name'] = json_data['name']

            # set new power profile
            # ignore 'power_profile' if SST-BF is enabled
            if 'power_profile' in json_data and not sstbf.is_sstbf_configured(
            ):
                pool['power_profile'] = json_data['power_profile']

            try:
                common.CONFIG_STORE.validate(data, admission_control_check)
            except Exception as ex:
                raise BadRequest("POOL " + str(pool_id) + " not updated, " +
                                 str(ex))

            common.CONFIG_STORE.set_config(data)

            res = {'message': "POOL " + str(pool_id) + " updated"}
            return res, 200

        raise NotFound("POOL " + str(pool_id) + " not found in config")
Example #14
0
    def put(app_id):
        # pylint: disable=too-many-branches
        """
        Handles HTTP PUT /apps/<app_id> request.
        Modifies an App (e.g.: moves to different pool)
        Raises NotFound, BadRequest

        Parameters:
            app_id: Id of app to modify

        Returns:
            response, status code
        """

        json_data = request.get_json()

        # validate app schema
        try:
            schema, resolver = ConfigStore.load_json_schema('modify_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 'apps' not in data or 'pools' not in data:
            raise NotFound("No apps or pools in config file")

        # move to another pool
        for app in data['apps']:
            if app['id'] != int(app_id):
                continue

            if 'pool_id' in json_data:
                pool_id = json_data['pool_id']

                # remove app id from pool
                for pool in data['pools']:
                    if 'apps' in pool:
                        if app['id'] in pool['apps']:
                            pool['apps'].remove(app['id'])
                            break

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

            # set new cores
            if 'cores' in json_data:
                app['cores'] = json_data['cores']

            # set new name
            if 'name' in json_data:
                app['name'] = json_data['name']

            # set new PIDs
            if 'pids' in json_data:
                app['pids'] = json_data['pids']

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

            common.CONFIG_STORE.set_config(data)
            if 'pool_id' in json_data:
                common.STATS_STORE.general_stats_inc_apps_moves()

            res = {'message': "APP " + str(app_id) + " updated"}
            return res, 200

        raise NotFound("APP " + str(app_id) + " not found in config")
Example #15
0
    def put(pool_id):
        """
        Handles HTTP PUT /pools/<pool_id> request.
        Modifies a Pool
        Raises NotFound, BadRequest, InternalError

        Parameters:
            pool_id: Id of pool

        Returns:
            response, status code
        """
        def check_alloc_tech(pool_id, json_data):
            alloc_tech = []
            if 'cbm' in json_data:
                alloc_tech.append(common.CAT_CAP)
            if 'mba' in json_data:
                alloc_tech.append(common.MBA_CAP)

            if not alloc_tech:
                return True

            return pool_id <= common.PQOS_API.get_max_cos_id(alloc_tech)

        json_data = request.get_json()

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

        data = common.CONFIG_STORE.get_config().copy()
        if 'pools' not in data:
            raise NotFound("No pools in config file")

        for pool in data['pools']:
            if pool['id'] != int(pool_id):
                continue

            if not check_alloc_tech(int(pool_id), json_data):
                raise BadRequest("Pool {} does not support requested technologies!"\
                    .format(pool_id))

            # set new cbm
            if 'cbm' in json_data:
                cbm = json_data['cbm']
                if not isinstance(cbm, int):
                    cbm = int(cbm, 16)

                pool['cbm'] = cbm

            # set new mba
            if 'mba' in json_data:
                pool['mba'] = json_data['mba']

            # set new cores
            if 'cores' in json_data:
                pool['cores'] = json_data['cores']

            # set new name
            if 'name' in json_data:
                pool['name'] = json_data['name']

            try:
                common.CONFIG_STORE.validate(data)
            except Exception as ex:
                raise BadRequest("POOL " + str(pool_id) + " not updated, " +
                                 str(ex))
            else:
                common.CONFIG_STORE.set_config(data)
                return "POOL " + str(pool_id) + " updated", 200

        raise NotFound("POOL " + str(pool_id) + " not found in config")
Example #16
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 #17
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