| Summary: | layerindex: Branch Comparison throws Internal Server Error | ||
|---|---|---|---|
| Product: | [Yocto Project Subprojects] Layer Index | Reporter: | Tim Orling <tim.orling> |
| Component: | Layer Index | Assignee: | Tim Orling <tim.orling> |
| Status: | IN PROGRESS REVIEW --- | QA Contact: | apoorv sangal <apoorvsangal> |
| Severity: | major | ||
| Priority: | Medium+ | CC: | randy.macleod |
| Version: | 5.0 | ||
| Target Milestone: | 6.2 M1 | ||
| Hardware: | x86 | ||
| OS: | Multiple | ||
| Whiteboard: | |||
| OS type for building Yocto: | --- | Type of Regression: | --- |
| Verified: | Documentation change: | No (bug/feature does not impact docs) | |
The issue is a typo in: https://git.yoctoproject.org/layerindex-web/tree/layerindex/views.py#n1794 recipe.to_versions = sorted(recipe.to_versions, key=lambda item: parser_version(item.pv)) Where parser_version should be parse_version. https://patchwork.yoctoproject.org/project/yocto/patch/01094d0e2a2c4f8df9feea877b2159677c642ab8.1703911977.git.tim.orling@konsulko.com/ This one was subtle. VSCode syntax highlighting is to be credited with actually catching the fix (although in hindsight the debug log was fairly obvious). Fixed in: https://git.yoctoproject.org/layerindex-web/commit/?id=a03b314bc1a0aea6f702c896a45a9e6376779569 If you try any other layer, such as meta-oe, you will still get an Internal Server Error:
Environment:
Request Method: GET
Request URL: http://<local instance>/layerindex/branch_comparison/?from_branch=29&to_branch=1&layers=2%2C1&l=2&l=1
Django Version: 4.2.9
Python Version: 3.10.12
Installed Applications:
('django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'django.contrib.admindocs',
'layerindex',
'rrs',
'django_registration',
'reversion',
'reversion_compare',
'captcha',
'axes',
'rest_framework',
'corsheaders')
Installed Middleware:
('corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'axes.middleware.AxesMiddleware',
'layerindex.middleware.NonAtomicRevisionMiddleware')
Traceback (most recent call last):
File "/usr/local/lib/python3.10/dist-packages/django/db/models/fields/__init__.py", line 2053, in get_prep_value
return int(value)
The above exception (invalid literal for int() with base 10: ',') was the direct cause of the following exception:
File "/usr/local/lib/python3.10/dist-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
File "/usr/local/lib/python3.10/dist-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.10/dist-packages/django/views/generic/base.py", line 104, in view
return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.10/dist-packages/django/views/generic/base.py", line 143, in dispatch
return handler(request, *args, **kwargs)
File "/usr/local/lib/python3.10/dist-packages/django/views/generic/edit.py", line 144, in get
return self.render_to_response(self.get_context_data())
File "/opt/layerindex/layerindex/views.py", line 1875, in get_context_data
context['added'], context['changed'], context['removed'] = self.get_recipes(from_branch, to_branch, layer_ids)
File "/opt/layerindex/layerindex/views.py", line 1811, in get_recipes
from_recipes = from_recipes.filter(layerbranch__layer__in=layer_ids)
File "/usr/local/lib/python3.10/dist-packages/django/db/models/query.py", line 1436, in filter
return self._filter_or_exclude(False, args, kwargs)
File "/usr/local/lib/python3.10/dist-packages/django/db/models/query.py", line 1454, in _filter_or_exclude
clone._filter_or_exclude_inplace(negate, args, kwargs)
File "/usr/local/lib/python3.10/dist-packages/django/db/models/query.py", line 1461, in _filter_or_exclude_inplace
self._query.add_q(Q(*args, **kwargs))
File "/usr/local/lib/python3.10/dist-packages/django/db/models/sql/query.py", line 1546, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "/usr/local/lib/python3.10/dist-packages/django/db/models/sql/query.py", line 1577, in _add_q
child_clause, needed_inner = self.build_filter(
File "/usr/local/lib/python3.10/dist-packages/django/db/models/sql/query.py", line 1492, in build_filter
condition = self.build_lookup(lookups, col, value)
File "/usr/local/lib/python3.10/dist-packages/django/db/models/sql/query.py", line 1319, in build_lookup
lookup = lookup_class(lhs, rhs)
File "/usr/local/lib/python3.10/dist-packages/django/db/models/lookups.py", line 27, in __init__
self.rhs = self.get_prep_lookup()
File "/usr/local/lib/python3.10/dist-packages/django/db/models/fields/related_lookups.py", line 92, in get_prep_lookup
self.rhs = [target_field.get_prep_value(v) for v in self.rhs]
File "/usr/local/lib/python3.10/dist-packages/django/db/models/fields/related_lookups.py", line 92, in <listcomp>
self.rhs = [target_field.get_prep_value(v) for v in self.rhs]
File "/usr/local/lib/python3.10/dist-packages/django/db/models/fields/__init__.py", line 2055, in get_prep_value
raise e.__class__(
Exception Type: ValueError at /layerindex/branch_comparison/
Exception Value: Field 'id' expected a number but got ','.
If you clear 'openembedded-core' and add only 'meta-oe' the comparison succeeds. So it looks like multiple selections are not being split() properly or something along those lines. Successful: https://layers.openembedded.org/layerindex/branch_comparison/?from_branch=29&to_branch=1&layers=2&l=2 vs. Failure: https://layers.openembedded.org/layerindex/branch_comparison/?from_branch=29&to_branch=1&layers=2%2C1&l=2&l=1 So the way that URL is being combined is not being handled as expected. Also, for some reason, meta-ros2-humble cannot be compared from nanbield to master (even though both LayerBranches exist): https://layers.openembedded.org/layerindex/branch_comparison/?from_branch=29&to_branch=1&layers=602&l=602 Something is wrong with the layer_id parsing, because if you hand code an url, like https://layers.openembedded.org/layerindex/branch_comparison/?from_branch=14&to_branch=30&layers=2 It properly shows the changes from sumo to scarthgap for meta-oe (layer_id = 2). If you click on the Plain Text button, you can see only one layer was selected: " From sumo (Yocto Project 2.5) to scarthgap (Yocto Project 5.0) (layers: meta-oe) Added ----- abseil-cpp 20240116.2 ace 6.5.19 ace-cloud-editor 02.07.17+git ... " If you choose any layer with more than 1 digit, such as meta-virtualization (which appears to be layer_id = 59) you instead see layer_id = 5 (e100-bsp) and layer_id = 9 (meta-gumstix) chosen! https://layers.openembedded.net/layerindex/branch_comparison/?from_branch=14&to_branch=30&layers=59 " From sumo (Yocto Project 2.5) to scarthgap (Yocto Project 5.0) (layers: e100-bsp, meta-gumstix) ... " If you use the GUI to select only meta-virtualization in the filter, the resulting URL is: https://layers.openembedded.net/layerindex/branch_comparison/?from_branch=14&to_branch=30&layers=59&l=59 Which still resolves to the same two layers above (layer_id = 5 and layer_id = 9) If you start with the default GUI (where oe-core is selected) and then add meta-virtualization, the resulting URL throws an Internal Server Error (expecting a layer_id and gets a ','): https://layers.moto-timo.net/layerindex/branch_comparison/?from_branch=14&to_branch=30&layers=59%2C1&l=59&l=1 So the drop down menu is not creating a proper URL, and more than single digit layer_id is not being parsed properly. The answer is rather obvious in hindsight. If you want a list of items to iterate on, ask for a list. (self.request.GET.getlist NOT self.request.GET.get). The first gives you a list, the second gives you a string which if you iterate over it, you get char.
diff --git a/layerindex/views.py b/layerindex/views.py
index 49bda30..908dfe1 100644
--- a/layerindex/views.py
+++ b/layerindex/views.py
@@ -1858,7 +1858,7 @@ class BranchCompareView(FormView):
to_branch_id = self.request.GET.get('to_branch', None)
if to_branch_id is not None:
initial['to_branch'] = get_object_or_404(Branch, id=to_branch_id)
- initial['layers'] = self.request.GET.get('layers', int(LayerItem.objects.get(name=settings.CORE_LAYER_NAME).id))
+ initial['layers'] = self.request.GET.getlist('layers', int(LayerItem.objects.get(name=settings.CORE_LAYER_NAME).id))
logger.debug(f"initial['layers']: {initial['layers']}")
return initial
@@ -1867,7 +1867,7 @@ class BranchCompareView(FormView):
from_branch_id = self.request.GET.get('from_branch', None)
to_branch_id = self.request.GET.get('to_branch', None)
- layer_ids = list(self.request.GET.get('layers', int(LayerItem.objects.get(name=settings.CORE_LAYER_NAME).id)))
+ layer_ids = self.request.GET.getlist('layers', int(LayerItem.objects.get(name=settings.CORE_LAYER_NAME).id))
from_branch = None
if from_branch_id is not None:
from_branch = get_object_or_404(Branch, id=from_branch_id)
|
If you try to compare e.g. "master" to "nanbield", an Internal Server Error is thrown. The debug output gives us a strong hint: NameError at /layerindex/branch_comparison/ name 'parser_version' is not defined ... Traceback (most recent call last): File "/usr/local/lib/python3.10/dist-packages/django/core/handlers/exception.py", line 55, in inner response = get_response(request) File "/usr/local/lib/python3.10/dist-packages/django/core/handlers/base.py", line 197, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/usr/local/lib/python3.10/dist-packages/django/views/generic/base.py", line 104, in view return self.dispatch(request, *args, **kwargs) File "/usr/local/lib/python3.10/dist-packages/django/views/generic/base.py", line 143, in dispatch return handler(request, *args, **kwargs) File "/usr/local/lib/python3.10/dist-packages/django/views/generic/edit.py", line 144, in get return self.render_to_response(self.get_context_data()) File "/opt/layerindex/layerindex/views.py", line 1850, in get_context_data context['added'], context['changed'], context['removed'] = self.get_recipes(from_branch, to_branch, layer_ids) File "/opt/layerindex/layerindex/views.py", line 1810, in get_recipes recipe.to_versions = sorted(recipe.to_versions, key=lambda item: parser_version(item.pv)) File "/opt/layerindex/layerindex/views.py", line 1810, in <lambda> recipe.to_versions = sorted(recipe.to_versions, key=lambda item: parser_version(item.pv)) Exception Type: NameError at /layerindex/branch_comparison/ Exception Value: name 'parser_version' is not defined Raised during: layerindex.views.BranchCompareView ...