From bcd68fd7231f166baff875fb88e4f9ce0d9bf91d Mon Sep 17 00:00:00 2001 From: David Reyna Date: Sun, 20 Aug 2017 18:01:48 -0700 Subject: toaster: custom image updates and original creation When Toaster removes a package from a custom image, it must also always remove the advised reverse-dependent recipes. Similarly, when adding a package it must always add its advised the packages it depends on. This code must be un-indented so that it applies to all respective added or removed packages. Toaster normally waits until a new custom image is built before creating the custom layer and the recipe. However, an intermediate different build can fail because the recipe has already been added to the project, so the image's default recipe must be created when the image is created. [YOCTO #11915] Signed-off-by: David Reyna Signed-off-by: Richard Purdie --- lib/toaster/orm/models.py | 2 +- lib/toaster/toastergui/api.py | 98 +++++++++++++++++++++++++++---------------- 2 files changed, 62 insertions(+), 38 deletions(-) diff --git a/lib/toaster/orm/models.py b/lib/toaster/orm/models.py index 7aaebedc2..3a7dff8ca 100644 --- a/lib/toaster/orm/models.py +++ b/lib/toaster/orm/models.py @@ -1658,7 +1658,7 @@ class CustomImageRecipe(Recipe): def get_base_recipe_file(self): """Get the base recipe file path if it exists on the file system""" - path_schema_one = "%s/%s" % (self.base_recipe.layer_version.dirpath, + path_schema_one = "%s/%s" % (self.base_recipe.layer_version.local_path, self.base_recipe.file_path) path_schema_two = self.base_recipe.file_path diff --git a/lib/toaster/toastergui/api.py b/lib/toaster/toastergui/api.py index 88d6aa7f6..cb8f0f312 100644 --- a/lib/toaster/toastergui/api.py +++ b/lib/toaster/toastergui/api.py @@ -18,6 +18,7 @@ # Please run flake8 on this file before sending patches +import os import re import logging import json @@ -28,7 +29,7 @@ from orm.models import LayerVersionDependency, LayerSource, ProjectLayer from orm.models import Recipe, CustomImageRecipe, CustomImagePackage from orm.models import Layer, Target, Package, Package_Dependency from orm.models import ProjectVariable -from bldcontrol.models import BuildRequest +from bldcontrol.models import BuildRequest, BuildEnvironment from bldcontrol import bbcontroller from django.http import HttpResponse, JsonResponse @@ -509,6 +510,27 @@ class XhrCustomRecipe(View): (tpackage.package.name, e)) pass + # pre-create layer directory structure, so that other builds + # are not blocked by this new recipe dependecy + # NOTE: this is parallel code to 'localhostbecontroller.py' + be = BuildEnvironment.objects.all()[0] + layerpath = os.path.join(be.builddir, + CustomImageRecipe.LAYER_NAME) + for name in ("conf", "recipes"): + path = os.path.join(layerpath, name) + if not os.path.isdir(path): + os.makedirs(path) + # pre-create layer.conf + config = os.path.join(layerpath, "conf", "layer.conf") + if not os.path.isfile(config): + with open(config, "w") as conf: + conf.write('BBPATH .= ":${LAYERDIR}"\nBBFILES += "${LAYERDIR}/recipes/*.bb"\n') + # pre-create new image's recipe file + recipe_path = os.path.join(layerpath, "recipes", "%s.bb" % + recipe.name) + with open(recipe_path, "w") as recipef: + recipef.write(recipe.generate_recipe_file_contents()) + return JsonResponse( {"error": "ok", "packages": recipe.get_all_packages().count(), @@ -752,7 +774,6 @@ class XhrCustomRecipePackages(View): return error_response("Package %s not found in excludes" " but was in included list" % package.name) - else: recipe.appends_set.add(package) # Make sure that package is not in the excludes set @@ -760,26 +781,27 @@ class XhrCustomRecipePackages(View): recipe.excludes_set.remove(package) except: pass - # Add the dependencies we think will be added to the recipe - # as a result of appending this package. - # TODO this should recurse down the entire deps tree - for dep in package.package_dependencies_source.all_depends(): + + # Add the dependencies we think will be added to the recipe + # as a result of appending this package. + # TODO this should recurse down the entire deps tree + for dep in package.package_dependencies_source.all_depends(): + try: + cust_package = CustomImagePackage.objects.get( + name=dep.depends_on.name) + + recipe.includes_set.add(cust_package) try: - cust_package = CustomImagePackage.objects.get( - name=dep.depends_on.name) - - recipe.includes_set.add(cust_package) - try: - # When adding the pre-requisite package, make - # sure it's not in the excluded list from a - # prior removal. - recipe.excludes_set.remove(cust_package) - except package.DoesNotExist: - # Don't care if the package had never been excluded - pass - except: - logger.warning("Could not add package's suggested" - "dependencies to the list") + # When adding the pre-requisite package, make + # sure it's not in the excluded list from a + # prior removal. + recipe.excludes_set.remove(cust_package) + except package.DoesNotExist: + # Don't care if the package had never been excluded + pass + except: + logger.warning("Could not add package's suggested" + "dependencies to the list") return JsonResponse({"error": "ok"}) def delete(self, request, *args, **kwargs): @@ -797,22 +819,24 @@ class XhrCustomRecipePackages(View): recipe.excludes_set.add(package) else: recipe.appends_set.remove(package) - all_current_packages = recipe.get_all_packages() - - reverse_deps_dictlist = self._get_all_dependents( - package.pk, - all_current_packages) - - ids = [entry['pk'] for entry in reverse_deps_dictlist] - reverse_deps = CustomImagePackage.objects.filter(id__in=ids) - for r in reverse_deps: - try: - if r.id in included_packages: - recipe.excludes_set.add(r) - else: - recipe.appends_set.remove(r) - except: - pass + + # remove dependencies as well + all_current_packages = recipe.get_all_packages() + + reverse_deps_dictlist = self._get_all_dependents( + package.pk, + all_current_packages) + + ids = [entry['pk'] for entry in reverse_deps_dictlist] + reverse_deps = CustomImagePackage.objects.filter(id__in=ids) + for r in reverse_deps: + try: + if r.id in included_packages: + recipe.excludes_set.add(r) + else: + recipe.appends_set.remove(r) + except: + pass return JsonResponse({"error": "ok"}) except CustomImageRecipe.DoesNotExist: -- cgit 1.2.3-korg