summaryrefslogtreecommitdiff
path: root/yocto-poky/bitbake/lib/toaster/orm/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'yocto-poky/bitbake/lib/toaster/orm/models.py')
-rw-r--r--yocto-poky/bitbake/lib/toaster/orm/models.py155
1 files changed, 118 insertions, 37 deletions
diff --git a/yocto-poky/bitbake/lib/toaster/orm/models.py b/yocto-poky/bitbake/lib/toaster/orm/models.py
index e4d2e87ae..383290583 100644
--- a/yocto-poky/bitbake/lib/toaster/orm/models.py
+++ b/yocto-poky/bitbake/lib/toaster/orm/models.py
@@ -191,10 +191,11 @@ class Project(models.Model):
# returns a queryset of compatible layers for a project
def compatible_layerversions(self, release = None, layer_name = None):
+ logger.warning("This function is deprecated")
if release == None:
release = self.release
# layers on the same branch or layers specifically set for this project
- queryset = Layer_Version.objects.filter((Q(up_branch__name = release.branch_name) & Q(project = None)) | Q(project = self) | Q(build__project = self))
+ queryset = Layer_Version.objects.filter(((Q(up_branch__name = release.branch_name) & Q(project = None)) | Q(project = self)) & Q(build__isnull=True))
if layer_name is not None:
# we select only a layer name
@@ -205,45 +206,55 @@ class Project(models.Model):
return queryset
- def projectlayer_equivalent_set(self):
- return self.compatible_layerversions().filter(layer__name__in = [x.layercommit.layer.name for x in self.projectlayer_set.all()]).select_related("up_branch")
+ def get_all_compatible_layer_versions(self):
+ """ Returns Queryset of all Layer_Versions which are compatible with
+ this project"""
+ queryset = Layer_Version.objects.filter(
+ (Q(up_branch__name=self.release.branch_name) & Q(build=None))
+ | Q(project=self))
+
+ return queryset
+
+ def get_project_layer_versions(self, pk=False):
+ """ Returns the Layer_Versions currently added to this project """
+ layer_versions = self.projectlayer_set.all().values('layercommit')
+
+ if pk is False:
+ return layer_versions
+ else:
+ return layer_versions.values_list('layercommit__pk', flat=True)
+
def get_available_machines(self):
""" Returns QuerySet of all Machines which are provided by the
Layers currently added to the Project """
- queryset = Machine.objects.filter(layer_version__in=self.projectlayer_equivalent_set)
+ queryset = Machine.objects.filter(
+ layer_version__in=self.get_project_layer_versions())
+
return queryset
def get_all_compatible_machines(self):
""" Returns QuerySet of all the compatible machines available to the
project including ones from Layers not currently added """
- compatible_layers = self.compatible_layerversions()
+ queryset = Machine.objects.filter(
+ layer_version__in=self.get_all_compatible_layer_versions())
- queryset = Machine.objects.filter(layer_version__in=compatible_layers)
return queryset
def get_available_recipes(self):
- """ Returns QuerySet of all Recipes which are provided by the Layers
- currently added to the Project """
- project_layers = self.projectlayer_equivalent_set()
- queryset = Recipe.objects.filter(layer_version__in = project_layers)
-
- # Copied from get_all_compatible_recipes
- search_maxids = map(lambda i: i[0], list(queryset.values('name').distinct().annotate(max_id=Max('id')).values_list('max_id')))
- queryset = queryset.filter(id__in=search_maxids).select_related('layer_version', 'layer_version__layer', 'layer_version__up_branch', 'layer_source')
- # End copy
+ """ Returns QuerySet of all the recipes that are provided by layers
+ added to this project """
+ queryset = Recipe.objects.filter(
+ layer_version__in=self.get_project_layer_versions())
return queryset
def get_all_compatible_recipes(self):
""" Returns QuerySet of all the compatible Recipes available to the
project including ones from Layers not currently added """
- compatible_layerversions = self.compatible_layerversions()
- queryset = Recipe.objects.filter(layer_version__in = compatible_layerversions)
+ queryset = Recipe.objects.filter(
+ layer_version__in=self.get_all_compatible_layer_versions()).exclude(name__exact='')
- search_maxids = map(lambda i: i[0], list(queryset.values('name').distinct().annotate(max_id=Max('id')).values_list('max_id')))
-
- queryset = queryset.filter(id__in=search_maxids).select_related('layer_version', 'layer_version__layer', 'layer_version__up_branch', 'layer_source')
return queryset
@@ -260,7 +271,7 @@ class Project(models.Model):
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)
- BRLayer.objects.create(req = br, name = l.layercommit.layer.name, giturl = l.layercommit.layer.vcs_url, commit = commit, dirpath = l.layercommit.dirpath)
+ BRLayer.objects.create(req = br, name = l.layercommit.layer.name, giturl = l.layercommit.layer.vcs_url, commit = commit, dirpath = l.layercommit.dirpath, layer_version=l.layercommit)
br.state = BuildRequest.REQ_QUEUED
now = timezone.now()
@@ -270,7 +281,7 @@ class Project(models.Model):
)
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)
+ 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)
@@ -333,13 +344,14 @@ class Build(models.Model):
tgts = Target.objects.filter(build_id = self.id).order_by( 'target' );
return( tgts );
- @property
- def toaster_exceptions(self):
- return self.logmessage_set.filter(level=LogMessage.EXCEPTION)
+ def get_outcome_text(self):
+ return Build.BUILD_OUTCOME[int(self.outcome)][1]
@property
def errors(self):
- return (self.logmessage_set.filter(level=LogMessage.ERROR)|self.logmessage_set.filter(level=LogMessage.EXCEPTION))
+ return (self.logmessage_set.filter(level=LogMessage.ERROR) |
+ self.logmessage_set.filter(level=LogMessage.EXCEPTION) |
+ self.logmessage_set.filter(level=LogMessage.CRITICAL))
@property
def warnings(self):
@@ -350,10 +362,23 @@ class Build(models.Model):
return (self.completed_on - self.started_on).total_seconds()
def get_current_status(self):
+ """
+ get the status string from the build request if the build
+ has one, or the text for the build outcome if it doesn't
+ """
+
from bldcontrol.models import BuildRequest
- if self.outcome == Build.IN_PROGRESS and self.buildrequest.state != BuildRequest.REQ_INPROGRESS:
+
+ build_request = None
+ if hasattr(self, 'buildrequest'):
+ build_request = self.buildrequest
+
+ if (build_request
+ and build_request.state != BuildRequest.REQ_INPROGRESS
+ and self.outcome == Build.IN_PROGRESS):
return self.buildrequest.get_state_display()
- return self.get_outcome_display()
+ else:
+ return self.get_outcome_text()
def __str__(self):
return "%d %s %s" % (self.id, self.project, ",".join([t.target for t in self.target_set.all()]))
@@ -551,7 +576,7 @@ class Task_Dependency(models.Model):
class Package(models.Model):
search_allowed_fields = ['name', 'version', 'revision', 'recipe__name', 'recipe__version', 'recipe__license', 'recipe__layer_version__layer__name', 'recipe__layer_version__branch', 'recipe__layer_version__commit', 'recipe__layer_version__local_path', 'installed_name']
- build = models.ForeignKey('Build')
+ build = models.ForeignKey('Build', null=True)
recipe = models.ForeignKey('Recipe', null=True)
name = models.CharField(max_length=100)
installed_name = models.CharField(max_length=100, default='')
@@ -828,6 +853,7 @@ class LayerIndexLayerSource(LayerSource):
import urllib2, urlparse, json
import os
proxy_settings = os.environ.get("http_proxy", None)
+ oe_core_layer = 'openembedded-core'
def _get_json_response(apiurl = self.apiurl):
_parsedurl = urlparse.urlparse(apiurl)
@@ -872,6 +898,25 @@ class LayerIndexLayerSource(LayerSource):
if not connection.features.autocommits_when_autocommit_is_off:
transaction.set_autocommit(False)
for li in layers_info:
+ # Special case for the openembedded-core layer
+ if li['name'] == oe_core_layer:
+ try:
+ # If we have an existing openembedded-core for example
+ # from the toasterconf.json augment the info using the
+ # layerindex rather than duplicate it
+ oe_core_l = Layer.objects.get(name=oe_core_layer)
+ # Take ownership of the layer as now coming from the
+ # layerindex
+ oe_core_l.layer_source = self
+ oe_core_l.up_id = li['id']
+ oe_core_l.summary = li['summary']
+ oe_core_l.description = li['description']
+ oe_core_l.save()
+ continue
+
+ except Layer.DoesNotExist:
+ pass
+
l, created = Layer.objects.get_or_create(layer_source = self, name = li['name'])
l.up_id = li['id']
l.up_date = li['updated']
@@ -882,6 +927,7 @@ class LayerIndexLayerSource(LayerSource):
l.summary = li['summary']
l.description = li['description']
l.save()
+
if not connection.features.autocommits_when_autocommit_is_off:
transaction.set_autocommit(True)
@@ -974,9 +1020,12 @@ class LayerIndexLayerSource(LayerSource):
ro.file_path = ri['filepath'] + "/" + ri['filename']
if 'inherits' in ri:
ro.is_image = 'image' in ri['inherits'].split()
+ else: # workaround for old style layer index
+ ro.is_image = "-image-" in ri['pn']
ro.save()
except IntegrityError as e:
logger.debug("Failed saving recipe, ignoring: %s (%s:%s)" % (e, ro.layer_version, ri['filepath']+"/"+ri['filename']))
+ ro.delete()
if not connection.features.autocommits_when_autocommit_is_off:
transaction.set_autocommit(True)
@@ -1132,17 +1181,36 @@ class Layer_Version(models.Model):
return project.compatible_layerversions(layer_name = self.layer.name)
def get_vcs_reference(self):
- if self.commit is not None and len(self.commit) > 0:
- return self.commit
if self.branch is not None and len(self.branch) > 0:
return self.branch
if self.up_branch is not None:
return self.up_branch.name
+ if self.commit is not None and len(self.commit) > 0:
+ return self.commit
return ("Cannot determine the vcs_reference for layer version %s" % vars(self))
def get_detailspage_url(self, project_id):
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):
+ 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):
+ 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):
+ # filter out duplicates and layers already belonging to the project
+ if dep not in result + projectlvers:
+ result.append(dep)
+
+ return sorted(result, key=lambda x: x.layer.name)
+
def __unicode__(self):
return "%d %s (VCS %s, Project %s)" % (self.pk, str(self.layer), self.get_vcs_reference(), self.build.project if self.build is not None else "No project")
@@ -1170,6 +1238,15 @@ class ProjectLayer(models.Model):
class Meta:
unique_together = (("project", "layercommit"),)
+class CustomImageRecipe(models.Model):
+ name = models.CharField(max_length=100)
+ base_recipe = models.ForeignKey(Recipe)
+ packages = models.ManyToManyField(Package)
+ project = models.ForeignKey(Project)
+
+ class Meta:
+ unique_together = ("name", "project")
+
class ProjectVariable(models.Model):
project = models.ForeignKey(Project)
name = models.CharField(max_length=100)
@@ -1206,16 +1283,20 @@ class LogMessage(models.Model):
INFO = 0
WARNING = 1
ERROR = 2
-
- LOG_LEVEL = ( (INFO, "info"),
- (WARNING, "warn"),
- (ERROR, "error"),
- (EXCEPTION, "toaster exception"))
+ CRITICAL = 3
+
+ LOG_LEVEL = (
+ (INFO, "info"),
+ (WARNING, "warn"),
+ (ERROR, "error"),
+ (CRITICAL, "critical"),
+ (EXCEPTION, "toaster exception")
+ )
build = models.ForeignKey(Build)
task = models.ForeignKey(Task, blank = True, null=True)
level = models.IntegerField(choices=LOG_LEVEL, default=INFO)
- message=models.CharField(max_length=240)
+ message = models.TextField(blank=True, null=True)
pathname = models.FilePathField(max_length=255, blank=True)
lineno = models.IntegerField(null=True)