diff options
author | Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> | 2018-04-11 18:06:37 +0900 |
---|---|---|
committer | Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> | 2018-04-11 18:11:33 +0900 |
commit | 6076969ae979a348abece53fdb26c7ab3c0db085 (patch) | |
tree | 51d52f7189b9b096a43a89ecd52e81c91357b714 | |
parent | cb38665143e6a93f21a08416c869f996b528459f (diff) | |
download | buildstream-6076969ae979a348abece53fdb26c7ab3c0db085.tar.gz |
element.py: Preserve workspace state in failed build sandboxes.
As reported in regression #346, since we started mounting the workspaces
we now fail to debug build failures for workspaces, the shell command
no longer sees the workspaces files to debug.
As the failed sysroot represents a very particular build failure, it
is incorrect to attempt to remount a workspace again after a failed
build, as the workspace files may have changed since the build.
Instead, in the case of a build failure on a workspaced element, we
copy the files from the workspace in place (while automatically preserving
the mtimes and everything, as utils.safe_copy() does).
When we implement failed build artifacts, this case will have to be
handled in a very similar way, too.
This fixes issue #346
-rw-r--r-- | buildstream/element.py | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/buildstream/element.py b/buildstream/element.py index 48d75274f..3e99d2844 100644 --- a/buildstream/element.py +++ b/buildstream/element.py @@ -162,6 +162,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 +614,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 +1185,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)) |