summaryrefslogtreecommitdiff
path: root/import-layers/yocto-poky/bitbake/lib/toaster/orm/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'import-layers/yocto-poky/bitbake/lib/toaster/orm/models.py')
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/orm/models.py126
1 files changed, 81 insertions, 45 deletions
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/orm/models.py b/import-layers/yocto-poky/bitbake/lib/toaster/orm/models.py
index a7de57c25..a49f9a432 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/orm/models.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/orm/models.py
@@ -38,6 +38,7 @@ import re
import itertools
from signal import SIGUSR1
+
import logging
logger = logging.getLogger("toaster")
@@ -178,24 +179,27 @@ class ProjectManager(models.Manager):
else:
return projects[0]
+
class Project(models.Model):
- search_allowed_fields = ['name', 'short_description', 'release__name', 'release__branch_name']
+ search_allowed_fields = ['name', 'short_description', 'release__name',
+ 'release__branch_name']
name = models.CharField(max_length=100)
short_description = models.CharField(max_length=50, blank=True)
bitbake_version = models.ForeignKey('BitbakeVersion', null=True)
- release = models.ForeignKey("Release", null=True)
- created = models.DateTimeField(auto_now_add = True)
- updated = models.DateTimeField(auto_now = True)
+ release = models.ForeignKey("Release", null=True)
+ created = models.DateTimeField(auto_now_add=True)
+ updated = models.DateTimeField(auto_now=True)
# This is a horrible hack; since Toaster has no "User" model available when
# running in interactive mode, we can't reference the field here directly
- # Instead, we keep a possible null reference to the User id, as not to force
+ # Instead, we keep a possible null reference to the User id,
+ # as not to force
# hard links to possibly missing models
- user_id = models.IntegerField(null = True)
- objects = ProjectManager()
+ user_id = models.IntegerField(null=True)
+ objects = ProjectManager()
# set to True for the project which is the default container
# for builds initiated by the command line etc.
- is_default = models.BooleanField(default = False)
+ is_default= models.BooleanField(default=False)
def __unicode__(self):
return "%s (Release %s, BBV %s)" % (self.name, self.release, self.bitbake_version)
@@ -221,16 +225,16 @@ class Project(models.Model):
return( -1 )
def get_last_outcome(self):
- build_id = self.get_last_build_id
+ build_id = self.get_last_build_id()
if (-1 == build_id):
return( "" )
try:
- return Build.objects.filter( id = self.get_last_build_id )[ 0 ].outcome
+ return Build.objects.filter( id = build_id )[ 0 ].outcome
except (Build.DoesNotExist,IndexError):
return( "not_found" )
def get_last_target(self):
- build_id = self.get_last_build_id
+ build_id = self.get_last_build_id()
if (-1 == build_id):
return( "" )
try:
@@ -239,7 +243,7 @@ class Project(models.Model):
return( "not_found" )
def get_last_errors(self):
- build_id = self.get_last_build_id
+ build_id = self.get_last_build_id()
if (-1 == build_id):
return( 0 )
try:
@@ -248,7 +252,7 @@ class Project(models.Model):
return( "not_found" )
def get_last_warnings(self):
- build_id = self.get_last_build_id
+ build_id = self.get_last_build_id()
if (-1 == build_id):
return( 0 )
try:
@@ -265,7 +269,7 @@ class Project(models.Model):
return last_build.get_image_file_extensions()
def get_last_imgfiles(self):
- build_id = self.get_last_build_id
+ build_id = self.get_last_build_id()
if (-1 == build_id):
return( "" )
try:
@@ -333,20 +337,45 @@ class Project(models.Model):
return queryset
-
def schedule_build(self):
- from bldcontrol.models import BuildRequest, BRTarget, BRLayer, BRVariable, BRBitbake
- br = BuildRequest.objects.create(project = self)
+
+ from bldcontrol.models import BuildRequest, BRTarget, BRLayer
+ from bldcontrol.models import BRBitbake, BRVariable
+
try:
+ now = timezone.now()
+ build = Build.objects.create(project=self,
+ completed_on=now,
+ started_on=now)
+
+ br = BuildRequest.objects.create(project=self,
+ state=BuildRequest.REQ_QUEUED,
+ build=build)
+ BRBitbake.objects.create(req=br,
+ giturl=self.bitbake_version.giturl,
+ commit=self.bitbake_version.branch,
+ dirpath=self.bitbake_version.dirpath)
- BRBitbake.objects.create(req = br,
- giturl = self.bitbake_version.giturl,
- commit = self.bitbake_version.branch,
- dirpath = self.bitbake_version.dirpath)
+ for t in self.projecttarget_set.all():
+ BRTarget.objects.create(req=br, target=t.target, task=t.task)
+ Target.objects.create(build=br.build, target=t.target,
+ task=t.task)
+ # If we're about to build a custom image recipe make sure
+ # that layer is currently in the project before we create the
+ # BRLayer objects
+ customrecipe = CustomImageRecipe.objects.filter(
+ name=t.target,
+ project=self).first()
+ if customrecipe:
+ ProjectLayer.objects.get_or_create(
+ project=self,
+ layercommit=customrecipe.layer_version,
+ optional=False)
for l in self.projectlayer_set.all().order_by("pk"):
commit = l.layercommit.get_vcs_reference()
- print("ii Building layer ", l.layercommit.layer.name, " at vcs point ", commit)
+ logger.debug("Adding layer to build %s" %
+ l.layercommit.layer.name)
BRLayer.objects.create(
req=br,
name=l.layercommit.layer.name,
@@ -357,25 +386,16 @@ class Project(models.Model):
local_source_dir=l.layercommit.layer.local_source_dir
)
- br.state = BuildRequest.REQ_QUEUED
- now = timezone.now()
- br.build = Build.objects.create(project = self,
- completed_on=now,
- started_on=now,
- )
- for t in self.projecttarget_set.all():
- BRTarget.objects.create(req = br, target = t.target, task = t.task)
- Target.objects.create(build = br.build, target = t.target, task = t.task)
-
for v in self.projectvariable_set.all():
- BRVariable.objects.create(req = br, name = v.name, value = v.value)
-
+ BRVariable.objects.create(req=br, name=v.name, value=v.value)
try:
- br.build.machine = self.projectvariable_set.get(name = 'MACHINE').value
+ br.build.machine = self.projectvariable_set.get(
+ name='MACHINE').value
br.build.save()
except ProjectVariable.DoesNotExist:
pass
+
br.save()
signal_runbuilds()
@@ -882,7 +902,7 @@ class Target_Image_File(models.Model):
'ext4.gz', 'ext3', 'ext3.gz', 'hdddirect', 'hddimg', 'iso', 'jffs2',
'jffs2.sum', 'multiubi', 'qcow2', 'squashfs', 'squashfs-lzo',
'squashfs-xz', 'tar', 'tar.bz2', 'tar.gz', 'tar.lz4', 'tar.xz', 'ubi',
- 'ubifs', 'vdi', 'vmdk', 'wic', 'wic.bz2', 'wic.gz', 'wic.lzma'
+ 'ubifs', 'vdi', 'vmdk', 'wic', 'wic.bmap', 'wic.bz2', 'wic.gz', 'wic.lzma'
}
target = models.ForeignKey(Target)
@@ -1365,7 +1385,7 @@ class Layer(models.Model):
name = models.CharField(max_length=100)
layer_index_url = models.URLField()
vcs_url = GitURLField(default=None, null=True)
- local_source_dir = models.TextField(null = True, default = None)
+ local_source_dir = models.TextField(null=True, default=None)
vcs_web_url = models.URLField(null=True, default=None)
vcs_web_tree_base_url = models.URLField(null=True, default=None)
vcs_web_file_base_url = models.URLField(null=True, default=None)
@@ -1473,22 +1493,33 @@ class Layer_Version(models.Model):
return self.commit
return 'N/A'
- def get_detailspage_url(self, project_id):
+ def get_detailspage_url(self, project_id=None):
+ """ returns the url to the layer details page uses own project
+ field if project_id is not specified """
+
+ if project_id is None:
+ project_id = self.project.pk
+
return reverse('layerdetails', args=(project_id, self.pk))
def get_alldeps(self, project_id):
"""Get full list of unique layer dependencies."""
- def gen_layerdeps(lver, project):
+ def gen_layerdeps(lver, project, depth):
+ if depth == 0:
+ return
for ldep in lver.dependencies.all():
yield ldep.depends_on
# get next level of deps recursively calling gen_layerdeps
- for subdep in gen_layerdeps(ldep.depends_on, project):
+ for subdep in gen_layerdeps(ldep.depends_on, project, depth-1):
yield subdep
project = Project.objects.get(pk=project_id)
result = []
- projectlvers = [player.layercommit for player in project.projectlayer_set.all()]
- for dep in gen_layerdeps(self, project):
+ projectlvers = [player.layercommit for player in
+ project.projectlayer_set.all()]
+ # protect against infinite layer dependency loops
+ maxdepth = 20
+ for dep in gen_layerdeps(self, project, maxdepth):
# filter out duplicates and layers already belonging to the project
if dep not in result + projectlvers:
result.append(dep)
@@ -1631,7 +1662,8 @@ class CustomImageRecipe(Recipe):
if base_recipe_path:
base_recipe = open(base_recipe_path, 'r').read()
else:
- raise IOError("Based on recipe file not found")
+ raise IOError("Based on recipe file not found: %s" %
+ base_recipe_path)
# Add a special case for when the recipe we have based a custom image
# recipe on requires another recipe.
@@ -1741,8 +1773,12 @@ def invalidate_cache(**kwargs):
def signal_runbuilds():
"""Send SIGUSR1 to runbuilds process"""
- with open(os.path.join(os.getenv('BUILDDIR'), '.runbuilds.pid')) as pidf:
- os.kill(int(pidf.read()), SIGUSR1)
+ try:
+ with open(os.path.join(os.getenv('BUILDDIR', '.'),
+ '.runbuilds.pid')) as pidf:
+ os.kill(int(pidf.read()), SIGUSR1)
+ except FileNotFoundError:
+ logger.info("Stopping existing runbuilds: no current process found")
django.db.models.signals.post_save.connect(invalidate_cache)
django.db.models.signals.post_delete.connect(invalidate_cache)