Skip to contentSkip to conversation

toaster patchset

PATCH New Alex DAMIAN 1 participant 18 messages Mar 12, 2015

lore
Share & tools
lore
#0 lore raw

cover toaster patchset

From: Alexandru DAMIAN <[email protected]>

This is a toaster bug fixing patchset, with patches tested and reviewed on the mailing list.

Can you please pull,

Cheers,
Alex

The following changes since commit 0e0ba408c2dce14a0fabd3fdf61d8465a031495b:

cooker/server: Fix up 100% CPU usage at idle (2015-03-10 10:37:07 +0000)

are available in the git repository at:

git://git.yoctoproject.org/poky-contrib adamian/20150312-submission-bb
http://git.yoctoproject.org/cgit.cgi/poky-contrib/log/?h=adamian/20150312-submission-bb

Alexandru DAMIAN (15):
toastergui: project page - consistent error display
toastergui: suggestion in alphabetical order
toastergui: fix project page layer branch names
toastergui: improve data suggestion
toastergui: improve performance in the all targets page
toasterui: identify proper layer in build mode
toastergui: update search fields
toastergui: project app build command fix
toastergui: tables display optimizations
toastergui: dirinfo needs path separation
toastergui: improve toaster suggestion
toasterui: relative recipe paths
toaster: localhost build increase timeout
toastergui: fix mrb Run again buttons
toastergui: replace ETA with percentage

Michael Wood (2):
toaster: projectconf fix typo of package name
toaster: Fix the orderkey to match the column

 lib/bb/ui/buildinfohelper.py                       | 29 +++++++--
 lib/toaster/bldcontrol/localhostbecontroller.py    |  8 +--
 lib/toaster/orm/models.py                          | 52 ++++++++-------
 lib/toaster/toastergui/static/js/projectapp.js     |  7 +-
 .../toastergui/templates/managed_mrb_section.html  |  7 +-
 lib/toaster/toastergui/templates/project.html      | 56 ++++++++--------
 lib/toaster/toastergui/templates/projectconf.html  | 22 +++----
 lib/toaster/toastergui/templates/targets.html      |  2 +-
 lib/toaster/toastergui/urls.py                     |  2 +-
 lib/toaster/toastergui/views.py                    | 75 ++++++++++++++--------
 10 files changed, 153 insertions(+), 107 deletions(-)
Signature · 1 line
1.9.1
#1 lore raw

PATCH 1/17 toastergui: project page - consistent error display

From: Alexandru DAMIAN <[email protected]>

We modify the project page to provide a consistent view of the build errors. The display is now similar with the managed_mrb_section and links point to the buildrequest detail view.

