diff options
Diffstat (limited to 'bitbake/lib/toaster/bldcontrol')
4 files changed, 133 insertions, 6 deletions
diff --git a/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py b/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py index 75674ccbf1..577e765f11 100644 --- a/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py +++ b/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py | |||
@@ -200,7 +200,7 @@ class LocalhostBEController(BuildEnvironmentController): | |||
200 | localdirpath = os.path.join(localdirname, dirpath) | 200 | localdirpath = os.path.join(localdirname, dirpath) |
201 | logger.debug("localhostbecontroller: localdirpath expects '%s'" % localdirpath) | 201 | logger.debug("localhostbecontroller: localdirpath expects '%s'" % localdirpath) |
202 | if not os.path.exists(localdirpath): | 202 | if not os.path.exists(localdirpath): |
203 | raise BuildSetupException("Cannot find layer git path '%s' in checked out repository '%s:%s'. Aborting." % (localdirpath, giturl, commit)) | 203 | raise BuildSetupException("Cannot find layer git path '%s' in checked out repository '%s:%s'. Exiting." % (localdirpath, giturl, commit)) |
204 | 204 | ||
205 | if name != "bitbake": | 205 | if name != "bitbake": |
206 | layerlist.append("%03d:%s" % (index,localdirpath.rstrip("/"))) | 206 | layerlist.append("%03d:%s" % (index,localdirpath.rstrip("/"))) |
@@ -467,7 +467,7 @@ class LocalhostBEController(BuildEnvironmentController): | |||
467 | logger.debug("localhostbecontroller: waiting for bblock content to appear") | 467 | logger.debug("localhostbecontroller: waiting for bblock content to appear") |
468 | time.sleep(1) | 468 | time.sleep(1) |
469 | else: | 469 | else: |
470 | raise BuildSetupException("Cannot find bitbake server lock file '%s'. Aborting." % bblock) | 470 | raise BuildSetupException("Cannot find bitbake server lock file '%s'. Exiting." % bblock) |
471 | 471 | ||
472 | with open(bblock) as fplock: | 472 | with open(bblock) as fplock: |
473 | for line in fplock: | 473 | for line in fplock: |
diff --git a/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py b/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py index 19f659ec41..834e32b36f 100644 --- a/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py +++ b/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py | |||
@@ -180,6 +180,77 @@ class Command(BaseCommand): | |||
180 | except Exception as e: | 180 | except Exception as e: |
181 | logger.warning("runbuilds: schedule exception %s" % str(e)) | 181 | logger.warning("runbuilds: schedule exception %s" % str(e)) |
182 | 182 | ||
183 | # Test to see if a build pre-maturely died due to a bitbake crash | ||
184 | def check_dead_builds(self): | ||
185 | do_cleanup = False | ||
186 | try: | ||
187 | for br in BuildRequest.objects.filter(state=BuildRequest.REQ_INPROGRESS): | ||
188 | # Get the build directory | ||
189 | if br.project.builddir: | ||
190 | builddir = br.project.builddir | ||
191 | else: | ||
192 | builddir = '%s-toaster-%d' % (br.environment.builddir,br.project.id) | ||
193 | # Check log to see if there is a recent traceback | ||
194 | toaster_ui_log = os.path.join(builddir, 'toaster_ui.log') | ||
195 | test_file = os.path.join(builddir, '._toaster_check.txt') | ||
196 | os.system("tail -n 50 %s > %s" % (os.path.join(builddir, 'toaster_ui.log'),test_file)) | ||
197 | traceback_text = '' | ||
198 | is_traceback = False | ||
199 | with open(test_file,'r') as test_file_fd: | ||
200 | test_file_tail = test_file_fd.readlines() | ||
201 | for line in test_file_tail: | ||
202 | if line.startswith('Traceback (most recent call last):'): | ||
203 | traceback_text = line | ||
204 | is_traceback = True | ||
205 | elif line.startswith('NOTE: ToasterUI waiting for events'): | ||
206 | # Ignore any traceback before new build start | ||
207 | traceback_text = '' | ||
208 | is_traceback = False | ||
209 | elif line.startswith('Note: Toaster traceback auto-stop'): | ||
210 | # Ignore any traceback before this previous traceback catch | ||
211 | traceback_text = '' | ||
212 | is_traceback = False | ||
213 | elif is_traceback: | ||
214 | traceback_text += line | ||
215 | # Test the results | ||
216 | is_stop = False | ||
217 | if is_traceback: | ||
218 | # Found a traceback | ||
219 | errtype = 'Bitbake crash' | ||
220 | errmsg = 'Bitbake crash\n' + traceback_text | ||
221 | state = BuildRequest.REQ_FAILED | ||
222 | # Clean up bitbake files | ||
223 | bitbake_lock = os.path.join(builddir, 'bitbake.lock') | ||
224 | if os.path.isfile(bitbake_lock): | ||
225 | os.remove(bitbake_lock) | ||
226 | bitbake_sock = os.path.join(builddir, 'bitbake.sock') | ||
227 | if os.path.isfile(bitbake_sock): | ||
228 | os.remove(bitbake_sock) | ||
229 | if os.path.isfile(test_file): | ||
230 | os.remove(test_file) | ||
231 | # Add note to ignore this traceback on next check | ||
232 | os.system('echo "Note: Toaster traceback auto-stop" >> %s' % toaster_ui_log) | ||
233 | is_stop = True | ||
234 | # Add more tests here | ||
235 | #elif ... | ||
236 | # Stop the build request? | ||
237 | if is_stop: | ||
238 | brerror = BRError( | ||
239 | req = br, | ||
240 | errtype = errtype, | ||
241 | errmsg = errmsg, | ||
242 | traceback = traceback_text, | ||
243 | ) | ||
244 | brerror.save() | ||
245 | br.state = state | ||
246 | br.save() | ||
247 | do_cleanup = True | ||
248 | # Do cleanup | ||
249 | if do_cleanup: | ||
250 | self.cleanup() | ||
251 | except Exception as e: | ||
252 | logger.error("runbuilds: Error in check_dead_builds %s" % e) | ||
253 | |||
183 | def handle(self, **options): | 254 | def handle(self, **options): |
184 | pidfile_path = os.path.join(os.environ.get("BUILDDIR", "."), | 255 | pidfile_path = os.path.join(os.environ.get("BUILDDIR", "."), |
185 | ".runbuilds.pid") | 256 | ".runbuilds.pid") |
@@ -187,10 +258,18 @@ class Command(BaseCommand): | |||
187 | with open(pidfile_path, 'w') as pidfile: | 258 | with open(pidfile_path, 'w') as pidfile: |
188 | pidfile.write("%s" % os.getpid()) | 259 | pidfile.write("%s" % os.getpid()) |
189 | 260 | ||
261 | # Clean up any stale/failed builds from previous Toaster run | ||
190 | self.runbuild() | 262 | self.runbuild() |
191 | 263 | ||
192 | signal.signal(signal.SIGUSR1, lambda sig, frame: None) | 264 | signal.signal(signal.SIGUSR1, lambda sig, frame: None) |
193 | 265 | ||
194 | while True: | 266 | while True: |
195 | signal.pause() | 267 | sigset = signal.sigtimedwait([signal.SIGUSR1], 5) |
196 | self.runbuild() | 268 | if sigset: |
269 | for sig in sigset: | ||
270 | # Consume each captured pending event | ||
271 | self.runbuild() | ||
272 | else: | ||
273 | # Check for build exceptions | ||
274 | self.check_dead_builds() | ||
275 | |||
diff --git a/bitbake/lib/toaster/bldcontrol/migrations/0008_models_bigautofield.py b/bitbake/lib/toaster/bldcontrol/migrations/0008_models_bigautofield.py new file mode 100644 index 0000000000..45b477d02c --- /dev/null +++ b/bitbake/lib/toaster/bldcontrol/migrations/0008_models_bigautofield.py | |||
@@ -0,0 +1,48 @@ | |||
1 | # Generated by Django 3.2.12 on 2022-03-06 03:28 | ||
2 | |||
3 | from django.db import migrations, models | ||
4 | |||
5 | |||
6 | class Migration(migrations.Migration): | ||
7 | |||
8 | dependencies = [ | ||
9 | ('bldcontrol', '0007_brlayers_optional_gitinfo'), | ||
10 | ] | ||
11 | |||
12 | operations = [ | ||
13 | migrations.AlterField( | ||
14 | model_name='brbitbake', | ||
15 | name='id', | ||
16 | field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), | ||
17 | ), | ||
18 | migrations.AlterField( | ||
19 | model_name='brerror', | ||
20 | name='id', | ||
21 | field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), | ||
22 | ), | ||
23 | migrations.AlterField( | ||
24 | model_name='brlayer', | ||
25 | name='id', | ||
26 | field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), | ||
27 | ), | ||
28 | migrations.AlterField( | ||
29 | model_name='brtarget', | ||
30 | name='id', | ||
31 | field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), | ||
32 | ), | ||
33 | migrations.AlterField( | ||
34 | model_name='brvariable', | ||
35 | name='id', | ||
36 | field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), | ||
37 | ), | ||
38 | migrations.AlterField( | ||
39 | model_name='buildenvironment', | ||
40 | name='id', | ||
41 | field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), | ||
42 | ), | ||
43 | migrations.AlterField( | ||
44 | model_name='buildrequest', | ||
45 | name='id', | ||
46 | field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), | ||
47 | ), | ||
48 | ] | ||
diff --git a/bitbake/lib/toaster/bldcontrol/models.py b/bitbake/lib/toaster/bldcontrol/models.py index c2f302da24..42750e7180 100644 --- a/bitbake/lib/toaster/bldcontrol/models.py +++ b/bitbake/lib/toaster/bldcontrol/models.py | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | from __future__ import unicode_literals | 5 | from __future__ import unicode_literals |
6 | from django.db import models | 6 | from django.db import models |
7 | from django.utils.encoding import force_text | 7 | from django.utils.encoding import force_str |
8 | from orm.models import Project, Build, Layer_Version | 8 | from orm.models import Project, Build, Layer_Version |
9 | 9 | ||
10 | import logging | 10 | import logging |
@@ -124,7 +124,7 @@ class BuildRequest(models.Model): | |||
124 | return self.brvariable_set.get(name="MACHINE").value | 124 | return self.brvariable_set.get(name="MACHINE").value |
125 | 125 | ||
126 | def __str__(self): | 126 | def __str__(self): |
127 | return force_text('%s %s' % (self.project, self.get_state_display())) | 127 | return force_str('%s %s' % (self.project, self.get_state_display())) |
128 | 128 | ||
129 | # These tables specify the settings for running an actual build. | 129 | # These tables specify the settings for running an actual build. |
130 | # They MUST be kept in sync with the tables in orm.models.Project* | 130 | # They MUST be kept in sync with the tables in orm.models.Project* |