[Notes] [Git][BuildStream/buildstream][richardmaw/distinguish-sandboxing-build-fail] 14 commits: CONTRIBUTING.rst: Added section in PEP-8 coding style about line lengths.



Title: GitLab

richardmaw-codethink pushed to branch richardmaw/distinguish-sandboxing-build-fail at BuildStream / buildstream

Commits:

6 changed files:

Changes:

  • CONTRIBUTING.rst
    ... ... @@ -14,7 +14,7 @@ if no issue already exists.
    14 14
     
    
    15 15
     For policies on how to submit an issue and how to use our project labels,
    
    16 16
     we recommend that you read the `policies guide
    
    17
    -<https://gitlab.com/BuildStream/nosoftware/alignment/blob/master/BuildStream_policies.md>`_
    
    17
    +<https://gitlab.com/BuildStream/nosoftware/alignment/blob/master/BuildStream_policies.md>`_.
    
    18 18
     
    
    19 19
     
    
    20 20
     .. _contributing_fixing_bugs:
    
    ... ... @@ -192,6 +192,21 @@ code readability by being overly restrictive on line length for instance.
    192 192
     The pep8 linter will run automatically when :ref:`running the test suite <contributing_testing>`.
    
    193 193
     
    
    194 194
     
    
    195
    +Line lengths
    
    196
    +''''''''''''
    
    197
    +Regarding laxness on the line length in our linter settings, it should be clarified
    
    198
    +that the line length limit is a hard limit which causes the linter to bail out
    
    199
    +and reject commits which break the high limit - not an invitation to write exceedingly
    
    200
    +long lines of code, comments, or API documenting docstrings.
    
    201
    +
    
    202
    +Code, comments and docstrings should strive to remain written for approximately 80
    
    203
    +or 90 character lines, where exceptions can be made when code would be less readable
    
    204
    +when exceeding 80 or 90 characters (often this happens in conditional statements
    
    205
    +when raising an exception, for example). Or, when comments contain a long link that
    
    206
    +causes the given line to to exceed 80 or 90 characters, we don't want this to cause
    
    207
    +the linter to refuse the commit.
    
    208
    +
    
    209
    +
    
    195 210
     .. _contributing_documenting_symbols:
    
    196 211
     
    
    197 212
     Documenting symbols
    
    ... ... @@ -255,6 +270,11 @@ comments and docstrings.
    255 270
         *Since: 1.2*
    
    256 271
         """
    
    257 272
     
    
    273
    +.. note::
    
    274
    +
    
    275
    +   Python does not support docstrings on instance variables, but sphinx does
    
    276
    +   pick them up and includes them in the generated documentation.
    
    277
    +
    
    258 278
     **Internal instance variable**::
    
    259 279
     
    
    260 280
       def __init__(self, context, element):
    
    ... ... @@ -389,7 +409,7 @@ on a Python class in BuildStream::
    389 409
              # Implementation of the "frobbish" abstract method
    
    390 410
              # defined by the parent Bar class.
    
    391 411
              #
    
    392
    -	 return True
    
    412
    +         return True
    
    393 413
     
    
    394 414
           ################################################
    
    395 415
           #                 Public Methods               #
    
    ... ... @@ -430,7 +450,7 @@ on a Python class in BuildStream::
    430 450
           # Returns:
    
    431 451
           #    (int): The count of this foo
    
    432 452
           #
    
    433
    -      def set_count(self, count):
    
    453
    +      def get_count(self, count):
    
    434 454
     
    
    435 455
               return self._count
    
    436 456
     
    
    ... ... @@ -444,7 +464,7 @@ on a Python class in BuildStream::
    444 464
           #       Even though these are private implementation
    
    445 465
           #       details, they still MUST have API documenting
    
    446 466
           #       comments on them.
    
    447
    -      
    
    467
    +
    
    448 468
           # _do_frobbing()
    
    449 469
           #
    
    450 470
           # Does the actual frobbing
    
    ... ... @@ -479,10 +499,10 @@ reference on how the PEP-8 defines public and non-public.
    479 499
     
    
    480 500
       A private symbol must be denoted by a leading underscore.
    
    481 501
     
    
    482
    -* When a class can have subclasses (for example, the ``Sandbox`` or ``Platform``
    
    502
    +* When a class can have subclasses, then private symbols should be denoted
    
    503
    +  by two leading underscores. For example, the ``Sandbox`` or ``Platform``
    
    483 504
       classes which have various implementations, or the ``Element`` and ``Source``
    
    484
    -  classes which plugins derive from), then private symbols should be denoted
    
    485
    -  by two leading underscores.
    
    505
    +  classes which plugins derive from.
    
    486 506
     
    
    487 507
       The double leading underscore naming convention invokes Python's name
    
    488 508
       mangling algorithm which helps prevent namespace collisions in the case
    
    ... ... @@ -521,7 +541,7 @@ In order to disambiguate between:
    521 541
     
    
    522 542
     * Symbols which are publicly accessible details of the ``Element`` class, can
    
    523 543
       be accessed by BuildStream internals, but must remain hidden from the
    
    524
    -  *"Public API Surface"*
    
    544
    +  *"Public API Surface"*.
    
    525 545
     
    
    526 546
     * Symbols which are private to the ``Element`` class, and cannot be accessed
    
    527 547
       from outside of the ``Element`` class at all.
    
    ... ... @@ -571,7 +591,7 @@ is found at ``_artifactcache/artifactcache.py``.
    571 591
     
    
    572 592
     Imports
    
    573 593
     ~~~~~~~
    
    574
    -Module imports inside BuildStream are done with relative ``.`` notation
    
    594
    +Module imports inside BuildStream are done with relative ``.`` notation:
    
    575 595
     
    
    576 596
     **Good**::
    
    577 597
     
    
    ... ... @@ -613,12 +633,12 @@ which exposes an instance variable is the only one in control of the value of th
    613 633
     variable.
    
    614 634
     
    
    615 635
     * If an instance variable is public and must be modified; then it must be
    
    616
    -  modified using a :ref:`mutator <contributing_accessor_mutator>`
    
    636
    +  modified using a :ref:`mutator <contributing_accessor_mutator>`.
    
    617 637
     
    
    618 638
     * Ideally for better encapsulation, all object state is declared as
    
    619 639
       :ref:`private instance variables <contributing_public_and_private>` and can
    
    620 640
       only be accessed by external classes via public :ref:`accessors and mutators
    
    621
    -  <contributing_accessor_mutator>`
    
    641
    +  <contributing_accessor_mutator>`.
    
    622 642
     
    
    623 643
     .. note::
    
    624 644
     
    
    ... ... @@ -705,10 +725,10 @@ In BuildStream, we use the term *"Abstract Method"*, to refer to
    705 725
     a method which **can** be overridden by a subclass, whereas it
    
    706 726
     is **illegal** to override any other method.
    
    707 727
     
    
    708
    -* Abstract methods are allowed to have default implementations
    
    728
    +* Abstract methods are allowed to have default implementations.
    
    709 729
     
    
    710 730
     * Subclasses are not allowed to redefine the calling signature
    
    711
    -  of an abstract method, or redefine the API contract in any way
    
    731
    +  of an abstract method, or redefine the API contract in any way.
    
    712 732
     
    
    713 733
     * Subclasses are not allowed to override any other methods.
    
    714 734
     
    
    ... ... @@ -783,7 +803,7 @@ BstError parameters
    783 803
     When raising ``BstError`` class exceptions, there are some common properties
    
    784 804
     which can be useful to know about:
    
    785 805
     
    
    786
    -* **message:** The brief human readable error, will be formatted on one line in the frontend
    
    806
    +* **message:** The brief human readable error, will be formatted on one line in the frontend.
    
    787 807
     
    
    788 808
     * **detail:** An optional detailed human readable message to accompany the **message** summary
    
    789 809
       of the error. This is often used to recommend the user some course of action, or to provide
    
    ... ... @@ -959,9 +979,9 @@ symbols to a minimum, this is important for both
    959 979
     
    
    960 980
     When anyone visits a file, there are two levels of comprehension:
    
    961 981
     
    
    962
    -* What do I need to know in order to *use* this object
    
    982
    +* What do I need to know in order to *use* this object.
    
    963 983
     
    
    964
    -* What do I need to know in order to *modify* this object
    
    984
    +* What do I need to know in order to *modify* this object.
    
    965 985
     
    
    966 986
     For the former, we want the reader to understand with as little effort
    
    967 987
     as possible, what the public API contract is for a given object and consequently,
    
    ... ... @@ -986,9 +1006,9 @@ well documented and minimal.
    986 1006
     
    
    987 1007
     When adding new API to a given object for a new purpose, consider whether
    
    988 1008
     the new API is in any way redundant with other API (should this value now
    
    989
    -go into the constructor, since we use it more than once ? could this
    
    1009
    +go into the constructor, since we use it more than once? could this
    
    990 1010
     value be passed along with another function, and the other function renamed,
    
    991
    -to better suit the new purposes of this module/object ?) and repurpose
    
    1011
    +to better suit the new purposes of this module/object?) and repurpose
    
    992 1012
     the outward facing API of an object as a whole every time.
    
    993 1013
     
    
    994 1014
     
    
    ... ... @@ -1168,7 +1188,7 @@ The BuildStream documentation style is as follows:
    1168 1188
     * Cross references should be of the form ``:role:`target```.
    
    1169 1189
     
    
    1170 1190
       * Explicit anchors can be declared as ``.. _anchor_name:`` on a line by itself.
    
    1171
    -  
    
    1191
    +
    
    1172 1192
       * To cross reference arbitrary locations with, for example, the anchor ``anchor_name``,
    
    1173 1193
         always provide some explicit text in the link instead of deriving the text from
    
    1174 1194
         the target, e.g.: ``:ref:`Link text <anchor_name>```.
    
    ... ... @@ -1251,23 +1271,23 @@ Documentation Examples
    1251 1271
     The examples section of the documentation contains a series of standalone
    
    1252 1272
     examples, here are the criteria for an example addition.
    
    1253 1273
     
    
    1254
    -* The example has a ``${name}``
    
    1274
    +* The example has a ``${name}``.
    
    1255 1275
     
    
    1256
    -* The example has a project users can copy and use
    
    1276
    +* The example has a project users can copy and use.
    
    1257 1277
     
    
    1258
    -  * This project is added in the directory ``doc/examples/${name}``
    
    1278
    +  * This project is added in the directory ``doc/examples/${name}``.
    
    1259 1279
     
    
    1260
    -* The example has a documentation component
    
    1280
    +* The example has a documentation component.
    
    1261 1281
     
    
    1262 1282
       * This is added at ``doc/source/examples/${name}.rst``
    
    1263 1283
       * A reference to ``examples/${name}`` is added to the toctree in ``doc/source/examples.rst``
    
    1264 1284
       * This documentation discusses the project elements declared in the project and may
    
    1265
    -    provide some BuildStream command examples
    
    1266
    -  * This documentation links out to the reference manual at every opportunity
    
    1285
    +    provide some BuildStream command examples.
    
    1286
    +  * This documentation links out to the reference manual at every opportunity.
    
    1267 1287
     
    
    1268
    -* The example has a CI test component
    
    1288
    +* The example has a CI test component.
    
    1269 1289
     
    
    1270
    -  * This is an integration test added at ``tests/examples/${name}``
    
    1290
    +  * This is an integration test added at ``tests/examples/${name}``.
    
    1271 1291
       * This test runs BuildStream in the ways described in the example
    
    1272 1292
         and assert that we get the results which we advertize to users in
    
    1273 1293
         the said examples.
    
    ... ... @@ -1294,17 +1314,17 @@ The ``.run`` file format is just another YAML dictionary which consists of a
    1294 1314
     
    
    1295 1315
     Each *command* is a dictionary, the members of which are listed here:
    
    1296 1316
     
    
    1297
    -* ``directory``: The input file relative project directory
    
    1317
    +* ``directory``: The input file relative project directory.
    
    1298 1318
     
    
    1299
    -* ``output``: The input file relative output html file to generate (optional)
    
    1319
    +* ``output``: The input file relative output html file to generate (optional).
    
    1300 1320
     
    
    1301 1321
     * ``fake-output``: Don't really run the command, just pretend to and pretend
    
    1302 1322
       this was the output, an empty string will enable this too.
    
    1303 1323
     
    
    1304
    -* ``command``: The command to run, without the leading ``bst``
    
    1324
    +* ``command``: The command to run, without the leading ``bst``.
    
    1305 1325
     
    
    1306 1326
     * ``shell``: Specifying ``True`` indicates that ``command`` should be run as
    
    1307
    -  a shell command from the project directory, instead of a bst command (optional)
    
    1327
    +  a shell command from the project directory, instead of a bst command (optional).
    
    1308 1328
     
    
    1309 1329
     When adding a new ``.run`` file, one should normally also commit the new
    
    1310 1330
     resulting generated ``.html`` file(s) into the ``doc/source/sessions-stored/``
    
    ... ... @@ -1402,7 +1422,7 @@ a subdirectory beside your test in which to store data.
    1402 1422
     When creating a test that needs data, use the datafiles extension
    
    1403 1423
     to decorate your test case (again, examples exist in the existing
    
    1404 1424
     tests for this), documentation on the datafiles extension can
    
    1405
    -be found here: https://pypi.python.org/pypi/pytest-datafiles
    
    1425
    +be found here: https://pypi.python.org/pypi/pytest-datafiles.
    
    1406 1426
     
    
    1407 1427
     Tests that run a sandbox should be decorated with::
    
    1408 1428
     
    

  • buildstream/_platform/linux.py
    ... ... @@ -44,6 +44,7 @@ class Linux(Platform):
    44 44
             self._local_sandbox_available = self._have_fuse and self._have_good_bwrap
    
    45 45
     
    
    46 46
             self._die_with_parent_available = _site.check_bwrap_version(0, 1, 8)
    
    47
    +        self._json_status_available = _site.check_bwrap_version(0, 3, 2)
    
    47 48
     
    
    48 49
             if self._local_sandbox_available:
    
    49 50
                 self._user_ns_available = self._check_user_ns_available()
    
    ... ... @@ -91,6 +92,7 @@ class Linux(Platform):
    91 92
             # Inform the bubblewrap sandbox as to whether it can use user namespaces or not
    
    92 93
             kwargs['user_ns_available'] = self._user_ns_available
    
    93 94
             kwargs['die_with_parent_available'] = self._die_with_parent_available
    
    95
    +        kwargs['json_status_available'] = self._json_status_available
    
    94 96
             return SandboxBwrap(*args, **kwargs)
    
    95 97
     
    
    96 98
         def _check_user_ns_available(self):
    

  • buildstream/sandbox/_sandboxbwrap.py
    ... ... @@ -17,6 +17,8 @@
    17 17
     #  Authors:
    
    18 18
     #        Andrew Leeming <andrew leeming codethink co uk>
    
    19 19
     #        Tristan Van Berkom <tristan vanberkom codethink co uk>
    
    20
    +import collections
    
    21
    +import json
    
    20 22
     import os
    
    21 23
     import sys
    
    22 24
     import time
    
    ... ... @@ -24,7 +26,8 @@ import errno
    24 26
     import signal
    
    25 27
     import subprocess
    
    26 28
     import shutil
    
    27
    -from contextlib import ExitStack
    
    29
    +from contextlib import ExitStack, suppress
    
    30
    +from tempfile import TemporaryFile
    
    28 31
     
    
    29 32
     import psutil
    
    30 33
     
    
    ... ... @@ -53,6 +56,7 @@ class SandboxBwrap(Sandbox):
    53 56
             super().__init__(*args, **kwargs)
    
    54 57
             self.user_ns_available = kwargs['user_ns_available']
    
    55 58
             self.die_with_parent_available = kwargs['die_with_parent_available']
    
    59
    +        self.json_status_available = kwargs['json_status_available']
    
    56 60
     
    
    57 61
         def run(self, command, flags, *, cwd=None, env=None):
    
    58 62
             stdout, stderr = self._get_output()
    
    ... ... @@ -159,24 +163,31 @@ class SandboxBwrap(Sandbox):
    159 163
                     gid = self._get_config().build_gid
    
    160 164
                     bwrap_command += ['--uid', str(uid), '--gid', str(gid)]
    
    161 165
     
    
    162
    -        # Add the command
    
    163
    -        bwrap_command += command
    
    164
    -
    
    165
    -        # bwrap might create some directories while being suid
    
    166
    -        # and may give them to root gid, if it does, we'll want
    
    167
    -        # to clean them up after, so record what we already had
    
    168
    -        # there just in case so that we can safely cleanup the debris.
    
    169
    -        #
    
    170
    -        existing_basedirs = {
    
    171
    -            directory: os.path.exists(os.path.join(root_directory, directory))
    
    172
    -            for directory in ['tmp', 'dev', 'proc']
    
    173
    -        }
    
    174
    -
    
    175
    -        # Use the MountMap context manager to ensure that any redirected
    
    176
    -        # mounts through fuse layers are in context and ready for bwrap
    
    177
    -        # to mount them from.
    
    178
    -        #
    
    179 166
             with ExitStack() as stack:
    
    167
    +            pass_fds = ()
    
    168
    +            # Improve error reporting with json-status if available
    
    169
    +            if self.json_status_available:
    
    170
    +                json_status_file = stack.enter_context(TemporaryFile())
    
    171
    +                pass_fds = (json_status_file.fileno(),)
    
    172
    +                bwrap_command += ['--json-status-fd', str(json_status_file.fileno())]
    
    173
    +
    
    174
    +            # Add the command
    
    175
    +            bwrap_command += command
    
    176
    +
    
    177
    +            # bwrap might create some directories while being suid
    
    178
    +            # and may give them to root gid, if it does, we'll want
    
    179
    +            # to clean them up after, so record what we already had
    
    180
    +            # there just in case so that we can safely cleanup the debris.
    
    181
    +            #
    
    182
    +            existing_basedirs = {
    
    183
    +                directory: os.path.exists(os.path.join(root_directory, directory))
    
    184
    +                for directory in ['tmp', 'dev', 'proc']
    
    185
    +            }
    
    186
    +
    
    187
    +            # Use the MountMap context manager to ensure that any redirected
    
    188
    +            # mounts through fuse layers are in context and ready for bwrap
    
    189
    +            # to mount them from.
    
    190
    +            #
    
    180 191
                 stack.enter_context(mount_map.mounted(self))
    
    181 192
     
    
    182 193
                 # Ensure the cwd exists
    
    ... ... @@ -194,7 +205,7 @@ class SandboxBwrap(Sandbox):
    194 205
     
    
    195 206
                 # Run bubblewrap !
    
    196 207
                 exit_code = self.run_bwrap(bwrap_command, stdin, stdout, stderr,
    
    197
    -                                       (flags & SandboxFlags.INTERACTIVE))
    
    208
    +                                       (flags & SandboxFlags.INTERACTIVE), pass_fds)
    
    198 209
     
    
    199 210
                 # Cleanup things which bwrap might have left behind, while
    
    200 211
                 # everything is still mounted because bwrap can be creating
    
    ... ... @@ -242,10 +253,24 @@ class SandboxBwrap(Sandbox):
    242 253
                             # a bug, bwrap mounted a tempfs here and when it exits, that better be empty.
    
    243 254
                             pass
    
    244 255
     
    
    256
    +            if self.json_status_available:
    
    257
    +                json_status_file.seek(0, 0)
    
    258
    +                child_exit_code = None
    
    259
    +                for line in json_status_file:
    
    260
    +                    with suppress(json.decoder.JSONDecodeError):
    
    261
    +                        o = json.loads(line)
    
    262
    +                        if isinstance(o, collections.abc.Mapping) and 'exit-code' in o:
    
    263
    +                            child_exit_code = o['exit-code']
    
    264
    +                            break
    
    265
    +                if child_exit_code is None:
    
    266
    +                    raise SandboxError("`bwrap' terminated during sandbox setup with exitcode {}".format(exit_code),
    
    267
    +                                       reason="bwrap-sandbox-fail")
    
    268
    +                exit_code = child_exit_code
    
    269
    +
    
    245 270
             self._vdir._mark_changed()
    
    246 271
             return exit_code
    
    247 272
     
    
    248
    -    def run_bwrap(self, argv, stdin, stdout, stderr, interactive):
    
    273
    +    def run_bwrap(self, argv, stdin, stdout, stderr, interactive, pass_fds):
    
    249 274
             # Wrapper around subprocess.Popen() with common settings.
    
    250 275
             #
    
    251 276
             # This function blocks until the subprocess has terminated.
    
    ... ... @@ -321,6 +346,7 @@ class SandboxBwrap(Sandbox):
    321 346
                     # The default is to share file descriptors from the parent process
    
    322 347
                     # to the subprocess, which is rarely good for sandboxing.
    
    323 348
                     close_fds=True,
    
    349
    +                pass_fds=pass_fds,
    
    324 350
                     stdin=stdin,
    
    325 351
                     stdout=stdout,
    
    326 352
                     stderr=stderr,
    

  • contrib/bst-docker-import
    ... ... @@ -93,10 +93,10 @@ echo "INFO: Checking out $element ..." >&2
    93 93
     $bst_cmd checkout --tar "$element" "$checkout_tar" || die "Failed to checkout $element"
    
    94 94
     echo "INFO: Successfully checked out $element" >&2
    
    95 95
     
    
    96
    -echo "INFO: Importing Docker image ..."
    
    96
    +echo "INFO: Importing Docker image ..." >&2
    
    97 97
     "${docker_import_cmd[@]}" "$checkout_tar" "$docker_image_tag" || die "Failed to import Docker image from tarball"
    
    98
    -echo "INFO: Successfully import Docker image $docker_image_tag"
    
    98
    +echo "INFO: Successfully import Docker image $docker_image_tag" >&2
    
    99 99
     
    
    100
    -echo "INFO: Cleaning up ..."
    
    100
    +echo "INFO: Cleaning up ..." >&2
    
    101 101
     rm "$checkout_tar" || die "Failed to remove $checkout_tar"
    
    102
    -echo "INFO: Clean up finished"
    102
    +echo "INFO: Clean up finished" >&2

  • tests/integration/sandbox-bwrap.py
    1 1
     import os
    
    2 2
     import pytest
    
    3 3
     
    
    4
    +from buildstream._exceptions import ErrorDomain
    
    5
    +
    
    4 6
     from tests.testutils import cli_integration as cli
    
    5 7
     from tests.testutils.integration import assert_contains
    
    6
    -from tests.testutils.site import HAVE_BWRAP
    
    8
    +from tests.testutils.site import HAVE_BWRAP, HAVE_BWRAP_JSON_STATUS
    
    7 9
     
    
    8 10
     
    
    9 11
     pytestmark = pytest.mark.integration
    
    ... ... @@ -29,3 +31,32 @@ def test_sandbox_bwrap_cleanup_build(cli, tmpdir, datafiles):
    29 31
         # Here, BuildStream should not attempt any rmdir etc.
    
    30 32
         result = cli.run(project=project, args=['build', element_name])
    
    31 33
         assert result.exit_code == 0
    
    34
    +
    
    35
    +
    
    36
    +@pytest.mark.skipif(not HAVE_BWRAP, reason='Only available with bubblewrap')
    
    37
    +@pytest.mark.skipif(not HAVE_BWRAP_JSON_STATUS, reason='Only available with bubblewrap supporting --json-status-fd')
    
    38
    +@pytest.mark.datafiles(DATA_DIR)
    
    39
    +def test_sandbox_bwrap_distinguish_setup_error(cli, tmpdir, datafiles):
    
    40
    +    project = os.path.join(datafiles.dirname, datafiles.basename)
    
    41
    +    element_name = 'sandbox-bwrap/non-executable-shell.bst'
    
    42
    +
    
    43
    +    result = cli.run(project=project, args=['build', element_name])
    
    44
    +    result.assert_task_error(error_domain=ErrorDomain.SANDBOX, error_reason="bwrap-sandbox-fail")
    
    45
    +
    
    46
    +
    
    47
    +@pytest.mark.integration
    
    48
    +@pytest.mark.skipif(not HAVE_BWRAP, reason='Only available with bubblewrap')
    
    49
    +@pytest.mark.datafiles(DATA_DIR)
    
    50
    +def test_sandbox_bwrap_return_subprocess(cli, tmpdir, datafiles):
    
    51
    +    project = os.path.join(datafiles.dirname, datafiles.basename)
    
    52
    +    element_name = 'sandbox-bwrap/command-exit-42.bst'
    
    53
    +
    
    54
    +    cli.configure({
    
    55
    +        "logging": {
    
    56
    +            "message-format": "%{element}|%{message}",
    
    57
    +        },
    
    58
    +    })
    
    59
    +
    
    60
    +    result = cli.run(project=project, args=['build', element_name])
    
    61
    +    result.assert_task_error(error_domain=ErrorDomain.ELEMENT, error_reason=None)
    
    62
    +    assert "sandbox-bwrap/command-exit-42.bst|Command 'exit 42' failed with exitcode 42" in result.stderr

  • tests/testutils/site.py
    ... ... @@ -4,7 +4,7 @@
    4 4
     import os
    
    5 5
     import sys
    
    6 6
     
    
    7
    -from buildstream import utils, ProgramNotFoundError
    
    7
    +from buildstream import _site, utils, ProgramNotFoundError
    
    8 8
     
    
    9 9
     try:
    
    10 10
         utils.get_host_tool('bzr')
    
    ... ... @@ -33,8 +33,10 @@ except (ImportError, ValueError):
    33 33
     try:
    
    34 34
         utils.get_host_tool('bwrap')
    
    35 35
         HAVE_BWRAP = True
    
    36
    +    HAVE_BWRAP_JSON_STATUS = _site.check_bwrap_version(0, 3, 2)
    
    36 37
     except ProgramNotFoundError:
    
    37 38
         HAVE_BWRAP = False
    
    39
    +    HAVE_BWRAP_JSON_STATUS = False
    
    38 40
     
    
    39 41
     try:
    
    40 42
         utils.get_host_tool('lzip')
    



  • [Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]