toaster: cummulative patch Aug 28 2018
cover toaster: cummulative patch Aug 28 2018
From: David Reyna <[email protected]>
---
This cumulative enhancement patch includes the following, to support flexibility and usability for Toaster.
* 12891 - "Allow flexible value for TOASTERDIR plus custom fixture support"
This supports the flexibility of having the Toaster base directory (used got the database and project build directories) to be specified by the user. It also allows for flexibility in the location of bitbake to be within one the specified local layers instead of being in the default fixed location.
* 12902 - "Enable project import and merged Toaster settings"
This optionally enables Toaster and command line compatibility, where the Toaster settings are saved in the normal "local.conf" and "bblayers.conf" in a well defined and contained append structure. It also supports importing and detaching existing command line build projects, where importing a project inherits the existing project settings.
---
The following changes since commit 87d3a9685dd9613e4f6718031d4ebd9344b01c47:
bitbake: parse/ast: ensure saved event handlers really do get restored (2018-08-24 07:53:14 +0100)
are available in the git repository at:
git://git.yoctoproject.org/poky-contrib dreyna/toaster/import_builds_12902
http://git.yoctoproject.org/cgit.cgi/poky-contrib/log/?h=dreyna/submit/dreyna/toaster/cummulative_082618
Awais Belal (8):
toaster: allow pokydirname to be evaluated when all layers are local
toaster: use a more flexible way to find bitbake
toaster: allow TOASTER_DIR to be overridden from cmdline toaster/widgets.py: avoid divide by zero issues toastergui/newproject.html: fix release divs toaster/checksettings: allow CUSTOM_XML_ONLY setting through env toaster/models.py: allow local paths for custom recipe's base toaster/layerdetails.js: don't hide local layer info
David Reyna (1):
toaster: enable project import and merged Toaster settings
bin/toaster | 9 +++- lib/toaster/bldcontrol/localhostbecontroller.py | 39 ++++++++++++--- .../management/commands/checksettings.py | 3 +- lib/toaster/orm/models.py | 7 +++ lib/toaster/toastergui/static/js/layerdetails.js | 3 +- lib/toaster/toastergui/templates/newproject.html | 57 +++++++++++----------- lib/toaster/toastergui/views.py | 22 ++++++--- lib/toaster/toastergui/widgets.py | 19 +++++--- .../toastermain/management/commands/buildimport.py | 7 +-- 9 files changed, 107 insertions(+), 59 deletions(-)
Signature · 1 line
1.9.1
PATCH 1/9 toaster: allow pokydirname to be evaluated when all layers are local
From: Awais Belal <[email protected]>
Toaster depends on pokydirname for identifying the location of the oe-init-build-env script (and there might be other purposes in the future). The problem with current approach is that it only checks/sets the variable with git based repos, whereas toaster provides mechanisms to allow having layers that are all locally available. The evaluation of the variable fails in such scenarios, so use a more flexible mechanism in this case and try to locate poky in the local layers as well, if not already set.
[YOCTO #12891]
--- lib/toaster/bldcontrol/localhostbecontroller.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
lib/toaster/bldcontrol/localhostbecontroller.py +15 -3
@@ -222,9 +222,21 @@ class LocalhostBEController(BuildEnvironmentController): self.setCloneStatus(bitbake,'complete',clone_total,clone_count,'') logger.debug("localhostbecontroller: current layer list %s " % pformat(layerlist)) - if self.pokydirname is None and os.path.exists(os.path.join(self.be.sourcedir, "oe-init-build-env")): - logger.debug("localhostbecontroller: selected poky dir name %s" % self.be.sourcedir) - self.pokydirname = self.be.sourcedir + # Resolve self.pokydirname if not resolved yet, consider the scenario + # where all layers are local, that's the else clause + if self.pokydirname is None: + if os.path.exists(os.path.join(self.be.sourcedir, "oe-init-build-env")): + logger.debug("localhostbecontroller: selected poky dir name %s" % self.be.sourcedir) + self.pokydirname = self.be.sourcedir + else: + # Alternatively, scan local layers for relative "oe-init-build-env" location + for layer in layers: + if os.path.exists(os.path.join(layer.layer_version.layer.local_source_dir,"..","oe-init-build-env")): + logger.debug("localhostbecontroller, setting pokydirname to %s" % (layer.layer_version.layer.local_source_dir)) + self.pokydirname = os.path.join(layer.layer_version.layer.local_source_dir,"..") + break + else: + logger.error("pokydirname is not set, you will run into trouble!") # 5. create custom layer and add custom recipes to it for target in targets:
Signature · 1 line
1.9.1
PATCH 2/9 toaster: use a more flexible way to find bitbake
In reply to David ReynaFrom: Awais Belal <[email protected]>
The current mechanism for finding the bitbake binary assumes a directory structure which is identical to poky, where oe-core's meta and bitbake directories are at the same level. There can be a case where bitbake is used from elsewhere and in such cases the above mentioned assumption fails to hold, whereas this is totally allowed by the oe-init-build-env script which can take bitbakedir as an argument.
The better approach is to allow bitbake to be derived from PATH, while keeping the older mechanism in place so it can be removed after tests are done in various environments. This makes more sense as toaster has also been launched from the same bitbake instance that is the one in PATH.
[YOCTO #12891]
--- lib/toaster/bldcontrol/localhostbecontroller.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
lib/toaster/bldcontrol/localhostbecontroller.py +12 -1
@@ -444,8 +444,19 @@ class LocalhostBEController(BuildEnvironmentController): # clean the Toaster to build environment env_clean = 'unset BBPATH;' # clean BBPATH for <= YP-2.4.0 - # run bitbake server from the clone + # run bitbake server from the clone if available + # otherwise pick it from the PATH bitbake = os.path.join(self.pokydirname, 'bitbake', 'bin', 'bitbake') + if not os.path.exists(bitbake): + logger.info("Bitbake not available under %s, will try to use it from PATH" % + self.pokydirname) + for path in os.environ["PATH"].split(os.pathsep): + if os.path.exists(os.path.join(path, 'bitbake')): + bitbake = os.path.join(path, 'bitbake') + break + else: + logger.error("Looks like Bitbake is not available, please fix your environment") + toasterlayers = os.path.join(builddir,"conf/toaster-bblayers.conf") if not is_merged_attr: self._shellcmd('%s bash -c \"source %s %s; BITBAKE_UI="knotty" %s --read %s --read %s '
Signature · 1 line
1.9.1
PATCH 3/9 toaster: allow TOASTER_DIR to be overridden from cmdline
In reply to David ReynaFrom: Awais Belal <[email protected]>
TOASTER_DIR is used for higher level toaster artifacts such the SQL DB and creating toaster internal build directories for projects. Prior to this change it was evaluated as dirname $BUILDDIR and user had no control over it. This change allows to override this variable from the command line for more flexibility. The variable defaults to its original setting if the optional argument is not passed.
[YOCTO #12891]
--- bin/toaster | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
bin/toaster +7 -2
@@ -18,11 +18,12 @@ # along with this program. If not, see http://www.gnu.org/licenses/. HELP=" -Usage: source toaster start|stop [webport=<address:port>] [noweb] [nobuild] +Usage: source toaster start|stop [webport=<address:port>] [noweb] [nobuild] [toasterdir] Optional arguments: [nobuild] Setup the environment for capturing builds with toaster but disable managed builds [noweb] Setup the environment for capturing builds with toaster but don't start the web server [webport] Set the development server (default: localhost:8000) + [toasterdir] Set absolute path to be used as TOASTER_DIR (default: BUILDDIR/../) " custom_extention()
@@ -186,6 +187,7 @@ unset OE_ROOT WEBSERVER=1 export TOASTER_BUILDSERVER=1 ADDR_PORT="localhost:8000" +TOASTERDIR=`dirname $BUILDDIR` unset CMD for param in $*; do case $param in
@@ -211,6 +213,9 @@ for param in $*; do ADDR_PORT="localhost:$PORT" fi ;; + toasterdir=*) + TOASTERDIR="${param#*=}" + ;; --help) echo "$HELP" return 0
@@ -241,7 +246,7 @@ fi # 2) the build dir (in build) # 3) the sqlite db if that is being used. # 4) pid's we need to clean up on exit/shutdown -export TOASTER_DIR=`dirname $BUILDDIR` +export TOASTER_DIR=$TOASTERDIR export BB_ENV_EXTRAWHITE="$BB_ENV_EXTRAWHITE TOASTER_DIR" # Determine the action. If specified by arguments, fine, if not, toggle it
Signature · 1 line
1.9.1
PATCH 4/9 toaster/widgets.py: avoid divide by zero issues
In reply to David ReynaFrom: Awais Belal <[email protected]>
There can be cases where the variables being used to divide in build percentage expressions can be zero. For example, a setup consisting of only local repos will have repos_to_clone=0 and will generate a divide by zero scenario.
Fix this by checking the divisor in such cases.
[YOCTO #12891]
--- lib/toaster/toastergui/widgets.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-)
lib/toaster/toastergui/widgets.py +12 -7
@@ -515,13 +515,18 @@ class MostRecentBuildsView(View): buildrequest_id = build_obj.buildrequest.pk build['buildrequest_id'] = buildrequest_id - build['recipes_parsed_percentage'] = \ - int((build_obj.recipes_parsed / - build_obj.recipes_to_parse) * 100) - - build['repos_cloned_percentage'] = \ - int((build_obj.repos_cloned / - build_obj.repos_to_clone) * 100) + if build_obj.recipes_to_parse > 0: + build['recipes_parsed_percentage'] = \ + int((build_obj.recipes_parsed / + build_obj.recipes_to_parse) * 100) + else: + build['recipes_parsed_percentage'] = 0 + if build_obj.repos_to_clone > 0: + build['repos_cloned_percentage'] = \ + int((build_obj.repos_cloned / + build_obj.repos_to_clone) * 100) + else: + build['repos_cloned_percentage'] = 0 build['progress_item'] = build_obj.progress_item
Signature · 1 line
1.9.1
PATCH 5/9 toastergui/newproject.html: fix release divs
In reply to David ReynaFrom: Awais Belal <[email protected]>
The release drop down divs are not being closed appropriately, which showed adverse reactions on the UI that aligned the "Create project" button with the left edge of the screen without any margins. This fixes these divs which in turn aligns the button appropriately.
[YOCTO #12891]
--- lib/toaster/toastergui/templates/newproject.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
lib/toaster/toastergui/templates/newproject.html +2 -2
@@ -54,12 +54,12 @@ <span class="help-block">{{release.helptext|safe}}</span> </div> {% endfor %} + </div> + </div> {% else %} <input type="hidden" name="projectversion" value="{{releases.0.id}}"/> {% endif %} </div> - </div> - </fieldset> {% endif %} <div class="top-air"> <input type="submit" id="create-project-button" class="btn btn-primary btn-lg" value="Create project"/>
Signature · 1 line
1.9.1
PATCH 6/9 toaster/checksettings: allow CUSTOM_XML_ONLY setting through env
In reply to David ReynaFrom: Awais Belal <[email protected]>
This change allows the CUSTOM_XML_ONLY toaster setting to be provided through the environment so the user can do this without mingling with the settings.xml, for scenarios where modifying settings.xml is not achievable.
[YOCTO #12891]
--- lib/toaster/bldcontrol/management/commands/checksettings.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
lib/toaster/bldcontrol/management/commands/checksettings.py +2 -1
@@ -74,8 +74,9 @@ class Command(BaseCommand): print("Loading default settings") call_command("loaddata", "settings") template_conf = os.environ.get("TEMPLATECONF", "") + custom_xml_only = os.environ.get("CUSTOM_XML_ONLY") - if ToasterSetting.objects.filter(name='CUSTOM_XML_ONLY').count() > 0: + if ToasterSetting.objects.filter(name='CUSTOM_XML_ONLY').count() > 0 or (not custom_xml_only == None): # only use the custom settings pass elif "poky" in template_conf:
Signature · 1 line
1.9.1
PATCH 7/9 toaster/models.py: allow local paths for custom recipe's base
In reply to David ReynaFrom: Awais Belal <[email protected]>
In a case where the layer source is local only and the recipe is not yet built, we can search for the path with layer's local_source_dir, and if available that should be used rather than just skipping the scenario.
[YOCTO #12891]
--- lib/toaster/orm/models.py | 7 +++++++ 1 file changed, 7 insertions(+)
lib/toaster/orm/models.py +7 -0
@@ -1712,6 +1712,9 @@ class CustomImageRecipe(Recipe): path_schema_two = self.base_recipe.file_path + path_schema_three = "%s/%s" % (self.base_recipe.layer_version.layer.local_source_dir, + self.base_recipe.file_path) + if os.path.exists(path_schema_one): return path_schema_one
@@ -1719,6 +1722,10 @@ class CustomImageRecipe(Recipe): if os.path.exists(path_schema_two): return path_schema_two + # Or a local path if all layers are local + if os.path.exists(path_schema_three): + return path_schema_three + return None def generate_recipe_file_contents(self):
Signature · 1 line
1.9.1
PATCH 8/9 toaster/layerdetails.js: don't hide local layer info
In reply to David ReynaFrom: Awais Belal <[email protected]>
The local layer info (provided through custom fixtures) should not be hidden. It is better to handle it in the same manner as an imported layer, otherwise the layer path and dependency info is not shown. The layer editing fields are handled in the html side of things appropriately so this does not harm that implementation.
[YOCTO #12891]
--- lib/toaster/toastergui/static/js/layerdetails.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
lib/toaster/toastergui/static/js/layerdetails.js +2 -1
@@ -359,7 +359,8 @@ function layerDetailsPageInit (ctx) { if ($(this).is("dt")) { var dd = $(this).next("dd"); if (!dd.children("form:visible")|| !dd.find(".current-value").html()){ - if (ctx.layerVersion.layer_source == ctx.layerSourceTypes.TYPE_IMPORTED){ + if (ctx.layerVersion.layer_source == ctx.layerSourceTypes.TYPE_IMPORTED || + ctx.layerVersion.layer_source == ctx.layerSourceTypes.TYPE_LOCAL) { /* There's no current value and the layer is editable * so show the "Not set" and hide the delete icon */
Signature · 1 line
1.9.1
PATCH 9/9 toaster: enable project import and merged Toaster settings
In reply to David ReynaFrom: David Reyna <[email protected]>
Enable the ability to select an existing build directory into Toaster. This opens to the user the backend features of 12823, for command line user compatibility.
Enable the ability to select saving Toaster settings in the regular "bblayers.conf" and "local.conf" instead of the default "toaster_bblayers.conf" and "toaster.conf". This opens to the user the backend features of 12821, for command line user compatibility.
[YOCTO #12902]
--- lib/toaster/bldcontrol/localhostbecontroller.py | 8 ++-- lib/toaster/toastergui/templates/newproject.html | 53 +++++++++++----------- lib/toaster/toastergui/views.py | 22 ++++++--- .../toastermain/management/commands/buildimport.py | 7 +-- 4 files changed, 48 insertions(+), 42 deletions(-)
lib/toaster/bldcontrol/localhostbecontroller.py +4 -4
@@ -373,8 +373,8 @@ class LocalhostBEController(BuildEnvironmentController): conf.write('INHERIT+="toaster buildhistory"') else: # Append the Toaster-specific values directly to the bblayers.conf - bblconfpath = os.path.join(bitbake.req.project.builddir, "conf/bblayers.conf") - bblconfpath_save = os.path.join(bitbake.req.project.builddir, "conf/bblayers.conf.save") + bblconfpath = os.path.join(builddir, "conf/bblayers.conf") + bblconfpath_save = os.path.join(builddir, "conf/bblayers.conf.save") shutil.copyfile(bblconfpath, bblconfpath_save) with open(bblconfpath) as bblayers: content = bblayers.readlines()
@@ -399,8 +399,8 @@ class LocalhostBEController(BuildEnvironmentController): bblayers.write(' "\n') bblayers.write('#=== TOASTER_CONFIG_EPILOG ===\n') # Append the Toaster-specific values directly to the local.conf - bbconfpath = os.path.join(bitbake.req.project.builddir, "conf/local.conf") - bbconfpath_save = os.path.join(bitbake.req.project.builddir, "conf/local.conf.save") + bbconfpath = os.path.join(builddir, "conf/local.conf") + bbconfpath_save = os.path.join(builddir, "conf/local.conf.save") shutil.copyfile(bbconfpath, bbconfpath_save) with open(bbconfpath) as f: content = f.readlines()
lib/toaster/toastergui/templates/newproject.html +26 -27
103 lines not on this page · raw message
lib/toaster/toastergui/views.py +16 -6
@@ -1398,7 +1398,9 @@ if True: mandatory_fields = ['projectname', 'ptype'] try: ptype = request.POST.get('ptype') - if ptype == "build": + if ptype == "import": + mandatory_fields.append('importdir') + else: mandatory_fields.append('projectversion') # make sure we have values for all mandatory_fields missing = [field for field in mandatory_fields if len(request.POST.get(field, '')) == 0]
@@ -1415,14 +1417,22 @@ if True: login(request, user) # save the project - if ptype == "analysis": - release = None + if ptype == "import": + if not os.path.isdir('%s/conf' % request.POST['importdir']): + raise BadParameterException("Bad path or missing 'conf' directory (%s)" % request.POST['importdir']) + from django.core import management + management.call_command('buildimport', '--command=import', '--name=%s' % request.POST['projectname'], '--path=%s' % request.POST['importdir'], interactive=False) + prj = Project.objects.get(name = request.POST['projectname']) + prj.merged_attr = True + prj.save() else: release = Release.objects.get(pk = request.POST.get('projectversion', None )) + prj = Project.objects.create_project(name = request.POST['projectname'], release = release) + prj.user_id = request.user.pk + if 'mergeattr' == request.POST.get('mergeattr', ''): + prj.merged_attr = True + prj.save() - prj = Project.objects.create_project(name = request.POST['projectname'], release = release) - prj.user_id = request.user.pk - prj.save() return redirect(reverse(project, args=(prj.pk,)) + "?notify=new-project") except (IntegrityError, BadParameterException) as e:
lib/toaster/toastermain/management/commands/buildimport.py +2 -5
@@ -484,11 +484,8 @@ class Command(BaseCommand): def handle(self, *args, **options): project_name = options['name'] project_path = options['path'] - project_callback = options['callback'] - if options['release']: - release_name = options['release'] - else: - release_name = '' + project_callback = options['callback'] if options['callback'] else '' + release_name = options['release'] if options['release'] else '' # # Delete project
Signature · 1 line
1.9.1