diff options
author | Michael Wood <michael.g.wood@intel.com> | 2016-05-26 16:12:23 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2016-06-15 08:35:04 +0100 |
commit | caae3b6206dc31690f0c6638daaa7bb072c69042 (patch) | |
tree | 780fc9c4e430f93e1b1ae8d522ee921e82515876 /bitbake | |
parent | b2a68f55110b39aaf0b0d47bf533251a59a40a41 (diff) | |
download | openembedded-core-contrib-caae3b6206dc31690f0c6638daaa7bb072c69042.tar.gz |
bitbake: toaster: port Installed packages table to ToasterTable
(Bitbake rev: 2418c092abd9a503becf5e786125f8cdddd8652c)
Signed-off-by: Michael Wood <michael.g.wood@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r-- | bitbake/lib/toaster/toastergui/buildtables.py | 63 | ||||
-rw-r--r-- | bitbake/lib/toaster/toastergui/templates/builddashboard.html | 4 | ||||
-rw-r--r-- | bitbake/lib/toaster/toastergui/templates/target.html | 118 | ||||
-rw-r--r-- | bitbake/lib/toaster/toastergui/urls.py | 9 | ||||
-rwxr-xr-x | bitbake/lib/toaster/toastergui/views.py | 169 |
5 files changed, 75 insertions, 288 deletions
diff --git a/bitbake/lib/toaster/toastergui/buildtables.py b/bitbake/lib/toaster/toastergui/buildtables.py index 51c136f988..17de369305 100644 --- a/bitbake/lib/toaster/toastergui/buildtables.py +++ b/bitbake/lib/toaster/toastergui/buildtables.py @@ -19,8 +19,8 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -from orm.models import Build, Task -from django.db.models import Q +from orm.models import Build, Task, Target, Package +from django.db.models import Q, Sum import toastergui.tables as tables from toastergui.widgets import ToasterTable @@ -155,6 +155,65 @@ class BuiltPackagesTable(BuildTablesMixin, BuiltPackagesTableBase): self.columns = list(remove_dep_cols(self.columns)) +class InstalledPackagesTable(BuildTablesMixin, BuiltPackagesTableBase): + """ Show all packages installed in an image """ + def __init__(self, *args, **kwargs): + super(InstalledPackagesTable, self).__init__(*args, **kwargs) + self.title = "Installed Packages" + self.default_orderby = "name" + + def make_package_list(self, target): + # The database design means that you get the intermediate objects and + # not package objects like you'd really want so we get them here + pkgs = target.target_installed_package_set.values_list('package', + flat=True) + return Package.objects.filter(pk__in=pkgs) + + def get_context_data(self, **kwargs): + context = super(InstalledPackagesTable, + self).get_context_data(**kwargs) + + target = Target.objects.get(pk=kwargs['target_id']) + packages = self.make_package_list(target) + + context['packages_sum'] = packages.aggregate( + Sum('installed_size'))['installed_size__sum'] + + context['target'] = target + return context + + def setup_queryset(self, *args, **kwargs): + build = Build.objects.get(pk=kwargs['build_id']) + self.static_context_extra['build'] = build + + target = Target.objects.get(pk=kwargs['target_id']) + self.queryset = self.make_package_list(target) + + def setup_columns(self, *args, **kwargs): + super(InstalledPackagesTable, self).setup_columns(**kwargs) + self.add_column(title="Installed size", + static_data_name="installed_size", + static_data_template="{% load projecttags %}" + "{{data.size|filtered_filesizeformat}}", + orderable=True) + + # Add the template to show installed name for installed packages + install_name_tmpl =\ + ('{{data.name}} ' + '{% if data.installed_name and data.installed_name !=' + ' data.name %}' + '<span class="muted"> as {{data.installed_name}}</span>' + ' <i class="icon-question-sign get-help hover-help"' + ' title="{{data.name}} was renamed at packaging time and' + ' was installed in your image as {{data.installed_name}}' + '"></i>{% endif %} ') + + for column in self.columns: + if column['static_data_name'] == 'name': + column['static_data_template'] = install_name_tmpl + break + + class BuiltRecipesTable(BuildTablesMixin): """ Table to show the recipes that have been built in this build """ diff --git a/bitbake/lib/toaster/toastergui/templates/builddashboard.html b/bitbake/lib/toaster/toastergui/templates/builddashboard.html index 5425dfe610..f33757eaca 100644 --- a/bitbake/lib/toaster/toastergui/templates/builddashboard.html +++ b/bitbake/lib/toaster/toastergui/templates/builddashboard.html @@ -102,7 +102,7 @@ files from a previous build already exist in your <code>.../poky/build/tmp/deploy</code> directory. You can - also <a href="{% url 'targetpkg' build.pk target.target.pk %}">view the + also <a href="{% url 'target' build.pk target.target.pk %}">view the license manifest information</a> in Toaster. </p> </div> @@ -115,7 +115,7 @@ License manifest </dt> <dd> - <a href="{% url 'targetpkg' build.pk target.target.pk %}">View in Toaster</a> | + <a href="{% url 'target' build.pk target.target.pk %}">View in Toaster</a> | <a href="{% url 'build_artifact' build.pk 'licensemanifest' target.target.pk %}">Download</a></dd> <dt> <i class="icon-question-sign get-help" title="Image files are stored in <code>/build/tmp/deploy/images/</code>"></i> diff --git a/bitbake/lib/toaster/toastergui/templates/target.html b/bitbake/lib/toaster/toastergui/templates/target.html index 9f31239d8e..0b2fe99577 100644 --- a/bitbake/lib/toaster/toastergui/templates/target.html +++ b/bitbake/lib/toaster/toastergui/templates/target.html @@ -17,9 +17,7 @@ {% endblock %} {% block buildinfomain %} - <div class="col-md-10"> - <div class="page-header"> <h1> {% if request.GET.search and objects.paginator.count > 0 %} @@ -31,8 +29,6 @@ {% endif %} </h1> </div> - - <div id="navTab"> <ul class="nav nav-pills"> <li class="active"> @@ -50,113 +46,11 @@ </ul> <div id="image-packages" class="tab-pane"> - - {% if objects.paginator.count == 0 %} - <div class="alert"> - <form class="no-results input-append" id="searchform"> - <input id="search" name="search" class="input-xxlarge" type="text" value="{% if request.GET.search %}{{request.GET.search}}{% endif %}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="input-append-addon btn" tabindex="-1"><i class="glyphicon glyphicon-remove"></i></a>{% endif %} - <button class="btn" type="submit" value="Search">Search</button> - <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all packages</button> - </form> - </div> - - - {% else %} - {% include "basetable_top.html" %} - {% for package in objects %} - <tr> - {# order of the table data must match the columns defined in template's context tablecols #} - <td class="package_name"> - <a href="{% url 'package_included_detail' build.id target.id package.id %}"> - {{package.name}} - </a> - {% if package.installed_name and package.name != package.installed_name %} - <span class="muted"> as {{package.installed_name}}</span> - <i class="icon-question-sign get-help hover-help" title='{{package.name|add:" was renamed at packaging time and was installed in your image as "|add:package.installed_name}}'></i> - {% endif %} - </td> - <td class="package_version"> - <a href="{% url 'package_included_detail' build.id target.id package.id %}"> - {{package.version|filtered_packageversion:package.revision}} - </a> - </td> - <td class="license"> - {{package.license}} - </td> - <td class="size sizecol"> - {{package.size|filtered_installedsize:package.installed_size|filtered_filesizeformat}} - </td> - - <td class="size_over_total sizecol"> - {{package|filter_sizeovertotal:packages_sum}} - </td> - <td class="depends"> - {% with deps=package.runtime_dependencies %} - {% with deps_count=deps|length %} - {% if deps_count > 0 %} - <a class="btn" - title="<a href='{% url "package_included_dependencies" build.id target.id package.id %}'>{{package.name}}</a> dependencies" - data-content="<ul class='list-unstyled'> - {% for i in deps|dictsort:'depends_on.name' %} - <li><a href='{% url "package_included_detail" build.pk target.id i.depends_on.pk %}'>{{i.depends_on.name}}</a></li> - {% endfor %} - </ul>"> - {{deps_count}} - </a> - {% endif %} - {% endwith %} - {% endwith %} - </td> - <td class="brought_in_by"> - {% with rdeps=package.reverse_runtime_dependencies %} - {% with rdeps_count=rdeps|length %} - {% if rdeps_count > 0 %} - <a class="btn" - title="<a href='{% url "package_included_reverse_dependencies" build.id target.id package.id %}'>{{package.name}}</a> reverse dependencies" - data-content="<ul class='list-unstyled'> - {% for i in rdeps|dictsort:'package.name' %} - <li><a href='{% url "package_included_detail" build.id target.id i.package.id %}'>{{i.package.name}}</a></li> - {% endfor %} - </ul>"> - {{rdeps_count}} - </a> - {% endif %} - {% endwith %} - {% endwith %} - </td> - <td class="recipe_name"> - {% if package.recipe.version %} - <a href="{% url 'recipe' build.id package.recipe_id %}"> - {{ package.recipe.name }} - </a> - {% endif %} - </td> - <td class="recipe_version"> - {% if package.recipe.version %} - <a href="{% url 'recipe' build.id package.recipe_id %}"> - {{ package.recipe.version }} - </a> - {% endif %} - </td> - <td class="layer_name"> - {{ package.recipe.layer_version.layer.name }} - </td> - <td class="layer_branch"> - {{ package.recipe.layer_version.branch}} - </td> - <td class="layer_commit"> - <a class="btn" - data-content="<ul class='list-unstyled'> - <li>{{package.recipe.layer_version.commit}}</li> - </ul>"> - {{package.recipe.layer_version.commit|truncatechars:13}} - </a> - </td> - </tr> - {% endfor %} - - {% include "basetable_bottom.html" %} - {% endif %} + {# xhr_table_url is just the current url so leave it blank #} + {% with xhr_table_url='' %} + {% include "toastertable.html" %} + {% endwith %} </div> <!-- tabpane --> -</div> <!--span 10--> + </div> <!--navTab -->> +<!-- col-md-10 --> {% endblock buildinfomain %} diff --git a/bitbake/lib/toaster/toastergui/urls.py b/bitbake/lib/toaster/toastergui/urls.py index c4913f124a..9510a386ea 100644 --- a/bitbake/lib/toaster/toastergui/urls.py +++ b/bitbake/lib/toaster/toastergui/urls.py @@ -68,9 +68,12 @@ urlpatterns = patterns('toastergui.views', url(r'^build/(?P<build_id>\d+)/package_included_reverse_dependencies/(?P<target_id>\d+)/(?P<package_id>\d+)$', 'package_included_reverse_dependencies', name='package_included_reverse_dependencies'), - # images are known as targets in the internal model - url(r'^build/(?P<build_id>\d+)/target/(?P<target_id>\d+)$', 'target', name='target'), - url(r'^build/(?P<build_id>\d+)/target/(?P<target_id>\d+)/targetpkg$', 'targetpkg', name='targetpkg'), + url(r'^build/(?P<build_id>\d+)/target/(?P<target_id>\d+)$', + buildtables.InstalledPackagesTable.as_view( + template_name="target.html"), + name='target'), + + url(r'^dentries/build/(?P<build_id>\d+)/target/(?P<target_id>\d+)$', 'xhr_dirinfo', name='dirinfo_ajax'), url(r'^build/(?P<build_id>\d+)/target/(?P<target_id>\d+)/dirinfo$', 'dirinfo', name='dirinfo'), url(r'^build/(?P<build_id>\d+)/target/(?P<target_id>\d+)/dirinfo_filepath/_(?P<file_path>(?:/[^/\n]+)*)$', 'dirinfo', name='dirinfo_filepath'), diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py index 35ab63a22e..88bc39a166 100755 --- a/bitbake/lib/toaster/toastergui/views.py +++ b/bitbake/lib/toaster/toastergui/views.py @@ -681,175 +681,6 @@ def recipe_packages(request, build_id, recipe_id): _set_parameters_values(pagesize, orderby, request) return response -def target_common( request, build_id, target_id, variant ): - template = "target.html" - default_orderby = 'name:+' - - (pagesize, orderby) = _get_parameters_values(request, 25, default_orderby) - mandatory_parameters = { 'count': pagesize, 'page' : 1, 'orderby': orderby } - retval = _verify_parameters( request.GET, mandatory_parameters ) - if retval: - return _redirect_parameters( - variant, request.GET, mandatory_parameters, - build_id = build_id, target_id = target_id ) - ( filter_string, search_term, ordering_string ) = _search_tuple( request, Package ) - - # FUTURE: get rid of nested sub-queries replacing with ManyToMany field - queryset = Package.objects.filter( - size__gte = 0, - id__in = Target_Installed_Package.objects.filter( - target_id=target_id ).values( 'package_id' )) - packages_sum = queryset.aggregate( Sum( 'installed_size' )) - queryset = _get_queryset( - Package, queryset, filter_string, search_term, ordering_string, 'name' ) - queryset = queryset.select_related("recipe", "recipe__layer_version", "recipe__layer_version__layer") - packages = _build_page_range( Paginator(queryset, pagesize), request.GET.get( 'page', 1 )) - - build = Build.objects.get( pk = build_id ) - - # bring in package dependencies - for p in packages.object_list: - p.runtime_dependencies = p.package_dependencies_source.filter( - target_id = target_id, dep_type=Package_Dependency.TYPE_TRDEPENDS ).select_related("depends_on") - p.reverse_runtime_dependencies = p.package_dependencies_target.filter( - target_id = target_id, dep_type=Package_Dependency.TYPE_TRDEPENDS ).select_related("package") - tc_package = { - 'name' : 'Package', - 'qhelp' : 'Packaged output resulting from building a recipe included in this image', - 'orderfield' : _get_toggle_order( request, "name" ), - 'ordericon' : _get_toggle_order_icon( request, "name" ), - } - tc_packageVersion = { - 'name' : 'Package version', - 'qhelp' : 'The package version and revision', - } - tc_size = { - 'name' : 'Size', - 'qhelp' : 'The size of the package', - 'orderfield' : _get_toggle_order( request, "size", True ), - 'ordericon' : _get_toggle_order_icon( request, "size" ), - 'orderkey' : 'size', - 'clclass' : 'size', - 'dclass' : 'span2', - } - if ( variant == 'target' ): - tc_size[ "hidden" ] = 0 - else: - tc_size[ "hidden" ] = 1 - tc_sizePercentage = { - 'name' : 'Size over total (%)', - 'qhelp' : 'Proportion of the overall size represented by this package', - 'clclass' : 'size_over_total', - 'hidden' : 1, - } - tc_license = { - 'name' : 'License', - 'qhelp' : 'The license under which the package is distributed. Separate license names u\ -sing | (pipe) means there is a choice between licenses. Separate license names using & (ampersand) m\ -eans multiple licenses exist that cover different parts of the source', - 'orderfield' : _get_toggle_order( request, "license" ), - 'ordericon' : _get_toggle_order_icon( request, "license" ), - 'orderkey' : 'license', - 'clclass' : 'license', - } - if ( variant == 'target' ): - tc_license[ "hidden" ] = 1 - else: - tc_license[ "hidden" ] = 0 - tc_dependencies = { - 'name' : 'Dependencies', - 'qhelp' : "Package runtime dependencies (other packages)", - 'clclass' : 'depends', - } - if ( variant == 'target' ): - tc_dependencies[ "hidden" ] = 0 - else: - tc_dependencies[ "hidden" ] = 1 - tc_rdependencies = { - 'name' : 'Reverse dependencies', - 'qhelp' : 'Package run-time reverse dependencies (i.e. which other packages depend on this package', - 'clclass' : 'brought_in_by', - } - if ( variant == 'target' ): - tc_rdependencies[ "hidden" ] = 0 - else: - tc_rdependencies[ "hidden" ] = 1 - tc_recipe = { - 'name' : 'Recipe', - 'qhelp' : 'The name of the recipe building the package', - 'orderfield' : _get_toggle_order( request, "recipe__name" ), - 'ordericon' : _get_toggle_order_icon( request, "recipe__name" ), - 'orderkey' : "recipe__name", - 'clclass' : 'recipe_name', - 'hidden' : 0, - } - tc_recipeVersion = { - 'name' : 'Recipe version', - 'qhelp' : 'Version and revision of the recipe building the package', - 'clclass' : 'recipe_version', - 'hidden' : 1, - } - tc_layer = { - 'name' : 'Layer', - 'qhelp' : 'The name of the layer providing the recipe that builds the package', - 'orderfield' : _get_toggle_order( request, "recipe__layer_version__layer__name" ), - 'ordericon' : _get_toggle_order_icon( request, "recipe__layer_version__layer__name" ), - 'orderkey' : "recipe__layer_version__layer__name", - 'clclass' : 'layer_name', - 'hidden' : 1, - } - tc_layerBranch = { - 'name' : 'Layer branch', - 'qhelp' : 'The Git branch of the layer providing the recipe that builds the package', - 'orderfield' : _get_toggle_order( request, "recipe__layer_version__branch" ), - 'ordericon' : _get_toggle_order_icon( request, "recipe__layer_version__branch" ), - 'orderkey' : "recipe__layer_version__branch", - 'clclass' : 'layer_branch', - 'hidden' : 1, - } - tc_layerCommit = { - 'name' : 'Layer commit', - 'qhelp' : 'The Git commit of the layer providing the recipe that builds the package', - 'clclass' : 'layer_commit', - 'hidden' : 1, - } - - context = { - 'objectname': variant, - 'build' : build, - 'project' : build.project, - 'target' : Target.objects.filter( pk = target_id )[ 0 ], - 'objects' : packages, - 'packages_sum' : packages_sum[ 'installed_size__sum' ], - 'object_search_display': "packages included", - 'default_orderby' : default_orderby, - 'tablecols' : [ - tc_package, - tc_packageVersion, - tc_license, - tc_size, - tc_sizePercentage, - tc_dependencies, - tc_rdependencies, - tc_recipe, - tc_recipeVersion, - tc_layer, - tc_layerBranch, - tc_layerCommit, - ] - } - - - response = render(request, template, context) - _set_parameters_values(pagesize, orderby, request) - return response - -def target( request, build_id, target_id ): - return( target_common( request, build_id, target_id, "target" )) - -def targetpkg( request, build_id, target_id ): - return( target_common( request, build_id, target_id, "targetpkg" )) - from django.core.serializers.json import DjangoJSONEncoder from django.http import HttpResponse def xhr_dirinfo(request, build_id, target_id): |