devtool: fix build env command execution error handling

If we execute an external command, we ought to prepare for the
possibility that it can fail and handle the failure appropriately. We
can especially expect this to happen when running bitbake in this
scenario. Ensure we return the appropriate exit code to the calling
process.

Fixes [YOCTO #7757].

(From OE-Core rev: 98a716d79bfc5434a5b42d3ca683eab3eea30a41)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Paul Eggleton 2015-05-14 10:18:18 +01:00 committed by Richard Purdie
parent 18114bb8a6
commit 1bab18f26f
2 changed files with 24 additions and 7 deletions

View File

@ -44,13 +44,14 @@ def exec_build_env_command(init_path, builddir, cmd, watch=False, **options):
if watch:
if sys.stdout.isatty():
# Fool bitbake into thinking it's outputting to a terminal (because it is, indirectly)
cmd = 'script -q -c "%s" /dev/null' % cmd
cmd = 'script -e -q -c "%s" /dev/null' % cmd
return exec_watch('%s%s' % (init_prefix, cmd), **options)
else:
return bb.process.run('%s%s' % (init_prefix, cmd), **options)
def exec_watch(cmd, **options):
"""Run program with stdout shown on sys.stdout"""
import bb
if isinstance(cmd, basestring) and not "shell" in options:
options["shell"] = True
@ -67,7 +68,11 @@ def exec_watch(cmd, **options):
buf += out
elif out == '' and process.poll() != None:
break
return buf
if process.returncode != 0:
raise bb.process.ExecutionError(cmd, process.returncode, buf, None)
return buf, None
def setup_tinfoil():
"""Initialize tinfoil api from bitbake"""

View File

@ -97,8 +97,12 @@ def add(args, config, basepath, workspace):
source = srctree
if args.version:
extracmdopts += ' -V %s' % args.version
stdout, _ = exec_build_env_command(config.init_path, basepath, 'recipetool --color=%s create -o %s "%s" %s' % (color, recipefile, source, extracmdopts))
logger.info('Recipe %s has been automatically created; further editing may be required to make it fully functional' % recipefile)
try:
stdout, _ = exec_build_env_command(config.init_path, basepath, 'recipetool --color=%s create -o %s "%s" %s' % (color, recipefile, source, extracmdopts))
logger.info('Recipe %s has been automatically created; further editing may be required to make it fully functional' % recipefile)
except bb.process.ExecutionError as e:
logger.error('Command \'%s\' failed:\n%s' % (e.command, e.stdout))
return 1
_add_md5(config, args.recipename, recipefile)
@ -688,7 +692,7 @@ def status(args, config, basepath, workspace):
def reset(args, config, basepath, workspace):
"""Entry point for the devtool 'reset' subcommand"""
import bb.utils
import bb
if args.recipename:
if args.all:
logger.error("Recipe cannot be specified if -a/--all is used")
@ -708,7 +712,11 @@ def reset(args, config, basepath, workspace):
for pn in recipes:
if not args.no_clean:
logger.info('Cleaning sysroot for recipe %s...' % pn)
exec_build_env_command(config.init_path, basepath, 'bitbake -c clean %s' % pn)
try:
exec_build_env_command(config.init_path, basepath, 'bitbake -c clean %s' % pn)
except bb.process.ExecutionError as e:
logger.error('Command \'%s\' failed, output:\n%s\nIf you wish, you may specify -n/--no-clean to skip running this command when resetting' % (e.command, e.stdout))
return 1
_check_preserve(config, pn)
@ -735,7 +743,11 @@ def build(args, config, basepath, workspace):
logger.error("no recipe named %s in your workspace" % args.recipename)
return -1
build_task = config.get('Build', 'build_task', 'populate_sysroot')
exec_build_env_command(config.init_path, basepath, 'bitbake -c %s %s' % (build_task, args.recipename), watch=True)
try:
exec_build_env_command(config.init_path, basepath, 'bitbake -c %s %s' % (build_task, args.recipename), watch=True)
except bb.process.ExecutionError as e:
# We've already seen the output since watch=True, so just ensure we return something to the user
return e.exitcode
return 0