libutil: remove sinkToSource eof callback
this is only used in one place, and only to set a nicer error message on EndOfFile. the only caller that actually *catches* this exception should provide an error message in that catch block rather than forcing support for setting error message so deep into the stack. copyStorePath is never called outside of PathSubstitutionGoal anyway, which catches everything. Change-Id: Ifbae8706d781c388737706faf4c8a8b7917ca278
This commit is contained in:
parent
f80d95e36d
commit
39a1e248c9
6 changed files with 48 additions and 17 deletions
|
@ -217,6 +217,7 @@ void PathSubstitutionGoal::tryToRun()
|
||||||
promise = std::promise<void>();
|
promise = std::promise<void>();
|
||||||
|
|
||||||
thr = std::thread([this]() {
|
thr = std::thread([this]() {
|
||||||
|
auto & fetchPath = subPath ? *subPath : storePath;
|
||||||
try {
|
try {
|
||||||
ReceiveInterrupts receiveInterrupts;
|
ReceiveInterrupts receiveInterrupts;
|
||||||
|
|
||||||
|
@ -226,10 +227,17 @@ void PathSubstitutionGoal::tryToRun()
|
||||||
Activity act(*logger, actSubstitute, Logger::Fields{worker.store.printStorePath(storePath), sub->getUri()});
|
Activity act(*logger, actSubstitute, Logger::Fields{worker.store.printStorePath(storePath), sub->getUri()});
|
||||||
PushActivity pact(act.id);
|
PushActivity pact(act.id);
|
||||||
|
|
||||||
copyStorePath(*sub, worker.store,
|
copyStorePath(
|
||||||
subPath ? *subPath : storePath, repair, sub->isTrusted ? NoCheckSigs : CheckSigs);
|
*sub, worker.store, fetchPath, repair, sub->isTrusted ? NoCheckSigs : CheckSigs
|
||||||
|
);
|
||||||
|
|
||||||
promise.set_value();
|
promise.set_value();
|
||||||
|
} catch (const EndOfFile &) {
|
||||||
|
promise.set_exception(std::make_exception_ptr(EndOfFile(
|
||||||
|
"NAR for '%s' fetched from '%s' is incomplete",
|
||||||
|
sub->printStorePath(fetchPath),
|
||||||
|
sub->getUri()
|
||||||
|
)));
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
promise.set_exception(std::current_exception());
|
promise.set_exception(std::current_exception());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1072,8 +1072,6 @@ void copyStorePath(
|
||||||
});
|
});
|
||||||
TeeSink tee { sink, progressSink };
|
TeeSink tee { sink, progressSink };
|
||||||
srcStore.narFromPath(storePath, tee);
|
srcStore.narFromPath(storePath, tee);
|
||||||
}, [&]() {
|
|
||||||
throw EndOfFile("NAR for '%s' fetched from '%s' is incomplete", srcStore.printStorePath(storePath), srcStore.getUri());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
dstStore.addToStore(*info, *source, repair, checkSigs);
|
dstStore.addToStore(*info, *source, repair, checkSigs);
|
||||||
|
|
|
@ -266,20 +266,17 @@ std::unique_ptr<FinishSink> sourceToSink(std::function<void(Source &)> fun)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<Source> sinkToSource(
|
std::unique_ptr<Source> sinkToSource(std::function<void(Sink &)> fun)
|
||||||
std::function<void(Sink &)> fun,
|
|
||||||
std::function<void()> eof)
|
|
||||||
{
|
{
|
||||||
struct SinkToSource : Source
|
struct SinkToSource : Source
|
||||||
{
|
{
|
||||||
typedef boost::coroutines2::coroutine<std::string> coro_t;
|
typedef boost::coroutines2::coroutine<std::string> coro_t;
|
||||||
|
|
||||||
std::function<void(Sink &)> fun;
|
std::function<void(Sink &)> fun;
|
||||||
std::function<void()> eof;
|
|
||||||
std::optional<coro_t::pull_type> coro;
|
std::optional<coro_t::pull_type> coro;
|
||||||
|
|
||||||
SinkToSource(std::function<void(Sink &)> fun, std::function<void()> eof)
|
SinkToSource(std::function<void(Sink &)> fun)
|
||||||
: fun(fun), eof(eof)
|
: fun(fun)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,7 +295,9 @@ std::unique_ptr<Source> sinkToSource(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!*coro) { eof(); abort(); }
|
if (!*coro) {
|
||||||
|
throw EndOfFile("coroutine has finished");
|
||||||
|
}
|
||||||
|
|
||||||
if (pos == cur.size()) {
|
if (pos == cur.size()) {
|
||||||
if (!cur.empty()) {
|
if (!cur.empty()) {
|
||||||
|
@ -317,7 +316,7 @@ std::unique_ptr<Source> sinkToSource(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return std::make_unique<SinkToSource>(fun, eof);
|
return std::make_unique<SinkToSource>(fun);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -338,11 +338,7 @@ std::unique_ptr<FinishSink> sourceToSink(std::function<void(Source &)> fun);
|
||||||
* Convert a function that feeds data into a Sink into a Source. The
|
* Convert a function that feeds data into a Sink into a Source. The
|
||||||
* Source executes the function as a coroutine.
|
* Source executes the function as a coroutine.
|
||||||
*/
|
*/
|
||||||
std::unique_ptr<Source> sinkToSource(
|
std::unique_ptr<Source> sinkToSource(std::function<void(Sink &)> fun);
|
||||||
std::function<void(Sink &)> fun,
|
|
||||||
std::function<void()> eof = []() {
|
|
||||||
throw EndOfFile("coroutine has finished");
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
void writePadding(size_t len, Sink & sink);
|
void writePadding(size_t len, Sink & sink);
|
||||||
|
|
|
@ -182,6 +182,7 @@ functional_tests_scripts = [
|
||||||
'debugger.sh',
|
'debugger.sh',
|
||||||
'test-libstoreconsumer.sh',
|
'test-libstoreconsumer.sh',
|
||||||
'extra-sandbox-profile.sh',
|
'extra-sandbox-profile.sh',
|
||||||
|
'substitute-truncated-nar.sh',
|
||||||
]
|
]
|
||||||
|
|
||||||
# Plugin tests require shared libraries support.
|
# Plugin tests require shared libraries support.
|
||||||
|
|
29
tests/functional/substitute-truncated-nar.sh
Normal file
29
tests/functional/substitute-truncated-nar.sh
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
source common.sh
|
||||||
|
|
||||||
|
BINARY_CACHE=file://$cacheDir
|
||||||
|
|
||||||
|
build() {
|
||||||
|
nix-build --no-out-link "$@" --expr 'derivation {
|
||||||
|
name = "text";
|
||||||
|
system = builtins.currentSystem;
|
||||||
|
builder = "/bin/sh";
|
||||||
|
args = [ "-c" "echo some text to make the nar less empty > $out" ];
|
||||||
|
}'
|
||||||
|
}
|
||||||
|
|
||||||
|
path=$(build)
|
||||||
|
nix copy --to "$BINARY_CACHE" "$path"
|
||||||
|
nix-collect-garbage >/dev/null 2>&1
|
||||||
|
|
||||||
|
nar=0bylmx35yjy2b1b4k7gjsl7i4vc03cpmryb41grfb1mp40n3hifl.nar.xz
|
||||||
|
|
||||||
|
[ -e $cacheDir/nar/$nar ] || fail "long nar missing?"
|
||||||
|
|
||||||
|
xzcat $cacheDir/nar/$nar > $TEST_HOME/tmp
|
||||||
|
truncate -s $(( $(stat -c %s $TEST_HOME/tmp) - 10 )) $TEST_HOME/tmp
|
||||||
|
xz < $TEST_HOME/tmp > $cacheDir/nar/$nar
|
||||||
|
|
||||||
|
# Copying back '$path' from the binary cache. This should fail as it is truncated
|
||||||
|
if build --option substituters "$BINARY_CACHE" --option require-sigs false -j0; then
|
||||||
|
fail "Importing a truncated nar should fail"
|
||||||
|
fi
|
Loading…
Reference in a new issue