diff options
author | Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> | 2018-02-22 22:39:52 +0900 |
---|---|---|
committer | Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> | 2018-02-23 01:52:50 +0900 |
commit | b696d36386b3ec0a57d1eda72449d4bcee2bd227 (patch) | |
tree | 67a345f00630b50a524fd0bfa16817469d683293 /buildstream | |
parent | 11f2de77287ff06d60b88452aa125a37de375030 (diff) | |
download | buildstream-b696d36386b3ec0a57d1eda72449d4bcee2bd227.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
Diffstat (limited to 'buildstream')
-rw-r--r-- | buildstream/_frontend/cli.py | 14 | ||||
-rw-r--r-- | buildstream/_frontend/main.py | 2 | ||||
-rw-r--r-- | buildstream/element.py | 20 |
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: |