From 2ece42b2b9f9d567ba3235c498c53d222c3346dc Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 30 Jun 2015 00:20:19 +0200 Subject: [PATCH] Support preferLocalBuild Derivations with "preferLocalBuild = true" can now be executed on specific machines (typically localhost) by setting the mandary system features field to include "local". For example: localhost x86_64-linux,i686-linux - 10 100 - local says that "localhost" can *only* do builds with "preferLocalBuild = true". The speed factor of 100 will make the machine almost always win over other machines. --- src/hydra-queue-runner/hydra-queue-runner.cc | 23 +++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/hydra-queue-runner/hydra-queue-runner.cc b/src/hydra-queue-runner/hydra-queue-runner.cc index 3ae69813..d1f748c4 100644 --- a/src/hydra-queue-runner/hydra-queue-runner.cc +++ b/src/hydra-queue-runner/hydra-queue-runner.cc @@ -138,6 +138,7 @@ struct Step Path drvPath; Derivation drv; std::set requiredSystemFeatures; + bool preferLocalBuild; struct State { @@ -194,7 +195,9 @@ struct Machine { if (systemTypes.find(step->drv.platform) == systemTypes.end()) return false; for (auto & f : mandatoryFeatures) - if (step->requiredSystemFeatures.find(f) == step->requiredSystemFeatures.end()) return false; + if (step->requiredSystemFeatures.find(f) == step->requiredSystemFeatures.end() + && !(step->preferLocalBuild && f == "local")) + return false; for (auto & f : step->requiredSystemFeatures) if (supportedFeatures.find(f) == supportedFeatures.end()) return false; return true; @@ -208,6 +211,8 @@ private: Path hydraData, logDir; + StringSet localPlatforms; + /* The queued builds. */ typedef std::map Builds; Sync builds; @@ -361,6 +366,10 @@ State::State() machinesFile = getEnv("NIX_REMOTE_SYSTEMS", "/etc/nix/machines"); machinesFileStat.st_ino = 0; machinesFileStat.st_mtime = 0; + + localPlatforms = {settings.thisSystem}; + if (settings.thisSystem == "x86_64-linux") + localPlatforms.insert("i686-linux"); } @@ -377,10 +386,7 @@ void State::loadMachinesFile() contents = readFile(machinesFile); machinesFileStat = st; } else { - StringSet systems = StringSet({settings.thisSystem}); - if (settings.thisSystem == "x86_64-linux") - systems.insert("i686-linux"); - contents = "localhost " + concatStringsSep(",", systems) + contents = "localhost " + concatStringsSep(",", localPlatforms) + " - " + int2String(settings.maxBuildJobs) + " 1"; } @@ -405,7 +411,9 @@ void State::loadMachinesFile() else machine->maxJobs = 1; machine->speedFactor = atof(tokens[4].c_str()); + if (tokens[5] == "-") tokens[5] = ""; machine->supportedFeatures = tokenizeString(tokens[5], ","); + if (tokens[6] == "-") tokens[6] = ""; machine->mandatoryFeatures = tokenizeString(tokens[6], ","); for (auto & f : machine->mandatoryFeatures) machine->supportedFeatures.insert(f); @@ -820,6 +828,11 @@ Step::ptr State::createStep(std::shared_ptr store, const Path & drvPat step->requiredSystemFeatures = tokenizeString>(i->second); } + auto attr = step->drv.env.find("preferLocalBuild"); + step->preferLocalBuild = + attr != step->drv.env.end() && attr->second == "1" + && has(localPlatforms, step->drv.platform); + /* Are all outputs valid? */ bool valid = true; for (auto & i : step->drv.outputs) {