Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14093767
D7421.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
9 KB
Referenced Files
None
Subscribers
None
D7421.diff
View Options
Index: scripts/ssh/ssh-exec.php
===================================================================
--- scripts/ssh/ssh-exec.php
+++ scripts/ssh/ssh-exec.php
@@ -61,6 +61,8 @@
$workflows = array(
new ConduitSSHWorkflow(),
+
+ new DiffusionSSHGitUploadPackWorkflow(),
);
$workflow_names = mpull($workflows, 'getName', 'getName');
@@ -81,16 +83,24 @@
throw new Exception("Unable to open stdout.");
}
+ $sock_stderr = fopen('php://stderr', 'w');
+ if (!$sock_stderr) {
+ throw new Exception("Unable to open stderr.");
+ }
+
$socket_channel = new PhutilSocketChannel(
$sock_stdin,
$sock_stdout);
+ $error_channel = new PhutilSocketChannel(null, $sock_stderr);
$metrics_channel = new PhutilMetricsChannel($socket_channel);
$workflow->setIOChannel($metrics_channel);
+ $workflow->setErrorChannel($error_channel);
$err = $workflow->execute($original_args);
$metrics_channel->flush();
+ $error_channel->flush();
} catch (Exception $ex) {
- echo "phabricator-ssh-exec: ".$ex->getMessage()."\n";
+ fwrite(STDERR, "phabricator-ssh-exec: ".$ex->getMessage()."\n");
exit(1);
}
Index: src/__phutil_library_map__.php
===================================================================
--- src/__phutil_library_map__.php
+++ src/__phutil_library_map__.php
@@ -526,6 +526,9 @@
'DiffusionRepositoryPath' => 'applications/diffusion/data/DiffusionRepositoryPath.php',
'DiffusionRepositoryTag' => 'applications/diffusion/data/DiffusionRepositoryTag.php',
'DiffusionRequest' => 'applications/diffusion/request/DiffusionRequest.php',
+ 'DiffusionSSHGitUploadPackWorkflow' => 'applications/diffusion/ssh/DiffusionSSHGitUploadPackWorkflow.php',
+ 'DiffusionSSHGitWorkflow' => 'applications/diffusion/ssh/DiffusionSSHGitWorkflow.php',
+ 'DiffusionSSHWorkflow' => 'applications/diffusion/ssh/DiffusionSSHWorkflow.php',
'DiffusionSetupException' => 'applications/diffusion/exception/DiffusionSetupException.php',
'DiffusionStableCommitNameQuery' => 'applications/diffusion/query/stablecommitname/DiffusionStableCommitNameQuery.php',
'DiffusionSvnCommitParentsQuery' => 'applications/diffusion/query/parents/DiffusionSvnCommitParentsQuery.php',
@@ -2711,6 +2714,9 @@
0 => 'DiffusionController',
1 => 'PhabricatorApplicationSearchResultsControllerInterface',
),
+ 'DiffusionSSHGitUploadPackWorkflow' => 'DiffusionSSHGitWorkflow',
+ 'DiffusionSSHGitWorkflow' => 'DiffusionSSHWorkflow',
+ 'DiffusionSSHWorkflow' => 'PhabricatorSSHWorkflow',
'DiffusionSetupException' => 'AphrontUsageException',
'DiffusionStableCommitNameQuery' => 'DiffusionQuery',
'DiffusionSvnCommitParentsQuery' => 'DiffusionCommitParentsQuery',
Index: src/applications/diffusion/controller/DiffusionRepositoryEditHostingController.php
===================================================================
--- src/applications/diffusion/controller/DiffusionRepositoryEditHostingController.php
+++ src/applications/diffusion/controller/DiffusionRepositoryEditHostingController.php
@@ -134,7 +134,7 @@
if ($request->isFormPost()) {
$v_http_mode = $request->getStr('http');
- $v_ssh_mode = PhabricatorRepository::SERVE_OFF;
+ $v_ssh_mode = $request->getStr('ssh');
$xactions = array();
$template = id(new PhabricatorRepositoryTransaction());
@@ -176,6 +176,29 @@
'writes.');
}
+ $ssh_control =
+ id(new AphrontFormRadioButtonControl())
+ ->setName('ssh')
+ ->setLabel(pht('SSH'))
+ ->setValue($v_ssh_mode)
+ ->addButton(
+ PhabricatorRepository::SERVE_OFF,
+ PhabricatorRepository::getProtocolAvailabilityName(
+ PhabricatorRepository::SERVE_OFF),
+ pht('Phabricator will not serve this repository.'))
+ ->addButton(
+ PhabricatorRepository::SERVE_READONLY,
+ PhabricatorRepository::getProtocolAvailabilityName(
+ PhabricatorRepository::SERVE_READONLY),
+ pht('Phabricator will serve a read-only copy of this repository.'))
+ ->addButton(
+ PhabricatorRepository::SERVE_READWRITE,
+ PhabricatorRepository::getProtocolAvailabilityName(
+ PhabricatorRepository::SERVE_READWRITE),
+ $rw_message,
+ $repository->isHosted() ? null : 'disabled',
+ $repository->isHosted() ? null : true);
+
$http_control =
id(new AphrontFormRadioButtonControl())
->setName('http')
@@ -205,6 +228,7 @@
pht(
'Phabricator can serve repositories over various protocols. You can '.
'configure server protocols here.'))
+ ->appendChild($ssh_control)
->appendChild($http_control)
->appendChild(
id(new AphrontFormSubmitControl())
Index: src/applications/diffusion/ssh/DiffusionSSHGitUploadPackWorkflow.php
===================================================================
--- /dev/null
+++ src/applications/diffusion/ssh/DiffusionSSHGitUploadPackWorkflow.php
@@ -0,0 +1,26 @@
+<?php
+
+final class DiffusionSSHGitUploadPackWorkflow
+ extends DiffusionSSHGitWorkflow {
+
+ public function didConstruct() {
+ $this->setName('git-upload-pack');
+ $this->setArguments(
+ array(
+ array(
+ 'name' => 'dir',
+ 'wildcard' => true,
+ ),
+ ));
+ }
+
+ public function isReadOnly() {
+ return true;
+ }
+
+ public function getRequestPath() {
+ $args = $this->getArgs();
+ return head($args->getArg('dir'));
+ }
+
+}
Index: src/applications/diffusion/ssh/DiffusionSSHGitWorkflow.php
===================================================================
--- /dev/null
+++ src/applications/diffusion/ssh/DiffusionSSHGitWorkflow.php
@@ -0,0 +1,10 @@
+<?php
+
+abstract class DiffusionSSHGitWorkflow extends DiffusionSSHWorkflow {
+
+ protected function writeError($message) {
+ // Git assumes we'll add our own newlines.
+ return parent::writeError($message."\n");
+ }
+
+}
Index: src/applications/diffusion/ssh/DiffusionSSHWorkflow.php
===================================================================
--- /dev/null
+++ src/applications/diffusion/ssh/DiffusionSSHWorkflow.php
@@ -0,0 +1,90 @@
+<?php
+
+abstract class DiffusionSSHWorkflow extends PhabricatorSSHWorkflow {
+
+ private $args;
+
+ public function getArgs() {
+ return $this->args;
+ }
+
+ abstract protected function isReadOnly();
+ abstract protected function getRequestPath();
+ protected function writeError($message) {
+ $this->getErrorChannel()->write($message);
+ return $this;
+ }
+
+ final public function execute(PhutilArgumentParser $args) {
+ $this->args = $args;
+
+ try {
+ $repository = $this->loadRepository();
+
+ throw new Exception("TODO: Implement serve over SSH.");
+
+ } catch (Exception $ex) {
+ $this->writeError(get_class($ex).': '.$ex->getMessage());
+ return 1;
+ }
+
+ return 0;
+ }
+
+ private function loadRepository() {
+ $viewer = $this->getUser();
+ $path = $this->getRequestPath();
+
+ $regex = '@^/?diffusion/(?P<callsign>[A-Z]+)(?:/|$)@';
+ $matches = null;
+ if (!preg_match($regex, $path, $matches)) {
+ throw new Exception(
+ pht(
+ 'Unrecognized repository path "%s". Expected a path like '.
+ '"%s".',
+ $path,
+ "/diffusion/X/"));
+ }
+
+ $callsign = $matches[1];
+ $repository = id(new PhabricatorRepositoryQuery())
+ ->setViewer($viewer)
+ ->withCallsigns(array($callsign))
+ ->executeOne();
+
+ if (!$repository) {
+ throw new Exception(
+ pht('No repository "%s" exists!', $callsign));
+ }
+
+ $is_push = !$this->isReadOnly();
+
+ switch ($repository->getServeOverSSH()) {
+ case PhabricatorRepository::SERVE_READONLY:
+ if ($is_push) {
+ throw new Exception(
+ pht('This repository is read-only over SSH.'));
+ }
+ break;
+ case PhabricatorRepository::SERVE_READWRITE:
+ if ($is_push) {
+ $can_push = PhabricatorPolicyFilter::hasCapability(
+ $viewer,
+ $repository,
+ DiffusionCapabilityPush::CAPABILITY);
+ if (!$can_push) {
+ throw new Exception(
+ pht('You do not have permission to push to this repository.'));
+ }
+ }
+ break;
+ case PhabricatorRepository::SERVE_OFF:
+ default:
+ throw new Exception(
+ pht('This repository is not available over SSH.'));
+ }
+
+ return $repository;
+ }
+
+}
Index: src/infrastructure/ssh/PhabricatorSSHWorkflow.php
===================================================================
--- src/infrastructure/ssh/PhabricatorSSHWorkflow.php
+++ src/infrastructure/ssh/PhabricatorSSHWorkflow.php
@@ -4,6 +4,16 @@
private $user;
private $iochannel;
+ private $errorChannel;
+
+ public function setErrorChannel(PhutilChannel $error_channel) {
+ $this->errorChannel = $error_channel;
+ return $this;
+ }
+
+ public function getErrorChannel() {
+ return $this->errorChannel;
+ }
public function setUser(PhabricatorUser $user) {
$this->user = $user;
@@ -38,4 +48,9 @@
return $channel->read();
}
+ public function writeIO($data) {
+ $this->getIOChannel()->write($data);
+ return $this;
+ }
+
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 26, 12:47 PM (4 h, 25 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6789468
Default Alt Text
D7421.diff (9 KB)
Attached To
Mode
D7421: Route some VCS connections over SSH
Attached
Detach File
Event Timeline
Log In to Comment