about summary refs log tree commit diff
path: root/src/build-remote/build-remote.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/build-remote/build-remote.cc')
-rw-r--r--src/build-remote/build-remote.cc105
1 files changed, 63 insertions, 42 deletions
diff --git a/src/build-remote/build-remote.cc b/src/build-remote/build-remote.cc
index 4b7a24d03e9a..6e05e165545d 100644
--- a/src/build-remote/build-remote.cc
+++ b/src/build-remote/build-remote.cc
@@ -16,6 +16,7 @@
 #include "serialise.hh"
 #include "store-api.hh"
 #include "derivations.hh"
+#include "local-store.hh"
 
 using namespace nix;
 using std::cin;
@@ -41,24 +42,33 @@ int main (int argc, char * * argv)
     return handleExceptions(argv[0], [&]() {
         initNix();
 
+        logger = makeJSONLogger(*logger);
+
         /* Ensure we don't get any SSH passphrase or host key popups. */
         unsetenv("DISPLAY");
         unsetenv("SSH_ASKPASS");
 
-        if (argc != 6)
+        if (argc != 2)
             throw UsageError("called without required arguments");
 
-        auto store = openStore();
+        verbosity = (Verbosity) std::stoll(argv[1]);
+
+        FdSource source(STDIN_FILENO);
+
+        /* Read the parent's settings. */
+        while (readInt(source)) {
+            auto name = readString(source);
+            auto value = readString(source);
+            settings.set(name, value);
+        }
+
+        settings.maxBuildJobs.set("1"); // hack to make tests with local?root= work
 
-        auto localSystem = argv[1];
-        settings.maxSilentTime = std::stoll(argv[2]);
-        settings.buildTimeout = std::stoll(argv[3]);
-        verbosity = (Verbosity) std::stoll(argv[4]);
-        settings.builders = argv[5];
+        auto store = openStore().cast<LocalStore>();
 
         /* It would be more appropriate to use $XDG_RUNTIME_DIR, since
            that gets cleared on reboot, but it wouldn't work on macOS. */
-        currentLoad = settings.nixStateDir + "/current-load";
+        currentLoad = store->stateDir + "/current-load";
 
         std::shared_ptr<Store> sshStore;
         AutoCloseFD bestSlotLock;
@@ -73,18 +83,20 @@ int main (int argc, char * * argv)
 
         string drvPath;
         string storeUri;
-        for (string line; getline(cin, line);) {
-            auto tokens = tokenizeString<std::vector<string>>(line);
-            auto sz = tokens.size();
-            if (sz != 3 && sz != 4)
-                throw Error("invalid build hook line '%1%'", line);
-            auto amWilling = tokens[0] == "1";
-            auto neededSystem = tokens[1];
-            drvPath = tokens[2];
-            auto requiredFeatures = sz == 3 ?
-                std::set<string>{} :
-                tokenizeString<std::set<string>>(tokens[3], ",");
-            auto canBuildLocally = amWilling && (neededSystem == localSystem);
+
+        while (true) {
+
+            try {
+                auto s = readString(source);
+                if (s != "try") return;
+            } catch (EndOfFile &) { return; }
+
+            auto amWilling = readInt(source);
+            auto neededSystem = readString(source);
+            source >> drvPath;
+            auto requiredFeatures = readStrings<std::set<std::string>>(source);
+
+            auto canBuildLocally = amWilling && (neededSystem == settings.thisSystem);
 
             /* Error ignored here, will be caught later */
             mkdir(currentLoad.c_str(), 0777);
@@ -99,7 +111,7 @@ int main (int argc, char * * argv)
                 Machine * bestMachine = nullptr;
                 unsigned long long bestLoad = 0;
                 for (auto & m : machines) {
-                    debug("considering building on '%s'", m.storeUri);
+                    debug("considering building on remote machine '%s'", m.storeUri);
 
                     if (m.enabled && std::find(m.systemTypes.begin(),
                             m.systemTypes.end(),
@@ -162,9 +174,15 @@ int main (int argc, char * * argv)
 
                 try {
 
-                    Store::Params storeParams{{"max-connections", "1"}, {"log-fd", "4"}};
-                    if (bestMachine->sshKey != "")
-                        storeParams["ssh-key"] = bestMachine->sshKey;
+                    Activity act(*logger, lvlTalkative, actUnknown, fmt("connecting to '%s'", bestMachine->storeUri));
+
+                    Store::Params storeParams;
+                    if (hasPrefix(storeUri, "ssh://")) {
+                        storeParams["max-connections"] ="1";
+                        storeParams["log-fd"] = "4";
+                        if (bestMachine->sshKey != "")
+                            storeParams["ssh-key"] = bestMachine->sshKey;
+                    }
 
                     sshStore = openStore(bestMachine->storeUri, storeParams);
                     sshStore->connect();
@@ -182,32 +200,34 @@ int main (int argc, char * * argv)
         }
 
 connected:
-        std::cerr << "# accept\n";
-        string line;
-        if (!getline(cin, line))
-            throw Error("hook caller didn't send inputs");
+        std::cerr << "# accept\n" << storeUri << "\n";
 
-        auto inputs = tokenizeString<PathSet>(line);
-        if (!getline(cin, line))
-            throw Error("hook caller didn't send outputs");
-
-        auto outputs = tokenizeString<PathSet>(line);
+        auto inputs = readStrings<PathSet>(source);
+        auto outputs = readStrings<PathSet>(source);
 
         AutoCloseFD uploadLock = openLockFile(currentLoad + "/" + escapeUri(storeUri) + ".upload-lock", true);
 
-        auto old = signal(SIGALRM, handleAlarm);
-        alarm(15 * 60);
-        if (!lockFile(uploadLock.get(), ltWrite, true))
-            printError("somebody is hogging the upload lock for '%s', continuing...");
-        alarm(0);
-        signal(SIGALRM, old);
-        copyPaths(store, ref<Store>(sshStore), inputs, NoRepair, NoCheckSigs);
+        {
+            Activity act(*logger, lvlTalkative, actUnknown, fmt("waiting for the upload lock to '%s'", storeUri));
+
+            auto old = signal(SIGALRM, handleAlarm);
+            alarm(15 * 60);
+            if (!lockFile(uploadLock.get(), ltWrite, true))
+                printError("somebody is hogging the upload lock for '%s', continuing...");
+            alarm(0);
+            signal(SIGALRM, old);
+        }
+
+        {
+            Activity act(*logger, lvlTalkative, actUnknown, fmt("copying dependencies to '%s'", storeUri));
+            copyPaths(store, ref<Store>(sshStore), inputs, NoRepair, NoCheckSigs);
+        }
+
         uploadLock = -1;
 
-        BasicDerivation drv(readDerivation(drvPath));
+        BasicDerivation drv(readDerivation(store->realStoreDir + "/" + baseNameOf(drvPath)));
         drv.inputSrcs = inputs;
 
-        printError("building '%s' on '%s'", drvPath, storeUri);
         auto result = sshStore->buildDerivation(drvPath, drv);
 
         if (!result.success())
@@ -218,6 +238,7 @@ connected:
             if (!store->isValidPath(path)) missing.insert(path);
 
         if (!missing.empty()) {
+            Activity act(*logger, lvlTalkative, actUnknown, fmt("copying outputs from '%s'", storeUri));
             setenv("NIX_HELD_LOCKS", concatStringsSep(" ", missing).c_str(), 1); /* FIXME: ugly */
             copyPaths(ref<Store>(sshStore), store, missing, NoRepair, NoCheckSigs);
         }