summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2018-02-22 22:39:52 +0900
committerTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2018-02-23 01:52:50 +0900
commitb696d36386b3ec0a57d1eda72449d4bcee2bd227 (patch)
tree67a345f00630b50a524fd0bfa16817469d683293
parent11f2de77287ff06d60b88452aa125a37de375030 (diff)
downloadbuildstream-tristan/isolate-shell.tar.gz
bst shell: Added --isolate option, disabled by default.tristan/isolate-shell
This changes a few things: o How the shell environment and sandbox modes are setup is not decided by whether a `--build` sandbox was staged or not o In interactive build debugging mode, an isolated build sandbox is used o The bst shell command now has the option to control it o All invocations of bst shell now use a read-only rootfs, avoiding FUSE layer and file descriptor limits (this can be made optional later if needed) This is a part of issue #223
-rw-r--r--buildstream/_frontend/cli.py14
-rw-r--r--buildstream/_frontend/main.py2
-rw-r--r--buildstream/element.py20
3 files changed, 19 insertions, 17 deletions
diff --git a/buildstream/_frontend/cli.py b/buildstream/_frontend/cli.py
index 9d203427f..c5fc87bab 100644
--- a/buildstream/_frontend/cli.py
+++ b/buildstream/_frontend/cli.py
@@ -458,20 +458,22 @@ def show(app, elements, deps, except_, order, format, downloadable):
##################################################################
@cli.command(short_help="Shell into an element's sandbox environment")
@click.option('--build', '-b', is_flag=True, default=False,
- help='Create a build sandbox')
+ help='Stage dependencies and sources to build')
@click.option('--sysroot', '-s', default=None,
type=click.Path(exists=True, file_okay=False, readable=True),
help="An existing sysroot")
+@click.option('--isolate', is_flag=True, default=False,
+ help='Create an isolated build sandbox')
@click.argument('element',
type=click.Path(dir_okay=False, readable=True))
@click.argument('command', type=click.STRING, nargs=-1)
@click.pass_obj
-def shell(app, element, sysroot, build, command):
+def shell(app, element, sysroot, isolate, build, command):
"""Run a command in the target element's sandbox environment
- This will first stage a temporary sysroot for running
- the target element, assuming it has already been built
- and all required artifacts are in the local cache.
+ This will stage a temporary sysroot for running the target
+ element, assuming it has already been built and all required
+ artifacts are in the local cache.
Use the --build option to create a temporary sysroot for
building the element instead.
@@ -508,7 +510,7 @@ def shell(app, element, sysroot, build, command):
sys.exit(-1)
try:
- exitcode = app.pipeline.targets[0]._shell(scope, sysroot, command=command)
+ exitcode = app.pipeline.targets[0]._shell(scope, sysroot, isolate=isolate, command=command)
sys.exit(exitcode)
except BstError as e:
click.echo("", err=True)
diff --git a/buildstream/_frontend/main.py b/buildstream/_frontend/main.py
index 9cab22c4a..dc251748d 100644
--- a/buildstream/_frontend/main.py
+++ b/buildstream/_frontend/main.py
@@ -342,7 +342,7 @@ class App():
if choice == 'shell':
click.echo("\nDropping into an interactive shell in the failed build sandbox\n", err=True)
try:
- element._shell(Scope.BUILD, failure.sandbox)
+ element._shell(Scope.BUILD, failure.sandbox, isolate=True)
except BstError as e:
click.echo("Error while attempting to create interactive shell: {}".format(e), err=True)
elif choice == 'log':
diff --git a/buildstream/element.py b/buildstream/element.py
index c43701d09..f0df03b26 100644
--- a/buildstream/element.py
+++ b/buildstream/element.py
@@ -1368,18 +1368,25 @@ class Element(Plugin):
# Args:
# scope (Scope): Either BUILD or RUN scopes are valid, or None
# directory (str): A directory to an existing sandbox, or None
+ # isolate (bool): Whether to isolate the environment like we do in builds
# command (list): An argv to launch in the sandbox
#
# Returns: Exit code
#
# If directory is not specified, one will be staged using scope
- def _shell(self, scope=None, directory=None, command=None):
+ def _shell(self, scope=None, directory=None, isolate=False, command=None):
with self._prepare_sandbox(scope, directory) as sandbox:
environment = self.get_environment()
- flags = SandboxFlags.INTERACTIVE
+ flags = SandboxFlags.INTERACTIVE | SandboxFlags.ROOT_READ_ONLY
+
+ # Special configurations for non-isolated sandboxes
+ if not isolate:
+
+ # Open the network, and reuse calling uid/gid
+ #
+ flags |= SandboxFlags.NETWORK_ENABLED | SandboxFlags.INHERIT_UID
- if scope == Scope.RUN:
# If a testing sandbox was requested, override the element environment
# with some of the host environment and use that for the shell.
#
@@ -1390,13 +1397,6 @@ class Element(Plugin):
if os.environ.get(override) is not None:
environment[override] = os.environ.get(override)
- # Decide whether to create a build style sandbox or an open
- # testing sandbox based on whether the build scope was requested
- if scope == Scope.BUILD:
- flags |= SandboxFlags.ROOT_READ_ONLY
- elif scope == Scope.RUN:
- flags |= SandboxFlags.NETWORK_ENABLED | SandboxFlags.INHERIT_UID
-
if command:
argv = [arg for arg in command]
else: