Esempio 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")
Esempio n. 2
0
    def get(profile_id):
        """
        Handles HTTP GET /power_profiles/<profile_id> request.
        Retrieve single power profile
        Raises NotFound

        Parameters:
            profile_id: Id of power profile to retrieve

        Returns:
            response, status code
        """

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

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

            return power, 200

        raise NotFound("Power profile " + str(profile_id) +
                       " not found in config")
Esempio n. 3
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")
Esempio n. 4
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")
Esempio n. 5
0
    def get(pool_id):
        """
        Handles HTTP GET /pools/<pool_id> request.
        Retrieve single pool
        Raises NotFound, BadRequest

        Parameters:
            pool_id: Id of pool to retrieve

        Returns:
            response, status code
        """

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

        try:
            pool = common.CONFIG_STORE.get_pool(data, int(pool_id))
        except:
            raise NotFound("POOL " + str(pool_id) + " not found in config")
        return pool, 200
Esempio n. 6
0
    def delete(app_id):
        """
        Handles HTTP DELETE /apps/<app_id> request.
        Deletes single App
        Raises NotFound, BadRequest

        Parameters:
            app_id: Id of app to delete

        Returns:
            response, status code
        """

        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' not in pool:
                    continue

                if app['id'] in pool['apps']:
                    pool['apps'].remove(app['id'])
                    break

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

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

        raise NotFound("APP " + str(app_id) + " not found in config")
Esempio n. 7
0
    def get():
        """
        Handles HTTP GET /power_profiles request.
        Retrieve all power profiles
        Raises NotFound

        Returns:
            response, status code
        """
        data = common.CONFIG_STORE.get_config()
        if 'power_profiles' not in data:
            raise NotFound("No power profiles in config file")

        return data['power_profiles'], 200
Esempio n. 8
0
    def get(app_id):
        """
        Handles HTTP GET /apps/<app_id> request.
        Retrieve single app
        Raises NotFound, BadRequest

        Parameters:
            app_id: Id of app to retrieve

        Returns:
            response, status code
        """

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

        try:
            app = common.CONFIG_STORE.get_app(data, int(app_id))
            app['pool_id'] = common.CONFIG_STORE.app_to_pool(int(app_id))
        except:
            raise NotFound("APP " + str(app_id) + " not found in config")

        return app, 200
Esempio n. 9
0
    def get():
        """
        Handles HTTP GET /apps request.
        Get all Apps
        Raises NotFound

        Returns:
            response, status code
        """
        data = common.CONFIG_STORE.get_config()
        if 'apps' not in data or not data['apps']:
            raise NotFound("No apps in config file")

        apps = data['apps']

        for app in apps:
            app['pool_id'] = common.CONFIG_STORE.app_to_pool(app['id'])

        return (data['apps']), 200
Esempio n. 10
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
Esempio n. 11
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")
Esempio n. 12
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")