Merge pull request #8349 from tweag/fix-control-master

Fix ControlMaster behaviour
This commit is contained in:
John Ericson 2023-05-17 12:17:09 -04:00 committed by GitHub
commit 32dc77ba5d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 7 deletions

View file

@ -41,6 +41,11 @@ void SSHMaster::addCommonSSHOpts(Strings & args)
args.push_back("-oLocalCommand=echo started"); args.push_back("-oLocalCommand=echo started");
} }
bool SSHMaster::isMasterRunning() {
auto res = runProgram(RunOptions {.program = "ssh", .args = {"-O", "check", host}, .mergeStderrToStdout = true});
return res.first == 0;
}
std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(const std::string & command) std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(const std::string & command)
{ {
Path socketPath = startMaster(); Path socketPath = startMaster();
@ -97,7 +102,7 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(const std::string
// Wait for the SSH connection to be established, // Wait for the SSH connection to be established,
// So that we don't overwrite the password prompt with our progress bar. // So that we don't overwrite the password prompt with our progress bar.
if (!fakeSSH && !useMaster) { if (!fakeSSH && !useMaster && !isMasterRunning()) {
std::string reply; std::string reply;
try { try {
reply = readLine(out.readSide.get()); reply = readLine(out.readSide.get());
@ -133,6 +138,8 @@ Path SSHMaster::startMaster()
logger->pause(); logger->pause();
Finally cleanup = [&]() { logger->resume(); }; Finally cleanup = [&]() { logger->resume(); };
bool wasMasterRunning = isMasterRunning();
state->sshMaster = startProcess([&]() { state->sshMaster = startProcess([&]() {
restoreProcessContext(); restoreProcessContext();
@ -152,13 +159,15 @@ Path SSHMaster::startMaster()
out.writeSide = -1; out.writeSide = -1;
std::string reply; if (!wasMasterRunning) {
try { std::string reply;
reply = readLine(out.readSide.get()); try {
} catch (EndOfFile & e) { } reply = readLine(out.readSide.get());
} catch (EndOfFile & e) { }
if (reply != "started") if (reply != "started")
throw Error("failed to start SSH master connection to '%s'", host); throw Error("failed to start SSH master connection to '%s'", host);
}
return state->socketPath; return state->socketPath;
} }

View file

@ -28,6 +28,7 @@ private:
Sync<State> state_; Sync<State> state_;
void addCommonSSHOpts(Strings & args); void addCommonSSHOpts(Strings & args);
bool isMasterRunning();
public: public:

View file

@ -23,6 +23,12 @@ in {
nix.settings.substituters = lib.mkForce [ ]; nix.settings.substituters = lib.mkForce [ ];
nix.settings.experimental-features = [ "nix-command" ]; nix.settings.experimental-features = [ "nix-command" ];
services.getty.autologinUser = "root"; services.getty.autologinUser = "root";
programs.ssh.extraConfig = ''
Host *
ControlMaster auto
ControlPath ~/.ssh/master-%h:%r@%n:%p
ControlPersist 15m
'';
}; };
server = server =
@ -62,6 +68,10 @@ in {
client.wait_for_text("done") client.wait_for_text("done")
server.succeed("nix-store --check-validity ${pkgA}") server.succeed("nix-store --check-validity ${pkgA}")
# Check that ControlMaster is working
client.send_chars("nix copy --to ssh://server ${pkgA} >&2; echo done\n")
client.wait_for_text("done")
client.copy_from_host("key", "/root/.ssh/id_ed25519") client.copy_from_host("key", "/root/.ssh/id_ed25519")
client.succeed("chmod 600 /root/.ssh/id_ed25519") client.succeed("chmod 600 /root/.ssh/id_ed25519")