aboutsummaryrefslogtreecommitdiff
path: root/src/libstore
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/build.cc4
-rw-r--r--src/libstore/download.cc20
-rw-r--r--src/libstore/download.hh3
-rw-r--r--src/libstore/globals.hh3
-rw-r--r--src/libstore/http-binary-cache-store.cc5
-rw-r--r--src/libstore/local-store.cc9
-rw-r--r--src/libstore/nar-info-disk-cache.cc7
-rw-r--r--src/libstore/sqlite.cc25
-rw-r--r--src/libstore/sqlite.hh6
-rw-r--r--src/libstore/store-api.cc9
-rw-r--r--src/libstore/store-api.hh1
11 files changed, 61 insertions, 31 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 4bec37e0f..db7300c58 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -1903,7 +1903,7 @@ void DerivationGoal::startBuilder()
concatStringsSep(", ", parsedDrv->getRequiredSystemFeatures()),
drvPath,
settings.thisSystem,
- concatStringsSep(", ", settings.systemFeatures));
+ concatStringsSep<StringSet>(", ", settings.systemFeatures));
if (drv->isBuiltin())
preloadNSS();
@@ -3283,7 +3283,7 @@ void DerivationGoal::registerOutputs()
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(), h2.to_string()));
+ dest, h.to_string(SRI), h2.to_string(SRI)));
Path actualDest = worker.store.toRealPath(dest);
diff --git a/src/libstore/download.cc b/src/libstore/download.cc
index 91087eebc..aec68d627 100644
--- a/src/libstore/download.cc
+++ b/src/libstore/download.cc
@@ -820,6 +820,7 @@ CachedDownloadResult Downloader::downloadCached(
CachedDownloadResult result;
result.storePath = expectedStorePath;
result.path = store->toRealPath(expectedStorePath);
+ assert(!request.getLastModified); // FIXME
return result;
}
}
@@ -904,16 +905,26 @@ CachedDownloadResult Downloader::downloadCached(
store->addTempRoot(unpackedStorePath);
if (!store->isValidPath(unpackedStorePath))
unpackedStorePath = "";
+ else
+ result.lastModified = lstat(unpackedLink).st_mtime;
}
if (unpackedStorePath.empty()) {
printInfo(format("unpacking '%1%'...") % url);
Path tmpDir = createTempDir();
AutoDelete autoDelete(tmpDir, true);
// FIXME: this requires GNU tar for decompression.
- runProgram("tar", true, {"xf", store->toRealPath(storePath), "-C", tmpDir, "--strip-components", "1"});
- unpackedStorePath = store->addToStore(name, tmpDir, true, htSHA256, defaultPathFilter, NoRepair);
+ runProgram("tar", true, {"xf", store->toRealPath(storePath), "-C", tmpDir});
+ auto members = readDirectory(tmpDir);
+ if (members.size() != 1)
+ throw nix::Error("tarball '%s' contains an unexpected number of top-level files", url);
+ auto topDir = tmpDir + "/" + members.begin()->name;
+ result.lastModified = lstat(topDir).st_mtime;
+ unpackedStorePath = store->addToStore(name, topDir, true, htSHA256, defaultPathFilter, NoRepair);
}
- replaceSymlink(unpackedStorePath, unpackedLink);
+ // Store the last-modified date of the tarball in the symlink
+ // mtime. This saves us from having to store it somewhere
+ // else.
+ replaceSymlink(unpackedStorePath, unpackedLink, result.lastModified);
storePath = unpackedStorePath;
}
@@ -926,6 +937,9 @@ CachedDownloadResult Downloader::downloadCached(
url, request.expectedHash.to_string(), gotHash.to_string());
}
+ if (request.gcRoot)
+ store->addIndirectRoot(fileLink);
+
result.storePath = storePath;
result.path = store->toRealPath(storePath);
return result;
diff --git a/src/libstore/download.hh b/src/libstore/download.hh
index 3b7fff3ba..c095ad053 100644
--- a/src/libstore/download.hh
+++ b/src/libstore/download.hh
@@ -69,6 +69,8 @@ struct CachedDownloadRequest
std::string name;
Hash expectedHash;
unsigned int ttl = settings.tarballTtl;
+ bool gcRoot = false;
+ bool getLastModified = false;
CachedDownloadRequest(const std::string & uri)
: uri(uri) { }
@@ -82,6 +84,7 @@ struct CachedDownloadResult
Path path;
std::optional<std::string> etag;
std::string effectiveUri;
+ std::optional<time_t> lastModified;
};
class Store;
diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh
index 13effb507..e845c29b0 100644
--- a/src/libstore/globals.hh
+++ b/src/libstore/globals.hh
@@ -350,6 +350,9 @@ public:
Setting<Paths> pluginFiles{this, {}, "plugin-files",
"Plugins to dynamically load at nix initialization time."};
+
+ Setting<std::string> githubAccessToken{this, "", "github-acces-token",
+ "GitHub access token to get access to GitHub data through the GitHub API for github:<..> flakes."};
};
diff --git a/src/libstore/http-binary-cache-store.cc b/src/libstore/http-binary-cache-store.cc
index df2fb9332..ea39d4f22 100644
--- a/src/libstore/http-binary-cache-store.cc
+++ b/src/libstore/http-binary-cache-store.cc
@@ -158,10 +158,11 @@ static RegisterStoreImplementation regStore([](
const std::string & uri, const Store::Params & params)
-> std::shared_ptr<Store>
{
+ static bool forceHttp = getEnv("_NIX_FORCE_HTTP") == "1";
if (std::string(uri, 0, 7) != "http://" &&
std::string(uri, 0, 8) != "https://" &&
- (getEnv("_NIX_FORCE_HTTP_BINARY_CACHE_STORE") != "1" || std::string(uri, 0, 7) != "file://")
- ) return 0;
+ (!forceHttp || std::string(uri, 0, 7) != "file://"))
+ return 0;
auto store = std::make_shared<HttpBinaryCacheStore>(params, uri);
store->init();
return store;
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 63b11467e..a9399130c 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -294,9 +294,7 @@ void LocalStore::openDB(State & state, bool create)
/* Open the Nix database. */
string dbPath = dbDir + "/db.sqlite";
auto & db(state.db);
- if (sqlite3_open_v2(dbPath.c_str(), &db.db,
- SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), 0) != SQLITE_OK)
- throw Error(format("cannot open Nix database '%1%'") % dbPath);
+ state.db = SQLite(dbPath, create);
#ifdef __CYGWIN__
/* The cygwin version of sqlite3 has a patch which calls
@@ -308,11 +306,6 @@ void LocalStore::openDB(State & state, bool create)
SetDllDirectoryW(L"");
#endif
- if (sqlite3_busy_timeout(db, 60 * 60 * 1000) != SQLITE_OK)
- throwSQLiteError(db, "setting timeout");
-
- db.exec("pragma foreign_keys = 1");
-
/* !!! check whether sqlite has been built with foreign key
support */
diff --git a/src/libstore/nar-info-disk-cache.cc b/src/libstore/nar-info-disk-cache.cc
index 32ad7f2b2..3f6dbbcf5 100644
--- a/src/libstore/nar-info-disk-cache.cc
+++ b/src/libstore/nar-info-disk-cache.cc
@@ -78,12 +78,7 @@ public:
state->db = SQLite(dbPath);
- if (sqlite3_busy_timeout(state->db, 60 * 60 * 1000) != SQLITE_OK)
- throwSQLiteError(state->db, "setting timeout");
-
- // We can always reproduce the cache.
- state->db.exec("pragma synchronous = off");
- state->db.exec("pragma main.journal_mode = truncate");
+ state->db.isCache();
state->db.exec(schema);
diff --git a/src/libstore/sqlite.cc b/src/libstore/sqlite.cc
index a061d64f3..eb1daafc5 100644
--- a/src/libstore/sqlite.cc
+++ b/src/libstore/sqlite.cc
@@ -25,11 +25,16 @@ namespace nix {
throw SQLiteError("%s: %s (in '%s')", fs.s, sqlite3_errstr(exterr), path);
}
-SQLite::SQLite(const Path & path)
+SQLite::SQLite(const Path & path, bool create)
{
if (sqlite3_open_v2(path.c_str(), &db,
- SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0) != SQLITE_OK)
+ SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), 0) != SQLITE_OK)
throw Error(format("cannot open SQLite database '%s'") % path);
+
+ if (sqlite3_busy_timeout(db, 60 * 60 * 1000) != SQLITE_OK)
+ throwSQLiteError(db, "setting timeout");
+
+ exec("pragma foreign_keys = 1");
}
SQLite::~SQLite()
@@ -42,6 +47,12 @@ SQLite::~SQLite()
}
}
+void SQLite::isCache()
+{
+ exec("pragma synchronous = off");
+ exec("pragma main.journal_mode = truncate");
+}
+
void SQLite::exec(const std::string & stmt)
{
retrySQLite<void>([&]() {
@@ -94,6 +105,16 @@ SQLiteStmt::Use & SQLiteStmt::Use::operator () (const std::string & value, bool
return *this;
}
+SQLiteStmt::Use & SQLiteStmt::Use::operator () (const unsigned char * data, size_t len, bool notNull)
+{
+ if (notNull) {
+ if (sqlite3_bind_blob(stmt, curArg++, data, len, SQLITE_TRANSIENT) != SQLITE_OK)
+ throwSQLiteError(stmt.db, "binding argument");
+ } else
+ bind();
+ return *this;
+}
+
SQLiteStmt::Use & SQLiteStmt::Use::operator () (int64_t value, bool notNull)
{
if (notNull) {
diff --git a/src/libstore/sqlite.hh b/src/libstore/sqlite.hh
index 115679b84..78e53fa32 100644
--- a/src/libstore/sqlite.hh
+++ b/src/libstore/sqlite.hh
@@ -15,13 +15,16 @@ struct SQLite
{
sqlite3 * db = 0;
SQLite() { }
- SQLite(const Path & path);
+ SQLite(const Path & path, bool create = true);
SQLite(const SQLite & from) = delete;
SQLite& operator = (const SQLite & from) = delete;
SQLite& operator = (SQLite && from) { db = from.db; from.db = 0; return *this; }
~SQLite();
operator sqlite3 * () { return db; }
+ /* Disable synchronous mode, set truncate journal mode. */
+ void isCache();
+
void exec(const std::string & stmt);
};
@@ -52,6 +55,7 @@ struct SQLiteStmt
/* Bind the next parameter. */
Use & operator () (const std::string & value, bool notNull = true);
+ Use & operator () (const unsigned char * data, size_t len, bool notNull = true);
Use & operator () (int64_t value, bool notNull = true);
Use & bind(); // null
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index f5608d384..e9042443c 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -55,7 +55,7 @@ Path Store::followLinksToStore(const Path & _path) const
path = absPath(target, dirOf(path));
}
if (!isInStore(path))
- throw Error(format("path '%1%' is not in the Nix store") % path);
+ throw NotInStore("path '%1%' is not in the Nix store", path);
return path;
}
@@ -733,12 +733,7 @@ ValidPathInfo decodeValidPathInfo(std::istream & str, bool hashGiven)
string showPaths(const PathSet & paths)
{
- string s;
- for (auto & i : paths) {
- if (s.size() != 0) s += ", ";
- s += "'" + i + "'";
- }
- return s;
+ return concatStringsSep(", ", quoteStrings(paths));
}
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 599677376..e5e5c182c 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -26,6 +26,7 @@ MakeError(InvalidPath, Error)
MakeError(Unsupported, Error)
MakeError(SubstituteGone, Error)
MakeError(SubstituterDisabled, Error)
+MakeError(NotInStore, Error)
struct BasicDerivation;