diff options
author | cw1.shin <cw1.shin@samsung.net> | 2017-07-19 12:59:18 +0900 |
---|---|---|
committer | cw1.shin <cw1.shin@samsung.net> | 2017-07-19 12:59:18 +0900 |
commit | ede8ccd5f62da8c3c7b094b6442dc32ce19abfc0 (patch) | |
tree | 9237afafb47e0fb264405a83e685844a15f174c4 | |
parent | acdbf38308a4d40cc85ce75d57eb36da2a01d824 (diff) | |
download | tic-core-ede8ccd5f62da8c3c7b094b6442dc32ce19abfc0.tar.gz tic-core-ede8ccd5f62da8c3c7b094b6442dc32ce19abfc0.tar.bz2 tic-core-ede8ccd5f62da8c3c7b094b6442dc32ce19abfc0.zip |
[TPE-103] Separation of analysis api for performance
- Split analysis api into two api (views/repodata) for performance
- Add dependency rpm to building-block
Change-Id: I8caabd385a2d307597663044fe928972c5b45080
Signed-off-by: cw1.shin <cw1.shin@samsung.net>
-rw-r--r-- | tic/command.py | 97 | ||||
-rw-r--r-- | tic/parser/view_parser.py | 78 | ||||
-rw-r--r-- | tic/server/tic_server.py | 41 |
3 files changed, 145 insertions, 71 deletions
diff --git a/tic/command.py b/tic/command.py index ac981b7..ac56d24 100644 --- a/tic/command.py +++ b/tic/command.py @@ -61,20 +61,26 @@ def get_pkg_metadata(repoinfo, architecture): logger.debug('use a cache parsing data - %s', analysis_file) return pkg_group -def analyze(architecture, recipe_list): - - def _make_result_data(arch, repos, viewdata, pkggroup, inst_pkgs): - return {'arch': arch, - 'view': viewdata, - 'data': {'packages': pkggroup.get('pkg_dict'), - 'provides': pkggroup.get('provides'), - 'files': pkggroup.get('files'), - 'groups': pkggroup.get('groups'), - 'conflicts': pkggroup.get('conflicts'), - 'supplements': pkggroup.get('supplements')}, - 'recipes': repos, - 'installpackages': inst_pkgs} +def _make_result_data(arch, viewdata, pkggroup, inst_pkgs, repos = None): + return {'arch': arch, + 'view': viewdata, + 'data': {'packages': pkggroup.get('pkg_dict'), + 'provides': pkggroup.get('provides'), + 'files': pkggroup.get('files'), + 'groups': pkggroup.get('groups'), + 'conflicts': pkggroup.get('conflicts'), + 'supplements': pkggroup.get('supplements')}, + 'installpackages': inst_pkgs, + 'recipes': repos} + +def _getArchFromRecipe(recipe): + # architecture priority + # 1. settings arch 2. recipe arch 3. default arch(armv7l) + if is_valid_arch(recipe['Recipe'].get('Architecture')): + return recipe['Recipe']['Architecture'] + return DEFAULT_ARCHITECTURE +def analyze(architecture, recipe_list): logger = Logger().get_logger() if not recipe_list: logger.info('Use default recipe for package analysis') @@ -85,13 +91,8 @@ def analyze(architecture, recipe_list): recipe_parser.parse() recipe = recipe_parser.get_merged_recipe() - # architecture priority - # 1. settings arch 2. recipe arch 3. default arch(armv7l) if not is_valid_arch(architecture): - if is_valid_arch(recipe['Recipe'].get('Architecture')): - architecture = recipe['Recipe']['Architecture'] - else: - architecture = DEFAULT_ARCHITECTURE + architecture = _getArchFromRecipe(recipe) recipe_parser.set_arch(architecture) # Download repodata from repositories (Remote/Local) @@ -116,12 +117,66 @@ def analyze(architecture, recipe_list): logger.info('Number of installation packages: %d', len(inst_packages)) logger.debug('time to analyze dependency: %d ms', misc.get_timestamp() - start_time) result = _make_result_data(architecture, - recipe_parser.get_repositories(), view_data, pkg_group, - inst_packages) + inst_packages, + recipe_parser.get_repositories()) return result +def getViewdata(architecture, recipe_list): + logger = Logger().get_logger() + if not recipe_list: + logger.info('Use default recipe for package analysis') + recipe_list = default_recipe.get_default_parameter() + + # parse recipe + recipe_parser = RecipeParser(recipe_list, architecture) + recipe_parser.parse() + recipe = recipe_parser.get_merged_recipe() + + if not is_valid_arch(architecture): + architecture = _getArchFromRecipe(recipe) + recipe_parser.set_arch(architecture) + + # Download repodata from repositories (Remote/Local) + repoinfo = get_repodata_from_repos(recipe.get('Repositories'), DEFAULT_CACHEDIR) + if not repoinfo: + raise TICError('There is no valid repository content in recipes') + # paring repodata and get pkg metadata + pkg_group = get_pkg_metadata(repoinfo, architecture) + view_data = make_view_data(pkg_group) + return {'arch': architecture, 'view': view_data} + +def getRepodata(architecture, recipe_list): + logger = Logger().get_logger() + if not recipe_list: + logger.info('Use default recipe for package analysis') + recipe_list = default_recipe.get_default_parameter() + + # parse recipe + recipe_parser = RecipeParser(recipe_list, architecture) + recipe_parser.parse() + recipe = recipe_parser.get_merged_recipe() + + if not is_valid_arch(architecture): + architecture = _getArchFromRecipe(recipe) + recipe_parser.set_arch(architecture) + + # Download repodata from repositories (Remote/Local) + repoinfo = get_repodata_from_repos(recipe.get('Repositories'), DEFAULT_CACHEDIR) + if not repoinfo: + raise TICError('There is no valid repository content in recipes') + # paring repodata and get pkg metadata + pkg_group = get_pkg_metadata(repoinfo, architecture) + return {'arch': architecture, + 'repodata': {'packages': pkg_group.get('pkg_dict'), + 'provides': pkg_group.get('provides'), + 'files': pkg_group.get('files'), + 'groups': pkg_group.get('groups'), + 'conflicts': pkg_group.get('conflicts'), + 'supplements': pkg_group.get('supplements')}, + 'installpackages': recipe['Recipe'].get('ExtraPackages')} + def imports(architecture, recipe_list): logger = Logger().get_logger() if not is_valid_arch(architecture): diff --git a/tic/parser/view_parser.py b/tic/parser/view_parser.py index be01be7..92dd01c 100644 --- a/tic/parser/view_parser.py +++ b/tic/parser/view_parser.py @@ -90,7 +90,7 @@ def make_view_data(pkg_group): def make_meta_node(pkgname, viewtext): return dict(text=viewtext, metaname=pkgname, nodes=[]) def make_linked_meta_node(pkgname, viewtext, cat): - return dict(text=' <i>'+viewtext+'</i>', metaname=pkgname, nodes=[], category=cat, tooltip="This is a link of a building block.") + return dict(text=viewtext, metaname=pkgname, nodes=[], category=cat) def is_blank_ui_meta_node(pkgname): return (pkgname[-8:-2] == '__UI__') def handle_ui_meta_node(tag, node): @@ -132,27 +132,27 @@ def make_view_data(pkg_group): # Search for filename if directory is given # e.g., Convert http://a.com/a/ to https://a.com/a/blahblah.ks # Works for file-indexing html -# if ksURL[-3:].lower() != ".ks": -# m = None -# error = 0 -# if ksURL[-1:] != "/": -# ksURL += "/" -# r = requests.get(ksURL) -# if r.status_code == requests.codes.ok: -# m = re.search('>([^<]*\\.ks)\\s*<', r.text) -# else: -# error = 1 -# if error == 0 and not m: -# m = re.search('"([^"]*\\.ks)\\s*"', r.text) -# if not m: -# m = re.search("'([^']*\\.ks)\\s*'", r.text) -# if not m: -# error = 1 -# if error == 1: -# node['icon'] = 'glyphicon glyphicon-remove-sign' -# node['tooltip'] = 'Cannot find image base from' + ksURL -# return node -# ksURL += m.group(0) + if ksURL[-3:].lower() != ".ks": + m = None + error = 0 + if ksURL[-1:] != "/": + ksURL += "/" + r = requests.get(ksURL) + if r.status_code == requests.codes.ok: + m = re.search('>([^<]*\\.ks)\\s*<', r.text) + else: + error = 1 + if error == 0 and not m: + m = re.search('"([^"]*\\.ks)\\s*"', r.text) + if not m: + m = re.search("'([^']*\\.ks)\\s*'", r.text) + if not m: + error = 1 + if error == 1: + node['icon'] = 'glyphicon glyphicon-remove-sign' + node['tooltip'] = 'Cannot find image base from' + ksURL + return node + ksURL += m.group(0) node['tooltip'] = 'Image base from '+ksURL node['icon'] = 'glyphicon glyphicon-list-alt' node['ks'] = ksURL @@ -205,30 +205,12 @@ def make_view_data(pkg_group): if root[0] in category_dict: root_node['category'] = category_dict[root[0]] else: - # Backup routine for GBS, which does not seem to publish suggest info correctly. - # TODO: This routine has hardcoded category names, which should be improved. - m = re.search('(?<=root-)[a-zA-Z]*', root[0]) - if m: - cat = m.group(0) - if cat == 'domain': - cat = 'domains' - if cat == 'feature': - cat = 'epicfeatures' - root_node['category'] = cat - logger.debug("Fallback for "+cat+" for "+root[0]) - if is_blank_ui_meta_node(root[0]): - name = root[0] - sub1_node = handle_ui_meta_node(name[-2:], root_node) - root_node = handle_description(root_node) + logger.debug('%s has the wrong category name.' % root_node.get('metaname')) view_data.append(root_node) for sub1 in meta_info['sub1']: sub1_node = make_meta_node(sub1[0], sub1[2]) view_ref[sub1[0]] = sub1_node - if is_blank_ui_meta_node(sub1[0]): - name = sub1[0] - sub1_node = handle_ui_meta_node(name[-2:], sub1_node) - sub1_node = handle_description(sub1_node) # search root if sub1[1] in view_ref: # add to root node @@ -242,10 +224,6 @@ def make_view_data(pkg_group): for sub2 in meta_info['sub2']: sub2_node = make_meta_node(sub2[0], sub2[3]) view_ref[sub2[0]] = sub2_node - if is_blank_ui_meta_node(sub2[0]): - name = sub2[0] - sub1_node = handle_ui_meta_node(name[-2:], sub2_node) - sub2_node = handle_description(sub2_node) # search sub1 if sub2[2] in view_ref: if 'category' in view_ref[sub2[2]] and view_ref[sub2[2]]['category']: @@ -264,16 +242,16 @@ def make_view_data(pkg_group): # configure meta dependency tree (requires) for meta_pkg in view_data: set_meta_require(meta_pkg) - - #The remaining rpms are grouped into a MISC tree + + #The non-blocks rpms are grouped into a MISC tree misc_info = {} misc_info['text'] = 'Advanced (individual packages)' misc_info['nodes'] = [] for k, v in pkg_dict.iteritems(): - # Add ALL non-block packages - if v['name'][0:15] != 'building-blocks': + if v.get('meta') is None: misc_info['nodes'].append(make_node(v)) - misc_info['nodes'] = sorted(misc_info['nodes'], key = lambda k: k['metaname'] if 'metaname' in k else k['text']) + #sort by rpm's name + misc_info['nodes'] = sorted(misc_info['nodes'], key = lambda k: k['text']) view_data.append(misc_info) logger.info('meta rpms: %d, rpms: %d', len(view_ref), len(misc_info['nodes'])) diff --git a/tic/server/tic_server.py b/tic/server/tic_server.py index 5004e93..5b70791 100644 --- a/tic/server/tic_server.py +++ b/tic/server/tic_server.py @@ -58,6 +58,47 @@ def analysis(): resp = makeresponse(str(ex), ex) return resp + +@app.route('/views', methods=['POST']) +def views(): + try: + logger = Logger().get_logger() + logger.info('%s - %s %s : data=%s' % (request.remote_addr, request.method, request.path, request.data)) + target_info = json.loads(request.data) + view_data = command.getViewdata(target_info.get('arch'), + target_info.get('recipes')) + resp = makeresponse(view_data, None) + except error.TICError as err: + logger.error(err) + resp = makeresponse(str(err), err) + except ValueError as ve: + logger.error(ve) + resp = makeresponse(str(ve), ve) + except Exception as ex: + logger.error(traceback.print_exc()) + resp = makeresponse(str(ex), ex) + return resp + +@app.route('/repodatas', methods=['POST']) +def repodatas(): + try: + logger = Logger().get_logger() + logger.info('%s - %s %s : data=%s' % (request.remote_addr, request.method, request.path, request.data)) + target_info = json.loads(request.data) + repodata = command.getRepodata(target_info.get('arch'), + target_info.get('recipes')) + resp = makeresponse(repodata, None) + except error.TICError as err: + logger.error(err) + resp = makeresponse(str(err), err) + except ValueError as ve: + logger.error(ve) + resp = makeresponse(str(ve), ve) + except Exception as ex: + logger.error(traceback.print_exc()) + resp = makeresponse(str(ex), ex) + return resp + @app.route('/imports', methods=['POST']) def imports(): try: |