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