summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandru DAMIAN <alexandru.damian@intel.com>2015-05-14 16:10:50 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-05-29 11:59:43 +0100
commite3e85bdf7100cc5619d7f184dc8d9e2a77a03364 (patch)
treea3dcc4abf6973288c0001e7498f8270d6fccdb7e
parenta5236be47fd62d41eaea2d4b4f1a394de0aac4a9 (diff)
downloadpoky-e3e85bdf7100cc5619d7f184dc8d9e2a77a03364.tar.gz
bitbake: toaster logger: refactor recipe and layer file paths
This refactoring brings the "local_path" of the layer from the Layer object to the Layer_Version object, which is more appropriate as different checkouts of the same Layer may live in different directories. This enables us to store Recipe file paths relative to a Layer_Version at all times, aleviating the need to store full file paths in the database. We also turn the prefix of the path (e.g. virtual:native path name space) into a pathflag field. In turn, this solves the problem of mis-identification of tasks based on the recipe file paths, since we can also match the namespace of the file paths on the recipe files. [YOCTO #7594] (Bitbake rev: ec43dc569e370767c709dec225cbee0c99151c19) Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--bitbake/lib/bb/ui/buildinfohelper.py47
-rwxr-xr-xbitbake/lib/toaster/contrib/tts/toasteruitest/toaster_automation_test.py14
-rw-r--r--bitbake/lib/toaster/orm/migrations/0020_auto__add_field_layer_version_local_path__add_field_recipe_pathflags__.py361
-rw-r--r--bitbake/lib/toaster/orm/models.py23
-rw-r--r--bitbake/lib/toaster/toastergui/templates/bpackage.html4
-rw-r--r--bitbake/lib/toaster/toastergui/templates/configuration.html2
-rw-r--r--bitbake/lib/toaster/toastergui/templates/package_detail_base.html2
-rw-r--r--bitbake/lib/toaster/toastergui/templates/recipe.html4
-rw-r--r--bitbake/lib/toaster/toastergui/templates/recipes.html4
-rw-r--r--bitbake/lib/toaster/toastergui/templates/target.html2
-rwxr-xr-xbitbake/lib/toaster/toastergui/views.py22
11 files changed, 427 insertions, 58 deletions
diff --git a/bitbake/lib/bb/ui/buildinfohelper.py b/bitbake/lib/bb/ui/buildinfohelper.py
index 647d663cb5..6812a52b7b 100644
--- a/bitbake/lib/bb/ui/buildinfohelper.py
+++ b/bitbake/lib/bb/ui/buildinfohelper.py
@@ -221,12 +221,12 @@ class ORMWrapper(object):
221 def get_update_recipe_object(self, recipe_information, must_exist = False): 221 def get_update_recipe_object(self, recipe_information, must_exist = False):
222 assert 'layer_version' in recipe_information 222 assert 'layer_version' in recipe_information
223 assert 'file_path' in recipe_information 223 assert 'file_path' in recipe_information
224 assert 'pathflags' in recipe_information
224 225
225 if recipe_information['file_path'].startswith(recipe_information['layer_version'].layer.local_path): 226 assert not recipe_information['file_path'].startswith("/") # we should have layer-relative paths at all times
226 recipe_information['file_path'] = recipe_information['file_path'][len(recipe_information['layer_version'].layer.local_path):].lstrip("/")
227 227
228 recipe_object, created = self._cached_get_or_create(Recipe, layer_version=recipe_information['layer_version'], 228 recipe_object, created = self._cached_get_or_create(Recipe, layer_version=recipe_information['layer_version'],
229 file_path=recipe_information['file_path']) 229 file_path=recipe_information['file_path'], pathflags = recipe_information['pathflags'])
230 if created and must_exist: 230 if created and must_exist:
231 raise NotExisting("Recipe object created when expected to exist", recipe_information) 231 raise NotExisting("Recipe object created when expected to exist", recipe_information)
232 232
@@ -247,13 +247,15 @@ class ORMWrapper(object):
247 assert 'branch' in layer_version_information 247 assert 'branch' in layer_version_information
248 assert 'commit' in layer_version_information 248 assert 'commit' in layer_version_information
249 assert 'priority' in layer_version_information 249 assert 'priority' in layer_version_information
250 assert 'local_path' in layer_version_information
250 251
251 layer_version_object, created = Layer_Version.objects.get_or_create( 252 layer_version_object, created = Layer_Version.objects.get_or_create(
252 build = build_obj, 253 build = build_obj,
253 layer = layer_obj, 254 layer = layer_obj,
254 branch = layer_version_information['branch'], 255 branch = layer_version_information['branch'],
255 commit = layer_version_information['commit'], 256 commit = layer_version_information['commit'],
256 priority = layer_version_information['priority'] 257 priority = layer_version_information['priority'],
258 local_path = layer_version_information['local_path'],
257 ) 259 )
258 260
259 self.layer_version_objects.append(layer_version_object) 261 self.layer_version_objects.append(layer_version_object)
@@ -262,13 +264,11 @@ class ORMWrapper(object):
262 264
263 def get_update_layer_object(self, layer_information, brbe): 265 def get_update_layer_object(self, layer_information, brbe):
264 assert 'name' in layer_information 266 assert 'name' in layer_information
265 assert 'local_path' in layer_information
266 assert 'layer_index_url' in layer_information 267 assert 'layer_index_url' in layer_information
267 268
268 if brbe is None: 269 if brbe is None:
269 layer_object, created = Layer.objects.get_or_create( 270 layer_object, created = Layer.objects.get_or_create(
270 name=layer_information['name'], 271 name=layer_information['name'],
271 local_path=layer_information['local_path'],
272 layer_index_url=layer_information['layer_index_url']) 272 layer_index_url=layer_information['layer_index_url'])
273 return layer_object 273 return layer_object
274 else: 274 else:
@@ -297,7 +297,6 @@ class ORMWrapper(object):
297 for pl in buildrequest.project.projectlayer_set.filter(layercommit__layer__name = brl.name): 297 for pl in buildrequest.project.projectlayer_set.filter(layercommit__layer__name = brl.name):
298 if pl.layercommit.layer.vcs_url == brl.giturl : 298 if pl.layercommit.layer.vcs_url == brl.giturl :
299 layer = pl.layercommit.layer 299 layer = pl.layercommit.layer
300 layer.local_path = layer_information['local_path']
301 layer.save() 300 layer.save()
302 return layer 301 return layer
303 302
@@ -687,12 +686,12 @@ class BuildInfoHelper(object):
687 if self.brbe is None: 686 if self.brbe is None:
688 def _slkey_interactive(layer_version): 687 def _slkey_interactive(layer_version):
689 assert isinstance(layer_version, Layer_Version) 688 assert isinstance(layer_version, Layer_Version)
690 return len(layer_version.layer.local_path) 689 return len(layer_version.local_path)
691 690
692 # Heuristics: we always match recipe to the deepest layer path in the discovered layers 691 # Heuristics: we always match recipe to the deepest layer path in the discovered layers
693 for lvo in sorted(self.orm_wrapper.layer_version_objects, reverse=True, key=_slkey_interactive): 692 for lvo in sorted(self.orm_wrapper.layer_version_objects, reverse=True, key=_slkey_interactive):
694 # we can match to the recipe file path 693 # we can match to the recipe file path
695 if path.startswith(lvo.layer.local_path): 694 if path.startswith(lvo.local_path):
696 return lvo 695 return lvo
697 696
698 else: 697 else:
@@ -721,7 +720,7 @@ class BuildInfoHelper(object):
721 logger.warn("Could not match layer version for recipe path %s : %s" % (path, self.orm_wrapper.layer_version_objects)) 720 logger.warn("Could not match layer version for recipe path %s : %s" % (path, self.orm_wrapper.layer_version_objects))
722 721
723 #mockup the new layer 722 #mockup the new layer
724 unknown_layer, created = Layer.objects.get_or_create(name="__FIXME__unidentified_layer", local_path="/", layer_index_url="") 723 unknown_layer, created = Layer.objects.get_or_create(name="__FIXME__unidentified_layer", layer_index_url="")
725 unknown_layer_version_obj, created = Layer_Version.objects.get_or_create(layer = unknown_layer, build = self.internal_state['build']) 724 unknown_layer_version_obj, created = Layer_Version.objects.get_or_create(layer = unknown_layer, build = self.internal_state['build'])
726 725
727 # append it so we don't run into this error again and again 726 # append it so we don't run into this error again and again
@@ -731,11 +730,20 @@ class BuildInfoHelper(object):
731 730
732 def _get_recipe_information_from_taskfile(self, taskfile): 731 def _get_recipe_information_from_taskfile(self, taskfile):
733 localfilepath = taskfile.split(":")[-1] 732 localfilepath = taskfile.split(":")[-1]
733 filepath_flags = ":".join(sorted(taskfile.split(":")[:-1]))
734 layer_version_obj = self._get_layer_version_for_path(localfilepath) 734 layer_version_obj = self._get_layer_version_for_path(localfilepath)
735 735
736
737
736 recipe_info = {} 738 recipe_info = {}
737 recipe_info['layer_version'] = layer_version_obj 739 recipe_info['layer_version'] = layer_version_obj
738 recipe_info['file_path'] = taskfile 740 recipe_info['file_path'] = localfilepath
741 recipe_info['pathflags'] = filepath_flags
742
743 if recipe_info['file_path'].startswith(recipe_info['layer_version'].local_path):
744 recipe_info['file_path'] = recipe_info['file_path'][len(recipe_info['layer_version'].local_path):].lstrip("/")
745 else:
746 raise RuntimeError("Recipe file path %s is not under layer version at %s" % (recipe_info['file_path'], recipe_info['layer_version'].local_path))
739 747
740 return recipe_info 748 return recipe_info
741 749
@@ -787,6 +795,7 @@ class BuildInfoHelper(object):
787 for layer in layerinfos: 795 for layer in layerinfos:
788 try: 796 try:
789 self.internal_state['lvs'][self.orm_wrapper.get_update_layer_object(layerinfos[layer], self.brbe)] = layerinfos[layer]['version'] 797 self.internal_state['lvs'][self.orm_wrapper.get_update_layer_object(layerinfos[layer], self.brbe)] = layerinfos[layer]['version']
798 self.internal_state['lvs'][self.orm_wrapper.get_update_layer_object(layerinfos[layer], self.brbe)]['local_path'] = layerinfos[layer]['local_path']
790 except NotExisting as nee: 799 except NotExisting as nee:
791 logger.warn("buildinfohelper: cannot identify layer exception:%s " % nee) 800 logger.warn("buildinfohelper: cannot identify layer exception:%s " % nee)
792 801
@@ -899,8 +908,8 @@ class BuildInfoHelper(object):
899 908
900 recipe_information = self._get_recipe_information_from_taskfile(taskfile) 909 recipe_information = self._get_recipe_information_from_taskfile(taskfile)
901 try: 910 try:
902 if recipe_information['file_path'].startswith(recipe_information['layer_version'].layer.local_path): 911 if recipe_information['file_path'].startswith(recipe_information['layer_version'].local_path):
903 recipe_information['file_path'] = recipe_information['file_path'][len(recipe_information['layer_version'].layer.local_path):].lstrip("/") 912 recipe_information['file_path'] = recipe_information['file_path'][len(recipe_information['layer_version'].local_path):].lstrip("/")
904 913
905 recipe_object = Recipe.objects.get(layer_version = recipe_information['layer_version'], 914 recipe_object = Recipe.objects.get(layer_version = recipe_information['layer_version'],
906 file_path__endswith = recipe_information['file_path'], 915 file_path__endswith = recipe_information['file_path'],
@@ -1051,8 +1060,9 @@ class BuildInfoHelper(object):
1051 self.internal_state['recipes'] = {} 1060 self.internal_state['recipes'] = {}
1052 for pn in event._depgraph['pn']: 1061 for pn in event._depgraph['pn']:
1053 1062
1054 file_name = event._depgraph['pn'][pn]['filename'] 1063 file_name = event._depgraph['pn'][pn]['filename'].split(":")[-1]
1055 layer_version_obj = self._get_layer_version_for_path(file_name.split(":")[-1]) 1064 pathflags = ":".join(sorted(event._depgraph['pn'][pn]['filename'].split(":")[:-1]))
1065 layer_version_obj = self._get_layer_version_for_path(file_name)
1056 1066
1057 assert layer_version_obj is not None 1067 assert layer_version_obj is not None
1058 1068
@@ -1082,6 +1092,13 @@ class BuildInfoHelper(object):
1082 recipe_info['bugtracker'] = event._depgraph['pn'][pn]['bugtracker'] 1092 recipe_info['bugtracker'] = event._depgraph['pn'][pn]['bugtracker']
1083 1093
1084 recipe_info['file_path'] = file_name 1094 recipe_info['file_path'] = file_name
1095 recipe_info['pathflags'] = pathflags
1096
1097 if recipe_info['file_path'].startswith(recipe_info['layer_version'].local_path):
1098 recipe_info['file_path'] = recipe_info['file_path'][len(recipe_info['layer_version'].local_path):].lstrip("/")
1099 else:
1100 raise RuntimeError("Recipe file path %s is not under layer version at %s" % (recipe_info['file_path'], recipe_info['layer_version'].local_path))
1101
1085 recipe = self.orm_wrapper.get_update_recipe_object(recipe_info) 1102 recipe = self.orm_wrapper.get_update_recipe_object(recipe_info)
1086 recipe.is_image = False 1103 recipe.is_image = False
1087 if 'inherits' in event._depgraph['pn'][pn].keys(): 1104 if 'inherits' in event._depgraph['pn'][pn].keys():
diff --git a/bitbake/lib/toaster/contrib/tts/toasteruitest/toaster_automation_test.py b/bitbake/lib/toaster/contrib/tts/toasteruitest/toaster_automation_test.py
index c03a937b89..0cb3934339 100755
--- a/bitbake/lib/toaster/contrib/tts/toasteruitest/toaster_automation_test.py
+++ b/bitbake/lib/toaster/contrib/tts/toasteruitest/toaster_automation_test.py
@@ -926,7 +926,7 @@ class toaster_cases(toaster_cases_base):
926 self.driver.find_element_by_id("depends_on").click() 926 self.driver.find_element_by_id("depends_on").click()
927 self.driver.find_element_by_id("layer_version__branch").click() 927 self.driver.find_element_by_id("layer_version__branch").click()
928 self.driver.find_element_by_id("layer_version__layer__commit").click() 928 self.driver.find_element_by_id("layer_version__layer__commit").click()
929 self.driver.find_element_by_id("layer_version__layer__local_path").click() 929 self.driver.find_element_by_id("layer_version__local_path").click()
930 self.driver.find_element_by_id("depends_by").click() 930 self.driver.find_element_by_id("depends_by").click()
931 self.driver.find_element_by_css_selector("button.btn.dropdown-toggle").click() 931 self.driver.find_element_by_css_selector("button.btn.dropdown-toggle").click()
932 932
@@ -945,7 +945,7 @@ class toaster_cases(toaster_cases_base):
945 945
946 table_head_dict = {'Recipe file':'recipe_file', 'Section':'recipe_section', \ 946 table_head_dict = {'Recipe file':'recipe_file', 'Section':'recipe_section', \
947 'License':'recipe_license', 'Layer':'layer_version__layer__name', \ 947 'License':'recipe_license', 'Layer':'layer_version__layer__name', \
948 'Layer branch':'layer_version__branch', 'Layer directory':'layer_version__layer__local_path'} 948 'Layer branch':'layer_version__branch', 'Layer directory':'layer_version__local_path'}
949 for key in table_head_dict: 949 for key in table_head_dict:
950 self.find_element_by_link_text_in_table(self.table_name, key).click() 950 self.find_element_by_link_text_in_table(self.table_name, key).click()
951 column_list = self.get_table_column_text("class", table_head_dict[key]) 951 column_list = self.get_table_column_text("class", table_head_dict[key])
@@ -1066,7 +1066,7 @@ class toaster_cases(toaster_cases_base):
1066 self.driver.find_element_by_id("depends_on").click() 1066 self.driver.find_element_by_id("depends_on").click()
1067 self.driver.find_element_by_id("layer_version__branch").click() 1067 self.driver.find_element_by_id("layer_version__branch").click()
1068 self.driver.find_element_by_id("layer_version__layer__commit").click() 1068 self.driver.find_element_by_id("layer_version__layer__commit").click()
1069 self.driver.find_element_by_id("layer_version__layer__local_path").click() 1069 self.driver.find_element_by_id("layer_version__local_path").click()
1070 self.driver.find_element_by_id("depends_by").click() 1070 self.driver.find_element_by_id("depends_by").click()
1071 self.driver.find_element_by_css_selector("button.btn.dropdown-toggle").click() 1071 self.driver.find_element_by_css_selector("button.btn.dropdown-toggle").click()
1072 # check if columns selected above is shown 1072 # check if columns selected above is shown
@@ -1081,7 +1081,7 @@ class toaster_cases(toaster_cases_base):
1081 self.driver.find_element_by_id("depends_on").click() 1081 self.driver.find_element_by_id("depends_on").click()
1082 self.driver.find_element_by_id("layer_version__branch").click() 1082 self.driver.find_element_by_id("layer_version__branch").click()
1083 self.driver.find_element_by_id("layer_version__layer__commit").click() 1083 self.driver.find_element_by_id("layer_version__layer__commit").click()
1084 self.driver.find_element_by_id("layer_version__layer__local_path").click() 1084 self.driver.find_element_by_id("layer_version__local_path").click()
1085 self.driver.find_element_by_id("depends_by").click() 1085 self.driver.find_element_by_id("depends_by").click()
1086 self.driver.find_element_by_css_selector("button.btn.dropdown-toggle").click() 1086 self.driver.find_element_by_css_selector("button.btn.dropdown-toggle").click()
1087 # don't exist any more 1087 # don't exist any more
@@ -1425,7 +1425,7 @@ class toaster_cases(toaster_cases_base):
1425# Step 4 1425# Step 4
1426 # pulldown menu 1426 # pulldown menu
1427 option_ids = ['recipe__layer_version__layer__name', 'recipe__layer_version__branch', \ 1427 option_ids = ['recipe__layer_version__layer__name', 'recipe__layer_version__branch', \
1428 'recipe__layer_version__layer__commit', 'recipe__layer_version__layer__local_path', \ 1428 'recipe__layer_version__layer__commit', 'recipe__layer_version__local_path', \
1429 'license', 'recipe__version'] 1429 'license', 'recipe__version']
1430 self.driver.find_element_by_css_selector("button.btn.dropdown-toggle").click() 1430 self.driver.find_element_by_css_selector("button.btn.dropdown-toggle").click()
1431 for item in option_ids: 1431 for item in option_ids:
@@ -1470,7 +1470,7 @@ class toaster_cases(toaster_cases_base):
1470 self.driver.find_element_by_css_selector("button.btn.dropdown-toggle").click() 1470 self.driver.find_element_by_css_selector("button.btn.dropdown-toggle").click()
1471 self.driver.find_element_by_id("layer_version__branch").click() 1471 self.driver.find_element_by_id("layer_version__branch").click()
1472 self.driver.find_element_by_id("layer_version__layer__commit").click() 1472 self.driver.find_element_by_id("layer_version__layer__commit").click()
1473 self.driver.find_element_by_id("layer_version__layer__local_path").click() 1473 self.driver.find_element_by_id("layer_version__local_path").click()
1474 self.driver.find_element_by_css_selector("button.btn.dropdown-toggle").click() 1474 self.driver.find_element_by_css_selector("button.btn.dropdown-toggle").click()
1475 # otable is the recipes table here 1475 # otable is the recipes table here
1476 otable_head_text = self.get_table_head_text('otable') 1476 otable_head_text = self.get_table_head_text('otable')
@@ -1488,7 +1488,7 @@ class toaster_cases(toaster_cases_base):
1488 self.driver.find_element_by_id("recipe__layer_version__layer__name").click() 1488 self.driver.find_element_by_id("recipe__layer_version__layer__name").click()
1489 self.driver.find_element_by_id("recipe__layer_version__branch").click() 1489 self.driver.find_element_by_id("recipe__layer_version__branch").click()
1490 self.driver.find_element_by_id("recipe__layer_version__layer__commit").click() 1490 self.driver.find_element_by_id("recipe__layer_version__layer__commit").click()
1491 self.driver.find_element_by_id("recipe__layer_version__layer__local_path").click() 1491 self.driver.find_element_by_id("recipe__layer_version__local_path").click()
1492 self.driver.find_element_by_css_selector("button.btn.dropdown-toggle").click() 1492 self.driver.find_element_by_css_selector("button.btn.dropdown-toggle").click()
1493 otable_head_text = self.get_table_head_text("otable") 1493 otable_head_text = self.get_table_head_text("otable")
1494 for item in ["Layer", "Layer branch", "Layer commit", "Layer directory"]: 1494 for item in ["Layer", "Layer branch", "Layer commit", "Layer directory"]:
diff --git a/bitbake/lib/toaster/orm/migrations/0020_auto__add_field_layer_version_local_path__add_field_recipe_pathflags__.py b/bitbake/lib/toaster/orm/migrations/0020_auto__add_field_layer_version_local_path__add_field_recipe_pathflags__.py
new file mode 100644
index 0000000000..0ec5795976
--- /dev/null
+++ b/bitbake/lib/toaster/orm/migrations/0020_auto__add_field_layer_version_local_path__add_field_recipe_pathflags__.py
@@ -0,0 +1,361 @@
1# -*- coding: utf-8 -*-
2from south.utils import datetime_utils as datetime
3from south.db import db
4from south.v2 import SchemaMigration
5from django.db import models
6
7
8class Migration(SchemaMigration):
9
10 def forwards(self, orm):
11 # Removing unique constraint on 'Recipe', fields ['layer_version', 'file_path']
12 db.delete_unique(u'orm_recipe', ['layer_version_id', 'file_path'])
13
14 # Adding field 'Layer_Version.local_path'
15 db.add_column(u'orm_layer_version', 'local_path',
16 self.gf('django.db.models.fields.FilePathField')(default="/", max_length=1024),
17 keep_default=False)
18
19 # Adding field 'Recipe.pathflags'
20 db.add_column(u'orm_recipe', 'pathflags',
21 self.gf('django.db.models.fields.CharField')(default='', max_length=200, blank=True),
22 keep_default=False)
23
24 # Adding unique constraint on 'Recipe', fields ['layer_version', 'file_path', 'pathflags']
25 db.create_unique(u'orm_recipe', ['layer_version_id', 'file_path', 'pathflags'])
26
27 # Migrate data from Layer.local_path to Layer_Version.local_path
28 if not db.dry_run:
29 for lv in orm.Layer_Version.objects.all():
30 if lv.layer.local_path is not None:
31 lv.local_path = lv.layer.local_path
32 else:
33 lv.local_path = "/"
34 lv.save()
35
36 db.delete_column(u'orm_layer', 'local_path')
37
38
39 def backwards(self, orm):
40 raise RuntimeError("Cannot reverse this migration")
41
42
43 models = {
44 u'orm.bitbakeversion': {
45 'Meta': {'object_name': 'BitbakeVersion'},
46 'branch': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
47 'dirpath': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
48 'giturl': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
49 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
50 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'})
51 },
52 u'orm.branch': {
53 'Meta': {'unique_together': "(('layer_source', 'name'), ('layer_source', 'up_id'))", 'object_name': 'Branch'},
54 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
55 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'True', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
56 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
57 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
58 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
59 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'})
60 },
61 u'orm.build': {
62 'Meta': {'object_name': 'Build'},
63 'bitbake_version': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
64 'build_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
65 'completed_on': ('django.db.models.fields.DateTimeField', [], {}),
66 'cooker_log_path': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
67 'distro': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
68 'distro_version': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
69 'errors_no': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
70 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
71 'machine': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
72 'outcome': ('django.db.models.fields.IntegerField', [], {'default': '2'}),
73 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Project']"}),
74 'started_on': ('django.db.models.fields.DateTimeField', [], {}),
75 'timespent': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
76 'warnings_no': ('django.db.models.fields.IntegerField', [], {'default': '0'})
77 },
78 u'orm.buildartifact': {
79 'Meta': {'object_name': 'BuildArtifact'},
80 'build': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Build']"}),
81 'file_name': ('django.db.models.fields.FilePathField', [], {'max_length': '100'}),
82 'file_size': ('django.db.models.fields.IntegerField', [], {}),
83 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
84 },
85 u'orm.helptext': {
86 'Meta': {'object_name': 'HelpText'},
87 'area': ('django.db.models.fields.IntegerField', [], {}),
88 'build': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'helptext_build'", 'to': u"orm['orm.Build']"}),
89 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
90 'key': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
91 'text': ('django.db.models.fields.TextField', [], {})
92 },
93 u'orm.layer': {
94 'Meta': {'unique_together': "(('layer_source', 'up_id'), ('layer_source', 'name'))", 'object_name': 'Layer'},
95 'description': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True'}),
96 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
97 'layer_index_url': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
98 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
99 'local_path': ('django.db.models.fields.FilePathField', [], {'default': 'None', 'max_length': '255', 'null': 'True'}),
100 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
101 'summary': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True'}),
102 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
103 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'}),
104 'vcs_url': ('django.db.models.fields.URLField', [], {'default': 'None', 'max_length': '200', 'null': 'True'}),
105 'vcs_web_file_base_url': ('django.db.models.fields.URLField', [], {'default': 'None', 'max_length': '200', 'null': 'True'}),
106 'vcs_web_tree_base_url': ('django.db.models.fields.URLField', [], {'default': 'None', 'max_length': '200', 'null': 'True'}),
107 'vcs_web_url': ('django.db.models.fields.URLField', [], {'default': 'None', 'max_length': '200', 'null': 'True'})
108 },
109 u'orm.layer_version': {
110 'Meta': {'unique_together': "(('layer_source', 'up_id'),)", 'object_name': 'Layer_Version'},
111 'branch': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
112 'build': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'layer_version_build'", 'null': 'True', 'to': u"orm['orm.Build']"}),
113 'commit': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
114 'dirpath': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True'}),
115 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
116 'layer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'layer_version_layer'", 'to': u"orm['orm.Layer']"}),
117 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
118 'local_path': ('django.db.models.fields.FilePathField', [], {'default': 'None', 'max_length': '255', 'null': 'True'}),
119 'priority': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
120 'project': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.Project']", 'null': 'True'}),
121 'up_branch': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.Branch']", 'null': 'True'}),
122 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
123 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'})
124 },
125 u'orm.layersource': {
126 'Meta': {'unique_together': "(('sourcetype', 'apiurl'),)", 'object_name': 'LayerSource'},
127 'apiurl': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True'}),
128 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
129 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '63'}),
130 'sourcetype': ('django.db.models.fields.IntegerField', [], {})
131 },
132 u'orm.layerversiondependency': {
133 'Meta': {'unique_together': "(('layer_source', 'up_id'),)", 'object_name': 'LayerVersionDependency'},
134 'depends_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'dependees'", 'to': u"orm['orm.Layer_Version']"}),
135 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
136 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
137 'layer_version': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'dependencies'", 'to': u"orm['orm.Layer_Version']"}),
138 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'})
139 },
140 u'orm.logmessage': {
141 'Meta': {'object_name': 'LogMessage'},
142 'build': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Build']"}),
143 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
144 'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
145 'lineno': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
146 'message': ('django.db.models.fields.CharField', [], {'max_length': '240'}),
147 'pathname': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'}),
148 'task': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Task']", 'null': 'True', 'blank': 'True'})
149 },
150 u'orm.machine': {
151 'Meta': {'unique_together': "(('layer_source', 'up_id'),)", 'object_name': 'Machine'},
152 'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
153 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
154 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
155 'layer_version': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Layer_Version']"}),
156 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
157 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
158 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'})
159 },
160 u'orm.package': {
161 'Meta': {'object_name': 'Package'},
162 'build': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Build']"}),
163 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
164 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
165 'installed_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '100'}),
166 'installed_size': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
167 'license': ('django.db.models.fields.CharField', [], {'max_length': '80', 'blank': 'True'}),
168 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
169 'recipe': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Recipe']", 'null': 'True'}),
170 'revision': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
171 'section': ('django.db.models.fields.CharField', [], {'max_length': '80', 'blank': 'True'}),
172 'size': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
173 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
174 'version': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
175 },
176 u'orm.package_dependency': {
177 'Meta': {'object_name': 'Package_Dependency'},
178 'dep_type': ('django.db.models.fields.IntegerField', [], {}),
179 'depends_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'package_dependencies_target'", 'to': u"orm['orm.Package']"}),
180 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
181 'package': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'package_dependencies_source'", 'to': u"orm['orm.Package']"}),
182 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Target']", 'null': 'True'})
183 },
184 u'orm.package_file': {
185 'Meta': {'object_name': 'Package_File'},
186 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
187 'package': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'buildfilelist_package'", 'to': u"orm['orm.Package']"}),
188 'path': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'}),
189 'size': ('django.db.models.fields.IntegerField', [], {})
190 },
191 u'orm.project': {
192 'Meta': {'object_name': 'Project'},
193 'bitbake_version': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.BitbakeVersion']", 'null': 'True'}),
194 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
195 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
196 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
197 'release': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Release']", 'null': 'True'}),
198 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
199 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
200 'user_id': ('django.db.models.fields.IntegerField', [], {'null': 'True'})
201 },
202 u'orm.projectlayer': {
203 'Meta': {'unique_together': "(('project', 'layercommit'),)", 'object_name': 'ProjectLayer'},
204 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
205 'layercommit': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Layer_Version']", 'null': 'True'}),
206 'optional': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
207 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Project']"})
208 },
209 u'orm.projecttarget': {
210 'Meta': {'object_name': 'ProjectTarget'},
211 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
212 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Project']"}),
213 'target': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
214 'task': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'})
215 },
216 u'orm.projectvariable': {
217 'Meta': {'object_name': 'ProjectVariable'},
218 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
219 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
220 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Project']"}),
221 'value': ('django.db.models.fields.TextField', [], {'blank': 'True'})
222 },
223 u'orm.recipe': {
224 'Meta': {'unique_together': "(('layer_version', 'file_path', 'pathflags'), ('file_path', 'pathflags'))", 'object_name': 'Recipe'},
225 'bugtracker': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
226 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
227 'file_path': ('django.db.models.fields.FilePathField', [], {'max_length': '255'}),
228 'homepage': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
229 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
230 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
231 'layer_version': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'recipe_layer_version'", 'to': u"orm['orm.Layer_Version']"}),
232 'license': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
233 'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
234 'pathflags': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
235 'section': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
236 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
237 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
238 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'}),
239 'version': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
240 },
241 u'orm.recipe_dependency': {
242 'Meta': {'object_name': 'Recipe_Dependency'},
243 'dep_type': ('django.db.models.fields.IntegerField', [], {}),
244 'depends_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'r_dependencies_depends'", 'to': u"orm['orm.Recipe']"}),
245 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
246 'recipe': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'r_dependencies_recipe'", 'to': u"orm['orm.Recipe']"})
247 },
248 u'orm.release': {
249 'Meta': {'object_name': 'Release'},
250 'bitbake_version': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.BitbakeVersion']"}),
251 'branch_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '50'}),
252 'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
253 'helptext': ('django.db.models.fields.TextField', [], {'null': 'True'}),
254 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
255 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'})
256 },
257 u'orm.releasedefaultlayer': {
258 'Meta': {'object_name': 'ReleaseDefaultLayer'},
259 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
260 'layer_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '100'}),
261 'release': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Release']"})
262 },
263 u'orm.releaselayersourcepriority': {
264 'Meta': {'unique_together': "(('release', 'layer_source'),)", 'object_name': 'ReleaseLayerSourcePriority'},
265 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
266 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.LayerSource']"}),
267 'priority': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
268 'release': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Release']"})
269 },
270 u'orm.target': {
271 'Meta': {'object_name': 'Target'},
272 'build': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Build']"}),
273 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
274 'image_size': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
275 'is_image': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
276 'license_manifest_path': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True'}),
277 'target': ('django.db.models.fields.CharField', [], {'max_length': '100'})
278 },
279 u'orm.target_file': {
280 'Meta': {'object_name': 'Target_File'},
281 'directory': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'directory_set'", 'null': 'True', 'to': u"orm['orm.Target_File']"}),
282 'group': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
283 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
284 'inodetype': ('django.db.models.fields.IntegerField', [], {}),
285 'owner': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
286 'path': ('django.db.models.fields.FilePathField', [], {'max_length': '100'}),
287 'permission': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
288 'size': ('django.db.models.fields.IntegerField', [], {}),
289 'sym_target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'symlink_set'", 'null': 'True', 'to': u"orm['orm.Target_File']"}),
290 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Target']"})
291 },
292 u'orm.target_image_file': {
293 'Meta': {'object_name': 'Target_Image_File'},
294 'file_name': ('django.db.models.fields.FilePathField', [], {'max_length': '254'}),
295 'file_size': ('django.db.models.fields.IntegerField', [], {}),
296 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
297 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Target']"})
298 },
299 u'orm.target_installed_package': {
300 'Meta': {'object_name': 'Target_Installed_Package'},
301 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
302 'package': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'buildtargetlist_package'", 'to': u"orm['orm.Package']"}),
303 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Target']"})
304 },
305 u'orm.task': {
306 'Meta': {'ordering': "('order', 'recipe')", 'unique_together': "(('build', 'recipe', 'task_name'),)", 'object_name': 'Task'},
307 'build': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'task_build'", 'to': u"orm['orm.Build']"}),
308 'cpu_usage': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '8', 'decimal_places': '2'}),
309 'disk_io': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
310 'elapsed_time': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '8', 'decimal_places': '2'}),
311 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
312 'line_number': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
313 'logfile': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'}),
314 'message': ('django.db.models.fields.CharField', [], {'max_length': '240'}),
315 'order': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
316 'outcome': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
317 'path_to_sstate_obj': ('django.db.models.fields.FilePathField', [], {'max_length': '500', 'blank': 'True'}),
318 'recipe': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tasks'", 'to': u"orm['orm.Recipe']"}),
319 'script_type': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
320 'source_url': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'}),
321 'sstate_checksum': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
322 'sstate_result': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
323 'task_executed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
324 'task_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
325 'work_directory': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'})
326 },
327 u'orm.task_dependency': {
328 'Meta': {'object_name': 'Task_Dependency'},
329 'depends_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'task_dependencies_depends'", 'to': u"orm['orm.Task']"}),
330 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
331 'task': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'task_dependencies_task'", 'to': u"orm['orm.Task']"})
332 },
333 u'orm.toastersetting': {
334 'Meta': {'object_name': 'ToasterSetting'},
335 'helptext': ('django.db.models.fields.TextField', [], {}),
336 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
337 'name': ('django.db.models.fields.CharField', [], {'max_length': '63'}),
338 'value': ('django.db.models.fields.CharField', [], {'max_length': '255'})
339 },
340 u'orm.variable': {
341 'Meta': {'object_name': 'Variable'},
342 'build': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'variable_build'", 'to': u"orm['orm.Build']"}),
343 'changed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
344 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
345 'human_readable_name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
346 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
347 'variable_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
348 'variable_value': ('django.db.models.fields.TextField', [], {'blank': 'True'})
349 },
350 u'orm.variablehistory': {
351 'Meta': {'object_name': 'VariableHistory'},
352 'file_name': ('django.db.models.fields.FilePathField', [], {'max_length': '255'}),
353 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
354 'line_number': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
355 'operation': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
356 'value': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
357 'variable': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'vhistory'", 'to': u"orm['orm.Variable']"})
358 }
359 }
360
361 complete_apps = ['orm']
diff --git a/bitbake/lib/toaster/orm/models.py b/bitbake/lib/toaster/orm/models.py
index 20b02bbbb3..29ede657c8 100644
--- a/bitbake/lib/toaster/orm/models.py
+++ b/bitbake/lib/toaster/orm/models.py
@@ -457,7 +457,7 @@ class Task_Dependency(models.Model):
457 depends_on = models.ForeignKey(Task, related_name='task_dependencies_depends') 457 depends_on = models.ForeignKey(Task, related_name='task_dependencies_depends')
458 458
459class Package(models.Model): 459class Package(models.Model):
460 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__layer__local_path', 'installed_name'] 460 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']
461 build = models.ForeignKey('Build') 461 build = models.ForeignKey('Build')
462 recipe = models.ForeignKey('Recipe', null=True) 462 recipe = models.ForeignKey('Recipe', null=True)
463 name = models.CharField(max_length=100) 463 name = models.CharField(max_length=100)
@@ -528,7 +528,7 @@ class Package_File(models.Model):
528 size = models.IntegerField() 528 size = models.IntegerField()
529 529
530class Recipe(models.Model): 530class Recipe(models.Model):
531 search_allowed_fields = ['name', 'version', 'file_path', 'section', 'summary', 'description', 'license', 'layer_version__layer__name', 'layer_version__branch', 'layer_version__commit', 'layer_version__layer__local_path', 'layer_version__layer_source__name'] 531 search_allowed_fields = ['name', 'version', 'file_path', 'section', 'summary', 'description', 'license', 'layer_version__layer__name', 'layer_version__branch', 'layer_version__commit', 'layer_version__local_path', 'layer_version__layer_source__name']
532 532
533 layer_source = models.ForeignKey('LayerSource', default = None, null = True) # from where did we get this recipe 533 layer_source = models.ForeignKey('LayerSource', default = None, null = True) # from where did we get this recipe
534 up_id = models.IntegerField(null = True, default = None) # id of entry in the source 534 up_id = models.IntegerField(null = True, default = None) # id of entry in the source
@@ -544,6 +544,7 @@ class Recipe(models.Model):
544 homepage = models.URLField(blank=True) 544 homepage = models.URLField(blank=True)
545 bugtracker = models.URLField(blank=True) 545 bugtracker = models.URLField(blank=True)
546 file_path = models.FilePathField(max_length=255) 546 file_path = models.FilePathField(max_length=255)
547 pathflags = models.CharField(max_length=200, blank=True)
547 548
548 def get_layersource_view_url(self): 549 def get_layersource_view_url(self):
549 if self.layer_source is None: 550 if self.layer_source is None:
@@ -555,18 +556,6 @@ class Recipe(models.Model):
555 def __unicode__(self): 556 def __unicode__(self):
556 return "Recipe " + self.name + ":" + self.version 557 return "Recipe " + self.name + ":" + self.version
557 558
558 def get_local_path(self):
559 if settings.MANAGED and self.layer_version.build is not None and self.layer_version.build.project is not None:
560 # strip any tag prefixes ('virtual:native:')
561 layer_path=self.layer_version.layer.local_path.split(":")[-1]
562 recipe_path=self.file_path.split(":")[-1]
563 if 0 == recipe_path.find(layer_path):
564 return recipe_path[len(layer_path)+1:]
565 else:
566 return recipe_path
567
568 return self.file_path
569
570 def get_vcs_recipe_file_link_url(self): 559 def get_vcs_recipe_file_link_url(self):
571 return self.layer_version.get_vcs_file_link_url(self.file_path) 560 return self.layer_version.get_vcs_file_link_url(self.file_path)
572 561
@@ -579,7 +568,8 @@ class Recipe(models.Model):
579 return "" 568 return ""
580 569
581 class Meta: 570 class Meta:
582 unique_together = ("layer_version", "file_path") 571 unique_together = (("layer_version", "file_path", "pathflags"), )
572
583 573
584class Recipe_DependencyManager(models.Manager): 574class Recipe_DependencyManager(models.Manager):
585 use_for_related_fields = True 575 use_for_related_fields = True
@@ -976,7 +966,6 @@ class Layer(models.Model):
976 up_date = models.DateTimeField(null = True, default = None) 966 up_date = models.DateTimeField(null = True, default = None)
977 967
978 name = models.CharField(max_length=100) 968 name = models.CharField(max_length=100)
979 local_path = models.FilePathField(max_length=255, null = True, default = None)
980 layer_index_url = models.URLField() 969 layer_index_url = models.URLField()
981 vcs_url = GitURLField(default = None, null = True) 970 vcs_url = GitURLField(default = None, null = True)
982 vcs_web_url = models.URLField(null = True, default = None) 971 vcs_web_url = models.URLField(null = True, default = None)
@@ -1009,6 +998,8 @@ class Layer_Version(models.Model):
1009 dirpath = models.CharField(max_length=255, null = True, default = None) # LayerBranch.vcs_subdir 998 dirpath = models.CharField(max_length=255, null = True, default = None) # LayerBranch.vcs_subdir
1010 priority = models.IntegerField(default = 0) # if -1, this is a default layer 999 priority = models.IntegerField(default = 0) # if -1, this is a default layer
1011 1000
1001 local_path = models.FilePathField(max_length=1024, default = "/") # where this layer was checked-out
1002
1012 project = models.ForeignKey('Project', null = True, default = None) # Set if this layer is project-specific; always set for imported layers, and project-set branches 1003 project = models.ForeignKey('Project', null = True, default = None) # Set if this layer is project-specific; always set for imported layers, and project-set branches
1013 1004
1014 # code lifted, with adaptations, from the layerindex-web application https://git.yoctoproject.org/cgit/cgit.cgi/layerindex-web/ 1005 # code lifted, with adaptations, from the layerindex-web application https://git.yoctoproject.org/cgit/cgit.cgi/layerindex-web/
diff --git a/bitbake/lib/toaster/toastergui/templates/bpackage.html b/bitbake/lib/toaster/toastergui/templates/bpackage.html
index 6fbdc7b92d..1c47354a99 100644
--- a/bitbake/lib/toaster/toastergui/templates/bpackage.html
+++ b/bitbake/lib/toaster/toastergui/templates/bpackage.html
@@ -89,7 +89,7 @@
89 </td> 89 </td>
90 <!-- Layer directory --> 90 <!-- Layer directory -->
91 {% if not MANAGED or not build.project %} 91 {% if not MANAGED or not build.project %}
92 <td class="recipe__layer_version__layer__local_path">{{package.recipe.layer_version.layer.local_path}}</td> 92 <td class="recipe__layer_version__local_path">{{package.recipe.layer_version.local_path}}</td>
93 {% endif %} 93 {% endif %}
94 {%else%} 94 {%else%}
95 <td class="recipe__name"></td> 95 <td class="recipe__name"></td>
@@ -97,7 +97,7 @@
97 <td class="recipe__layer_version__layer__name"></td> 97 <td class="recipe__layer_version__layer__name"></td>
98 <td class="recipe__layer_version__branch"></td> 98 <td class="recipe__layer_version__branch"></td>
99 <td class="recipe__layer_version__layer__commit"></td> 99 <td class="recipe__layer_version__layer__commit"></td>
100 <td class="recipe__layer_version__layer__local_path"></td> 100 <td class="recipe__layer_version__local_path"></td>
101 {%endif%} 101 {%endif%}
102 102
103 </tr> 103 </tr>
diff --git a/bitbake/lib/toaster/toastergui/templates/configuration.html b/bitbake/lib/toaster/toastergui/templates/configuration.html
index d3b34a2096..2aa1ae1a49 100644
--- a/bitbake/lib/toaster/toastergui/templates/configuration.html
+++ b/bitbake/lib/toaster/toastergui/templates/configuration.html
@@ -64,7 +64,7 @@
64 {{lv.commit|truncatechars:13}} 64 {{lv.commit|truncatechars:13}}
65 </a></td> 65 </a></td>
66 {% if not MANAGED or not build.project %} 66 {% if not MANAGED or not build.project %}
67 <td>{{lv.layer.local_path}}</td> 67 <td>{{lv.local_path}}</td>
68 {% endif %} 68 {% endif %}
69 </tr>{% endfor %} 69 </tr>{% endfor %}
70 </tbody> 70 </tbody>
diff --git a/bitbake/lib/toaster/toastergui/templates/package_detail_base.html b/bitbake/lib/toaster/toastergui/templates/package_detail_base.html
index ad75454310..e2ec75d157 100644
--- a/bitbake/lib/toaster/toastergui/templates/package_detail_base.html
+++ b/bitbake/lib/toaster/toastergui/templates/package_detail_base.html
@@ -141,7 +141,7 @@
141 Layer directory 141 Layer directory
142 <i class="icon-question-sign get-help" title="Path to the layer providing the recipe that builds this package"></i> 142 <i class="icon-question-sign get-help" title="Path to the layer providing the recipe that builds this package"></i>
143 </dt> 143 </dt>
144 <dd><code>{{package.recipe.layer_version.layer.local_path}}</code></dd> 144 <dd><code>{{package.recipe.layer_version.local_path}}</code></dd>
145 {% endif %} 145 {% endif %}
146 </dl> 146 </dl>
147 </div> <!-- row4 well --> 147 </div> <!-- row4 well -->
diff --git a/bitbake/lib/toaster/toastergui/templates/recipe.html b/bitbake/lib/toaster/toastergui/templates/recipe.html
index a0fe6d71d3..2da41c3085 100644
--- a/bitbake/lib/toaster/toastergui/templates/recipe.html
+++ b/bitbake/lib/toaster/toastergui/templates/recipe.html
@@ -58,13 +58,13 @@
58 <i class="icon-question-sign get-help" title="Path to the layer providing the recipe"></i> 58 <i class="icon-question-sign get-help" title="Path to the layer providing the recipe"></i>
59 Layer directory 59 Layer directory
60 </dt> 60 </dt>
61 <dd><code>{{layer.local_path}}</code></dd> 61 <dd><code>{{object.layer_version.local_path}}</code></dd>
62 {% endif %} 62 {% endif %}
63 <dt> 63 <dt>
64 <i class="icon-question-sign get-help" title="Path to the recipe .bb file"></i> 64 <i class="icon-question-sign get-help" title="Path to the recipe .bb file"></i>
65 Recipe file 65 Recipe file
66 </dt> 66 </dt>
67 <dd><code>{{object.get_local_path}}</code></dd> 67 <dd><code>{{object.file_path}} {% if object.pathflags %}<i>({{object.pathflags}})</i>{% endif %}</code></dd>
68 {% if layer_version.branch %} 68 {% if layer_version.branch %}
69 <dt> 69 <dt>
70 <i class="icon-question-sign get-help" title="The Git branch of the layer providing the recipe"></i> 70 <i class="icon-question-sign get-help" title="The Git branch of the layer providing the recipe"></i>
diff --git a/bitbake/lib/toaster/toastergui/templates/recipes.html b/bitbake/lib/toaster/toastergui/templates/recipes.html
index dc2d9e8c3a..8d4494e7ef 100644
--- a/bitbake/lib/toaster/toastergui/templates/recipes.html
+++ b/bitbake/lib/toaster/toastergui/templates/recipes.html
@@ -84,7 +84,7 @@
84 {% endwith %} 84 {% endwith %}
85 </td> 85 </td>
86 <!-- Recipe file --> 86 <!-- Recipe file -->
87 <td class="recipe_file">{{recipe.get_local_path}}</td> 87 <td class="recipe_file">{{recipe.file_path}} {% if recipe.pathflags %}<i>({{recipe.pathflags}})</i>{% endif %}</td>
88 <!-- Section --> 88 <!-- Section -->
89 <td class="recipe_section">{{recipe.section}}</td> 89 <td class="recipe_section">{{recipe.section}}</td>
90 <!-- License --> 90 <!-- License -->
@@ -105,7 +105,7 @@
105 105
106 {% if not MANAGED or not build.project %} 106 {% if not MANAGED or not build.project %}
107 <!-- Layer directory --> 107 <!-- Layer directory -->
108 <td class="layer_version__layer__local_path">{{recipe.layer_version.layer.local_path}}</td> 108 <td class="layer_version__local_path">{{recipe.layer_version.local_path}}</td>
109 {% endif %} 109 {% endif %}
110 </tr> 110 </tr>
111 111
diff --git a/bitbake/lib/toaster/toastergui/templates/target.html b/bitbake/lib/toaster/toastergui/templates/target.html
index 1309b52dad..e7febaf22a 100644
--- a/bitbake/lib/toaster/toastergui/templates/target.html
+++ b/bitbake/lib/toaster/toastergui/templates/target.html
@@ -154,7 +154,7 @@
154 </td> 154 </td>
155 {% if not MANAGED or not build.project %} 155 {% if not MANAGED or not build.project %}
156 <td class="layer_directory"> 156 <td class="layer_directory">
157 {{ package.recipe.layer_version.layer.local_path }} 157 {{ package.recipe.layer_version.local_path }}
158 </td> 158 </td>
159 {% endif %} 159 {% endif %}
160 </tr> 160 </tr>
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py
index c16fc2219f..761bf53a11 100755
--- a/bitbake/lib/toaster/toastergui/views.py
+++ b/bitbake/lib/toaster/toastergui/views.py
@@ -725,9 +725,9 @@ eans multiple licenses exist that cover different parts of the source',
725 tc_layerDir = { 725 tc_layerDir = {
726 'name':'Layer directory', 726 'name':'Layer directory',
727 'qhelp':'Location in disk of the layer providing the recipe that builds the package', 727 'qhelp':'Location in disk of the layer providing the recipe that builds the package',
728 'orderfield' : _get_toggle_order( request, "recipe__layer_version__layer__local_path" ), 728 'orderfield' : _get_toggle_order( request, "recipe__layer_version__local_path" ),
729 'ordericon' : _get_toggle_order_icon( request, "recipe__layer_version__layer__local_path" ), 729 'ordericon' : _get_toggle_order_icon( request, "recipe__layer_version__local_path" ),
730 'orderkey' : "recipe__layer_version__layer__local_path", 730 'orderkey' : "recipe__layer_version__local_path",
731 'clclass' : 'layer_directory', 731 'clclass' : 'layer_directory',
732 'hidden' : 1, 732 'hidden' : 1,
733 } 733 }
@@ -1254,10 +1254,10 @@ def recipes(request, build_id):
1254 { 1254 {
1255 'name':'Layer directory', 1255 'name':'Layer directory',
1256 'qhelp':'Path to the layer prodiving the recipe', 1256 'qhelp':'Path to the layer prodiving the recipe',
1257 'orderfield': _get_toggle_order(request, "layer_version__layer__local_path"), 1257 'orderfield': _get_toggle_order(request, "layer_version__local_path"),
1258 'ordericon':_get_toggle_order_icon(request, "layer_version__layer__local_path"), 1258 'ordericon':_get_toggle_order_icon(request, "layer_version__local_path"),
1259 'orderkey' : 'layer_version__layer__local_path', 1259 'orderkey' : 'layer_version__local_path',
1260 'clclass': 'layer_version__layer__local_path', 'hidden': 1, 1260 'clclass': 'layer_version__local_path', 'hidden': 1,
1261 }) 1261 })
1262 1262
1263 1263
@@ -1464,10 +1464,10 @@ def bpackage(request, build_id):
1464 tc_layerDir = { 1464 tc_layerDir = {
1465 'name':'Layer directory', 1465 'name':'Layer directory',
1466 'qhelp':'Path to the layer providing the recipe that builds the package', 1466 'qhelp':'Path to the layer providing the recipe that builds the package',
1467 'orderfield': _get_toggle_order(request, "recipe__layer_version__layer__local_path"), 1467 'orderfield': _get_toggle_order(request, "recipe__layer_version__local_path"),
1468 'ordericon':_get_toggle_order_icon(request, "recipe__layer_version__layer__local_path"), 1468 'ordericon':_get_toggle_order_icon(request, "recipe__layer_version__local_path"),
1469 'orderkey' : 'recipe__layer_version__layer__local_path', 1469 'orderkey' : 'recipe__layer_version__local_path',
1470 'clclass': 'recipe__layer_version__layer__local_path', 'hidden': 1, 1470 'clclass': 'recipe__layer_version__local_path', 'hidden': 1,
1471 } 1471 }
1472 context['tablecols'].append(tc_layerDir) 1472 context['tablecols'].append(tc_layerDir)
1473 1473