diff --git a/src/build-remote/build-remote.cc b/src/build-remote/build-remote.cc index 63e3e3fa9287..dd54a9eead78 100644 --- a/src/build-remote/build-remote.cc +++ b/src/build-remote/build-remote.cc @@ -111,6 +111,13 @@ static int main_build_remote(int argc, char * * argv) auto amWilling = readInt(source); auto neededSystem = readString(source); drvPath = store->parseStorePath(readString(source)); + + std::string drvstr; + if (drvPath.has_value()) + drvstr = drvPath->to_string(); + else + drvstr = ""; + auto requiredFeatures = readStrings>(source); /* It would be possible to build locally after some builds clear out, @@ -137,14 +144,19 @@ static int main_build_remote(int argc, char * * argv) for (auto & m : machines) { debug("considering building on remote machine '%s'", m.storeUri); - if (m.enabled - && (neededSystem == "builtin" - || std::find(m.systemTypes.begin(), - m.systemTypes.end(), - neededSystem) != m.systemTypes.end()) && - m.allSupported(requiredFeatures) && - m.mandatoryMet(requiredFeatures)) - { + if (!m.enabled) { + debug("declined remote machine '%s' because it is disabled", storeUri); + } else if (neededSystem != "builtin" && + std::find(m.systemTypes.begin(), m.systemTypes.end(), neededSystem) + == m.systemTypes.end()) { + printError("declined remote machine '%s' for building '%s' because it does not have the needed system type '%s", m.storeUri, drvstr, neededSystem); + } else if (!m.allSupported(requiredFeatures)) { + std::string joinedFeatures = concatStringsSep(" ", requiredFeatures); // includes leading space + printError("declined remote machine '%1%' for building '%2%' because it does not have all required features: [ %3% ]", m.storeUri, drvstr, joinedFeatures); + } else if (!m.mandatoryMet(requiredFeatures)) { + std::string joinedFeatures = concatStringsSep(" ", requiredFeatures); // includes leading space + printError("declined remote machine '%1%' for building '%2%' because the derivation does not have all mandatory features to build on that machine: [ %3% ]", m.storeUri, drvstr, joinedFeatures); + } else { rightType = true; AutoCloseFD free; uint64_t load = 0; @@ -199,12 +211,6 @@ static int main_build_remote(int argc, char * * argv) errorText += "\n([%s], %s, [%s], [%s])"; // add the template values. - std::string drvstr; - if (drvPath.has_value()) - drvstr = drvPath->to_string(); - else - drvstr = ""; - auto error = hintformat(errorText); error % drvstr diff --git a/src/libstore/build/worker.cc b/src/libstore/build/worker.cc index f775f8486a0e..5a7c72cf8bed 100644 --- a/src/libstore/build/worker.cc +++ b/src/libstore/build/worker.cc @@ -283,9 +283,14 @@ void Worker::run(const Goals & _topGoals) "or enable remote builds." "\nhttps://nixos.org/manual/nix/stable/advanced-topics/distributed-builds.html"); else - throw Error("unable to start any build; remote machines may not have " - "all required system features." - "\nhttps://nixos.org/manual/nix/stable/advanced-topics/distributed-builds.html"); + throw Error("unable to start any build; either increase '--max-jobs' " + "to also allow building locally, or ensure that the configured" + "remote builder machines have all required system features." + "For example, to enable the 'big-parallel' feature, use:" + "\n --builders 'yourbuilderhostname - - - - big-parallel'" + "\nhttps://nixos.org/nix/manual/stable/advanced-topics/distributed-builds" + "\nYou can enable -v verbosity to see why any machine " + "was declined for any given build."); } assert(!awake.empty());