bitbake: toaster: move CustomImageRecipe generation to API entry point

Use the CustomImageRecipe generate_recipe_file_contents to generate the
recipe that we build from. Move creation of the dummy layer and recipe
object to the point of recipe creation as we need these objects before
the build time. Also update the methods to add and remove packages to
account for the CustomImageRecipe inheriting from Recipe.

(Bitbake rev: f3322567378d6038a00da0fab6c5641a1a8e5409)

Signed-off-by: Michael Wood <michael.g.wood@intel.com>
Signed-off-by: brian avery <avery.brian@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Michael Wood
2015-11-04 15:02:28 +00:00
committed by Richard Purdie
parent c402ac2654
commit 2cf55afb97
2 changed files with 90 additions and 29 deletions

View File

@@ -240,23 +240,22 @@ class LocalhostBEController(BuildEnvironmentController):
conf.write('BBPATH .= ":${LAYERDIR}"\nBBFILES += "${LAYERDIR}/recipes/*.bb"\n')
# create recipe
recipe = os.path.join(layerpath, "recipes", "%s.bb" % target.target)
with open(recipe, "w") as recipef:
recipef.write("require %s\n" % customrecipe.base_recipe.file_path)
packages = [pkg.name for pkg in customrecipe.packages.all()]
if packages:
recipef.write('IMAGE_INSTALL = "%s"\n' % ' '.join(packages))
recipe_path = \
os.path.join(layerpath, "recipes", "%s.bb" % target.target)
with open(recipe_path, "w") as recipef:
recipef.write(customrecipe.generate_recipe_file_contents())
# Update the layer and recipe objects
customrecipe.layer_version.dirpath = layerpath
customrecipe.layer_version.save()
customrecipe.file_path = recipe_path
customrecipe.save()
# create *Layer* objects needed for build machinery to work
layer = Layer.objects.get_or_create(name="Toaster Custom layer",
summary="Layer for custom recipes",
vcs_url="file://%s" % layerpath)[0]
breq = target.req
lver = Layer_Version.objects.get_or_create(project=breq.project, layer=layer,
dirpath=layerpath, build=breq.build)[0]
ProjectLayer.objects.get_or_create(project=breq.project, layercommit=lver,
optional=False)
BRLayer.objects.get_or_create(req=breq, name=layer.name, dirpath=layerpath,
BRLayer.objects.get_or_create(req=target.req,
name=layer.name,
dirpath=layerpath,
giturl="file://%s" % layerpath)
if os.path.isdir(layerpath):
layerlist.append(layerpath)

View File

@@ -2362,10 +2362,37 @@ if True:
# create custom recipe
try:
# create layer 'Custom layer' and verion if needed
layer = Layer.objects.get_or_create(name="toaster-custom-images",
summary="Layer for custom recipes",
vcs_url="file:///toaster_created_layer"
)[0]
lver = Layer_Version.objects.get_or_create(
project=params['project'],
layer=layer,
dirpath='toaster_created_layer',
build=None)[0]
# Add a dependency on our layer to the base recipe's layer
LayerVersionDependency.objects.get_or_create(layer_version=lver,
depends_on=params["base"].layer_version)
# Add it to our current project if needed
ProjectLayer.objects.get_or_create(project=params['project'],
layercommit=lver,
optional=False)
# Create the actual recipe
recipe = CustomImageRecipe.objects.create(
name=request.POST["name"],
base_recipe=params["base"],
project=params["project"])
project=params["project"],
file_path=request.POST["name"],
license="MIT",
version="0.1",
layer_version=lver)
except Error as err:
return {"error": "Can't create custom recipe: %s" % err}
@@ -2378,20 +2405,24 @@ if True:
# We don't want these packages to be linked to anything because
# that underlying data may change e.g. delete a build
for package in build.package_set.all():
# Create the duplicate
package.pk = None
package.save()
# Disassociate the package from the build
package.build = None
package.save()
recipe.packages.add(package)
_copy_packge_to_recipe(recipe, package)
else:
logger.warn("No packages found for this base recipe")
logger.debug("No packages found for this base recipe")
return {"error": "ok",
"url": reverse('customrecipe', args=(params['project'].pk,
recipe.id))}
def _copy_packge_to_recipe(recipe, package):
""" copy a package from another recipe """
package.pk = None
package.save()
# Disassociate the package from the build
package.build = None
package.recipe = recipe
package.save()
return package
@xhr_response
def xhr_customrecipe_id(request, recipe_id):
"""
@@ -2454,8 +2485,12 @@ if True:
"not found" % recipe_id}
if request.method == 'GET' and not package_id:
packages = recipe.package_set.values("id", "name", "version")
return {"error": "ok",
"packages": list(recipe.packages.values_list('id'))}
"packages" : list(packages),
"total" : len(packages)
}
try:
package = Package.objects.get(id=package_id)
@@ -2464,11 +2499,38 @@ if True:
"not found" % package_id}
if request.method == 'PUT':
recipe.packages.add(package)
return {"error": "ok"}
# As these requests are asynchronous we need to make sure we don't
# already have the package in the image recipe
if recipe.package_set.filter(Q(name=package.name) &
Q(version=package.version)).count() > 0:
return {"error" : "Package %s already in recipe" %
package.name }
# Make a copy of this package
dependencies = _get_package_dependencies(package.pk)
package = _copy_packge_to_recipe(recipe, package)
recipe.package_set.add(package)
# Filter out dependencies already in the custom image
all_in_image = recipe.package_set.all().values_list('name',
flat=True)
def in_image(pkg):
return pkg['name'] not in all_in_image
dependencies = filter(in_image, dependencies['runtime_deps'])
return {"error": "ok",
"new_package" : {"id": package.pk,
"url": reverse('xhr_customrecipe_packages',
args=(recipe.pk, package.pk))
},
"dependencies_needed" : dependencies,
}
elif request.method == 'DELETE':
if package in recipe.packages.all():
recipe.packages.remove(package)
if package in recipe.package_set.all():
# note that we are infact deleting the copy of the package
package.delete()
return {"error": "ok"}
else:
return {"error": "Package '%s' is not in the recipe '%s'" % \