Skip to contentSkip to conversation

Task progress reporting

RFC PATCH New Paul Eggleton 1 participant 7 messages May 10, 2016

lore
Share & tools
lore
#0 lore raw

cover Task progress reporting

I've often thought it would be nice if we could print progress information for individual tasks so that you could get some idea of whether the task is doing anything and how much longer it might take, and so I've been working on a set of patches to implement just that in the background for a while now and this is the result. Unfortunately this isn't necessarily practical to do for all tasks, but things like do_fetch are running processes that do output progress information so it's not too hard to tap into that and present it in the form of a progress bar next to the task, which is what this patchset does. I was also able to enable progress for do_compile in recipes that use cmake (since that outputs % complete as it runs) as well as do_rootfs where it has a number of internal steps that can be counted and weighted.

Note that this patchset is on top of Poky because there are changes required in both BitBake and OE-Core. However, for those that prefer BitBake + OE-core separately I have pushed a paule/progress-bb branch to poky-contrib (on top of bitbake master) and paule/progress-oecore to openembedded-core-contrib on top of openembedded-core master containing the same changes - ensure you have both if you go down this route.

I have contemplated and even prototyped going a step further and using the count of lines in the output to track progress for *all* long-running tasks, which does work reasonably well - the caveat is you actually need the expected line count ahead of time for each task, so you have to be able to get that from somewhere. I haven't worked out a practical means of delivering that, suggestions would be very much welcome - my prototype stuff is on poky-contrib paule/progress-wip and relies on someone profiling a build containing all the tasks beforehand and that information somehow being made available to everyone else.

Anyway, please let me know what you think.

Please review the following changes for suitability for inclusion. If you have any objections or suggestions for improvement, please respond to the patches. If you agree with the changes, please provide your Acked-by.

The following changes since commit 7ca60ec8bff7656b4e52f5a4d238913e851da089:

test-empty-image: Fix LIC_FILES_CHKSUM typo (2016-05-06 10:48:06 +0100)

are available in the git repository at:

git://git.yoctoproject.org/poky-contrib paule/progress
http://git.yoctoproject.org/cgit.cgi/poky-contrib/log/?h=paule/progress

Paul Eggleton (6):
knotty: import latest python-progressbar
lib: implement basic task progress support
fetch2: implement progress support bitbake.conf: whitelist progress varflag classes/cmake: enable progress for do_compile classes/image: implement progress support for do_rootfs

 bitbake/lib/bb/build.py                           | 143 ++++++++
 bitbake/lib/bb/fetch2/__init__.py                 |   4 +-
 bitbake/lib/bb/fetch2/git.py                      |  47 ++-
 bitbake/lib/bb/fetch2/wget.py                     |  26 +-
 bitbake/lib/bb/ui/knotty.py                       |  76 ++++-
 bitbake/lib/bb/ui/uihelper.py                     |   7 +-
 bitbake/lib/progressbar.py                        | 384 ---------------------
 bitbake/lib/progressbar/LICENSE.txt               |  52 +++
 bitbake/lib/progressbar/__init__.py               |  49 +++
 bitbake/lib/progressbar/compat.py                 |  44 +++
 bitbake/lib/progressbar/progressbar.py            | 315 +++++++++++++++++
 bitbake/lib/progressbar/widgets.py                | 391 ++++++++++++++++++++++
 meta/classes/cmake.bbclass                        |   1 +
 meta/classes/image.bbclass                        |   9 +-
 meta/conf/bitbake.conf                            |   3 +-
 meta/lib/oe/rootfs.py                             | 101 +++++-
 meta/recipes-devtools/cmake/cmake-native_3.4.3.bb |   2 +
 17 files changed, 1238 insertions(+), 416 deletions(-)
 delete mode 100644 bitbake/lib/progressbar.py
 create mode 100644 bitbake/lib/progressbar/LICENSE.txt
 create mode 100644 bitbake/lib/progressbar/__init__.py
 create mode 100644 bitbake/lib/progressbar/compat.py
 create mode 100644 bitbake/lib/progressbar/progressbar.py
 create mode 100644 bitbake/lib/progressbar/widgets.py
