aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.dir-locals.el1
-rw-r--r--src/libstore/content-address.cc12
-rw-r--r--src/libstore/content-address.hh2
-rw-r--r--src/libstore/store-api.cc35
-rw-r--r--src/libstore/store-api.hh7
-rw-r--r--src/nix-prefetch-url/nix-prefetch-url.cc27
-rw-r--r--src/nix-store/nix-store.cc6
7 files changed, 69 insertions, 21 deletions
diff --git a/.dir-locals.el b/.dir-locals.el
index 8b21d4e40..a2d1dc48d 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -1,6 +1,7 @@
((c++-mode . (
(c-file-style . "k&r")
(c-basic-offset . 4)
+ (c-block-comment-prefix . " ")
(indent-tabs-mode . nil)
(tab-width . 4)
(show-trailing-whitespace . t)
diff --git a/src/libstore/content-address.cc b/src/libstore/content-address.cc
index 470cc62c9..a562f2d23 100644
--- a/src/libstore/content-address.cc
+++ b/src/libstore/content-address.cc
@@ -92,4 +92,16 @@ std::string renderContentAddress(std::optional<ContentAddress> ca) {
return ca ? renderContentAddress(*ca) : "";
}
+Hash getContentAddressHash(const ContentAddress & ca)
+{
+ return std::visit(overloaded {
+ [](TextHash th) {
+ return th.hash;
+ },
+ [](FixedOutputHash fsh) {
+ return fsh.hash;
+ }
+ }, ca);
+}
+
}
diff --git a/src/libstore/content-address.hh b/src/libstore/content-address.hh
index ba4797f5b..22a039242 100644
--- a/src/libstore/content-address.hh
+++ b/src/libstore/content-address.hh
@@ -53,4 +53,6 @@ ContentAddress parseContentAddress(std::string_view rawCa);
std::optional<ContentAddress> parseContentAddressOpt(std::string_view rawCaOpt);
+Hash getContentAddressHash(const ContentAddress & ca);
+
}
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index 54d067502..b8cc9e2e1 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -7,6 +7,7 @@
#include "json.hh"
#include "derivations.hh"
#include "url.hh"
+#include "archive.hh"
#include <future>
@@ -221,6 +222,40 @@ StorePath Store::computeStorePathForText(const string & name, const string & s,
}
+ValidPathInfo Store::addToStoreSlow(std::string_view name, const Path & srcPath,
+ FileIngestionMethod method, HashType hashAlgo,
+ std::optional<Hash> expectedCAHash)
+{
+ /* FIXME: inefficient: we're reading/hashing 'tmpFile' three
+ times. */
+
+ auto [narHash, narSize] = hashPath(htSHA256, srcPath);
+
+ auto hash = method == FileIngestionMethod::Recursive
+ ? hashAlgo == htSHA256
+ ? narHash
+ : hashPath(hashAlgo, srcPath).first
+ : hashFile(hashAlgo, srcPath);
+
+ if (expectedCAHash && expectedCAHash != hash)
+ throw Error("hash mismatch for '%s'", srcPath);
+
+ ValidPathInfo info(makeFixedOutputPath(method, hash, name));
+ info.narHash = narHash;
+ info.narSize = narSize;
+ info.ca = FixedOutputHash { .method = method, .hash = hash };
+
+ if (!isValidPath(info.path)) {
+ auto source = sinkToSource([&](Sink & sink) {
+ dumpPath(srcPath, sink);
+ });
+ addToStore(info, *source);
+ }
+
+ return info;
+}
+
+
Store::Store(const Params & params)
: Config(params)
, state({(size_t) pathInfoCacheSize})
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index bb6198662..63e16e5d5 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -451,6 +451,13 @@ public:
FileIngestionMethod method = FileIngestionMethod::Recursive, HashType hashAlgo = htSHA256,
PathFilter & filter = defaultPathFilter, RepairFlag repair = NoRepair) = 0;
+ /* Copy the contents of a path to the store and register the
+ validity the resulting path, using a constant amount of
+ memory. */
+ ValidPathInfo addToStoreSlow(std::string_view name, const Path & srcPath,
+ FileIngestionMethod method = FileIngestionMethod::Recursive, HashType hashAlgo = htSHA256,
+ std::optional<Hash> expectedCAHash = {});
+
// FIXME: remove?
virtual StorePath addToStoreFromDump(const string & dump, const string & name,
FileIngestionMethod method = FileIngestionMethod::Recursive, HashType hashAlgo = htSHA256, RepairFlag repair = NoRepair)
diff --git a/src/nix-prefetch-url/nix-prefetch-url.cc b/src/nix-prefetch-url/nix-prefetch-url.cc
index f752e0448..1001f27af 100644
--- a/src/nix-prefetch-url/nix-prefetch-url.cc
+++ b/src/nix-prefetch-url/nix-prefetch-url.cc
@@ -153,14 +153,15 @@ static int _main(int argc, char * * argv)
/* If an expected hash is given, the file may already exist in
the store. */
- Hash hash(ht), expectedHash(ht);
+ std::optional<Hash> expectedHash;
+ Hash hash(ht);
std::optional<StorePath> storePath;
if (args.size() == 2) {
expectedHash = Hash::parseAny(args[1], ht);
const auto recursive = unpack ? FileIngestionMethod::Recursive : FileIngestionMethod::Flat;
- storePath = store->makeFixedOutputPath(recursive, expectedHash, name);
+ storePath = store->makeFixedOutputPath(recursive, *expectedHash, name);
if (store->isValidPath(*storePath))
- hash = expectedHash;
+ hash = *expectedHash;
else
storePath.reset();
}
@@ -200,22 +201,12 @@ static int _main(int argc, char * * argv)
tmpFile = unpacked;
}
- /* FIXME: inefficient; addToStore() will also hash
- this. */
- hash = unpack ? hashPath(ht, tmpFile).first : hashFile(ht, tmpFile);
+ const auto method = unpack ? FileIngestionMethod::Recursive : FileIngestionMethod::Flat;
- if (expectedHash != Hash(ht) && expectedHash != hash)
- throw Error("hash mismatch for '%1%'", uri);
-
- const auto recursive = unpack ? FileIngestionMethod::Recursive : FileIngestionMethod::Flat;
-
- /* Copy the file to the Nix store. FIXME: if RemoteStore
- implemented addToStoreFromDump() and downloadFile()
- supported a sink, we could stream the download directly
- into the Nix store. */
- storePath = store->addToStore(name, tmpFile, recursive, ht);
-
- assert(*storePath == store->makeFixedOutputPath(recursive, hash, name));
+ auto info = store->addToStoreSlow(name, tmpFile, method, ht, expectedHash);
+ storePath = info.path;
+ assert(info.ca);
+ hash = getContentAddressHash(*info.ca);
}
stopProgressBar();
diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc
index cc3b07c31..a16170137 100644
--- a/src/nix-store/nix-store.cc
+++ b/src/nix-store/nix-store.cc
@@ -174,10 +174,10 @@ static void opAdd(Strings opFlags, Strings opArgs)
store. */
static void opAddFixed(Strings opFlags, Strings opArgs)
{
- auto recursive = FileIngestionMethod::Flat;
+ auto method = FileIngestionMethod::Flat;
for (auto & i : opFlags)
- if (i == "--recursive") recursive = FileIngestionMethod::Recursive;
+ if (i == "--recursive") method = FileIngestionMethod::Recursive;
else throw UsageError("unknown flag '%1%'", i);
if (opArgs.empty())
@@ -187,7 +187,7 @@ static void opAddFixed(Strings opFlags, Strings opArgs)
opArgs.pop_front();
for (auto & i : opArgs)
- cout << fmt("%s\n", store->printStorePath(store->addToStore(std::string(baseNameOf(i)), i, recursive, hashAlgo)));
+ std::cout << fmt("%s\n", store->printStorePath(store->addToStoreSlow(baseNameOf(i), i, method, hashAlgo).path));
}