diff options
author | Jürg Billeter <j@bitron.ch> | 2020-02-03 19:42:22 +0000 |
---|---|---|
committer | Jürg Billeter <j@bitron.ch> | 2020-02-03 19:42:22 +0000 |
commit | 5c9da3a51e1906fd149ac5de4798ecb33795f7e1 (patch) | |
tree | 3a6c686b1a86898e8f24b7012ad4499cfd8193e3 | |
parent | 5e169159ebf45cabaf168bdf8b0e3c9d1e019bb5 (diff) | |
parent | dba3d8b0f7afe6ce7d43b6cbbb1477546a821c3f (diff) | |
download | buildstream-5c9da3a51e1906fd149ac5de4798ecb33795f7e1.tar.gz |
Merge branch 'juerg/buildbox-run-bind-mount' into 'master'
_sandboxbuildboxrun.py: Support host-files
See merge request BuildStream/buildstream!1807
-rw-r--r-- | src/buildstream/sandbox/_sandboxbuildboxrun.py | 34 | ||||
-rw-r--r-- | src/buildstream/sandbox/_sandboxreapi.py | 3 | ||||
-rw-r--r-- | tests/integration/shell.py | 15 |
3 files changed, 48 insertions, 4 deletions
diff --git a/src/buildstream/sandbox/_sandboxbuildboxrun.py b/src/buildstream/sandbox/_sandboxbuildboxrun.py index d542d39f8..93ee330b1 100644 --- a/src/buildstream/sandbox/_sandboxbuildboxrun.py +++ b/src/buildstream/sandbox/_sandboxbuildboxrun.py @@ -24,6 +24,7 @@ import psutil from .. import utils, _signals from . import SandboxFlags from .._exceptions import SandboxError +from .._message import Message, MessageType from .._protos.build.bazel.remote.execution.v2 import remote_execution_pb2 from ._sandboxreapi import SandboxREAPI @@ -40,11 +41,19 @@ class SandboxBuildBoxRun(SandboxREAPI): @classmethod def check_available(cls): try: - utils.get_host_tool("buildbox-run") + path = utils.get_host_tool("buildbox-run") except utils.ProgramNotFoundError as Error: cls._dummy_reasons += ["buildbox-run not found"] raise SandboxError(" and ".join(cls._dummy_reasons), reason="unavailable-local-sandbox") from Error + exit_code, output = utils._call([path, "--capabilities"], stdout=subprocess.PIPE) + if exit_code == 0: + # buildbox-run --capabilities prints one capability per line + cls._capabilities = set(output.split("\n")) + else: + # buildbox-run is too old to support extra capabilities + cls._capabilities = set() + @classmethod def check_sandbox_config(cls, platform, config): # Report error for elements requiring non-0 UID/GID @@ -78,11 +87,31 @@ class SandboxBuildBoxRun(SandboxREAPI): "--action-result={}".format(result_file.name), ] + marked_directories = self._get_marked_directories() + mount_sources = self._get_mount_sources() + for mark in marked_directories: + mount_point = mark["directory"] + mount_source = mount_sources.get(mount_point) + if not mount_source: + # Handled by the input tree in the action + continue + + if "bind-mount" not in self._capabilities: + self._warn("buildbox-run does not support host-files") + break + + buildbox_command.append("--bind-mount={}:{}".format(mount_source, mount_point)) + # If we're interactive, we want to inherit our stdin, # otherwise redirect to /dev/null, ensuring process # disconnected from terminal. if flags & SandboxFlags.INTERACTIVE: stdin = sys.stdin + + if "bind-mount" in self._capabilities: + # In interactive mode, we want a complete devpts inside + # the container, so there is a /dev/console and such. + buildbox_command.append("--bind-mount=/dev:/dev") else: stdin = subprocess.DEVNULL @@ -146,3 +175,6 @@ class SandboxBuildBoxRun(SandboxREAPI): if returncode != 0: raise SandboxError("buildbox-run failed with returncode {}".format(returncode)) + + def _warn(self, msg): + self._get_context().messenger.message(Message(MessageType.WARN, msg)) diff --git a/src/buildstream/sandbox/_sandboxreapi.py b/src/buildstream/sandbox/_sandboxreapi.py index 2430fd372..f1cd477d6 100644 --- a/src/buildstream/sandbox/_sandboxreapi.py +++ b/src/buildstream/sandbox/_sandboxreapi.py @@ -59,8 +59,11 @@ class SandboxREAPI(Sandbox): # Create directories for all marked directories. This emulates # some of the behaviour of other sandboxes, which create these # to use as mount points. + mount_sources = self._get_mount_sources() for mark in self._get_marked_directories(): directory = mark["directory"] + if directory in mount_sources: + continue # Create each marked directory vdir.descend(*directory.split(os.path.sep), create=True) diff --git a/tests/integration/shell.py b/tests/integration/shell.py index 5e35d550c..c4725ec07 100644 --- a/tests/integration/shell.py +++ b/tests/integration/shell.py @@ -162,7 +162,10 @@ def test_no_shell(cli, datafiles): @pytest.mark.parametrize("path", [("/etc/pony.conf"), ("/usr/share/pony/pony.txt")]) @pytest.mark.datafiles(DATA_DIR) @pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox") -@pytest.mark.xfail(HAVE_SANDBOX == "buildbox-run", reason="Not working with BuildBox") +@pytest.mark.xfail( + HAVE_SANDBOX == "buildbox-run" and BUILDBOX_RUN != "buildbox-run-bubblewrap", + reason="Only available with bubblewrap", +) def test_host_files(cli, datafiles, path): project = str(datafiles) ponyfile = os.path.join(project, "files", "shell-mount", "pony.txt") @@ -177,7 +180,10 @@ def test_host_files(cli, datafiles, path): @pytest.mark.parametrize("path", [("/etc"), ("/usr/share/pony")]) @pytest.mark.datafiles(DATA_DIR) @pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox") -@pytest.mark.xfail(HAVE_SANDBOX == "buildbox-run", reason="Not working with BuildBox") +@pytest.mark.xfail( + HAVE_SANDBOX == "buildbox-run" and BUILDBOX_RUN != "buildbox-run-bubblewrap", + reason="Only available with bubblewrap", +) def test_host_files_expand_environ(cli, datafiles, path): project = str(datafiles) hostpath = os.path.join(project, "files", "shell-mount") @@ -250,7 +256,10 @@ def test_host_files_missing(cli, datafiles, optional): @pytest.mark.parametrize("path", [("/etc/pony.conf"), ("/usr/share/pony/pony.txt")]) @pytest.mark.datafiles(DATA_DIR) @pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox") -@pytest.mark.xfail(HAVE_SANDBOX == "buildbox-run", reason="Not working with BuildBox") +@pytest.mark.xfail( + HAVE_SANDBOX == "buildbox-run" and BUILDBOX_RUN != "buildbox-run-bubblewrap", + reason="Only available with bubblewrap", +) def test_cli_mount(cli, datafiles, path): project = str(datafiles) ponyfile = os.path.join(project, "files", "shell-mount", "pony.txt") |