diff options
| author | David Reyna <David.Reyna@windriver.com> | 2017-06-27 13:44:29 -0700 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2017-06-28 16:02:15 +0100 |
| commit | 43aaa802c35ecc9d972f3b9adcd060033de1d9de (patch) | |
| tree | bd8e0fd2ec8c01df2316538ac07527fe67823e6b /bitbake/lib | |
| parent | d74bcbeaf241a67871d62b7e2c17900ae900642e (diff) | |
| download | poky-43aaa802c35ecc9d972f3b9adcd060033de1d9de.tar.gz | |
bitbake: toaster: git clone progress bar
If a project has a lot of additional layers, the build may
appear to hang while those layers are checked out.
This patch adds a clone progress bar that is visible before
the parsing progress appears.
[YOCTO #9916]
(Bitbake rev: 0c94d947b74c4dee23d7b9d255facd3cf839ccbe)
Signed-off-by: David Reyna <David.Reyna@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib')
| -rw-r--r-- | bitbake/lib/toaster/bldcontrol/localhostbecontroller.py | 12 | ||||
| -rw-r--r-- | bitbake/lib/toaster/orm/migrations/0016_clone_progress.py | 24 | ||||
| -rw-r--r-- | bitbake/lib/toaster/orm/models.py | 15 | ||||
| -rw-r--r-- | bitbake/lib/toaster/toastergui/static/js/mrbsection.js | 15 | ||||
| -rw-r--r-- | bitbake/lib/toaster/toastergui/templates/mrb_section.html | 29 | ||||
| -rw-r--r-- | bitbake/lib/toaster/toastergui/widgets.py | 4 |
6 files changed, 98 insertions, 1 deletions
diff --git a/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py b/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py index 62e62fe19e..291624625b 100644 --- a/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py +++ b/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py | |||
| @@ -85,6 +85,11 @@ class LocalhostBEController(BuildEnvironmentController): | |||
| 85 | return local_checkout_path | 85 | return local_checkout_path |
| 86 | 86 | ||
| 87 | 87 | ||
| 88 | def setCloneStatus(self,bitbake,status,total,current): | ||
| 89 | bitbake.req.build.repos_cloned=current | ||
| 90 | bitbake.req.build.repos_to_clone=total | ||
| 91 | bitbake.req.build.save() | ||
| 92 | |||
| 88 | def setLayers(self, bitbake, layers, targets): | 93 | def setLayers(self, bitbake, layers, targets): |
| 89 | """ a word of attention: by convention, the first layer for any build will be poky! """ | 94 | """ a word of attention: by convention, the first layer for any build will be poky! """ |
| 90 | 95 | ||
| @@ -147,7 +152,13 @@ class LocalhostBEController(BuildEnvironmentController): | |||
| 147 | logger.info("Using pre-checked out source for layer %s", cached_layers) | 152 | logger.info("Using pre-checked out source for layer %s", cached_layers) |
| 148 | 153 | ||
| 149 | # 3. checkout the repositories | 154 | # 3. checkout the repositories |
| 155 | clone_count=0 | ||
| 156 | clone_total=len(gitrepos.keys()) | ||
| 157 | self.setCloneStatus(bitbake,'Started',clone_total,clone_count) | ||
| 150 | for giturl, commit in gitrepos.keys(): | 158 | for giturl, commit in gitrepos.keys(): |
| 159 | self.setCloneStatus(bitbake,'progress',clone_total,clone_count) | ||
| 160 | clone_count += 1 | ||
| 161 | |||
| 151 | localdirname = os.path.join(self.be.sourcedir, self.getGitCloneDirectory(giturl, commit)) | 162 | localdirname = os.path.join(self.be.sourcedir, self.getGitCloneDirectory(giturl, commit)) |
| 152 | logger.debug("localhostbecontroller: giturl %s:%s checking out in current directory %s" % (giturl, commit, localdirname)) | 163 | logger.debug("localhostbecontroller: giturl %s:%s checking out in current directory %s" % (giturl, commit, localdirname)) |
| 153 | 164 | ||
| @@ -198,6 +209,7 @@ class LocalhostBEController(BuildEnvironmentController): | |||
| 198 | if name != "bitbake": | 209 | if name != "bitbake": |
| 199 | layerlist.append(localdirpath.rstrip("/")) | 210 | layerlist.append(localdirpath.rstrip("/")) |
| 200 | 211 | ||
| 212 | self.setCloneStatus(bitbake,'complete',clone_total,clone_count) | ||
| 201 | logger.debug("localhostbecontroller: current layer list %s " % pformat(layerlist)) | 213 | logger.debug("localhostbecontroller: current layer list %s " % pformat(layerlist)) |
| 202 | 214 | ||
| 203 | # 5. create custom layer and add custom recipes to it | 215 | # 5. create custom layer and add custom recipes to it |
diff --git a/bitbake/lib/toaster/orm/migrations/0016_clone_progress.py b/bitbake/lib/toaster/orm/migrations/0016_clone_progress.py new file mode 100644 index 0000000000..852b8785fe --- /dev/null +++ b/bitbake/lib/toaster/orm/migrations/0016_clone_progress.py | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | # -*- coding: utf-8 -*- | ||
| 2 | from __future__ import unicode_literals | ||
| 3 | |||
| 4 | from django.db import migrations, models | ||
| 5 | |||
| 6 | class Migration(migrations.Migration): | ||
| 7 | |||
| 8 | dependencies = [ | ||
| 9 | ('orm', '0015_layer_local_source_dir'), | ||
| 10 | ] | ||
| 11 | |||
| 12 | operations = [ | ||
| 13 | migrations.AddField( | ||
| 14 | model_name='build', | ||
| 15 | name='repos_cloned', | ||
| 16 | field=models.IntegerField(default=0), | ||
| 17 | ), | ||
| 18 | migrations.AddField( | ||
| 19 | model_name='build', | ||
| 20 | name='repos_to_clone', | ||
| 21 | field=models.IntegerField(default=1), | ||
| 22 | ), | ||
| 23 | ] | ||
| 24 | |||
diff --git a/bitbake/lib/toaster/orm/models.py b/bitbake/lib/toaster/orm/models.py index a49f9a432a..13bd11704a 100644 --- a/bitbake/lib/toaster/orm/models.py +++ b/bitbake/lib/toaster/orm/models.py | |||
| @@ -437,6 +437,12 @@ class Build(models.Model): | |||
| 437 | # number of recipes parsed so far for this build | 437 | # number of recipes parsed so far for this build |
| 438 | recipes_parsed = models.IntegerField(default=0) | 438 | recipes_parsed = models.IntegerField(default=0) |
| 439 | 439 | ||
| 440 | # number of repos to clone for this build | ||
| 441 | repos_to_clone = models.IntegerField(default=1) | ||
| 442 | |||
| 443 | # number of repos cloned so far for this build | ||
| 444 | repos_cloned = models.IntegerField(default=0) | ||
| 445 | |||
| 440 | @staticmethod | 446 | @staticmethod |
| 441 | def get_recent(project=None): | 447 | def get_recent(project=None): |
| 442 | """ | 448 | """ |
| @@ -667,6 +673,13 @@ class Build(models.Model): | |||
| 667 | else: | 673 | else: |
| 668 | return False | 674 | return False |
| 669 | 675 | ||
| 676 | def is_cloning(self): | ||
| 677 | """ | ||
| 678 | True if the build is still cloning repos | ||
| 679 | """ | ||
| 680 | return self.outcome == Build.IN_PROGRESS and \ | ||
| 681 | self.repos_cloned < self.repos_to_clone | ||
| 682 | |||
| 670 | def is_parsing(self): | 683 | def is_parsing(self): |
| 671 | """ | 684 | """ |
| 672 | True if the build is still parsing recipes | 685 | True if the build is still parsing recipes |
| @@ -698,6 +711,8 @@ class Build(models.Model): | |||
| 698 | return 'Cancelling'; | 711 | return 'Cancelling'; |
| 699 | elif self.is_queued(): | 712 | elif self.is_queued(): |
| 700 | return 'Queued' | 713 | return 'Queued' |
| 714 | elif self.is_cloning(): | ||
| 715 | return 'Cloning' | ||
| 701 | elif self.is_parsing(): | 716 | elif self.is_parsing(): |
| 702 | return 'Parsing' | 717 | return 'Parsing' |
| 703 | elif self.is_starting(): | 718 | elif self.is_starting(): |
diff --git a/bitbake/lib/toaster/toastergui/static/js/mrbsection.js b/bitbake/lib/toaster/toastergui/static/js/mrbsection.js index 73d0935fa5..c0c5fa9589 100644 --- a/bitbake/lib/toaster/toastergui/static/js/mrbsection.js +++ b/bitbake/lib/toaster/toastergui/static/js/mrbsection.js | |||
| @@ -61,6 +61,12 @@ function mrbSectionInit(ctx){ | |||
| 61 | return (cached.recipes_parsed_percentage !== build.recipes_parsed_percentage); | 61 | return (cached.recipes_parsed_percentage !== build.recipes_parsed_percentage); |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | // returns true if the number of repos cloned/to clone changed | ||
| 65 | function cloneProgressChanged(build) { | ||
| 66 | var cached = getCached(build); | ||
| 67 | return (cached.repos_cloned_percentage !== build.repos_cloned_percentage); | ||
| 68 | } | ||
| 69 | |||
| 64 | function refreshMostRecentBuilds(){ | 70 | function refreshMostRecentBuilds(){ |
| 65 | libtoaster.getMostRecentBuilds( | 71 | libtoaster.getMostRecentBuilds( |
| 66 | libtoaster.ctx.mostRecentBuildsUrl, | 72 | libtoaster.ctx.mostRecentBuildsUrl, |
| @@ -100,6 +106,15 @@ function mrbSectionInit(ctx){ | |||
| 100 | 106 | ||
| 101 | container.html(html); | 107 | container.html(html); |
| 102 | } | 108 | } |
| 109 | else if (cloneProgressChanged(build)) { | ||
| 110 | // update the clone progress text | ||
| 111 | selector = '#repos-cloned-percentage-' + build.id; | ||
| 112 | $(selector).html(build.repos_cloned_percentage); | ||
| 113 | |||
| 114 | // update the recipe progress bar | ||
| 115 | selector = '#repos-cloned-percentage-bar-' + build.id; | ||
| 116 | $(selector).width(build.repos_cloned_percentage + '%'); | ||
| 117 | } | ||
| 103 | else if (tasksProgressChanged(build)) { | 118 | else if (tasksProgressChanged(build)) { |
| 104 | // update the task progress text | 119 | // update the task progress text |
| 105 | selector = '#build-pc-done-' + build.id; | 120 | selector = '#build-pc-done-' + build.id; |
diff --git a/bitbake/lib/toaster/toastergui/templates/mrb_section.html b/bitbake/lib/toaster/toastergui/templates/mrb_section.html index b761ffe1df..c5b9fe90d3 100644 --- a/bitbake/lib/toaster/toastergui/templates/mrb_section.html +++ b/bitbake/lib/toaster/toastergui/templates/mrb_section.html | |||
| @@ -64,7 +64,9 @@ | |||
| 64 | </div> | 64 | </div> |
| 65 | 65 | ||
| 66 | <div data-build-state="<%:state%>"> | 66 | <div data-build-state="<%:state%>"> |
| 67 | <%if state == 'Parsing'%> | 67 | <%if state == 'Cloning'%> |
| 68 | <%include tmpl='#cloning-repos-build-template'/%> | ||
| 69 | <%else state == 'Parsing'%> | ||
| 68 | <%include tmpl='#parsing-recipes-build-template'/%> | 70 | <%include tmpl='#parsing-recipes-build-template'/%> |
| 69 | <%else state == 'Queued'%> | 71 | <%else state == 'Queued'%> |
| 70 | <%include tmpl='#queued-build-template'/%> | 72 | <%include tmpl='#queued-build-template'/%> |
| @@ -98,6 +100,31 @@ | |||
| 98 | </div> | 100 | </div> |
| 99 | </script> | 101 | </script> |
| 100 | 102 | ||
| 103 | <!-- cloning repos build --> | ||
| 104 | <script id="cloning-repos-build-template" type="text/x-jsrender"> | ||
| 105 | <!-- progress bar and parse completion percentage --> | ||
| 106 | <div data-role="build-status" class="col-md-4 col-md-offset-1 progress-info"> | ||
| 107 | <!-- progress bar --> | ||
| 108 | <div class="progress"> | ||
| 109 | <div id="repos-cloned-percentage-bar-<%:id%>" | ||
| 110 | style="width: <%:repos_cloned_percentage%>%;" | ||
| 111 | class="progress-bar"> | ||
| 112 | </div> | ||
| 113 | </div> | ||
| 114 | </div> | ||
| 115 | |||
| 116 | <div class="col-md-4 progress-info"> | ||
| 117 | <!-- parse completion percentage --> | ||
| 118 | <span class="glyphicon glyphicon-question-sign get-help get-help-blue" | ||
| 119 | title="Toaster is cloning the repos required for your build"> | ||
| 120 | </span> | ||
| 121 | |||
| 122 | Cloning <span id="repos-cloned-percentage-<%:id%>"><%:repos_cloned_percentage%></span>% complete | ||
| 123 | |||
| 124 | <%include tmpl='#cancel-template'/%> | ||
| 125 | </div> | ||
| 126 | </script> | ||
| 127 | |||
| 101 | <!-- parsing recipes build --> | 128 | <!-- parsing recipes build --> |
| 102 | <script id="parsing-recipes-build-template" type="text/x-jsrender"> | 129 | <script id="parsing-recipes-build-template" type="text/x-jsrender"> |
| 103 | <!-- progress bar and parse completion percentage --> | 130 | <!-- progress bar and parse completion percentage --> |
diff --git a/bitbake/lib/toaster/toastergui/widgets.py b/bitbake/lib/toaster/toastergui/widgets.py index 6b7b981f3b..67c1ff9615 100644 --- a/bitbake/lib/toaster/toastergui/widgets.py +++ b/bitbake/lib/toaster/toastergui/widgets.py | |||
| @@ -511,6 +511,10 @@ class MostRecentBuildsView(View): | |||
| 511 | int((build_obj.recipes_parsed / | 511 | int((build_obj.recipes_parsed / |
| 512 | build_obj.recipes_to_parse) * 100) | 512 | build_obj.recipes_to_parse) * 100) |
| 513 | 513 | ||
| 514 | build['repos_cloned_percentage'] = \ | ||
| 515 | int((build_obj.repos_cloned / | ||
| 516 | build_obj.repos_to_clone) * 100) | ||
| 517 | |||
| 514 | tasks_complete_percentage = 0 | 518 | tasks_complete_percentage = 0 |
| 515 | if build_obj.outcome in (Build.SUCCEEDED, Build.FAILED): | 519 | if build_obj.outcome in (Build.SUCCEEDED, Build.FAILED): |
| 516 | tasks_complete_percentage = 100 | 520 | tasks_complete_percentage = 100 |
