summaryrefslogtreecommitdiff
path: root/buildstream/sandbox/sandbox.py
diff options
context:
space:
mode:
Diffstat (limited to 'buildstream/sandbox/sandbox.py')
-rw-r--r--buildstream/sandbox/sandbox.py76
1 files changed, 66 insertions, 10 deletions
diff --git a/buildstream/sandbox/sandbox.py b/buildstream/sandbox/sandbox.py
index 3ab75f1a8..f3cab41ec 100644
--- a/buildstream/sandbox/sandbox.py
+++ b/buildstream/sandbox/sandbox.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python3
#
# Copyright (C) 2017 Codethink Limited
#
@@ -19,9 +18,8 @@
# Andrew Leeming <andrew.leeming@codethink.co.uk>
# Tristan Van Berkom <tristan.vanberkom@codethink.co.uk>
"""
-Sandbox
-=======
-
+Sandbox - The build sandbox
+===========================
:class:`.Element` plugins which want to interface with the sandbox
need only understand this interface, while it may be given a different
sandbox implementation, any sandbox implementation it is given will
@@ -31,7 +29,8 @@ See also: :ref:`sandboxing`.
"""
import os
-from .._exceptions import ImplError
+from .._exceptions import ImplError, BstError
+from ..storage._filebaseddirectory import FileBasedDirectory
class SandboxFlags():
@@ -92,28 +91,63 @@ class Sandbox():
self.__cwd = None
self.__env = None
self.__mount_sources = {}
+ self.__allow_real_directory = kwargs['allow_real_directory']
+
# Configuration from kwargs common to all subclasses
self.__config = kwargs['config']
self.__stdout = kwargs['stdout']
self.__stderr = kwargs['stderr']
- # Setup the directories
+ # Setup the directories. Root should be available to subclasses, hence
+ # being single-underscore. The others are private to this class.
+ self._root = os.path.join(directory, 'root')
self.__directory = directory
- self.__root = os.path.join(self.__directory, 'root')
self.__scratch = os.path.join(self.__directory, 'scratch')
- for directory_ in [self.__root, self.__scratch]:
+ for directory_ in [self._root, self.__scratch]:
os.makedirs(directory_, exist_ok=True)
def get_directory(self):
"""Fetches the sandbox root directory
The root directory is where artifacts for the base
- runtime environment should be staged.
+ runtime environment should be staged. Only works if
+ BST_VIRTUAL_DIRECTORY is not set.
Returns:
(str): The sandbox root directory
+
"""
- return self.__root
+ if self.__allow_real_directory:
+ return self._root
+ else:
+ raise BstError("You can't use get_directory")
+
+ def get_virtual_directory(self):
+ """Fetches the sandbox root directory
+
+ The root directory is where artifacts for the base
+ runtime environment should be staged. Only works if
+ BST_VIRTUAL_DIRECTORY is not set.
+
+ Returns:
+ (str): The sandbox root directory
+
+ """
+ # For now, just create a new Directory every time we're asked
+ return FileBasedDirectory(self._root)
+
+ def get_virtual_toplevel_directory(self):
+ """Fetches the sandbox's toplevel directory
+
+ The toplevel directory contains 'root', 'scratch' and later
+ 'artifact' where output is copied to.
+
+ Returns:
+ (str): The sandbox toplevel directory
+
+ """
+ # For now, just create a new Directory every time we're asked
+ return FileBasedDirectory(self.__directory)
def set_environment(self, environment):
"""Sets the environment variables for the sandbox
@@ -281,3 +315,25 @@ class Sandbox():
# data passed in during construction.
def _get_config(self):
return self.__config
+
+ # _has_command()
+ #
+ # Tests whether a command exists inside the sandbox
+ #
+ # Args:
+ # command (list): The command to test.
+ # env (dict): A dictionary of string key, value pairs to set as environment
+ # variables inside the sandbox environment.
+ # Returns:
+ # (bool): Whether a command exists inside the sandbox.
+ def _has_command(self, command, env=None):
+ if os.path.isabs(command):
+ return os.path.exists(os.path.join(
+ self.get_directory(), command.lstrip(os.sep)))
+
+ for path in env.get('PATH').split(':'):
+ if os.path.exists(os.path.join(
+ self.get_directory(), path.lstrip(os.sep), command)):
+ return True
+
+ return False