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) {