summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJürg Billeter <j@bitron.ch>2018-10-04 09:45:58 +0000
committerJürg Billeter <j@bitron.ch>2018-10-04 09:45:58 +0000
commitfd6a957366e5abe3cddc225118969205000e182d (patch)
treeaae0773b6169681fe86df5798bb2e1437642f46e
parent3cf38c8e0a1828ed7ba6b5ec125c415a40da7f21 (diff)
parentc46a7e878ad94c856083fc84dbc09fc9f6126ff3 (diff)
downloadbuildstream-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.py3
-rw-r--r--buildstream/_platform/linux.py45
-rw-r--r--buildstream/_site.py18
-rw-r--r--buildstream/sandbox/_sandboxdummy.py3
-rwxr-xr-xsetup.py20
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))
diff --git a/setup.py b/setup.py
index 405a39061..74ccfc24a 100755
--- a/setup.py
+++ b/setup.py
@@ -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'
]