Signature · 1 line
2.5.5
#1 lore raw

RFC PATCH 1/6 knotty: import latest python-progressbar

Since we're going to make some minor extensions to it, it makes sense to bring in the latest version of python-progressbar. Its structure has changed a little but the API hasn't; however we do need to ensure our overridden _needs_update() function's signature in BBProgress() matches properly.

---
 bitbake/lib/bb/ui/knotty.py            |   2 +-
 bitbake/lib/progressbar.py             | 384 ---------------------------------
 bitbake/lib/progressbar/LICENSE.txt    |  52 +++++
 bitbake/lib/progressbar/__init__.py    |  49 +++++
 bitbake/lib/progressbar/compat.py      |  44 ++++
 bitbake/lib/progressbar/progressbar.py | 307 ++++++++++++++++++++++++++
 bitbake/lib/progressbar/widgets.py     | 355 ++++++++++++++++++++++++++++++
 7 files changed, 808 insertions(+), 385 deletions(-)
 delete mode 100644 bitbake/lib/progressbar.py
 create mode 100644 bitbake/lib/progressbar/LICENSE.txt
 create mode 100644 bitbake/lib/progressbar/__init__.py
 create mode 100644 bitbake/lib/progressbar/compat.py
 create mode 100644 bitbake/lib/progressbar/progressbar.py
 create mode 100644 bitbake/lib/progressbar/widgets.py
bitbake/lib/bb/ui/knotty.py +1 -1
index 2685627..010b06d 100644
@@ -51,7 +51,7 @@ class BBProgress(progressbar.ProgressBar):
             self._resize_default = None
         progressbar.ProgressBar.__init__(self, maxval, [self.msg + ": "] + widgets, fd=sys.stdout)
 
-    def _handle_resize(self, signum, frame):
+    def _handle_resize(self, signum=None, frame=None):
         progressbar.ProgressBar._handle_resize(self, signum, frame)
         if self._resize_default:
             self._resize_default(signum, frame)
bitbake/lib/progressbar.py deleted +0 -384

384 lines not on this page · raw message

bitbake/lib/progressbar/LICENSE.txt new file +52 -0

52 lines not on this page · raw message

bitbake/lib/progressbar/__init__.py new file +49 -0

49 lines not on this page · raw message

bitbake/lib/progressbar/compat.py new file +44 -0

44 lines not on this page · raw message

bitbake/lib/progressbar/progressbar.py new file +307 -0

307 lines not on this page · raw message

bitbake/lib/progressbar/widgets.py new file +355 -0

355 lines not on this page · raw message

Signature · 1 line
2.5.5
#2 lore raw

RFC PATCH 2/6 lib: implement basic task progress support

In reply to Paul Eggleton

For long-running tasks where we have some output from the task that gives us some idea of the progress of the task (such as a percentage complete), provide the means to scrape the output for that progress information and show it to the user in the default knotty terminal output in the form of a progress bar. This is implemented using a new TaskProgress event as well as some code we can insert to do output scanning/filtering.

Any task can fire TaskProgress events; however, if you have a shell task whose output you wish to scan for progress information, you just need to set the "progress" varflag on the task. This can be set to:
* "percent" to just look for a number followed by a % sign
* "percent:<regex>" to specify your own regex matching a percentage value (must have a single group which matches the percentage number)
* "outof:<regex>" to look for the specified regex matching x out of y items completed (must have two groups - first group needs to be x, second y).
We can potentially extend this in future but this should be a good start.

Line changes such as the ones you get in git's output as it progresses don't make it to the log files, you only get the final state of the line so the logs aren't filled with progress information that's useless after the fact.

