aboutsummaryrefslogtreecommitdiff
path: root/src/nix-store
diff options
context:
space:
mode:
Diffstat (limited to 'src/nix-store')
-rw-r--r--src/nix-store/nix-store.cc177
1 files changed, 77 insertions, 100 deletions
diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc
index b948380bb..c3e2b57c9 100644
--- a/src/nix-store/nix-store.cc
+++ b/src/nix-store/nix-store.cc
@@ -9,7 +9,8 @@
#include "util.hh"
#include "worker-protocol.hh"
#include "graphml.hh"
-#include "../nix/legacy.hh"
+#include "legacy.hh"
+#include "path-with-outputs.hh"
#include <iostream>
#include <algorithm>
@@ -19,9 +20,8 @@
#include <sys/stat.h>
#include <fcntl.h>
-#if HAVE_SODIUM
-#include <sodium.h>
-#endif
+
+namespace nix_store {
using namespace nix;
@@ -34,7 +34,6 @@ typedef void (* Operation) (Strings opFlags, Strings opArgs);
static Path gcRoot;
static int rootNr = 0;
-static bool indirectRoot = false;
static bool noOutput = false;
static std::shared_ptr<Store> store;
@@ -64,7 +63,8 @@ static PathSet realisePath(StorePathWithOutputs path, bool build = true)
auto store2 = std::dynamic_pointer_cast<LocalFSStore>(store);
if (path.path.isDerivation()) {
- if (build) store->buildPaths({path});
+ if (build) store->buildPaths({path.toDerivedPath()});
+ auto outputPaths = store->queryDerivationOutputMap(path.path);
Derivation drv = store->derivationFromPath(path.path);
rootNr++;
@@ -77,7 +77,8 @@ static PathSet realisePath(StorePathWithOutputs path, bool build = true)
if (i == drv.outputs.end())
throw Error("derivation '%s' does not have an output named '%s'",
store2->printStorePath(path.path), j);
- auto outPath = store2->printStorePath(i->second.path);
+ auto outPath = outputPaths.at(i->first);
+ auto retPath = store->printStorePath(outPath);
if (store2) {
if (gcRoot == "")
printGCWarning();
@@ -85,10 +86,10 @@ static PathSet realisePath(StorePathWithOutputs path, bool build = true)
Path rootName = gcRoot;
if (rootNr > 1) rootName += "-" + std::to_string(rootNr);
if (i->first != "out") rootName += "-" + i->first;
- outPath = store2->addPermRoot(store->parseStorePath(outPath), rootName, indirectRoot);
+ retPath = store2->addPermRoot(outPath, rootName);
}
}
- outputs.insert(outPath);
+ outputs.insert(retPath);
}
return outputs;
}
@@ -104,7 +105,7 @@ static PathSet realisePath(StorePathWithOutputs path, bool build = true)
Path rootName = gcRoot;
rootNr++;
if (rootNr > 1) rootName += "-" + std::to_string(rootNr);
- return {store2->addPermRoot(path.path, rootName, indirectRoot)};
+ return {store2->addPermRoot(path.path, rootName)};
}
}
return {store->printStorePath(path.path)};
@@ -128,11 +129,13 @@ static void opRealise(Strings opFlags, Strings opArgs)
std::vector<StorePathWithOutputs> paths;
for (auto & i : opArgs)
- paths.push_back(store->followLinksToStorePathWithOutputs(i));
+ paths.push_back(followLinksToStorePathWithOutputs(*store, i));
- unsigned long long downloadSize, narSize;
+ uint64_t downloadSize, narSize;
StorePathSet willBuild, willSubstitute, unknown;
- store->queryMissing(paths, willBuild, willSubstitute, unknown, downloadSize, narSize);
+ store->queryMissing(
+ toDerivedPaths(paths),
+ willBuild, willSubstitute, unknown, downloadSize, narSize);
if (ignoreUnknown) {
std::vector<StorePathWithOutputs> paths2;
@@ -148,7 +151,7 @@ static void opRealise(Strings opFlags, Strings opArgs)
if (dryRun) return;
/* Build all paths at the same time to exploit parallelism. */
- store->buildPaths(paths, buildMode);
+ store->buildPaths(toDerivedPaths(paths), buildMode);
if (!ignoreUnknown)
for (auto & i : paths) {
@@ -174,10 +177,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 +190,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));
}
@@ -208,7 +211,7 @@ static void opPrintFixedPath(Strings opFlags, Strings opArgs)
string hash = *i++;
string name = *i++;
- cout << fmt("%s\n", store->printStorePath(store->makeFixedOutputPath(recursive, Hash(hash, hashAlgo), name)));
+ cout << fmt("%s\n", store->printStorePath(store->makeFixedOutputPath(recursive, Hash::parseAny(hash, hashAlgo), name)));
}
@@ -218,8 +221,13 @@ static StorePathSet maybeUseOutputs(const StorePath & storePath, bool useOutput,
if (useOutput && storePath.isDerivation()) {
auto drv = store->derivationFromPath(storePath);
StorePathSet outputs;
- for (auto & i : drv.outputs)
- outputs.insert(i.second.path);
+ if (forceRealise)
+ return store->queryDerivationOutputs(storePath);
+ for (auto & i : drv.outputsAndOptPaths(*store)) {
+ if (!i.second.second)
+ throw UsageError("Cannot use output path of floating content-addressed derivation until we know what it is (e.g. by building it)");
+ outputs.insert(*i.second.second);
+ }
return outputs;
}
else return {storePath};
@@ -309,11 +317,9 @@ static void opQuery(Strings opFlags, Strings opArgs)
case qOutputs: {
for (auto & i : opArgs) {
- auto i2 = store->followLinksToStorePath(i);
- if (forceRealise) realisePath({i2});
- Derivation drv = store->derivationFromPath(i2);
- for (auto & j : drv.outputs)
- cout << fmt("%1%\n", store->printStorePath(j.second.path));
+ auto outputs = maybeUseOutputs(store->followLinksToStorePath(i), true, forceRealise);
+ for (auto & outputPath : outputs)
+ cout << fmt("%1%\n", store->printStorePath(outputPath));
}
break;
}
@@ -495,7 +501,10 @@ static void registerValidity(bool reregister, bool hashGiven, bool canonicalise)
ValidPathInfos infos;
while (1) {
- auto info = decodeValidPathInfo(*store, cin, hashGiven);
+ // We use a dummy value because we'll set it below. FIXME be correct by
+ // construction and avoid dummy value.
+ auto hashResultOpt = !hashGiven ? std::optional<HashResult> { {Hash::dummy, -1} } : std::nullopt;
+ auto info = decodeValidPathInfo(*store, cin, hashResultOpt);
if (!info) break;
if (!store->isValidPath(info->path) || reregister) {
/* !!! races */
@@ -506,7 +515,7 @@ static void registerValidity(bool reregister, bool hashGiven, bool canonicalise)
info->narHash = hash.first;
info->narSize = hash.second;
}
- infos.push_back(std::move(*info));
+ infos.insert_or_assign(info->path, *info);
}
}
@@ -572,10 +581,8 @@ static void opGC(Strings opFlags, Strings opArgs)
if (*i == "--print-roots") printRoots = true;
else if (*i == "--print-live") options.action = GCOptions::gcReturnLive;
else if (*i == "--print-dead") options.action = GCOptions::gcReturnDead;
- else if (*i == "--max-freed") {
- long long maxFreed = getIntArg<long long>(*i, i, opFlags.end(), true);
- options.maxFreed = maxFreed >= 0 ? maxFreed : 0;
- }
+ else if (*i == "--max-freed")
+ options.maxFreed = std::max(getIntArg<int64_t>(*i, i, opFlags.end(), true), (int64_t) 0);
else throw UsageError("bad sub-operation '%1%' in GC", *i);
if (!opArgs.empty()) throw UsageError("no arguments expected");
@@ -671,7 +678,7 @@ static void opImport(Strings opFlags, Strings opArgs)
if (!opArgs.empty()) throw UsageError("no arguments expected");
FdSource source(STDIN_FILENO);
- auto paths = store->importPaths(source, nullptr, NoCheckSigs);
+ auto paths = store->importPaths(source, NoCheckSigs);
for (auto & i : paths)
cout << fmt("%s\n", store->printStorePath(i)) << std::flush;
@@ -704,10 +711,7 @@ static void opVerify(Strings opFlags, Strings opArgs)
else throw UsageError("unknown flag '%1%'", i);
if (store->verifyStore(checkContents, repair)) {
- logWarning({
- .name = "Store consistency",
- .description = "not all errors were fixed"
- });
+ warn("not all store errors were fixed");
throw Exit(1);
}
}
@@ -725,18 +729,14 @@ static void opVerifyPath(Strings opFlags, Strings opArgs)
auto path = store->followLinksToStorePath(i);
printMsg(lvlTalkative, "checking path '%s'...", store->printStorePath(path));
auto info = store->queryPathInfo(path);
- HashSink sink(*info->narHash.type);
+ HashSink sink(info->narHash.type);
store->narFromPath(path, sink);
auto current = sink.finish();
if (current.first != info->narHash) {
- logError({
- .name = "Hash mismatch",
- .hint = hintfmt(
- "path '%s' was modified! expected hash '%s', got '%s'",
+ printError("path '%s' was modified! expected hash '%s', got '%s'",
store->printStorePath(path),
info->narHash.to_string(Base32, true),
- current.first.to_string(Base32, true))
- });
+ current.first.to_string(Base32, true));
status = 1;
}
}
@@ -753,7 +753,7 @@ static void opRepairPath(Strings opFlags, Strings opArgs)
throw UsageError("no flags expected");
for (auto & i : opArgs)
- ensureLocalStore()->repairPath(store->followLinksToStorePath(i));
+ store->repairPath(store->followLinksToStorePath(i));
}
/* Optimise the disk space usage of the Nix store by hard-linking
@@ -817,54 +817,35 @@ static void opServe(Strings opFlags, Strings opArgs)
case cmdQueryValidPaths: {
bool lock = readInt(in);
bool substitute = readInt(in);
- auto paths = readStorePaths<StorePathSet>(*store, in);
+ auto paths = worker_proto::read(*store, in, Phantom<StorePathSet> {});
if (lock && writeAllowed)
for (auto & path : paths)
store->addTempRoot(path);
- /* If requested, substitute missing paths. This
- implements nix-copy-closure's --use-substitutes
- flag. */
if (substitute && writeAllowed) {
- /* Filter out .drv files (we don't want to build anything). */
- std::vector<StorePathWithOutputs> paths2;
- for (auto & path : paths)
- if (!path.isDerivation())
- paths2.push_back({path});
- unsigned long long downloadSize, narSize;
- StorePathSet willBuild, willSubstitute, unknown;
- store->queryMissing(paths2,
- willBuild, willSubstitute, unknown, downloadSize, narSize);
- /* FIXME: should use ensurePath(), but it only
- does one path at a time. */
- if (!willSubstitute.empty())
- try {
- std::vector<StorePathWithOutputs> subs;
- for (auto & p : willSubstitute) subs.push_back({p});
- store->buildPaths(subs);
- } catch (Error & e) {
- logWarning(e.info());
- }
+ store->substitutePaths(paths);
}
- writeStorePaths(*store, out, store->queryValidPaths(paths));
+ worker_proto::write(*store, out, store->queryValidPaths(paths));
break;
}
case cmdQueryPathInfos: {
- auto paths = readStorePaths<StorePathSet>(*store, in);
+ auto paths = worker_proto::read(*store, in, Phantom<StorePathSet> {});
// !!! Maybe we want a queryPathInfos?
for (auto & i : paths) {
try {
auto info = store->queryPathInfo(i);
out << store->printStorePath(info->path)
<< (info->deriver ? store->printStorePath(*info->deriver) : "");
- writeStorePaths(*store, out, info->references);
+ worker_proto::write(*store, out, info->references);
// !!! Maybe we want compression?
out << info->narSize // downloadSize
<< info->narSize;
if (GET_PROTOCOL_MINOR(clientVersion) >= 4)
- out << (info->narHash ? info->narHash.to_string(Base32, true) : "") << renderContentAddress(info->ca) << info->sigs;
+ out << info->narHash.to_string(Base32, true)
+ << renderContentAddress(info->ca)
+ << info->sigs;
} catch (InvalidPath &) {
}
}
@@ -878,14 +859,14 @@ static void opServe(Strings opFlags, Strings opArgs)
case cmdImportPaths: {
if (!writeAllowed) throw Error("importing paths is not allowed");
- store->importPaths(in, nullptr, NoCheckSigs); // FIXME: should we skip sig checking?
+ store->importPaths(in, NoCheckSigs); // FIXME: should we skip sig checking?
out << 1; // indicate success
break;
}
case cmdExportPaths: {
readInt(in); // obsolete
- store->exportPaths(readStorePaths<StorePathSet>(*store, in), out);
+ store->exportPaths(worker_proto::read(*store, in, Phantom<StorePathSet> {}), out);
break;
}
@@ -895,13 +876,13 @@ static void opServe(Strings opFlags, Strings opArgs)
std::vector<StorePathWithOutputs> paths;
for (auto & s : readStrings<Strings>(in))
- paths.push_back(store->parsePathWithOutputs(s));
+ paths.push_back(parsePathWithOutputs(*store, s));
getBuildSettings();
try {
MonitorFdHup monitor(in.fd);
- store->buildPaths(paths);
+ store->buildPaths(toDerivedPaths(paths));
out << 0;
} catch (Error & e) {
assert(e.status);
@@ -914,9 +895,9 @@ static void opServe(Strings opFlags, Strings opArgs)
if (!writeAllowed) throw Error("building paths is not allowed");
- auto drvPath = store->parseStorePath(readString(in)); // informational only
+ auto drvPath = store->parseStorePath(readString(in));
BasicDerivation drv;
- readDerivation(in, *store, drv);
+ readDerivation(in, *store, drv, Derivation::nameFromPath(drvPath));
getBuildSettings();
@@ -927,6 +908,10 @@ static void opServe(Strings opFlags, Strings opArgs)
if (GET_PROTOCOL_MINOR(clientVersion) >= 3)
out << status.timesBuilt << status.isNonDeterministic << status.startTime << status.stopTime;
+ if (GET_PROTOCOL_MINOR(clientVersion >= 6)) {
+ worker_proto::write(*store, out, status.builtOutputs);
+ }
+
break;
}
@@ -934,9 +919,9 @@ static void opServe(Strings opFlags, Strings opArgs)
case cmdQueryClosure: {
bool includeOutputs = readInt(in);
StorePathSet closure;
- store->computeFSClosure(readStorePaths<StorePathSet>(*store, in),
+ store->computeFSClosure(worker_proto::read(*store, in, Phantom<StorePathSet> {}),
closure, false, includeOutputs);
- writeStorePaths(*store, out, closure);
+ worker_proto::write(*store, out, closure);
break;
}
@@ -944,12 +929,14 @@ static void opServe(Strings opFlags, Strings opArgs)
if (!writeAllowed) throw Error("importing paths is not allowed");
auto path = readString(in);
- ValidPathInfo info(store->parseStorePath(path));
auto deriver = readString(in);
+ ValidPathInfo info {
+ store->parseStorePath(path),
+ Hash::parseAny(readString(in), htSHA256),
+ };
if (deriver != "")
info.deriver = store->parseStorePath(deriver);
- info.narHash = Hash(readString(in), htSHA256);
- info.references = readStorePaths<StorePathSet>(*store, in);
+ info.references = worker_proto::read(*store, in, Phantom<StorePathSet> {});
in >> info.registrationTime >> info.narSize >> info.ultimate;
info.sigs = readStrings<StringSet>(in);
info.ca = parseContentAddressOpt(readString(in));
@@ -989,21 +976,11 @@ static void opGenerateBinaryCacheKey(Strings opFlags, Strings opArgs)
string secretKeyFile = *i++;
string publicKeyFile = *i++;
-#if HAVE_SODIUM
- if (sodium_init() == -1)
- throw Error("could not initialise libsodium");
-
- unsigned char pk[crypto_sign_PUBLICKEYBYTES];
- unsigned char sk[crypto_sign_SECRETKEYBYTES];
- if (crypto_sign_keypair(pk, sk) != 0)
- throw Error("key generation failed");
+ auto secretKey = SecretKey::generate(keyName);
- writeFile(publicKeyFile, keyName + ":" + base64Encode(string((char *) pk, crypto_sign_PUBLICKEYBYTES)));
+ writeFile(publicKeyFile, secretKey.toPublicKey().to_string());
umask(0077);
- writeFile(secretKeyFile, keyName + ":" + base64Encode(string((char *) sk, crypto_sign_SECRETKEYBYTES)));
-#else
- throw Error("Nix was not compiled with libsodium, required for signed binary cache support");
-#endif
+ writeFile(secretKeyFile, secretKey.to_string());
}
@@ -1016,7 +993,7 @@ static void opVersion(Strings opFlags, Strings opArgs)
/* Scan the arguments; find the operation, set global flags, put all
other flags in a list, and put all other arguments in another
list. */
-static int _main(int argc, char * * argv)
+static int main_nix_store(int argc, char * * argv)
{
{
Strings opFlags, opArgs;
@@ -1080,7 +1057,7 @@ static int _main(int argc, char * * argv)
else if (*arg == "--add-root")
gcRoot = absPath(getArg(*arg, arg, end));
else if (*arg == "--indirect")
- indirectRoot = true;
+ ;
else if (*arg == "--no-output")
noOutput = true;
else if (*arg != "" && arg->at(0) == '-') {
@@ -1097,8 +1074,6 @@ static int _main(int argc, char * * argv)
return true;
});
- initPlugins();
-
if (!op) throw UsageError("no operation specified");
if (op != opDump && op != opRestore) /* !!! hack */
@@ -1112,4 +1087,6 @@ static int _main(int argc, char * * argv)
}
}
-static RegisterLegacyCommand s1("nix-store", _main);
+static RegisterLegacyCommand r_nix_store("nix-store", main_nix_store);
+
+}