summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/toaster')
-rw-r--r--bitbake/lib/toaster/bldcontrol/localhostbecontroller.py2
-rw-r--r--bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py10
-rw-r--r--bitbake/lib/toaster/orm/migrations/0023_auto__del_field_build_warnings_no__del_field_build_errors_no__del_fiel.py353
-rw-r--r--bitbake/lib/toaster/orm/models.py19
-rw-r--r--bitbake/lib/toaster/toastergui/templates/builddashboard.html23
-rw-r--r--bitbake/lib/toaster/toastergui/templates/builds.html22
-rw-r--r--bitbake/lib/toaster/toastergui/templates/configuration.html6
-rw-r--r--bitbake/lib/toaster/toastergui/templates/filtersnippet.html2
-rw-r--r--bitbake/lib/toaster/toastergui/templates/landing.html37
-rw-r--r--bitbake/lib/toaster/toastergui/templates/mrb_section.html29
-rw-r--r--bitbake/lib/toaster/toastergui/templates/package_detail_base.html7
-rw-r--r--bitbake/lib/toaster/toastergui/templates/projectbuilds.html29
-rw-r--r--bitbake/lib/toaster/toastergui/templates/projects.html9
-rw-r--r--bitbake/lib/toaster/toastergui/templates/recipe.html9
-rw-r--r--bitbake/lib/toaster/toastergui/templates/recipes.html7
-rw-r--r--bitbake/lib/toaster/toastergui/templates/runagain.html7
-rw-r--r--bitbake/lib/toaster/toastergui/templates/target.html5
-rw-r--r--bitbake/lib/toaster/toastergui/templates/task.html36
-rw-r--r--bitbake/lib/toaster/toastergui/templates/tasks.html7
-rw-r--r--bitbake/lib/toaster/toastergui/urls.py3
-rwxr-xr-xbitbake/lib/toaster/toastergui/views.py17
21 files changed, 453 insertions, 186 deletions
diff --git a/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py b/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py
index ad0a561398..3e16837be1 100644
--- a/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py
+++ b/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py
@@ -113,7 +113,7 @@ class LocalhostBEController(BuildEnvironmentController):
113 # get the file length; we need to detect the _last_ start of the toaster UI, not the first 113 # get the file length; we need to detect the _last_ start of the toaster UI, not the first
114 toaster_ui_log_filelength = 0 114 toaster_ui_log_filelength = 0
115 if os.path.exists(toaster_ui_log_filepath): 115 if os.path.exists(toaster_ui_log_filepath):
116 with open(toaster_ui_log_filepath, "r") as f: 116 with open(toaster_ui_log_filepath, "w") as f:
117 f.seek(0, 2) # jump to the end 117 f.seek(0, 2) # jump to the end
118 toaster_ui_log_filelength = f.tell() 118 toaster_ui_log_filelength = f.tell()
119 119
diff --git a/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py b/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py
index bcf3b04cf0..33cc94ea89 100644
--- a/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py
+++ b/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py
@@ -107,20 +107,24 @@ class Command(NoArgsCommand):
107 def cleanup(self): 107 def cleanup(self):
108 from django.utils import timezone 108 from django.utils import timezone
109 from datetime import timedelta 109 from datetime import timedelta
110 # DISABLED environments locked for more than 30 seconds - they should be unlocked 110 # environments locked for more than 30 seconds - they should be unlocked
111 #BuildEnvironment.objects.filter(lock=BuildEnvironment.LOCK_LOCK).filter(updated__lt = timezone.now() - timedelta(seconds = 30)).update(lock = BuildEnvironment.LOCK_FREE) 111 BuildEnvironment.objects.filter(buildrequest__state__in=[BuildRequest.REQ_FAILED, BuildRequest.REQ_COMPLETED]).filter(lock=BuildEnvironment.LOCK_LOCK).filter(updated__lt = timezone.now() - timedelta(seconds = 30)).update(lock = BuildEnvironment.LOCK_FREE)
112 112
113 113
114 # update all Builds that failed to start 114 # update all Builds that failed to start
115 115
116 for br in BuildRequest.objects.filter(state = BuildRequest.REQ_FAILED, build__outcome = Build.IN_PROGRESS): 116 for br in BuildRequest.objects.filter(state = BuildRequest.REQ_FAILED, build__outcome = Build.IN_PROGRESS):
117 br.build.outcome = Build.FAILED
118 # transpose the launch errors in ToasterExceptions 117 # transpose the launch errors in ToasterExceptions
118 br.build.outcome = Build.FAILED
119 for brerror in br.brerror_set.all(): 119 for brerror in br.brerror_set.all():
120 logger.debug("Saving error %s" % brerror) 120 logger.debug("Saving error %s" % brerror)
121 LogMessage.objects.create(build = br.build, level = LogMessage.EXCEPTION, message = brerror.errmsg) 121 LogMessage.objects.create(build = br.build, level = LogMessage.EXCEPTION, message = brerror.errmsg)
122 br.build.save() 122 br.build.save()
123 123
124 # we don't have a true build object here; hence, toasterui didn't have a change to release the BE lock
125 br.environment.lock = BuildEnvironment.LOCK_FREE
126 br.environment.save()
127
124 128
125 129
126 # update all BuildRequests without a build created 130 # update all BuildRequests without a build created
diff --git a/bitbake/lib/toaster/orm/migrations/0023_auto__del_field_build_warnings_no__del_field_build_errors_no__del_fiel.py b/bitbake/lib/toaster/orm/migrations/0023_auto__del_field_build_warnings_no__del_field_build_errors_no__del_fiel.py
new file mode 100644
index 0000000000..b5b200cdd8
--- /dev/null
+++ b/bitbake/lib/toaster/orm/migrations/0023_auto__del_field_build_warnings_no__del_field_build_errors_no__del_fiel.py
@@ -0,0 +1,353 @@
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 # Deleting field 'Build.warnings_no'
12 db.delete_column(u'orm_build', 'warnings_no')
13
14 # Deleting field 'Build.errors_no'
15 db.delete_column(u'orm_build', 'errors_no')
16
17 # Deleting field 'Build.timespent'
18 db.delete_column(u'orm_build', 'timespent')
19
20
21 def backwards(self, orm):
22 # Adding field 'Build.warnings_no'
23 db.add_column(u'orm_build', 'warnings_no',
24 self.gf('django.db.models.fields.IntegerField')(default=0),
25 keep_default=False)
26
27 # Adding field 'Build.errors_no'
28 db.add_column(u'orm_build', 'errors_no',
29 self.gf('django.db.models.fields.IntegerField')(default=0),
30 keep_default=False)
31
32 # Adding field 'Build.timespent'
33 db.add_column(u'orm_build', 'timespent',
34 self.gf('django.db.models.fields.IntegerField')(default=0),
35 keep_default=False)
36
37
38 models = {
39 u'orm.bitbakeversion': {
40 'Meta': {'object_name': 'BitbakeVersion'},
41 'branch': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
42 'dirpath': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
43 'giturl': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
44 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
45 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'})
46 },
47 u'orm.branch': {
48 'Meta': {'unique_together': "(('layer_source', 'name'), ('layer_source', 'up_id'))", 'object_name': 'Branch'},
49 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
50 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'True', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
51 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
52 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
53 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
54 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'})
55 },
56 u'orm.build': {
57 'Meta': {'object_name': 'Build'},
58 'bitbake_version': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
59 'build_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
60 'completed_on': ('django.db.models.fields.DateTimeField', [], {}),
61 'cooker_log_path': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
62 'distro': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
63 'distro_version': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
64 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
65 'machine': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
66 'outcome': ('django.db.models.fields.IntegerField', [], {'default': '2'}),
67 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Project']"}),
68 'started_on': ('django.db.models.fields.DateTimeField', [], {})
69 },
70 u'orm.buildartifact': {
71 'Meta': {'object_name': 'BuildArtifact'},
72 'build': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Build']"}),
73 'file_name': ('django.db.models.fields.FilePathField', [], {'max_length': '100'}),
74 'file_size': ('django.db.models.fields.IntegerField', [], {}),
75 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
76 },
77 u'orm.helptext': {
78 'Meta': {'object_name': 'HelpText'},
79 'area': ('django.db.models.fields.IntegerField', [], {}),
80 'build': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'helptext_build'", 'to': u"orm['orm.Build']"}),
81 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
82 'key': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
83 'text': ('django.db.models.fields.TextField', [], {})
84 },
85 u'orm.layer': {
86 'Meta': {'unique_together': "(('layer_source', 'up_id'), ('layer_source', 'name'))", 'object_name': 'Layer'},
87 'description': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True'}),
88 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
89 'layer_index_url': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
90 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
91 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
92 'summary': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True'}),
93 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
94 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'}),
95 'vcs_url': ('django.db.models.fields.URLField', [], {'default': 'None', 'max_length': '200', 'null': 'True'}),
96 'vcs_web_file_base_url': ('django.db.models.fields.URLField', [], {'default': 'None', 'max_length': '200', 'null': 'True'}),
97 'vcs_web_tree_base_url': ('django.db.models.fields.URLField', [], {'default': 'None', 'max_length': '200', 'null': 'True'}),
98 'vcs_web_url': ('django.db.models.fields.URLField', [], {'default': 'None', 'max_length': '200', 'null': 'True'})
99 },
100 u'orm.layer_version': {
101 'Meta': {'unique_together': "(('layer_source', 'up_id'),)", 'object_name': 'Layer_Version'},
102 'branch': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
103 'build': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'layer_version_build'", 'null': 'True', 'to': u"orm['orm.Build']"}),
104 'commit': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
105 'dirpath': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True'}),
106 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
107 'layer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'layer_version_layer'", 'to': u"orm['orm.Layer']"}),
108 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
109 'local_path': ('django.db.models.fields.FilePathField', [], {'default': "'/'", 'max_length': '1024'}),
110 'priority': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
111 'project': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.Project']", 'null': 'True'}),
112 'up_branch': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.Branch']", 'null': 'True'}),
113 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
114 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'})
115 },
116 u'orm.layersource': {
117 'Meta': {'unique_together': "(('sourcetype', 'apiurl'),)", 'object_name': 'LayerSource'},
118 'apiurl': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True'}),
119 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
120 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '63'}),
121 'sourcetype': ('django.db.models.fields.IntegerField', [], {})
122 },
123 u'orm.layerversiondependency': {
124 'Meta': {'unique_together': "(('layer_source', 'up_id'),)", 'object_name': 'LayerVersionDependency'},
125 'depends_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'dependees'", 'to': u"orm['orm.Layer_Version']"}),
126 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
127 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
128 'layer_version': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'dependencies'", 'to': u"orm['orm.Layer_Version']"}),
129 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'})
130 },
131 u'orm.logmessage': {
132 'Meta': {'object_name': 'LogMessage'},
133 'build': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Build']"}),
134 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
135 'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
136 'lineno': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
137 'message': ('django.db.models.fields.CharField', [], {'max_length': '240'}),
138 'pathname': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'}),
139 'task': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Task']", 'null': 'True', 'blank': 'True'})
140 },
141 u'orm.machine': {
142 'Meta': {'unique_together': "(('layer_source', 'up_id'),)", 'object_name': 'Machine'},
143 'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
144 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
145 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
146 'layer_version': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Layer_Version']"}),
147 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
148 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
149 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'})
150 },
151 u'orm.package': {
152 'Meta': {'object_name': 'Package'},
153 'build': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Build']"}),
154 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
155 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
156 'installed_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '100'}),
157 'installed_size': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
158 'license': ('django.db.models.fields.CharField', [], {'max_length': '80', 'blank': 'True'}),
159 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
160 'recipe': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Recipe']", 'null': 'True'}),
161 'revision': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
162 'section': ('django.db.models.fields.CharField', [], {'max_length': '80', 'blank': 'True'}),
163 'size': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
164 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
165 'version': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
166 },
167 u'orm.package_dependency': {
168 'Meta': {'object_name': 'Package_Dependency'},
169 'dep_type': ('django.db.models.fields.IntegerField', [], {}),
170 'depends_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'package_dependencies_target'", 'to': u"orm['orm.Package']"}),
171 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
172 'package': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'package_dependencies_source'", 'to': u"orm['orm.Package']"}),
173 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Target']", 'null': 'True'})
174 },
175 u'orm.package_file': {
176 'Meta': {'object_name': 'Package_File'},
177 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
178 'package': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'buildfilelist_package'", 'to': u"orm['orm.Package']"}),
179 'path': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'}),
180 'size': ('django.db.models.fields.IntegerField', [], {})
181 },
182 u'orm.project': {
183 'Meta': {'object_name': 'Project'},
184 'bitbake_version': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.BitbakeVersion']", 'null': 'True'}),
185 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
186 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
187 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
188 'release': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Release']", 'null': 'True'}),
189 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
190 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
191 'user_id': ('django.db.models.fields.IntegerField', [], {'null': 'True'})
192 },
193 u'orm.projectlayer': {
194 'Meta': {'unique_together': "(('project', 'layercommit'),)", 'object_name': 'ProjectLayer'},
195 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
196 'layercommit': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Layer_Version']", 'null': 'True'}),
197 'optional': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
198 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Project']"})
199 },
200 u'orm.projecttarget': {
201 'Meta': {'object_name': 'ProjectTarget'},
202 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
203 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Project']"}),
204 'target': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
205 'task': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'})
206 },
207 u'orm.projectvariable': {
208 'Meta': {'object_name': 'ProjectVariable'},
209 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
210 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
211 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Project']"}),
212 'value': ('django.db.models.fields.TextField', [], {'blank': 'True'})
213 },
214 u'orm.recipe': {
215 'Meta': {'unique_together': "(('layer_version', 'file_path', 'pathflags'),)", 'object_name': 'Recipe'},
216 'bugtracker': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
217 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
218 'file_path': ('django.db.models.fields.FilePathField', [], {'max_length': '255'}),
219 'homepage': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
220 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
221 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
222 'layer_version': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'recipe_layer_version'", 'to': u"orm['orm.Layer_Version']"}),
223 'license': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
224 'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
225 'pathflags': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
226 'section': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
227 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
228 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
229 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'}),
230 'version': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
231 },
232 u'orm.recipe_dependency': {
233 'Meta': {'object_name': 'Recipe_Dependency'},
234 'dep_type': ('django.db.models.fields.IntegerField', [], {}),
235 'depends_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'r_dependencies_depends'", 'to': u"orm['orm.Recipe']"}),
236 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
237 'recipe': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'r_dependencies_recipe'", 'to': u"orm['orm.Recipe']"})
238 },
239 u'orm.release': {
240 'Meta': {'object_name': 'Release'},
241 'bitbake_version': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.BitbakeVersion']"}),
242 'branch_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '50'}),
243 'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
244 'helptext': ('django.db.models.fields.TextField', [], {'null': 'True'}),
245 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
246 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'})
247 },
248 u'orm.releasedefaultlayer': {
249 'Meta': {'object_name': 'ReleaseDefaultLayer'},
250 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
251 'layer_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '100'}),
252 'release': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Release']"})
253 },
254 u'orm.releaselayersourcepriority': {
255 'Meta': {'unique_together': "(('release', 'layer_source'),)", 'object_name': 'ReleaseLayerSourcePriority'},
256 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
257 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.LayerSource']"}),
258 'priority': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
259 'release': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Release']"})
260 },
261 u'orm.target': {
262 'Meta': {'object_name': 'Target'},
263 'build': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Build']"}),
264 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
265 'image_size': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
266 'is_image': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
267 'license_manifest_path': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True'}),
268 'target': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
269 'task': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'})
270 },
271 u'orm.target_file': {
272 'Meta': {'object_name': 'Target_File'},
273 'directory': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'directory_set'", 'null': 'True', 'to': u"orm['orm.Target_File']"}),
274 'group': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
275 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
276 'inodetype': ('django.db.models.fields.IntegerField', [], {}),
277 'owner': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
278 'path': ('django.db.models.fields.FilePathField', [], {'max_length': '100'}),
279 'permission': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
280 'size': ('django.db.models.fields.IntegerField', [], {}),
281 'sym_target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'symlink_set'", 'null': 'True', 'to': u"orm['orm.Target_File']"}),
282 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Target']"})
283 },
284 u'orm.target_image_file': {
285 'Meta': {'object_name': 'Target_Image_File'},
286 'file_name': ('django.db.models.fields.FilePathField', [], {'max_length': '254'}),
287 'file_size': ('django.db.models.fields.IntegerField', [], {}),
288 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
289 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Target']"})
290 },
291 u'orm.target_installed_package': {
292 'Meta': {'object_name': 'Target_Installed_Package'},
293 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
294 'package': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'buildtargetlist_package'", 'to': u"orm['orm.Package']"}),
295 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Target']"})
296 },
297 u'orm.task': {
298 'Meta': {'ordering': "('order', 'recipe')", 'unique_together': "(('build', 'recipe', 'task_name'),)", 'object_name': 'Task'},
299 'build': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'task_build'", 'to': u"orm['orm.Build']"}),
300 'cpu_usage': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '8', 'decimal_places': '2'}),
301 'disk_io': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
302 'elapsed_time': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '8', 'decimal_places': '2'}),
303 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
304 'line_number': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
305 'logfile': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'}),
306 'message': ('django.db.models.fields.CharField', [], {'max_length': '240'}),
307 'order': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
308 'outcome': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
309 'path_to_sstate_obj': ('django.db.models.fields.FilePathField', [], {'max_length': '500', 'blank': 'True'}),
310 'recipe': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tasks'", 'to': u"orm['orm.Recipe']"}),
311 'script_type': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
312 'source_url': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'}),
313 'sstate_checksum': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
314 'sstate_result': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
315 'task_executed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
316 'task_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
317 'work_directory': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'})
318 },
319 u'orm.task_dependency': {
320 'Meta': {'object_name': 'Task_Dependency'},
321 'depends_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'task_dependencies_depends'", 'to': u"orm['orm.Task']"}),
322 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
323 'task': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'task_dependencies_task'", 'to': u"orm['orm.Task']"})
324 },
325 u'orm.toastersetting': {
326 'Meta': {'object_name': 'ToasterSetting'},
327 'helptext': ('django.db.models.fields.TextField', [], {}),
328 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
329 'name': ('django.db.models.fields.CharField', [], {'max_length': '63'}),
330 'value': ('django.db.models.fields.CharField', [], {'max_length': '255'})
331 },
332 u'orm.variable': {
333 'Meta': {'object_name': 'Variable'},
334 'build': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'variable_build'", 'to': u"orm['orm.Build']"}),
335 'changed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
336 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
337 'human_readable_name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
338 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
339 'variable_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
340 'variable_value': ('django.db.models.fields.TextField', [], {'blank': 'True'})
341 },
342 u'orm.variablehistory': {
343 'Meta': {'object_name': 'VariableHistory'},
344 'file_name': ('django.db.models.fields.FilePathField', [], {'max_length': '255'}),
345 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
346 'line_number': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
347 'operation': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
348 'value': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
349 'variable': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'vhistory'", 'to': u"orm['orm.Variable']"})
350 }
351 }
352
353 complete_apps = ['orm'] \ No newline at end of file
diff --git a/bitbake/lib/toaster/orm/models.py b/bitbake/lib/toaster/orm/models.py
index e93629b7ba..077c94d818 100644
--- a/bitbake/lib/toaster/orm/models.py
+++ b/bitbake/lib/toaster/orm/models.py
@@ -147,7 +147,7 @@ class Project(models.Model):
147 if (-1 == build_id): 147 if (-1 == build_id):
148 return( 0 ) 148 return( 0 )
149 try: 149 try:
150 return Build.objects.filter(id = build_id)[ 0 ].errors_no 150 return Build.objects.filter(id = build_id)[ 0 ].errors.count()
151 except (Build.DoesNotExist,IndexError): 151 except (Build.DoesNotExist,IndexError):
152 return( "not_found" ) 152 return( "not_found" )
153 153
@@ -156,7 +156,7 @@ class Project(models.Model):
156 if (-1 == build_id): 156 if (-1 == build_id):
157 return( 0 ) 157 return( 0 )
158 try: 158 try:
159 return Build.objects.filter(id = build_id)[ 0 ].warnings_no 159 return Build.objects.filter(id = build_id)[ 0 ].warnings.count()
160 except (Build.DoesNotExist,IndexError): 160 except (Build.DoesNotExist,IndexError):
161 return( "not_found" ) 161 return( "not_found" )
162 162
@@ -248,10 +248,7 @@ class Build(models.Model):
248 distro_version = models.CharField(max_length=100) 248 distro_version = models.CharField(max_length=100)
249 started_on = models.DateTimeField() 249 started_on = models.DateTimeField()
250 completed_on = models.DateTimeField() 250 completed_on = models.DateTimeField()
251 timespent = models.IntegerField(default=0)
252 outcome = models.IntegerField(choices=BUILD_OUTCOME, default=IN_PROGRESS) 251 outcome = models.IntegerField(choices=BUILD_OUTCOME, default=IN_PROGRESS)
253 errors_no = models.IntegerField(default=0)
254 warnings_no = models.IntegerField(default=0)
255 cooker_log_path = models.CharField(max_length=500) 252 cooker_log_path = models.CharField(max_length=500)
256 build_name = models.CharField(max_length=100) 253 build_name = models.CharField(max_length=100)
257 bitbake_version = models.CharField(max_length=50) 254 bitbake_version = models.CharField(max_length=50)
@@ -281,6 +278,17 @@ class Build(models.Model):
281 def toaster_exceptions(self): 278 def toaster_exceptions(self):
282 return self.logmessage_set.filter(level=LogMessage.EXCEPTION) 279 return self.logmessage_set.filter(level=LogMessage.EXCEPTION)
283 280
281 @property
282 def errors(self):
283 return (self.logmessage_set.filter(level=LogMessage.ERROR)|self.logmessage_set.filter(level=LogMessage.EXCEPTION))
284
285 @property
286 def warnings(self):
287 return self.logmessage_set.filter(level=LogMessage.WARNING)
288
289 @property
290 def timespent_seconds(self):
291 return (self.completed_on - self.started_on).total_seconds()
284 292
285 def get_current_status(self): 293 def get_current_status(self):
286 from bldcontrol.models import BuildRequest 294 from bldcontrol.models import BuildRequest
@@ -298,7 +306,6 @@ class BuildArtifact(models.Model):
298 file_name = models.FilePathField() 306 file_name = models.FilePathField()
299 file_size = models.IntegerField() 307 file_size = models.IntegerField()
300 308
301
302 def get_local_file_name(self): 309 def get_local_file_name(self):
303 try: 310 try:
304 deploydir = Variable.objects.get(build = self.build, variable_name="DEPLOY_DIR").variable_value 311 deploydir = Variable.objects.get(build = self.build, variable_name="DEPLOY_DIR").variable_value
diff --git a/bitbake/lib/toaster/toastergui/templates/builddashboard.html b/bitbake/lib/toaster/toastergui/templates/builddashboard.html
index 47b8d7aa1f..bab8e388f5 100644
--- a/bitbake/lib/toaster/toastergui/templates/builddashboard.html
+++ b/bitbake/lib/toaster/toastergui/templates/builddashboard.html
@@ -23,22 +23,23 @@
23 </strong> on 23 </strong> on
24 {{build.completed_on|date:"d/m/y H:i"}} 24 {{build.completed_on|date:"d/m/y H:i"}}
25</span> 25</span>
26{% if build.warnings_no or build.errors_no %} 26{% if build.warnings.count or build.errors.count %}
27&nbsp;with 27&nbsp;with
28{% endif %} 28{% endif %}
29{%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %} 29{%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %}
30{% if build.errors_no %} 30{% if build.errors.count %}
31 <span > <i class="icon-minus-sign red"></i><strong><a href="#errors" class="error show-errors"> {{build.errors_no}} error{{build.errors_no|pluralize}}</a></strong></span> 31 <span > <i class="icon-minus-sign red"></i><strong><a href="#errors" class="error show-errors"> {{build.errors.count}} error{{build.errors.count|pluralize}}</a></strong></span>
32{% endif %} 32{% endif %}
33{% if build.warnings_no %} 33{% if build.warnings.count %}
34{% if build.errors_no %} 34{% if build.errors.count %}
35 and 35 and
36{% endif %} 36{% endif %}
37 <span > <i class="icon-warning-sign yellow"></i><strong><a href="#warnings" class="warning show-warnings"> {{build.warnings_no}} warning{{build.warnings_no|pluralize}}</a></strong></span> 37 <span > <i class="icon-warning-sign yellow"></i><strong><a href="#warnings" class="warning show-warnings"> {{build.warnings.count}} warning{{build.warnings.count|pluralize}}</a></strong></span>
38{% endif %} 38{% endif %}
39 <span class="pull-right">Build time: <a href="{% url 'buildtime' build.pk %}">{{ build.timespent|sectohms }}</a> 39 <span class="pull-right">Build time: <a href="{% url 'buildtime' build.pk %}">{{ build.timespent_seconds|sectohms }}</a>
40 <a class="btn {%if build.outcome == build.SUCCEEDED%}btn-success{%else%}btn-danger{%endif%} pull-right log" href="{% url 'build_artifact' build.id "cookerlog" build.id %}">Download build log</a> 40 <a class="btn {%if build.outcome == build.SUCCEEDED%}btn-success{%else%}btn-danger{%endif%} pull-right log" href="{% url 'build_artifact' build.id "cookerlog" build.id %}">Download build log</a>
41 </span> 41 </span>
42
42{%endif%} 43{%endif%}
43 </div> 44 </div>
44 {% if build.toaster_exceptions.count > 0 %} 45 {% if build.toaster_exceptions.count > 0 %}
@@ -52,14 +53,14 @@
52 </div> 53 </div>
53</div> 54</div>
54 55
55{% if build.errors_no %} 56{% if build.errors.count %}
56<div class="accordion span10 pull-right" id="errors"> 57<div class="accordion span10 pull-right" id="errors">
57 <div class="accordion-group"> 58 <div class="accordion-group">
58 <div class="accordion-heading"> 59 <div class="accordion-heading">
59 <a class="accordion-toggle error toggle-errors"> 60 <a class="accordion-toggle error toggle-errors">
60 <h2 id="error-toggle"> 61 <h2 id="error-toggle">
61 <i class="icon-minus-sign"></i> 62 <i class="icon-minus-sign"></i>
62 {{build.errors_no}} error{{build.errors_no|pluralize}} 63 {{build.errors.count}} error{{build.errors.count|pluralize}}
63 </h2> 64 </h2>
64 </a> 65 </a>
65 </div> 66 </div>
@@ -241,14 +242,14 @@
241 </div> 242 </div>
242</div> 243</div>
243 244
244{% if build.warnings_no %} 245{% if build.warnings.count %}
245<div class="accordion span10 pull-right" id="warnings"> 246<div class="accordion span10 pull-right" id="warnings">
246 <div class="accordion-group"> 247 <div class="accordion-group">
247 <div class="accordion-heading"> 248 <div class="accordion-heading">
248 <a class="accordion-toggle warning toggle-warnings"> 249 <a class="accordion-toggle warning toggle-warnings">
249 <h2 id="warning-toggle"> 250 <h2 id="warning-toggle">
250 <i class="icon-warning-sign"></i> 251 <i class="icon-warning-sign"></i>
251 {{build.warnings_no}} warning{{build.warnings_no|pluralize}} 252 {{build.warnings.count}} warning{{build.warnings.count|pluralize}}
252 </h2> 253 </h2>
253 </a> 254 </a>
254 </div> 255 </div>
diff --git a/bitbake/lib/toaster/toastergui/templates/builds.html b/bitbake/lib/toaster/toastergui/templates/builds.html
index e9211affcd..00d1d4edd1 100644
--- a/bitbake/lib/toaster/toastergui/templates/builds.html
+++ b/bitbake/lib/toaster/toastergui/templates/builds.html
@@ -46,7 +46,11 @@
46 <div class="row-fluid"> 46 <div class="row-fluid">
47 <div class="alert"> 47 <div class="alert">
48 <form class="no-results input-append" id="searchform"> 48 <form class="no-results input-append" id="searchform">
49 <input id="search" name="search" class="input-xxlarge" type="text" value="{{request.GET.search}}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %} 49 <input id="search" name="search" class="input-xxlarge" type="text" value="
50 {% if request.GET.search %}
51 {{request.GET.search}}
52 {% endif %}"/>
53 {% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %}
50 <button class="btn" type="submit" value="Search">Search</button> 54 <button class="btn" type="submit" value="Search">Search</button>
51 <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all builds</button> 55 <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all builds</button>
52 </form> 56 </form>
@@ -60,8 +64,8 @@
60 {% for build in objects %} 64 {% for build in objects %}
61 <tr class="data"> 65 <tr class="data">
62 <td class="outcome"> 66 <td class="outcome">
63 <a href="{% url "builddashboard" build.id %}">{%if build.outcome == build.SUCCEEDED%}<i class="icon-ok-sign success"></i>{%elif build.outcome == build.FAILED%}<i class="icon-minus-sign error"></i>{%else%}{%endif%}</a> &nbsp; 67 <a href="{% url "builddashboard" build.id %}">{%if build.outcome == build.SUCCEEDED%}<i class="icon-ok-sign success"></i>{%elif build.outcome == build.FAILED%}<i class="icon-minus-sign error"></i>{%else%}{%endif%}</a> &nbsp;
64 </td> 68 </td>
65 <td class="target">{% for t in build.target_set.all %} <a href="{% url "builddashboard" build.id %}"> {{t.target}} </a> <br />{% endfor %}</td> 69 <td class="target">{% for t in build.target_set.all %} <a href="{% url "builddashboard" build.id %}"> {{t.target}} </a> <br />{% endfor %}</td>
66 <td class="machine"><a href="{% url "builddashboard" build.id %}">{{build.machine}}</a></td> 70 <td class="machine"><a href="{% url "builddashboard" build.id %}">{{build.machine}}</a></td>
67 <td class="started_on"><a href="{% url "builddashboard" build.id %}">{{build.started_on|date:"d/m/y H:i"}}</a></td> 71 <td class="started_on"><a href="{% url "builddashboard" build.id %}">{{build.started_on|date:"d/m/y H:i"}}</a></td>
@@ -77,19 +81,19 @@
77 <a href="{% url "tasks" build.id %}?filter=outcome%3A4">{{exectask.count}} task{{exectask.count|pluralize}}</a> 81 <a href="{% url "tasks" build.id %}?filter=outcome%3A4">{{exectask.count}} task{{exectask.count|pluralize}}</a>
78 {%endif%} 82 {%endif%}
79 </td> 83 </td>
80 <td class="errors_no"> 84 <td class="errors.count">
81 {% if build.errors_no %} 85 {% if build.errors.count %}
82 <a class="errors_no error" href="{% url "builddashboard" build.id %}#errors">{{build.errors_no}} error{{build.errors_no|pluralize}}</a> 86 <a class="errors.count error" href="{% url "builddashboard" build.id %}#errors">{{build.errors.count}} error{{build.errors.count|pluralize}}</a>
83 {%endif%} 87 {%endif%}
84 </td> 88 </td>
85 <td class="warnings_no">{% if build.warnings_no %}<a class="warnings_no warning" href="{% url "builddashboard" build.id %}#warnings">{{build.warnings_no}} warning{{build.warnings_no|pluralize}}</a>{%endif%}</td> 89 <td class="warnings.count">{% if build.warnings.count %}<a class="warnings.count warning" href="{% url "builddashboard" build.id %}#warnings">{{build.warnings.count}} warning{{build.warnings.count|pluralize}}</a>{%endif%}</td>
86 <td class="time"><a href="{% url "buildtime" build.id %}">{{build.timespent|sectohms}}</a></td> 90 <td class="time"><a href="{% url "buildtime" build.id %}">{{build.timespent_seconds|sectohms}}</a></td>
87 <td class="output"> 91 <td class="output">
88 {% if build.outcome == build.SUCCEEDED %} 92 {% if build.outcome == build.SUCCEEDED %}
89 <a href="{%url "builddashboard" build.id%}#images">{{fstypes|get_dict_value:build.id}}</a> 93 <a href="{%url "builddashboard" build.id%}#images">{{fstypes|get_dict_value:build.id}}</a>
90 {% endif %} 94 {% endif %}
91 </td> 95 </td>
92 <td> 96 <td>
93 <a href="{% url 'project' build.project.id %}">{{build.project.name}}</a> 97 <a href="{% url 'project' build.project.id %}">{{build.project.name}}</a>
94 </td> 98 </td>
95 </tr> 99 </tr>
diff --git a/bitbake/lib/toaster/toastergui/templates/configuration.html b/bitbake/lib/toaster/toastergui/templates/configuration.html
index 2aa1ae1a49..3e489918d2 100644
--- a/bitbake/lib/toaster/toastergui/templates/configuration.html
+++ b/bitbake/lib/toaster/toastergui/templates/configuration.html
@@ -50,9 +50,6 @@
50 <th>Layer</th> 50 <th>Layer</th>
51 <th>Layer branch</th> 51 <th>Layer branch</th>
52 <th>Layer commit</th> 52 <th>Layer commit</th>
53 {% if not MANAGED or not build.project %}
54 <th>Layer directory</th>
55 {% endif %}
56 </tr> 53 </tr>
57 </thead> 54 </thead>
58 <tbody>{% for lv in build.layer_version_build.all|dictsort:"layer.name" %} 55 <tbody>{% for lv in build.layer_version_build.all|dictsort:"layer.name" %}
@@ -63,9 +60,6 @@
63 <li>{{lv.commit}}</li> </ul>"> 60 <li>{{lv.commit}}</li> </ul>">
64 {{lv.commit|truncatechars:13}} 61 {{lv.commit|truncatechars:13}}
65 </a></td> 62 </a></td>
66 {% if not MANAGED or not build.project %}
67 <td>{{lv.local_path}}</td>
68 {% endif %}
69 </tr>{% endfor %} 63 </tr>{% endfor %}
70 </tbody> 64 </tbody>
71 </table> 65 </table>
diff --git a/bitbake/lib/toaster/toastergui/templates/filtersnippet.html b/bitbake/lib/toaster/toastergui/templates/filtersnippet.html
index 56e2b21cc0..1101aa8100 100644
--- a/bitbake/lib/toaster/toastergui/templates/filtersnippet.html
+++ b/bitbake/lib/toaster/toastergui/templates/filtersnippet.html
@@ -40,8 +40,10 @@
40 {% endif %} 40 {% endif %}
41 {% endfor %} 41 {% endfor %}
42 <!-- daterange persistence --> 42 <!-- daterange persistence -->
43 {% if last_date_from and last_date_to %}
43 <input type="hidden" id="last_date_from_{{key}}" name="last_date_from" value="{{last_date_from}}"/> 44 <input type="hidden" id="last_date_from_{{key}}" name="last_date_from" value="{{last_date_from}}"/>
44 <input type="hidden" id="last_date_to_{{key}}" name="last_date_to" value="{{last_date_to}}"/> 45 <input type="hidden" id="last_date_to_{{key}}" name="last_date_to" value="{{last_date_to}}"/>
46 {% endif %}
45 </div> 47 </div>
46 <div class="modal-footer"> 48 <div class="modal-footer">
47 <button type="submit" class="btn btn-primary" data-key="{{key}}">Apply</button> 49 <button type="submit" class="btn btn-primary" data-key="{{key}}">Apply</button>
diff --git a/bitbake/lib/toaster/toastergui/templates/landing.html b/bitbake/lib/toaster/toastergui/templates/landing.html
index 4af849c2b3..15cac47b39 100644
--- a/bitbake/lib/toaster/toastergui/templates/landing.html
+++ b/bitbake/lib/toaster/toastergui/templates/landing.html
@@ -9,7 +9,7 @@
9 <div class="container-fluid"> 9 <div class="container-fluid">
10 <div class="row-fluid"> 10 <div class="row-fluid">
11 <!-- Empty - no data in database --> 11 <!-- Empty - no data in database -->
12 <div class="hero-unit span12 {%if MANAGED%}well-transparent{%endif%}"> 12 <div class="hero-unit span12 well-transparent">
13 <div class="row-fluid"> 13 <div class="row-fluid">
14 <div class="span6"> 14 <div class="span6">
15 <h1> 15 <h1>
@@ -17,7 +17,6 @@
17 </h1> 17 </h1>
18 <p>A web interface to <a href="http://www.openembedded.org">OpenEmbedded</a> and <a href="http://www.yoctoproject.org/tools-resources/projects/bitbake">BitBake</a>, the <a href="http://www.yoctoproject.org">Yocto Project</a> build system.</p> 18 <p>A web interface to <a href="http://www.openembedded.org">OpenEmbedded</a> and <a href="http://www.yoctoproject.org/tools-resources/projects/bitbake">BitBake</a>, the <a href="http://www.yoctoproject.org">Yocto Project</a> build system.</p>
19 19
20 {% if MANAGED %}
21 20
22 {% if lvs_nos %} 21 {% if lvs_nos %}
23 <p class="hero-actions"> 22 <p class="hero-actions">
@@ -37,7 +36,7 @@
37 </li> 36 </li>
38 </ul> 37 </ul>
39 </div> 38 </div>
40 {% endif %} 39 {% endif %}
41 40
42 <ul class="unstyled"> 41 <ul class="unstyled">
43 <li> 42 <li>
@@ -48,18 +47,6 @@
48 </li> 47 </li>
49 </ul> 48 </ul>
50 49
51 {% else %}
52
53 <p class="hero-actions">
54 <a class="btn btn-primary btn-large" href="http://www.yoctoproject.org/docs/latest/toaster-manual/toaster-manual.html">
55 Show me the manual
56 </a>
57 <a class="btn btn-large" href="https://wiki.yoctoproject.org/wiki/Contribute_to_Toaster">
58 I want to contribute
59 </a>
60 </p>
61
62 {% endif %}
63 </div> 50 </div>
64 <div class="span6"> 51 <div class="span6">
65 {% if MANAGED %} 52 {% if MANAGED %}
@@ -70,26 +57,6 @@
70 </div> 57 </div>
71 </div> 58 </div>
72 </div> 59 </div>
73
74 {% if not MANAGED %}
75 <!-- Empty - no data in database -->
76 <div class="page-header top-air">
77 <h1>
78 All builds
79 </h1>
80 </div>
81 <div class="alert alert-info lead">
82 Toaster has not recorded any builds yet. Go build something with
83 <a href="http://www.yoctoproject.org/docs/current/yocto-project-qs/yocto-project-qs.html#test-run">
84 Knotty
85 </a>
86 or
87 <a href="https://www.yoctoproject.org/documentation/hob-manual">
88 Hob
89 </a>
90 </div>
91 {% endif %}
92
93 </div> 60 </div>
94 61
95{% endblock %} 62{% endblock %}
diff --git a/bitbake/lib/toaster/toastergui/templates/mrb_section.html b/bitbake/lib/toaster/toastergui/templates/mrb_section.html
index 7e84e4134d..d37b694f3d 100644
--- a/bitbake/lib/toaster/toastergui/templates/mrb_section.html
+++ b/bitbake/lib/toaster/toastergui/templates/mrb_section.html
@@ -43,19 +43,35 @@
43 </div> 43 </div>
44 {%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %} 44 {%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %}
45 <div class="span2 lead"> 45 <div class="span2 lead">
46 {% if build.errors_no %} 46 {% if build.errors.count %}
47 <i class="icon-minus-sign red"></i> <a href="{%url 'builddashboard' build.pk%}#errors" class="error">{{build.errors_no}} error{{build.errors_no|pluralize}}</a> 47 <i class="icon-minus-sign red"></i> <a href="{%url 'builddashboard' build.pk%}#errors" class="error">{{build.errors.count}} error{{build.errors.count|pluralize}}</a>
48 {% endif %} 48 {% endif %}
49 </div> 49 </div>
50 <div class="span2 lead"> 50 <div class="span2 lead">
51 {% if build.warnings_no %} 51 {% if build.warnings.count %}
52 <i class="icon-warning-sign yellow"></i> <a href="{%url 'builddashboard' build.pk%}#warnings" class="warning">{{build.warnings_no}} warning{{build.warnings_no|pluralize}}</a> 52 <i class="icon-warning-sign yellow"></i> <a href="{%url 'builddashboard' build.pk%}#warnings" class="warning">{{build.warnings.count}} warning{{build.warnings.count|pluralize}}</a>
53 {% endif %} 53 {% endif %}
54 </div> 54 </div>
55 <div class="lead "> 55 <div class="lead ">
56 <span class="lead{%if not MANAGED or not build.project%} pull-right{%endif%}"> 56 <span class="lead">
57 Build time: <a href="{% url 'buildtime' build.pk %}">{{ build.timespent|sectohms }}</a> 57 Build time: <a href="{% url 'buildtime' build.pk %}">{{ build.timespent_seconds|sectohms }}</a>
58 </span> 58 </span>
59 <button class="btn
60 {% if build.outcome == build.SUCCEEDED %}
61 btn-success
62 {% elif build.outcome == build.FAILED %}
63 btn-danger
64 {% else %}
65 btn-info
66 {%endif%}
67 pull-right"
68 onclick='scheduleBuild({% url 'projectbuilds' build.project.id as bpi %}{{bpi|json}},
69 {{build.project.name|json}},
70 {% url 'project' build.project.id as bpurl %}{{bpurl|json}},
71 {{build.target_set.all|get_tasks|json}})'>
72
73 Run again
74 </button>
59 </div> 75 </div>
60 {%endif%} 76 {%endif%}
61 {%if build.outcome == build.IN_PROGRESS %} 77 {%if build.outcome == build.IN_PROGRESS %}
@@ -77,6 +93,7 @@
77function scheduleBuild(url, projectName, projectUrl, buildlist) { 93function scheduleBuild(url, projectName, projectUrl, buildlist) {
78 console.log("scheduleBuild"); 94 console.log("scheduleBuild");
79 libtoaster.startABuild(url, null, buildlist.join(" "), function(){ 95 libtoaster.startABuild(url, null, buildlist.join(" "), function(){
96 console.log("reloading page");
80 window.location.reload(); 97 window.location.reload();
81 }, null); 98 }, null);
82} 99}
diff --git a/bitbake/lib/toaster/toastergui/templates/package_detail_base.html b/bitbake/lib/toaster/toastergui/templates/package_detail_base.html
index e2ec75d157..a24bc8e436 100644
--- a/bitbake/lib/toaster/toastergui/templates/package_detail_base.html
+++ b/bitbake/lib/toaster/toastergui/templates/package_detail_base.html
@@ -136,13 +136,6 @@
136 136
137 <dd class="iscommit">{{package.recipe.layer_version.commit}}</dd> 137 <dd class="iscommit">{{package.recipe.layer_version.commit}}</dd>
138 138
139 {% if not MANAGED or not build.project %}
140 <dt>
141 Layer directory
142 <i class="icon-question-sign get-help" title="Path to the layer providing the recipe that builds this package"></i>
143 </dt>
144 <dd><code>{{package.recipe.layer_version.local_path}}</code></dd>
145 {% endif %}
146 </dl> 139 </dl>
147 </div> <!-- row4 well --> 140 </div> <!-- row4 well -->
148 {% endblock twocolumns %} 141 {% endblock twocolumns %}
diff --git a/bitbake/lib/toaster/toastergui/templates/projectbuilds.html b/bitbake/lib/toaster/toastergui/templates/projectbuilds.html
index 896c3b5af7..ac87d8c166 100644
--- a/bitbake/lib/toaster/toastergui/templates/projectbuilds.html
+++ b/bitbake/lib/toaster/toastergui/templates/projectbuilds.html
@@ -79,25 +79,20 @@
79 {% query build.task_build outcome=4 order__gt=0 as exectask%} 79 {% query build.task_build outcome=4 order__gt=0 as exectask%}
80 {% if exectask.count == 1 %} 80 {% if exectask.count == 1 %}
81 <a href="{% url "task" build.id exectask.0.id %}">{{exectask.0.recipe.name}}.{{exectask.0.task_name}}</a> 81 <a href="{% url "task" build.id exectask.0.id %}">{{exectask.0.recipe.name}}.{{exectask.0.task_name}}</a>
82 {% if MANAGED and build.project %}
83 <a href="{% url 'build_artifact' build.id "tasklogfile" exectask.0.id %}"> 82 <a href="{% url 'build_artifact' build.id "tasklogfile" exectask.0.id %}">
84 <i class="icon-download-alt" title="" data-original-title="Download task log file"></i> 83 <i class="icon-download-alt" title="" data-original-title="Download task log file"></i>
85 </a> 84 </a>
86 {% endif %}
87 {% elif exectask.count > 1%} 85 {% elif exectask.count > 1%}
88 <a href="{% url "tasks" build.id %}?filter=outcome%3A4">{{exectask.count}} task{{exectask.count|pluralize}}</a> 86 <a href="{% url "tasks" build.id %}?filter=outcome%3A4">{{exectask.count}} task{{exectask.count|pluralize}}</a>
89 {%endif%} 87 {%endif%}
90 </td> 88 </td>
91 <td class="errors_no"> 89 <td class="errors.count">
92 {% if build.errors_no %} 90 {% if build.errors.count %}
93 <a class="errors_no error" href="{% url "builddashboard" build.id %}#errors">{{build.errors_no}} error{{build.errors_no|pluralize}}</a> 91 <a class="errors.count error" href="{% url "builddashboard" build.id %}#errors">{{build.errors.count}} error{{build.errors.count|pluralize}}</a>
94 {%endif%} 92 {%endif%}
95 </td> 93 </td>
96 <td class="warnings_no">{% if build.warnings_no %}<a class="warnings_no warning" href="{% url "builddashboard" build.id %}#warnings">{{build.warnings_no}} warning{{build.warnings_no|pluralize}}</a>{%endif%}</td> 94 <td class="warnings.count">{% if build.warnings.count %}<a class="warnings.count warning" href="{% url "builddashboard" build.id %}#warnings">{{build.warnings.count}} warning{{build.warnings.count|pluralize}}</a>{%endif%}</td>
97 <td class="time"><a href="{% url "buildtime" build.id %}">{{build.timespent|sectohms}}</a></td> 95 <td class="time"><a href="{% url "buildtime" build.id %}">{{build.timespent_seconds|sectohms}}</a></td>
98 {% if not MANAGED or not build.project %}
99 <td class="log">{{build.cooker_log_path}}</td>
100 {% endif %}
101 <td class="output"> 96 <td class="output">
102 {% if build.outcome == build.SUCCEEDED %} 97 {% if build.outcome == build.SUCCEEDED %}
103 <a href="{%url "builddashboard" build.id%}#images">{{fstypes|get_dict_value:build.id}}</a> 98 <a href="{%url "builddashboard" build.id%}#images">{{fstypes|get_dict_value:build.id}}</a>
@@ -113,23 +108,23 @@
113 <tr class="data"> 108 <tr class="data">
114 <td class="outcome">{% if br.state == br.REQ_FAILED %}<i class="icon-minus-sign error"></i>{%else%}FIXME_build_request_state{%endif%}</td> 109 <td class="outcome">{% if br.state == br.REQ_FAILED %}<i class="icon-minus-sign error"></i>{%else%}FIXME_build_request_state{%endif%}</td>
115 <td class="target"> 110 <td class="target">
116 <a href="{% url "buildrequestdetails" br.project.id br.id %}"><span data-toggle="tooltip" {%if br.brtarget_set.all.count > 1%}title="Targets: {%for target in br.brtarget_set.all%}{{target.target}} {%endfor%}"{%endif%}>{{br.brtarget_set.all.0.target}} {%if br.brtarget_set.all.count > 1%}(+ {{br.brtarget_set.all.count|add:"-1"}}){%endif%} </span></a> 111 <a href="{% url "builddashboard" br.id %}"><span data-toggle="tooltip" {%if br.brtarget_set.all.count > 1%}title="Targets: {%for target in br.brtarget_set.all%}{{target.target}} {%endfor%}"{%endif%}>{{br.brtarget_set.all.0.target}} {%if br.brtarget_set.all.count > 1%}(+ {{br.brtarget_set.all.count|add:"-1"}}){%endif%} </span></a>
117 </td> 112 </td>
118 <td class="machine"> 113 <td class="machine">
119 <a href="{% url "buildrequestdetails" br.project.id br.id %}">{{br.machine}}</a> 114 <a href="{% url "builddashboard" br.id %}">{{br.machine}}</a>
120 </td> 115 </td>
121 <td class="started_on"> 116 <td class="started_on">
122 <a href="{% url "buildrequestdetails" br.project.id br.id %}">{{br.created|date:"d/m/y H:i"}}</a> 117 <a href="{% url "builddashboard" br.id %}">{{br.created|date:"d/m/y H:i"}}</a>
123 </td> 118 </td>
124 <td class="completed_on"> 119 <td class="completed_on">
125 <a href="{% url "buildrequestdetails" br.project.id br.id %}">{{br.updated|date:"d/m/y H:i"}}</a> 120 <a href="{% url "builddashboard" br.id %}">{{br.updated|date:"d/m/y H:i"}}</a>
126 </td> 121 </td>
127 <td class="failed_tasks error"> 122 <td class="failed_tasks error">
128 </td> 123 </td>
129 <td class="errors_no"> 124 <td class="errors.count">
130 <a class="errors_no error" href="{% url "buildrequestdetails" br.project.id br.id %}#errors">{{br.brerror_set.all.count}} error{{br.brerror_set.all.count|pluralize}}</a> 125 <a class="errors.count error" href="{% url "builddashboard" br.id %}#errors">{{br.brerror_set.all.count}} error{{br.brerror_set.all.count|pluralize}}</a>
131 </td> 126 </td>
132 <td class="warnings_no"> 127 <td class="warnings.count">
133 </td> 128 </td>
134 <td class="time"> 129 <td class="time">
135 {{br.timespent.total_seconds|sectohms}} 130 {{br.timespent.total_seconds|sectohms}}
diff --git a/bitbake/lib/toaster/toastergui/templates/projects.html b/bitbake/lib/toaster/toastergui/templates/projects.html
index 9c4346c45a..e6519530ef 100644
--- a/bitbake/lib/toaster/toastergui/templates/projects.html
+++ b/bitbake/lib/toaster/toastergui/templates/projects.html
@@ -26,7 +26,10 @@
26 <div class="row-fluid"> 26 <div class="row-fluid">
27 <div class="alert"> 27 <div class="alert">
28 <form class="no-results input-append" id="searchform"> 28 <form class="no-results input-append" id="searchform">
29 <input id="search" name="search" class="input-xxlarge" type="text" value="{{request.GET.search}}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %} 29 <input id="search" name="search" class="input-xxlarge" type="text" value="
30 {% if request.GET.search %}
31 {{request.GET.search}}
32 {% endif %}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %}
30 <button class="btn" type="submit" value="Search">Search</button> 33 <button class="btn" type="submit" value="Search">Search</button>
31 <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all projects</button> 34 <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all projects</button>
32 </form> 35 </form>
@@ -58,8 +61,8 @@
58 <td><a href="{% url 'projectbuilds' o.id %}">{{o.get_number_of_builds}}</a></td> 61 <td><a href="{% url 'projectbuilds' o.id %}">{{o.get_number_of_builds}}</a></td>
59 <td class="loutcome"><a href="{% url "builddashboard" o.get_last_build_id %}">{%if o.get_last_outcome == build_SUCCEEDED%}<i class="icon-ok-sign success"></i>{%elif o.get_last_outcome == build_FAILED%}<i class="icon-minus-sign error"></i>{%else%}{%endif%}</a></td> 62 <td class="loutcome"><a href="{% url "builddashboard" o.get_last_build_id %}">{%if o.get_last_outcome == build_SUCCEEDED%}<i class="icon-ok-sign success"></i>{%elif o.get_last_outcome == build_FAILED%}<i class="icon-minus-sign error"></i>{%else%}{%endif%}</a></td>
60 <td class="ltarget"><a href="{% url "builddashboard" o.get_last_build_id %}">{{o.get_last_target}} </a></td> 63 <td class="ltarget"><a href="{% url "builddashboard" o.get_last_build_id %}">{{o.get_last_target}} </a></td>
61 <td class="lerrors">{% if o.get_last_errors %}<a class="errors_no error" href="{% url "builddashboard" o.get_last_build_id %}#errors">{{o.get_last_errors}} error{{o.get_last_errors|pluralize}}</a>{%endif%}</td> 64 <td class="lerrors">{% if o.get_last_errors %}<a class="errors.count error" href="{% url "builddashboard" o.get_last_build_id %}#errors">{{o.get_last_errors}} error{{o.get_last_errors|pluralize}}</a>{%endif%}</td>
62 <td class="lwarnings">{% if o.get_last_warnings %}<a class="warnings_no warning" href="{% url "builddashboard" o.get_last_build_id %}#warnings">{{o.get_last_warnings}} warning{{o.get_last_warnings|pluralize}}</a>{%endif%}</td> 65 <td class="lwarnings">{% if o.get_last_warnings %}<a class="warnings.count warning" href="{% url "builddashboard" o.get_last_build_id %}#warnings">{{o.get_last_warnings}} warning{{o.get_last_warnings|pluralize}}</a>{%endif%}</td>
63 <td class="limagefiles"> 66 <td class="limagefiles">
64 {% if o.get_last_outcome == build_SUCCEEDED %} 67 {% if o.get_last_outcome == build_SUCCEEDED %}
65 <a href="{%url "builddashboard" o.get_last_build_id %}#images">{{fstypes|get_dict_value:o.id}}</a> 68 <a href="{%url "builddashboard" o.get_last_build_id %}#images">{{fstypes|get_dict_value:o.id}}</a>
diff --git a/bitbake/lib/toaster/toastergui/templates/recipe.html b/bitbake/lib/toaster/toastergui/templates/recipe.html
index dd8753d7fc..b5e4192d6b 100644
--- a/bitbake/lib/toaster/toastergui/templates/recipe.html
+++ b/bitbake/lib/toaster/toastergui/templates/recipe.html
@@ -53,13 +53,6 @@
53 </dt> 53 </dt>
54 <dd>{{layer.name}}</dd> 54 <dd>{{layer.name}}</dd>
55 55
56 {% if not MANAGED or not build.project %}
57 <dt>
58 <i class="icon-question-sign get-help" title="Path to the layer providing the recipe"></i>
59 Layer directory
60 </dt>
61 <dd><code>{{object.layer_version.local_path}}</code></dd>
62 {% endif %}
63 <dt> 56 <dt>
64 <i class="icon-question-sign get-help" title="Path to the recipe .bb file"></i> 57 <i class="icon-question-sign get-help" title="Path to the recipe .bb file"></i>
65 Recipe file 58 Recipe file
@@ -126,7 +119,7 @@
126 119
127 <td> 120 <td>
128 <a {{ task|task_color }} href="{% url "task" build.pk task.pk %}">{{task.get_outcome_display}} </a> 121 <a {{ task|task_color }} href="{% url "task" build.pk task.pk %}">{{task.get_outcome_display}} </a>
129 {% if MANAGED and build.project and task.outcome = task.OUTCOME_FAILED %} 122 {% if task.outcome = task.OUTCOME_FAILED %}
130 <a href="{% url 'build_artifact' build.pk "tasklogfile" task.pk %}"> 123 <a href="{% url 'build_artifact' build.pk "tasklogfile" task.pk %}">
131 <i class="icon-download-alt" title="Download task log file"></i> 124 <i class="icon-download-alt" title="Download task log file"></i>
132 </a> 125 </a>
diff --git a/bitbake/lib/toaster/toastergui/templates/recipes.html b/bitbake/lib/toaster/toastergui/templates/recipes.html
index 8d4494e7ef..5cdac437c4 100644
--- a/bitbake/lib/toaster/toastergui/templates/recipes.html
+++ b/bitbake/lib/toaster/toastergui/templates/recipes.html
@@ -28,7 +28,7 @@
28 <div class="row-fluid"> 28 <div class="row-fluid">
29 <div class="alert"> 29 <div class="alert">
30 <form class="no-results input-append" id="searchform"> 30 <form class="no-results input-append" id="searchform">
31 <input id="search" name="search" class="input-xxlarge" type="text" value="{{request.GET.search}}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %} 31 <input id="search" name="search" class="input-xxlarge" type="text" value="{%if request.GET.search%}{{request.GET.search}}{%endif%}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %}
32 <button class="btn" type="submit" value="Search">Search</button> 32 <button class="btn" type="submit" value="Search">Search</button>
33 <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all recipes</button> 33 <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all recipes</button>
34 </form> 34 </form>
@@ -102,11 +102,6 @@
102 {{recipe.layer_version.commit|truncatechars:13}} 102 {{recipe.layer_version.commit|truncatechars:13}}
103 </a> 103 </a>
104 </td> 104 </td>
105
106 {% if not MANAGED or not build.project %}
107 <!-- Layer directory -->
108 <td class="layer_version__local_path">{{recipe.layer_version.local_path}}</td>
109 {% endif %}
110 </tr> 105 </tr>
111 106
112 {% endfor %} 107 {% endfor %}
diff --git a/bitbake/lib/toaster/toastergui/templates/runagain.html b/bitbake/lib/toaster/toastergui/templates/runagain.html
deleted file mode 100644
index b4ba5fbf15..0000000000
--- a/bitbake/lib/toaster/toastergui/templates/runagain.html
+++ /dev/null
@@ -1,7 +0,0 @@
1{% load projecttags %}
2onclick='scheduleBuild(
3 {% url 'projectbuilds' buildrequest.project.id as bpi %}{{bpi|json}},
4 {{buildrequest.project.name|json}},
5 {% url 'project' buildrequest.project.id as bpurl %}{{bpurl|json}},
6 {{buildrequest.brtarget_set.all|get_tasks|json}})
7'>Run again
diff --git a/bitbake/lib/toaster/toastergui/templates/target.html b/bitbake/lib/toaster/toastergui/templates/target.html
index e7febaf22a..fa59f4eeba 100644
--- a/bitbake/lib/toaster/toastergui/templates/target.html
+++ b/bitbake/lib/toaster/toastergui/templates/target.html
@@ -152,11 +152,6 @@
152 {{package.recipe.layer_version.commit|truncatechars:13}} 152 {{package.recipe.layer_version.commit|truncatechars:13}}
153 </a> 153 </a>
154 </td> 154 </td>
155 {% if not MANAGED or not build.project %}
156 <td class="layer_directory">
157 {{ package.recipe.layer_version.local_path }}
158 </td>
159 {% endif %}
160 </tr> 155 </tr>
161 {% endfor %} 156 {% endfor %}
162 157
diff --git a/bitbake/lib/toaster/toastergui/templates/task.html b/bitbake/lib/toaster/toastergui/templates/task.html
index 6e06ddfa31..635098a024 100644
--- a/bitbake/lib/toaster/toastergui/templates/task.html
+++ b/bitbake/lib/toaster/toastergui/templates/task.html
@@ -23,18 +23,7 @@
23{%if task.task_executed %} 23{%if task.task_executed %}
24 {# executed tasks outcome #} 24 {# executed tasks outcome #}
25 {% if task.logfile %} 25 {% if task.logfile %}
26 {% if MANAGED and build.project %}
27 <a class="btn btn-large" href="{% url 'build_artifact' build.id "tasklogfile" task.pk %}" style="margin:15px;">Download task log</a> 26 <a class="btn btn-large" href="{% url 'build_artifact' build.id "tasklogfile" task.pk %}" style="margin:15px;">Download task log</a>
28 {% else %}
29 <dl class="dl-horizontal">
30 <dt>
31 <i class="icon-question-sign get-help" title="Path the task log file"></i> Log file
32 </dt>
33 <dd>
34 <code>{{task.logfile}}</code>
35 </dd>
36 </dl>
37 {% endif %}
38 {% endif %} 27 {% endif %}
39 {# show stack trace for failed task #} 28 {# show stack trace for failed task #}
40 {% if task.outcome == task.OUTCOME_FAILED and log_head %} 29 {% if task.outcome == task.OUTCOME_FAILED and log_head %}
@@ -130,22 +119,12 @@
130 </dd> 119 </dd>
131 </dl> 120 </dl>
132 {%elif task.outcome == task.OUTCOME_CACHED%} 121 {%elif task.outcome == task.OUTCOME_CACHED%}
133 {% if MANAGED and build.project %}
134 {% for t in task.get_related_setscene %} 122 {% for t in task.get_related_setscene %}
135 {% if forloop.last %} 123 {% if forloop.last %}
136 <a class="btn btn-large" href="{% url 'build_artifact' build.id "tasklogfile" t.pk %}" style="margin:15px;">Download task log</a> 124 <a class="btn btn-large" href="{% url 'build_artifact' build.id "tasklogfile" t.pk %}" style="margin:15px;">Download task log</a>
137 {% endif %} 125 {% endif %}
138 {% endfor %} 126 {% endfor %}
139 {% else %} 127
140 <dl class="dl-horizontal">
141 <dt>
142 <i class="icon-question-sign get-help" title="Path the task log file"></i> Log file
143 </dt>
144 <dd>
145 <code>{% for t in task.get_related_setscene %} {{t.logfile}} {% endfor %}</code>
146 </dd>
147 </dl>
148 {% endif %}
149 {%elif task.outcome == task.OUTCOME_EMPTY%} 128 {%elif task.outcome == task.OUTCOME_EMPTY%}
150 <div class="alert alert-info details"> 129 <div class="alert alert-info details">
151 This task is empty because it has the <code>noexec</code> flag set to <code>1</code>, or the task function is empty 130 This task is empty because it has the <code>noexec</code> flag set to <code>1</code>, or the task function is empty
@@ -200,20 +179,7 @@
200 <strong>Failed</strong> to restore output from sstate cache. The file was found but could not be unpacked. 179 <strong>Failed</strong> to restore output from sstate cache. The file was found but could not be unpacked.
201 </div> 180 </div>
202 <dl class="dl-horizontal"> 181 <dl class="dl-horizontal">
203 {% if MANAGED and build.project %}
204 <a href="{% url 'build_artifact' build.id "tasklogfile" task.pk %}" style="margin:15px;">Download log</a> 182 <a href="{% url 'build_artifact' build.id "tasklogfile" task.pk %}" style="margin:15px;">Download log</a>
205 {% else %}
206 <dt>
207 <i class="icon-question-sign get-help" title="Path to the cache attempt log file"></i>
208 Log file
209 </dt>
210 <dd><code>{{task.logfile}}</code></dd>
211 <dt>
212 <i class="icon-question-sign get-help" title="How long it took the cache attempt to finish in seconds"></i>
213 Time (secs)
214 </dt>
215 <dd>{{task.elapsed_time|format_none_and_zero}}</dd>
216 {% endif %}
217 </dl> 183 </dl>
218 <div class="alert alert-info"> 184 <div class="alert alert-info">
219 Running the real task instead. 185 Running the real task instead.
diff --git a/bitbake/lib/toaster/toastergui/templates/tasks.html b/bitbake/lib/toaster/toastergui/templates/tasks.html
index 32c0552360..b18b5c7c46 100644
--- a/bitbake/lib/toaster/toastergui/templates/tasks.html
+++ b/bitbake/lib/toaster/toastergui/templates/tasks.html
@@ -93,7 +93,7 @@
93 </td> 93 </td>
94 <td class="outcome"> 94 <td class="outcome">
95 <a href="{%url "task" build.pk task.pk%}">{{task.get_outcome_display}} </a> 95 <a href="{%url "task" build.pk task.pk%}">{{task.get_outcome_display}} </a>
96 {% if MANAGED and build.project and task.outcome = task.OUTCOME_FAILED %} 96 {% if task.outcome = task.OUTCOME_FAILED %}
97 <a href="{% url 'build_artifact' build.pk "tasklogfile" task.pk %}"> 97 <a href="{% url 'build_artifact' build.pk "tasklogfile" task.pk %}">
98 <i class="icon-download-alt" title="Download task log file"></i> 98 <i class="icon-download-alt" title="Download task log file"></i>
99 </a> 99 </a>
@@ -113,11 +113,6 @@
113 {{task.disk_io|format_none_and_zero}} 113 {{task.disk_io|format_none_and_zero}}
114 </td> 114 </td>
115 115
116 {% if not MANAGED or not build.project %}
117 <td class="task_log">
118 {{task.logfile}}
119 </td>
120 {% endif %}
121 </tr> 116 </tr>
122 {% endfor %} 117 {% endfor %}
123 118
diff --git a/bitbake/lib/toaster/toastergui/urls.py b/bitbake/lib/toaster/toastergui/urls.py
index 681f06787a..feb15139fb 100644
--- a/bitbake/lib/toaster/toastergui/urls.py
+++ b/bitbake/lib/toaster/toastergui/urls.py
@@ -131,9 +131,6 @@ urlpatterns = patterns('toastergui.views',
131 url(r'^xhr_importlayer/$', 'xhr_importlayer', name='xhr_importlayer'), 131 url(r'^xhr_importlayer/$', 'xhr_importlayer', name='xhr_importlayer'),
132 url(r'^xhr_updatelayer/$', 'xhr_updatelayer', name='xhr_updatelayer'), 132 url(r'^xhr_updatelayer/$', 'xhr_updatelayer', name='xhr_updatelayer'),
133 133
134 # dashboard for failed build requests
135 url(r'^project/(?P<pid>\d+)/buildrequest/(?P<bid>\d+)$', 'buildrequestdetails', name='buildrequestdetails'),
136
137 # default redirection 134 # default redirection
138 url(r'^$', RedirectView.as_view( url= 'landing')), 135 url(r'^$', RedirectView.as_view( url= 'landing')),
139) 136)
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py
index 00b1387d63..8c6f9fa84f 100755
--- a/bitbake/lib/toaster/toastergui/views.py
+++ b/bitbake/lib/toaster/toastergui/views.py
@@ -21,7 +21,7 @@
21 21
22import operator,re 22import operator,re
23 23
24from django.db.models import Q, Sum, Count, Max 24from django.db.models import F, Q, Sum, Count, Max
25from django.db import IntegrityError 25from django.db import IntegrityError
26from django.shortcuts import render, redirect 26from django.shortcuts import render, redirect
27from orm.models import Build, Target, Task, Layer, Layer_Version, Recipe, LogMessage, Variable 27from orm.models import Build, Target, Task, Layer, Layer_Version, Recipe, LogMessage, Variable
@@ -81,15 +81,15 @@ def _project_recent_build_list(prj):
81 "errors": map(lambda y: {"type": y.lineno, "msg": y.message, "tb": y.pathname}, (x.logmessage_set.filter(level__gte=LogMessage.WARNING)|x.logmessage_set.filter(level=LogMessage.EXCEPTION))), 81 "errors": map(lambda y: {"type": y.lineno, "msg": y.message, "tb": y.pathname}, (x.logmessage_set.filter(level__gte=LogMessage.WARNING)|x.logmessage_set.filter(level=LogMessage.EXCEPTION))),
82 "updated": x.completed_on.strftime('%s')+"000", 82 "updated": x.completed_on.strftime('%s')+"000",
83 "command_time": (x.completed_on - x.started_on).total_seconds(), 83 "command_time": (x.completed_on - x.started_on).total_seconds(),
84 "br_page_url": reverse('buildrequestdetails', args=(x.project.id, x.pk) ), 84 "br_page_url": reverse('builddashboard', args=(x.pk,) ),
85 "build" : map( lambda y: {"id": y.pk, 85 "build" : map( lambda y: {"id": y.pk,
86 "status": y.get_outcome_display(), 86 "status": y.get_outcome_display(),
87 "completed_on" : y.completed_on.strftime('%s')+"000", 87 "completed_on" : y.completed_on.strftime('%s')+"000",
88 "build_time" : (y.completed_on - y.started_on).total_seconds(), 88 "build_time" : (y.completed_on - y.started_on).total_seconds(),
89 "build_page_url" : reverse('builddashboard', args=(y.pk,)), 89 "build_page_url" : reverse('builddashboard', args=(y.pk,)),
90 'build_time_page_url': reverse('buildtime', args=(y.pk,)), 90 'build_time_page_url': reverse('buildtime', args=(y.pk,)),
91 "errors": y.errors_no, 91 "errors": y.errors.count(),
92 "warnings": y.warnings_no, 92 "warnings": y.warnings.count(),
93 "completeper": y.completeper() if y.outcome == Build.IN_PROGRESS else "0", 93 "completeper": y.completeper() if y.outcome == Build.IN_PROGRESS else "0",
94 "eta": y.eta().strftime('%s')+"000" if y.outcome == Build.IN_PROGRESS else "0", 94 "eta": y.eta().strftime('%s')+"000" if y.outcome == Build.IN_PROGRESS else "0",
95 }, [x]), 95 }, [x]),
@@ -1906,7 +1906,7 @@ if True:
1906 (filter_string, search_term, ordering_string) = _search_tuple(request, Build) 1906 (filter_string, search_term, ordering_string) = _search_tuple(request, Build)
1907 # post-process any date range filters 1907 # post-process any date range filters
1908 filter_string,daterange_selected = _modify_date_range_filter(filter_string) 1908 filter_string,daterange_selected = _modify_date_range_filter(filter_string)
1909 queryset_all = queryset_all.select_related("project") 1909 queryset_all = queryset_all.select_related("project").annotate(errors_no = Count('logmessage', only=Q(logmessage__level=LogMessage.ERROR)|Q(logmessage__level=LogMessage.EXCEPTION))).annotate(warnings_no = Count('logmessage', only=Q(logmessage__level=LogMessage.WARNING))).extra(select={'timespent':'completed_on - started_on'})
1910 queryset_with_search = _get_queryset(Build, queryset_all, None, search_term, ordering_string, '-completed_on') 1910 queryset_with_search = _get_queryset(Build, queryset_all, None, search_term, ordering_string, '-completed_on')
1911 queryset = _get_queryset(Build, queryset_all, filter_string, search_term, ordering_string, '-completed_on') 1911 queryset = _get_queryset(Build, queryset_all, filter_string, search_term, ordering_string, '-completed_on')
1912 1912
@@ -2841,10 +2841,3 @@ if True:
2841 2841
2842 _set_parameters_values(pagesize, orderby, request) 2842 _set_parameters_values(pagesize, orderby, request)
2843 return context 2843 return context
2844
2845 @_template_renderer("buildrequestdetails.html")
2846 def buildrequestdetails(request, pid, bid):
2847 context = {
2848 'buildrequest' : Build.objects.get(pk = bid, project_id = pid).buildrequest
2849 }
2850 return context