Page MenuHomePhabricator

D11036.diff
No OneTemporary

D11036.diff

diff --git a/resources/sql/autopatches/20141223.daemonloguser.sql b/resources/sql/autopatches/20141223.daemonloguser.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20141223.daemonloguser.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_daemon.daemon_log
+ ADD runningAsUser VARCHAR(255) COLLATE {$COLLATE_TEXT};
diff --git a/src/applications/config/check/PhabricatorSetupCheckDaemons.php b/src/applications/config/check/PhabricatorSetupCheckDaemons.php
--- a/src/applications/config/check/PhabricatorSetupCheckDaemons.php
+++ b/src/applications/config/check/PhabricatorSetupCheckDaemons.php
@@ -43,12 +43,47 @@
->addCommand('phabricator/ $ ./bin/phd start');
}
+ $phd_user = PhabricatorEnv::getEnvConfig('phd.user');
$environment_hash = PhabricatorEnv::calculateEnvironmentHash();
$all_daemons = id(new PhabricatorDaemonLogQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE)
->execute();
foreach ($all_daemons as $daemon) {
+
+ if ($phd_user) {
+ if ($daemon->getRunningAsUser() != $phd_user) {
+ $doc_href = PhabricatorEnv::getDocLink(
+ 'Managing Daemons with phd');
+
+ $summary = pht(
+ 'At least one daemon is currently running as a different '.
+ 'user than configured in the Phabricator phd.user setting');
+
+ $message = pht(
+ 'A daemon is running as user %s while the Phabricator config '.
+ 'specifies phd.user to be %s.'.
+ "\n\n".
+ 'Either adjust phd.user to match %s or start '.
+ 'the daemons as the correct user. '.
+ "\n\n".
+ 'phd Daemons will try to '.
+ 'use sudo to start as the configured user. '.
+ 'Make sure that the user who starts phd has the correct '.
+ 'sudo permissions to start phd daemons as %s',
+ phutil_tag('tt', array(), $daemon->getRunningAsUser()),
+ phutil_tag('tt', array(), $phd_user),
+ phutil_tag('tt', array(), $daemon->getRunningAsUser()),
+ phutil_tag('tt', array(), $phd_user));
+
+ $this->newIssue('daemons.run-as-different-user')
+ ->setName(pht('Daemons are running as the wrong user'))
+ ->setSummary($summary)
+ ->setMessage($message)
+ ->addCommand('phabricator/ $ ./bin/phd restart');
+ }
+ }
+
if ($daemon->getEnvHash() != $environment_hash) {
$doc_href = PhabricatorEnv::getDocLink(
'Managing Daemons with phd');
diff --git a/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php b/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php
--- a/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php
+++ b/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php
@@ -163,6 +163,7 @@
$view->addProperty(pht('Daemon Class'), $daemon->getDaemon());
$view->addProperty(pht('Host'), $daemon->getHost());
$view->addProperty(pht('PID'), $daemon->getPID());
+ $view->addProperty(pht('Running as'), $daemon->getRunningAsUser());
$view->addProperty(pht('Started'), phabricator_datetime($c_epoch, $viewer));
$view->addProperty(
pht('Seen'),
diff --git a/src/applications/daemon/event/PhabricatorDaemonEventListener.php b/src/applications/daemon/event/PhabricatorDaemonEventListener.php
--- a/src/applications/daemon/event/PhabricatorDaemonEventListener.php
+++ b/src/applications/daemon/event/PhabricatorDaemonEventListener.php
@@ -34,11 +34,13 @@
private function handleLaunchEvent(PhutilEvent $event) {
$id = $event->getValue('id');
+ $current_user = posix_getpwuid(posix_geteuid());
$daemon = id(new PhabricatorDaemonLog())
->setDaemon($event->getValue('daemonClass'))
->setHost(php_uname('n'))
->setPID(getmypid())
+ ->setRunningAsUser($current_user['name'])
->setEnvHash(PhabricatorEnv::calculateEnvironmentHash())
->setStatus(PhabricatorDaemonLog::STATUS_RUNNING)
->setArgv($event->getValue('argv'))
diff --git a/src/applications/daemon/management/PhabricatorDaemonManagementDebugWorkflow.php b/src/applications/daemon/management/PhabricatorDaemonManagementDebugWorkflow.php
--- a/src/applications/daemon/management/PhabricatorDaemonManagementDebugWorkflow.php
+++ b/src/applications/daemon/management/PhabricatorDaemonManagementDebugWorkflow.php
@@ -21,11 +21,17 @@
'name' => 'argv',
'wildcard' => true,
),
+ array(
+ 'name' => 'as-current-user',
+ 'help' => 'Run the daemon as the current user '.
+ 'instead of the configured phd.user',
+ ),
));
}
public function execute(PhutilArgumentParser $args) {
$argv = $args->getArg('argv');
+ $run_as_current_user = $args->getArg('as-current-user');
if (!$argv) {
throw new PhutilArgumentUsageException(
@@ -33,7 +39,11 @@
}
$daemon_class = array_shift($argv);
- return $this->launchDaemon($daemon_class, $argv, $is_debug = true);
+ return $this->launchDaemon(
+ $daemon_class,
+ $argv,
+ $is_debug = true,
+ $run_as_current_user);
}
}
diff --git a/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php b/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php
--- a/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php
+++ b/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php
@@ -3,6 +3,8 @@
abstract class PhabricatorDaemonManagementWorkflow
extends PhabricatorManagementWorkflow {
+ private $runDaemonsAsUser = null;
+
protected final function loadAvailableDaemonClasses() {
$loader = new PhutilSymbolLoader();
return $loader
@@ -103,10 +105,37 @@
return head($match);
}
- protected final function launchDaemon($class, array $argv, $debug) {
+ protected final function launchDaemon(
+ $class,
+ array $argv,
+ $debug,
+ $run_as_current_user = false) {
+
$daemon = $this->findDaemonClass($class);
$console = PhutilConsole::getConsole();
+ if (!$run_as_current_user) {
+ // Check if the script is started as the correct user
+ $phd_user = PhabricatorEnv::getEnvConfig('phd.user');
+ $current_user = posix_getpwuid(posix_geteuid());
+ $current_user = $current_user['name'];
+ if ($phd_user && $phd_user != $current_user) {
+ if ($debug) {
+ throw new PhutilArgumentUsageException(pht(
+ 'You are trying to run a daemon as a nonstandard user, '.
+ 'and `phd` was not able to `sudo` to the correct user. '."\n".
+ 'Phabricator is configured to run daemons as "%s", '.
+ 'but the current user is "%s". '."\n".
+ 'Use `sudo` to run as a different user, pass `--as-current-user` '.
+ 'to ignore this warning, or edit `phd.user` '.
+ 'to change the configuration.', $phd_user, $current_user));
+ } else {
+ $this->runDaemonsAsUser = $phd_user;
+ $console->writeOut(pht('Starting daemons as %s', $phd_user)."\n");
+ }
+ }
+ }
+
if ($debug) {
if ($argv) {
$console->writeOut(
@@ -187,11 +216,39 @@
phutil_passthru('(cd %s && exec %C)', $daemon_script_dir, $command);
} else {
- $future = new ExecFuture('exec %C', $command);
- // Play games to keep 'ps' looking reasonable.
- $future->setCWD($daemon_script_dir);
- $future->resolvex();
+ try {
+ $this->executeDaemonLaunchCommand(
+ $command,
+ $daemon_script_dir,
+ $this->runDaemonsAsUser);
+ } catch (CommandException $e) {
+ // Retry without sudo
+ $console->writeOut(pht(
+ "sudo command failed. Starting daemon as current user\n"));
+ $this->executeDaemonLaunchCommand(
+ $command,
+ $daemon_script_dir);
+ }
+ }
+ }
+
+ private function executeDaemonLaunchCommand(
+ $command,
+ $daemon_script_dir,
+ $run_as_user = null) {
+
+ if ($run_as_user) {
+ // If anything else besides sudo should be
+ // supported then insert it here (runuser, su, ...)
+ $command = csprintf(
+ 'sudo -En -u %s -- %C',
+ $run_as_user,
+ $command);
}
+ $future = new ExecFuture('exec %C', $command);
+ // Play games to keep 'ps' looking reasonable.
+ $future->setCWD($daemon_script_dir);
+ $future->resolvex();
}
public static function ignoreSignal($signo) {
diff --git a/src/applications/daemon/storage/PhabricatorDaemonLog.php b/src/applications/daemon/storage/PhabricatorDaemonLog.php
--- a/src/applications/daemon/storage/PhabricatorDaemonLog.php
+++ b/src/applications/daemon/storage/PhabricatorDaemonLog.php
@@ -13,6 +13,7 @@
protected $daemon;
protected $host;
protected $pid;
+ protected $runningAsUser;
protected $argv;
protected $explicitArgv = array();
protected $envHash;
@@ -28,6 +29,7 @@
'daemon' => 'text255',
'host' => 'text255',
'pid' => 'uint32',
+ 'runningAsUser' => 'text255?',
'envHash' => 'bytes40',
'status' => 'text8',
),

File Metadata

Mime Type
text/plain
Expires
Sun, May 12, 6:28 AM (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6290719
Default Alt Text
D11036.diff (9 KB)

Event Timeline