aboutsummaryrefslogtreecommitdiff
path: root/src/libstore
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2019-07-06 21:06:22 +0200
committerEelco Dolstra <edolstra@gmail.com>2019-07-06 21:06:22 +0200
commitcc218b15bad7d1883ac951bc48a8285fcef78916 (patch)
treebb0779a2727c38e2cb05832ac9d9c6ecf5f4638c /src/libstore
parente5f881a7e49b2c4401fd868e0fcd2503b16a1dc8 (diff)
parentb5ae85f0882f4857f550ed68b23af260af5000a0 (diff)
Merge remote-tracking branch 'origin/master' into flakes
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/build.cc38
-rw-r--r--src/libstore/download.cc5
-rw-r--r--src/libstore/store-api.cc13
3 files changed, 49 insertions, 7 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 5187750cf..dabd447f5 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -266,6 +266,12 @@ public:
/* Set if at least one derivation had a timeout. */
bool timedOut;
+ /* Set if at least one derivation fails with a hash mismatch. */
+ bool hashMismatch;
+
+ /* Set if at least one derivation is not deterministic in check mode. */
+ bool checkMismatch;
+
LocalStore & store;
std::unique_ptr<HookInstance> hook;
@@ -3213,6 +3219,7 @@ void DerivationGoal::registerOutputs()
/* Throw an error after registering the path as
valid. */
+ worker.hashMismatch = true;
delayedException = std::make_exception_ptr(
BuildError("hash mismatch in fixed-output derivation '%s':\n wanted: %s\n got: %s",
dest, h.to_string(SRI), h2.to_string(SRI)));
@@ -3255,6 +3262,7 @@ void DerivationGoal::registerOutputs()
if (!worker.store.isValidPath(path)) continue;
auto info = *worker.store.queryPathInfo(path);
if (hash.first != info.narHash) {
+ worker.checkMismatch = true;
if (settings.runDiffHook || settings.keepFailed) {
Path dst = worker.store.toRealPath(path + checkSuffix);
deletePath(dst);
@@ -3266,10 +3274,10 @@ void DerivationGoal::registerOutputs()
buildUser ? buildUser->getGID() : getgid(),
path, dst, drvPath, tmpDir);
- throw Error(format("derivation '%1%' may not be deterministic: output '%2%' differs from '%3%'")
+ throw NotDeterministic(format("derivation '%1%' may not be deterministic: output '%2%' differs from '%3%'")
% drvPath % path % dst);
} else
- throw Error(format("derivation '%1%' may not be deterministic: output '%2%' differs")
+ throw NotDeterministic(format("derivation '%1%' may not be deterministic: output '%2%' differs")
% drvPath % path);
}
@@ -4101,6 +4109,8 @@ Worker::Worker(LocalStore & store)
lastWokenUp = steady_time_point::min();
permanentFailure = false;
timedOut = false;
+ hashMismatch = false;
+ checkMismatch = false;
}
@@ -4461,7 +4471,29 @@ void Worker::waitForInput()
unsigned int Worker::exitStatus()
{
- return timedOut ? 101 : (permanentFailure ? 100 : 1);
+ /*
+ * 1100100
+ * ^^^^
+ * |||`- timeout
+ * ||`-- output hash mismatch
+ * |`--- build failure
+ * `---- not deterministic
+ */
+ unsigned int mask = 0;
+ bool buildFailure = permanentFailure || timedOut || hashMismatch;
+ if (buildFailure)
+ mask |= 0x04; // 100
+ if (timedOut)
+ mask |= 0x01; // 101
+ if (hashMismatch)
+ mask |= 0x02; // 102
+ if (checkMismatch) {
+ mask |= 0x08; // 104
+ }
+
+ if (mask)
+ mask |= 0x60;
+ return mask ? mask : 1;
}
diff --git a/src/libstore/download.cc b/src/libstore/download.cc
index cf79b2af5..071eb5a96 100644
--- a/src/libstore/download.cc
+++ b/src/libstore/download.cc
@@ -244,6 +244,8 @@ struct CurlDownloader : public Downloader
#if LIBCURL_VERSION_NUM >= 0x072f00
if (downloadSettings.enableHttp2)
curl_easy_setopt(req, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS);
+ else
+ curl_easy_setopt(req, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
#endif
curl_easy_setopt(req, CURLOPT_WRITEFUNCTION, DownloadItem::writeCallbackWrapper);
curl_easy_setopt(req, CURLOPT_WRITEDATA, this);
@@ -864,10 +866,11 @@ CachedDownloadResult Downloader::downloadCached(
}
if (expectedStorePath != "" && storePath != expectedStorePath) {
+ unsigned int statusCode = 102;
Hash gotHash = request.unpack
? hashPath(request.expectedHash.type, store->toRealPath(storePath)).first
: hashFile(request.expectedHash.type, store->toRealPath(storePath));
- throw nix::Error("hash mismatch in file downloaded from '%s':\n wanted: %s\n got: %s",
+ throw nix::Error(statusCode, "hash mismatch in file downloaded from '%s':\n wanted: %s\n got: %s",
url, request.expectedHash.to_string(), gotHash.to_string());
}
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index f577799da..77f52f0f3 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -86,18 +86,25 @@ string storePathToHash(const Path & path)
void checkStoreName(const string & name)
{
string validChars = "+-._?=";
+
+ auto baseError = format("The path name '%2%' is invalid: %3%. "
+ "Path names are alphanumeric and can include the symbols %1% "
+ "and must not begin with a period. "
+ "Note: If '%2%' is a source file and you cannot rename it on "
+ "disk, builtins.path { name = ... } can be used to give it an "
+ "alternative name.") % validChars % name;
+
/* Disallow names starting with a dot for possible security
reasons (e.g., "." and ".."). */
if (string(name, 0, 1) == ".")
- throw Error(format("illegal name: '%1%'") % name);
+ throw Error(baseError % "it is illegal to start the name with a period");
for (auto & i : name)
if (!((i >= 'A' && i <= 'Z') ||
(i >= 'a' && i <= 'z') ||
(i >= '0' && i <= '9') ||
validChars.find(i) != string::npos))
{
- throw Error(format("invalid character '%1%' in name '%2%'")
- % i % name);
+ throw Error(baseError % (format("the '%1%' character is invalid") % i));
}
}