nix/daemon: wrap kj stdio forwarding errors nicely
not doing this has lix crash if stdio forwarding fails for odd reasons, such as ssh failing to set up a connection due to transient dns errors. cf #1148 Change-Id: I543b7444236e69d3c13b47fb6c6eb37c65b96763
This commit is contained in:
+13
-4
@@ -34,7 +34,9 @@
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#include <exception>
|
||||
#include <kj/async.h>
|
||||
#include <kj/exception.h>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
@@ -536,13 +538,20 @@ static void forwardStdioConnection(AsyncIoRoot & aio, RemoteStore & store)
|
||||
|
||||
aio.blockOn(connSocket->pumpTo(*asyncStdout)
|
||||
.then([](auto) -> Result<void> {
|
||||
return {
|
||||
std::make_exception_ptr(EndOfFile("unexpected EOF from daemon socket"))
|
||||
};
|
||||
return {std::make_exception_ptr(EndOfFile("unexpected EOF from daemon socket"))};
|
||||
})
|
||||
.exclusiveJoin(asyncStdin->pumpTo(*connSocket).then([](auto) -> Result<void> {
|
||||
return result::success();
|
||||
})));
|
||||
}))
|
||||
.catch_([](kj::Exception && e) -> Result<void> {
|
||||
if (e.getType() == kj::Exception::Type::DISCONNECTED) {
|
||||
return std::make_exception_ptr(Error("peer disconnected unexpectedly"));
|
||||
} else {
|
||||
return std::make_exception_ptr(
|
||||
Error("forwarding daemon connection: %s", e.getDescription().cStr())
|
||||
);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
from pathlib import Path
|
||||
from testlib.fixtures.nix import Nix
|
||||
from testlib.fixtures.file_helper import with_files
|
||||
from testlib.utils import get_global_asset_pack
|
||||
|
||||
|
||||
@with_files(get_global_asset_pack("simple-drv"))
|
||||
def test_stdio_forward_failure(nix: Nix, files: Path):
|
||||
result = (
|
||||
nix.nix_build(
|
||||
[
|
||||
f"{files}/simple.nix",
|
||||
"--builders",
|
||||
# build-remote handles the first ssh-ng in-process, but we want to test how nix-daemon
|
||||
# behaves in error cases. we need to explicitly set remote-program for the main remote
|
||||
# connection since we may choose the wrong binary otherwise. the inner ssh-ng also has
|
||||
# a remote-program set to cause predictable failures (rather than using ssh impurely).
|
||||
f"ssh-ng://localhost?remote-program={nix.env.dirs.nix_bin_dir}/nix-daemon&remote-store=ssh-ng://localhost?remote-program=false",
|
||||
"-j0",
|
||||
]
|
||||
)
|
||||
.run()
|
||||
.expect(1)
|
||||
)
|
||||
assert "stream ended unexpectedly" in result.stderr_plain
|
||||
assert "Lix crashed" not in result.stderr_plain
|
||||
Reference in New Issue
Block a user