1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-25 16:22:43 +01:00

Promote instance identity to the upstream and pass it to commit hooks

Summary:
Fixes T7019. In a cluster environment, pushes currently fail because the commit hook can't identify the instance.

For web processes, the hostname identifies the instance -- but we don't have a hostname in the hook.

For CLI processes, the environment identifies the instance -- but we don't have an environment in the hook under SVN.

Promote the instance identifier into the upstream and pack/unpack it explicitly for hooks. This is probably not useful for anyone but us, but the amount of special-purpose code we're introducing is very small.

I poked at trying to do this in a more general way, but:

  - We MUST know this BEFORE we run code, so the normal subclassing stuff is useless.
  - I couldn't come up with any other parameter which might ever be useful to pass in.

Test Plan: Used `git push` to push code through proxied HTTP, got a clean push.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T7019

Differential Revision: https://secure.phabricator.com/D11495
This commit is contained in:
epriestley 2015-01-27 14:51:48 -08:00
parent fb5e50e6cc
commit d8550c114d
4 changed files with 57 additions and 4 deletions

View file

@ -1,6 +1,25 @@
#!/usr/bin/env php
<?php
// Commit hooks execute in an unusual context where the environment may be
// unavailable, particularly in SVN. The first parameter to this script is
// either a bare repository identifier ("X"), or a repository identifier
// followed by an instance identifier ("X:instance"). If we have an instance
// identifier, unpack it into the environment before we start up. This allows
// subclasses of PhabricatorConfigSiteSource to read it and build an instance
// environment.
if ($argc > 1) {
$context = $argv[1];
$context = explode(':', $context, 2);
$argv[1] = $context[0];
if (count($context) > 1) {
$_ENV['PHABRICATOR_INSTANCE'] = $context[1];
putenv('PHABRICATOR_INSTANCE='.$context[1]);
}
}
$root = dirname(dirname(dirname(__FILE__)));
require_once $root.'/scripts/__init_script__.php';

View file

@ -52,6 +52,18 @@ final class PhabricatorClusterConfigOptions
'0.0.0.0/0',
),
pht('Allow Any Host (Insecure!)')),
$this->newOption('cluster.instance', 'string', null)
->setLocked(true)
->setSummary(pht('Instance identifier for multi-tenant clusters.'))
->setDescription(
pht(
'WARNING: This is a very advanced option, and only useful for '.
'hosting providers running multi-tenant clusters.'.
"\n\n".
'If you provide an instance identifier here (normally by '.
'injecting it with a `PhabricatorConfigSiteSource`), Phabricator '.
'will pass it to subprocesses and commit hooks in the '.
'`PHABRICATOR_INSTANCE` environmental variable.')),
);
}

View file

@ -161,7 +161,7 @@ final class PhabricatorRepositoryPullEngine
$this->log('%s', pht('Installing commit hook to "%s"...', $path));
$repository = $this->getRepository();
$callsign = $repository->getCallsign();
$identifier = $this->getHookContextIdentifier($repository);
$root = dirname(phutil_get_library_root('phabricator'));
$bin = $root.'/bin/commit-hook';
@ -171,7 +171,7 @@ final class PhabricatorRepositoryPullEngine
'exec %s -f %s -- %s "$@"',
$full_php_path,
$bin,
$callsign);
$identifier);
$hook = "#!/bin/sh\nexport TERM=dumb\n{$cmd}\n";
@ -190,6 +190,17 @@ final class PhabricatorRepositoryPullEngine
Filesystem::writeFile($path.'/README', $readme);
}
private function getHookContextIdentifier(PhabricatorRepository $repository) {
$identifier = $repository->getCallsign();
$instance = PhabricatorEnv::getEnvConfig('cluster.instance');
if (strlen($instance)) {
$identifier = "{$identifier}:{$instance}";
}
return $identifier;
}
/* -( Pulling Git Working Copies )----------------------------------------- */
@ -412,6 +423,8 @@ final class PhabricatorRepositoryPullEngine
$repository = $this->getRepository();
$path = $repository->getLocalPath().'/.hg/hgrc';
$identifier = $this->getHookContextIdentifier($repository);
$root = dirname(phutil_get_library_root('phabricator'));
$bin = $root.'/bin/commit-hook';
@ -422,14 +435,14 @@ final class PhabricatorRepositoryPullEngine
$data[] = csprintf(
'pretxnchangegroup.phabricator = %s %s %s',
$bin,
$repository->getCallsign(),
$identifier,
'pretxnchangegroup');
// This one handles creating bookmarks.
$data[] = csprintf(
'prepushkey.phabricator = %s %s %s',
$bin,
$repository->getCallsign(),
$identifier,
'prepushkey');
$data[] = null;

View file

@ -112,6 +112,15 @@ final class PhabricatorEnv {
// subprocess environments.
$_ENV['PATH'] = $env_path;
// If an instance identifier is defined, write it into the environment so
// it's available to subprocesses.
$instance = PhabricatorEnv::getEnvConfig('cluster.instance');
if (strlen($instance)) {
putenv('PHABRICATOR_INSTANCE='.$instance);
$_ENV['PHABRICATOR_INSTANCE'] = $instance;
}
PhabricatorEventEngine::initialize();
$translation = PhabricatorEnv::newObjectFromConfig('translation.provider');