libstore: asyncify Store::queryPathInfo{,Uncached}
Change-Id: I182c396ec0bfdfc8febd6752774e668b3d97dcc1
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
#include "dotgraph.hh"
|
#include "dotgraph.hh"
|
||||||
#include "lix/libstore/store-api.hh"
|
#include "lix/libstore/store-api.hh"
|
||||||
|
#include "lix/libutil/async.hh"
|
||||||
#include "lix/libutil/result.hh"
|
#include "lix/libutil/result.hh"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -56,7 +57,7 @@ try {
|
|||||||
|
|
||||||
cout << makeNode(std::string(path.to_string()), path.name(), "#ff0000");
|
cout << makeNode(std::string(path.to_string()), path.name(), "#ff0000");
|
||||||
|
|
||||||
for (auto & p : store->queryPathInfo(path)->references) {
|
for (auto & p : TRY_AWAIT(store->queryPathInfo(path))->references) {
|
||||||
if (p != path) {
|
if (p != path) {
|
||||||
workList.insert(p);
|
workList.insert(p);
|
||||||
cout << makeEdge(std::string(p.to_string()), std::string(path.to_string()));
|
cout << makeEdge(std::string(p.to_string()), std::string(path.to_string()));
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "graphml.hh"
|
#include "graphml.hh"
|
||||||
#include "lix/libstore/store-api.hh"
|
#include "lix/libstore/store-api.hh"
|
||||||
#include "lix/libstore/derivations.hh"
|
#include "lix/libstore/derivations.hh"
|
||||||
|
#include "lix/libutil/async.hh"
|
||||||
#include "lix/libutil/result.hh"
|
#include "lix/libutil/result.hh"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -68,7 +69,7 @@ try {
|
|||||||
ret = doneSet.insert(path);
|
ret = doneSet.insert(path);
|
||||||
if (ret.second == false) continue;
|
if (ret.second == false) continue;
|
||||||
|
|
||||||
auto info = store->queryPathInfo(path);
|
auto info = TRY_AWAIT(store->queryPathInfo(path));
|
||||||
cout << makeNode(*info);
|
cout << makeNode(*info);
|
||||||
|
|
||||||
for (auto & p : info->references) {
|
for (auto & p : info->references) {
|
||||||
|
|||||||
+14
-12
@@ -51,13 +51,15 @@ ref<LocalStore> ensureLocalStore()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static StorePath useDeriver(const StorePath & path)
|
static kj::Promise<Result<StorePath>> useDeriver(const StorePath & path)
|
||||||
{
|
try {
|
||||||
if (path.isDerivation()) return path;
|
if (path.isDerivation()) co_return path;
|
||||||
auto info = store->queryPathInfo(path);
|
auto info = TRY_AWAIT(store->queryPathInfo(path));
|
||||||
if (!info->deriver)
|
if (!info->deriver)
|
||||||
throw Error("deriver of path '%s' is not known", store->printStorePath(path));
|
throw Error("deriver of path '%s' is not known", store->printStorePath(path));
|
||||||
return *info->deriver;
|
co_return *info->deriver;
|
||||||
|
} catch (...) {
|
||||||
|
co_return result::current_exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -278,7 +280,7 @@ static void printTree(AsyncIoRoot & aio, const StorePath & path,
|
|||||||
|
|
||||||
cout << fmt("%s%s\n", firstPad, store->printStorePath(path));
|
cout << fmt("%s%s\n", firstPad, store->printStorePath(path));
|
||||||
|
|
||||||
auto info = store->queryPathInfo(path);
|
auto info = aio.blockOn(store->queryPathInfo(path));
|
||||||
|
|
||||||
/* Topologically sort under the relation A < B iff A \in
|
/* Topologically sort under the relation A < B iff A \in
|
||||||
closure(B). That is, if derivation A is an (possibly indirect)
|
closure(B). That is, if derivation A is an (possibly indirect)
|
||||||
@@ -368,7 +370,7 @@ static void opQuery(AsyncIoRoot & aio, Strings opFlags, Strings opArgs)
|
|||||||
aio.blockOn(store->computeFSClosure(j, paths, false, includeOutputs));
|
aio.blockOn(store->computeFSClosure(j, paths, false, includeOutputs));
|
||||||
}
|
}
|
||||||
else if (query == qReferences) {
|
else if (query == qReferences) {
|
||||||
for (auto & p : store->queryPathInfo(j)->references)
|
for (auto & p : aio.blockOn(store->queryPathInfo(j))->references)
|
||||||
paths.insert(p);
|
paths.insert(p);
|
||||||
}
|
}
|
||||||
else if (query == qReferrers) {
|
else if (query == qReferrers) {
|
||||||
@@ -390,7 +392,7 @@ static void opQuery(AsyncIoRoot & aio, Strings opFlags, Strings opArgs)
|
|||||||
|
|
||||||
case qDeriver:
|
case qDeriver:
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
auto info = store->queryPathInfo(store->followLinksToStorePath(i));
|
auto info = aio.blockOn(store->queryPathInfo(store->followLinksToStorePath(i)));
|
||||||
cout << fmt("%s\n", info->deriver ? store->printStorePath(*info->deriver) : "unknown-deriver");
|
cout << fmt("%s\n", info->deriver ? store->printStorePath(*info->deriver) : "unknown-deriver");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -413,7 +415,7 @@ static void opQuery(AsyncIoRoot & aio, Strings opFlags, Strings opArgs)
|
|||||||
|
|
||||||
case qBinding:
|
case qBinding:
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
auto path = useDeriver(store->followLinksToStorePath(i));
|
auto path = aio.blockOn(useDeriver(store->followLinksToStorePath(i)));
|
||||||
Derivation drv = aio.blockOn(store->derivationFromPath(path));
|
Derivation drv = aio.blockOn(store->derivationFromPath(path));
|
||||||
StringPairs::iterator j = drv.env.find(bindingName);
|
StringPairs::iterator j = drv.env.find(bindingName);
|
||||||
if (j == drv.env.end())
|
if (j == drv.env.end())
|
||||||
@@ -427,7 +429,7 @@ static void opQuery(AsyncIoRoot & aio, Strings opFlags, Strings opArgs)
|
|||||||
case qSize:
|
case qSize:
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
for (auto & j : aio.blockOn(maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise))) {
|
for (auto & j : aio.blockOn(maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise))) {
|
||||||
auto info = store->queryPathInfo(j);
|
auto info = aio.blockOn(store->queryPathInfo(j));
|
||||||
if (query == qHash) {
|
if (query == qHash) {
|
||||||
assert(info->narHash.type == HashType::SHA256);
|
assert(info->narHash.type == HashType::SHA256);
|
||||||
cout << fmt("%s\n", info->narHash.to_string(Base::Base32, true));
|
cout << fmt("%s\n", info->narHash.to_string(Base::Base32, true));
|
||||||
@@ -789,7 +791,7 @@ static void opVerifyPath(AsyncIoRoot & aio, Strings opFlags, Strings opArgs)
|
|||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
auto path = store->followLinksToStorePath(i);
|
auto path = store->followLinksToStorePath(i);
|
||||||
printMsg(lvlTalkative, "checking path '%s'...", store->printStorePath(path));
|
printMsg(lvlTalkative, "checking path '%s'...", store->printStorePath(path));
|
||||||
auto info = store->queryPathInfo(path);
|
auto info = aio.blockOn(store->queryPathInfo(path));
|
||||||
HashSink sink(info->narHash.type);
|
HashSink sink(info->narHash.type);
|
||||||
aio.blockOn(store->narFromPath(path))->drainInto(sink);
|
aio.blockOn(store->narFromPath(path))->drainInto(sink);
|
||||||
auto current = sink.finish();
|
auto current = sink.finish();
|
||||||
@@ -917,7 +919,7 @@ static void opServe(AsyncIoRoot & aio, Strings opFlags, Strings opArgs)
|
|||||||
// !!! Maybe we want a queryPathInfos?
|
// !!! Maybe we want a queryPathInfos?
|
||||||
for (auto & i : paths) {
|
for (auto & i : paths) {
|
||||||
try {
|
try {
|
||||||
auto info = store->queryPathInfo(i);
|
auto info = aio.blockOn(store->queryPathInfo(i));
|
||||||
out << store->printStorePath(info->path);
|
out << store->printStorePath(info->path);
|
||||||
out << ServeProto::write(*store, wconn, static_cast<const UnkeyedValidPathInfo &>(*info));
|
out << ServeProto::write(*store, wconn, static_cast<const UnkeyedValidPathInfo &>(*info));
|
||||||
} catch (InvalidPath &) {
|
} catch (InvalidPath &) {
|
||||||
|
|||||||
@@ -1284,7 +1284,11 @@ static void prim_readFile(EvalState & state, const PosIdx pos, Value * * args, V
|
|||||||
StorePathSet refs;
|
StorePathSet refs;
|
||||||
if (state.ctx.store->isInStore(path.canonical().abs())) {
|
if (state.ctx.store->isInStore(path.canonical().abs())) {
|
||||||
try {
|
try {
|
||||||
refs = state.ctx.store->queryPathInfo(state.ctx.store->toStorePath(path.canonical().abs()).first)->references;
|
refs = state.aio
|
||||||
|
.blockOn(state.ctx.store->queryPathInfo(
|
||||||
|
state.ctx.store->toStorePath(path.canonical().abs()).first
|
||||||
|
))
|
||||||
|
->references;
|
||||||
} catch (Error &) { // FIXME: should be InvalidPathError
|
} catch (Error &) { // FIXME: should be InvalidPathError
|
||||||
}
|
}
|
||||||
// Re-scan references to filter down to just the ones that actually occur in the file.
|
// Re-scan references to filter down to just the ones that actually occur in the file.
|
||||||
@@ -1530,7 +1534,7 @@ static void addPath(
|
|||||||
try {
|
try {
|
||||||
auto [storePath, subPath] = state.ctx.store->toStorePath(path);
|
auto [storePath, subPath] = state.ctx.store->toStorePath(path);
|
||||||
// FIXME: we should scanForReferences on the path before adding it
|
// FIXME: we should scanForReferences on the path before adding it
|
||||||
refs = state.ctx.store->queryPathInfo(storePath)->references;
|
refs = state.aio.blockOn(state.ctx.store->queryPathInfo(storePath))->references;
|
||||||
realPath = state.ctx.store->toRealPath(path);
|
realPath = state.ctx.store->toRealPath(path);
|
||||||
} catch (Error &) { // FIXME: should be InvalidPathError
|
} catch (Error &) { // FIXME: should be InvalidPathError
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ static void runFetchClosureWithRewrite(EvalState & state, const PosIdx pos, Stor
|
|||||||
|
|
||||||
// check and return
|
// check and return
|
||||||
|
|
||||||
auto resultInfo = state.ctx.store->queryPathInfo(toPath);
|
auto resultInfo = state.aio.blockOn(state.ctx.store->queryPathInfo(toPath));
|
||||||
|
|
||||||
if (!resultInfo->isContentAddressed(*state.ctx.store)) {
|
if (!resultInfo->isContentAddressed(*state.ctx.store)) {
|
||||||
// We don't perform the rewriting when outPath already exists, as an optimisation.
|
// We don't perform the rewriting when outPath already exists, as an optimisation.
|
||||||
@@ -71,7 +71,7 @@ static void runFetchClosureWithContentAddressedPath(EvalState & state, const Pos
|
|||||||
if (!state.aio.blockOn(state.ctx.store->isValidPath(fromPath)))
|
if (!state.aio.blockOn(state.ctx.store->isValidPath(fromPath)))
|
||||||
state.aio.blockOn(copyClosure(fromStore, *state.ctx.store, RealisedPath::Set { fromPath }));
|
state.aio.blockOn(copyClosure(fromStore, *state.ctx.store, RealisedPath::Set { fromPath }));
|
||||||
|
|
||||||
auto info = state.ctx.store->queryPathInfo(fromPath);
|
auto info = state.aio.blockOn(state.ctx.store->queryPathInfo(fromPath));
|
||||||
|
|
||||||
if (!info->isContentAddressed(*state.ctx.store)) {
|
if (!info->isContentAddressed(*state.ctx.store)) {
|
||||||
throw Error({
|
throw Error({
|
||||||
@@ -97,7 +97,7 @@ static void runFetchClosureWithInputAddressedPath(EvalState & state, const PosId
|
|||||||
if (!state.aio.blockOn(state.ctx.store->isValidPath(fromPath)))
|
if (!state.aio.blockOn(state.ctx.store->isValidPath(fromPath)))
|
||||||
state.aio.blockOn(copyClosure(fromStore, *state.ctx.store, RealisedPath::Set { fromPath }));
|
state.aio.blockOn(copyClosure(fromStore, *state.ctx.store, RealisedPath::Set { fromPath }));
|
||||||
|
|
||||||
auto info = state.ctx.store->queryPathInfo(fromPath);
|
auto info = state.aio.blockOn(state.ctx.store->queryPathInfo(fromPath));
|
||||||
|
|
||||||
if (info->isContentAddressed(*state.ctx.store)) {
|
if (info->isContentAddressed(*state.ctx.store)) {
|
||||||
throw Error({
|
throw Error({
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ static void fetch(EvalState & state, const PosIdx pos, Value * * args, Value & v
|
|||||||
|
|
||||||
if (expectedHash) {
|
if (expectedHash) {
|
||||||
auto hash = unpack
|
auto hash = unpack
|
||||||
? state.ctx.store->queryPathInfo(storePath)->narHash
|
? state.aio.blockOn(state.ctx.store->queryPathInfo(storePath))->narHash
|
||||||
: hashFile(HashType::SHA256, state.ctx.store->toRealPath(storePath));
|
: hashFile(HashType::SHA256, state.ctx.store->toRealPath(storePath));
|
||||||
if (hash != *expectedHash) {
|
if (hash != *expectedHash) {
|
||||||
state.ctx.errors.make<EvalError>(
|
state.ctx.errors.make<EvalError>(
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ try {
|
|||||||
.storePath = storePath,
|
.storePath = storePath,
|
||||||
};
|
};
|
||||||
|
|
||||||
auto narHash = store->queryPathInfo(tree.storePath)->narHash;
|
auto narHash = TRY_AWAIT(store->queryPathInfo(tree.storePath))->narHash;
|
||||||
input.attrs.insert_or_assign("narHash", narHash.to_string(Base::SRI, true));
|
input.attrs.insert_or_assign("narHash", narHash.to_string(Base::SRI, true));
|
||||||
|
|
||||||
if (auto prevNarHash = getNarHash()) {
|
if (auto prevNarHash = getNarHash()) {
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ try {
|
|||||||
for (auto & ref : info.references)
|
for (auto & ref : info.references)
|
||||||
try {
|
try {
|
||||||
if (ref != info.path)
|
if (ref != info.path)
|
||||||
queryPathInfo(ref);
|
TRY_AWAIT(queryPathInfo(ref));
|
||||||
} catch (InvalidPath &) {
|
} catch (InvalidPath &) {
|
||||||
throw Error("cannot add '%s' to the binary cache because the reference '%s' does not exist",
|
throw Error("cannot add '%s' to the binary cache because the reference '%s' does not exist",
|
||||||
printStorePath(info.path), printStorePath(ref));
|
printStorePath(info.path), printStorePath(ref));
|
||||||
@@ -343,7 +343,7 @@ BinaryCacheStore::queryPathFromHashPart(const std::string & hashPart)
|
|||||||
try {
|
try {
|
||||||
auto pseudoPath = StorePath(hashPart + "-" + MissingName);
|
auto pseudoPath = StorePath(hashPart + "-" + MissingName);
|
||||||
try {
|
try {
|
||||||
auto info = queryPathInfo(pseudoPath);
|
auto info = TRY_AWAIT(queryPathInfo(pseudoPath));
|
||||||
co_return info->path;
|
co_return info->path;
|
||||||
} catch (InvalidPath &) {
|
} catch (InvalidPath &) {
|
||||||
co_return std::nullopt;
|
co_return std::nullopt;
|
||||||
@@ -354,7 +354,7 @@ try {
|
|||||||
|
|
||||||
kj::Promise<Result<box_ptr<Source>>> BinaryCacheStore::narFromPath(const StorePath & storePath)
|
kj::Promise<Result<box_ptr<Source>>> BinaryCacheStore::narFromPath(const StorePath & storePath)
|
||||||
try {
|
try {
|
||||||
auto info = queryPathInfo(storePath).cast<const NarInfo>();
|
auto info = TRY_AWAIT(queryPathInfo(storePath)).cast<const NarInfo>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto file = getFile(info->url);
|
auto file = getFile(info->url);
|
||||||
@@ -385,8 +385,9 @@ try {
|
|||||||
co_return result::current_exception();
|
co_return result::current_exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const ValidPathInfo> BinaryCacheStore::queryPathInfoUncached(const StorePath & storePath)
|
kj::Promise<Result<std::shared_ptr<const ValidPathInfo>>>
|
||||||
{
|
BinaryCacheStore::queryPathInfoUncached(const StorePath & storePath)
|
||||||
|
try {
|
||||||
auto uri = getUri();
|
auto uri = getUri();
|
||||||
auto storePathS = printStorePath(storePath);
|
auto storePathS = printStorePath(storePath);
|
||||||
auto act = std::make_shared<Activity>(*logger, lvlTalkative, actQueryPathInfo,
|
auto act = std::make_shared<Activity>(*logger, lvlTalkative, actQueryPathInfo,
|
||||||
@@ -397,11 +398,13 @@ std::shared_ptr<const ValidPathInfo> BinaryCacheStore::queryPathInfoUncached(con
|
|||||||
|
|
||||||
auto data = getFileContents(narInfoFile);
|
auto data = getFileContents(narInfoFile);
|
||||||
|
|
||||||
if (!data) return nullptr;
|
if (!data) co_return result::success(nullptr);
|
||||||
|
|
||||||
stats.narInfoRead++;
|
stats.narInfoRead++;
|
||||||
|
|
||||||
return std::make_shared<NarInfo>(*this, *data, narInfoFile);
|
co_return std::make_shared<NarInfo>(*this, *data, narInfoFile);
|
||||||
|
} catch (...) {
|
||||||
|
co_return result::current_exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
static ValidPathInfo makeAddToStoreInfo(
|
static ValidPathInfo makeAddToStoreInfo(
|
||||||
@@ -542,7 +545,8 @@ try {
|
|||||||
S3 might return an outdated cached version. */
|
S3 might return an outdated cached version. */
|
||||||
|
|
||||||
// downcast: BinaryCacheStore always returns NarInfo from queryPathInfoUncached, making it sound
|
// downcast: BinaryCacheStore always returns NarInfo from queryPathInfoUncached, making it sound
|
||||||
auto narInfo = make_ref<NarInfo>(dynamic_cast<NarInfo const &>(*queryPathInfo(storePath)));
|
auto narInfo =
|
||||||
|
make_ref<NarInfo>(dynamic_cast<NarInfo const &>(*TRY_AWAIT(queryPathInfo(storePath))));
|
||||||
|
|
||||||
narInfo->sigs.insert(sigs.begin(), sigs.end());
|
narInfo->sigs.insert(sigs.begin(), sigs.end());
|
||||||
|
|
||||||
|
|||||||
@@ -111,7 +111,8 @@ public:
|
|||||||
|
|
||||||
kj::Promise<Result<bool>> isValidPathUncached(const StorePath & path) override;
|
kj::Promise<Result<bool>> isValidPathUncached(const StorePath & path) override;
|
||||||
|
|
||||||
std::shared_ptr<const ValidPathInfo> queryPathInfoUncached(const StorePath & path) override;
|
kj::Promise<Result<std::shared_ptr<const ValidPathInfo>>>
|
||||||
|
queryPathInfoUncached(const StorePath & path) override;
|
||||||
|
|
||||||
kj::Promise<Result<std::optional<StorePath>>>
|
kj::Promise<Result<std::optional<StorePath>>>
|
||||||
queryPathFromHashPart(const std::string & hashPart) override;
|
queryPathFromHashPart(const std::string & hashPart) override;
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ try {
|
|||||||
if (result.exitCode != Goal::ecSuccess) {
|
if (result.exitCode != Goal::ecSuccess) {
|
||||||
/* Since substituting the path didn't work, if we have a valid
|
/* Since substituting the path didn't work, if we have a valid
|
||||||
deriver, then rebuild the deriver. */
|
deriver, then rebuild the deriver. */
|
||||||
auto info = queryPathInfo(path);
|
auto info = TRY_AWAIT(queryPathInfo(path));
|
||||||
if (info->deriver && TRY_AWAIT(isValidPath(*info->deriver))) {
|
if (info->deriver && TRY_AWAIT(isValidPath(*info->deriver))) {
|
||||||
TRY_AWAIT(processGoals(*this, *this, [&](GoalFactory & gf) {
|
TRY_AWAIT(processGoals(*this, *this, [&](GoalFactory & gf) {
|
||||||
Worker::Targets goals;
|
Worker::Targets goals;
|
||||||
|
|||||||
@@ -1050,23 +1050,26 @@ struct RestrictedStore : public virtual IndirectRootStore, public virtual GcStor
|
|||||||
co_return result::current_exception();
|
co_return result::current_exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const ValidPathInfo> queryPathInfoUncached(const StorePath & path) override
|
kj::Promise<Result<std::shared_ptr<const ValidPathInfo>>>
|
||||||
{
|
queryPathInfoUncached(const StorePath & path) override
|
||||||
|
try {
|
||||||
if (goal.isAllowed(path)) {
|
if (goal.isAllowed(path)) {
|
||||||
try {
|
try {
|
||||||
/* Censor impure information. */
|
/* Censor impure information. */
|
||||||
auto info = std::make_shared<ValidPathInfo>(*next->queryPathInfo(path));
|
auto info = std::make_shared<ValidPathInfo>(*TRY_AWAIT(next->queryPathInfo(path)));
|
||||||
info->deriver.reset();
|
info->deriver.reset();
|
||||||
info->registrationTime = 0;
|
info->registrationTime = 0;
|
||||||
info->ultimate = false;
|
info->ultimate = false;
|
||||||
info->sigs.clear();
|
info->sigs.clear();
|
||||||
return info;
|
co_return info;
|
||||||
} catch (InvalidPath &) {
|
} catch (InvalidPath &) {
|
||||||
return nullptr;
|
co_return result::success(nullptr);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
return nullptr;
|
co_return result::success(nullptr);
|
||||||
};
|
} catch (...) {
|
||||||
|
co_return result::current_exception();
|
||||||
|
}
|
||||||
|
|
||||||
kj::Promise<Result<void>>
|
kj::Promise<Result<void>>
|
||||||
queryReferrers(const StorePath & path, StorePathSet & referrers) override
|
queryReferrers(const StorePath & path, StorePathSet & referrers) override
|
||||||
@@ -2403,7 +2406,7 @@ try {
|
|||||||
if (buildMode == bmCheck) {
|
if (buildMode == bmCheck) {
|
||||||
|
|
||||||
if (!TRY_AWAIT(worker.store.isValidPath(newInfo.path))) continue;
|
if (!TRY_AWAIT(worker.store.isValidPath(newInfo.path))) continue;
|
||||||
ValidPathInfo oldInfo(*worker.store.queryPathInfo(newInfo.path));
|
ValidPathInfo oldInfo(*TRY_AWAIT(worker.store.queryPathInfo(newInfo.path)));
|
||||||
if (newInfo.narHash != oldInfo.narHash) {
|
if (newInfo.narHash != oldInfo.narHash) {
|
||||||
anyCheckMismatchSeen = true;
|
anyCheckMismatchSeen = true;
|
||||||
if (settings.runDiffHook || settings.keepFailed) {
|
if (settings.runDiffHook || settings.keepFailed) {
|
||||||
@@ -2558,115 +2561,132 @@ try {
|
|||||||
/* Compute the closure and closure size of some output. This
|
/* Compute the closure and closure size of some output. This
|
||||||
is slightly tricky because some of its references (namely
|
is slightly tricky because some of its references (namely
|
||||||
other outputs) may not be valid yet. */
|
other outputs) may not be valid yet. */
|
||||||
auto getClosure = [&](const StorePath & path)
|
// NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines)
|
||||||
{
|
auto getClosure = [&](const StorePath & path
|
||||||
uint64_t closureSize = 0;
|
) -> kj::Promise<Result<std::pair<StorePathSet, uint64_t>>> {
|
||||||
StorePathSet pathsDone;
|
try {
|
||||||
std::queue<StorePath> pathsLeft;
|
uint64_t closureSize = 0;
|
||||||
pathsLeft.push(path);
|
StorePathSet pathsDone;
|
||||||
|
std::queue<StorePath> pathsLeft;
|
||||||
|
pathsLeft.push(path);
|
||||||
|
|
||||||
while (!pathsLeft.empty()) {
|
while (!pathsLeft.empty()) {
|
||||||
auto path = pathsLeft.front();
|
auto path = pathsLeft.front();
|
||||||
pathsLeft.pop();
|
pathsLeft.pop();
|
||||||
if (!pathsDone.insert(path).second) continue;
|
if (!pathsDone.insert(path).second) continue;
|
||||||
|
|
||||||
auto i = outputsByPath.find(worker.store.printStorePath(path));
|
auto i = outputsByPath.find(worker.store.printStorePath(path));
|
||||||
if (i != outputsByPath.end()) {
|
if (i != outputsByPath.end()) {
|
||||||
closureSize += i->second.narSize;
|
closureSize += i->second.narSize;
|
||||||
for (auto & ref : i->second.references)
|
for (auto & ref : i->second.references)
|
||||||
pathsLeft.push(ref);
|
pathsLeft.push(ref);
|
||||||
} else {
|
} else {
|
||||||
auto info = worker.store.queryPathInfo(path);
|
auto info = TRY_AWAIT(worker.store.queryPathInfo(path));
|
||||||
closureSize += info->narSize;
|
closureSize += info->narSize;
|
||||||
for (auto & ref : info->references)
|
for (auto & ref : info->references)
|
||||||
pathsLeft.push(ref);
|
pathsLeft.push(ref);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return std::make_pair(std::move(pathsDone), closureSize);
|
co_return std::make_pair(std::move(pathsDone), closureSize);
|
||||||
|
} catch (...) {
|
||||||
|
co_return result::current_exception();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto applyChecks = [&](const Checks & checks)
|
// NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines)
|
||||||
{
|
auto applyChecks = [&](const Checks & checks) -> kj::Promise<Result<void>> {
|
||||||
if (checks.maxSize && info.narSize > *checks.maxSize)
|
try {
|
||||||
throw BuildError("path '%s' is too large at %d bytes; limit is %d bytes",
|
if (checks.maxSize && info.narSize > *checks.maxSize)
|
||||||
worker.store.printStorePath(info.path), info.narSize, *checks.maxSize);
|
throw BuildError("path '%s' is too large at %d bytes; limit is %d bytes",
|
||||||
|
worker.store.printStorePath(info.path), info.narSize, *checks.maxSize);
|
||||||
|
|
||||||
if (checks.maxClosureSize) {
|
if (checks.maxClosureSize) {
|
||||||
uint64_t closureSize = getClosure(info.path).second;
|
uint64_t closureSize = TRY_AWAIT(getClosure(info.path)).second;
|
||||||
if (closureSize > *checks.maxClosureSize)
|
if (closureSize > *checks.maxClosureSize)
|
||||||
throw BuildError("closure of path '%s' is too large at %d bytes; limit is %d bytes",
|
throw BuildError("closure of path '%s' is too large at %d bytes; limit is %d bytes",
|
||||||
worker.store.printStorePath(info.path), closureSize, *checks.maxClosureSize);
|
worker.store.printStorePath(info.path), closureSize, *checks.maxClosureSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto checkRefs = [&](const std::optional<Strings> & value, bool allowed, bool recursive)
|
// NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines)
|
||||||
{
|
auto checkRefs = [&](const std::optional<Strings> & value,
|
||||||
if (!value) return;
|
bool allowed,
|
||||||
|
bool recursive) -> kj::Promise<Result<void>> {
|
||||||
|
try {
|
||||||
|
if (!value) co_return result::success();
|
||||||
|
|
||||||
/* Parse a list of reference specifiers. Each element must
|
/* Parse a list of reference specifiers. Each element must
|
||||||
either be a store path, or the symbolic name of the output
|
either be a store path, or the symbolic name of the output
|
||||||
of the derivation (such as `out'). */
|
of the derivation (such as `out'). */
|
||||||
StorePathSet spec;
|
StorePathSet spec;
|
||||||
for (auto & i : *value) {
|
for (auto & i : *value) {
|
||||||
if (worker.store.isStorePath(i))
|
if (worker.store.isStorePath(i))
|
||||||
spec.insert(worker.store.parseStorePath(i));
|
spec.insert(worker.store.parseStorePath(i));
|
||||||
else if (auto output = get(newlyBuiltOutputs, i))
|
else if (auto output = get(newlyBuiltOutputs, i))
|
||||||
spec.insert(output->path);
|
spec.insert(output->path);
|
||||||
else if (auto storePath = get(alreadyRegisteredOutputs, i))
|
else if (auto storePath = get(alreadyRegisteredOutputs, i))
|
||||||
spec.insert(*storePath);
|
spec.insert(*storePath);
|
||||||
else {
|
else {
|
||||||
std::string outputsListing = concatMapStringsSep(
|
std::string outputsListing = concatMapStringsSep(
|
||||||
", ",
|
", ",
|
||||||
newlyBuiltOutputs,
|
newlyBuiltOutputs,
|
||||||
[](auto & o) { return o.first; }
|
[](auto & o) { return o.first; }
|
||||||
);
|
);
|
||||||
if (!alreadyRegisteredOutputs.empty()) {
|
if (!alreadyRegisteredOutputs.empty()) {
|
||||||
outputsListing.append(outputsListing.empty() ? "" : ", ");
|
outputsListing.append(outputsListing.empty() ? "" : ", ");
|
||||||
outputsListing.append(concatMapStringsSep(
|
outputsListing.append(concatMapStringsSep(
|
||||||
", ",
|
", ",
|
||||||
alreadyRegisteredOutputs,
|
alreadyRegisteredOutputs,
|
||||||
[](auto & o) { return o.first; })
|
[](auto & o) { return o.first; })
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
throw BuildError("derivation '%s' output check for '%s' contains an illegal reference specifier '%s',"
|
||||||
|
" expected store path or output name (one of [%s])",
|
||||||
|
worker.store.printStorePath(drvPath), outputName, i, outputsListing);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw BuildError("derivation '%s' output check for '%s' contains an illegal reference specifier '%s',"
|
|
||||||
" expected store path or output name (one of [%s])",
|
auto used = recursive
|
||||||
worker.store.printStorePath(drvPath), outputName, i, outputsListing);
|
? TRY_AWAIT(getClosure(info.path)).first
|
||||||
|
: info.references;
|
||||||
|
|
||||||
|
if (recursive && checks.ignoreSelfRefs)
|
||||||
|
used.erase(info.path);
|
||||||
|
|
||||||
|
StorePathSet badPaths;
|
||||||
|
|
||||||
|
for (auto & i : used)
|
||||||
|
if (allowed) {
|
||||||
|
if (!spec.count(i))
|
||||||
|
badPaths.insert(i);
|
||||||
|
} else {
|
||||||
|
if (spec.count(i))
|
||||||
|
badPaths.insert(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!badPaths.empty()) {
|
||||||
|
std::string badPathsStr;
|
||||||
|
for (auto & i : badPaths) {
|
||||||
|
badPathsStr += "\n ";
|
||||||
|
badPathsStr += worker.store.printStorePath(i);
|
||||||
|
}
|
||||||
|
throw BuildError("output '%s' is not allowed to refer to the following paths:%s",
|
||||||
|
worker.store.printStorePath(info.path), badPathsStr);
|
||||||
|
}
|
||||||
|
co_return result::success();
|
||||||
|
} catch (...) {
|
||||||
|
co_return result::current_exception();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
auto used = recursive
|
TRY_AWAIT(checkRefs(checks.allowedReferences, true, false));
|
||||||
? getClosure(info.path).first
|
TRY_AWAIT(checkRefs(checks.allowedRequisites, true, true));
|
||||||
: info.references;
|
TRY_AWAIT(checkRefs(checks.disallowedReferences, false, false));
|
||||||
|
TRY_AWAIT(checkRefs(checks.disallowedRequisites, false, true));
|
||||||
if (recursive && checks.ignoreSelfRefs)
|
co_return result::success();
|
||||||
used.erase(info.path);
|
} catch (...) {
|
||||||
|
co_return result::current_exception();
|
||||||
StorePathSet badPaths;
|
}
|
||||||
|
|
||||||
for (auto & i : used)
|
|
||||||
if (allowed) {
|
|
||||||
if (!spec.count(i))
|
|
||||||
badPaths.insert(i);
|
|
||||||
} else {
|
|
||||||
if (spec.count(i))
|
|
||||||
badPaths.insert(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!badPaths.empty()) {
|
|
||||||
std::string badPathsStr;
|
|
||||||
for (auto & i : badPaths) {
|
|
||||||
badPathsStr += "\n ";
|
|
||||||
badPathsStr += worker.store.printStorePath(i);
|
|
||||||
}
|
|
||||||
throw BuildError("output '%s' is not allowed to refer to the following paths:%s",
|
|
||||||
worker.store.printStorePath(info.path), badPathsStr);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
checkRefs(checks.allowedReferences, true, false);
|
|
||||||
checkRefs(checks.allowedRequisites, true, true);
|
|
||||||
checkRefs(checks.disallowedReferences, false, false);
|
|
||||||
checkRefs(checks.disallowedRequisites, false, true);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (auto structuredAttrs = parsedDrv->getStructuredAttrs()) {
|
if (auto structuredAttrs = parsedDrv->getStructuredAttrs()) {
|
||||||
@@ -2717,7 +2737,7 @@ try {
|
|||||||
checks.disallowedReferences = get_("disallowedReferences");
|
checks.disallowedReferences = get_("disallowedReferences");
|
||||||
checks.disallowedRequisites = get_("disallowedRequisites");
|
checks.disallowedRequisites = get_("disallowedRequisites");
|
||||||
|
|
||||||
applyChecks(checks);
|
TRY_AWAIT(applyChecks(checks));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -2728,7 +2748,7 @@ try {
|
|||||||
checks.allowedRequisites = parsedDrv->getStringsAttr("allowedRequisites");
|
checks.allowedRequisites = parsedDrv->getStringsAttr("allowedRequisites");
|
||||||
checks.disallowedReferences = parsedDrv->getStringsAttr("disallowedReferences");
|
checks.disallowedReferences = parsedDrv->getStringsAttr("disallowedReferences");
|
||||||
checks.disallowedRequisites = parsedDrv->getStringsAttr("disallowedRequisites");
|
checks.disallowedRequisites = parsedDrv->getStringsAttr("disallowedRequisites");
|
||||||
applyChecks(checks);
|
TRY_AWAIT(applyChecks(checks));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -109,8 +109,7 @@ try {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
try {
|
try {
|
||||||
// FIXME: make async
|
info = TRY_AWAIT(sub->queryPathInfo(subPath ? *subPath : storePath));
|
||||||
info = sub->queryPathInfo(subPath ? *subPath : storePath);
|
|
||||||
break;
|
break;
|
||||||
} catch (InvalidPath &) {
|
} catch (InvalidPath &) {
|
||||||
} catch (SubstituterDisabled &) {
|
} catch (SubstituterDisabled &) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "build/derivation-goal.hh"
|
#include "build/derivation-goal.hh"
|
||||||
#include "lix/libutil/async-collect.hh"
|
#include "lix/libutil/async-collect.hh"
|
||||||
|
#include "lix/libutil/async.hh"
|
||||||
#include "lix/libutil/charptr-cast.hh"
|
#include "lix/libutil/charptr-cast.hh"
|
||||||
#include "lix/libstore/build/worker.hh"
|
#include "lix/libstore/build/worker.hh"
|
||||||
#include "lix/libutil/finally.hh"
|
#include "lix/libutil/finally.hh"
|
||||||
@@ -326,7 +327,7 @@ try {
|
|||||||
auto i = pathContentsGoodCache.find(path);
|
auto i = pathContentsGoodCache.find(path);
|
||||||
if (i != pathContentsGoodCache.end()) co_return i->second;
|
if (i != pathContentsGoodCache.end()) co_return i->second;
|
||||||
printInfo("checking path '%s'...", store.printStorePath(path));
|
printInfo("checking path '%s'...", store.printStorePath(path));
|
||||||
auto info = store.queryPathInfo(path);
|
auto info = TRY_AWAIT(store.queryPathInfo(path));
|
||||||
bool res;
|
bool res;
|
||||||
if (!pathExists(store.printStorePath(path)))
|
if (!pathExists(store.printStorePath(path)))
|
||||||
res = false;
|
res = false;
|
||||||
|
|||||||
@@ -426,14 +426,14 @@ static void performOp(AsyncIoRoot & aio, TunnelLogger * logger, ref<Store> store
|
|||||||
// We could stream this by changing Store
|
// We could stream this by changing Store
|
||||||
std::string contents = source.drain();
|
std::string contents = source.drain();
|
||||||
auto path = aio.blockOn(store->addTextToStore(name, contents, refs, repair));
|
auto path = aio.blockOn(store->addTextToStore(name, contents, refs, repair));
|
||||||
return store->queryPathInfo(path);
|
return aio.blockOn(store->queryPathInfo(path));
|
||||||
},
|
},
|
||||||
[&](const FileIngestionMethod & fim) {
|
[&](const FileIngestionMethod & fim) {
|
||||||
AsyncSourceInputStream stream{source};
|
AsyncSourceInputStream stream{source};
|
||||||
auto path = aio.blockOn(
|
auto path = aio.blockOn(
|
||||||
store->addToStoreFromDump(stream, name, fim, hashType, repair, refs)
|
store->addToStoreFromDump(stream, name, fim, hashType, repair, refs)
|
||||||
);
|
);
|
||||||
return store->queryPathInfo(path);
|
return aio.blockOn(store->queryPathInfo(path));
|
||||||
},
|
},
|
||||||
}, contentAddressMethod.raw);
|
}, contentAddressMethod.raw);
|
||||||
}();
|
}();
|
||||||
@@ -837,7 +837,7 @@ static void performOp(AsyncIoRoot & aio, TunnelLogger * logger, ref<Store> store
|
|||||||
std::shared_ptr<const ValidPathInfo> info;
|
std::shared_ptr<const ValidPathInfo> info;
|
||||||
logger->startWork();
|
logger->startWork();
|
||||||
try {
|
try {
|
||||||
info = store->queryPathInfo(path);
|
info = aio.blockOn(store->queryPathInfo(path));
|
||||||
} catch (InvalidPath &) {
|
} catch (InvalidPath &) {
|
||||||
// The path being invalid isn't fatal here since it will just be
|
// The path being invalid isn't fatal here since it will just be
|
||||||
// sent as not present.
|
// sent as not present.
|
||||||
|
|||||||
@@ -34,9 +34,10 @@ struct DummyStore final : public Store
|
|||||||
return *uriSchemes().begin();
|
return *uriSchemes().begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const ValidPathInfo> queryPathInfoUncached(const StorePath & path) override
|
kj::Promise<Result<std::shared_ptr<const ValidPathInfo>>>
|
||||||
|
queryPathInfoUncached(const StorePath & path) override
|
||||||
{
|
{
|
||||||
return nullptr;
|
return {result::success(nullptr)};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ try {
|
|||||||
|
|
||||||
kj::Promise<Result<void>> Store::exportPath(const StorePath & path, Sink & sink)
|
kj::Promise<Result<void>> Store::exportPath(const StorePath & path, Sink & sink)
|
||||||
try {
|
try {
|
||||||
auto info = queryPathInfo(path);
|
auto info = TRY_AWAIT(queryPathInfo(path));
|
||||||
|
|
||||||
HashSink hashSink(HashType::SHA256);
|
HashSink hashSink(HashType::SHA256);
|
||||||
TeeSink teeSink(sink, hashSink);
|
TeeSink teeSink(sink, hashSink);
|
||||||
|
|||||||
+1
-1
@@ -780,7 +780,7 @@ try {
|
|||||||
{
|
{
|
||||||
if (maybeOutPath &&
|
if (maybeOutPath &&
|
||||||
TRY_AWAIT(isValidPath(*maybeOutPath)) &&
|
TRY_AWAIT(isValidPath(*maybeOutPath)) &&
|
||||||
queryPathInfo(*maybeOutPath)->deriver == *path)
|
TRY_AWAIT(queryPathInfo(*maybeOutPath))->deriver == *path)
|
||||||
enqueue(*maybeOutPath);
|
enqueue(*maybeOutPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,8 +160,9 @@ struct LegacySSHStore final : public Store
|
|||||||
return *uriSchemes().begin() + "://" + host;
|
return *uriSchemes().begin() + "://" + host;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const ValidPathInfo> queryPathInfoUncached(const StorePath & path) override
|
kj::Promise<Result<std::shared_ptr<const ValidPathInfo>>>
|
||||||
{
|
queryPathInfoUncached(const StorePath & path) override
|
||||||
|
try {
|
||||||
auto conn(connections->get());
|
auto conn(connections->get());
|
||||||
|
|
||||||
/* No longer support missing NAR hash */
|
/* No longer support missing NAR hash */
|
||||||
@@ -173,7 +174,7 @@ struct LegacySSHStore final : public Store
|
|||||||
conn->to.flush();
|
conn->to.flush();
|
||||||
|
|
||||||
auto p = readString(conn->from);
|
auto p = readString(conn->from);
|
||||||
if (p.empty()) return nullptr;
|
if (p.empty()) co_return result::success(nullptr);
|
||||||
auto path2 = parseStorePath(p);
|
auto path2 = parseStorePath(p);
|
||||||
assert(path == path2);
|
assert(path == path2);
|
||||||
auto info = std::make_shared<ValidPathInfo>(
|
auto info = std::make_shared<ValidPathInfo>(
|
||||||
@@ -186,7 +187,9 @@ struct LegacySSHStore final : public Store
|
|||||||
auto s = readString(conn->from);
|
auto s = readString(conn->from);
|
||||||
assert(s == "");
|
assert(s == "");
|
||||||
|
|
||||||
return info;
|
co_return info;
|
||||||
|
} catch (...) {
|
||||||
|
co_return result::current_exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
kj::Promise<Result<void>> addToStore(const ValidPathInfo & info, AsyncInputStream & source,
|
kj::Promise<Result<void>> addToStore(const ValidPathInfo & info, AsyncInputStream & source,
|
||||||
|
|||||||
@@ -916,12 +916,22 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<const ValidPathInfo> LocalStore::queryPathInfoUncached(const StorePath & path)
|
kj::Promise<Result<std::shared_ptr<const ValidPathInfo>>>
|
||||||
{
|
LocalStore::queryPathInfoUncached(const StorePath & path)
|
||||||
return retrySQLite([&]() {
|
try {
|
||||||
auto state = dbPool.get();
|
co_return TRY_AWAIT(
|
||||||
return queryPathInfoInternal(*state, path);
|
// NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines)
|
||||||
}, always_progresses);
|
retrySQLite([&]() -> kj::Promise<Result<std::shared_ptr<const ValidPathInfo>>> {
|
||||||
|
try {
|
||||||
|
auto state = dbPool.get();
|
||||||
|
co_return queryPathInfoInternal(*state, path);
|
||||||
|
} catch (...) {
|
||||||
|
co_return result::current_exception();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} catch (...) {
|
||||||
|
co_return result::current_exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1734,7 +1744,9 @@ try {
|
|||||||
for (auto & i : validPaths) {
|
for (auto & i : validPaths) {
|
||||||
std::optional<Error> caught;
|
std::optional<Error> caught;
|
||||||
try {
|
try {
|
||||||
auto info = std::const_pointer_cast<ValidPathInfo>(std::shared_ptr<const ValidPathInfo>(queryPathInfo(i)));
|
auto info = std::const_pointer_cast<ValidPathInfo>(
|
||||||
|
std::shared_ptr<const ValidPathInfo>(TRY_AWAIT(queryPathInfo(i)))
|
||||||
|
);
|
||||||
|
|
||||||
/* Check the content hash (optionally - slow). */
|
/* Check the content hash (optionally - slow). */
|
||||||
printMsg(lvlTalkative, "checking contents of '%s'", printStorePath(i));
|
printMsg(lvlTalkative, "checking contents of '%s'", printStorePath(i));
|
||||||
|
|||||||
@@ -196,7 +196,8 @@ public:
|
|||||||
|
|
||||||
kj::Promise<Result<StorePathSet>> queryAllValidPaths() override;
|
kj::Promise<Result<StorePathSet>> queryAllValidPaths() override;
|
||||||
|
|
||||||
std::shared_ptr<const ValidPathInfo> queryPathInfoUncached(const StorePath & path) override;
|
kj::Promise<Result<std::shared_ptr<const ValidPathInfo>>>
|
||||||
|
queryPathInfoUncached(const StorePath & path) override;
|
||||||
|
|
||||||
kj::Promise<Result<void>>
|
kj::Promise<Result<void>>
|
||||||
queryReferrers(const StorePath & path, StorePathSet & referrers) override;
|
queryReferrers(const StorePath & path, StorePathSet & referrers) override;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ try {
|
|||||||
|
|
||||||
for (auto & path : paths) {
|
for (auto & path : paths) {
|
||||||
auto pathS = srcStore.printStorePath(path);
|
auto pathS = srcStore.printStorePath(path);
|
||||||
auto oldInfo = srcStore.queryPathInfo(path);
|
auto oldInfo = TRY_AWAIT(srcStore.queryPathInfo(path));
|
||||||
std::string oldHashPart(path.hashPart());
|
std::string oldHashPart(path.hashPart());
|
||||||
|
|
||||||
StringSink sink;
|
StringSink sink;
|
||||||
|
|||||||
+17
-8
@@ -9,6 +9,7 @@
|
|||||||
#include "lix/libutil/closure.hh"
|
#include "lix/libutil/closure.hh"
|
||||||
#include "lix/libstore/filetransfer.hh"
|
#include "lix/libstore/filetransfer.hh"
|
||||||
#include "lix/libutil/strings.hh"
|
#include "lix/libutil/strings.hh"
|
||||||
|
#include <kj/async.h>
|
||||||
#include <kj/common.h>
|
#include <kj/common.h>
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
@@ -70,8 +71,13 @@ try {
|
|||||||
|
|
||||||
paths_.merge(TRY_AWAIT(computeClosureAsync<StorePath>(
|
paths_.merge(TRY_AWAIT(computeClosureAsync<StorePath>(
|
||||||
startPaths,
|
startPaths,
|
||||||
[&](const StorePath& path) -> kj::Promise<Result<std::set<StorePath>>> {
|
// NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines)
|
||||||
return queryDeps(path, queryPathInfo(path));
|
[&](const StorePath& path) -> kj::Promise<Result<StorePathSet>> {
|
||||||
|
try {
|
||||||
|
co_return TRY_AWAIT(queryDeps(path, TRY_AWAIT(queryPathInfo(path))));
|
||||||
|
} catch (...) {
|
||||||
|
co_return result::current_exception();
|
||||||
|
}
|
||||||
})));
|
})));
|
||||||
co_return result::success();
|
co_return result::success();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
@@ -369,12 +375,15 @@ try {
|
|||||||
|
|
||||||
kj::Promise<Result<StorePaths>> Store::topoSortPaths(const StorePathSet & paths)
|
kj::Promise<Result<StorePaths>> Store::topoSortPaths(const StorePathSet & paths)
|
||||||
try {
|
try {
|
||||||
co_return topoSort(paths,
|
co_return TRY_AWAIT(topoSortAsync(paths,
|
||||||
{[&](const StorePath & path) {
|
// NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines)
|
||||||
|
{[&](const StorePath & path) -> kj::Promise<Result<StorePathSet>> {
|
||||||
try {
|
try {
|
||||||
return queryPathInfo(path)->references;
|
co_return TRY_AWAIT(queryPathInfo(path))->references;
|
||||||
} catch (InvalidPath &) {
|
} catch (InvalidPath &) {
|
||||||
return StorePathSet();
|
co_return StorePathSet();
|
||||||
|
} catch (...) {
|
||||||
|
co_return result::current_exception();
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
{[&](const StorePath & path, const StorePath & parent) {
|
{[&](const StorePath & path, const StorePath & parent) {
|
||||||
@@ -382,7 +391,7 @@ try {
|
|||||||
"cycle detected in the references of '%s' from '%s'",
|
"cycle detected in the references of '%s' from '%s'",
|
||||||
printStorePath(path),
|
printStorePath(path),
|
||||||
printStorePath(parent));
|
printStorePath(parent));
|
||||||
}});
|
}}));
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
co_return result::current_exception();
|
co_return result::current_exception();
|
||||||
}
|
}
|
||||||
@@ -461,7 +470,7 @@ try {
|
|||||||
for (const auto & [inputDrv, inputNode] : drv.inputDrvs.map)
|
for (const auto & [inputDrv, inputNode] : drv.inputDrvs.map)
|
||||||
TRY_AWAIT(accumRealisations(inputDrv, inputNode));
|
TRY_AWAIT(accumRealisations(inputDrv, inputNode));
|
||||||
|
|
||||||
auto info = store.queryPathInfo(outputPath);
|
auto info = TRY_AWAIT(store.queryPathInfo(outputPath));
|
||||||
|
|
||||||
co_return TRY_AWAIT(drvOutputReferences(
|
co_return TRY_AWAIT(drvOutputReferences(
|
||||||
TRY_AWAIT(Realisation::closure(store, inputRealisations)), info->references
|
TRY_AWAIT(Realisation::closure(store, inputRealisations)), info->references
|
||||||
|
|||||||
@@ -286,8 +286,9 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<const ValidPathInfo> RemoteStore::queryPathInfoUncached(const StorePath & path)
|
kj::Promise<Result<std::shared_ptr<const ValidPathInfo>>>
|
||||||
{
|
RemoteStore::queryPathInfoUncached(const StorePath & path)
|
||||||
|
try {
|
||||||
auto conn(getConnection());
|
auto conn(getConnection());
|
||||||
conn->to << WorkerProto::Op::QueryPathInfo << printStorePath(path);
|
conn->to << WorkerProto::Op::QueryPathInfo << printStorePath(path);
|
||||||
try {
|
try {
|
||||||
@@ -295,16 +296,18 @@ std::shared_ptr<const ValidPathInfo> RemoteStore::queryPathInfoUncached(const St
|
|||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
// Ugly backwards compatibility hack. TODO(fj#325): remove.
|
// Ugly backwards compatibility hack. TODO(fj#325): remove.
|
||||||
if (e.msg().find("is not valid") != std::string::npos)
|
if (e.msg().find("is not valid") != std::string::npos)
|
||||||
return nullptr;
|
co_return result::success(nullptr);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool valid; conn->from >> valid;
|
bool valid; conn->from >> valid;
|
||||||
if (!valid) return nullptr;
|
if (!valid) co_return result::success(nullptr);
|
||||||
|
|
||||||
return std::make_shared<ValidPathInfo>(
|
co_return std::make_shared<ValidPathInfo>(
|
||||||
StorePath{path},
|
StorePath{path},
|
||||||
WorkerProto::Serialise<UnkeyedValidPathInfo>::read(*this, *conn));
|
WorkerProto::Serialise<UnkeyedValidPathInfo>::read(*this, *conn));
|
||||||
|
} catch (...) {
|
||||||
|
co_return result::current_exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -497,7 +500,7 @@ try {
|
|||||||
auto path = parseStorePath(readString(conn->from));
|
auto path = parseStorePath(readString(conn->from));
|
||||||
// Release our connection to prevent a deadlock in queryPathInfo().
|
// Release our connection to prevent a deadlock in queryPathInfo().
|
||||||
conn_.reset();
|
conn_.reset();
|
||||||
co_return queryPathInfo(path);
|
co_return TRY_AWAIT(queryPathInfo(path));
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
co_return result::current_exception();
|
co_return result::current_exception();
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ public:
|
|||||||
|
|
||||||
kj::Promise<Result<StorePathSet>> queryAllValidPaths() override;
|
kj::Promise<Result<StorePathSet>> queryAllValidPaths() override;
|
||||||
|
|
||||||
std::shared_ptr<const ValidPathInfo> queryPathInfoUncached(const StorePath & path) override;
|
kj::Promise<Result<std::shared_ptr<const ValidPathInfo>>>
|
||||||
|
queryPathInfoUncached(const StorePath & path) override;
|
||||||
|
|
||||||
kj::Promise<Result<void>>
|
kj::Promise<Result<void>>
|
||||||
queryReferrers(const StorePath & path, StorePathSet & referrers) override;
|
queryReferrers(const StorePath & path, StorePathSet & referrers) override;
|
||||||
|
|||||||
@@ -315,7 +315,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
|
|||||||
a GET is unlikely to be slower than HEAD. */
|
a GET is unlikely to be slower than HEAD. */
|
||||||
kj::Promise<Result<bool>> isValidPathUncached(const StorePath & storePath) override
|
kj::Promise<Result<bool>> isValidPathUncached(const StorePath & storePath) override
|
||||||
try {
|
try {
|
||||||
queryPathInfo(storePath);
|
TRY_AWAIT(queryPathInfo(storePath));
|
||||||
co_return true;
|
co_return true;
|
||||||
} catch (InvalidPath & e) {
|
} catch (InvalidPath & e) {
|
||||||
co_return false;
|
co_return false;
|
||||||
|
|||||||
+20
-17
@@ -21,6 +21,7 @@
|
|||||||
#include "lix/libstore/worker-protocol.hh"
|
#include "lix/libstore/worker-protocol.hh"
|
||||||
#include "lix/libutil/users.hh"
|
#include "lix/libutil/users.hh"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <kj/async.h>
|
#include <kj/async.h>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
@@ -600,7 +601,7 @@ try {
|
|||||||
|
|
||||||
debug("checking substituter '%s' for path '%s'", sub->getUri(), sub->printStorePath(subPath));
|
debug("checking substituter '%s' for path '%s'", sub->getUri(), sub->printStorePath(subPath));
|
||||||
try {
|
try {
|
||||||
auto info = sub->queryPathInfo(subPath);
|
auto info = TRY_AWAIT(sub->queryPathInfo(subPath));
|
||||||
|
|
||||||
if (sub->config().storeDir != config().storeDir
|
if (sub->config().storeDir != config().storeDir
|
||||||
&& !(info->isContentAddressed(*sub) && info->references.empty()))
|
&& !(info->isContentAddressed(*sub) && info->references.empty()))
|
||||||
@@ -671,7 +672,7 @@ try {
|
|||||||
queryPathInfoUncached(). */
|
queryPathInfoUncached(). */
|
||||||
kj::Promise<Result<bool>> Store::isValidPathUncached(const StorePath & path)
|
kj::Promise<Result<bool>> Store::isValidPathUncached(const StorePath & path)
|
||||||
try {
|
try {
|
||||||
queryPathInfo(path);
|
TRY_AWAIT(queryPathInfo(path));
|
||||||
co_return true;
|
co_return true;
|
||||||
} catch (InvalidPath &) {
|
} catch (InvalidPath &) {
|
||||||
co_return false;
|
co_return false;
|
||||||
@@ -696,8 +697,8 @@ static void ensureGoodStorePath(Store * store, const StorePath & expected, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ref<const ValidPathInfo> Store::queryPathInfo(const StorePath & storePath)
|
kj::Promise<Result<ref<const ValidPathInfo>>> Store::queryPathInfo(const StorePath & storePath)
|
||||||
{
|
try {
|
||||||
auto hashPart = std::string(storePath.hashPart());
|
auto hashPart = std::string(storePath.hashPart());
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -706,7 +707,7 @@ ref<const ValidPathInfo> Store::queryPathInfo(const StorePath & storePath)
|
|||||||
stats.narInfoReadAverted++;
|
stats.narInfoReadAverted++;
|
||||||
if (!res->didExist())
|
if (!res->didExist())
|
||||||
throw InvalidPath("path '%s' does not exist in the store", printStorePath(storePath));
|
throw InvalidPath("path '%s' does not exist in the store", printStorePath(storePath));
|
||||||
return ref<const ValidPathInfo>(res->value);
|
co_return ref<const ValidPathInfo>(res->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -721,11 +722,11 @@ ref<const ValidPathInfo> Store::queryPathInfo(const StorePath & storePath)
|
|||||||
if (res.first == NarInfoDiskCache::oInvalid)
|
if (res.first == NarInfoDiskCache::oInvalid)
|
||||||
throw InvalidPath("path '%s' does not exist in the store", printStorePath(storePath));
|
throw InvalidPath("path '%s' does not exist in the store", printStorePath(storePath));
|
||||||
}
|
}
|
||||||
return ref<const ValidPathInfo>(res.second);
|
co_return ref<const ValidPathInfo>(res.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto info = queryPathInfoUncached(storePath);
|
auto info = TRY_AWAIT(queryPathInfoUncached(storePath));
|
||||||
if (info) {
|
if (info) {
|
||||||
// first, before we cache anything, check that the store gave us valid data.
|
// first, before we cache anything, check that the store gave us valid data.
|
||||||
ensureGoodStorePath(this, storePath, info->path);
|
ensureGoodStorePath(this, storePath, info->path);
|
||||||
@@ -745,7 +746,9 @@ ref<const ValidPathInfo> Store::queryPathInfo(const StorePath & storePath)
|
|||||||
throw InvalidPath("path '%s' does not exist in the store", printStorePath(storePath));
|
throw InvalidPath("path '%s' does not exist in the store", printStorePath(storePath));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ref<const ValidPathInfo>(info);
|
co_return ref<const ValidPathInfo>(info);
|
||||||
|
} catch (...) {
|
||||||
|
co_return result::current_exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
kj::Promise<Result<std::shared_ptr<const Realisation>>> Store::queryRealisation(const DrvOutput & id)
|
kj::Promise<Result<std::shared_ptr<const Realisation>>> Store::queryRealisation(const DrvOutput & id)
|
||||||
@@ -823,14 +826,14 @@ try {
|
|||||||
std::condition_variable wakeup;
|
std::condition_variable wakeup;
|
||||||
ThreadPool pool{"queryValidPaths pool"};
|
ThreadPool pool{"queryValidPaths pool"};
|
||||||
|
|
||||||
auto doQuery = [&](const StorePath & path) {
|
auto doQuery = [&](AsyncIoRoot & aio, const StorePath & path) {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
|
||||||
bool exists = false;
|
bool exists = false;
|
||||||
std::exception_ptr newExc{};
|
std::exception_ptr newExc{};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
queryPathInfo(path);
|
aio.blockOn(queryPathInfo(path));
|
||||||
exists = true;
|
exists = true;
|
||||||
} catch (InvalidPath &) {
|
} catch (InvalidPath &) {
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
@@ -853,7 +856,7 @@ try {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (auto & path : paths)
|
for (auto & path : paths)
|
||||||
pool.enqueue(std::bind(doQuery, path));
|
pool.enqueueWithAio(std::bind(doQuery, std::placeholders::_1, path));
|
||||||
|
|
||||||
TRY_AWAIT(pool.processAsync());
|
TRY_AWAIT(pool.processAsync());
|
||||||
|
|
||||||
@@ -881,7 +884,7 @@ try {
|
|||||||
for (auto & i : paths) {
|
for (auto & i : paths) {
|
||||||
s += printStorePath(i) + "\n";
|
s += printStorePath(i) + "\n";
|
||||||
|
|
||||||
auto info = queryPathInfo(i);
|
auto info = TRY_AWAIT(queryPathInfo(i));
|
||||||
|
|
||||||
if (showHash) {
|
if (showHash) {
|
||||||
s += info->narHash.to_string(Base::Base16, false) + "\n";
|
s += info->narHash.to_string(Base::Base16, false) + "\n";
|
||||||
@@ -952,7 +955,7 @@ try {
|
|||||||
auto& jsonPath = jsonList.emplace_back(json::object());
|
auto& jsonPath = jsonList.emplace_back(json::object());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto info = queryPathInfo(storePath);
|
auto info = TRY_AWAIT(queryPathInfo(storePath));
|
||||||
|
|
||||||
jsonPath["path"] = printStorePath(info->path);
|
jsonPath["path"] = printStorePath(info->path);
|
||||||
jsonPath["valid"] = true;
|
jsonPath["valid"] = true;
|
||||||
@@ -1024,7 +1027,7 @@ try {
|
|||||||
StorePathSet closure;
|
StorePathSet closure;
|
||||||
TRY_AWAIT(computeFSClosure(storePath, closure, false, false));
|
TRY_AWAIT(computeFSClosure(storePath, closure, false, false));
|
||||||
for (auto & p : closure) {
|
for (auto & p : closure) {
|
||||||
auto info = queryPathInfo(p);
|
auto info = TRY_AWAIT(queryPathInfo(p));
|
||||||
totalNarSize += info->narSize;
|
totalNarSize += info->narSize;
|
||||||
auto narInfo = std::dynamic_pointer_cast<const NarInfo>(
|
auto narInfo = std::dynamic_pointer_cast<const NarInfo>(
|
||||||
std::shared_ptr<const ValidPathInfo>(info));
|
std::shared_ptr<const ValidPathInfo>(info));
|
||||||
@@ -1106,7 +1109,7 @@ try {
|
|||||||
{storePathS, srcUri, dstUri});
|
{storePathS, srcUri, dstUri});
|
||||||
PushActivity pact(act.id);
|
PushActivity pact(act.id);
|
||||||
|
|
||||||
auto info = srcStore.queryPathInfo(storePath);
|
auto info = TRY_AWAIT(srcStore.queryPathInfo(storePath));
|
||||||
|
|
||||||
// recompute store path on the chance dstStore does it differently
|
// recompute store path on the chance dstStore does it differently
|
||||||
if (info->ca && info->references.empty()) {
|
if (info->ca && info->references.empty()) {
|
||||||
@@ -1239,7 +1242,7 @@ try {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (auto & missingPath : sortedMissing) {
|
for (auto & missingPath : sortedMissing) {
|
||||||
auto info = srcStore.queryPathInfo(missingPath);
|
auto info = TRY_AWAIT(srcStore.queryPathInfo(missingPath));
|
||||||
|
|
||||||
auto storePathForDst = computeStorePathForDst(*info);
|
auto storePathForDst = computeStorePathForDst(*info);
|
||||||
pathsMap.insert_or_assign(missingPath, storePathForDst);
|
pathsMap.insert_or_assign(missingPath, storePathForDst);
|
||||||
@@ -1411,7 +1414,7 @@ try {
|
|||||||
|
|
||||||
if (!path.isDerivation()) {
|
if (!path.isDerivation()) {
|
||||||
try {
|
try {
|
||||||
auto info = queryPathInfo(path);
|
auto info = TRY_AWAIT(queryPathInfo(path));
|
||||||
co_return info->deriver;
|
co_return info->deriver;
|
||||||
} catch (InvalidPath &) {
|
} catch (InvalidPath &) {
|
||||||
co_return std::nullopt;
|
co_return std::nullopt;
|
||||||
|
|||||||
@@ -385,7 +385,7 @@ public:
|
|||||||
* Query information about a valid path. It is permitted to omit
|
* Query information about a valid path. It is permitted to omit
|
||||||
* the name part of the store path.
|
* the name part of the store path.
|
||||||
*/
|
*/
|
||||||
ref<const ValidPathInfo> queryPathInfo(const StorePath & path);
|
kj::Promise<Result<ref<const ValidPathInfo>>> queryPathInfo(const StorePath & path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query the information about a realisation.
|
* Query the information about a realisation.
|
||||||
@@ -420,7 +420,8 @@ protected:
|
|||||||
* Queries the path info without caching.
|
* Queries the path info without caching.
|
||||||
* Note to implementors: should return `nullptr` when the path is not found.
|
* Note to implementors: should return `nullptr` when the path is not found.
|
||||||
*/
|
*/
|
||||||
virtual std::shared_ptr<const ValidPathInfo> queryPathInfoUncached(const StorePath & path) = 0;
|
virtual kj::Promise<Result<std::shared_ptr<const ValidPathInfo>>>
|
||||||
|
queryPathInfoUncached(const StorePath & path) = 0;
|
||||||
virtual kj::Promise<Result<std::shared_ptr<const Realisation>>>
|
virtual kj::Promise<Result<std::shared_ptr<const Realisation>>>
|
||||||
queryRealisationUncached(const DrvOutput &) = 0;
|
queryRealisationUncached(const DrvOutput &) = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -67,17 +67,22 @@ try {
|
|||||||
auto & beforeVersions = beforeClosure[name];
|
auto & beforeVersions = beforeClosure[name];
|
||||||
auto & afterVersions = afterClosure[name];
|
auto & afterVersions = afterClosure[name];
|
||||||
|
|
||||||
auto totalSize = [&](const std::map<std::string, std::map<StorePath, Info>> & versions)
|
// NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines)
|
||||||
{
|
auto totalSize = [&](const std::map<std::string, std::map<StorePath, Info>> & versions
|
||||||
uint64_t sum = 0;
|
) -> kj::Promise<Result<uint64_t>> {
|
||||||
for (auto & [_, paths] : versions)
|
try {
|
||||||
for (auto & [path, _] : paths)
|
uint64_t sum = 0;
|
||||||
sum += store->queryPathInfo(path)->narSize;
|
for (auto & [_, paths] : versions)
|
||||||
return sum;
|
for (auto & [path, _] : paths)
|
||||||
|
sum += TRY_AWAIT(store->queryPathInfo(path))->narSize;
|
||||||
|
co_return sum;
|
||||||
|
} catch (...) {
|
||||||
|
co_return result::current_exception();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto beforeSize = totalSize(beforeVersions);
|
auto beforeSize = TRY_AWAIT(totalSize(beforeVersions));
|
||||||
auto afterSize = totalSize(afterVersions);
|
auto afterSize = TRY_AWAIT(totalSize(afterVersions));
|
||||||
auto sizeDelta = (int64_t) afterSize - (int64_t) beforeSize;
|
auto sizeDelta = (int64_t) afterSize - (int64_t) beforeSize;
|
||||||
auto showDelta = std::abs(sizeDelta) >= 8 * 1024;
|
auto showDelta = std::abs(sizeDelta) >= 8 * 1024;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1439,7 +1439,7 @@ struct CmdFlakePrefetch : FlakeCommand, MixJSON
|
|||||||
auto originalRef = getFlakeRef();
|
auto originalRef = getFlakeRef();
|
||||||
auto resolvedRef = aio().blockOn(originalRef.resolve(store));
|
auto resolvedRef = aio().blockOn(originalRef.resolve(store));
|
||||||
auto [tree, lockedRef] = aio().blockOn(resolvedRef.fetchTree(store));
|
auto [tree, lockedRef] = aio().blockOn(resolvedRef.fetchTree(store));
|
||||||
auto hash = store->queryPathInfo(tree.storePath)->narHash;
|
auto hash = aio().blockOn(store->queryPathInfo(tree.storePath))->narHash;
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
auto res = nlohmann::json::object();
|
auto res = nlohmann::json::object();
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "lix/libmain/shared.hh"
|
#include "lix/libmain/shared.hh"
|
||||||
#include "lix/libstore/store-api.hh"
|
#include "lix/libstore/store-api.hh"
|
||||||
#include "lix/libmain/common-args.hh"
|
#include "lix/libmain/common-args.hh"
|
||||||
|
#include "lix/libutil/async.hh"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
@@ -100,7 +101,7 @@ struct CmdPathInfo : StorePathsCommand, MixJSON
|
|||||||
else {
|
else {
|
||||||
|
|
||||||
for (auto & storePath : storePaths) {
|
for (auto & storePath : storePaths) {
|
||||||
auto info = store->queryPathInfo(storePath);
|
auto info = aio().blockOn(store->queryPathInfo(storePath));
|
||||||
auto storePathS = store->printStorePath(info->path);
|
auto storePathS = store->printStorePath(info->path);
|
||||||
|
|
||||||
std::cout << storePathS;
|
std::cout << storePathS;
|
||||||
|
|||||||
+3
-3
@@ -50,13 +50,13 @@ struct CmdCopySigs : StorePathsCommand
|
|||||||
|
|
||||||
auto storePath = store->parseStorePath(storePathS);
|
auto storePath = store->parseStorePath(storePathS);
|
||||||
|
|
||||||
auto info = store->queryPathInfo(storePath);
|
auto info = aio.blockOn(store->queryPathInfo(storePath));
|
||||||
|
|
||||||
StringSet newSigs;
|
StringSet newSigs;
|
||||||
|
|
||||||
for (auto & store2 : substituters) {
|
for (auto & store2 : substituters) {
|
||||||
try {
|
try {
|
||||||
auto info2 = store2->queryPathInfo(info->path);
|
auto info2 = aio.blockOn(store2->queryPathInfo(info->path));
|
||||||
|
|
||||||
/* Don't import signatures that don't match this
|
/* Don't import signatures that don't match this
|
||||||
binary. */
|
binary. */
|
||||||
@@ -130,7 +130,7 @@ struct CmdSign : StorePathsCommand
|
|||||||
|
|
||||||
auto storePath = store->parseStorePath(storePathS);
|
auto storePath = store->parseStorePath(storePathS);
|
||||||
|
|
||||||
auto info = store->queryPathInfo(storePath);
|
auto info = aio.blockOn(store->queryPathInfo(storePath));
|
||||||
|
|
||||||
auto info2(*info);
|
auto info2(*info);
|
||||||
info2.sigs.clear();
|
info2.sigs.clear();
|
||||||
|
|||||||
+2
-2
@@ -90,7 +90,7 @@ struct CmdVerify : StorePathsCommand
|
|||||||
MaintainCount<std::atomic<size_t>> mcActive(active);
|
MaintainCount<std::atomic<size_t>> mcActive(active);
|
||||||
update();
|
update();
|
||||||
|
|
||||||
auto info = store->queryPathInfo(storePath);
|
auto info = aio.blockOn(store->queryPathInfo(storePath));
|
||||||
|
|
||||||
// Note: info->path can be different from storePath
|
// Note: info->path can be different from storePath
|
||||||
// for binary cache stores when using --all (since we
|
// for binary cache stores when using --all (since we
|
||||||
@@ -143,7 +143,7 @@ struct CmdVerify : StorePathsCommand
|
|||||||
for (auto & store2 : substituters) {
|
for (auto & store2 : substituters) {
|
||||||
if (validSigs >= actualSigsNeeded) break;
|
if (validSigs >= actualSigsNeeded) break;
|
||||||
try {
|
try {
|
||||||
auto info2 = store2->queryPathInfo(info->path);
|
auto info2 = aio.blockOn(store2->queryPathInfo(info->path));
|
||||||
if (info2->isContentAddressed(*store)) validSigs = ValidPathInfo::maxSigs;
|
if (info2->isContentAddressed(*store)) validSigs = ValidPathInfo::maxSigs;
|
||||||
doSigs(info2->sigs);
|
doSigs(info2->sigs);
|
||||||
} catch (InvalidPath &) {
|
} catch (InvalidPath &) {
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ struct CmdWhyDepends : SourceExprCommand, MixOperateOnOptions
|
|||||||
for (auto & path : closure)
|
for (auto & path : closure)
|
||||||
graph.emplace(path, Node {
|
graph.emplace(path, Node {
|
||||||
.path = path,
|
.path = path,
|
||||||
.refs = store->queryPathInfo(path)->references,
|
.refs = aio().blockOn(store->queryPathInfo(path))->references,
|
||||||
.dist = path == dependencyPath ? 0 : inf
|
.dist = path == dependencyPath ? 0 : inf
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ int isValidPath(char * path)
|
|||||||
SV * queryReferences(char * path)
|
SV * queryReferences(char * path)
|
||||||
PPCODE:
|
PPCODE:
|
||||||
try {
|
try {
|
||||||
for (auto & i : store()->queryPathInfo(store()->parseStorePath(path))->references)
|
for (auto & i : aio().blockOn(store()->queryPathInfo(store()->parseStorePath(path)))->references)
|
||||||
XPUSHs(sv_2mortal(newSVpv(store()->printStorePath(i).c_str(), 0)));
|
XPUSHs(sv_2mortal(newSVpv(store()->printStorePath(i).c_str(), 0)));
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
croak("%s", e.what());
|
croak("%s", e.what());
|
||||||
@@ -89,7 +89,7 @@ SV * queryReferences(char * path)
|
|||||||
SV * queryPathHash(char * path)
|
SV * queryPathHash(char * path)
|
||||||
PPCODE:
|
PPCODE:
|
||||||
try {
|
try {
|
||||||
auto s = store()->queryPathInfo(store()->parseStorePath(path))->narHash.to_string(Base::Base32, true);
|
auto s = aio().blockOn(store()->queryPathInfo(store()->parseStorePath(path)))->narHash.to_string(Base::Base32, true);
|
||||||
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
|
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
croak("%s", e.what());
|
croak("%s", e.what());
|
||||||
@@ -99,7 +99,7 @@ SV * queryPathHash(char * path)
|
|||||||
SV * queryDeriver(char * path)
|
SV * queryDeriver(char * path)
|
||||||
PPCODE:
|
PPCODE:
|
||||||
try {
|
try {
|
||||||
auto info = store()->queryPathInfo(store()->parseStorePath(path));
|
auto info = aio().blockOn(store()->queryPathInfo(store()->parseStorePath(path)));
|
||||||
if (!info->deriver) XSRETURN_UNDEF;
|
if (!info->deriver) XSRETURN_UNDEF;
|
||||||
XPUSHs(sv_2mortal(newSVpv(store()->printStorePath(*info->deriver).c_str(), 0)));
|
XPUSHs(sv_2mortal(newSVpv(store()->printStorePath(*info->deriver).c_str(), 0)));
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
@@ -110,7 +110,7 @@ SV * queryDeriver(char * path)
|
|||||||
SV * queryPathInfo(char * path, int base32)
|
SV * queryPathInfo(char * path, int base32)
|
||||||
PPCODE:
|
PPCODE:
|
||||||
try {
|
try {
|
||||||
auto info = store()->queryPathInfo(store()->parseStorePath(path));
|
auto info = aio().blockOn(store()->queryPathInfo(store()->parseStorePath(path)));
|
||||||
if (!info->deriver)
|
if (!info->deriver)
|
||||||
XPUSHs(&PL_sv_undef);
|
XPUSHs(&PL_sv_undef);
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user