[YOCTO #7188]

---
 lib/toaster/toastergui/templates/project.html | 50 +++++++++++++++------------
 lib/toaster/toastergui/views.py               |  5 ++-
 2 files changed, 32 insertions(+), 23 deletions(-)
lib/toaster/toastergui/templates/project.html +28 -22
index 54590ee..039601f 100644
@@ -130,29 +130,35 @@ vim: expandtab tabstop=2
         <switch ng-switch="b.status">
 
           <case ng-switch-when="failed">
-            <div class="lead span3"> <span ng-repeat="t in b.targets" ng-include src="'target_display'"></span></div>
-            <div >
-                <button class="btn pull-right btn-danger" ng-click="buildExistingTarget(b.targets)">Run again</button>
+            <div class="lead span3">
+              <a ng-class="{'succeeded': 'success', 'failed': 'error'}[b.status]" href="{[b.br_page_url]}">
+                <span ng-repeat="t in b.targets" ng-include src="'target_display'"></span>
+              </a>
             </div>
-            <div class="row-fluid">
-              <div class="air well" ng-repeat="e in b.errors">
-                    <pre>{[e.msg]}</pre>
-                  <ngif ng-if="e.msg.indexOf('Nothin') == 0">
-                    <div ng-repeat="t in getTargetNameFromErrorMsg(e.msg)">
-                     <p class="lead">The target <strong>{[t]}</strong> is not provided by any of your project layers.</p>
-                     <p> Your build has failed because the target <strong>{[t]}</strong> is not provided by any of your project layers.</p>
-                     <ngif ng-if="layersForTargets[t].length > 0">
-                       <p>The following layers provide this target. You could add one of them to your project.</p>
-                       <button class="btn btn-danger add-layer-with-dependencies" ng-repeat="l in layersForTargets[t]" ng-click="layerAddById(l.id)">Add {[l.name]}</button>
-                     </ngif>
-                    </div>
-                  </ngif>
-                  <ngif ng-if="e.msg.indexOf('Nothin') != 0">
-                    <p>
-                    Please contact your system administrator to help troubleshoot this error.
-                    </p>
-                  </ngif>
-              </div>
+            <div class="span2 lead">
+              <ngif ng-if="b.updated - todaydate > 0">
+                 {[b.updated|date:'HH:mm']}
+              </ngif>
+              <ngif ng-if="b.updated - todaydate < 0">
+                 {[b.updated|date:'dd/MM/yy HH:mm']}
+              </ngif>
+            </div>
+            <div class="span2">
+              <ngif ng-if="b.errors.length">
+                <span>
+                  <i class="icon-minus-sign red lead"></i>
+                  <a href="{[b.br_page_url]}#errors" class="lead error">{[b.errors.length]}
+                  <ng-pluralize count="b.errors.length" when="{'1':'error','other':'errors'}"></ng-pluralize></a>
+                </span>
+              </ngif>
+            </div>
+            <div class="span2">
+              <!-- we don't have warnings in this case -->
+            </div>
+            <div> <span class="lead">Build time: {[b.command_time|timediff]}</span>
+                <button class="btn pull-right" ng-class="{'succeeded':  'btn-success', 'failed': 'btn-danger'}[b.status]"
+                    ng-click="buildExistingTarget(b.targets)">Run again</button>
+
             </div>
           </case>
 
lib/toaster/toastergui/views.py +4 -1
index 8034cfc..1e9df3f 100755
@@ -66,7 +66,10 @@ def _project_recent_build_list(prj):
             "id":  x.pk,
             "targets" : map(lambda y: {"target": y.target, "task": y.task }, x.brtarget_set.all()),
             "status": x.get_state_display(),
-            "errors": map(lambda y: {"type": y.errtype, "msg": y.errmsg, "tb": y.traceback}, x.brerror_set.exclude(errmsg__contains="Command Failed")),
+            "errors": map(lambda y: {"type": y.errtype, "msg": y.errmsg, "tb": y.traceback}, x.brerror_set.all()),
+            "updated": x.updated.strftime('%s')+"000",
+            "command_time": (x.updated - x.created).total_seconds(),
+            "br_page_url": reverse('buildrequestdetails', args=(x.project.id, x.pk) ),
             "build" : map( lambda y: {"id": y.pk,
                         "status": y.get_outcome_display(),
                         "completed_on" : y.completed_on.strftime('%s')+"000",
Signature · 1 line
1.9.1
#2 lore raw

PATCH 2/17 toastergui: suggestion in alphabetical order

From: Alexandru DAMIAN <[email protected]>

Patch bringing ordering in alphabetical order for targets, machines and layers suggestion in typeaheads.

[YOCTO #7152]

---
 lib/toaster/toastergui/views.py | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
lib/toaster/toastergui/views.py +4 -4
index 1e9df3f..a07f720 100755
@@ -2304,7 +2304,7 @@ if toastermain.settings.MANAGED:
                 # and show only the selected layers for this project
                 final_list = set([x.get_equivalents_wpriority(prj)[0] for x in queryset_all])
 
-                return HttpResponse(jsonfilter( { "error":"ok",  "list" : map( _lv_to_dict, final_list) }), content_type = "application/json")
+                return HttpResponse(jsonfilter( { "error":"ok",  "list" : map( _lv_to_dict, sorted(final_list, key = lambda x: x.layer.name)) }), content_type = "application/json")
 
 
             # returns layer dependencies for a layer, excluding current project layers
@@ -2314,7 +2314,7 @@ if toastermain.settings.MANAGED:
 
                 final_list = set([x.get_equivalents_wpriority(prj)[0] for x in queryset])
 
-                return HttpResponse(jsonfilter( { "error":"ok", "list" : map( _lv_to_dict, final_list) }), content_type = "application/json")
+                return HttpResponse(jsonfilter( { "error":"ok", "list" : map( _lv_to_dict, sorted(final_list, key = lambda x: x.layer.name)) }), content_type = "application/json")
 
 
 
@@ -2361,7 +2361,7 @@ if toastermain.settings.MANAGED:
 
                 # if we have more than one hit here (for distinct name and version), max the id it out
                 queryset_all_maxids = queryset_all.values('name').distinct().annotate(max_id=Max('id')).values_list('max_id')
-                queryset_all = queryset_all.filter(id__in = queryset_all_maxids)
+                queryset_all = queryset_all.filter(id__in = queryset_all_maxids).order_by("name")
 
 
                 return HttpResponse(jsonfilter({ "error":"ok",
@@ -2374,7 +2374,7 @@ if toastermain.settings.MANAGED:
             if request.GET['type'] == "machines":
                 queryset_all = Machine.objects.all()
                 if 'project_id' in request.session:
-                    queryset_all = queryset_all.filter(layer_version__in =  prj.projectlayer_equivalent_set())
+                    queryset_all = queryset_all.filter(layer_version__in =  prj.projectlayer_equivalent_set()).order_by("name")
 
                 return HttpResponse(jsonfilter({ "error":"ok",
                     "list" : map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name+ (" | " + x.layer_version.up_branch.name + "]" if x.layer_version.up_branch is not None else "]")},
Signature · 1 line
1.9.1
#3 lore raw

PATCH 3/17 toastergui: fix project page layer branch names

In reply to Alex DAMIAN

From: Alexandru DAMIAN <[email protected]>

Change inconsistent branch name usage in project page to the uniquely defined get_vcs_reference()

[YOCTO #7381]

---
 lib/toaster/toastergui/templates/project.html | 2 +-
 lib/toaster/toastergui/views.py               | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)
lib/toaster/toastergui/templates/project.html +1 -1
index 039601f..06fc6a5 100644
@@ -271,7 +271,7 @@ vim: expandtab tabstop=2
     <div id="layer-container" class="well well-transparent span4">
       <h3>
         Layers <span class="muted counter">({[layers.length]})</span>
-        <i class="icon-question-sign get-help heading-help" title="OpenEmbedded organises metadata into modules called 'layers'. Layers allow you to isolate different types of customizations from each other. <a href='http://www.yoctoproject.org/docs/current/dev-manual/dev-manual.html#understanding-and-creating-layers' target='_blank'>More on layers</a>"></i>
+        <i class="icon-question-sign get-help heading-help" title="Bitbake reads metadata files from modules called 'layers'. Layers allow you to isolate different types of customizations from each other. <a href='http://www.yoctoproject.org/docs/current/dev-manual/dev-manual.html#understanding-and-creating-layers' target='_blank'>More on layers</a>"></i>
       </h3>
       <div class="alert" ng-if="!layers.length">
         <b>You need to add some layers </b>
lib/toaster/toastergui/views.py +2 -2
index a07f720..9f0bb99 100755
@@ -2135,7 +2135,7 @@ if toastermain.settings.MANAGED:
                         "url": x.layercommit.layer.layer_index_url,
                         "layerdetailurl": reverse("layerdetails", args=(x.layercommit.pk,)),
                 # This branch name is actually the release
-                        "branch" : { "name" : x.layercommit.commit, "layersource" : x.layercommit.up_branch.layer_source.name if x.layercommit.up_branch != None else None}},
+                        "branch" : { "name" : x.layercommit.get_vcs_reference(), "layersource" : x.layercommit.up_branch.layer_source.name if x.layercommit.up_branch != None else None}},
                     prj.projectlayer_set.all().order_by("id")),
             "targets" : map(lambda x: {"target" : x.target, "task" : x.task, "pk": x.pk}, prj.projecttarget_set.all()),
             "freqtargets": freqtargets,
@@ -2257,7 +2257,7 @@ if toastermain.settings.MANAGED:
             # return all project settings
             return HttpResponse(jsonfilter( {
                 "error": "ok",
-                "layers" :  map(lambda x: {"id": x.layercommit.pk, "orderid" : x.pk, "name" : x.layercommit.layer.name, "giturl" : x.layercommit.layer.vcs_url, "url": x.layercommit.layer.layer_index_url, "layerdetailurl": reverse("layerdetails", args=(x.layercommit.layer.pk,)), "branch" : { "name" : x.layercommit.up_branch.name, "layersource" : x.layercommit.up_branch.layer_source.name}}, prj.projectlayer_set.all().select_related("layer").order_by("id")),
+                "layers" :  map(lambda x: {"id": x.layercommit.pk, "orderid" : x.pk, "name" : x.layercommit.layer.name, "giturl" : x.layercommit.layer.vcs_url, "url": x.layercommit.layer.layer_index_url, "layerdetailurl": reverse("layerdetails", args=(x.layercommit.layer.pk,)), "branch" : { "name" : x.layercommit.get_vcs_reference(), "layersource" : x.layercommit.up_branch.layer_source.name}}, prj.projectlayer_set.all().select_related("layer").order_by("id")),
                 "builds" : _project_recent_build_list(prj),
                 "variables": map(lambda x: (x.name, x.value), prj.projectvariable_set.all()),
                 "machine": {"name": prj.projectvariable_set.get(name="MACHINE").value},
Signature · 1 line
1.9.1
#4 lore raw

PATCH 4/17 toastergui: improve data suggestion

In reply to Alex DAMIAN

From: Alexandru DAMIAN <[email protected]>

We improve the data suggestions in the project page.

The machines suggestions now contain the layer name.

The targets and machine do not show the layer branch.

For targets, the layer name is searchable. For machines, the description field is searchable.

[YOCTO #7153]
[YOCTO #7154]

---
 lib/toaster/toastergui/templates/project.html |  2 +-
 lib/toaster/toastergui/views.py               | 14 ++++++++------
 2 files changed, 9 insertions(+), 7 deletions(-)
lib/toaster/toastergui/templates/project.html +1 -1
index 06fc6a5..f4a3a75 100644
@@ -355,7 +355,7 @@ vim: expandtab tabstop=2
               You cannot really compare the builds for the new machine with the previous ones.
         </div>
         <form ng-submit="editProjectSettings('#select-machine')" class="input-append">
-              <input type="text" id="machine" autocomplete="off" ng-model="machineName" typeahead="m.name for m in getAutocompleteSuggestions('machines', $viewValue)"/>
+              <input type="text" id="machine" autocomplete="off" ng-model="machineName" typeahead="m.name for m in getAutocompleteSuggestions('machines', $viewValue)" typeahead-template-url="suggestion_details" />
               <input type="submit" id="apply-change-machine" class="btn" type="button" ng-disabled="machineName == machine.name || machineName.length == 0" value="Save"></input>
               <input type="reset" id="cancel-machine" class="btn btn-link" ng-click="toggle('#select-machine')" value="Cancel"></input>
               {% csrf_token %}
lib/toaster/toastergui/views.py +8 -6
index 9f0bb99..9f1fbca 100755
@@ -2353,7 +2353,8 @@ if toastermain.settings.MANAGED:
 
             # returns targets provided by current project layers
             if request.GET['type'] == "targets":
-                queryset_all = Recipe.objects.filter(name__icontains=request.GET.get('value',''))
+                search_token = request.GET.get('value','')
+                queryset_all = Recipe.objects.filter(Q(name__icontains=search_token) | Q(layer_version__layer__name__icontains=search_token) )
                 layer_equivalent_set = []
                 for i in prj.projectlayer_set.all():
                     layer_equivalent_set += i.layercommit.get_equivalents_wpriority(prj)
@@ -2361,11 +2362,11 @@ if toastermain.settings.MANAGED:
 
                 # if we have more than one hit here (for distinct name and version), max the id it out
                 queryset_all_maxids = queryset_all.values('name').distinct().annotate(max_id=Max('id')).values_list('max_id')
-                queryset_all = queryset_all.filter(id__in = queryset_all_maxids).order_by("name")
+                queryset_all = queryset_all.filter(id__in = queryset_all_maxids).order_by("name").select_related("layer_version__layer")
 
 
                 return HttpResponse(jsonfilter({ "error":"ok",
-                    "list" : map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name + (" | " + x.layer_version.up_branch.name + "]" if x.layer_version.up_branch is not None else "]")},
+                    "list" : map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name +"]"},
                         queryset_all[:8]),
 
                     }), content_type = "application/json")
@@ -2376,10 +2377,11 @@ if toastermain.settings.MANAGED:
                 if 'project_id' in request.session:
                     queryset_all = queryset_all.filter(layer_version__in =  prj.projectlayer_equivalent_set()).order_by("name")
 
-                return HttpResponse(jsonfilter({ "error":"ok",
-                    "list" : map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name+ (" | " + x.layer_version.up_branch.name + "]" if x.layer_version.up_branch is not None else "]")},
-                        queryset_all.filter(name__icontains=request.GET.get('value',''))[:8]),
+                search_token = request.GET.get('value','')
+                querysetall = queryset_all.filter(Q(name__icontains=search_token) | Q(description__icontains=search_token))
 
+                return HttpResponse(jsonfilter({ "error":"ok",
+                        "list" : map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name+ "]"}, queryset_all[:8])
                     }), content_type = "application/json")
 
             # returns all projects
Signature · 1 line
1.9.1
#5 lore raw

PATCH 5/17 toastergui: improve performance in the all targets page

In reply to Alex DAMIAN

From: Alexandru DAMIAN <[email protected]>

This patch improves performance in the all targets display by computing the preffered layer only for displayed targets, instead of computing for all targets.

---
 lib/toaster/toastergui/views.py | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
lib/toaster/toastergui/views.py +7 -7
index 9f1fbca..5b481cb 100755
@@ -2752,21 +2752,21 @@ if toastermain.settings.MANAGED:
 
         queryset_with_search = _get_queryset(Recipe, queryset_all, None, search_term, ordering_string, '-name')
 
-        # get unique values for 'name' and 'version', and select the maximum ID for each entry (the max id is the newest one)
+        # get unique values for 'name', and select the maximum ID for each entry (the max id is the newest one)
         queryset_with_search_maxids = queryset_with_search.values('name').distinct().annotate(max_id=Max('id')).values_list('max_id')
 
-        queryset_with_search = queryset_with_search.filter(id__in=queryset_with_search_maxids).select_related('layer_version', 'layer_version__layer')
+        queryset_with_search = queryset_with_search.filter(id__in=queryset_with_search_maxids).select_related('layer_version', 'layer_version__layer', 'layer_version__up_branch')
 
-        objects = list(queryset_with_search)
-        for e in objects:
-            e.preffered_layerversion = e.layer_version.get_equivalents_wpriority(prj)[0]
 
         # retrieve the objects that will be displayed in the table; targets a paginator and gets a page range to display
-        target_info = _build_page_range(Paginator(objects, request.GET.get('count', 10)),request.GET.get('page', 1))
+        target_info = _build_page_range(Paginator(queryset_with_search, request.GET.get('count', 10)),request.GET.get('page', 1))
+
+        for e in target_info.object_list:
+            e.preffered_layerversion = e.layer_version.get_equivalents_wpriority(prj)[0]
 
 
         context = {
-            'projectlayerset' : jsonfilter(map(lambda x: x.layercommit.id, prj.projectlayer_set.all())),
+            'projectlayerset' : jsonfilter(map(lambda x: x.layercommit.id, prj.projectlayer_set.all().select_related("layercommit"))),
             'objects' : target_info,
             'objectname' : "targets",
             'default_orderby' : 'name:+',
Signature · 1 line
1.9.1
#6 lore raw

PATCH 6/17 toasterui: identify proper layer in build mode

In reply to Alex DAMIAN

From: Alexandru DAMIAN <[email protected]>

In build mode, instead of creating our own layer objects, we identify the layer objects that the build system set up.

[YOCTO #7378]

---
 lib/bb/ui/buildinfohelper.py                    | 23 ++++++++++++++++++-----
 lib/toaster/bldcontrol/localhostbecontroller.py |  4 ++--
 lib/toaster/orm/models.py                       | 10 ++--------
 3 files changed, 22 insertions(+), 15 deletions(-)
lib/bb/ui/buildinfohelper.py +18 -5
index 19ddd8e..ae2ac9f 100644
@@ -270,15 +270,28 @@ class ORMWrapper(object):
         else:
             # we are under managed mode; we must match the layer used in the Project Layer
             from bldcontrol.models import BuildEnvironment, BuildRequest
-            br, be = brbe.split(":")
+            br_id, be_id = brbe.split(":")
 
-            buildrequest = BuildRequest.objects.get(pk = br)
+            # find layer by checkout path;
+            from bldcontrol import bbcontroller
+            bc = bbcontroller.getBuildEnvironmentController(pk = be_id)
 
             # we might have a race condition here, as the project layers may change between the build trigger and the actual build execution
             # but we can only match on the layer name, so the worst thing can happen is a mis-identification of the layer, not a total failure
-            layer_object = buildrequest.project.projectlayer_set.get(layercommit__layer__name=layer_information['name']).layercommit.layer
 
-            return layer_object
+            from pprint import pformat
+            # note that this is different
+            buildrequest = BuildRequest.objects.get(pk = br_id)
+            for brl in buildrequest.brlayer_set.all():
+                localdirname = os.path.join(bc.getGitCloneDirectory(brl.giturl, brl.commit), brl.dirpath)
+                logger.warn("Matched %s to BRlayer %s" % (pformat(layer_information["local_path"]), localdirname))
+                if localdirname.startswith(layer_information['local_path']):
+                    # we matched the BRLayer, but we need the layer_version that generated this BR; reverse of the Project.schedule_build()
+                    for pl in buildrequest.project.projectlayer_set.filter(layercommit__layer__name = brl.name):
+                        if pl.layercommit.layer.vcs_url == brl.giturl :
+                            return pl.layercommit.layer
+
+            raise Exception("Unidentified layer %s" % pformat(layer_information))
 
 
     def save_target_file_information(self, build_obj, target_obj, filedata):
@@ -683,7 +696,7 @@ class BuildInfoHelper(object):
 
             # Heuristics: we match the path to where the layers have been checked out
             for brl in sorted(BuildRequest.objects.get(pk = br_id).brlayer_set.all(), reverse = True, key = _slkey_managed):
-                localdirname = os.path.join(os.path.join(bc.be.sourcedir, bc.getGitCloneDirectory(brl.giturl, brl.commit)), brl.dirpath)
+                localdirname = os.path.join(bc.getGitCloneDirectory(brl.giturl, brl.commit), brl.dirpath)
                 if path.startswith(localdirname):
                     #logger.warn("-- managed: matched path %s with layer %s " % (path, localdirname))
                     # we matched the BRLayer, but we need the layer_version that generated this br
lib/toaster/bldcontrol/localhostbecontroller.py +2 -2
index 25ce052..aef9b60 100644
@@ -180,7 +180,7 @@ class LocalhostBEController(BuildEnvironmentController):
         base = components[-2] if components[-1] == "git" else components[-1]
 
         if branch != "HEAD":
-            return "_%s_%s.toaster_cloned" % (base, branch)
+            return os.path.join(self.be.sourcedir, "_%s_%s.toaster_cloned" % (base, branch))
 
 
         # word of attention; this is a localhost-specific issue; only on the localhost we expect to have "HEAD" releases
@@ -239,7 +239,7 @@ class LocalhostBEController(BuildEnvironmentController):
 
         # 3. checkout the repositories
         for giturl, commit in gitrepos.keys():
-            localdirname = os.path.join(self.be.sourcedir, self.getGitCloneDirectory(giturl, commit))
+            localdirname = self.getGitCloneDirectory(giturl, commit)
             logger.debug("localhostbecontroller: giturl %s:%s checking out in current directory %s" % (giturl, commit, localdirname))
 
             # make sure our directory is a git repository
lib/toaster/orm/models.py +2 -8
index 4d1dcbc..80e6d92 100644
@@ -195,14 +195,8 @@ class Project(models.Model):
                 dirpath = self.bitbake_version.dirpath)
 
             for l in self.projectlayer_set.all().order_by("pk"):
-                commit = l.layercommit.commit
-                print("ii Building layer ", l.layercommit.layer.name, " at commit ", commit)
-                if l.layercommit.up_branch:
-                    commit = l.layercommit.up_branch.name
-                    print("ii Building layer ", l.layercommit.layer.name, " at upbranch ", commit)
-                if l.layercommit.branch:
-                    commit = l.layercommit.branch
-                    print("ii Building layer ", l.layercommit.layer.name, " at actual_branch ", commit)
+                commit = l.layercommit.get_vcs_reference()
+                print("ii Building layer ", l.layercommit.layer.name, " at vcs point ", commit)
                 BRLayer.objects.create(req = br, name = l.layercommit.layer.name, giturl = l.layercommit.layer.vcs_url, commit = commit, dirpath = l.layercommit.dirpath)
             for t in self.projecttarget_set.all():
                 BRTarget.objects.create(req = br, target = t.target, task = t.task)
Signature · 1 line
1.9.1
#7 lore raw

PATCH 7/17 toastergui: update search fields

In reply to Alex DAMIAN

From: Alexandru DAMIAN <[email protected]>

We update the search fields for the machine suggestions and recipes tables.

---
 lib/toaster/orm/models.py       | 2 +-
 lib/toaster/toastergui/views.py | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
lib/toaster/orm/models.py +1 -1
index 80e6d92..b941d4a 100644
@@ -528,7 +528,7 @@ class Package_File(models.Model):
     size = models.IntegerField()
 
 class Recipe(models.Model):
-    search_allowed_fields = ['name', 'version', 'file_path', 'section', 'description', 'license', 'layer_version__layer__name', 'layer_version__branch', 'layer_version__commit', 'layer_version__layer__local_path', 'layer_version__layer_source__name']
+    search_allowed_fields = ['name', 'version', 'file_path', 'section', 'summary', 'description', 'license', 'layer_version__layer__name', 'layer_version__branch', 'layer_version__commit', 'layer_version__layer__local_path', 'layer_version__layer_source__name']
 
     layer_source = models.ForeignKey('LayerSource', default = None, null = True)  # from where did we get this recipe
     up_id = models.IntegerField(null = True, default = None)                    # id of entry in the source
lib/toaster/toastergui/views.py +1 -1
index 5b481cb..90d47c6 100755
@@ -2378,7 +2378,7 @@ if toastermain.settings.MANAGED:
                     queryset_all = queryset_all.filter(layer_version__in =  prj.projectlayer_equivalent_set()).order_by("name")
 
                 search_token = request.GET.get('value','')
-                querysetall = queryset_all.filter(Q(name__icontains=search_token) | Q(description__icontains=search_token))
+                queryset_all = queryset_all.filter(Q(name__icontains=search_token) | Q(description__icontains=search_token))
 
                 return HttpResponse(jsonfilter({ "error":"ok",
                         "list" : map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name+ "]"}, queryset_all[:8])
Signature · 1 line
1.9.1
#8 lore raw

PATCH 8/17 toastergui: project app build command fix

In reply to Alex DAMIAN

From: Alexandru DAMIAN <[email protected]>

This patch fixes the build command in the angular project for builds triggered from All targets page.

---
 lib/toaster/toastergui/static/js/projectapp.js | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
lib/toaster/toastergui/static/js/projectapp.js +4 -3
index 82db107..6b1bbb4 100644
@@ -327,7 +327,7 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc
         }).error(function(_data, _status, _headers, _config) {
             if (_status === 0) {
                 // the server has gone away
-                alert("The server is not responding. The application will terminate now");
+                // alert("The server is not responding. The application will terminate now");
                 $interval.cancel($scope.pollHandle);
             }
             else {
@@ -652,9 +652,9 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc
      */
 
     $scope.updateDisplayWithCommands = function() {
-        cmd = $location.path();
 
         function _cmdExecuteWithParam(param, f) {
+            var cmd = $location.path();
             if (cmd.indexOf(param) === 0) {
                 if (cmd.indexOf("=") > -1) {
                     var parameter = cmd.split("=", 2)[1];
@@ -725,8 +725,9 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc
         _cmdExecuteWithParam("/targetbuild=", function (targets) {
             var oldTargetName = $scope.targetName;
             $scope.targetName = targets.split(",").join(" ");
-            $scope.targetNamedBuild();
+            $scope.buildNamedTarget();
             $scope.targetName = oldTargetName;
+            $location.path('');
         });
 
         _cmdExecuteWithParam("/machineselect=", function (machine) {
Signature · 1 line
1.9.1
#9 lore raw

PATCH 9/17 toastergui: tables display optimizations

In reply to Alex DAMIAN

From: Alexandru DAMIAN <[email protected]>

This patch brings in a new set of optimizations in the tables pages, with the focus of reducing the number of SQL queries performed per row.

---
 lib/toaster/orm/models.py                     | 40 +++++++++++++++------------
 lib/toaster/toastergui/templates/targets.html |  2 +-
 lib/toaster/toastergui/views.py               | 14 +++++++---
 3 files changed, 33 insertions(+), 23 deletions(-)
lib/toaster/orm/models.py +22 -18
index b941d4a..2132f87 100644
@@ -182,7 +182,7 @@ class Project(models.Model):
 
     # returns a set of layer-equivalent set of layers already in project
     def projectlayer_equivalent_set(self):
-        return [j for i in [x.layercommit.get_equivalents_wpriority(self) for x in self.projectlayer_set.all()] for j in i]
+        return [j for i in [x.layercommit.get_equivalents_wpriority(self) for x in self.projectlayer_set.all().select_related("up_branch")] for j in i]
 
     def schedule_build(self):
         from bldcontrol.models import BuildRequest, BRTarget, BRLayer, BRVariable, BRBitbake
@@ -545,11 +545,6 @@ class Recipe(models.Model):
     bugtracker = models.URLField(blank=True)
     file_path = models.FilePathField(max_length=255)
 
-    def get_vcs_link_url(self):
-        if self.layer_version.layer.vcs_web_file_base_url is None:
-            return ""
-        return self.layer_version.layer.vcs_web_file_base_url.replace('%path%', self.file_path).replace('%branch%', self.layer_version.up_branch.name)
-
     def get_layersource_view_url(self):
         if self.layer_source is None:
             return ""
@@ -708,8 +703,6 @@ class LayerIndexLayerSource(LayerSource):
         self.sourcetype = LayerSource.TYPE_LAYERINDEX
 
     def get_object_view(self, branch, objectype, upid):
-        if self != branch.layer_source:
-            raise Exception("Invalid branch specification")
         return self.apiurl + "../branch/" + branch.name + "/" + objectype + "/?q=" + str(upid)
 
     def update(self):
@@ -1044,14 +1037,6 @@ class Layer_Version(models.Model):
 
     def get_equivalents_wpriority(self, project):
         """ Returns an ordered layerversion list that satisfies a LayerVersionDependency using the layer name and the current Project Releases' LayerSource priority """
-        def _get_ls_priority(ls):
-            try:
-                # if there is no layer source, we have minus infinite priority, as we don't want this layer selected
-                if ls == None:
-                    return -10000
-                return ls.releaselayersourcepriority_set.get(release=project.release).priority
-            except ReleaseLayerSourcePriority.DoesNotExist:
-                raise
 
         # layers created for this project, or coming from a build inthe project
         query = Q(project = project) | Q(build__project = project)
@@ -1062,8 +1047,27 @@ class Layer_Version(models.Model):
             # or we have a layer in the project that's similar to mine (See the layer.name constraint below)
             query |= Q(projectlayer__project=project)
 
-        return sorted(
-                Layer_Version.objects.filter(layer__name = self.layer.name).filter(query).select_related('layer_source', 'layer').order_by("-id"),
+        candidate_layer_versions = list(Layer_Version.objects.filter(layer__name = self.layer.name).filter(query).select_related('layer_source', 'layer', 'up_branch').order_by("-id"))
+
+        # optimization - if we have only one, we don't need no stinking sort
+        if len(candidate_layer_versions) == 1:
+            return candidate_layer_versions
+
+#        raise Exception(candidate_layer_versions)
+
+        release_priorities = map(lambda x: (x.layer_source_id, x.priority), project.release.releaselayersourcepriority_set.all().order_by("-priority"))
+
+
+        def _get_ls_priority(ls):
+            # if there is no layer source, we have minus infinite priority, as we don't want this layer selected
+            if ls == None:
+                return -10000
+            try:
+                return release_priorities[ls.id]
+            except IndexError:
+                raise Exception("Unknown %d %s" % (ls.id, release_priorities))
+
+        return sorted( candidate_layer_versions ,
                 key = lambda x: _get_ls_priority(x.layer_source),
                 reverse = True)
 
lib/toaster/toastergui/templates/targets.html +1 -1
index 690c6a5..f918d6c 100644
@@ -60,7 +60,7 @@
         <td class="description">{% if o.description %}{{o.description}}{% else %}{{o.summary}}{%endif%}</td>
         <td class="recipe-file">
                 <code>{{o.file_path}}</code>
-                <a href="{{o.get_vcs_link_url}}{{o.file_path}}" target="_blank"><i class="icon-share get-info"></i></a>
+                <a href="{{o.vcs_link_url}}" target="_blank"><i class="icon-share get-info"></i></a>
         </td>
         <td class="target-section">{{o.section}}</td>
         <td class="license">{{o.license}}</td>
lib/toaster/toastergui/views.py +10 -4
index 90d47c6..541b16a 100755
@@ -515,17 +515,19 @@ def target_common( request, build_id, target_id, variant ):
     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 )
+            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 )
+            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',
@@ -2755,7 +2757,7 @@ if toastermain.settings.MANAGED:
         # get unique values for 'name', and select the maximum ID for each entry (the max id is the newest one)
         queryset_with_search_maxids = queryset_with_search.values('name').distinct().annotate(max_id=Max('id')).values_list('max_id')
 
-        queryset_with_search = queryset_with_search.filter(id__in=queryset_with_search_maxids).select_related('layer_version', 'layer_version__layer', 'layer_version__up_branch')
+        queryset_with_search = queryset_with_search.filter(id__in=queryset_with_search_maxids).select_related('layer_version', 'layer_version__layer', 'layer_version__up_branch', 'layer_source')
 
 
         # retrieve the objects that will be displayed in the table; targets a paginator and gets a page range to display
@@ -2763,7 +2765,11 @@ if toastermain.settings.MANAGED:
 
         for e in target_info.object_list:
             e.preffered_layerversion = e.layer_version.get_equivalents_wpriority(prj)[0]
-
+            e.vcs_link_url = Layer.objects.filter(name = e.preffered_layerversion.layer.name).exclude(vcs_web_file_base_url__isnull=True)[0].vcs_web_file_base_url
+            if e.vcs_link_url != None:
+                fp = e.preffered_layerversion.dirpath + "/" + e.file_path
+                e.vcs_link_url = e.vcs_link_url.replace('%path%', fp)
+                e.vcs_link_url = e.vcs_link_url.replace('%branch%', e.preffered_layerversion.up_branch.name)
 
         context = {
             'projectlayerset' : jsonfilter(map(lambda x: x.layercommit.id, prj.projectlayer_set.all().select_related("layercommit"))),
Signature · 1 line
1.9.1
#10 lore raw

PATCH 10/17 toastergui: dirinfo needs path separation

In reply to Alex DAMIAN

From: Alexandru DAMIAN <[email protected]>

In the dirinfo URLs we use the "/" separator for directory separation which coincides with the "/" separator in HTTP URIs.

This is not a problem, but we must not have consecutive "/" characters as the web servers will conflate those - we add a "_" delimitator to separate the Django managed URL from the dirpath parameter, while maintaining the unique ID of REST urls.

---
 lib/toaster/toastergui/urls.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
lib/toaster/toastergui/urls.py +1 -1
index 8a7fef1..76357e3 100644
@@ -55,7 +55,7 @@ urlpatterns = patterns('toastergui.views',
         url(r'^build/(?P<build_id>\d+)/target/(?P<target_id>\d+)/targetpkg$', 'targetpkg', name='targetpkg'),
         url(r'^dentries/build/(?P<build_id>\d+)/target/(?P<target_id>\d+)$', 'dirinfo_ajax', 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'),
+        url(r'^build/(?P<build_id>\d+)/target/(?P<target_id>\d+)/dirinfo_filepath/_(?P<file_path>(?:/[^/\n]+)*)$', 'dirinfo', name='dirinfo_filepath'),
         url(r'^build/(?P<build_id>\d+)/target/(?P<target_id>\d+)/packages$', 'tpackage', name='targetpackages'),
         url(r'^build/(?P<build_id>\d+)/configuration$', 'configuration', name='configuration'),
         url(r'^build/(?P<build_id>\d+)/configvars$', 'configvars', name='configvars'),
Signature · 1 line
1.9.1
#11 lore raw

PATCH 11/17 toastergui: improve toaster suggestion

In reply to Alex DAMIAN

From: Alexandru DAMIAN <[email protected]>

Improving the suggestions by ordering entries
based on position of the search string.

Speed improvements in suggestion calls.

[YOCTO #7152]

---
 lib/toaster/toastergui/views.py | 28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)
lib/toaster/toastergui/views.py +20 -8
index 541b16a..807bf9b 100755
@@ -2259,7 +2259,7 @@ if toastermain.settings.MANAGED:
             # return all project settings
             return HttpResponse(jsonfilter( {
                 "error": "ok",
-                "layers" :  map(lambda x: {"id": x.layercommit.pk, "orderid" : x.pk, "name" : x.layercommit.layer.name, "giturl" : x.layercommit.layer.vcs_url, "url": x.layercommit.layer.layer_index_url, "layerdetailurl": reverse("layerdetails", args=(x.layercommit.layer.pk,)), "branch" : { "name" : x.layercommit.get_vcs_reference(), "layersource" : x.layercommit.up_branch.layer_source.name}}, prj.projectlayer_set.all().select_related("layer").order_by("id")),
+                "layers" :  map(lambda x: {"id": x.layercommit.pk, "orderid" : x.pk, "name" : x.layercommit.layer.name, "giturl" : x.layercommit.layer.vcs_url, "url": x.layercommit.layer.layer_index_url, "layerdetailurl": reverse("layerdetails", args=(x.layercommit.pk,)), "branch" : { "name" : x.layercommit.get_vcs_reference(), "layersource" : x.layercommit.up_branch.layer_source.name}}, prj.projectlayer_set.all().select_related("layer").order_by("id")),
                 "builds" : _project_recent_build_list(prj),
                 "variables": map(lambda x: (x.name, x.value), prj.projectvariable_set.all()),
                 "machine": {"name": prj.projectvariable_set.get(name="MACHINE").value},
@@ -2356,11 +2356,13 @@ if toastermain.settings.MANAGED:
             # returns targets provided by current project layers
             if request.GET['type'] == "targets":
                 search_token = request.GET.get('value','')
-                queryset_all = Recipe.objects.filter(Q(name__icontains=search_token) | Q(layer_version__layer__name__icontains=search_token) )
-                layer_equivalent_set = []
-                for i in prj.projectlayer_set.all():
-                    layer_equivalent_set += i.layercommit.get_equivalents_wpriority(prj)
-                queryset_all = queryset_all.filter(layer_version__in =  layer_equivalent_set)
+                queryset_all = Recipe.objects.filter(layer_version__layer__name__in = [x.layercommit.layer.name for x in prj.projectlayer_set.all().select_related("layercommit__layer")]).filter(Q(name__icontains=search_token) | Q(layer_version__layer__name__icontains=search_token))
+
+#                layer_equivalent_set = []
+#                for i in prj.projectlayer_set.all().select_related("layercommit__up_branch", "layercommit__layer"):
+#                    layer_equivalent_set += i.layercommit.get_equivalents_wpriority(prj)
+
+#                queryset_all = queryset_all.filter(layer_version__in =  layer_equivalent_set)
 
                 # if we have more than one hit here (for distinct name and version), max the id it out
                 queryset_all_maxids = queryset_all.values('name').distinct().annotate(max_id=Max('id')).values_list('max_id')
@@ -2368,8 +2370,13 @@ if toastermain.settings.MANAGED:
 
 
                 return HttpResponse(jsonfilter({ "error":"ok",
-                    "list" : map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name +"]"},
+                    "list" :
+                        # 7152 - sort by token position
+                        sorted (
+                            map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name +"]"},
                         queryset_all[:8]),
+                            key = lambda i: i["name"].find(search_token) if i["name"].find(search_token) > -1 else 9999,
+                        )
 
                     }), content_type = "application/json")
 
@@ -2383,7 +2390,12 @@ if toastermain.settings.MANAGED:
                 queryset_all = queryset_all.filter(Q(name__icontains=search_token) | Q(description__icontains=search_token))
 
                 return HttpResponse(jsonfilter({ "error":"ok",
-                        "list" : map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name+ "]"}, queryset_all[:8])
+                        "list" :
+                        # 7152 - sort by the token position
+                        sorted (
+                            map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name+ "]"}, queryset_all[:8]),
+                            key = lambda i: i["name"].find(search_token) if i["name"].find(search_token) > -1 else 9999,
+                        )
                     }), content_type = "application/json")
 
             # returns all projects
Signature · 1 line
1.9.1
#12 lore raw

PATCH 12/17 toasterui: relative recipe paths

In reply to Alex DAMIAN

From: Alexandru DAMIAN <[email protected]>

We modify the toasterui to log relative recipe paths in order to maintain consistency with data fetched from the layer sources.

---
 lib/bb/ui/buildinfohelper.py | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
lib/bb/ui/buildinfohelper.py +7 -1
index ae2ac9f..cf8c444 100644
@@ -221,6 +221,9 @@ class ORMWrapper(object):
         assert 'layer_version' in recipe_information
         assert 'file_path' in recipe_information
 
+        if recipe_information['file_path'].startswith(recipe_information['layer_version'].layer.local_path):
+            recipe_information['file_path'] = recipe_information['file_path'][len(recipe_information['layer_version'].layer.local_path):].lstrip("/")
+
         recipe_object, created = self._cached_get_or_create(Recipe, layer_version=recipe_information['layer_version'],
                                      file_path=recipe_information['file_path'])
         if created and must_exist:
@@ -289,7 +292,10 @@ class ORMWrapper(object):
                     # we matched the BRLayer, but we need the layer_version that generated this BR; reverse of the Project.schedule_build()
                     for pl in buildrequest.project.projectlayer_set.filter(layercommit__layer__name = brl.name):
                         if pl.layercommit.layer.vcs_url == brl.giturl :
-                            return pl.layercommit.layer
+                            layer = pl.layercommit.layer
+                            layer.local_path = layer_information['local_path']
+                            layer.save()
+                            return layer
 
             raise Exception("Unidentified layer %s" % pformat(layer_information))
 
Signature · 1 line
1.9.1
#13 lore raw

PATCH 13/17 toaster: localhost build increase timeout

In reply to Alex DAMIAN

From: Alexandru DAMIAN <[email protected]>

We increase the timeout for waiting bitbake to start for localhost builds.

---
 lib/toaster/bldcontrol/localhostbecontroller.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
lib/toaster/bldcontrol/localhostbecontroller.py +2 -2
index aef9b60..374991b 100644
@@ -136,7 +136,7 @@ class LocalhostBEController(BuildEnvironmentController):
 
         retries = 0
         started = False
-        while not started and retries < 10:
+        while not started and retries < 30:
             started = _toaster_ui_started(toaster_ui_log_filepath, toaster_ui_log_filelength)
             import time
             logger.debug("localhostbecontroller: Waiting bitbake server to start")
@@ -144,7 +144,7 @@ class LocalhostBEController(BuildEnvironmentController):
             retries += 1
 
         if not started:
-            raise BuildSetupException("localhostbecontroller: Bitbake server did not start in 5 seconds, aborting (Error: '%s')" % (cmdoutput))
+            raise BuildSetupException("localhostbecontroller: Bitbake server did not start in 15 seconds, aborting (Error: '%s')" % (cmdoutput))
 
         logger.debug("localhostbecontroller: Started bitbake server")
 
Signature · 1 line
1.9.1
#14 lore raw

PATCH 14/17 toastergui: fix mrb Run again buttons

In reply to Alex DAMIAN

From: Alexandru DAMIAN <[email protected]>

The button for error-ed builds had invalid javascript markup, this patch fixes the buttons.

---
 lib/toaster/toastergui/templates/managed_mrb_section.html | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
lib/toaster/toastergui/templates/managed_mrb_section.html +2 -3
index d6e32f8..edaa08e 100644
@@ -54,8 +54,7 @@
                 Build time: <a href="{% url 'buildtime' build.pk %}">{{ build.timespent|sectohms }}</a>
               </span>
           {% if build.project %}
-              <button class="btn {%if build.outcome == build.SUCCEEDED%}btn-success{%elif build.outcome == build.FAILED%}btn-danger{%else%}btn-info{%endif%} pull-right" onclick='scheduleBuild({% url 'xhr_projectbuild' build.project.id as bpi%}{{bpi|json}}, {{build.project.name|json}},
-{% url 'project' buildrequest.project.id as bpurl%}{{bpurl|json}}, {{build.get_sorted_target_list|mapselect:'target'|json}})'>Run again</button>
+              <button class="btn {%if build.outcome == build.SUCCEEDED%}btn-success{%elif build.outcome == build.FAILED%}btn-danger{%else%}btn-info{%endif%} pull-right" onclick='scheduleBuild({% url 'xhr_projectbuild' build.project.id as bpi%}{{bpi|json}}, {{build.project.name|json}}, {% url 'project' buildrequest.project.id as bpurl%}{{bpurl|json}}, {{build.get_sorted_target_list|mapselect:'target'|json}})'>Run again</button>
           {% endif %}
             </div>
     {%endif%}
@@ -105,7 +104,7 @@
               <span class="lead{%if not MANAGED or not buildrequest.project%} pull-right{%endif%}">
                 Build time: {{ buildrequest.get_duration|sectohms }}
               </span>
-              <button class="btn btn-danger pull-right" onclick='scheduleBuild({% url 'xhr_projectbuild' buildrequest.project.id as bpi%}{{bpi|json}},  {{buildrequest.project.name|json}}, {% url 'project' buildrequest.project.id as bpurl%}|{{bpurl|json}}, {{buildrequest.get_sorted_target_list|mapselect:'target'|json}})'>Run again</button>
+              <button class="btn btn-danger pull-right" onclick='scheduleBuild({% url 'xhr_projectbuild' buildrequest.project.id as bpi%}{{bpi|json}},  {{buildrequest.project.name|json}}, {% url 'project' buildrequest.project.id as bpurl%}{{bpurl|json}}, {{buildrequest.get_sorted_target_list|mapselect:'target'|json}})'>Run again</button>
 
             </div>
 
Signature · 1 line
1.9.1
#15 lore raw

PATCH 15/17 toastergui: replace ETA with percentage

In reply to Alex DAMIAN

From: Alexandru DAMIAN <[email protected]>

We replace the ETA (which was an inaccurate estimation) with the percentage of completed tasks.

---
 lib/toaster/toastergui/templates/managed_mrb_section.html | 2 +-
 lib/toaster/toastergui/templates/project.html             | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
lib/toaster/toastergui/templates/managed_mrb_section.html +1 -1
index edaa08e..51610e4 100644
@@ -64,7 +64,7 @@
                     <div style="width: {{build.completeper}}%;" class="bar"></div>
                 </div>
             </div>
-            <div class="lead pull-right">ETA: in {{build.eta|naturaltime}}</div>
+            <div class="lead pull-right">{{build.completeper}}% tasks completed</div>
     {%endif%}
         </div>
     </div>
lib/toaster/toastergui/templates/project.html +1 -1
index f4a3a75..badc8a6 100644
@@ -202,7 +202,7 @@ vim: expandtab tabstop=2
                       <div style="width: {[b.build[0].completeper]}%;" class="bar"></div>
                   </div>
                 </div>
-                <div class="text-right lead">ETA in {[b.build[0].eta|toeta|timediff]}</div>
+                <div class="text-right lead">{[b.build[0].completeper]}% tasks completed</div>
               </case>
           </case>
 
Signature · 1 line
1.9.1
#16 lore raw

PATCH 16/17 toaster: projectconf fix typo of package name

In reply to Alex DAMIAN

From: Michael Wood <[email protected]>

The package should be deb rather than dev.

---
 lib/toaster/toastergui/templates/projectconf.html | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)
lib/toaster/toastergui/templates/projectconf.html +11 -11
index c994f31..ffdf760 100644
@@ -89,7 +89,7 @@
                         <i class="icon-question-sign get-help" title="The package format used to generate the root file system. Options are <code>dev</code>, <code>ipk</code> and <code>rpm</code>"></i>
                     </label>
                     <select id="package_classes-select">
-                        <option>package_dev</option>
+                        <option>package_deb</option>
                         <option>package_ipk</option>
                         <option>package_rpm</option>
                     </select>
@@ -98,7 +98,7 @@
                         <i class="icon-question-sign get-help" title="Extra package formats to build"></i>
                     </label>
                     <label class="checkbox" id="package_class_1">
-                        <input type="checkbox" id="package_class_1_input"> package_dev
+                        <input type="checkbox" id="package_class_1_input"> package_deb
                     </label>
                     <label class="checkbox" id="package_class_2">
                         <input type="checkbox" id="package_class_2_input"> package_ipk
@@ -325,16 +325,16 @@
         // Preset or reset the Package Class checkbox labels
         function updatePackageClassCheckboxes() {
             $('#package_class_1, #package_class_2').hide();
-            if ($('select').val() == 'package_dev') {
+            if ($('select').val() == 'package_deb') {
                 $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_ipk');
                 $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_rpm');
             }
             if ($('select').val() == 'package_ipk') {
-                $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_dev');
+                $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_deb');
                 $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_rpm');
             }
             if ($('select').val() == 'package_rpm') {
-                $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_dev');
+                $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_deb');
                 $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_ipk');
             }
             $('#package_class_1, #package_class_2').fadeIn(1500);
@@ -687,7 +687,7 @@
 
                 // initialize the pulldown and checkboxes
                 var value = document.getElementById("package_classes").innerHTML;
-                if (0 == value.indexOf("package_dev")) {
+                if (0 == value.indexOf("package_deb")) {
                     $('select').selectedIndex = 0;
                     updatePackageClassCheckboxes();
                     if (0 < value.indexOf("package_ipk")) {document.getElementById("package_class_1_input").checked = true};
@@ -696,13 +696,13 @@
                 if (0 == value.indexOf("package_ipk")) {
                     $('select').selectedIndex = 1;
                     updatePackageClassCheckboxes();
-                    if (0 < value.indexOf("package_dev")) {document.getElementById("package_class_1_input").checked = true;};
+                    if (0 < value.indexOf("package_deb")) {document.getElementById("package_class_1_input").checked = true;};
                     if (0 < value.indexOf("package_rpm")) {document.getElementById("package_class_2_input").checked = true;};
                 }
                 if (0 == value.indexOf("package_rpm")) {
                     $('select').selectedIndex = 2;
                     updatePackageClassCheckboxes();
-                    if (0 < value.indexOf("package_dev")) {document.getElementById("#package_class_1_input").checked = true;};
+                    if (0 < value.indexOf("package_deb")) {document.getElementById("#package_class_1_input").checked = true;};
                     if (0 < value.indexOf("package_ipk")) {document.getElementById("#package_class_2_input").checked = true;};
                 }
             });
@@ -723,16 +723,16 @@
 
                 pc1_checked = document.getElementById("package_class_1_input").checked;
                 pc2_checked = document.getElementById("package_class_2_input").checked;
-                if (val == "package_dev") {
+                if (val == "package_deb") {
                     if (pc1_checked) val = val + " package_ipk";
                     if (pc2_checked) val = val + " package_rpm";
                 }
                 if (val == "package_ipk") {
-                    if (pc1_checked) val = val + " package_dev";
+                    if (pc1_checked) val = val + " package_deb";
                     if (pc2_checked) val = val + " package_rpm";
                 }
                 if (val == "package_rpm") {
-                    if (pc1_checked) val = val + " package_dev";
+                    if (pc1_checked) val = val + " package_deb";
                     if (pc2_checked) val = val + " package_ipk";
                 }
 
Signature · 1 line
1.9.1
#17 lore raw

PATCH 17/17 toaster: Fix the orderkey to match the column

In reply to Alex DAMIAN

From: Michael Wood <[email protected]>

If the orderkey doesn't map to the current sort value then when hiding the column the sort doesn't get removed.

[YOCTO #7262]

---
 lib/toaster/toastergui/views.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
lib/toaster/toastergui/views.py +1 -1
index 807bf9b..fe016cc 100755
@@ -1401,7 +1401,7 @@ def bpackage(request, build_id):
                 '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__layer__branch',
+                'orderkey' : 'recipe__layer_version__branch',
                 'clclass': 'recipe__layer_version__branch', 'hidden': 1,
             },
             {
Signature · 1 line
1.9.1