Daniel pushed to branch danielsilverstone-ct/bwrap-check-runtime-only at BuildStream / buildstream
Commits:
-
df0d5a8b
by Daniel Silverstone at 2018-10-04T09:04:21Z
-
b8421a9c
by Daniel Silverstone at 2018-10-04T09:04:21Z
-
c74bfbe5
by Daniel Silverstone at 2018-10-04T09:04:21Z
-
32d2ad8f
by Daniel Silverstone at 2018-10-04T09:04:21Z
3 changed files:
Changes:
... | ... | @@ -37,25 +37,27 @@ class Linux(Platform): |
37 | 37 |
self._uid = os.geteuid()
|
38 | 38 |
self._gid = os.getegid()
|
39 | 39 |
|
40 |
+ self._have_fuse = os.path.exists("/dev/fuse")
|
|
41 |
+ self._bwrap_exists = _site.check_bwrap_version(0, 0, 0)
|
|
42 |
+ self._have_good_bwrap = _site.check_bwrap_version(0, 1, 2)
|
|
43 |
+ |
|
44 |
+ self._local_sandbox_available = self._have_fuse and self._have_good_bwrap
|
|
45 |
+ |
|
40 | 46 |
self._die_with_parent_available = _site.check_bwrap_version(0, 1, 8)
|
41 | 47 |
|
42 |
- if self._local_sandbox_available():
|
|
48 |
+ if self._local_sandbox_available:
|
|
43 | 49 |
self._user_ns_available = self._check_user_ns_available()
|
44 | 50 |
else:
|
45 | 51 |
self._user_ns_available = False
|
46 | 52 |
|
47 | 53 |
def create_sandbox(self, *args, **kwargs):
|
48 |
- if not self._local_sandbox_available():
|
|
49 |
- return SandboxDummy(*args, **kwargs)
|
|
54 |
+ if not self._local_sandbox_available:
|
|
55 |
+ return self._create_dummy_sandbox(*args, **kwargs)
|
|
50 | 56 |
else:
|
51 |
- from ..sandbox._sandboxbwrap import SandboxBwrap
|
|
52 |
- # Inform the bubblewrap sandbox as to whether it can use user namespaces or not
|
|
53 |
- kwargs['user_ns_available'] = self._user_ns_available
|
|
54 |
- kwargs['die_with_parent_available'] = self._die_with_parent_available
|
|
55 |
- return SandboxBwrap(*args, **kwargs)
|
|
57 |
+ return self._create_bwrap_sandbox(*args, **kwargs)
|
|
56 | 58 |
|
57 | 59 |
def check_sandbox_config(self, config):
|
58 |
- if not self._local_sandbox_available():
|
|
60 |
+ if not self._local_sandbox_available:
|
|
59 | 61 |
# Accept all sandbox configs as it's irrelevant with the dummy sandbox (no Sandbox.run).
|
60 | 62 |
return True
|
61 | 63 |
|
... | ... | @@ -70,11 +72,26 @@ class Linux(Platform): |
70 | 72 |
################################################
|
71 | 73 |
# Private Methods #
|
72 | 74 |
################################################
|
73 |
- def _local_sandbox_available(self):
|
|
74 |
- try:
|
|
75 |
- return os.path.exists(utils.get_host_tool('bwrap')) and os.path.exists('/dev/fuse')
|
|
76 |
- except utils.ProgramNotFoundError:
|
|
77 |
- return False
|
|
75 |
+ |
|
76 |
+ def _create_dummy_sandbox(self, *args, **kwargs):
|
|
77 |
+ reasons = []
|
|
78 |
+ if not self._have_fuse:
|
|
79 |
+ reasons.append("FUSE is unavailable")
|
|
80 |
+ if not self._have_good_bwrap:
|
|
81 |
+ if self._bwrap_exists:
|
|
82 |
+ reasons.append("`bwrap` is too old (bst needs at least 0.1.2)")
|
|
83 |
+ else:
|
|
84 |
+ reasons.append("`bwrap` executable not found")
|
|
85 |
+ |
|
86 |
+ kwargs['dummy_reason'] = " and ".join(reasons)
|
|
87 |
+ return SandboxDummy(*args, **kwargs)
|
|
88 |
+ |
|
89 |
+ def _create_bwrap_sandbox(self, *args, **kwargs):
|
|
90 |
+ from ..sandbox._sandboxbwrap import SandboxBwrap
|
|
91 |
+ # Inform the bubblewrap sandbox as to whether it can use user namespaces or not
|
|
92 |
+ kwargs['user_ns_available'] = self._user_ns_available
|
|
93 |
+ kwargs['die_with_parent_available'] = self._die_with_parent_available
|
|
94 |
+ return SandboxBwrap(*args, **kwargs)
|
|
78 | 95 |
|
79 | 96 |
def _check_user_ns_available(self):
|
80 | 97 |
# Here, lets check if bwrap is able to create user namespaces,
|
... | ... | @@ -78,18 +78,12 @@ def check_bwrap_version(major, minor, patch): |
78 | 78 |
if not bwrap_path:
|
79 | 79 |
return False
|
80 | 80 |
cmd = [bwrap_path, "--version"]
|
81 |
- version = str(subprocess.check_output(cmd).split()[1], "utf-8")
|
|
81 |
+ try:
|
|
82 |
+ version = str(subprocess.check_output(cmd).split()[1], "utf-8")
|
|
83 |
+ except subprocess.CalledProcessError:
|
|
84 |
+ # Failure trying to run bubblewrap
|
|
85 |
+ return False
|
|
82 | 86 |
_bwrap_major, _bwrap_minor, _bwrap_patch = map(int, version.split("."))
|
83 | 87 |
|
84 | 88 |
# Check whether the installed version meets the requirements
|
85 |
- if _bwrap_major > major:
|
|
86 |
- return True
|
|
87 |
- elif _bwrap_major < major:
|
|
88 |
- return False
|
|
89 |
- else:
|
|
90 |
- if _bwrap_minor > minor:
|
|
91 |
- return True
|
|
92 |
- elif _bwrap_minor < minor:
|
|
93 |
- return False
|
|
94 |
- else:
|
|
95 |
- return _bwrap_patch >= patch
|
|
89 |
+ return (_bwrap_major, _bwrap_minor, _bwrap_patch) >= (major, minor, patch)
|
... | ... | @@ -54,12 +54,13 @@ REQUIRED_BWRAP_MINOR = 1 |
54 | 54 |
REQUIRED_BWRAP_PATCH = 2
|
55 | 55 |
|
56 | 56 |
|
57 |
-def exit_bwrap(reason):
|
|
57 |
+def warn_bwrap(reason):
|
|
58 | 58 |
print(reason +
|
59 |
- "\nBuildStream requires Bubblewrap (bwrap) for"
|
|
60 |
- " sandboxing the build environment. Install it using your package manager"
|
|
61 |
- " (usually bwrap or bubblewrap)")
|
|
62 |
- sys.exit(1)
|
|
59 |
+ "\nBuildStream requires Bubblewrap (bwrap {}.{}.{} or better),"
|
|
60 |
+ " during local builds, for"
|
|
61 |
+ " sandboxing the build environment.\nInstall it using your package manager"
|
|
62 |
+ " (usually bwrap or bubblewrap) otherwise you will be limited to"
|
|
63 |
+ " remote builds only.".format(REQUIRED_BWRAP_MAJOR, REQUIRED_BWRAP_MINOR, REQUIRED_BWRAP_PATCH))
|
|
63 | 64 |
|
64 | 65 |
|
65 | 66 |
def bwrap_too_old(major, minor, patch):
|
... | ... | @@ -76,18 +77,19 @@ def bwrap_too_old(major, minor, patch): |
76 | 77 |
return False
|
77 | 78 |
|
78 | 79 |
|
79 |
-def assert_bwrap():
|
|
80 |
+def check_for_bwrap():
|
|
80 | 81 |
platform = os.environ.get('BST_FORCE_BACKEND', '') or sys.platform
|
81 | 82 |
if platform.startswith('linux'):
|
82 | 83 |
bwrap_path = shutil.which('bwrap')
|
83 | 84 |
if not bwrap_path:
|
84 |
- exit_bwrap("Bubblewrap not found")
|
|
85 |
+ warn_bwrap("Bubblewrap not found")
|
|
86 |
+ return
|
|
85 | 87 |
|
86 | 88 |
version_bytes = subprocess.check_output([bwrap_path, "--version"]).split()[1]
|
87 | 89 |
version_string = str(version_bytes, "utf-8")
|
88 | 90 |
major, minor, patch = map(int, version_string.split("."))
|
89 | 91 |
if bwrap_too_old(major, minor, patch):
|
90 |
- exit_bwrap("Bubblewrap too old")
|
|
92 |
+ warn_bwrap("Bubblewrap too old")
|
|
91 | 93 |
|
92 | 94 |
|
93 | 95 |
###########################################
|
... | ... | @@ -126,7 +128,7 @@ bst_install_entry_points = { |
126 | 128 |
}
|
127 | 129 |
|
128 | 130 |
if not os.environ.get('BST_ARTIFACTS_ONLY', ''):
|
129 |
- assert_bwrap()
|
|
131 |
+ check_for_bwrap()
|
|
130 | 132 |
bst_install_entry_points['console_scripts'] += [
|
131 | 133 |
'bst = buildstream._frontend:cli'
|
132 | 134 |
]
|