summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2017-10-31 18:41:20 +0900
committerTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2017-10-31 20:16:37 +0900
commita9a2bcece3b90092d9260f5c46675a0e17df381d (patch)
tree76583989b3680b00ed85658927d60561bed3abbb
parent40f5fe7789d4085183717cfc158297959d8b380b (diff)
downloadbuildstream-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.py41
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)