summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--buildstream/element.py28
1 files changed, 28 insertions, 0 deletions
diff --git a/buildstream/element.py b/buildstream/element.py
index 48d75274f..7c94354f5 100644
--- a/buildstream/element.py
+++ b/buildstream/element.py
@@ -38,6 +38,7 @@ from . import _yaml
from ._variables import Variables
from ._versions import BST_CORE_ARTIFACT_VERSION
from ._exceptions import BstError, LoadError, LoadErrorReason, ImplError, ErrorDomain
+from .utils import UtilError
from . import Plugin, Consistency
from . import SandboxFlags
from . import utils
@@ -162,6 +163,7 @@ class Element(Plugin):
self.__log_path = None # Path to dedicated log file or None
self.__splits = None
self.__whitelist_regex = None
+ self.__staged_sources_directory = None # Location where Element.stage_sources() was called
# Ensure we have loaded this class's defaults
self.__init_defaults(plugin_conf)
@@ -613,6 +615,13 @@ class Element(Plugin):
directory (str): An absolute path within the sandbox to stage the sources at
"""
+ # Hold on to the location where a plugin decided to stage sources,
+ # this will be used to reconstruct the failed sysroot properly
+ # after a failed build.
+ #
+ assert self.__staged_sources_directory is None
+ self.__staged_sources_directory = directory
+
self._stage_sources_in_sandbox(sandbox, directory)
def get_public_data(self, domain):
@@ -1177,6 +1186,25 @@ class Element(Plugin):
# If an error occurred assembling an element in a sandbox,
# then tack on the sandbox directory to the error
e.sandbox = rootdir
+
+ # If there is a workspace open on this element, it will have
+ # been mounted for sandbox invocations instead of being staged.
+ #
+ # In order to preserve the correct failure state, we need to
+ # copy over the workspace files into the appropriate directory
+ # in the sandbox.
+ #
+ workspace = self._get_workspace()
+ if workspace and self.__staged_sources_directory:
+ sandbox_root = sandbox.get_directory()
+ sandbox_path = os.path.join(sandbox_root,
+ self.__staged_sources_directory.lstrip(os.sep))
+ try:
+ utils.copy_files(workspace.path, sandbox_path)
+ except UtilError as e:
+ self.warn("Failed to preserve workspace state for failed build sysroot: {}"
+ .format(e))
+
raise
collectdir = os.path.join(sandbox_root, collect.lstrip(os.sep))