summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2017-05-24 17:50:00 +0900
committerTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2017-05-24 17:50:00 +0900
commitca9a8837dd00a283fd8a9cca1760588640d23571 (patch)
treeff5546440ff4f4f4421b0256832b68b94c5cf162
parentf82a9be8f50490afa972468b1dad9aa5a5f7d5fb (diff)
downloadbuildstream-ca9a8837dd00a283fd8a9cca1760588640d23571.tar.gz
script element: interim hacks
We will soon be refactoring this element to be more widely useful, in the meantime I needed the following changes: o Make staging of the input element optional o Dont mount the root read-only o Allow configuration of where to collect the output artifact This was needed for a straight forward use case where the user wants to A.) Stage something in the root B.) Modify that sysroot by running some commands C.) Collect the entire resulting sysroot as an artifact In this case, I needed to be able to run `dpkg --configure -a` in a sysroot and collect the result.
-rw-r--r--buildstream/plugins/elements/script.py54
-rw-r--r--buildstream/plugins/elements/script.yaml4
2 files changed, 33 insertions, 25 deletions
diff --git a/buildstream/plugins/elements/script.py b/buildstream/plugins/elements/script.py
index d00fe53a0..f1c301056 100644
--- a/buildstream/plugins/elements/script.py
+++ b/buildstream/plugins/elements/script.py
@@ -42,11 +42,12 @@ class ScriptElement(Element):
def configure(self, node):
self.base_dep = self.node_get_member(node, str, 'base')
- self.input_dep = self.node_get_member(node, str, 'input')
+ self.input_dep = self.node_get_member(node, str, 'input', '') or None
self.stage_mode = self.node_get_member(node, str, 'stage-mode')
+ self.collect = self.node_get_member(node, str, 'collect')
# Assert stage mode is valid
- if self.stage_mode not in ['build', 'install']:
+ if self.stage_mode and self.stage_mode not in ['build', 'install']:
p = self.node_provenance(node, 'stage-mode')
raise ElementError("{}: Stage mode must be either 'build' or 'install'"
.format(p))
@@ -80,24 +81,22 @@ class ScriptElement(Element):
# Assert that a base and an input were specified
if not self.base_dep:
raise ElementError("{}: No base dependencies were specified".format(self))
- if not self.input_dep:
- raise ElementError("{}: No input dependencies were specified".format(self))
# Now resolve the base and input elements
self.base_elt = self.search(Scope.BUILD, self.base_dep)
- self.input_elt = self.search(Scope.BUILD, self.input_dep)
+ if self.input_dep:
+ self.input_elt = self.search(Scope.BUILD, self.input_dep)
if self.base_elt is None:
raise ElementError("{}: Could not find base dependency {}".format(self, self.base_dep))
- if self.input_elt is None:
- raise ElementError("{}: Could not find input dependency {}".format(self, self.input_dep))
def get_unique_key(self):
return {
'commands': self.commands,
'base': self.base_dep,
'input': self.input_dep,
- 'stage-mode': self.stage_mode
+ 'stage-mode': self.stage_mode,
+ 'collect': self.collect
}
def assemble(self, sandbox):
@@ -107,26 +106,29 @@ class ScriptElement(Element):
# Stage the base in the sandbox root
with self.timed_activity("Staging {} as base".format(self.base_dep), silent_nested=True):
- self.base_elt.stage_dependencies(sandbox, Scope.BUILD)
+ self.base_elt.stage_dependencies(sandbox, Scope.RUN)
# Run any integration commands on the base
with self.timed_activity("Integrating sandbox", silent_nested=True):
- for dep in self.base_elt.dependencies(Scope.BUILD):
+ for dep in self.base_elt.dependencies(Scope.RUN):
dep.integrate(sandbox)
# Ensure some directories we'll need
- os.makedirs(os.path.join(directory,
- 'buildstream',
- 'build'), exist_ok=True)
- os.makedirs(os.path.join(directory,
- 'buildstream',
- 'install'), exist_ok=True)
-
- # Stage the input
- input_dir = os.path.join(os.sep, 'buildstream', self.stage_mode)
- with self.timed_activity("Staging {} as input at {}"
- .format(self.input_dep, input_dir), silent_nested=True):
- self.input_elt.stage_dependencies(sandbox, Scope.RUN, path=input_dir)
+ cmd_dir = '/'
+ if self.stage_mode:
+ os.makedirs(os.path.join(directory,
+ 'buildstream',
+ 'build'), exist_ok=True)
+ os.makedirs(os.path.join(directory,
+ 'buildstream',
+ 'install'), exist_ok=True)
+
+ # Stage the input
+ input_dir = os.path.join(os.sep, 'buildstream', self.stage_mode)
+ cmd_dir = input_dir
+ with self.timed_activity("Staging {} as input at {}"
+ .format(self.input_dep, input_dir), silent_nested=True):
+ self.input_elt.stage_dependencies(sandbox, Scope.RUN, path=input_dir)
# Run the scripts
with self.timed_activity("Running script commands"):
@@ -136,14 +138,16 @@ class ScriptElement(Element):
# Note the -e switch to 'sh' means to exit with an error
# if any untested command fails.
exitcode = sandbox.run(['sh', '-c', '-e', cmd + '\n'],
- SandboxFlags.ROOT_READ_ONLY,
- cwd=input_dir,
+ 0,
+ cwd=cmd_dir,
env=environment)
if exitcode != 0:
raise ElementError("Command '{}' failed with exitcode {}".format(cmd, exitcode))
# Return the install dir
- return os.path.join(os.sep, 'buildstream', 'install')
+ if not self.collect:
+ self.collect = os.path.join(os.sep, 'buildstream', 'install')
+ return self.collect
# Plugin entry point
diff --git a/buildstream/plugins/elements/script.yaml b/buildstream/plugins/elements/script.yaml
index c21e115fa..17e0cfa54 100644
--- a/buildstream/plugins/elements/script.yaml
+++ b/buildstream/plugins/elements/script.yaml
@@ -30,3 +30,7 @@ config:
# List of commands to run in the sandbox
#
commands: []
+
+ # Directory to collect the output artifact from,
+ # default is %{install-root}
+ # collect: