diff options
author | Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> | 2017-10-31 18:41:20 +0900 |
---|---|---|
committer | Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> | 2017-10-31 20:16:37 +0900 |
commit | a9a2bcece3b90092d9260f5c46675a0e17df381d (patch) | |
tree | 76583989b3680b00ed85658927d60561bed3abbb | |
parent | 40f5fe7789d4085183717cfc158297959d8b380b (diff) | |
download | buildstream-a9a2bcece3b90092d9260f5c46675a0e17df381d.tar.gz |
_platform/linux.py: Add preflight check to detect user namespaces
Here we check if `bwrap --ro-bind / / --unshare-user --uid 0 --gid 0 whoami`
returns successfully and prints 'root', to check if we are indeed capable
of creating user namespaces on the host.
If we are unable, then we save that state in the platform allowing
buildstream to behave differently, and print an informative startup
warning about this.
This fixes issue #92
-rw-r--r-- | buildstream/_platform/linux.py | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/buildstream/_platform/linux.py b/buildstream/_platform/linux.py index 38afc5423..c94e3632d 100644 --- a/buildstream/_platform/linux.py +++ b/buildstream/_platform/linux.py @@ -20,8 +20,11 @@ import os import sys +import subprocess from .. import utils +from .. import PlatformError +from .._message import Message, MessageType from ..sandbox import SandboxBwrap from .._artifactcache.ostreecache import OSTreeCache @@ -33,11 +36,47 @@ class Linux(Platform): def __init__(self, context, project): super().__init__(context, project) - self._artifact_cache = OSTreeCache(context, project) + + self._user_ns_available = False + self.check_user_ns_available(context) + self._artifact_cache = OSTreeCache(context, project, self._user_ns_available) + + def check_user_ns_available(self, context): + + # Here, lets check if bwrap is able to create user namespaces, + # issue a warning if it's not available, and save the state + # locally so that we can inform the sandbox to not try it + # later on. + bwrap = utils.get_host_tool('bwrap') + whoami = utils.get_host_tool('whoami') + try: + output = subprocess.check_output([ + bwrap, + '--ro-bind', '/', '/', + '--unshare-user', + '--uid', '0', '--gid', '0', + whoami, + ]) + output = output.decode('UTF-8').strip() + except subprocess.CalledProcessError: + output = '' + + if output == 'root': + self._user_ns_available = True + + # Issue a warning + if not self._user_ns_available: + context._message( + Message(None, MessageType.WARN, + "Unable to create user namespaces with bubblewrap, resorting to fallback", + detail="Some builds may not function due to lack of uid / gid 0, " + + "artifacts created will not be trusted for push purposes.")) @property def artifactcache(self): return self._artifact_cache def create_sandbox(self, *args, **kwargs): + # Inform the bubblewrap sandbox as to whether it can use user namespaces or not + kwargs['user_ns_available'] = self._user_ns_available return SandboxBwrap(*args, **kwargs) |