aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2016-10-31 17:09:52 +0100
committerEelco Dolstra <edolstra@gmail.com>2016-10-31 17:09:52 +0100
commit18b7363a699c0b5a4bf59d2b320dfc2b84dc4e67 (patch)
treef6cb48fb5020020538633199b8246949baa55530 /src
parentc4969aebaf195500cbf97fa29b6e05377b3970cc (diff)
Support optional sandbox paths
For example, you can now set build-sandbox-paths = /dev/nvidiactl? to specify that /dev/nvidiactl should only be mounted in the sandbox if it exists in the host filesystem. This is useful e.g. for EC2 images that should support both CUDA and non-CUDA instances.
Diffstat (limited to 'src')
-rw-r--r--src/libstore/build.cc35
1 files changed, 26 insertions, 9 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index efd6c0719..b682a8019 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -768,7 +768,14 @@ private:
GoalState state;
/* Stuff we need to pass to initChild(). */
- typedef map<Path, Path> DirsInChroot; // maps target path to source path
+ struct ChrootPath {
+ Path source;
+ bool optional;
+ ChrootPath(Path source = "", bool optional = false)
+ : source(source), optional(optional)
+ { }
+ };
+ typedef map<Path, ChrootPath> DirsInChroot; // maps target path to source path
DirsInChroot dirsInChroot;
typedef map<string, string> Environment;
Environment env;
@@ -1865,12 +1872,18 @@ void DerivationGoal::startBuilder()
dirsInChroot.clear();
- for (auto & i : dirs) {
+ for (auto i : dirs) {
+ if (i.empty()) continue;
+ bool optional = false;
+ if (i[i.size() - 1] == '?') {
+ optional = true;
+ i.pop_back();
+ }
size_t p = i.find('=');
if (p == string::npos)
- dirsInChroot[i] = i;
+ dirsInChroot[i] = {i, optional};
else
- dirsInChroot[string(i, 0, p)] = string(i, p + 1);
+ dirsInChroot[string(i, 0, p)] = {string(i, p + 1), optional};
}
dirsInChroot[tmpDirInSandbox] = tmpDir;
@@ -1878,8 +1891,8 @@ void DerivationGoal::startBuilder()
PathSet closure;
for (auto & i : dirsInChroot)
try {
- if (worker.store.isInStore(i.second))
- worker.store.computeFSClosure(worker.store.toStorePath(i.second), closure);
+ if (worker.store.isInStore(i.second.source))
+ worker.store.computeFSClosure(worker.store.toStorePath(i.second.source), closure);
} catch (Error & e) {
throw Error(format("while processing ‘build-sandbox-paths’: %s") % e.what());
}
@@ -2325,12 +2338,16 @@ void DerivationGoal::runChild()
environment. */
for (auto & i : dirsInChroot) {
struct stat st;
- Path source = i.second;
+ Path source = i.second.source;
Path target = chrootRootDir + i.first;
if (source == "/proc") continue; // backwards compatibility
debug(format("bind mounting ‘%1%’ to ‘%2%’") % source % target);
- if (stat(source.c_str(), &st) == -1)
- throw SysError(format("getting attributes of path ‘%1%’") % source);
+ if (stat(source.c_str(), &st) == -1) {
+ if (i.second.optional && errno == ENOENT)
+ continue;
+ else
+ throw SysError(format("getting attributes of path ‘%1%’") % source);
+ }
if (S_ISDIR(st.st_mode))
createDirs(target);
else {