BinaryCacheStore: Implement addToStore()

So now you can do

  $ NIX_REMOTE=file:///tmp/binary-cache nix-instantiate '<nixpkgs>' -A hello

and lots of other operations.
This commit is contained in:
Eelco Dolstra 2016-02-24 16:52:28 +01:00
parent 30e9d01516
commit 9ccbd55c5b
4 changed files with 74 additions and 12 deletions

View file

@ -24,6 +24,10 @@ BinaryCacheStore::BinaryCacheStore(std::shared_ptr<Store> localStore,
auto key = PublicKey(readFile(publicKeyFile)); auto key = PublicKey(readFile(publicKeyFile));
publicKeys->emplace(key.name, key); publicKeys->emplace(key.name, key);
} }
StringSink sink;
sink << narVersionMagic1;
narMagic = sink.s;
} }
void BinaryCacheStore::init() void BinaryCacheStore::init()
@ -55,6 +59,8 @@ void BinaryCacheStore::addToCache(const ValidPathInfo & info,
auto narInfoFile = narInfoFileFor(info.path); auto narInfoFile = narInfoFileFor(info.path);
if (fileExists(narInfoFile)) return; if (fileExists(narInfoFile)) return;
assert(nar.compare(0, narMagic.size(), narMagic) == 0);
auto narInfo = make_ref<NarInfo>(info); auto narInfo = make_ref<NarInfo>(info);
narInfo->narSize = nar.size(); narInfo->narSize = nar.size();
@ -261,6 +267,50 @@ void BinaryCacheStore::querySubstitutablePathInfos(const PathSet & paths,
localStore->querySubstitutablePathInfos(left, infos); localStore->querySubstitutablePathInfos(left, infos);
} }
Path BinaryCacheStore::addToStore(const string & name, const Path & srcPath,
bool recursive, HashType hashAlgo, PathFilter & filter, bool repair)
{
// FIXME: some cut&paste from LocalStore::addToStore().
/* Read the whole path into memory. This is not a very scalable
method for very large paths, but `copyPath' is mainly used for
small files. */
StringSink sink;
Hash h;
if (recursive) {
dumpPath(srcPath, sink, filter);
h = hashString(hashAlgo, sink.s);
} else {
auto s = readFile(srcPath);
dumpString(s, sink);
h = hashString(hashAlgo, s);
}
ValidPathInfo info;
info.path = makeFixedOutputPath(recursive, hashAlgo, h, name);
if (repair || !isValidPath(info.path))
addToCache(info, sink.s);
return info.path;
}
Path BinaryCacheStore::addTextToStore(const string & name, const string & s,
const PathSet & references, bool repair)
{
ValidPathInfo info;
info.path = computeStorePathForText(name, s, references);
info.references = references;
if (repair || !isValidPath(info.path)) {
StringSink sink;
dumpString(s, sink);
addToCache(info, sink.s);
}
return info.path;
}
void BinaryCacheStore::buildPaths(const PathSet & paths, BuildMode buildMode) void BinaryCacheStore::buildPaths(const PathSet & paths, BuildMode buildMode)
{ {
for (auto & storePath : paths) { for (auto & storePath : paths) {

View file

@ -68,6 +68,8 @@ private:
Stats stats; Stats stats;
std::string narMagic;
std::string narInfoFileFor(const Path & storePath); std::string narInfoFileFor(const Path & storePath);
void addToCache(const ValidPathInfo & info, const string & nar); void addToCache(const ValidPathInfo & info, const string & nar);
@ -96,10 +98,10 @@ public:
{ notImpl(); } { notImpl(); }
Path queryDeriver(const Path & path) override Path queryDeriver(const Path & path) override
{ notImpl(); } { return ""; }
PathSet queryValidDerivers(const Path & path) override PathSet queryValidDerivers(const Path & path) override
{ notImpl(); } { return {}; }
PathSet queryDerivationOutputs(const Path & path) override PathSet queryDerivationOutputs(const Path & path) override
{ notImpl(); } { notImpl(); }
@ -111,19 +113,17 @@ public:
{ notImpl(); } { notImpl(); }
PathSet querySubstitutablePaths(const PathSet & paths) override PathSet querySubstitutablePaths(const PathSet & paths) override
{ notImpl(); } { return {}; }
void querySubstitutablePathInfos(const PathSet & paths, void querySubstitutablePathInfos(const PathSet & paths,
SubstitutablePathInfos & infos) override; SubstitutablePathInfos & infos) override;
Path addToStore(const string & name, const Path & srcPath, Path addToStore(const string & name, const Path & srcPath,
bool recursive = true, HashType hashAlgo = htSHA256, bool recursive = true, HashType hashAlgo = htSHA256,
PathFilter & filter = defaultPathFilter, bool repair = false) override PathFilter & filter = defaultPathFilter, bool repair = false) override;
{ notImpl(); }
Path addTextToStore(const string & name, const string & s, Path addTextToStore(const string & name, const string & s,
const PathSet & references, bool repair = false) override const PathSet & references, bool repair = false) override;
{ notImpl(); }
void exportPath(const Path & path, bool sign, void exportPath(const Path & path, bool sign,
Sink & sink) override; Sink & sink) override;
@ -156,7 +156,7 @@ public:
{ notImpl(); } { notImpl(); }
PathSet queryFailedPaths() override PathSet queryFailedPaths() override
{ return PathSet(); } { return {}; }
void clearFailedPaths(const PathSet & paths) override void clearFailedPaths(const PathSet & paths) override
{ } { }

View file

@ -29,7 +29,7 @@ bool useCaseHack =
false; false;
#endif #endif
static string archiveVersion1 = "nix-archive-1"; const std::string narVersionMagic1 = "nix-archive-1";
static string caseHackSuffix = "~nix~case~hack~"; static string caseHackSuffix = "~nix~case~hack~";
@ -113,11 +113,17 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter)
void dumpPath(const Path & path, Sink & sink, PathFilter & filter) void dumpPath(const Path & path, Sink & sink, PathFilter & filter)
{ {
sink << archiveVersion1; sink << narVersionMagic1;
dump(path, sink, filter); dump(path, sink, filter);
} }
void dumpString(const std::string & s, Sink & sink)
{
sink << narVersionMagic1 << "(" << "type" << "regular" << "contents" << s << ")";
}
static SerialisationError badArchive(string s) static SerialisationError badArchive(string s)
{ {
return SerialisationError("bad archive: " + s); return SerialisationError("bad archive: " + s);
@ -214,7 +220,8 @@ static void parse(ParseSink & sink, Source & source, const Path & path)
} }
else if (s == "executable" && type == tpRegular) { else if (s == "executable" && type == tpRegular) {
readString(source); auto s = readString(source);
if (s != "") throw badArchive("executable marker has non-empty value");
sink.isExecutable(); sink.isExecutable();
} }
@ -275,7 +282,7 @@ void parseDump(ParseSink & sink, Source & source)
/* This generally means the integer at the start couldn't be /* This generally means the integer at the start couldn't be
decoded. Ignore and throw the exception below. */ decoded. Ignore and throw the exception below. */
} }
if (version != archiveVersion1) if (version != narVersionMagic1)
throw badArchive("input doesn't look like a Nix archive"); throw badArchive("input doesn't look like a Nix archive");
parse(sink, source, ""); parse(sink, source, "");
} }

View file

@ -55,6 +55,8 @@ extern PathFilter defaultPathFilter;
void dumpPath(const Path & path, Sink & sink, void dumpPath(const Path & path, Sink & sink,
PathFilter & filter = defaultPathFilter); PathFilter & filter = defaultPathFilter);
void dumpString(const std::string & s, Sink & sink);
struct ParseSink struct ParseSink
{ {
virtual void createDirectory(const Path & path) { }; virtual void createDirectory(const Path & path) { };
@ -76,4 +78,7 @@ void restorePath(const Path & path, Source & source);
extern bool useCaseHack; extern bool useCaseHack;
extern const std::string narVersionMagic1;
} }