bitbake: toaster: buildinfohelper Add the concept of CustomImagePackage

This adds the concept of CustomImagePackage this is similar to the way
layers and recipes work in that we have a set of data which is part of
the build history and a set of data which is part of the configuration
data that toaster uses to guide people in configuring their project. We
create a set of  built_packages for every build but only create a package
for configuration purposes if we don't already have one, so that the
CustomImagePackage only ever contains a unique list of packages that are
available to be added and removed from a CustomImageRecipe.

(Bitbake rev: f81bb65883baa6c0f8a4d48a4de3291a10543992)

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-12-07 18:26:47 +00:00 committed by Richard Purdie
parent e1bfe1ceb6
commit a6e4f94b01
1 changed files with 89 additions and 16 deletions

View File

@ -42,8 +42,8 @@ from orm.models import Variable, VariableHistory
from orm.models import Package, Package_File, Target_Installed_Package, Target_File from orm.models import Package, Package_File, Target_Installed_Package, Target_File
from orm.models import Task_Dependency, Package_Dependency from orm.models import Task_Dependency, Package_Dependency
from orm.models import Recipe_Dependency, Provides from orm.models import Recipe_Dependency, Provides
from orm.models import Project, CustomImagePackage
from orm.models import Project
from bldcontrol.models import BuildEnvironment, BuildRequest from bldcontrol.models import BuildEnvironment, BuildRequest
from bb.msg import BBLogFormatter as formatter from bb.msg import BBLogFormatter as formatter
@ -323,6 +323,11 @@ class ORMWrapper(object):
def get_update_layer_version_object(self, build_obj, layer_obj, layer_version_information): def get_update_layer_version_object(self, build_obj, layer_obj, layer_version_information):
if isinstance(layer_obj, Layer_Version): if isinstance(layer_obj, Layer_Version):
# Special case the toaster-custom-images layer which is created
# on the fly so don't update the values which may cause the layer
# to be duplicated on a future get_or_create
if layer_obj.layer.name == "toaster-custom-images":
return layer_obj
# We already found our layer version for this build so just # We already found our layer version for this build so just
# update it with the new build information # update it with the new build information
logger.debug("We found our layer from toaster") logger.debug("We found our layer from toaster")
@ -527,12 +532,14 @@ class ORMWrapper(object):
sym_target = filetarget_obj) sym_target = filetarget_obj)
def save_target_package_information(self, build_obj, target_obj, packagedict, pkgpnmap, recipes): def save_target_package_information(self, build_obj, target_obj, packagedict, pkgpnmap, recipes, built_package=False):
assert isinstance(build_obj, Build) assert isinstance(build_obj, Build)
assert isinstance(target_obj, Target) assert isinstance(target_obj, Target)
errormsg = "" errormsg = ""
for p in packagedict: for p in packagedict:
# Search name swtiches round the installed name vs package name
# by default installed name == package name
searchname = p searchname = p
if p not in pkgpnmap: if p not in pkgpnmap:
logger.warning("Image packages list contains %p, but is" logger.warning("Image packages list contains %p, but is"
@ -543,11 +550,30 @@ class ORMWrapper(object):
if 'OPKGN' in pkgpnmap[p].keys(): if 'OPKGN' in pkgpnmap[p].keys():
searchname = pkgpnmap[p]['OPKGN'] searchname = pkgpnmap[p]['OPKGN']
packagedict[p]['object'], created = Package.objects.get_or_create( build = build_obj, name = searchname ) built_recipe = recipes[pkgpnmap[p]['PN']]
if built_package:
packagedict[p]['object'], created = Package.objects.get_or_create( build = build_obj, name = searchname )
recipe = built_recipe
else:
packagedict[p]['object'], created = \
CustomImagePackage.objects.get_or_create(name=searchname)
try:
recipe = self._cached_get(Recipe,
name=built_recipe.name,
layer_version__build=None,
file_path=built_recipe.file_path,
version=built_recipe.version)
except (Recipe.DoesNotExist,
Recipe.MultipleObjectsReturned) as e:
logger.info("We did not find one recipe for the"
"configuration data package %s %s" % (p, e))
continue
if created or packagedict[p]['object'].size == -1: # save the data anyway we can, not just if it was not created here; bug [YOCTO #6887] if created or packagedict[p]['object'].size == -1: # save the data anyway we can, not just if it was not created here; bug [YOCTO #6887]
# fill in everything we can from the runtime-reverse package data # fill in everything we can from the runtime-reverse package data
try: try:
packagedict[p]['object'].recipe = recipes[pkgpnmap[p]['PN']] packagedict[p]['object'].recipe = recipe
packagedict[p]['object'].version = pkgpnmap[p]['PV'] packagedict[p]['object'].version = pkgpnmap[p]['PV']
packagedict[p]['object'].installed_name = p packagedict[p]['object'].installed_name = p
packagedict[p]['object'].revision = pkgpnmap[p]['PR'] packagedict[p]['object'].revision = pkgpnmap[p]['PR']
@ -573,7 +599,8 @@ class ORMWrapper(object):
packagedict[p]['object'].installed_size = packagedict[p]['size'] packagedict[p]['object'].installed_size = packagedict[p]['size']
packagedict[p]['object'].save() packagedict[p]['object'].save()
Target_Installed_Package.objects.create(target = target_obj, package = packagedict[p]['object']) if built_package:
Target_Installed_Package.objects.create(target = target_obj, package = packagedict[p]['object'])
packagedeps_objs = [] packagedeps_objs = []
for p in packagedict: for p in packagedict:
@ -584,6 +611,21 @@ class ORMWrapper(object):
tdeptype = Package_Dependency.TYPE_TRECOMMENDS tdeptype = Package_Dependency.TYPE_TRECOMMENDS
try: try:
# If this is a built package we are always going to have
# new package objects as it's part of the build history
# which also means new package dependency for each object.
# However if they are project packages we don't want to
# duplicate these so check if they exist or not first
if built_package == False:
try:
Package_Dependency.objects.get(
package=packagedict[p]['object'],
depends_on=packagedict[px]['object'],
dep_type=tdeptype)
continue
except Package_Dependency.DoesNotExist:
pass
packagedeps_objs.append(Package_Dependency( packagedeps_objs.append(Package_Dependency(
package = packagedict[p]['object'], package = packagedict[p]['object'],
depends_on = packagedict[px]['object'], depends_on = packagedict[px]['object'],
@ -634,19 +676,37 @@ class ORMWrapper(object):
return log_object.save() return log_object.save()
def save_build_package_information(self, build_obj, package_info, recipes): def save_build_package_information(self, build_obj, package_info, recipes,
assert isinstance(build_obj, Build) built_package):
# assert isinstance(build_obj, Build)
# create and save the object # create and save the object
pname = package_info['PKG'] pname = package_info['PKG']
built_recipe = recipes[package_info['PN']]
if 'OPKGN' in package_info.keys(): if 'OPKGN' in package_info.keys():
pname = package_info['OPKGN'] pname = package_info['OPKGN']
bp_object, _ = Package.objects.get_or_create( build = build_obj, if built_package:
name = pname ) bp_object, _ = Package.objects.get_or_create( build = build_obj,
name = pname )
recipe = built_recipe
else:
bp_object, created = \
CustomImagePackage.objects.get_or_create(name=pname)
try:
recipe = self._cached_get(Recipe,
name=built_recipe.name,
layer_version__build=None,
file_path=built_recipe.file_path,
version=built_recipe.version)
except (Recipe.DoesNotExist, Recipe.MultipleObjectsReturned):
logger.debug("We did not find one recipe for the configuration"
"data package %s" % pname)
return
bp_object.installed_name = package_info['PKG'] bp_object.installed_name = package_info['PKG']
bp_object.recipe = recipes[package_info['PN']] bp_object.recipe = recipe
bp_object.version = package_info['PKGV'] bp_object.version = package_info['PKGV']
bp_object.revision = package_info['PKGR'] bp_object.revision = package_info['PKGR']
bp_object.summary = package_info['SUMMARY'] bp_object.summary = package_info['SUMMARY']
@ -666,7 +726,12 @@ class ORMWrapper(object):
Package_File.objects.bulk_create(packagefile_objects) Package_File.objects.bulk_create(packagefile_objects)
def _po_byname(p): def _po_byname(p):
pkg, created = Package.objects.get_or_create(build = build_obj, name = p) if built_package:
pkg, created = Package.objects.get_or_create(build=build_obj,
name=p)
else:
pkg, created = CustomImagePackage.objects.get_or_create(name=p)
if created: if created:
pkg.size = -1 pkg.size = -1
pkg.save() pkg.save()
@ -1167,7 +1232,8 @@ class BuildInfoHelper(object):
filedata = BuildInfoHelper._get_data_from_event(event)['filedata'][target.target] filedata = BuildInfoHelper._get_data_from_event(event)['filedata'][target.target]
try: try:
self.orm_wrapper.save_target_package_information(self.internal_state['build'], target, imgdata, pkgdata, self.internal_state['recipes']) self.orm_wrapper.save_target_package_information(self.internal_state['build'], target, imgdata, pkgdata, self.internal_state['recipes'], built_package=True)
self.orm_wrapper.save_target_package_information(self.internal_state['build'], target, imgdata.copy(), pkgdata, self.internal_state['recipes'], built_package=False)
except KeyError as e: except KeyError as e:
logger.warn("KeyError in save_target_package_information" logger.warn("KeyError in save_target_package_information"
"%s ", e) "%s ", e)
@ -1324,10 +1390,17 @@ class BuildInfoHelper(object):
def store_build_package_information(self, event): def store_build_package_information(self, event):
package_info = BuildInfoHelper._get_data_from_event(event) package_info = BuildInfoHelper._get_data_from_event(event)
self.orm_wrapper.save_build_package_information(self.internal_state['build'], self.orm_wrapper.save_build_package_information(
package_info, self.internal_state['build'],
self.internal_state['recipes'], package_info,
) self.internal_state['recipes'],
built_package=True)
self.orm_wrapper.save_build_package_information(
self.internal_state['build'],
package_info,
self.internal_state['recipes'],
built_package=False)
def _store_build_done(self, errorcode): def _store_build_done(self, errorcode):
logger.info("Build exited with errorcode %d", errorcode) logger.info("Build exited with errorcode %d", errorcode)