Part of the implementation for [YOCTO #5383].

---
 bitbake/lib/bb/build.py                | 112 +++++++++++++++++++++++++++++++++
 bitbake/lib/bb/ui/knotty.py            |  74 +++++++++++++++++++---
 bitbake/lib/bb/ui/uihelper.py          |   7 ++-
 bitbake/lib/progressbar/progressbar.py |  16 +++--
 bitbake/lib/progressbar/widgets.py     |  36 +++++++++++
 5 files changed, 231 insertions(+), 14 deletions(-)
bitbake/lib/bb/build.py +112 -0
index a5b99ed..0b28492 100644
@@ -35,6 +35,7 @@ import stat
 import bb
 import bb.msg
 import bb.process
+import re
 from contextlib import nested
 from bb import event, utils
 
@@ -138,6 +139,13 @@ class TaskInvalid(TaskBase):
         super(TaskInvalid, self).__init__(task, None, metadata)
         self._message = "No such task '%s'" % task
 
+class TaskProgress(event.Event):
+    def __init__(self, task, progress, rate=None):
+        self.task = task
+        self.progress = progress
+        self.rate = rate
+        event.Event.__init__(self)
+
 
 class LogTee(object):
     def __init__(self, logger, outfile):
@@ -161,6 +169,96 @@ class LogTee(object):
     def flush(self):
         self.outfile.flush()
 
+
+class ProgressHandler(object):
+    """
+    Base class that can pretend to be a file object well enough to be
+    used to build objects to intercept console output and determine the
+    progress of some operation.
+    """
+    def __init__(self, d, outfile=None):
+        self._progress = 0
+        self._data = d
+        self._lastevent = 0
+        if outfile:
+            self._outfile = outfile
+        else:
+            self._outfile = sys.stdout
+
+    def write(self, string):
+        self._outfile.write(string)
+
+    def flush(self):
+        self._outfile.flush()
+
+    def update(self, progress, rate=None):
+        ts = time.time()
+        if progress > 100:
+            progress = 100
+        if progress != self._progress or self._lastevent + 1 < ts:
+            bb.event.fire(bb.build.TaskProgress(0, progress, rate), self._data)
+            self._lastevent = ts
+            self._progress = progress
+
+class BasicProgressHandler(ProgressHandler):
+    def __init__(self, d, regex=r'(\d+)%', outfile=None):
+        super(BasicProgressHandler, self).__init__(d, outfile)
+        self._regex = re.compile(regex)
+        # Send an initial progress event so the bar gets shown
+        bb.event.fire(bb.build.TaskProgress(0, 0), self._data)
+
+    def write(self, string):
+        percs = self._regex.findall(string)
+        if percs:
+            progress = int(percs[-1])
+            self.update(progress)
+        super(BasicProgressHandler, self).write(string)
+
+class OutOfProgressHandler(ProgressHandler):
+    def __init__(self, d, regex, outfile=None):
+        super(OutOfProgressHandler, self).__init__(d, outfile)
+        self._regex = re.compile(regex)
+        # Send an initial progress event so the bar gets shown
+        bb.event.fire(bb.build.TaskProgress(0, 0), self._data)
+
+    def write(self, string):
+        nums = self._regex.findall(string)
+        if nums:
+            progress = (float(nums[-1][0]) / float(nums[-1][1])) * 100
+            self.update(progress)
+        super(OutOfProgressHandler, self).write(string)
+
+class MultiStageProgressReporter(object):
+    """
+    Class which allows reporting progress without the caller
+    having to know where they are in the overall sequence. Useful
+    for tasks made up of python code spread across multiple
+    classes / functions.
+    """
+    def __init__(self, d, stage_weights):
+        self._data = d
+        self._stage_weights = stage_weights
+        self._stage = 0
+        self._base_progress = 0
+        # Send an initial progress event so the bar gets shown
+        bb.event.fire(bb.build.TaskProgress(0, 0), self._data)
+
+    def next_stage(self):
+        self._stage += 1
+        if self._stage < len(self._stage_weights):
+            self._base_progress = sum(self._stage_weights[:self._stage]) * 100
+        else:
+            bb.warn('ProgressReporter: current stage beyond declared number of stages')
+            self._base_progress = 100
+        bb.event.fire(bb.build.TaskProgress(0, self._base_progress), self._data)
+
+    def update(self, stageprogress):
+        progress = self._base_progress + (stageprogress * self._stage_weights[self._stage])
+        if progress > 100:
+            progress = 100
+        bb.event.fire(bb.build.TaskProgress(0, progress), self._data)
+
+
 #
 # pythonexception allows the python exceptions generated to be raised
 # as the real exceptions (not FuncFailed) and without a backtrace at the 
@@ -341,6 +439,20 @@ exit $ret
     else:
         logfile = sys.stdout
 
+    progress = d.getVarFlag(func, 'progress', True)
+    if progress:
+        if progress == 'percent':
+            # Use default regex
+            logfile = BasicProgressHandler(d, outfile=logfile)
+        elif progress.startswith('percent:'):
+            # Use specified regex
+            logfile = BasicProgressHandler(d, regex=progress.split(':', 1)[1], outfile=logfile)
+        elif progress.startswith('outof:'):
+            # Use specified regex
+            logfile = OutOfProgressHandler(d, regex=progress.split(':', 1)[1], outfile=logfile)
+        else:
+            bb.warn('%s: invalid task progress varflag value "%s", ignoring' % (func, progress))
+
     def readfifo(data):
         lines = data.split('\0')
         for line in lines:
bitbake/lib/bb/ui/knotty.py +65 -9

123 lines not on this page · raw message

bitbake/lib/bb/ui/uihelper.py +6 -1
index db70b76..1915e47 100644
@@ -18,6 +18,7 @@
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
 import bb.build
+import time
 
 class BBUIHelper:
     def __init__(self):
@@ -31,7 +32,7 @@ class BBUIHelper:
 
     def eventHandler(self, event):
         if isinstance(event, bb.build.TaskStarted):
-            self.running_tasks[event.pid] = { 'title' : "%s %s" % (event._package, event._task) }
+            self.running_tasks[event.pid] = { 'title' : "%s %s" % (event._package, event._task), 'starttime' : time.time() }
             self.running_pids.append(event.pid)
             self.needUpdate = True
         if isinstance(event, bb.build.TaskSucceeded):
@@ -52,6 +53,10 @@ class BBUIHelper:
             self.tasknumber_current = event.stats.completed + event.stats.active + event.stats.failed + 1
             self.tasknumber_total = event.stats.total
             self.needUpdate = True
+        if isinstance(event, bb.build.TaskProgress):
+            self.running_tasks[event.pid]['progress'] = event.progress
+            self.running_tasks[event.pid]['rate'] = event.rate
+            self.needUpdate = True
 
     def getTasks(self):
         self.needUpdate = False
bitbake/lib/progressbar/progressbar.py +12 -4
index 0b9dcf7..2873ad6 100644
@@ -3,6 +3,8 @@
 # progressbar  - Text progress bar library for Python.
 # Copyright (c) 2005 Nilton Volpato
 #
+# (With some small changes after importing into BitBake)
+#
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
 # License as published by the Free Software Foundation; either
@@ -261,12 +263,14 @@ class ProgressBar(object):
         now = time.time()
         self.seconds_elapsed = now - self.start_time
         self.next_update = self.currval + self.update_interval
-        self.fd.write(self._format_line() + '\r')
+        output = self._format_line()
+        self.fd.write(output + '\r')
         self.fd.flush()
         self.last_update_time = now
+        return output
 
 
-    def start(self):
+    def start(self, update=True):
         """Starts measuring time, and prints the bar at 0%.
 
         It returns self so you can use it like this:
@@ -289,8 +293,12 @@ class ProgressBar(object):
             self.update_interval = self.maxval / self.num_intervals
 
 
-        self.start_time = self.last_update_time = time.time()
-        self.update(0)
+        self.start_time = time.time()
+        if update:
+            self.last_update_time = self.start_time
+            self.update(0)
+        else:
+            self.last_update_time = 0
 
         return self
 
bitbake/lib/progressbar/widgets.py +36 -0
index 6434ad5..77285ca 100644
@@ -353,3 +353,39 @@ class BouncingBar(Bar):
         if not self.fill_left: rpad, lpad = lpad, rpad
 
         return '%s%s%s%s%s' % (left, lpad, marker, rpad, right)
+
+
+class BouncingSlider(Bar):
+    """
+    A slider that bounces back and forth in response to update() calls
+    without reference to the actual value. Based on a combination of
+    BouncingBar from a newer version of this module and RotatingMarker.
+    """
+    def __init__(self, marker='<=>'):
+        self.curmark = -1
+        self.forward = True
+        Bar.__init__(self, marker=marker)
+    def update(self, pbar, width):
+        left, marker, right = (format_updatable(i, pbar) for i in
+                               (self.left, self.marker, self.right))
+
+        width -= len(left) + len(right)
+        if width < 0:
+            return ''
+
+        if pbar.finished: return '%s%s%s' % (left, width * '=', right)
+
+        self.curmark = self.curmark + 1
+        position = int(self.curmark % (width * 2 - 1))
+        if position + len(marker) > width:
+            self.forward = not self.forward
+            self.curmark = 1
+            position = 1
+        lpad = ' ' * (position - 1)
+        rpad = ' ' * (width - len(marker) - len(lpad))
+
+        if not self.forward:
+            temp = lpad
+            lpad = rpad
+            rpad = temp
+        return '%s%s%s%s%s' % (left, lpad, marker, rpad, right)
Signature · 1 line
2.5.5
#3 lore raw

RFC PATCH 3/6 fetch2: implement progress support

In reply to Paul Eggleton

Implement progress reporting support specifically for the fetchers. For fetch tasks we don't necessarily know which fetcher will be used (we might initially be fetching a git:// URI, but if we instead download a mirror tarball we may fetch that over http using wget). These programs also have different abilities as far as reporting progress goes (e.g. wget gives us percentage complete and rate, git gives this some of the time depending on what stage it's at). Additionally we filter out the progress output before it makes it to the logs, in order to prevent the logs filling up with junk.

At the moment this is only implemented for the wget and git fetchers since they are the most commonly used (and svn doesn't seem to support any kind of progress output, at least not without doing a relatively expensive remote file listing first).

Part of the implementation for [YOCTO #5383].

---
 bitbake/lib/bb/build.py           | 31 ++++++++++++++++++++++++++
 bitbake/lib/bb/fetch2/__init__.py |  4 ++--
 bitbake/lib/bb/fetch2/git.py      | 47 +++++++++++++++++++++++++++++++++++++--
 bitbake/lib/bb/fetch2/wget.py     | 26 +++++++++++++++++++++-
 4 files changed, 103 insertions(+), 5 deletions(-)
bitbake/lib/bb/build.py +31 -0
index 0b28492..8cb80cf 100644
@@ -200,6 +200,37 @@ class ProgressHandler(object):
             self._lastevent = ts
             self._progress = progress
 
+class LineFilterProgressHandler(ProgressHandler):
+    """
+    A ProgressHandler variant that provides the ability to filter out
+    the lines if they contain progress information. Additionally, it
+    filters out anything before the last line feed on a line. This can
+    be used to keep the logs clean of output that we've only enabled for
+    getting progress, assuming that that can be done on a per-line
+    basis.
+    """
+    def __init__(self, d, outfile=None):
+        self._linebuffer = ''
+        super(LineFilterProgressHandler, self).__init__(d, outfile)
+
+    def write(self, string):
+        self._linebuffer += string
+        while True:
+            breakpos = self._linebuffer.find('\n') + 1
+            if breakpos == 0:
+                break
+            line = self._linebuffer[:breakpos]
+            self._linebuffer = self._linebuffer[breakpos:]
+            # Drop any line feeds and anything that precedes them
+            lbreakpos = line.rfind('\r') + 1
+            if lbreakpos:
+                line = line[lbreakpos:]
+            if self.writeline(line):
+                super(LineFilterProgressHandler, self).write(line)
+
+    def writeline(self, line):
+        return True
+
 class BasicProgressHandler(ProgressHandler):
     def __init__(self, d, regex=r'(\d+)%', outfile=None):
         super(BasicProgressHandler, self).__init__(d, outfile)
bitbake/lib/bb/fetch2/__init__.py +2 -2
index 6ef0c6f..394c31c 100644
@@ -784,7 +784,7 @@ def localpath(url, d):
     fetcher = bb.fetch2.Fetch([url], d)
     return fetcher.localpath(url)
 
-def runfetchcmd(cmd, d, quiet=False, cleanup=None):
+def runfetchcmd(cmd, d, quiet=False, cleanup=None, log=None):
     """
     Run cmd returning the command output
     Raise an error if interrupted or cmd fails
@@ -825,7 +825,7 @@ def runfetchcmd(cmd, d, quiet=False, cleanup=None):
     error_message = ""
 
     try:
-        (output, errors) = bb.process.run(cmd, shell=True, stderr=subprocess.PIPE)
+        (output, errors) = bb.process.run(cmd, log=log, shell=True, stderr=subprocess.PIPE)
         success = True
     except bb.process.NotFoundError as e:
         error_message = "Fetch command %s" % (e.command)
bitbake/lib/bb/fetch2/git.py +45 -2

66 lines not on this page · raw message

bitbake/lib/bb/fetch2/wget.py +25 -1
index 8bc9e93..c07c3c8 100644
@@ -31,6 +31,7 @@ import subprocess
 import os
 import logging
 import bb
+import bb.build
 import urllib
 from   bb import data
 from   bb.fetch2 import FetchMethod
@@ -41,6 +42,27 @@ from   bb.utils import export_proxies
 from   bs4 import BeautifulSoup
 from   bs4 import SoupStrainer
 
+class WgetProgressHandler(bb.build.LineFilterProgressHandler):
+    """
+    Extract progress information from wget output.
+    Note: relies on --progress=dot --show-progress being specified on the
+    wget command line.
+    """
+    def __init__(self, d):
+        super(WgetProgressHandler, self).__init__(d)
+        # Send an initial progress event so the bar gets shown
+        bb.event.fire(bb.build.TaskProgress(0, 0), self._data)
+
+    def writeline(self, line):
+        percs = re.findall(r'(\d+)%\s+([\d.]+[A-Z])', line)
+        if percs:
+            progress = int(percs[-1][0])
+            rate = percs[-1][1] + '/s'
+            self.update(progress, rate)
+            return False
+        return True
+
+
 class Wget(FetchMethod):
     """Class to fetch urls via 'wget'"""
     def supports(self, ud, d):
@@ -70,9 +92,11 @@ class Wget(FetchMethod):
 
     def _runwget(self, ud, d, command, quiet):
 
+        progresshandler = WgetProgressHandler(d)
+
         logger.debug(2, "Fetching %s using command '%s'" % (ud.url, command))
         bb.fetch2.check_network_access(d, command)
-        runfetchcmd(command, d, quiet)
+        runfetchcmd(command + ' --progress=dot --show-progress', d, quiet, log=progresshandler)
 
     def download(self, ud, d):
         """Fetch urls"""
Signature · 1 line
2.5.5
#4 lore raw

RFC PATCH 4/6 bitbake.conf: whitelist progress varflag

In reply to Paul Eggleton

We don't want the value of this varflag in any signatures since it's only there for the purpose of aiding display of task execution.

---
 meta/conf/bitbake.conf | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
meta/conf/bitbake.conf +2 -1
index 1c4175f..14fee7f 100644
@@ -814,7 +814,8 @@ BB_SIGNATURE_EXCLUDE_FLAGS ?= "doc deps depends \
     lockfiles type vardepsexclude vardeps vardepvalue vardepvalueexclude \
     file-checksums python func task export unexport noexec nostamp dirs cleandirs \
     sstate-lockfile-shared prefuncs postfuncs export_func deptask rdeptask \
-    recrdeptask nodeprrecs stamp-extra-info sstate-outputdirs filename lineno"
+    recrdeptask nodeprrecs stamp-extra-info sstate-outputdirs filename lineno \
+    progress"
 
 MLPREFIX ??= ""
 MULTILIB_VARIANTS ??= ""
Signature · 1 line
2.5.5
#5 lore raw

RFC PATCH 5/6 classes/cmake: enable progress for do_compile

In reply to Paul Eggleton

cmake outputs percentage complete as part of its compilation process, so we can enable BitBake's new progress scanning for do_compile here.

---
 meta/classes/cmake.bbclass                        | 1 +
 meta/recipes-devtools/cmake/cmake-native_3.4.3.bb | 2 ++
 2 files changed, 3 insertions(+)
meta/classes/cmake.bbclass +1 -0
index 02f313a..f06600f 100644
@@ -124,6 +124,7 @@ cmake_do_configure() {
 	  -Wno-dev
 }
 
+do_compile[progress] = "percent"
 cmake_do_compile()  {
 	cd ${B}
 	base_do_compile
meta/recipes-devtools/cmake/cmake-native_3.4.3.bb +2 -0
index cb4e749..33930fb 100644
@@ -14,3 +14,5 @@ CMAKE_EXTRACONF = "\
     -DENABLE_ACL=0 -DHAVE_ACL_LIBACL_H=0 \
     -DHAVE_SYS_ACL_H=0 \
 "
+
+do_compile[progress] = "percent"
Signature · 1 line
2.5.5
#6 lore raw

RFC PATCH 6/6 classes/image: implement progress support for do_rootfs

In reply to Paul Eggleton

Use the new task progress functionality to report progress during do_rootfs. I did some timings of the various parts of the do_rootfs code and set some weightings accordingly. This is a little coarse and ideally we would have some progress within the installation section, but it's better than nothing.

---
 meta/classes/image.bbclass |   9 +++-
 meta/lib/oe/rootfs.py      | 101 +++++++++++++++++++++++++++++++++++++++------
 2 files changed, 95 insertions(+), 15 deletions(-)
meta/classes/image.bbclass +7 -2
index 4542e95..efa0629 100644
@@ -198,6 +198,9 @@ fakeroot python do_rootfs () {
     from oe.rootfs import create_rootfs
     from oe.manifest import create_manifest
 
+    stage_weights = [0.01, 0.1, 0.18, 0.1, 0.03, 0.5, 0, 0.01, 0.02, 0.02, 0.02, 0.01, 0]
+    progress_reporter = bb.build.MultiStageProgressReporter(d, stage_weights)
+
     # Handle package exclusions
     excl_pkgs = d.getVar("PACKAGE_EXCLUDE", True).split()
     inst_pkgs = d.getVar("PACKAGE_INSTALL", True).split()
@@ -230,8 +233,10 @@ fakeroot python do_rootfs () {
     # Generate the initial manifest
     create_manifest(d)
 
-    # Generate rootfs
-    create_rootfs(d)
+    progress_reporter.next_stage()
+
+    # generate rootfs
+    create_rootfs(d, progress_reporter=progress_reporter)
 }
 do_rootfs[dirs] = "${TOPDIR}"
 do_rootfs[cleandirs] += "${S}"
meta/lib/oe/rootfs.py +88 -13

248 lines not on this page · raw message

Signature · 1 line
2.5.5