diff options
Diffstat (limited to 'bitbake/lib/toaster/bldcontrol/localhostbecontroller.py')
-rw-r--r-- | bitbake/lib/toaster/bldcontrol/localhostbecontroller.py | 172 |
1 files changed, 139 insertions, 33 deletions
diff --git a/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py b/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py index 16c7c80441..6bdd743b8b 100644 --- a/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py +++ b/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py | |||
@@ -27,8 +27,9 @@ import shutil | |||
27 | import time | 27 | import time |
28 | from django.db import transaction | 28 | from django.db import transaction |
29 | from django.db.models import Q | 29 | from django.db.models import Q |
30 | from bldcontrol.models import BuildEnvironment, BRLayer, BRVariable, BRTarget, BRBitbake | 30 | from bldcontrol.models import BuildEnvironment, BuildRequest, BRLayer, BRVariable, BRTarget, BRBitbake, Build |
31 | from orm.models import CustomImageRecipe, Layer, Layer_Version, ProjectLayer, ToasterSetting | 31 | from orm.models import CustomImageRecipe, Layer, Layer_Version, Project, ProjectLayer, ToasterSetting |
32 | from orm.models import signal_runbuilds | ||
32 | import subprocess | 33 | import subprocess |
33 | 34 | ||
34 | from toastermain import settings | 35 | from toastermain import settings |
@@ -38,6 +39,8 @@ from bldcontrol.bbcontroller import BuildEnvironmentController, ShellCmdExceptio | |||
38 | import logging | 39 | import logging |
39 | logger = logging.getLogger("toaster") | 40 | logger = logging.getLogger("toaster") |
40 | 41 | ||
42 | install_dir = os.environ.get('TOASTER_DIR') | ||
43 | |||
41 | from pprint import pprint, pformat | 44 | from pprint import pprint, pformat |
42 | 45 | ||
43 | class LocalhostBEController(BuildEnvironmentController): | 46 | class LocalhostBEController(BuildEnvironmentController): |
@@ -87,10 +90,10 @@ class LocalhostBEController(BuildEnvironmentController): | |||
87 | #logger.debug("localhostbecontroller: using HEAD checkout in %s" % local_checkout_path) | 90 | #logger.debug("localhostbecontroller: using HEAD checkout in %s" % local_checkout_path) |
88 | return local_checkout_path | 91 | return local_checkout_path |
89 | 92 | ||
90 | 93 | def setCloneStatus(self,bitbake,status,total,current,repo_name): | |
91 | def setCloneStatus(self,bitbake,status,total,current): | ||
92 | bitbake.req.build.repos_cloned=current | 94 | bitbake.req.build.repos_cloned=current |
93 | bitbake.req.build.repos_to_clone=total | 95 | bitbake.req.build.repos_to_clone=total |
96 | bitbake.req.build.progress_item=repo_name | ||
94 | bitbake.req.build.save() | 97 | bitbake.req.build.save() |
95 | 98 | ||
96 | def setLayers(self, bitbake, layers, targets): | 99 | def setLayers(self, bitbake, layers, targets): |
@@ -100,6 +103,7 @@ class LocalhostBEController(BuildEnvironmentController): | |||
100 | 103 | ||
101 | layerlist = [] | 104 | layerlist = [] |
102 | nongitlayerlist = [] | 105 | nongitlayerlist = [] |
106 | layer_index = 0 | ||
103 | git_env = os.environ.copy() | 107 | git_env = os.environ.copy() |
104 | # (note: add custom environment settings here) | 108 | # (note: add custom environment settings here) |
105 | 109 | ||
@@ -113,7 +117,7 @@ class LocalhostBEController(BuildEnvironmentController): | |||
113 | if bitbake.giturl and bitbake.commit: | 117 | if bitbake.giturl and bitbake.commit: |
114 | gitrepos[(bitbake.giturl, bitbake.commit)] = [] | 118 | gitrepos[(bitbake.giturl, bitbake.commit)] = [] |
115 | gitrepos[(bitbake.giturl, bitbake.commit)].append( | 119 | gitrepos[(bitbake.giturl, bitbake.commit)].append( |
116 | ("bitbake", bitbake.dirpath)) | 120 | ("bitbake", bitbake.dirpath, 0)) |
117 | 121 | ||
118 | for layer in layers: | 122 | for layer in layers: |
119 | # We don't need to git clone the layer for the CustomImageRecipe | 123 | # We don't need to git clone the layer for the CustomImageRecipe |
@@ -124,12 +128,13 @@ class LocalhostBEController(BuildEnvironmentController): | |||
124 | # If we have local layers then we don't need clone them | 128 | # If we have local layers then we don't need clone them |
125 | # For local layers giturl will be empty | 129 | # For local layers giturl will be empty |
126 | if not layer.giturl: | 130 | if not layer.giturl: |
127 | nongitlayerlist.append(layer.layer_version.layer.local_source_dir) | 131 | nongitlayerlist.append( "%03d:%s" % (layer_index,layer.local_source_dir) ) |
128 | continue | 132 | continue |
129 | 133 | ||
130 | if not (layer.giturl, layer.commit) in gitrepos: | 134 | if not (layer.giturl, layer.commit) in gitrepos: |
131 | gitrepos[(layer.giturl, layer.commit)] = [] | 135 | gitrepos[(layer.giturl, layer.commit)] = [] |
132 | gitrepos[(layer.giturl, layer.commit)].append( (layer.name, layer.dirpath) ) | 136 | gitrepos[(layer.giturl, layer.commit)].append( (layer.name,layer.dirpath,layer_index) ) |
137 | layer_index += 1 | ||
133 | 138 | ||
134 | 139 | ||
135 | logger.debug("localhostbecontroller, our git repos are %s" % pformat(gitrepos)) | 140 | logger.debug("localhostbecontroller, our git repos are %s" % pformat(gitrepos)) |
@@ -159,9 +164,9 @@ class LocalhostBEController(BuildEnvironmentController): | |||
159 | # 3. checkout the repositories | 164 | # 3. checkout the repositories |
160 | clone_count=0 | 165 | clone_count=0 |
161 | clone_total=len(gitrepos.keys()) | 166 | clone_total=len(gitrepos.keys()) |
162 | self.setCloneStatus(bitbake,'Started',clone_total,clone_count) | 167 | self.setCloneStatus(bitbake,'Started',clone_total,clone_count,'') |
163 | for giturl, commit in gitrepos.keys(): | 168 | for giturl, commit in gitrepos.keys(): |
164 | self.setCloneStatus(bitbake,'progress',clone_total,clone_count) | 169 | self.setCloneStatus(bitbake,'progress',clone_total,clone_count,gitrepos[(giturl, commit)][0][0]) |
165 | clone_count += 1 | 170 | clone_count += 1 |
166 | 171 | ||
167 | localdirname = os.path.join(self.be.sourcedir, self.getGitCloneDirectory(giturl, commit)) | 172 | localdirname = os.path.join(self.be.sourcedir, self.getGitCloneDirectory(giturl, commit)) |
@@ -205,16 +210,16 @@ class LocalhostBEController(BuildEnvironmentController): | |||
205 | self._shellcmd("git clone -b \"%s\" \"%s\" \"%s\" " % (bitbake.commit, bitbake.giturl, os.path.join(self.pokydirname, 'bitbake')),env=git_env) | 210 | self._shellcmd("git clone -b \"%s\" \"%s\" \"%s\" " % (bitbake.commit, bitbake.giturl, os.path.join(self.pokydirname, 'bitbake')),env=git_env) |
206 | 211 | ||
207 | # verify our repositories | 212 | # verify our repositories |
208 | for name, dirpath in gitrepos[(giturl, commit)]: | 213 | for name, dirpath, index in gitrepos[(giturl, commit)]: |
209 | localdirpath = os.path.join(localdirname, dirpath) | 214 | localdirpath = os.path.join(localdirname, dirpath) |
210 | logger.debug("localhostbecontroller: localdirpath expected '%s'" % localdirpath) | 215 | logger.debug("localhostbecontroller: localdirpath expects '%s'" % localdirpath) |
211 | if not os.path.exists(localdirpath): | 216 | if not os.path.exists(localdirpath): |
212 | raise BuildSetupException("Cannot find layer git path '%s' in checked out repository '%s:%s'. Aborting." % (localdirpath, giturl, commit)) | 217 | raise BuildSetupException("Cannot find layer git path '%s' in checked out repository '%s:%s'. Aborting." % (localdirpath, giturl, commit)) |
213 | 218 | ||
214 | if name != "bitbake": | 219 | if name != "bitbake": |
215 | layerlist.append(localdirpath.rstrip("/")) | 220 | layerlist.append("%03d:%s" % (index,localdirpath.rstrip("/"))) |
216 | 221 | ||
217 | self.setCloneStatus(bitbake,'complete',clone_total,clone_count) | 222 | self.setCloneStatus(bitbake,'complete',clone_total,clone_count,'') |
218 | logger.debug("localhostbecontroller: current layer list %s " % pformat(layerlist)) | 223 | logger.debug("localhostbecontroller: current layer list %s " % pformat(layerlist)) |
219 | 224 | ||
220 | if self.pokydirname is None and os.path.exists(os.path.join(self.be.sourcedir, "oe-init-build-env")): | 225 | if self.pokydirname is None and os.path.exists(os.path.join(self.be.sourcedir, "oe-init-build-env")): |
@@ -232,7 +237,7 @@ class LocalhostBEController(BuildEnvironmentController): | |||
232 | customrecipe, layers) | 237 | customrecipe, layers) |
233 | 238 | ||
234 | if os.path.isdir(custom_layer_path): | 239 | if os.path.isdir(custom_layer_path): |
235 | layerlist.append(custom_layer_path) | 240 | layerlist.append("%03d:%s" % (layer_index,custom_layer_path)) |
236 | 241 | ||
237 | except CustomImageRecipe.DoesNotExist: | 242 | except CustomImageRecipe.DoesNotExist: |
238 | continue # not a custom recipe, skip | 243 | continue # not a custom recipe, skip |
@@ -240,7 +245,11 @@ class LocalhostBEController(BuildEnvironmentController): | |||
240 | layerlist.extend(nongitlayerlist) | 245 | layerlist.extend(nongitlayerlist) |
241 | logger.debug("\n\nset layers gives this list %s" % pformat(layerlist)) | 246 | logger.debug("\n\nset layers gives this list %s" % pformat(layerlist)) |
242 | self.islayerset = True | 247 | self.islayerset = True |
243 | return layerlist | 248 | |
249 | # restore the order of layer list for bblayers.conf | ||
250 | layerlist.sort() | ||
251 | sorted_layerlist = [l[4:] for l in layerlist] | ||
252 | return sorted_layerlist | ||
244 | 253 | ||
245 | def setup_custom_image_recipe(self, customrecipe, layers): | 254 | def setup_custom_image_recipe(self, customrecipe, layers): |
246 | """ Set up toaster-custom-images layer and recipe files """ | 255 | """ Set up toaster-custom-images layer and recipe files """ |
@@ -310,31 +319,115 @@ class LocalhostBEController(BuildEnvironmentController): | |||
310 | 319 | ||
311 | def triggerBuild(self, bitbake, layers, variables, targets, brbe): | 320 | def triggerBuild(self, bitbake, layers, variables, targets, brbe): |
312 | layers = self.setLayers(bitbake, layers, targets) | 321 | layers = self.setLayers(bitbake, layers, targets) |
322 | is_merged_attr = bitbake.req.project.merged_attr | ||
323 | |||
324 | git_env = os.environ.copy() | ||
325 | # (note: add custom environment settings here) | ||
326 | try: | ||
327 | # insure that the project init/build uses the selected bitbake, and not Toaster's | ||
328 | del git_env['TEMPLATECONF'] | ||
329 | del git_env['BBBASEDIR'] | ||
330 | del git_env['BUILDDIR'] | ||
331 | except KeyError: | ||
332 | pass | ||
313 | 333 | ||
314 | # init build environment from the clone | 334 | # init build environment from the clone |
315 | builddir = '%s-toaster-%d' % (self.be.builddir, bitbake.req.project.id) | 335 | if bitbake.req.project.builddir: |
336 | builddir = bitbake.req.project.builddir | ||
337 | else: | ||
338 | builddir = '%s-toaster-%d' % (self.be.builddir, bitbake.req.project.id) | ||
316 | oe_init = os.path.join(self.pokydirname, 'oe-init-build-env') | 339 | oe_init = os.path.join(self.pokydirname, 'oe-init-build-env') |
317 | # init build environment | 340 | # init build environment |
318 | try: | 341 | try: |
319 | custom_script = ToasterSetting.objects.get(name="CUSTOM_BUILD_INIT_SCRIPT").value | 342 | custom_script = ToasterSetting.objects.get(name="CUSTOM_BUILD_INIT_SCRIPT").value |
320 | custom_script = custom_script.replace("%BUILDDIR%" ,builddir) | 343 | custom_script = custom_script.replace("%BUILDDIR%" ,builddir) |
321 | self._shellcmd("bash -c 'source %s'" % (custom_script)) | 344 | self._shellcmd("bash -c 'source %s'" % (custom_script),env=git_env) |
322 | except ToasterSetting.DoesNotExist: | 345 | except ToasterSetting.DoesNotExist: |
323 | self._shellcmd("bash -c 'source %s %s'" % (oe_init, builddir), | 346 | self._shellcmd("bash -c 'source %s %s'" % (oe_init, builddir), |
324 | self.be.sourcedir) | 347 | self.be.sourcedir,env=git_env) |
325 | 348 | ||
326 | # update bblayers.conf | 349 | # update bblayers.conf |
327 | bblconfpath = os.path.join(builddir, "conf/toaster-bblayers.conf") | 350 | if not is_merged_attr: |
328 | with open(bblconfpath, 'w') as bblayers: | 351 | bblconfpath = os.path.join(builddir, "conf/toaster-bblayers.conf") |
329 | bblayers.write('# line added by toaster build control\n' | 352 | with open(bblconfpath, 'w') as bblayers: |
330 | 'BBLAYERS = "%s"' % ' '.join(layers)) | 353 | bblayers.write('# line added by toaster build control\n' |
331 | 354 | 'BBLAYERS = "%s"' % ' '.join(layers)) | |
332 | # write configuration file | 355 | |
333 | confpath = os.path.join(builddir, 'conf/toaster.conf') | 356 | # write configuration file |
334 | with open(confpath, 'w') as conf: | 357 | confpath = os.path.join(builddir, 'conf/toaster.conf') |
335 | for var in variables: | 358 | with open(confpath, 'w') as conf: |
336 | conf.write('%s="%s"\n' % (var.name, var.value)) | 359 | for var in variables: |
337 | conf.write('INHERIT+="toaster buildhistory"') | 360 | conf.write('%s="%s"\n' % (var.name, var.value)) |
361 | conf.write('INHERIT+="toaster buildhistory"') | ||
362 | else: | ||
363 | # Append the Toaster-specific values directly to the bblayers.conf | ||
364 | bblconfpath = os.path.join(bitbake.req.project.builddir, "conf/bblayers.conf") | ||
365 | bblconfpath_save = os.path.join(bitbake.req.project.builddir, "conf/bblayers.conf.save") | ||
366 | shutil.copyfile(bblconfpath, bblconfpath_save) | ||
367 | with open(bblconfpath) as bblayers: | ||
368 | content = bblayers.readlines() | ||
369 | do_write = True | ||
370 | was_toaster = False | ||
371 | with open(bblconfpath,'w') as bblayers: | ||
372 | for line in content: | ||
373 | #line = line.strip('\n') | ||
374 | if 'TOASTER_CONFIG_PROLOG' in line: | ||
375 | do_write = False | ||
376 | was_toaster = True | ||
377 | elif 'TOASTER_CONFIG_EPILOG' in line: | ||
378 | do_write = True | ||
379 | elif do_write: | ||
380 | bblayers.write(line) | ||
381 | if not was_toaster: | ||
382 | bblayers.write('\n') | ||
383 | bblayers.write('#=== TOASTER_CONFIG_PROLOG ===\n') | ||
384 | bblayers.write('BBLAYERS = "\\\n') | ||
385 | for layer in layers: | ||
386 | bblayers.write(' %s \\\n' % layer) | ||
387 | bblayers.write(' "\n') | ||
388 | bblayers.write('#=== TOASTER_CONFIG_EPILOG ===\n') | ||
389 | # Append the Toaster-specific values directly to the local.conf | ||
390 | bbconfpath = os.path.join(bitbake.req.project.builddir, "conf/local.conf") | ||
391 | bbconfpath_save = os.path.join(bitbake.req.project.builddir, "conf/local.conf.save") | ||
392 | shutil.copyfile(bbconfpath, bbconfpath_save) | ||
393 | with open(bbconfpath) as f: | ||
394 | content = f.readlines() | ||
395 | do_write = True | ||
396 | was_toaster = False | ||
397 | with open(bbconfpath,'w') as conf: | ||
398 | for line in content: | ||
399 | #line = line.strip('\n') | ||
400 | if 'TOASTER_CONFIG_PROLOG' in line: | ||
401 | do_write = False | ||
402 | was_toaster = True | ||
403 | elif 'TOASTER_CONFIG_EPILOG' in line: | ||
404 | do_write = True | ||
405 | elif do_write: | ||
406 | conf.write(line) | ||
407 | if not was_toaster: | ||
408 | conf.write('\n') | ||
409 | conf.write('#=== TOASTER_CONFIG_PROLOG ===\n') | ||
410 | for var in variables: | ||
411 | if (not var.name.startswith("INTERNAL_")) and (not var.name == "BBLAYERS"): | ||
412 | conf.write('%s="%s"\n' % (var.name, var.value)) | ||
413 | conf.write('#=== TOASTER_CONFIG_EPILOG ===\n') | ||
414 | |||
415 | # If 'target' is just the project preparation target, then we are done | ||
416 | for target in targets: | ||
417 | if "_PROJECT_PREPARE_" == target.target: | ||
418 | logger.debug('localhostbecontroller: Project has been prepared. Done.') | ||
419 | # Update the Build Request and release the build environment | ||
420 | bitbake.req.state = BuildRequest.REQ_COMPLETED | ||
421 | bitbake.req.save() | ||
422 | self.be.lock = BuildEnvironment.LOCK_FREE | ||
423 | self.be.save() | ||
424 | # Close the project build and progress bar | ||
425 | bitbake.req.build.outcome = Build.SUCCEEDED | ||
426 | bitbake.req.build.save() | ||
427 | # Update the project status | ||
428 | bitbake.req.project.set_variable(Project.PROJECT_SPECIFIC_STATUS,Project.PROJECT_SPECIFIC_CLONING_SUCCESS) | ||
429 | signal_runbuilds() | ||
430 | return | ||
338 | 431 | ||
339 | # clean the Toaster to build environment | 432 | # clean the Toaster to build environment |
340 | env_clean = 'unset BBPATH;' # clean BBPATH for <= YP-2.4.0 | 433 | env_clean = 'unset BBPATH;' # clean BBPATH for <= YP-2.4.0 |
@@ -342,9 +435,14 @@ class LocalhostBEController(BuildEnvironmentController): | |||
342 | # run bitbake server from the clone | 435 | # run bitbake server from the clone |
343 | bitbake = os.path.join(self.pokydirname, 'bitbake', 'bin', 'bitbake') | 436 | bitbake = os.path.join(self.pokydirname, 'bitbake', 'bin', 'bitbake') |
344 | toasterlayers = os.path.join(builddir,"conf/toaster-bblayers.conf") | 437 | toasterlayers = os.path.join(builddir,"conf/toaster-bblayers.conf") |
345 | self._shellcmd('%s bash -c \"source %s %s; BITBAKE_UI="knotty" %s --read %s --read %s ' | 438 | if not is_merged_attr: |
346 | '--server-only -B 0.0.0.0:0\"' % (env_clean, oe_init, | 439 | self._shellcmd('%s bash -c \"source %s %s; BITBAKE_UI="knotty" %s --read %s --read %s ' |
347 | builddir, bitbake, confpath, toasterlayers), self.be.sourcedir) | 440 | '--server-only -B 0.0.0.0:0\"' % (env_clean, oe_init, |
441 | builddir, bitbake, confpath, toasterlayers), self.be.sourcedir) | ||
442 | else: | ||
443 | self._shellcmd('%s bash -c \"source %s %s; BITBAKE_UI="knotty" %s ' | ||
444 | '--server-only -B 0.0.0.0:0\"' % (env_clean, oe_init, | ||
445 | builddir, bitbake), self.be.sourcedir) | ||
348 | 446 | ||
349 | # read port number from bitbake.lock | 447 | # read port number from bitbake.lock |
350 | self.be.bbport = -1 | 448 | self.be.bbport = -1 |
@@ -390,12 +488,20 @@ class LocalhostBEController(BuildEnvironmentController): | |||
390 | log = os.path.join(builddir, 'toaster_ui.log') | 488 | log = os.path.join(builddir, 'toaster_ui.log') |
391 | local_bitbake = os.path.join(os.path.dirname(os.getenv('BBBASEDIR')), | 489 | local_bitbake = os.path.join(os.path.dirname(os.getenv('BBBASEDIR')), |
392 | 'bitbake') | 490 | 'bitbake') |
393 | self._shellcmd(['%s bash -c \"(TOASTER_BRBE="%s" BBSERVER="0.0.0.0:%s" ' | 491 | if not is_merged_attr: |
492 | self._shellcmd(['%s bash -c \"(TOASTER_BRBE="%s" BBSERVER="0.0.0.0:%s" ' | ||
394 | '%s %s -u toasterui --read %s --read %s --token="" >>%s 2>&1;' | 493 | '%s %s -u toasterui --read %s --read %s --token="" >>%s 2>&1;' |
395 | 'BITBAKE_UI="knotty" BBSERVER=0.0.0.0:%s %s -m)&\"' \ | 494 | 'BITBAKE_UI="knotty" BBSERVER=0.0.0.0:%s %s -m)&\"' \ |
396 | % (env_clean, brbe, self.be.bbport, local_bitbake, bbtargets, confpath, toasterlayers, log, | 495 | % (env_clean, brbe, self.be.bbport, local_bitbake, bbtargets, confpath, toasterlayers, log, |
397 | self.be.bbport, bitbake,)], | 496 | self.be.bbport, bitbake,)], |
398 | builddir, nowait=True) | 497 | builddir, nowait=True) |
498 | else: | ||
499 | self._shellcmd(['%s bash -c \"(TOASTER_BRBE="%s" BBSERVER="0.0.0.0:%s" ' | ||
500 | '%s %s -u toasterui --token="" >>%s 2>&1;' | ||
501 | 'BITBAKE_UI="knotty" BBSERVER=0.0.0.0:%s %s -m)&\"' \ | ||
502 | % (env_clean, brbe, self.be.bbport, local_bitbake, bbtargets, log, | ||
503 | self.be.bbport, bitbake,)], | ||
504 | builddir, nowait=True) | ||
399 | 505 | ||
400 | logger.debug('localhostbecontroller: Build launched, exiting. ' | 506 | logger.debug('localhostbecontroller: Build launched, exiting. ' |
401 | 'Follow build logs at %s' % log) | 507 | 'Follow build logs at %s' % log) |