Changeset View
Changeset View
Standalone View
Standalone View
scripts/sql/manage_storage.php
| Show All 28 Lines | array( | ||||
| 'short' => 'f', | 'short' => 'f', | ||||
| 'help' => pht( | 'help' => pht( | ||||
| 'Do not prompt before performing dangerous operations.'), | 'Do not prompt before performing dangerous operations.'), | ||||
| ), | ), | ||||
| array( | array( | ||||
| 'name' => 'host', | 'name' => 'host', | ||||
| 'param' => 'hostname', | 'param' => 'hostname', | ||||
| 'help' => pht( | 'help' => pht( | ||||
| 'Connect to __host__ instead of the default host.'), | 'Operate on the database server identified by __hostname__.'), | ||||
| ), | |||||
| array( | |||||
| 'name' => 'ref', | |||||
| 'param' => 'ref', | |||||
| 'help' => pht( | |||||
| 'Operate on the database identified by __ref__.'), | |||||
| ), | ), | ||||
| array( | array( | ||||
| 'name' => 'user', | 'name' => 'user', | ||||
| 'short' => 'u', | 'short' => 'u', | ||||
| 'param' => 'username', | 'param' => 'username', | ||||
| 'help' => pht( | 'help' => pht( | ||||
| 'Connect with __username__ instead of the configured default.'), | 'Connect with __username__ instead of the configured default.'), | ||||
| ), | ), | ||||
| Show All 30 Lines | |||||
| } catch (PhutilArgumentUsageException $ex) { | } catch (PhutilArgumentUsageException $ex) { | ||||
| $args->printUsageException($ex); | $args->printUsageException($ex); | ||||
| exit(77); | exit(77); | ||||
| } | } | ||||
| // First, test that the Phabricator configuration is set up correctly. After | // First, test that the Phabricator configuration is set up correctly. After | ||||
| // we know this works we'll test any administrative credentials specifically. | // we know this works we'll test any administrative credentials specifically. | ||||
| $host = $args->getArg('host'); | $refs = PhabricatorDatabaseRef::getActiveDatabaseRefs(); | ||||
| if (strlen($host)) { | if (!$refs) { | ||||
| $ref = null; | throw new PhutilArgumentUsageException( | ||||
| pht('No databases are configured.')); | |||||
| $refs = PhabricatorDatabaseRef::getLiveRefs(); | } | ||||
| // Include the master in case the user is just specifying a redundant | $host = $args->getArg('host'); | ||||
| // "--host" flag for no reason and does not actually have a database | $ref_key = $args->getArg('ref'); | ||||
| // cluster configured. | if (strlen($host) || strlen($ref_key)) { | ||||
| foreach (PhabricatorDatabaseRef::getMasterDatabaseRefs() as $master_ref) { | if ($host && $ref_key) { | ||||
| $refs[] = $master_ref; | throw new PhutilArgumentUsageException( | ||||
| pht( | |||||
| 'Use "--host" or "--ref" to select a database, but not both.')); | |||||
| } | } | ||||
| $refs = PhabricatorDatabaseRef::getActiveDatabaseRefs(); | |||||
| $possible_refs = array(); | |||||
| foreach ($refs as $possible_ref) { | foreach ($refs as $possible_ref) { | ||||
| if ($possible_ref->getHost() == $host) { | if ($host && ($possible_ref->getHost() == $host)) { | ||||
| $ref = $possible_ref; | $possible_refs[] = $possible_ref; | ||||
| break; | |||||
| } | |||||
| if ($ref_key && ($possible_ref->getRefKey() == $ref_key)) { | |||||
| $possible_refs[] = $possible_ref; | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| if (!$ref) { | if (!$possible_refs) { | ||||
| if ($host) { | |||||
| throw new PhutilArgumentUsageException( | throw new PhutilArgumentUsageException( | ||||
| pht( | pht( | ||||
| 'There is no configured database on host "%s". This command can '. | 'There is no configured database on host "%s". This command can '. | ||||
| 'only interact with configured databases.', | 'only interact with configured databases.', | ||||
| $host)); | $host)); | ||||
| } | |||||
| } else { | } else { | ||||
| $ref = PhabricatorDatabaseRef::getMasterDatabaseRef(); | throw new PhutilArgumentUsageException( | ||||
| if (!$ref) { | pht( | ||||
| throw new Exception( | 'There is no configured database with ref "%s". This command can '. | ||||
| pht('No database master is configured.')); | 'only interact with configured databases.', | ||||
| $ref_key)); | |||||
| } | } | ||||
| } | } | ||||
| if (count($possible_refs) > 1) { | |||||
| throw new PhutilArgumentUsageException( | |||||
| pht( | |||||
| 'Host "%s" identifies more than one database. Use "--ref" to select '. | |||||
| 'a specific database.', | |||||
| $host)); | |||||
| } | |||||
| $refs = $possible_refs; | |||||
| } | |||||
| $apis = array(); | |||||
| foreach ($refs as $ref) { | |||||
| $default_user = $ref->getUser(); | $default_user = $ref->getUser(); | ||||
| $default_host = $ref->getHost(); | $default_host = $ref->getHost(); | ||||
| $default_port = $ref->getPort(); | $default_port = $ref->getPort(); | ||||
| $test_api = id(new PhabricatorStorageManagementAPI()) | $test_api = id(new PhabricatorStorageManagementAPI()) | ||||
| ->setUser($default_user) | ->setUser($default_user) | ||||
| ->setHost($default_host) | ->setHost($default_host) | ||||
| ->setPort($default_port) | ->setPort($default_port) | ||||
| ->setPassword($ref->getPass()) | ->setPassword($ref->getPass()) | ||||
| ->setNamespace($args->getArg('namespace')); | ->setNamespace($args->getArg('namespace')); | ||||
| try { | try { | ||||
| queryfx( | queryfx( | ||||
| $test_api->getConn(null), | $test_api->getConn(null), | ||||
| 'SELECT 1'); | 'SELECT 1'); | ||||
| } catch (AphrontQueryException $ex) { | } catch (AphrontQueryException $ex) { | ||||
| $message = phutil_console_format( | $message = phutil_console_format( | ||||
| "**%s**\n\n%s\n\n%s\n\n%s\n\n**%s**: %s\n", | "**%s**\n\n%s\n\n%s\n\n%s\n\n**%s**: %s\n", | ||||
| pht('MySQL Credentials Not Configured'), | pht('MySQL Credentials Not Configured'), | ||||
| pht( | pht( | ||||
| 'Unable to connect to MySQL using the configured credentials. '. | 'Unable to connect to MySQL using the configured credentials. '. | ||||
| 'You must configure standard credentials before you can upgrade '. | 'You must configure standard credentials before you can upgrade '. | ||||
| 'storage. Run these commands to set up credentials:'), | 'storage. Run these commands to set up credentials:'), | ||||
| " phabricator/ $ ./bin/config set mysql.host __host__\n". | " phabricator/ $ ./bin/config set mysql.host __host__\n". | ||||
| " phabricator/ $ ./bin/config set mysql.user __username__\n". | " phabricator/ $ ./bin/config set mysql.user __username__\n". | ||||
| " phabricator/ $ ./bin/config set mysql.pass __password__", | " phabricator/ $ ./bin/config set mysql.pass __password__", | ||||
| pht( | pht( | ||||
| 'These standard credentials are separate from any administrative '. | 'These standard credentials are separate from any administrative '. | ||||
| 'credentials provided to this command with __%s__ or '. | 'credentials provided to this command with __%s__ or '. | ||||
| '__%s__, and must be configured correctly before you can proceed.', | '__%s__, and must be configured correctly before you can proceed.', | ||||
| '--user', | '--user', | ||||
| '--password'), | '--password'), | ||||
| pht('Raw MySQL Error'), | pht('Raw MySQL Error'), | ||||
| $ex->getMessage()); | $ex->getMessage()); | ||||
| echo phutil_console_wrap($message); | echo phutil_console_wrap($message); | ||||
| exit(1); | exit(1); | ||||
| } | } | ||||
| if ($args->getArg('password') === null) { | if ($args->getArg('password') === null) { | ||||
| // This is already a PhutilOpaqueEnvelope. | // This is already a PhutilOpaqueEnvelope. | ||||
| $password = $ref->getPass(); | $password = $ref->getPass(); | ||||
| } else { | } else { | ||||
| // Put this in a PhutilOpaqueEnvelope. | // Put this in a PhutilOpaqueEnvelope. | ||||
| $password = new PhutilOpaqueEnvelope($args->getArg('password')); | $password = new PhutilOpaqueEnvelope($args->getArg('password')); | ||||
| PhabricatorEnv::overrideConfig('mysql.pass', $args->getArg('password')); | PhabricatorEnv::overrideConfig('mysql.pass', $args->getArg('password')); | ||||
| } | } | ||||
| $selected_user = $args->getArg('user'); | $selected_user = $args->getArg('user'); | ||||
| if ($selected_user === null) { | if ($selected_user === null) { | ||||
| $selected_user = $default_user; | $selected_user = $default_user; | ||||
| } | } | ||||
| $api = id(new PhabricatorStorageManagementAPI()) | $api = id(new PhabricatorStorageManagementAPI()) | ||||
| ->setUser($selected_user) | ->setUser($selected_user) | ||||
| ->setHost($default_host) | ->setHost($default_host) | ||||
| ->setPort($default_port) | ->setPort($default_port) | ||||
| ->setPassword($password) | ->setPassword($password) | ||||
| ->setNamespace($args->getArg('namespace')) | ->setNamespace($args->getArg('namespace')) | ||||
| ->setDisableUTF8MB4($args->getArg('disable-utf8mb4')); | ->setDisableUTF8MB4($args->getArg('disable-utf8mb4')); | ||||
| PhabricatorEnv::overrideConfig('mysql.user', $api->getUser()); | PhabricatorEnv::overrideConfig('mysql.user', $api->getUser()); | ||||
| try { | try { | ||||
| queryfx( | queryfx( | ||||
| $api->getConn(null), | $api->getConn(null), | ||||
| 'SELECT 1'); | 'SELECT 1'); | ||||
| } catch (AphrontQueryException $ex) { | } catch (AphrontQueryException $ex) { | ||||
| $message = phutil_console_format( | $message = phutil_console_format( | ||||
| "**%s**\n\n%s\n\n**%s**: %s\n", | "**%s**\n\n%s\n\n**%s**: %s\n", | ||||
| pht('Bad Administrative Credentials'), | pht('Bad Administrative Credentials'), | ||||
| pht( | pht( | ||||
| 'Unable to connect to MySQL using the administrative credentials '. | 'Unable to connect to MySQL using the administrative credentials '. | ||||
| 'provided with the __%s__ and __%s__ flags. Check that '. | 'provided with the __%s__ and __%s__ flags. Check that '. | ||||
| 'you have entered them correctly.', | 'you have entered them correctly.', | ||||
| '--user', | '--user', | ||||
| '--password'), | '--password'), | ||||
| pht('Raw MySQL Error'), | pht('Raw MySQL Error'), | ||||
| $ex->getMessage()); | $ex->getMessage()); | ||||
| echo phutil_console_wrap($message); | echo phutil_console_wrap($message); | ||||
| exit(1); | exit(1); | ||||
| } | } | ||||
| $api->setRef($ref); | |||||
| $apis[] = $api; | |||||
| } | |||||
| $workflows = id(new PhutilClassMapQuery()) | $workflows = id(new PhutilClassMapQuery()) | ||||
| ->setAncestorClass('PhabricatorStorageManagementWorkflow') | ->setAncestorClass('PhabricatorStorageManagementWorkflow') | ||||
| ->execute(); | ->execute(); | ||||
| $patches = PhabricatorSQLPatchList::buildAllPatches(); | $patches = PhabricatorSQLPatchList::buildAllPatches(); | ||||
| foreach ($workflows as $workflow) { | foreach ($workflows as $workflow) { | ||||
| $workflow->setAPI($api); | $workflow->setAPIs($apis); | ||||
| $workflow->setPatches($patches); | $workflow->setPatches($patches); | ||||
| } | } | ||||
| $workflows[] = new PhutilHelpArgumentWorkflow(); | $workflows[] = new PhutilHelpArgumentWorkflow(); | ||||
| $args->parseWorkflows($workflows); | $args->parseWorkflows($workflows); | ||||