Allow cluster devices to SSH to one another without acting as a user
Summary: Ref T4292. When you run `git fetch` and connect to, say, `repo001.west.company.com`, we'll look at the current version of the repository in other nodes in the cluster. If `repo002.east.company.com` has a newer version of the repository, we'll fetch that version first, then respond to your request. To do this, we need to run `git fetch repo002.east.company.com ...` and have that connect to the other host and be able to fetch data. This change allows us to run `PHABRICATOR_AS_DEVICE=1 git fetch ...` to use device credentials to do this fetch. (Device credentials are already supported and used, they just always connect as a user right now, but these fetches should be doable without having a user. We will have a valid user when you run `git fetch` yourself, but we won't have one if the daemons notice that a repository is out of date and want to update it, so the update code should not depend on having a user.) Test Plan: ``` $ PHABRICATOR_AS_DEVICE=1 ./bin/ssh-connect local.phacility.com Warning: Permanently added 'local.phacility.com' (RSA) to the list of known hosts. PTY allocation request failed on channel 0 phabricator-ssh-exec: Welcome to Phabricator. You are logged in as device/daemon.phacility.net. You haven't specified a command to run. This means you're requesting an interactive shell, but Phabricator does not provide an interactive shell over SSH. Usually, you should run a command like `git clone` or `hg push` rather than connecting directly with SSH. Supported commands are: conduit, git-lfs-authenticate, git-receive-pack, git-upload-pack, hg, svnserve. Connection to local.phacility.com closed. ``` Reviewers: chad Reviewed By: chad Maniphest Tasks: T4292 Differential Revision: https://secure.phabricator.com/D15755
This commit is contained in:
@@ -153,32 +153,37 @@ try {
|
||||
->splitArguments($original_command);
|
||||
|
||||
if ($device) {
|
||||
$act_as_name = array_shift($original_argv);
|
||||
if (!preg_match('/^@/', $act_as_name)) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Commands executed by devices must identify an acting user in the '.
|
||||
'first command argument. This request was not constructed '.
|
||||
'properly.'));
|
||||
// If we're authenticating as a device, the first argument may be a
|
||||
// "@username" argument to act as a particular user.
|
||||
$first_argument = head($original_argv);
|
||||
if (preg_match('/^@/', $first_argument)) {
|
||||
$act_as_name = array_shift($original_argv);
|
||||
$act_as_name = substr($act_as_name, 1);
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withUsernames(array($act_as_name))
|
||||
->executeOne();
|
||||
if (!$user) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Device request identifies an acting user with an invalid '.
|
||||
'username ("%s"). There is no user with this username.',
|
||||
$act_as_name));
|
||||
}
|
||||
} else {
|
||||
$user = PhabricatorUser::getOmnipotentUser();
|
||||
}
|
||||
}
|
||||
|
||||
$act_as_name = substr($act_as_name, 1);
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withUsernames(array($act_as_name))
|
||||
->executeOne();
|
||||
if (!$user) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Device request identifies an acting user with an invalid '.
|
||||
'username ("%s"). There is no user with this username.',
|
||||
$act_as_name));
|
||||
}
|
||||
if ($user->isOmnipotent()) {
|
||||
$user_name = 'device/'.$device->getName();
|
||||
} else {
|
||||
$user_name = $user->getUsername();
|
||||
}
|
||||
|
||||
$ssh_log->setData(
|
||||
array(
|
||||
'u' => $user->getUsername(),
|
||||
'u' => $user_name,
|
||||
'P' => $user->getPHID(),
|
||||
));
|
||||
|
||||
@@ -187,7 +192,7 @@ try {
|
||||
pht(
|
||||
'Your account ("%s") does not have permission to establish SSH '.
|
||||
'sessions. Visit the web interface for more information.',
|
||||
$user->getUsername()));
|
||||
$user_name));
|
||||
}
|
||||
|
||||
$workflows = id(new PhutilClassMapQuery())
|
||||
@@ -206,7 +211,7 @@ try {
|
||||
"Usually, you should run a command like `%s` or `%s` ".
|
||||
"rather than connecting directly with SSH.\n\n".
|
||||
"Supported commands are: %s.",
|
||||
$user->getUsername(),
|
||||
$user_name,
|
||||
'git clone',
|
||||
'hg push',
|
||||
implode(', ', array_keys($workflows))));
|
||||
|
||||
Reference in New Issue
Block a user