Differential D15954 Diff 38414 src/applications/diffusion/ssh/DiffusionGitReceivePackSSHWorkflow.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/diffusion/ssh/DiffusionGitReceivePackSSHWorkflow.php
| <?php | <?php | ||||
| final class DiffusionGitReceivePackSSHWorkflow extends DiffusionGitSSHWorkflow { | final class DiffusionGitReceivePackSSHWorkflow extends DiffusionGitSSHWorkflow { | ||||
| private $inProtocol; | |||||
| private $outProtocol; | |||||
| protected function didConstruct() { | protected function didConstruct() { | ||||
| $this->setName('git-receive-pack'); | $this->setName('git-receive-pack'); | ||||
| $this->setArguments( | $this->setArguments( | ||||
| array( | array( | ||||
| array( | array( | ||||
| 'name' => 'dir', | 'name' => 'dir', | ||||
| 'wildcard' => true, | 'wildcard' => true, | ||||
| ), | ), | ||||
| Show All 10 Lines | protected function executeRepositoryOperations() { | ||||
| $cluster_engine = id(new DiffusionRepositoryClusterEngine()) | $cluster_engine = id(new DiffusionRepositoryClusterEngine()) | ||||
| ->setViewer($viewer) | ->setViewer($viewer) | ||||
| ->setRepository($repository) | ->setRepository($repository) | ||||
| ->setLog($this); | ->setLog($this); | ||||
| if ($this->shouldProxy()) { | if ($this->shouldProxy()) { | ||||
| $command = $this->getProxyCommand(); | $command = $this->getProxyCommand(); | ||||
| $intercept = false; | |||||
| $did_synchronize = false; | $did_synchronize = false; | ||||
| if ($device) { | if ($device) { | ||||
| $this->writeClusterEngineLogMessage( | $this->writeClusterEngineLogMessage( | ||||
| pht( | pht( | ||||
| "# Push received by \"%s\", forwarding to cluster host.\n", | "# Push received by \"%s\", forwarding to cluster host.\n", | ||||
| $device->getName())); | $device->getName())); | ||||
| } | } | ||||
| } else { | } else { | ||||
| $command = csprintf('git-receive-pack %s', $repository->getLocalPath()); | $command = csprintf('git-receive-pack %s', $repository->getLocalPath()); | ||||
| $intercept = true; | |||||
| $did_synchronize = true; | $did_synchronize = true; | ||||
| $cluster_engine->synchronizeWorkingCopyBeforeWrite(); | $cluster_engine->synchronizeWorkingCopyBeforeWrite(); | ||||
| if ($device) { | if ($device) { | ||||
| $this->writeClusterEngineLogMessage( | $this->writeClusterEngineLogMessage( | ||||
| pht( | pht( | ||||
| "# Ready to receive on cluster host \"%s\".\n", | "# Ready to receive on cluster host \"%s\".\n", | ||||
| $device->getName())); | $device->getName())); | ||||
| } | } | ||||
| } | } | ||||
| $caught = null; | $caught = null; | ||||
| try { | try { | ||||
| $err = $this->executeRepositoryCommand($command); | $err = $this->executeRepositoryCommand($command, $intercept); | ||||
| } catch (Exception $ex) { | } catch (Exception $ex) { | ||||
| $caught = $ex; | $caught = $ex; | ||||
| } | } | ||||
| // We've committed the write (or rejected it), so we can release the lock | // We've committed the write (or rejected it), so we can release the lock | ||||
| // without waiting for the client to receive the acknowledgement. | // without waiting for the client to receive the acknowledgement. | ||||
| if ($did_synchronize) { | if ($did_synchronize) { | ||||
| $cluster_engine->synchronizeWorkingCopyAfterWrite(); | $cluster_engine->synchronizeWorkingCopyAfterWrite(); | ||||
| } | } | ||||
| if ($caught) { | if ($caught) { | ||||
| throw $caught; | throw $caught; | ||||
| } | } | ||||
| if (!$err) { | if (!$err) { | ||||
| $repository->writeStatusMessage( | $repository->writeStatusMessage( | ||||
| PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE, | PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE, | ||||
| PhabricatorRepositoryStatusMessage::CODE_OKAY); | PhabricatorRepositoryStatusMessage::CODE_OKAY); | ||||
| $this->waitForGitClient(); | $this->waitForGitClient(); | ||||
| } | } | ||||
| return $err; | return $err; | ||||
| } | } | ||||
| private function executeRepositoryCommand($command) { | private function executeRepositoryCommand($command, $intercept) { | ||||
| $repository = $this->getRepository(); | $repository = $this->getRepository(); | ||||
| $command = PhabricatorDaemon::sudoCommandAsDaemonUser($command); | $command = PhabricatorDaemon::sudoCommandAsDaemonUser($command); | ||||
| $future = id(new ExecFuture('%C', $command)) | $future = id(new ExecFuture('%C', $command)) | ||||
| ->setEnv($this->getEnvironment()); | ->setEnv($this->getEnvironment()); | ||||
| return $this->newPassthruCommand() | $command = $this->newPassthruCommand() | ||||
| ->setIOChannel($this->getIOChannel()) | ->setIOChannel($this->getIOChannel()) | ||||
| ->setCommandChannelFromExecFuture($future) | ->setCommandChannelFromExecFuture($future); | ||||
| ->execute(); | |||||
| if ($intercept) { | |||||
| $this->inProtocol = new DiffusionGitWireProtocol(); | |||||
| $this->outProtocol = new DiffusionGitWireProtocol(); | |||||
| $command | |||||
| ->setWillReadCallback(array($this, 'willReadMessageCallback')) | |||||
| ->setWillWriteCallback(array($this, 'willWriteMessageCallback')); | |||||
| } | |||||
| return $command->execute(); | |||||
| } | |||||
| public function willReadMessageCallback( | |||||
| PhabricatorSSHPassthruCommand $command, | |||||
| $message) { | |||||
| $f = fopen('/tmp/git-response.log', 'a'); | |||||
| fwrite($f, $message); | |||||
| fflush($f); | |||||
| fclose($f); | |||||
| return $this->outProtocol->writeData($message); | |||||
| } | |||||
| public function willWriteMessageCallback( | |||||
| PhabricatorSSHPassthruCommand $command, | |||||
| $message) { | |||||
| $f = fopen('/tmp/git-request.log', 'a'); | |||||
| fwrite($f, $message); | |||||
| fflush($f); | |||||
| fclose($f); | |||||
| return $this->inProtocol->writeData($message); | |||||
| } | } | ||||
| } | } | ||||