From b38da15a054c4ce5ac7c46147995f1387ab24d3b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 9 Nov 2022 19:14:42 -0700 Subject: [PATCH] binman: Use an exit code when blobs are missing At present binman returns success when told to handle missing/faked blobs or missing bintools. This is confusing since in fact the resulting image cannot work. Use exit code 103 to signal this problem, with a -W option to convert it to a warning. Rename the flag to --ignore-missing since it controls bintools also. Add documentation about exit codes while we are here. Signed-off-by: Simon Glass --- tools/binman/binman.rst | 22 ++++++++++++++++++++++ tools/binman/cmdline.py | 5 ++++- tools/binman/control.py | 9 ++++++++- tools/binman/ftest.py | 19 +++++++++++++++++-- 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst index fda16f1992..16508d6ba5 100644 --- a/tools/binman/binman.rst +++ b/tools/binman/binman.rst @@ -1461,6 +1461,10 @@ space-separated list of directories to search for binary blobs:: odroid-c4/build/board/hardkernel/odroidc4/firmware \ odroid-c4/build/scp_task" binman ... +Note that binman fails with exit code 103 when there are missing blobs. If you +wish binman to continue anyway, you can pass `-W` to binman. + + Code coverage ------------- @@ -1472,6 +1476,24 @@ To enable Python test coverage on Debian-type distributions (e.g. Ubuntu):: $ sudo apt-get install python-coverage python3-coverage python-pytest +Exit status +----------- + +Binman produces the following exit codes: + +0 + Success + +1 + Any sort of failure - see output for more details + +103 + There are missing external blobs or bintools. This is only returned if + -M is passed to binman, otherwise missing blobs return an exit status of 1. + Note, if -W is passed as well as -M, then this is converted into a warning + and will return an exit status of 0 instead. + + Error messages -------------- diff --git a/tools/binman/cmdline.py b/tools/binman/cmdline.py index 1d1ca43993..986d6f1a31 100644 --- a/tools/binman/cmdline.py +++ b/tools/binman/cmdline.py @@ -114,7 +114,7 @@ controlled by a description in the board device tree.''' build_parser.add_argument('-m', '--map', action='store_true', default=False, help='Output a map file for each image') build_parser.add_argument('-M', '--allow-missing', action='store_true', - default=False, help='Allow external blobs to be missing') + default=False, help='Allow external blobs and bintools to be missing') build_parser.add_argument('-n', '--no-expanded', action='store_true', help="Don't use 'expanded' versions of entries where available; " "normally 'u-boot' becomes 'u-boot-expanded', for example") @@ -128,6 +128,9 @@ controlled by a description in the board device tree.''' default=False, help='Update the binman node with offset/size info') build_parser.add_argument('--update-fdt-in-elf', type=str, help='Update an ELF file with the output dtb: infile,outfile,begin_sym,end_sym') + build_parser.add_argument( + '-W', '--ignore-missing', action='store_true', default=False, + help='Return success even if there are missing blobs/bintools (requires -M)') subparsers.add_parser( 'bintool-docs', help='Write out bintool documentation (see bintool.rst)') diff --git a/tools/binman/control.py b/tools/binman/control.py index bfe63a1520..964c6984f9 100644 --- a/tools/binman/control.py +++ b/tools/binman/control.py @@ -741,8 +741,15 @@ def Binman(args): data = state.GetFdtForEtype('u-boot-dtb').GetContents() elf.UpdateFile(*elf_params, data) + # This can only be True if -M is provided, since otherwise binman + # would have raised an error already if invalid: - tout.warning("\nSome images are invalid") + msg = '\nSome images are invalid' + if args.ignore_missing: + tout.warning(msg) + else: + tout.error(msg) + return 103 # Use this to debug the time take to pack the image #state.TimingShow() diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index e849d96587..62ee86b9b7 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -340,7 +340,7 @@ class TestFunctional(unittest.TestCase): use_expanded=False, verbosity=None, allow_missing=False, allow_fake_blobs=False, extra_indirs=None, threads=None, test_section_timeout=False, update_fdt_in_elf=None, - force_missing_bintools=''): + force_missing_bintools='', ignore_missing=False): """Run binman with a given test file Args: @@ -403,6 +403,8 @@ class TestFunctional(unittest.TestCase): args.append('-a%s=%s' % (arg, value)) if allow_missing: args.append('-M') + if ignore_missing: + args.append('-W') if allow_fake_blobs: args.append('--fake-ext-blobs') if force_missing_bintools: @@ -3725,9 +3727,22 @@ class TestFunctional(unittest.TestCase): def testExtblobMissingOk(self): """Test an image with an missing external blob that is allowed""" with test_util.capture_sys_output() as (stdout, stderr): - self._DoTestFile('158_blob_ext_missing.dts', allow_missing=True) + ret = self._DoTestFile('158_blob_ext_missing.dts', + allow_missing=True) + self.assertEqual(103, ret) err = stderr.getvalue() self.assertRegex(err, "Image 'main-section'.*missing.*: blob-ext") + self.assertIn('Some images are invalid', err) + + def testExtblobMissingOkFlag(self): + """Test an image with an missing external blob allowed with -W""" + with test_util.capture_sys_output() as (stdout, stderr): + ret = self._DoTestFile('158_blob_ext_missing.dts', + allow_missing=True, ignore_missing=True) + self.assertEqual(0, ret) + err = stderr.getvalue() + self.assertRegex(err, "Image 'main-section'.*missing.*: blob-ext") + self.assertIn('Some images are invalid', err) def testExtblobMissingOkSect(self): """Test an image with an missing external blob that is allowed"""