1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-02-01 01:18:22 +01:00

Serve Git reads over SSH

Summary: Like D7423, but for SSH.

Test Plan: Ran `git clone ssh://...`, got a clone.

Reviewers: btrahan

Reviewed By: btrahan

CC: hach-que, aran

Maniphest Tasks: T2230

Differential Revision: https://secure.phabricator.com/D7424
This commit is contained in:
epriestley 2013-10-26 12:18:54 -07:00
parent 7d9dfb561d
commit 9a2e45ef12
3 changed files with 65 additions and 5 deletions

View file

@ -23,4 +23,12 @@ final class DiffusionSSHGitUploadPackWorkflow
return head($args->getArg('dir'));
}
protected function executeRepositoryOperations(
PhabricatorRepository $repository) {
$future = new ExecFuture('git-upload-pack %s', $repository->getLocalPath());
return $this->passthruIO($future);
}
}

View file

@ -10,6 +10,9 @@ abstract class DiffusionSSHWorkflow extends PhabricatorSSHWorkflow {
abstract protected function isReadOnly();
abstract protected function getRequestPath();
abstract protected function executeRepositoryOperations(
PhabricatorRepository $repository);
protected function writeError($message) {
$this->getErrorChannel()->write($message);
return $this;
@ -20,15 +23,11 @@ abstract class DiffusionSSHWorkflow extends PhabricatorSSHWorkflow {
try {
$repository = $this->loadRepository();
throw new Exception("TODO: Implement serve over SSH.");
return $this->executeRepositoryOperations($repository);
} catch (Exception $ex) {
$this->writeError(get_class($ex).': '.$ex->getMessage());
return 1;
}
return 0;
}
private function loadRepository() {

View file

@ -37,6 +37,50 @@ abstract class PhabricatorSSHWorkflow extends PhutilArgumentWorkflow {
return $this->iochannel;
}
public function passthruIO(ExecFuture $future) {
$exec_channel = new PhutilExecChannel($future);
$exec_channel->setStderrHandler(array($this, 'writeErrorIOCallback'));
$io_channel = $this->getIOChannel();
$error_channel = $this->getErrorChannel();
$channels = array($exec_channel, $io_channel, $error_channel);
while (true) {
PhutilChannel::waitForAny($channels);
$io_channel->update();
$exec_channel->update();
$error_channel->update();
$done = !$exec_channel->isOpen();
$data = $io_channel->read();
if (strlen($data)) {
$exec_channel->write($data);
}
$data = $exec_channel->read();
if (strlen($data)) {
$io_channel->write($data);
}
// If we have nothing left on stdin, close stdin on the subprocess.
if (!$io_channel->isOpenForReading()) {
// TODO: This should probably be part of PhutilExecChannel?
$future->write('');
}
if ($done) {
break;
}
}
list($err) = $future->resolve();
return $err;
}
public function readAllInput() {
$channel = $this->getIOChannel();
while ($channel->update()) {
@ -53,4 +97,13 @@ abstract class PhabricatorSSHWorkflow extends PhutilArgumentWorkflow {
return $this;
}
public function writeErrorIO($data) {
$this->getErrorChannel()->write($data);
return $this;
}
public function writeErrorIOCallback(PhutilChannel $channel, $data) {
$this->writeErrorIO($data);
}
}