diff options
author | Richard Maw <richard.maw@codethink.co.uk> | 2018-09-04 14:37:54 +0100 |
---|---|---|
committer | Tristan Van Berkom <tristan.van.berkom@gmail.com> | 2018-09-18 13:22:38 +0000 |
commit | d042560842ce504bb57605b1388ccc7daaa16c66 (patch) | |
tree | e82ce765da3061b768e9bcd135df19f5f1d012aa | |
parent | 081dcafa03f1b2604ce52e9dc5be696444d8f71e (diff) | |
download | buildstream-d042560842ce504bb57605b1388ccc7daaa16c66.tar.gz |
FUSE: Mount with -odev in chroot sandbox
This is needed to permit access to the device nodes added to /dev
on Linux when FUSE is used as root.
The chroot sandbox only works with all privileges,
so there's no explicit check for being root
or having the appropriate capabilities.
A check for whether it's running as root isn't needed on Linux with bubblewrap
because /dev or its devices are mounted on top of the FUSE layer,
so device nodes are accessed directly rather than through the FUSE layer.
-rw-r--r-- | buildstream/_fuse/hardlinks.py | 3 | ||||
-rw-r--r-- | buildstream/_fuse/mount.py | 6 | ||||
-rw-r--r-- | buildstream/sandbox/_mount.py | 11 | ||||
-rw-r--r-- | buildstream/sandbox/_sandboxchroot.py | 6 |
4 files changed, 18 insertions, 8 deletions
diff --git a/buildstream/_fuse/hardlinks.py b/buildstream/_fuse/hardlinks.py index f9e2b959b..0797cb4bc 100644 --- a/buildstream/_fuse/hardlinks.py +++ b/buildstream/_fuse/hardlinks.py @@ -42,9 +42,10 @@ from .mount import Mount # class SafeHardlinks(Mount): - def __init__(self, directory, tempdir): + def __init__(self, directory, tempdir, fuse_mount_options={}): self.directory = directory self.tempdir = tempdir + super().__init__(fuse_mount_options=fuse_mount_options) def create_operations(self): return SafeHardlinkOps(self.directory, self.tempdir) diff --git a/buildstream/_fuse/mount.py b/buildstream/_fuse/mount.py index 0ab1ce715..30cc85b77 100644 --- a/buildstream/_fuse/mount.py +++ b/buildstream/_fuse/mount.py @@ -87,6 +87,9 @@ class Mount(): # User Facing API # ################################################ + def __init__(self, fuse_mount_options={}): + self._fuse_mount_options = fuse_mount_options + # mount(): # # User facing API for mounting a fuse subclass implementation @@ -184,7 +187,8 @@ class Mount(): # Run fuse in foreground in this child process, internally libfuse # will handle SIGTERM and gracefully exit it's own little main loop. # - FUSE(self.__operations, self.__mountpoint, nothreads=True, foreground=True, nonempty=True) + FUSE(self.__operations, self.__mountpoint, nothreads=True, foreground=True, nonempty=True, + **self._fuse_mount_options) # Explicit 0 exit code, if the operations crashed for some reason, the exit # code will not be 0, and we want to know about it. diff --git a/buildstream/sandbox/_mount.py b/buildstream/sandbox/_mount.py index 49068fe92..4fca3d1b0 100644 --- a/buildstream/sandbox/_mount.py +++ b/buildstream/sandbox/_mount.py @@ -30,7 +30,7 @@ from .._fuse import SafeHardlinks # Helper data object representing a single mount point in the mount map # class Mount(): - def __init__(self, sandbox, mount_point, safe_hardlinks): + def __init__(self, sandbox, mount_point, safe_hardlinks, fuse_mount_options={}): scratch_directory = sandbox._get_scratch_directory() # Getting _get_underlying_directory() here is acceptable as # we're part of the sandbox code. This will fail if our @@ -39,6 +39,7 @@ class Mount(): self.mount_point = mount_point self.safe_hardlinks = safe_hardlinks + self._fuse_mount_options = fuse_mount_options # FIXME: When the criteria for mounting something and it's parent # mount is identical, then there is no need to mount an additional @@ -82,7 +83,7 @@ class Mount(): @contextmanager def mounted(self, sandbox): if self.safe_hardlinks: - mount = SafeHardlinks(self.mount_origin, self.mount_tempdir) + mount = SafeHardlinks(self.mount_origin, self.mount_tempdir, self._fuse_mount_options) with mount.mounted(self.mount_source): yield else: @@ -100,12 +101,12 @@ class Mount(): # class MountMap(): - def __init__(self, sandbox, root_readonly): + def __init__(self, sandbox, root_readonly, fuse_mount_options={}): # We will be doing the mounts in the order in which they were declared. self.mounts = OrderedDict() # We want safe hardlinks on rootfs whenever root is not readonly - self.mounts['/'] = Mount(sandbox, '/', not root_readonly) + self.mounts['/'] = Mount(sandbox, '/', not root_readonly, fuse_mount_options) for mark in sandbox._get_marked_directories(): directory = mark['directory'] @@ -113,7 +114,7 @@ class MountMap(): # We want safe hardlinks for any non-root directory where # artifacts will be staged to - self.mounts[directory] = Mount(sandbox, directory, artifact) + self.mounts[directory] = Mount(sandbox, directory, artifact, fuse_mount_options) # get_mount_source() # diff --git a/buildstream/sandbox/_sandboxchroot.py b/buildstream/sandbox/_sandboxchroot.py index 64fb3c1bc..b3a2a6d9d 100644 --- a/buildstream/sandbox/_sandboxchroot.py +++ b/buildstream/sandbox/_sandboxchroot.py @@ -35,6 +35,9 @@ from . import Sandbox, SandboxFlags class SandboxChroot(Sandbox): + + _FUSE_MOUNT_OPTIONS = {'dev': True} + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -67,7 +70,8 @@ class SandboxChroot(Sandbox): # Create the mount map, this will tell us where # each mount point needs to be mounted from and to - self.mount_map = MountMap(self, flags & SandboxFlags.ROOT_READ_ONLY) + self.mount_map = MountMap(self, flags & SandboxFlags.ROOT_READ_ONLY, + self._FUSE_MOUNT_OPTIONS) root_mount_source = self.mount_map.get_mount_source('/') # Create a sysroot and run the command inside it |