mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-25 16:22:43 +01:00
Add a "setup" mode which guides new users through application configuration
Summary: Alters the installation instructions to guide installers into a "setup" mode which does config file sanity checking. Test Plan: Put myself in setup mode, simulated all the failures it detects, took myself out of setup mode, Phabricator works OK. Reviewed By: tuomaspelkonen Reviewers: jungejason, tuomaspelkonen, aran CC: aran, tuomaspelkonen, epriestley Differential Revision: 230
This commit is contained in:
parent
90364cafdc
commit
f7e2b03077
13 changed files with 461 additions and 100 deletions
|
@ -27,6 +27,10 @@ return array(
|
||||||
// contain the right links.
|
// contain the right links.
|
||||||
'phabricator.production-uri' => null,
|
'phabricator.production-uri' => null,
|
||||||
|
|
||||||
|
// Setting this to 'true' will invoke a special setup mode which helps guide
|
||||||
|
// you through setting up Phabricator.
|
||||||
|
'phabricator.setup' => false,
|
||||||
|
|
||||||
// The default PHID for users who haven't uploaded a profile image. It should
|
// The default PHID for users who haven't uploaded a profile image. It should
|
||||||
// be 50x50px.
|
// be 50x50px.
|
||||||
'user.default-profile-image-phid' => 'PHID-FILE-4d61229816cfe6f2b2a3',
|
'user.default-profile-image-phid' => 'PHID-FILE-4d61229816cfe6f2b2a3',
|
||||||
|
@ -78,7 +82,7 @@ return array(
|
||||||
// some data like queries and stack traces, so you should be careful about
|
// some data like queries and stack traces, so you should be careful about
|
||||||
// turning it on in production (although users can not normally see it, even
|
// turning it on in production (although users can not normally see it, even
|
||||||
// if the deployment configuration enables it).
|
// if the deployment configuration enables it).
|
||||||
'darkconsole.enabled' => true,
|
'darkconsole.enabled' => false,
|
||||||
|
|
||||||
// Always enable DarkConsole, even for logged out users. This potentially
|
// Always enable DarkConsole, even for logged out users. This potentially
|
||||||
// exposes sensitive information to users, so make sure untrusted users can
|
// exposes sensitive information to users, so make sure untrusted users can
|
||||||
|
|
|
@ -18,5 +18,6 @@
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
|
||||||
|
'darkconsole.enabled' => true,
|
||||||
|
|
||||||
) + phabricator_read_config_file('default');
|
) + phabricator_read_config_file('default');
|
||||||
|
|
|
@ -18,7 +18,5 @@
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
|
||||||
'darkconsole.enabled' => false,
|
|
||||||
|
|
||||||
) + phabricator_read_config_file('default');
|
) + phabricator_read_config_file('default');
|
||||||
|
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2011 Facebook, Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
return array(
|
|
||||||
|
|
||||||
|
|
||||||
) + phabricator_read_config_file('default');
|
|
1
resources/sql/patches/037.setuptest.sql
Normal file
1
resources/sql/patches/037.setuptest.sql
Normal file
|
@ -0,0 +1 @@
|
||||||
|
SELECT 1;
|
|
@ -22,6 +22,7 @@ require_once $root.'/scripts/__init_script__.php';
|
||||||
require_once $root.'/scripts/__init_env__.php';
|
require_once $root.'/scripts/__init_env__.php';
|
||||||
|
|
||||||
phutil_require_module('phutil', 'console');
|
phutil_require_module('phutil', 'console');
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/setup/sql');
|
||||||
|
|
||||||
define('SCHEMA_VERSION_TABLE_NAME', 'schema_version');
|
define('SCHEMA_VERSION_TABLE_NAME', 'schema_version');
|
||||||
|
|
||||||
|
@ -95,28 +96,7 @@ END;
|
||||||
$next_version = $version['version'] + 1;
|
$next_version = $version['version'] + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the patch files
|
$patches = PhabricatorSQLPatchList::getPatchList();
|
||||||
$patches_dir = $root.'/resources/sql/patches/';
|
|
||||||
$finder = id(new FileFinder($patches_dir))
|
|
||||||
->withSuffix('sql');
|
|
||||||
$results = $finder->find();
|
|
||||||
|
|
||||||
$patches = array();
|
|
||||||
foreach ($results as $r) {
|
|
||||||
$matches = array();
|
|
||||||
if (preg_match('/(\d+)\..*\.sql$/', $r, $matches)) {
|
|
||||||
$patches[] = array('version' => (int)$matches[1],
|
|
||||||
'file' => $r);
|
|
||||||
} else {
|
|
||||||
print
|
|
||||||
"*** WARNING : File {$r} does not follow the normal naming ".
|
|
||||||
"convention. ***\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Files are in some 'random' order returned by the operating system
|
|
||||||
// We need to apply them in proper order
|
|
||||||
$patches = isort($patches, 'version');
|
|
||||||
|
|
||||||
$patch_applied = false;
|
$patch_applied = false;
|
||||||
foreach ($patches as $patch) {
|
foreach ($patches as $patch) {
|
||||||
|
@ -124,16 +104,15 @@ END;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
print "Applying patch {$patch['file']}\n";
|
$short_name = basename($patch['path']);
|
||||||
|
print "Applying patch {$short_name}...\n";
|
||||||
$path = Filesystem::resolvePath($patches_dir.$patch['file']);
|
|
||||||
|
|
||||||
list($stdout, $stderr) = execx(
|
list($stdout, $stderr) = execx(
|
||||||
"mysql --user=%s --password=%s --host=%s < %s",
|
"mysql --user=%s --password=%s --host=%s < %s",
|
||||||
$conn_user,
|
$conn_user,
|
||||||
$conn_pass,
|
$conn_pass,
|
||||||
$conn_host,
|
$conn_host,
|
||||||
$path);
|
$patch['path']);
|
||||||
|
|
||||||
if ($stderr) {
|
if ($stderr) {
|
||||||
print $stderr;
|
print $stderr;
|
||||||
|
|
|
@ -425,6 +425,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorRepositorySvnCommitDiscoveryDaemon' => 'applications/repository/daemon/commitdiscovery/svn',
|
'PhabricatorRepositorySvnCommitDiscoveryDaemon' => 'applications/repository/daemon/commitdiscovery/svn',
|
||||||
'PhabricatorRepositorySvnCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/svn',
|
'PhabricatorRepositorySvnCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/svn',
|
||||||
'PhabricatorRepositoryType' => 'applications/repository/constants/repositorytype',
|
'PhabricatorRepositoryType' => 'applications/repository/constants/repositorytype',
|
||||||
|
'PhabricatorSQLPatchList' => 'infrastructure/setup/sql',
|
||||||
'PhabricatorSearchAbstractDocument' => 'applications/search/index/abstractdocument',
|
'PhabricatorSearchAbstractDocument' => 'applications/search/index/abstractdocument',
|
||||||
'PhabricatorSearchBaseController' => 'applications/search/controller/base',
|
'PhabricatorSearchBaseController' => 'applications/search/controller/base',
|
||||||
'PhabricatorSearchController' => 'applications/search/controller/search',
|
'PhabricatorSearchController' => 'applications/search/controller/search',
|
||||||
|
@ -440,6 +441,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorSearchMySQLExecutor' => 'applications/search/execute/mysql',
|
'PhabricatorSearchMySQLExecutor' => 'applications/search/execute/mysql',
|
||||||
'PhabricatorSearchQuery' => 'applications/search/storage/query',
|
'PhabricatorSearchQuery' => 'applications/search/storage/query',
|
||||||
'PhabricatorSearchRelationship' => 'applications/search/constants/relationship',
|
'PhabricatorSearchRelationship' => 'applications/search/constants/relationship',
|
||||||
|
'PhabricatorSetup' => 'infrastructure/setup',
|
||||||
'PhabricatorStandardPageView' => 'view/page/standard',
|
'PhabricatorStandardPageView' => 'view/page/standard',
|
||||||
'PhabricatorStatusController' => 'applications/status/base',
|
'PhabricatorStatusController' => 'applications/status/base',
|
||||||
'PhabricatorTaskmasterDaemon' => 'infrastructure/daemon/workers/taskmaster',
|
'PhabricatorTaskmasterDaemon' => 'infrastructure/daemon/workers/taskmaster',
|
||||||
|
|
|
@ -16,9 +16,32 @@ schemata into it. First, load the initial database schema.
|
||||||
|
|
||||||
mysql -uroot < path/to/phabricator/resources/sql/init/initialize.sql
|
mysql -uroot < path/to/phabricator/resources/sql/init/initialize.sql
|
||||||
|
|
||||||
After this you need to upgrade the schema see @{article:Upgrading Schema},
|
After this you need to upgrade the schema (see @{article:Upgrading Schema}),
|
||||||
but you need to finish the rest of the configuration first.
|
but you need to finish the rest of the configuration first.
|
||||||
|
|
||||||
|
= Configuring Phabricator =
|
||||||
|
|
||||||
|
Create a new file here:
|
||||||
|
|
||||||
|
path/to/phabricator/conf/custom/myconfig.conf.php
|
||||||
|
|
||||||
|
...where ##myconfig## is some name which identifies your installation. Put this
|
||||||
|
in the file:
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
// Important! This will put Phabricator into setup mode to help you
|
||||||
|
// configure things.
|
||||||
|
'phabricator.setup' => true,
|
||||||
|
|
||||||
|
) + phabricator_read_config_file('production');
|
||||||
|
|
||||||
|
For the last line, you can also use ##'development'## instead of
|
||||||
|
##'production'## if you are planning to develop Phabricator itself. This will
|
||||||
|
turn on some debugging features.
|
||||||
|
|
||||||
= Configuring Apache =
|
= Configuring Apache =
|
||||||
|
|
||||||
Get Apache running and verify it's serving a test page. Consult the Apache
|
Get Apache running and verify it's serving a test page. Consult the Apache
|
||||||
|
@ -49,27 +72,38 @@ this:
|
||||||
RewriteRule ^/favicon.ico - [L,QSA]
|
RewriteRule ^/favicon.ico - [L,QSA]
|
||||||
RewriteRule ^(.*)$ /index.php?__path__=$1 [L,QSA]
|
RewriteRule ^(.*)$ /index.php?__path__=$1 [L,QSA]
|
||||||
|
|
||||||
# This will use "setup" defaults for configuration options, which will
|
# This will use the config file you set up in the previous step. If you
|
||||||
# expose error messages. Before you make the install public, you should
|
# called it something other than 'myconfig', put that here.
|
||||||
# change this to "production" and/or customize your configuration. See
|
SetEnv PHABRICATOR_ENV custom/myconfig
|
||||||
# the next section for details.
|
|
||||||
SetEnv PHABRICATOR_ENV setup
|
|
||||||
</VirtualHost>
|
</VirtualHost>
|
||||||
|
|
||||||
Now, restart apache and navigate to whichever subdomain you set up. You should
|
Now, restart apache and navigate to whichever subdomain you set up. You should
|
||||||
either see the Phabricator login screen, which means you're all set, or some
|
either see the Phabricator setup screen, which is a simple text page that looks
|
||||||
useful error message telling you what else you need to fix (for instance, you
|
something like this:
|
||||||
may need to set up MySQL credentials). If you see something else, you did
|
|
||||||
something very wrong and/or this document lied to you.
|
PHABRICATOR SETUP
|
||||||
|
|
||||||
|
This setup mode will guide you through setting up your Phabricator
|
||||||
|
configuration.
|
||||||
|
|
||||||
|
>>> REQUIRED PHP EXTENSIONS ------------------------------------------------
|
||||||
|
...
|
||||||
|
|
||||||
|
If you see this, you're in good shape. Follow the instructions and correct any
|
||||||
|
problems setup detects. If you don't see it but you do see a useful error
|
||||||
|
message, try to fix that. If neither of these cover you, something is wrong.
|
||||||
|
If you can't figure it out, come get help in IRC or on the mailing list (see
|
||||||
|
http://phabricator.org/ for links).
|
||||||
|
|
||||||
= Configuring Phabricator =
|
= Configuring Phabricator =
|
||||||
|
|
||||||
Now that basic setup is complete, you should configure Phabricator. Phabricator
|
Now that basic setup is complete, you should configure Phabricator for your
|
||||||
configuration options which control how the applications behave are stored here:
|
installation. Phabricator configuration options which control how the
|
||||||
|
applications behave are documented here:
|
||||||
|
|
||||||
/path/to/phabricator/conf/
|
/path/to/phabricator/conf/default.conf.php
|
||||||
|
|
||||||
There are several configuration templates:
|
There are several builtin configurations:
|
||||||
|
|
||||||
- ##default.conf.php##: root configuration, lists every configuration option
|
- ##default.conf.php##: root configuration, lists every configuration option
|
||||||
and sets some default for it. Look in this file to figure out what you can
|
and sets some default for it. Look in this file to figure out what you can
|
||||||
|
@ -80,44 +114,14 @@ There are several configuration templates:
|
||||||
changes to Phabricator itself.
|
changes to Phabricator itself.
|
||||||
- ##production.conf.php##: pulls in ##default.conf.php##, but overrides some
|
- ##production.conf.php##: pulls in ##default.conf.php##, but overrides some
|
||||||
configuration options to provide better values for a production install.
|
configuration options to provide better values for a production install.
|
||||||
Once you've completed setup, you should switch to this configuration or
|
|
||||||
one based upon it.
|
|
||||||
- ##setup.conf.php##: pulls in ##default.conf.php##, but sets some flags that
|
|
||||||
make it easier to set up a Phabricator install. Switch away from this before
|
|
||||||
deploying a production install.
|
|
||||||
|
|
||||||
While you can use these templates as-is, you'll probably want to set up custom
|
To actually configure your install, edit your ##custom/myconfig.conf.php## file
|
||||||
configuration. To do this, create a new file:
|
and override values from either the ##'production'## or ##'development'##
|
||||||
|
configurations. You should not edit the builtin configurations directly because
|
||||||
/path/to/phabricator/conf/custom/myconfig.conf.php
|
that will make upgrading Phabricator more difficult in the future.
|
||||||
|
|
||||||
Put this in the file:
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
return array(
|
|
||||||
|
|
||||||
// This is just an example.
|
|
||||||
'some.config' => 'some_value',
|
|
||||||
|
|
||||||
) + phabricator_read_config_file('production');
|
|
||||||
|
|
||||||
This will create a new config called "custom/myconfig" which uses the
|
|
||||||
"production" config as the default but allows you to override options. You can
|
|
||||||
select it by editing the VirtualHost or Directory entry you set up when
|
|
||||||
configuring Apache:
|
|
||||||
|
|
||||||
<VirtualHost *>
|
|
||||||
# ...
|
|
||||||
SetEnv PHABRICATOR_ENV custom/myconfig
|
|
||||||
# ...
|
|
||||||
</VirtualHost>
|
|
||||||
|
|
||||||
Now, look through ##default.conf.php## and override any options you want to
|
|
||||||
change by providing overrides in ##myconfig.conf.php##.
|
|
||||||
|
|
||||||
= Upgrading Schema =
|
= Upgrading Schema =
|
||||||
|
|
||||||
After you have configured Phabricator, you need to upgrade the database
|
After you have configured Phabricator, you need to upgrade the database
|
||||||
schema, see @{article:Upgrading Schema}. You'll also need to do this after you
|
schema -- see @{article:Upgrading Schema}. You'll also need to do this after you
|
||||||
update the code in the future.
|
update the code in the future.
|
||||||
|
|
298
src/infrastructure/setup/PhabricatorSetup.php
Normal file
298
src/infrastructure/setup/PhabricatorSetup.php
Normal file
|
@ -0,0 +1,298 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorSetup {
|
||||||
|
|
||||||
|
const EXPECTED_SCHEMA_VERSION = 36;
|
||||||
|
|
||||||
|
public static function runSetup() {
|
||||||
|
header("Content-Type: text/plain");
|
||||||
|
self::write("PHABRICATOR SETUP\n\n");
|
||||||
|
|
||||||
|
// Force browser to stop buffering.
|
||||||
|
self::write(str_repeat(' ', 2048));
|
||||||
|
usleep(250000);
|
||||||
|
|
||||||
|
self::write("This setup mode will guide you through setting up your ".
|
||||||
|
"Phabricator configuration.\n");
|
||||||
|
|
||||||
|
self::writeHeader("REQUIRED PHP EXTENSIONS");
|
||||||
|
$extensions = array(
|
||||||
|
'mysql',
|
||||||
|
'hash',
|
||||||
|
'json',
|
||||||
|
);
|
||||||
|
foreach ($extensions as $extension) {
|
||||||
|
$ok = self::requireExtension($extension);
|
||||||
|
if (!$ok) {
|
||||||
|
self::writeFailure();
|
||||||
|
self::write("Setup failure! Install PHP extension '{$extension}'.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self::write("[OKAY] All extensions OKAY\n\n");
|
||||||
|
|
||||||
|
self::writeHeader("GIT SUBMODULES");
|
||||||
|
$root = dirname(phutil_get_library_root('phabricator'));
|
||||||
|
if (!Filesystem::pathExists($root.'/.git')) {
|
||||||
|
self::write(" skip Not a git clone.\n\n");
|
||||||
|
} else {
|
||||||
|
list($info) = execx(
|
||||||
|
'(cd %s && git submodule status)',
|
||||||
|
$root);
|
||||||
|
foreach (explode("\n", rtrim($info)) as $line) {
|
||||||
|
$matches = null;
|
||||||
|
if (!preg_match('/^(.)([0-9a-f]{40}) (\S+)(?: |$)/', $line, $matches)) {
|
||||||
|
self::writeFailure();
|
||||||
|
self::write(
|
||||||
|
"Setup failure! 'git submodule' produced unexpected output:\n".
|
||||||
|
$line);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$status = $matches[1];
|
||||||
|
$module = $matches[3];
|
||||||
|
|
||||||
|
switch ($status) {
|
||||||
|
case '-':
|
||||||
|
case '+':
|
||||||
|
case 'U':
|
||||||
|
self::writeFailure();
|
||||||
|
self::write(
|
||||||
|
"Setup failure! Git submodule '{$module}' is not up to date. ".
|
||||||
|
"Run:\n\n".
|
||||||
|
" cd {$root} && git submodule update --init\n\n".
|
||||||
|
"...to update submodules.");
|
||||||
|
return;
|
||||||
|
case ' ':
|
||||||
|
self::write(" okay Git submodule '{$module}' up to date.\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
self::writeFailure();
|
||||||
|
self::write(
|
||||||
|
"Setup failure! 'git submodule' reported unknown status ".
|
||||||
|
"'{$status}' for submodule '{$module}'. This is a bug; report ".
|
||||||
|
"it to the Phabricator maintainers.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self::write("[OKAY] All submodules OKAY.");
|
||||||
|
|
||||||
|
self::writeHeader("BASIC CONFIGURATION");
|
||||||
|
|
||||||
|
$env = PhabricatorEnv::getEnvConfig('phabricator.env');
|
||||||
|
if ($env == 'production' || $env == 'default' || $env == 'development') {
|
||||||
|
self::writeFailure();
|
||||||
|
self::write(
|
||||||
|
"Setup failure! Your PHABRICATOR_ENV is set to '{$env}', which is ".
|
||||||
|
"a Phabricator environmental default. You should create a custom ".
|
||||||
|
"environmental configuration instead of editing the defaults ".
|
||||||
|
"directly. See this document for instructions:\n");
|
||||||
|
self::writeDoc('article/Configuration_Guide.html');
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
self::write(" okay Custom configuration loaded.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PhabricatorEnv::getEnvConfig('phabricator.base-uri')) {
|
||||||
|
self::writeFailure();
|
||||||
|
self::write(
|
||||||
|
"Setup failure! You must specify 'phabricator.base-uri' in your ".
|
||||||
|
"custom config file. Refer to 'default.conf.php' for documentation ".
|
||||||
|
"on configuration options.\n");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
self::write(" okay phabricator.base-uri\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
self::write("[OKAY] Basic configuration OKAY\n");
|
||||||
|
|
||||||
|
self::writeHeader('FACEBOOK INTEGRATION');
|
||||||
|
$fb_auth = PhabricatorEnv::getEnvConfig('facebook.auth-enabled');
|
||||||
|
if (!$fb_auth) {
|
||||||
|
self::write(" skip 'facebook.auth-enabled' not enabled.\n");
|
||||||
|
} else {
|
||||||
|
self::write(" okay 'facebook.auth-enabled' is enabled.\n");
|
||||||
|
$app_id = PhabricatorEnv::getEnvConfig('facebook.application-id');
|
||||||
|
$app_secret = PhabricatorEnv::getEnvConfig('facebook.application-secret');
|
||||||
|
|
||||||
|
if (!$app_id) {
|
||||||
|
self::writeFailure();
|
||||||
|
self::write(
|
||||||
|
"Setup failure! 'facebook.auth-enabled' is true but there is no ".
|
||||||
|
"setting for 'facebook.application-id'.\n");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
self::write(" okay 'facebook.application-id' is set.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_string($app_id)) {
|
||||||
|
self::writeFailure();
|
||||||
|
self::write(
|
||||||
|
"Setup failure! 'facebook.application-id' should be a string.");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
self::write(" okay 'facebook.application-id' is string.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$app_secret) {
|
||||||
|
self::writeFailure();
|
||||||
|
self::write(
|
||||||
|
"Setup failure! 'facebook.auth-enabled' is true but there is no ".
|
||||||
|
"setting for 'facebook.application-secret'.");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
self::write(" okay 'facebook.application-secret is set.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
self::write("[OKAY] Facebook integration OKAY\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
self::writeHeader("MySQL DATABASE CONFIGURATION");
|
||||||
|
|
||||||
|
$conn_user = PhabricatorEnv::getEnvConfig('mysql.user');
|
||||||
|
$conn_pass = PhabricatorEnv::getEnvConfig('mysql.pass');
|
||||||
|
$conn_host = PhabricatorEnv::getEnvConfig('mysql.host');
|
||||||
|
|
||||||
|
$timeout = ini_get('mysql.connect_timeout');
|
||||||
|
if ($timeout > 5) {
|
||||||
|
self::writeNote(
|
||||||
|
"Your MySQL connect timeout is very high ({$timeout} seconds). ".
|
||||||
|
"Consider reducing it by setting 'mysql.connect_timeout' in your ".
|
||||||
|
"php.ini.");
|
||||||
|
}
|
||||||
|
|
||||||
|
self::write(" okay Trying to connect to MySQL database ".
|
||||||
|
"{$conn_user}@{$conn_host}...\n");
|
||||||
|
|
||||||
|
ini_set('mysql.connect_timeout', 2);
|
||||||
|
|
||||||
|
$conn_raw = new AphrontMySQLDatabaseConnection(
|
||||||
|
array(
|
||||||
|
'user' => $conn_user,
|
||||||
|
'pass' => $conn_pass,
|
||||||
|
'host' => $conn_host,
|
||||||
|
'database' => null,
|
||||||
|
));
|
||||||
|
|
||||||
|
try {
|
||||||
|
queryfx($conn_raw, 'SELECT 1');
|
||||||
|
self::write(" okay Connection successful!\n");
|
||||||
|
} catch (AphrontQueryConnectionException $ex) {
|
||||||
|
self::writeFailure();
|
||||||
|
self::write(
|
||||||
|
"Setup failure! Unable to connect to MySQL database ".
|
||||||
|
"'{$conn_host}' with user '{$conn_user}'. Edit Phabricator ".
|
||||||
|
"configuration keys 'mysql.user', 'mysql.host' and 'mysql.pass' to ".
|
||||||
|
"enable Phabricator to connect.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$databases = queryfx_all($conn_raw, 'SHOW DATABASES');
|
||||||
|
$databases = ipull($databases, 'Database');
|
||||||
|
$databases = array_fill_keys($databases, true);
|
||||||
|
if (empty($databases['phabricator_meta_data'])) {
|
||||||
|
self::writeFailure();
|
||||||
|
self::write(
|
||||||
|
"Setup failure! You haven't loaded the 'initialize.sql' file into ".
|
||||||
|
"MySQL. This file initializes necessary databases. See this guide for ".
|
||||||
|
"instructions:\n");
|
||||||
|
self::writeDoc('article/Configuration_Guide.html');
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
self::write(" okay Databases have been initialized.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
$schema_version = queryfx_one(
|
||||||
|
$conn_raw,
|
||||||
|
'SELECT version FROM phabricator_meta_data.schema_version');
|
||||||
|
$schema_version = idx($schema_version, 'version', 'null');
|
||||||
|
|
||||||
|
$expect = PhabricatorSQLPatchList::getExpectedSchemaVersion();
|
||||||
|
if ($schema_version != $expect) {
|
||||||
|
self::writeFailure();
|
||||||
|
self::write(
|
||||||
|
"Setup failure! You haven't upgraded your database schema to the ".
|
||||||
|
"latest version. Expected version is '{$expect}', but your local ".
|
||||||
|
"version is '{$schema_version}'. See this guide for instructions:\n");
|
||||||
|
self::writeDoc('article/Upgrading_Schema.html');
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
self::write(" okay Database schema are up to date (v{$expect}).\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
self::write("[OKAY] Database configuration OKAY\n");
|
||||||
|
|
||||||
|
|
||||||
|
self::writeHeader('SUCCESS!');
|
||||||
|
self::write(
|
||||||
|
"Congratulations! Your setup seems mostly correct, or at least fairly ".
|
||||||
|
"reasonable.\n\n".
|
||||||
|
"*** NEXT STEP ***\n".
|
||||||
|
"Edit your configuration file (conf/{$env}.conf.php) and remove the ".
|
||||||
|
"'phabricator.setup' line to finish installation.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function requireExtension($extension) {
|
||||||
|
if (extension_loaded($extension)) {
|
||||||
|
self::write(" okay Extension '{$extension}' installed.\n");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
self::write("[FAIL] Extension '{$extension}' is NOT INSTALLED!\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function writeFailure() {
|
||||||
|
self::write("\n\n<<< *** FAILURE! *** >>>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function write($str) {
|
||||||
|
echo $str;
|
||||||
|
ob_flush();
|
||||||
|
flush();
|
||||||
|
|
||||||
|
// This, uh, makes it look cool. -_-
|
||||||
|
usleep(40000);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function writeNote($note) {
|
||||||
|
self::write(
|
||||||
|
'Note: '.wordwrap($note, 75, "\n ", true)."\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function writeHeader($header) {
|
||||||
|
$template = '>>>'.str_repeat('-', 77);
|
||||||
|
$template = substr_replace(
|
||||||
|
$template,
|
||||||
|
' '.$header.' ',
|
||||||
|
3,
|
||||||
|
strlen($header) + 4);
|
||||||
|
self::write("\n\n{$template}\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function writeDoc($doc) {
|
||||||
|
self::write(
|
||||||
|
"\n".
|
||||||
|
' http://phabricator.com/docs/phabricator/'.$doc.
|
||||||
|
"\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
20
src/infrastructure/setup/__init__.php
Normal file
20
src/infrastructure/setup/__init__.php
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/env');
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/setup/sql');
|
||||||
|
phutil_require_module('phabricator', 'storage/connection/mysql');
|
||||||
|
phutil_require_module('phabricator', 'storage/queryfx');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'filesystem');
|
||||||
|
phutil_require_module('phutil', 'future/exec');
|
||||||
|
phutil_require_module('phutil', 'moduleutils');
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorSetup.php');
|
57
src/infrastructure/setup/sql/PhabricatorSQLPatchList.php
Normal file
57
src/infrastructure/setup/sql/PhabricatorSQLPatchList.php
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
final class PhabricatorSQLPatchList {
|
||||||
|
|
||||||
|
public static function getPatchList() {
|
||||||
|
$root = dirname(phutil_get_library_root('phabricator'));
|
||||||
|
|
||||||
|
// Find the patch files
|
||||||
|
$patches_dir = $root.'/resources/sql/patches/';
|
||||||
|
$finder = id(new FileFinder($patches_dir))
|
||||||
|
->withSuffix('sql');
|
||||||
|
$results = $finder->find();
|
||||||
|
|
||||||
|
$patches = array();
|
||||||
|
foreach ($results as $path) {
|
||||||
|
$matches = array();
|
||||||
|
if (preg_match('/(\d+)\..*\.sql$/', $path, $matches)) {
|
||||||
|
$patches[] = array(
|
||||||
|
'version' => (int)$matches[1],
|
||||||
|
'path' => $patches_dir.$path,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw new Exception("Patch file '{$path}' is not properly named.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Files are in some 'random' order returned by the operating system
|
||||||
|
// We need to apply them in proper order
|
||||||
|
$patches = isort($patches, 'version');
|
||||||
|
|
||||||
|
return $patches;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getExpectedSchemaVersion() {
|
||||||
|
$patches = self::getPatchList();
|
||||||
|
$versions = ipull($patches, 'version');
|
||||||
|
$max_version = max($versions);
|
||||||
|
return $max_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
14
src/infrastructure/setup/sql/__init__.php
Normal file
14
src/infrastructure/setup/sql/__init__.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'filesystem/filefinder');
|
||||||
|
phutil_require_module('phutil', 'moduleutils');
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorSQLPatchList.php');
|
|
@ -89,6 +89,11 @@ foreach (PhabricatorEnv::getEnvConfig('load-libraries') as $library) {
|
||||||
phutil_load_library($library);
|
phutil_load_library($library);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PhabricatorEnv::getEnvConfig('phabricator.setup')) {
|
||||||
|
PhabricatorSetup::runSetup();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$host = $_SERVER['HTTP_HOST'];
|
$host = $_SERVER['HTTP_HOST'];
|
||||||
$path = $_REQUEST['__path__'];
|
$path = $_REQUEST['__path__'];
|
||||||
|
|
Loading…
Reference in a new issue