SSHMaster: pause logger to show password prompt

Pause logger before starting SSH connections, and resume it after the
connection is established, so that SSH password prompts are not erased
by the logger's updates.
This commit is contained in:
Alexander Bantyev 2023-03-09 18:16:29 +04:00
parent 85df7e7ea2
commit 5291a82cd9
No known key found for this signature in database
GPG key ID: 48ABA304F3A30FE9

View file

@ -1,4 +1,5 @@
#include "ssh.hh"
#include "finally.hh"
namespace nix {
@ -35,6 +36,9 @@ void SSHMaster::addCommonSSHOpts(Strings & args)
}
if (compress)
args.push_back("-C");
args.push_back("-oPermitLocalCommand=yes");
args.push_back("-oLocalCommand=echo started");
}
std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(const std::string & command)
@ -49,6 +53,11 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(const std::string
ProcessOptions options;
options.dieWithParent = false;
if (!fakeSSH && !useMaster) {
logger->pause();
}
Finally cleanup = [&]() { logger->resume(); };
conn->sshPid = startProcess([&]() {
restoreProcessContext();
@ -86,6 +95,18 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(const std::string
in.readSide = -1;
out.writeSide = -1;
// Wait for the SSH connection to be established,
// So that we don't overwrite the password prompt with our progress bar.
if (!fakeSSH && !useMaster) {
std::string reply;
try {
reply = readLine(out.readSide.get());
} catch (EndOfFile & e) { }
if (reply != "started")
throw Error("failed to start SSH connection to '%s'", host);
}
conn->out = std::move(out.readSide);
conn->in = std::move(in.writeSide);
@ -109,6 +130,9 @@ Path SSHMaster::startMaster()
ProcessOptions options;
options.dieWithParent = false;
logger->pause();
Finally cleanup = [&]() { logger->resume(); };
state->sshMaster = startProcess([&]() {
restoreProcessContext();
@ -117,11 +141,7 @@ Path SSHMaster::startMaster()
if (dup2(out.writeSide.get(), STDOUT_FILENO) == -1)
throw SysError("duping over stdout");
Strings args =
{ "ssh", host.c_str(), "-M", "-N", "-S", state->socketPath
, "-o", "LocalCommand=echo started"
, "-o", "PermitLocalCommand=yes"
};
Strings args = { "ssh", host.c_str(), "-M", "-N", "-S", state->socketPath };
if (verbosity >= lvlChatty)
args.push_back("-v");
addCommonSSHOpts(args);