about summary refs log tree commit diff
path: root/src/libstore
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/build.cc41
-rw-r--r--src/libstore/globals.cc10
-rw-r--r--src/libstore/globals.hh8
-rw-r--r--src/libstore/local-store.cc3
-rw-r--r--src/libstore/local.mk1
5 files changed, 61 insertions, 2 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 90bcccd243a7..50c59c1314d9 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -20,6 +20,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/utsname.h>
+#include <sys/select.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
@@ -1786,8 +1787,10 @@ void DerivationGoal::startBuilder()
     if (useChroot) {
 
         string defaultChrootDirs;
+#if CHROOT_ENABLED
         if (isInStore(BASH_PATH))
             defaultChrootDirs = "/bin/sh=" BASH_PATH;
+#endif
 
         /* Allow a user-configurable set of directories from the
            host file system. */
@@ -1895,7 +1898,7 @@ void DerivationGoal::startBuilder()
            build user. */
         Path chrootStoreDir = chrootRootDir + settings.nixStore;
         createDirs(chrootStoreDir);
-        chmod_(chrootStoreDir, 0730);
+        chmod_(chrootStoreDir, 01775);
 
         if (chown(chrootStoreDir.c_str(), 0, buildUser.getGID()) == -1)
             throw SysError(format("cannot change ownership of ‘%1%’") % chrootStoreDir);
@@ -1969,6 +1972,42 @@ void DerivationGoal::startBuilder()
                 }
     }
 
+    if (settings.preBuildHook != "") {
+        printMsg(lvlChatty, format("executing pre-build hook ‘%1%’")
+            % settings.preBuildHook);
+        auto args = useChroot ? Strings({drvPath, chrootRootDir}) :
+            Strings({ drvPath });
+        enum BuildHookState {
+            stBegin,
+            stExtraChrootDirs
+        };
+        auto state = stBegin;
+        auto lines = runProgram(settings.preBuildHook, false, args);
+        auto lastPos = std::string::size_type{0};
+        for (auto nlPos = lines.find('\n'); nlPos != string::npos;
+                nlPos = lines.find('\n', lastPos)) {
+            auto line = std::string{lines, lastPos, nlPos};
+            lastPos = nlPos + 1;
+            if (state == stBegin) {
+                if (line == "extra-chroot-dirs") {
+                    state = stExtraChrootDirs;
+                } else {
+                    throw Error(format("unknown pre-build hook command ‘%1%’")
+                        % line);
+                }
+            } else if (state == stExtraChrootDirs) {
+                if (line == "") {
+                    state = stBegin;
+                } else {
+                    auto p = line.find('=');
+                    if (p == string::npos)
+                        dirsInChroot[line] = line;
+                    else
+                        dirsInChroot[string(line, 0, p)] = string(line, p + 1);
+                }
+            }
+        }
+    }
 
     /* Run the builder. */
     printMsg(lvlChatty, format("executing builder ‘%1%’") % drv.builder);
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index e382b3aac03a..d5615d93c7d0 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -67,6 +67,7 @@ Settings::Settings()
 
 void Settings::processEnvironment()
 {
+    nixPrefix = NIX_PREFIX;
     nixStore = canonPath(getEnv("NIX_STORE_DIR", getEnv("NIX_STORE", NIX_STORE_DIR)));
     nixDataDir = canonPath(getEnv("NIX_DATA_DIR", NIX_DATA_DIR));
     nixLogDir = canonPath(getEnv("NIX_LOG_DIR", NIX_LOG_DIR));
@@ -143,6 +144,14 @@ bool Settings::get(const string & name, bool def)
 }
 
 
+int Settings::get(const string & name, int def)
+{
+    int res = def;
+    _get(res, name);
+    return res;
+}
+
+
 void Settings::update()
 {
     _get(tryFallback, "build-fallback");
@@ -173,6 +182,7 @@ void Settings::update()
     _get(logServers, "log-servers");
     _get(enableImportNative, "allow-unsafe-native-code-during-evaluation");
     _get(useCaseHack, "use-case-hack");
+    _get(preBuildHook, "pre-build-hook");
 
     string subs = getEnv("NIX_SUBSTITUTERS", "default");
     if (subs == "default") {
diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh
index 0230a540e655..60b11afe6088 100644
--- a/src/libstore/globals.hh
+++ b/src/libstore/globals.hh
@@ -27,6 +27,8 @@ struct Settings {
 
     bool get(const string & name, bool def);
 
+    int get(const string & name, int def);
+
     void update();
 
     string pack();
@@ -40,6 +42,8 @@ struct Settings {
 
     Path nixDataDir; /* !!! fix */
 
+    Path nixPrefix;
+
     /* The directory where we log various operations. */
     Path nixLogDir;
 
@@ -202,6 +206,10 @@ struct Settings {
     /* Whether the importNative primop should be enabled */
     bool enableImportNative;
 
+    /* The hook to run just before a build to set derivation-specific
+       build settings */
+    Path preBuildHook;
+
 private:
     SettingsMap settings, overrides;
 
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 3ec467649d3b..1dcd7228f347 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -13,6 +13,7 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/select.h>
 #include <sys/time.h>
 #include <unistd.h>
 #include <utime.h>
@@ -256,7 +257,7 @@ LocalStore::LocalStore(bool reserveSpace)
         if (chmod(perUserDir.c_str(), 01777) == -1)
             throw SysError(format("could not set permissions on ‘%1%’ to 1777") % perUserDir);
 
-        mode_t perm = 01735;
+        mode_t perm = 01775;
 
         struct group * gr = getgrnam(settings.buildUsersGroup.c_str());
         if (!gr)
diff --git a/src/libstore/local.mk b/src/libstore/local.mk
index 78b4d0fd4b94..771c06753a65 100644
--- a/src/libstore/local.mk
+++ b/src/libstore/local.mk
@@ -15,6 +15,7 @@ ifeq ($(OS), SunOS)
 endif
 
 libstore_CXXFLAGS = \
+ -DNIX_PREFIX=\"$(prefix)\" \
  -DNIX_STORE_DIR=\"$(storedir)\" \
  -DNIX_DATA_DIR=\"$(datadir)\" \
  -DNIX_STATE_DIR=\"$(localstatedir)/nix\" \