summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcw1.shin <cw1.shin@samsung.net>2017-07-19 12:59:18 +0900
committercw1.shin <cw1.shin@samsung.net>2017-07-19 12:59:18 +0900
commitede8ccd5f62da8c3c7b094b6442dc32ce19abfc0 (patch)
tree9237afafb47e0fb264405a83e685844a15f174c4
parentacdbf38308a4d40cc85ce75d57eb36da2a01d824 (diff)
downloadtic-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.py97
-rw-r--r--tic/parser/view_parser.py78
-rw-r--r--tic/server/tic_server.py41
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='&nbsp;&nbsp;<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: