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:
parent
fb5e50e6cc
commit
d8550c114d
4 changed files with 57 additions and 4 deletions
|
@ -1,6 +1,25 @@
|
||||||
#!/usr/bin/env php
|
#!/usr/bin/env php
|
||||||
<?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__)));
|
$root = dirname(dirname(dirname(__FILE__)));
|
||||||
require_once $root.'/scripts/__init_script__.php';
|
require_once $root.'/scripts/__init_script__.php';
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,18 @@ final class PhabricatorClusterConfigOptions
|
||||||
'0.0.0.0/0',
|
'0.0.0.0/0',
|
||||||
),
|
),
|
||||||
pht('Allow Any Host (Insecure!)')),
|
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.')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,7 @@ final class PhabricatorRepositoryPullEngine
|
||||||
$this->log('%s', pht('Installing commit hook to "%s"...', $path));
|
$this->log('%s', pht('Installing commit hook to "%s"...', $path));
|
||||||
|
|
||||||
$repository = $this->getRepository();
|
$repository = $this->getRepository();
|
||||||
$callsign = $repository->getCallsign();
|
$identifier = $this->getHookContextIdentifier($repository);
|
||||||
|
|
||||||
$root = dirname(phutil_get_library_root('phabricator'));
|
$root = dirname(phutil_get_library_root('phabricator'));
|
||||||
$bin = $root.'/bin/commit-hook';
|
$bin = $root.'/bin/commit-hook';
|
||||||
|
@ -171,7 +171,7 @@ final class PhabricatorRepositoryPullEngine
|
||||||
'exec %s -f %s -- %s "$@"',
|
'exec %s -f %s -- %s "$@"',
|
||||||
$full_php_path,
|
$full_php_path,
|
||||||
$bin,
|
$bin,
|
||||||
$callsign);
|
$identifier);
|
||||||
|
|
||||||
$hook = "#!/bin/sh\nexport TERM=dumb\n{$cmd}\n";
|
$hook = "#!/bin/sh\nexport TERM=dumb\n{$cmd}\n";
|
||||||
|
|
||||||
|
@ -190,6 +190,17 @@ final class PhabricatorRepositoryPullEngine
|
||||||
Filesystem::writeFile($path.'/README', $readme);
|
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 )----------------------------------------- */
|
/* -( Pulling Git Working Copies )----------------------------------------- */
|
||||||
|
|
||||||
|
@ -412,6 +423,8 @@ final class PhabricatorRepositoryPullEngine
|
||||||
$repository = $this->getRepository();
|
$repository = $this->getRepository();
|
||||||
$path = $repository->getLocalPath().'/.hg/hgrc';
|
$path = $repository->getLocalPath().'/.hg/hgrc';
|
||||||
|
|
||||||
|
$identifier = $this->getHookContextIdentifier($repository);
|
||||||
|
|
||||||
$root = dirname(phutil_get_library_root('phabricator'));
|
$root = dirname(phutil_get_library_root('phabricator'));
|
||||||
$bin = $root.'/bin/commit-hook';
|
$bin = $root.'/bin/commit-hook';
|
||||||
|
|
||||||
|
@ -422,14 +435,14 @@ final class PhabricatorRepositoryPullEngine
|
||||||
$data[] = csprintf(
|
$data[] = csprintf(
|
||||||
'pretxnchangegroup.phabricator = %s %s %s',
|
'pretxnchangegroup.phabricator = %s %s %s',
|
||||||
$bin,
|
$bin,
|
||||||
$repository->getCallsign(),
|
$identifier,
|
||||||
'pretxnchangegroup');
|
'pretxnchangegroup');
|
||||||
|
|
||||||
// This one handles creating bookmarks.
|
// This one handles creating bookmarks.
|
||||||
$data[] = csprintf(
|
$data[] = csprintf(
|
||||||
'prepushkey.phabricator = %s %s %s',
|
'prepushkey.phabricator = %s %s %s',
|
||||||
$bin,
|
$bin,
|
||||||
$repository->getCallsign(),
|
$identifier,
|
||||||
'prepushkey');
|
'prepushkey');
|
||||||
|
|
||||||
$data[] = null;
|
$data[] = null;
|
||||||
|
|
9
src/infrastructure/env/PhabricatorEnv.php
vendored
9
src/infrastructure/env/PhabricatorEnv.php
vendored
|
@ -112,6 +112,15 @@ final class PhabricatorEnv {
|
||||||
// subprocess environments.
|
// subprocess environments.
|
||||||
$_ENV['PATH'] = $env_path;
|
$_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();
|
PhabricatorEventEngine::initialize();
|
||||||
|
|
||||||
$translation = PhabricatorEnv::newObjectFromConfig('translation.provider');
|
$translation = PhabricatorEnv::newObjectFromConfig('translation.provider');
|
||||||
|
|
Loading…
Reference in a new issue