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.
This commit is contained in:
Eelco Dolstra 2015-06-30 00:20:19 +02:00
parent 171303864e
commit 2ece42b2b9

View file

@ -138,6 +138,7 @@ struct Step
Path drvPath; Path drvPath;
Derivation drv; Derivation drv;
std::set<std::string> requiredSystemFeatures; std::set<std::string> requiredSystemFeatures;
bool preferLocalBuild;
struct State struct State
{ {
@ -194,7 +195,9 @@ struct Machine
{ {
if (systemTypes.find(step->drv.platform) == systemTypes.end()) return false; if (systemTypes.find(step->drv.platform) == systemTypes.end()) return false;
for (auto & f : mandatoryFeatures) 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) for (auto & f : step->requiredSystemFeatures)
if (supportedFeatures.find(f) == supportedFeatures.end()) return false; if (supportedFeatures.find(f) == supportedFeatures.end()) return false;
return true; return true;
@ -208,6 +211,8 @@ private:
Path hydraData, logDir; Path hydraData, logDir;
StringSet localPlatforms;
/* The queued builds. */ /* The queued builds. */
typedef std::map<BuildID, Build::ptr> Builds; typedef std::map<BuildID, Build::ptr> Builds;
Sync<Builds> builds; Sync<Builds> builds;
@ -361,6 +366,10 @@ State::State()
machinesFile = getEnv("NIX_REMOTE_SYSTEMS", "/etc/nix/machines"); machinesFile = getEnv("NIX_REMOTE_SYSTEMS", "/etc/nix/machines");
machinesFileStat.st_ino = 0; machinesFileStat.st_ino = 0;
machinesFileStat.st_mtime = 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); contents = readFile(machinesFile);
machinesFileStat = st; machinesFileStat = st;
} else { } else {
StringSet systems = StringSet({settings.thisSystem}); contents = "localhost " + concatStringsSep(",", localPlatforms)
if (settings.thisSystem == "x86_64-linux")
systems.insert("i686-linux");
contents = "localhost " + concatStringsSep(",", systems)
+ " - " + int2String(settings.maxBuildJobs) + " 1"; + " - " + int2String(settings.maxBuildJobs) + " 1";
} }
@ -405,7 +411,9 @@ void State::loadMachinesFile()
else else
machine->maxJobs = 1; machine->maxJobs = 1;
machine->speedFactor = atof(tokens[4].c_str()); machine->speedFactor = atof(tokens[4].c_str());
if (tokens[5] == "-") tokens[5] = "";
machine->supportedFeatures = tokenizeString<StringSet>(tokens[5], ","); machine->supportedFeatures = tokenizeString<StringSet>(tokens[5], ",");
if (tokens[6] == "-") tokens[6] = "";
machine->mandatoryFeatures = tokenizeString<StringSet>(tokens[6], ","); machine->mandatoryFeatures = tokenizeString<StringSet>(tokens[6], ",");
for (auto & f : machine->mandatoryFeatures) for (auto & f : machine->mandatoryFeatures)
machine->supportedFeatures.insert(f); machine->supportedFeatures.insert(f);
@ -820,6 +828,11 @@ Step::ptr State::createStep(std::shared_ptr<StoreAPI> store, const Path & drvPat
step->requiredSystemFeatures = tokenizeString<std::set<std::string>>(i->second); step->requiredSystemFeatures = tokenizeString<std::set<std::string>>(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? */ /* Are all outputs valid? */
bool valid = true; bool valid = true;
for (auto & i : step->drv.outputs) { for (auto & i : step->drv.outputs) {