diff --git a/src/applications/drydock/interface/command/DrydockSSHCommandInterface.php b/src/applications/drydock/interface/command/DrydockSSHCommandInterface.php index ab0dd94e3e..4e015afab0 100644 --- a/src/applications/drydock/interface/command/DrydockSSHCommandInterface.php +++ b/src/applications/drydock/interface/command/DrydockSSHCommandInterface.php @@ -2,7 +2,32 @@ final class DrydockSSHCommandInterface extends DrydockCommandInterface { + private $passphraseSSHKey; + + private function openCredentialsIfNotOpen() { + if ($this->passphraseSSHKey !== null) { + return; + } + + $credential = id(new PassphraseCredentialQuery()) + ->setViewer(PhabricatorUser::getOmnipotentUser()) + ->withIDs(array($this->getConfig('credential'))) + ->needSecrets(true) + ->executeOne(); + + if ($credential->getProvidesType() !== + PassphraseCredentialTypeSSHPrivateKey::PROVIDES_TYPE) { + throw new Exception("Only private key credentials are supported."); + } + + $this->passphraseSSHKey = PassphraseSSHKey::loadFromPHID( + $credential->getPHID(), + PhabricatorUser::getOmnipotentUser()); + } + public function getExecFuture($command) { + $this->openCredentialsIfNotOpen(); + $argv = func_get_args(); // This assumes there's a UNIX shell living at the other @@ -21,32 +46,12 @@ final class DrydockSSHCommandInterface extends DrydockCommandInterface { // NOTE: The "-t -t" is for psuedo-tty allocation so we can "sudo" on some // systems, but maybe more trouble than it's worth? - - $credential = id(new PassphraseCredentialQuery()) - ->setViewer(PhabricatorUser::getOmnipotentUser()) - ->withIDs(array($this->getConfig('credential'))) - ->needSecrets(true) - ->executeOne(); - - // FIXME: We can't use text-based SSH files here because the TempFile goes - // out of scope after this function ends and thus the file gets removed - // before it can be used. - if ($credential->getCredentialType() !== - PassphraseCredentialTypeSSHPrivateKeyFile::CREDENTIAL_TYPE) { - throw new Exception("Only private key file credentials are supported."); - } - - $ssh_key = PassphraseSSHKey::loadFromPHID( - $credential->getPHID(), - PhabricatorUser::getOmnipotentUser()); - return new ExecFuture( - 'ssh -t -t -o StrictHostKeyChecking=no -p %s -i %s %s@%s -- %s', + 'ssh -t -t -o StrictHostKeyChecking=no -p %s -i %P %P@%s -- %s', $this->getConfig('port'), - $ssh_key->getKeyfileEnvelope()->openEnvelope(), - $credential->getUsername(), + $this->passphraseSSHKey->getKeyfileEnvelope(), + $this->passphraseSSHKey->getUsernameEnvelope(), $this->getConfig('host'), $full_command); } - }