Ejemplo n.º 1
0
    def delete(pool_id):
        """
        Handles HTTP DELETE /pool/<pull_id> request.
        Deletes single Pool
        Raises NotFound, BadRequest

        Parameters:
            pool_id: Id of pool to delete

        Returns:
            response, status code
        """

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

        if int(pool_id) == 0:
            raise BadRequest("POOL " + str(pool_id) + " is Default, cannot delete")

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

            if 'apps' in pool and pool['apps']:
                raise BadRequest("POOL " + str(pool_id) + " is not empty")

            # remove app
            data['pools'].remove(pool)
            common.CONFIG_STORE.set_config(data)

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

        raise NotFound("POOL " + str(pool_id) + " not found in config")
Ejemplo n.º 2
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
Ejemplo n.º 3
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
Ejemplo n.º 4
0
        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))
Ejemplo n.º 5
0
    def put(profile_id):
        # pylint: disable=too-many-branches
        """
        Handles HTTP PUT /power_profiles/<profile_id> request.
        Modifies a Power Profile
        Raises NotFound, BadRequest

        Parameters:
            profile_id: Id of pool

        Returns:
            response, status code
        """

        json_data = request.get_json()

        # validate app schema
        try:
            schema, resolver = common.CONFIG_STORE.load_json_schema(
                'modify_power.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)

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

        for profile in data['power_profiles']:
            if profile['id'] != int(profile_id):
                continue

            # set new values
            profile.update(json_data)

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

            common.CONFIG_STORE.set_config(data)

            res = {'message': "POWER PROFILE " + str(profile_id) + " updated"}
            return res, 200

        raise NotFound("POWER PROFILE" + str(profile_id) +
                       " not found in config")
Ejemplo n.º 6
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
Ejemplo n.º 7
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
Ejemplo n.º 8
0
    def post():
        """
        Handles HTTP POST /power_profiles request.
        Add a new Power Profile
        Raises BadRequest

        Returns:
            response, status code
        """

        # validate power profile schema
        json_data = request.get_json()

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

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

        data = deepcopy(common.CONFIG_STORE.get_config())
        if 'power_profiles' not in data:
            data['power_profiles'] = []
        data['power_profiles'].append(json_data)

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

        common.CONFIG_STORE.set_config(data)

        res = {
            'id': json_data['id'],
            'message': "New POWER PROFILE {} added".format(json_data['id'])
        }

        return res, 201
Ejemplo n.º 9
0
    def delete(profile_id):
        """
        Handles HTTP DELETE /power_profiles/<profile_id> request.
        Deletes single Power Profile
        Raises NotFound, BadRequest

        Parameters:
            profile_id: Id of power_profile to delete

        Returns:
            response, status code
        """

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

        if 'power_profiles' not in data:
            raise NotFound("No Power Profiles in config file")

        for profile in data['power_profiles']:
            if profile['id'] != int(profile_id):
                continue

            for pool in data['pools']:
                if 'power_profile' not in pool:
                    continue

                if pool['power_profile'] == int(profile_id):
                    raise BadRequest("POWER PROFILE {} is in use.".format(
                        str(profile_id)))

            # remove profile
            data['power_profiles'].remove(profile)
            common.CONFIG_STORE.set_config(data)

            res = {'message': "POWER PROFILE " + str(profile_id) + " deleted"}
            return res, 200

        raise NotFound("POWER PROFILE " + str(profile_id) +
                       " not found in config")
Ejemplo n.º 10
0
        def check_alloc_tech(pool_id, json_data):
            if 'cbm' in json_data:
                if not caps.cat_l3_supported():
                    raise BadRequest("System does not support CAT!")
                if pool_id > common.PQOS_API.get_max_cos_id([common.CAT_L3_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.")
Ejemplo n.º 11
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
Ejemplo n.º 12
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")
Ejemplo n.º 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:
                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))

        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

            # 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']

            # 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")