diff options
author | Jürg Billeter <j@bitron.ch> | 2018-10-04 09:45:58 +0000 |
---|---|---|
committer | Jürg Billeter <j@bitron.ch> | 2018-10-04 09:45:58 +0000 |
commit | fd6a957366e5abe3cddc225118969205000e182d (patch) | |
tree | aae0773b6169681fe86df5798bb2e1437642f46e | |
parent | 3cf38c8e0a1828ed7ba6b5ec125c415a40da7f21 (diff) | |
parent | c46a7e878ad94c856083fc84dbc09fc9f6126ff3 (diff) | |
download | buildstream-fd6a957366e5abe3cddc225118969205000e182d.tar.gz |
Merge branch 'danielsilverstone-ct/bwrap-check-runtime-only' into 'master'
Make bwrap check runtime only
Closes #644
See merge request BuildStream/buildstream!847
-rw-r--r-- | buildstream/_platform/darwin.py | 3 | ||||
-rw-r--r-- | buildstream/_platform/linux.py | 45 | ||||
-rw-r--r-- | buildstream/_site.py | 18 | ||||
-rw-r--r-- | buildstream/sandbox/_sandboxdummy.py | 3 | ||||
-rwxr-xr-x | setup.py | 20 |
5 files changed, 53 insertions, 36 deletions
diff --git a/buildstream/_platform/darwin.py b/buildstream/_platform/darwin.py index c4361e897..04a83110e 100644 --- a/buildstream/_platform/darwin.py +++ b/buildstream/_platform/darwin.py @@ -34,6 +34,9 @@ class Darwin(Platform): super().__init__() def create_sandbox(self, *args, **kwargs): + kwargs['dummy_reason'] = \ + "OSXFUSE is not supported and there are no supported sandbox" + \ + "technologies for OSX at this time" return SandboxDummy(*args, **kwargs) def check_sandbox_config(self, config): diff --git a/buildstream/_platform/linux.py b/buildstream/_platform/linux.py index 97fbb47be..09db19f2d 100644 --- a/buildstream/_platform/linux.py +++ b/buildstream/_platform/linux.py @@ -37,25 +37,27 @@ class Linux(Platform): self._uid = os.geteuid() self._gid = os.getegid() + self._have_fuse = os.path.exists("/dev/fuse") + self._bwrap_exists = _site.check_bwrap_version(0, 0, 0) + self._have_good_bwrap = _site.check_bwrap_version(0, 1, 2) + + self._local_sandbox_available = self._have_fuse and self._have_good_bwrap + self._die_with_parent_available = _site.check_bwrap_version(0, 1, 8) - if self._local_sandbox_available(): + if self._local_sandbox_available: self._user_ns_available = self._check_user_ns_available() else: self._user_ns_available = False def create_sandbox(self, *args, **kwargs): - if not self._local_sandbox_available(): - return SandboxDummy(*args, **kwargs) + if not self._local_sandbox_available: + return self._create_dummy_sandbox(*args, **kwargs) else: - from ..sandbox._sandboxbwrap import SandboxBwrap - # Inform the bubblewrap sandbox as to whether it can use user namespaces or not - kwargs['user_ns_available'] = self._user_ns_available - kwargs['die_with_parent_available'] = self._die_with_parent_available - return SandboxBwrap(*args, **kwargs) + return self._create_bwrap_sandbox(*args, **kwargs) def check_sandbox_config(self, config): - if not self._local_sandbox_available(): + if not self._local_sandbox_available: # Accept all sandbox configs as it's irrelevant with the dummy sandbox (no Sandbox.run). return True @@ -70,11 +72,26 @@ class Linux(Platform): ################################################ # Private Methods # ################################################ - def _local_sandbox_available(self): - try: - return os.path.exists(utils.get_host_tool('bwrap')) and os.path.exists('/dev/fuse') - except utils.ProgramNotFoundError: - return False + + def _create_dummy_sandbox(self, *args, **kwargs): + reasons = [] + if not self._have_fuse: + reasons.append("FUSE is unavailable") + if not self._have_good_bwrap: + if self._bwrap_exists: + reasons.append("`bwrap` is too old (bst needs at least 0.1.2)") + else: + reasons.append("`bwrap` executable not found") + + kwargs['dummy_reason'] = " and ".join(reasons) + return SandboxDummy(*args, **kwargs) + + def _create_bwrap_sandbox(self, *args, **kwargs): + from ..sandbox._sandboxbwrap import SandboxBwrap + # Inform the bubblewrap sandbox as to whether it can use user namespaces or not + kwargs['user_ns_available'] = self._user_ns_available + kwargs['die_with_parent_available'] = self._die_with_parent_available + return SandboxBwrap(*args, **kwargs) def _check_user_ns_available(self): # Here, lets check if bwrap is able to create user namespaces, diff --git a/buildstream/_site.py b/buildstream/_site.py index ff169180f..30e1000d4 100644 --- a/buildstream/_site.py +++ b/buildstream/_site.py @@ -78,18 +78,12 @@ def check_bwrap_version(major, minor, patch): if not bwrap_path: return False cmd = [bwrap_path, "--version"] - version = str(subprocess.check_output(cmd).split()[1], "utf-8") + try: + version = str(subprocess.check_output(cmd).split()[1], "utf-8") + except subprocess.CalledProcessError: + # Failure trying to run bubblewrap + return False _bwrap_major, _bwrap_minor, _bwrap_patch = map(int, version.split(".")) # Check whether the installed version meets the requirements - if _bwrap_major > major: - return True - elif _bwrap_major < major: - return False - else: - if _bwrap_minor > minor: - return True - elif _bwrap_minor < minor: - return False - else: - return _bwrap_patch >= patch + return (_bwrap_major, _bwrap_minor, _bwrap_patch) >= (major, minor, patch) diff --git a/buildstream/sandbox/_sandboxdummy.py b/buildstream/sandbox/_sandboxdummy.py index 51239a4ea..29ff4bf69 100644 --- a/buildstream/sandbox/_sandboxdummy.py +++ b/buildstream/sandbox/_sandboxdummy.py @@ -23,6 +23,7 @@ from . import Sandbox class SandboxDummy(Sandbox): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + self._reason = kwargs.get("dummy_reason", "no reason given") def run(self, command, flags, *, cwd=None, env=None): @@ -37,4 +38,4 @@ class SandboxDummy(Sandbox): "'{}'".format(command[0]), reason='missing-command') - raise SandboxError("This platform does not support local builds") + raise SandboxError("This platform does not support local builds: {}".format(self._reason)) @@ -54,12 +54,13 @@ REQUIRED_BWRAP_MINOR = 1 REQUIRED_BWRAP_PATCH = 2 -def exit_bwrap(reason): +def warn_bwrap(reason): print(reason + - "\nBuildStream requires Bubblewrap (bwrap) for" - " sandboxing the build environment. Install it using your package manager" - " (usually bwrap or bubblewrap)") - sys.exit(1) + "\nBuildStream requires Bubblewrap (bwrap {}.{}.{} or better)," + " during local builds, for" + " sandboxing the build environment.\nInstall it using your package manager" + " (usually bwrap or bubblewrap) otherwise you will be limited to" + " remote builds only.".format(REQUIRED_BWRAP_MAJOR, REQUIRED_BWRAP_MINOR, REQUIRED_BWRAP_PATCH)) def bwrap_too_old(major, minor, patch): @@ -76,18 +77,19 @@ def bwrap_too_old(major, minor, patch): return False -def assert_bwrap(): +def check_for_bwrap(): platform = os.environ.get('BST_FORCE_BACKEND', '') or sys.platform if platform.startswith('linux'): bwrap_path = shutil.which('bwrap') if not bwrap_path: - exit_bwrap("Bubblewrap not found") + warn_bwrap("Bubblewrap not found") + return version_bytes = subprocess.check_output([bwrap_path, "--version"]).split()[1] version_string = str(version_bytes, "utf-8") major, minor, patch = map(int, version_string.split(".")) if bwrap_too_old(major, minor, patch): - exit_bwrap("Bubblewrap too old") + warn_bwrap("Bubblewrap too old") ########################################### @@ -126,7 +128,7 @@ bst_install_entry_points = { } if not os.environ.get('BST_ARTIFACTS_ONLY', ''): - assert_bwrap() + check_for_bwrap() bst_install_entry_points['console_scripts'] += [ 'bst = buildstream._frontend:cli' ] |