mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-29 02:02:41 +01:00
Generate a random unique "Request ID" for SSH requests so processes can coordinate better
Summary: Depends on D19247. Ref T13109. When we receive an SSH request, generate a random unique ID for the request. Then thread it down through the process tree. The immediate goal is to let the `ssh-exec` process coordinate with `commit-hook` process and log information about read and write lock wait times. Today, there's no way for `ssh-exec` to interact with the `PushEvent`, but this is the most helpful place to store this data for users. Test Plan: Made pushes, saw the `PushEvent` table populate with a random request ID. Exported data and saw the ID preserved in the export. Maniphest Tasks: T13109 Differential Revision: https://secure.phabricator.com/D19249
This commit is contained in:
parent
e010aaca43
commit
69bff489d4
9 changed files with 69 additions and 3 deletions
|
@ -0,0 +1,5 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_repository.repository_pushevent
|
||||||
|
ADD requestIdentifier VARBINARY(12);
|
||||||
|
|
||||||
|
ALTER TABLE {$NAMESPACE}_repository.repository_pushevent
|
||||||
|
ADD UNIQUE KEY `key_request` (requestIdentifier);
|
|
@ -187,6 +187,11 @@ if (strlen($remote_protocol)) {
|
||||||
$engine->setRemoteProtocol($remote_protocol);
|
$engine->setRemoteProtocol($remote_protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$request_identifier = getenv(DiffusionCommitHookEngine::ENV_REQUEST);
|
||||||
|
if (strlen($request_identifier)) {
|
||||||
|
$engine->setRequestIdentifier($request_identifier);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$err = $engine->execute();
|
$err = $engine->execute();
|
||||||
} catch (DiffusionCommitHookRejectException $ex) {
|
} catch (DiffusionCommitHookRejectException $ex) {
|
||||||
|
|
|
@ -8,6 +8,12 @@ require_once $root.'/scripts/__init_script__.php';
|
||||||
|
|
||||||
$ssh_log = PhabricatorSSHLog::getLog();
|
$ssh_log = PhabricatorSSHLog::getLog();
|
||||||
|
|
||||||
|
$request_identifier = Filesystem::readRandomCharacters(12);
|
||||||
|
$ssh_log->setData(
|
||||||
|
array(
|
||||||
|
'Q' => $request_identifier,
|
||||||
|
));
|
||||||
|
|
||||||
$args = new PhutilArgumentParser($argv);
|
$args = new PhutilArgumentParser($argv);
|
||||||
$args->setTagline(pht('execute SSH requests'));
|
$args->setTagline(pht('execute SSH requests'));
|
||||||
$args->setSynopsis(<<<EOSYNOPSIS
|
$args->setSynopsis(<<<EOSYNOPSIS
|
||||||
|
@ -248,6 +254,7 @@ try {
|
||||||
$workflow->setSSHUser($user);
|
$workflow->setSSHUser($user);
|
||||||
$workflow->setOriginalArguments($original_argv);
|
$workflow->setOriginalArguments($original_argv);
|
||||||
$workflow->setIsClusterRequest($is_cluster_request);
|
$workflow->setIsClusterRequest($is_cluster_request);
|
||||||
|
$workflow->setRequestIdentifier($request_identifier);
|
||||||
|
|
||||||
$sock_stdin = fopen('php://stdin', 'r');
|
$sock_stdin = fopen('php://stdin', 'r');
|
||||||
if (!$sock_stdin) {
|
if (!$sock_stdin) {
|
||||||
|
|
|
@ -47,6 +47,10 @@ final class PhabricatorAccessLogConfigOptions
|
||||||
's' => pht('The system user.'),
|
's' => pht('The system user.'),
|
||||||
'S' => pht('The system sudo user.'),
|
'S' => pht('The system sudo user.'),
|
||||||
'k' => pht('ID of the SSH key used to authenticate the request.'),
|
'k' => pht('ID of the SSH key used to authenticate the request.'),
|
||||||
|
|
||||||
|
// TODO: This is a reasonable thing to support in the HTTP access
|
||||||
|
// log, too.
|
||||||
|
'Q' => pht('A random, unique string which identifies the request.'),
|
||||||
);
|
);
|
||||||
|
|
||||||
$http_desc = pht(
|
$http_desc = pht(
|
||||||
|
|
|
@ -12,6 +12,7 @@ final class DiffusionCommitHookEngine extends Phobject {
|
||||||
|
|
||||||
const ENV_REPOSITORY = 'PHABRICATOR_REPOSITORY';
|
const ENV_REPOSITORY = 'PHABRICATOR_REPOSITORY';
|
||||||
const ENV_USER = 'PHABRICATOR_USER';
|
const ENV_USER = 'PHABRICATOR_USER';
|
||||||
|
const ENV_REQUEST = 'PHABRICATOR_REQUEST';
|
||||||
const ENV_REMOTE_ADDRESS = 'PHABRICATOR_REMOTE_ADDRESS';
|
const ENV_REMOTE_ADDRESS = 'PHABRICATOR_REMOTE_ADDRESS';
|
||||||
const ENV_REMOTE_PROTOCOL = 'PHABRICATOR_REMOTE_PROTOCOL';
|
const ENV_REMOTE_PROTOCOL = 'PHABRICATOR_REMOTE_PROTOCOL';
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ final class DiffusionCommitHookEngine extends Phobject {
|
||||||
private $subversionRepository;
|
private $subversionRepository;
|
||||||
private $remoteAddress;
|
private $remoteAddress;
|
||||||
private $remoteProtocol;
|
private $remoteProtocol;
|
||||||
|
private $requestIdentifier;
|
||||||
private $transactionKey;
|
private $transactionKey;
|
||||||
private $mercurialHook;
|
private $mercurialHook;
|
||||||
private $mercurialCommits = array();
|
private $mercurialCommits = array();
|
||||||
|
@ -58,6 +60,15 @@ final class DiffusionCommitHookEngine extends Phobject {
|
||||||
return $this->remoteAddress;
|
return $this->remoteAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setRequestIdentifier($request_identifier) {
|
||||||
|
$this->requestIdentifier = $request_identifier;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequestIdentifier() {
|
||||||
|
return $this->requestIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
public function setSubversionTransactionInfo($transaction, $repository) {
|
public function setSubversionTransactionInfo($transaction, $repository) {
|
||||||
$this->subversionTransaction = $transaction;
|
$this->subversionTransaction = $transaction;
|
||||||
$this->subversionRepository = $repository;
|
$this->subversionRepository = $repository;
|
||||||
|
@ -620,6 +631,7 @@ final class DiffusionCommitHookEngine extends Phobject {
|
||||||
$env = array(
|
$env = array(
|
||||||
self::ENV_REPOSITORY => $this->getRepository()->getPHID(),
|
self::ENV_REPOSITORY => $this->getRepository()->getPHID(),
|
||||||
self::ENV_USER => $this->getViewer()->getUsername(),
|
self::ENV_USER => $this->getViewer()->getUsername(),
|
||||||
|
self::ENV_REQUEST => $this->getRequestIdentifier(),
|
||||||
self::ENV_REMOTE_PROTOCOL => $this->getRemoteProtocol(),
|
self::ENV_REMOTE_PROTOCOL => $this->getRemoteProtocol(),
|
||||||
self::ENV_REMOTE_ADDRESS => $this->getRemoteAddress(),
|
self::ENV_REMOTE_ADDRESS => $this->getRemoteAddress(),
|
||||||
);
|
);
|
||||||
|
@ -1081,16 +1093,24 @@ final class DiffusionCommitHookEngine extends Phobject {
|
||||||
->setDevicePHID($device_phid)
|
->setDevicePHID($device_phid)
|
||||||
->setRepositoryPHID($this->getRepository()->getPHID())
|
->setRepositoryPHID($this->getRepository()->getPHID())
|
||||||
->attachRepository($this->getRepository())
|
->attachRepository($this->getRepository())
|
||||||
->setEpoch(time());
|
->setEpoch(PhabricatorTime::getNow());
|
||||||
}
|
}
|
||||||
|
|
||||||
private function newPushEvent() {
|
private function newPushEvent() {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
return PhabricatorRepositoryPushEvent::initializeNewEvent($viewer)
|
|
||||||
|
$event = PhabricatorRepositoryPushEvent::initializeNewEvent($viewer)
|
||||||
->setRepositoryPHID($this->getRepository()->getPHID())
|
->setRepositoryPHID($this->getRepository()->getPHID())
|
||||||
->setRemoteAddress($this->getRemoteAddress())
|
->setRemoteAddress($this->getRemoteAddress())
|
||||||
->setRemoteProtocol($this->getRemoteProtocol())
|
->setRemoteProtocol($this->getRemoteProtocol())
|
||||||
->setEpoch(time());
|
->setEpoch(PhabricatorTime::getNow());
|
||||||
|
|
||||||
|
$identifier = $this->getRequestIdentifier();
|
||||||
|
if (strlen($identifier)) {
|
||||||
|
$event->setRequestIdentifier($identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $event;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function rejectEnormousChanges(array $content_updates) {
|
private function rejectEnormousChanges(array $content_updates) {
|
||||||
|
|
|
@ -30,6 +30,11 @@ abstract class DiffusionSSHWorkflow extends PhabricatorSSHWorkflow {
|
||||||
DiffusionCommitHookEngine::ENV_REMOTE_PROTOCOL => 'ssh',
|
DiffusionCommitHookEngine::ENV_REMOTE_PROTOCOL => 'ssh',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$identifier = $this->getRequestIdentifier();
|
||||||
|
if ($identifier !== null) {
|
||||||
|
$env[DiffusionCommitHookEngine::ENV_REQUEST] = $identifier;
|
||||||
|
}
|
||||||
|
|
||||||
$remote_address = $this->getSSHRemoteAddress();
|
$remote_address = $this->getSSHRemoteAddress();
|
||||||
if ($remote_address !== null) {
|
if ($remote_address !== null) {
|
||||||
$env[DiffusionCommitHookEngine::ENV_REMOTE_ADDRESS] = $remote_address;
|
$env[DiffusionCommitHookEngine::ENV_REMOTE_ADDRESS] = $remote_address;
|
||||||
|
|
|
@ -101,6 +101,9 @@ final class PhabricatorRepositoryPushLogSearchEngine
|
||||||
$fields[] = id(new PhabricatorIDExportField())
|
$fields[] = id(new PhabricatorIDExportField())
|
||||||
->setKey('pushID')
|
->setKey('pushID')
|
||||||
->setLabel(pht('Push ID')),
|
->setLabel(pht('Push ID')),
|
||||||
|
$fields[] = id(new PhabricatorStringExportField())
|
||||||
|
->setKey('unique')
|
||||||
|
->setLabel(pht('Unique')),
|
||||||
$fields[] = id(new PhabricatorStringExportField())
|
$fields[] = id(new PhabricatorStringExportField())
|
||||||
->setKey('protocol')
|
->setKey('protocol')
|
||||||
->setLabel(pht('Protocol')),
|
->setLabel(pht('Protocol')),
|
||||||
|
@ -209,6 +212,7 @@ final class PhabricatorRepositoryPushLogSearchEngine
|
||||||
|
|
||||||
$map = array(
|
$map = array(
|
||||||
'pushID' => $event->getID(),
|
'pushID' => $event->getID(),
|
||||||
|
'unique' => $event->getRequestIdentifier(),
|
||||||
'protocol' => $event->getRemoteProtocol(),
|
'protocol' => $event->getRemoteProtocol(),
|
||||||
'repositoryPHID' => $repository_phid,
|
'repositoryPHID' => $repository_phid,
|
||||||
'repository' => $repository_name,
|
'repository' => $repository_name,
|
||||||
|
|
|
@ -11,6 +11,7 @@ final class PhabricatorRepositoryPushEvent
|
||||||
protected $repositoryPHID;
|
protected $repositoryPHID;
|
||||||
protected $epoch;
|
protected $epoch;
|
||||||
protected $pusherPHID;
|
protected $pusherPHID;
|
||||||
|
protected $requestIdentifier;
|
||||||
protected $remoteAddress;
|
protected $remoteAddress;
|
||||||
protected $remoteProtocol;
|
protected $remoteProtocol;
|
||||||
protected $rejectCode;
|
protected $rejectCode;
|
||||||
|
@ -29,6 +30,7 @@ final class PhabricatorRepositoryPushEvent
|
||||||
self::CONFIG_AUX_PHID => true,
|
self::CONFIG_AUX_PHID => true,
|
||||||
self::CONFIG_TIMESTAMPS => false,
|
self::CONFIG_TIMESTAMPS => false,
|
||||||
self::CONFIG_COLUMN_SCHEMA => array(
|
self::CONFIG_COLUMN_SCHEMA => array(
|
||||||
|
'requestIdentifier' => 'bytes12?',
|
||||||
'remoteAddress' => 'ipaddress?',
|
'remoteAddress' => 'ipaddress?',
|
||||||
'remoteProtocol' => 'text32?',
|
'remoteProtocol' => 'text32?',
|
||||||
'rejectCode' => 'uint32',
|
'rejectCode' => 'uint32',
|
||||||
|
@ -38,6 +40,10 @@ final class PhabricatorRepositoryPushEvent
|
||||||
'key_repository' => array(
|
'key_repository' => array(
|
||||||
'columns' => array('repositoryPHID'),
|
'columns' => array('repositoryPHID'),
|
||||||
),
|
),
|
||||||
|
'key_request' => array(
|
||||||
|
'columns' => array('requestIdentifier'),
|
||||||
|
'unique' => true,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
) + parent::getConfiguration();
|
) + parent::getConfiguration();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ abstract class PhabricatorSSHWorkflow
|
||||||
private $errorChannel;
|
private $errorChannel;
|
||||||
private $isClusterRequest;
|
private $isClusterRequest;
|
||||||
private $originalArguments;
|
private $originalArguments;
|
||||||
|
private $requestIdentifier;
|
||||||
|
|
||||||
public function isExecutable() {
|
public function isExecutable() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -89,6 +90,15 @@ abstract class PhabricatorSSHWorkflow
|
||||||
return $this->originalArguments;
|
return $this->originalArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setRequestIdentifier($request_identifier) {
|
||||||
|
$this->requestIdentifier = $request_identifier;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequestIdentifier() {
|
||||||
|
return $this->requestIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
public function getSSHRemoteAddress() {
|
public function getSSHRemoteAddress() {
|
||||||
$ssh_client = getenv('SSH_CLIENT');
|
$ssh_client = getenv('SSH_CLIENT');
|
||||||
if (!strlen($ssh_client)) {
|
if (!strlen($ssh_client)) {
|
||||||
|
|
Loading…
Reference in a new issue