Commit 11d12e65 authored by Adrian Rossouw's avatar Adrian Rossouw Committed by adrian

More work towards restore functionality. Moved the mysql utility functions to...

More work towards restore functionality. Moved the mysql utility functions to provision_mysql.inc, and the help stuff to it's own include too.

Made more constants to replace the various helper functions, still need to document them.

Replaced all references to db_username with db_user, which is consistent with everywhere else in the system.
parent 3872c8a5
......@@ -6,7 +6,10 @@
* The goal of this module is to create mysql databases and user accounts, for sites that are about to be created.
* It uses the provision API to tie into the right places in the site creation work flow.
*/
include_once('provision_mysql.inc');
/**
* @ingroup provisionui
* @{
......@@ -18,7 +21,7 @@
function provision_mysql_help($section) {
switch ($section) {
case 'admin/help/provision#requirements':
$username = provision_get_script_owner();
$username = PROVISION_SCRIPT_USER;
$output .= "<ol>";
$command = <<<EOF
[$username@hm2 ~]$ mysql -uroot -pXXXXXXXXX mysql
......@@ -55,14 +58,14 @@ function provision_mysql_provision_configure($node = null) {
if (!is_object($node) && ($nid = variable_get('hosting_own_db_server', 0))) {
$node = node_load($nid);
}
$form['db_type'] = array('#type' => 'hidden', '#value' => ($node->db_type) ? $node->db_type : 'mysqli');
$form['db_type'] = array('#type' => 'hidden', '#value' => ($node->db_type) ? $node->db_type : PROVISION_DB_TYPE);
$form['db_host'] = array(
'#type' => 'textfield',
'#title' => t('Mysql server hostname'),
'#description' => t('The mysql server to connect to.'),
'#size' => 30,
'#default_value' => ($node->db_host) ? $node->db_host : variable_get('provision_db_host', 'localhost'),
'#default_value' => ($node->db_host) ? $node->db_host : PROVISION_DB_HOST,
'#maxlength' => 64,
);
......@@ -72,7 +75,7 @@ function provision_mysql_provision_configure($node = null) {
'#title' => t('Mysql user account'),
'#description' => t('The user that will be used to create users and databases for new sites.'),
'#size' => 40,
'#default_value' => ($node->db_user) ? $node->db_user : variable_get('provision_db_user', 'root'),
'#default_value' => ($node->db_user) ? $node->db_user : PROVISION_DB_USER,
'#maxlength' => 255,
);
if ($node->db_passwd) {
......@@ -80,7 +83,7 @@ function provision_mysql_provision_configure($node = null) {
}
$form['db_passwd'] = array(
'#type' => 'password_confirm',
'#required' => (variable_get("provision_db_password", TRUE)) ? FALSE : TRUE,
'#required' => (PROVISION_DB_PASSWD) ? FALSE : TRUE,
'#title' => t('Mysql user password'),
'#description' => $passwd_description . t('The user account that will be used to create new mysql users and databases for new sites'),
'#size' => 30,
......@@ -94,43 +97,40 @@ function provision_mysql_provision_configure($node = null) {
function provision_mysql_provision_pre_install($url, &$data) {
$data['site_db_type'] = ($data['site_db_type']) ? $data['site_db_type'] : 'mysql'; # only support innodb. for now.
$data['site_db_host'] = ($data['site_db_host']) ? $data['site_db_host'] : variable_get('provision_db_host', 'localhost');
$data['site_db_passwd'] = user_password(); # generate a random password for use
if ($data['site_id']) {
$data['site_db_name'] = 'site_' . $data['site_id'];
$data['site_db_username'] = $data['site_db_name']; // mysql has some really really stupid rules about who db / usernames, so site id is the safest.
}
else {
$data['site_db_name'] = ereg_replace("^www\.", "", str_replace('-', '_', str_replace(".", "", $url)));
$data['site_db_username'] = substr($data['site_db_name'], 0, 16);
}
$data['site_db_type'] = ($data['site_db_type']) ? $data['site_db_type'] : PROVISION_DB_TYPE;
$data['site_db_host'] = ($data['site_db_host']) ? $data['site_db_host'] : PROVISION_DB_HOST;
provision_set_active_db(_provision_master_db_url());
if ( _provision_mysql_database_exists($data['site_db_name']) ) {
_provision_mysql_drop_database($data['site_db_name']);
}
_provision_mysql_create_database($data['site_db_name']);
if ( !_provision_mysql_database_exists($data['site_db_name']) ) {
provision_set_error(PROVISION_DB_ERROR);
provision_log("error", "Database could not be created.");
provision_set_active_db();
return FALSE;
# generate a random password for use
$data['site_db_passwd'] = user_password();
$data['site_db_name'] = _provision_mysql_suggest_db_name($url, $data);
$data['site_db_user'] = $data['site_db_name'];
return _provision_mysql_new_site_db($data['site_db_name'], $data['site_db_user'], $data['site_db_passwd'], $data['site_db_host']);
}
function provision_mysql_provision_pre_restore($url, $backup_file, &$data) {
// store a backup of the credentials of the site.
$keys = array('site_db_name', 'site_db_passwd', 'site_db_user', 'site_db_host');
foreach ($keys as $key) {
$data['old_' . $key] = $data[$key];
}
_provision_mysql_grant($data['site_db_name'], $data['site_db_username'], $data['site_db_passwd']);
_provision_mysql_grant($data['site_db_name'], $data['site_db_username'], $data['site_db_passwd'], $data['site_db_host']);
if ($data['site_mysql_old_passwords']) {
_provision_mysql_old_password($data['site_db_username'], $data['site_db_passwd']);
_provision_mysql_old_password($data['site_db_username'], $data['site_db_passwd'], $data['site_db_host']);
# generate a random password for use
$data['site_db_passwd'] = user_password();
$data['site_db_name'] = _provision_mysql_suggest_db_name($url, $data);
$data['site_db_user'] = $data['site_db_name'];
$success = _provision_mysql_new_site_db($data['site_db_name'], $data['site_db_user'], $data['site_db_passwd'], $data['site_db_host']);
if (!$success) {
// store a backup of the credentials of the site.
foreach ($keys as $key) {
$data[$key] = $data['old_' . $key];
}
return false; # i really really need to dust up on my rollback code.
}
_provision_mysql_flush();
provision_set_active_db();
#TODO : Test to confirm that the database is actually writeable. Taking this on faith for now.
_provision_mysql_import_dump($url, $data);
}
/**
......@@ -139,89 +139,20 @@ function provision_mysql_provision_pre_install($url, &$data) {
* This will drop the database, revoke the privileges and flush the privileges.
*/
function provision_mysql_provision_delete($url, &$data) {
$data['site_db_host'] = ($data['site_db_host']) ? $data['site_db_host'] : variable_get('provision_db_host', 'localhost');
if ($data['site_id']) {
$data['site_db_name'] = 'site_' . $data['site_id'];
$data['site_db_username'] = $data['site_db_name']; // mysql has some really really stupid rules about who db / usernames, so site id is the safest.
}
else {
$data['site_db_name'] = ereg_replace("^www\.", "", str_replace('-', '_', str_replace(".", "", $url)));
$data['site_db_username'] = substr($data['site_db_name'], 0, 16);
}
provision_set_active_db(_provision_master_db_url());
if ( _provision_mysql_database_exists($data['site_db_name']) ) {
provision_log("notice", "Dropping database");
_provision_mysql_drop_database($data['site_db_name']);
}
if ( _provision_mysql_database_exists($data['site_db_name']) ) {
provision_set_error(PROVISION_DB_ERROR);
provision_log("error", "Database could not be destroyed.");
provision_set_active_db();
return FALSE;
}
provision_log("notice", "Revoking privileges");
_provision_mysql_revoke($data['site_db_name'], $data['site_db_username']);
_provision_mysql_revoke($data['site_db_name'], $data['site_db_username'], $data['site_db_host']);
return _provision_mysql_destroy_site_db($data['site_db_name'], $data['db_user'], $data['db_passwd'], $data['db_host']);
}
_provision_mysql_flush();
provision_set_active_db();
function provision_mysql_provision_post_restore($url, &$data) {
return _provision_mysql_destroy_site_db($data['old_site_db_name'], $data['old_db_user'], $data['old_db_passwd'], $data['old_db_host']);
}
function provision_mysql_provision_backup($url, &$data) {
provision_log("backup", "Generating mysql dump for $url.");
provision_shell_exec("mysqldump -u%s -p%s %s > sites/%s/database.sql", $data['site_db_username'], $data['site_db_passwd'], $data['site_db_name'], $url);
provision_shell_exec("mysqldump -u%s -p%s %s > sites/%s/database.sql", $data['site_db_user'], $data['site_db_passwd'], $data['site_db_name'], $url);
provision_shell_exec("cd sites/%; tar -rf %s database.sql; rm database.sql", $url, $data['backup_file']);
}
function _provision_mysql_database_exists($name) {
return db_result(db_query("SHOW DATABASES LIKE '%s'", $name));
}
function _provision_mysql_drop_database($name) {
db_query("DROP DATABASE `%s`", $name);
}
function _provision_mysql_create_database($name) {
db_query("CREATE DATABASE %s", $name);
}
function _provision_mysql_can_create_database() {
$test = 'provision_test';
_provision_mysql_create_database($test);
if (_provision_mysql_database_exists($test)) {
_provision_mysql_drop_database($test);
return true;
}
return false;
}
function _provision_mysql_grant($name, $username, $password, $host = '') {
$host = ($host) ? $host : '%';
db_query("GRANT ALL PRIVILEGES ON %s.* TO %s@`%s` IDENTIFIED BY '%s'", $name, $username, $host, $password);
}
function _provision_mysql_revoke($name, $username, $host = '') {
$host = ($host) ? $host : '%';
db_query("REVOKE ALL PRIVILEGES ON %s.* FROM %s@`%s`", $name, $username, $host);
}
function _provision_mysql_old_password($username, $password, $host = '') {
$host = ($host) ? $host : '%';
db_query("SET PASSWORD FOR '%s'@'%s' = OLD_PASSWORD('%s')", $username, $host, $password);
}
function _provision_mysql_flush() {
db_query("FLUSH PRIVILEGES");
}
function _provision_master_db_url($data = array()) {
return sprintf("%s://%s:%s@%s/mysql", variable_get('provision_db_type', 'mysqli'), variable_get('provision_db_user', 'root'), variable_get('provision_db_passwd', 'root'), variable_get('provision_db_host', 'localhost'));
}
/**
* Implementation of hook_provision_verify
*/
......@@ -237,11 +168,7 @@ function provision_mysql_provision_verify() {
provision_set_active_db();
}
function provision_mysql_pre_restore($url, $backup_file, &$data) {
}
function provision_mysql_import_dump($url, $backup_file, &$data) {
}
......@@ -128,7 +128,7 @@ function _provision_drupal_create_settings_file($url, &$data) {
# Change the permissions of the file
provision_path("chmod", "sites/$url/settings.php", 0550);
provision_path("chgrp", "sites/$url/settings.php", provision_get_group_name());
provision_path("chgrp", "sites/$url/settings.php", PROVISION_WEB_GROUP);
}
/**
......@@ -154,11 +154,11 @@ function _provision_drupal_create_directories($url, $profile = null) {
t("Could not create <code>@path</code>"),
PROVISION_PERM_ERROR | PROVISION_INSTALL_ERROR );
}
provision_path("chown", $path, provision_get_script_owner(),
provision_path("chown", $path, PROVISION_SCRIPT_USER,
t("Changed ownership of <code>@path</code>"),
t("Could not change ownership <code>@path</code>"),
PROVISION_PERM_ERROR | PROVISION_INSTALL_ERROR );
provision_path("chgrp", $path, provision_get_group_name(),
provision_path("chgrp", $path, PROVISION_WEB_GROUP,
t("Changed group ownership of <code>@path</code>"),
t("Could not change group ownership <code>@path</code>"));
......
$db_url = '<?php print "$site_db_type://$site_db_username:$site_db_passwd@$site_db_host/$site_db_name"; ?>';
$db_url = '<?php print "$site_db_type://$site_db_user:$site_db_passwd@$site_db_host/$site_db_name"; ?>';
$profile = "<?php print $site_profile ?>";
# Additional host wide configuration settings. Useful for safely specifying configuration settings.
......
<?php
/**
* @file ProvisionHelp contains the bulk of the provision help system
*/
/**
* Implementation of hook_help()
*/
function provision_help($section) {
switch ($section) {
case 'admin/help#provision':
$output .= t('<p>The Provision framework is a powerful set of modules that lets you to accomplish a lot of maintenance tasks through the unix command line such as installing new sites, backing them up, rolling back to previous backups and facilitating upgrades.</p>');
$output .= t('<p>Additionally, the Provision framework is one component of the distributed hosting infrastructure provided by the <code>hostmaster</code> install profile.
The Hostmaster profile is capable of driving several provision backends, in a distributed manner, and provides an interface for the functionality of provision.</p>');
$output .= t('<p>It is not required to run the hosting front end to use the Provision framework, but the system does not provide much in the way of a web accessible front end, by design.</p>');
$output .= '<a name=\'requirements\'><h3>' . t('Requirements') . '</h3></a>';
$output .= t('<p>For a more detailed breakdown of steps that need to be taken to configure Provisioning to run with your system, please read the <a href="@url">in depth requirement documentation</a></p>',
array('@url' => url('admin/help/provision/requirements')));
$output .= '<a name=\'commands\'><h3>' . t('Commands') . '</h3></a>';
$commands = module_invoke_all('drush_command');
$output .= "<dl>";
foreach ($commands as $command => $info) {
if (preg_match('/^provision/', $command)) {
if (sizeof($info['arguments'])) {
$command .= ' ' . implode(' ', (array) key($info['arguments']));
}
if (sizeof($info['optional arguments'])) {
$command .= ' [' . implode('] [', (array) key($info['optional arguments'])) . ']';
}
$output .= '<dt>' . "<code>drush.php $command</code>" . '</dt>';
$output .= '<dd>' . $info["description"] . '</dd>';
}
}
$output .= "</dl>";
$output .= '<a name=\'options\'><h3>' . t('Options') . '</h3></a>';
$options = module_invoke_all('value_list');
$output .= "<dl>";
foreach ($options as $option => $description) {
$output .= '<dt>' . "<code>--$option</code>" . '</dt>';
$output .= '<dd>' . $description . '</dd>';
}
$output .= "</dl>";
return $output;
case 'admin/help/provision#requirements' :
$username = PROVISION_SCRIPT_USER;
$group = PROVISION_WEB_GROUP;
$backup_path = PROVISION_BACKUP_PATH;
$mkdir_cmd['@backup_path'] = $backup_path;
$mkdir_cmd['@provision_link'] = url('admin/settings/provision');
$mkdir_cmd['@mkdir_cmd'] = <<<EOF
[$username@hm2 ~]$ mkdir $backup_path
[$username@hm2 ~]$ chown $username:$username $backup_path
[$username@hm2 ~]$ chmod 0700 $backup_path
EOF;
$output .= "<ol>";
$output .= '<li>' . t('<p><strong>The user account running the script, and the group of the httpd daemon.</strong>
The provision framework takes special care to make sure that the file permissions of the
hosted sites are always as safe as can be, especially to make sure that the web server does
not have the ability to modify the code of the site, therefor this information is required
to assure that safety while keeping the sites accessible.</p>
<p>Based on your server configuration we have determined that you should set the
username to "<code>@username</code>" and the group to "<code>@group</code>",
but you can change these in the <a href="@provision_link">provisioning section</a>.</p>', array("@username" => $username, "@group" => $group, "@provision_link" => url('admin/settings/provision'))) . '</li>';
$output .= '<li>' . t('<p><strong>Write access to a directory to store backups.</strong>
The drush user needs to be able to maintain the backups repository to ensure that your site is backed up successfully.
It is incredibly important that this path is not accessible via the web server, so that no undesirables can get their
hands on your database. The recommended path is directly above your platform path, but it can be anywhere.</p>
<p>Based on your server configuration we have determined that your path should be <code>@backup_path</code>,
but you can change this in the <a href="@provision_link">provisioning section</a>.</p>
<strong>To configure: </strong> Please enter the following commands :
<pre>@mkdir_cmd</pre>',$mkdir_cmd) . '</li>';
$output .= "</ol>";
return $output;
}
}
/**
* Page callback with in depth requirement documentation
*/
function provision_help_requirements() {
$output .= t('<p>Unfortunately, due to the requirements of some of the functionality, significantly more access than is usually allowed on a shared hosting solution is required,
and as such, a virtual server or dedicated hosting system will be required to run this system.</p>');
$output .= t('<p>Some of the features of the system also require the ability to create symlinks, which means that it needs to run on a unix-like operating system. There are no plans currently to add windows support.</p>');
$modules = module_implements('provision_service');
foreach ($modules as $module) {
$service = module_invoke($module, 'provision_service');
$name = current($service);
$help = module_invoke($module, 'help', 'admin/help/provision#requirements');
if ($name && $help) {
$output .= '<a href="requirements-$module"></a><h3>' . t($name) . '</h3>';
$output .= $help;
}
}
return $output;
}
......@@ -316,13 +316,12 @@ function provision_save_site_data($url, $data) {
provision_set_error(PROVISION_PERM_ERROR);
}
else {
fwrite($fp, "\n\n#" . format_date(mktime(), "large"));
if ($data['action_id']) {
$action = array('id' => $data['action_id'],
'timestamp' => mktime(),
'action' => $data['site_action_type'],
'status' => provision_get_error());
$line = "\n\$actions[] = " . str_replace(array(" ", "\n"), "", var_export($action, TRUE)) . ";";
$timestamp = mktime();
$aid = $data['action_id'];
fwrite($fp, "\n\n#" . format_date($timestamp, "large"));
if ($aid) {
$action = array('action' => $data['site_action_type'], 'status' => provision_get_error());
$line = "\n\$actions[$aid][$timestamp] = " . str_replace(array(" ", "\n"), "", var_export($action, TRUE)) . ";";
fwrite($fp, $line);
}
foreach ($data as $key => $value) {
......@@ -385,31 +384,6 @@ function provision_render_config($template, $variables) {
* @} End of "defgroup provisionvalues".
*/
/**
* Provide defines for all the major paths.
* Avoids duplication and possible errors in duplication
*/
function provision_init_paths() {
if (function_exists('drush_get_option')) {
$docroot = drush_get_option(array("r", "root"), $_SERVER['PWD']);
}
else {
$docroot = $_SERVER['pwd'];
}
$path = ($docroot) ? $docroot : $_SERVER['DOCUMENT_ROOT'];
define('PROVISION_DOCROOT_PATH', rtrim($path, '/'));
define('PROVISION_SITES_PATH', rtrim($path, '/'));
$parts = explode("/", rtrim($path, '/'));
array_pop($parts);
define('PROVISION_BACKUP_PATH', rtrim(variable_get('provision_backup_path', implode("/" , $parts) . '/backups'), '/'));
define('PROVISION_CONFIG_PATH', rtrim(variable_get('provision_config_path', implode("/" , $parts) . '/config'), '/')) ;
define('PROVISION_VHOST_PATH', PROVISION_CONFIG_PATH . '/vhost.d');
define('PROVISION_DRUSHRC_PATH', PROVISION_CONFIG_PATH . '/drushrc.d');
}
/**
* Remove files or directories, recursively
......@@ -487,26 +461,6 @@ function provision_set_active_db($new_db_url = null) {
db_set_active('default');
}
}
/**
* Return the user who owns this script.
*
* Used to generate permissions. Can be overridden by variable_set().
*/
function provision_get_script_owner() {
return variable_get('provision_script_user', get_current_user());
}
/**
* Return the group who runs the httpd daemin.
*
* Used to generate permissions. Can be overridden by variable_set().
*/
function provision_get_group_name() {
$info = posix_getgrgid(posix_getgid());
return variable_get('provision_web_group', $info['name']);
}
/**
* Check whether a user is a member of a group.
*
......
......@@ -36,16 +36,51 @@
// Include the provisioning API.
include_once('provision.inc');
include_once('provision.path.inc');
include_once('provision.help.inc');
/**
* Implementation of hook_init
*
* Provide defines for all the major paths and settings.
* These are settings that must not be modified during the running of the
* program, but are configurable.
*/
function provision_init() {
// Set up defines for platform
provision_init_paths();
if (function_exists('drush_get_option')) {
$docroot = drush_get_option(array("r", "root"), $_SERVER['PWD']);
}
else {
$docroot = $_SERVER['pwd'];
}
$path = ($docroot) ? $docroot : $_SERVER['DOCUMENT_ROOT'];
define('PROVISION_DOCROOT_PATH', rtrim($path, '/'));
define('PROVISION_SITES_PATH', rtrim($path, '/'));
$parts = explode("/", rtrim($path, '/'));
array_pop($parts);
define('PROVISION_PARENT_PATH', rtrim(implode("/" , $parts), '/'));
define('PROVISION_BACKUP_PATH', variable_get('provision_backup_path', PROVISION_PARENT_PATH . '/backups'));
define('PROVISION_CONFIG_PATH', variable_get('provision_config_path', PROVISION_PARENT_PATH . '/config')) ;
define('PROVISION_VHOST_PATH', PROVISION_CONFIG_PATH . '/vhost.d');
define('PROVISION_DRUSHRC_PATH', PROVISION_CONFIG_PATH . '/drushrc.d');
define('PROVISION_SCRIPT_USER', variable_get('provision_script_user', get_current_user()));
$info = posix_getgrgid(posix_getgid());
define('PROVISION_WEB_GROUP', variable_get('provision_web_group', $info['name']));
define('PROVISION_DB_TYPE', variable_get('provision_db_type', 'mysqli'));
define('PROVISION_DB_USER', variable_get('provision_db_user', 'root'));
define('PROVISION_DB_PASSWD', variable_get('provision_db_passwd', 'root'));
define('PROVISION_DB_HOST', variable_get('provision_db_host', 'localhost'));
}
/**
* Implementation of hook_provision_service
*/
......@@ -108,106 +143,7 @@ function provision_menu($may_cache = true) {
return $items;
}
/**
* Implementation of hook_help()
*/
function provision_help($section) {
switch ($section) {
case 'admin/help#provision':
$output .= t('<p>The Provision framework is a powerful set of modules that lets you to accomplish a lot of maintenance tasks through the unix command line such as installing new sites, backing them up, rolling back to previous backups and facilitating upgrades.</p>');
$output .= t('<p>Additionally, the Provision framework is one component of the distributed hosting infrastructure provided by the <code>hostmaster</code> install profile.
The Hostmaster profile is capable of driving several provision backends, in a distributed manner, and provides an interface for the functionality of provision.</p>');
$output .= t('<p>It is not required to run the hosting front end to use the Provision framework, but the system does not provide much in the way of a web accessible front end, by design.</p>');
$output .= '<a name=\'requirements\'><h3>' . t('Requirements') . '</h3></a>';
$output .= t('<p>For a more detailed breakdown of steps that need to be taken to configure Provisioning to run with your system, please read the <a href="@url">in depth requirement documentation</a></p>',
array('@url' => url('admin/help/provision/requirements')));
$output .= '<a name=\'commands\'><h3>' . t('Commands') . '</h3></a>';
$commands = module_invoke_all('drush_command');
$output .= "<dl>";
foreach ($commands as $command => $info) {
if (preg_match('/^provision/', $command)) {
if (sizeof($info['arguments'])) {
$command .= ' ' . implode(' ', (array) key($info['arguments']));
}
if (sizeof($info['optional arguments'])) {
$command .= ' [' . implode('] [', (array) key($info['optional arguments'])) . ']';
}
$output .= '<dt>' . "<code>drush.php $command</code>" . '</dt>';
$output .= '<dd>' . $info["description"] . '</dd>';
}
}
$output .= "</dl>";
$output .= '<a name=\'options\'><h3>' . t('Options') . '</h3></a>';
$options = module_invoke_all('value_list');
$output .= "<dl>";
foreach ($options as $option => $description) {
$output .= '<dt>' . "<code>--$option</code>" . '</dt>';
$output .= '<dd>' . $description . '</dd>';
}
$output .= "</dl>";
return $output;
case 'admin/help/provision#requirements' :
$username = provision_get_script_owner();
$group = provision_get_group_name();
$backup_path = PROVISION_BACKUP_PATH;
$mkdir_cmd['@backup_path'] = $backup_path;
$mkdir_cmd['@provision_link'] = url('admin/settings/provision');
$mkdir_cmd['@mkdir_cmd'] = <<<EOF
[$username@hm2 ~]$ mkdir $backup_path
[$username@hm2 ~]$ chown $username:$username $backup_path
[$username@hm2 ~]$ chmod 0700 $backup_path
EOF;
$output .= "<ol>";
$output .= '<li>' . t('<p><strong>The user account running the script, and the group of the httpd daemon.</strong>
The provision framework takes special care to make sure that the file permissions of the
hosted sites are always as safe as can be, especially to make sure that the web server does
not have the ability to modify the code of the site, therefor this information is required
to assure that safety while keeping the sites accessible.</p>
<p>Based on your server configuration we have determined that you should set the
username to "<code>@username</code>" and the group to "<code>@group</code>",
but you can change these in the <a href="@provision_link">provisioning section</a>.</p>', array("@username" => $username, "@group" => $group, "@provision_link" => url('admin/settings/provision'))) . '</li>';
$output .= '<li>' . t('<p><strong>Write access to a directory to store backups.</strong>
The drush user needs to be able to maintain the backups repository to ensure that your site is backed up successfully.
It is incredibly important that this path is not accessible via the web server, so that no undesirables can get their
hands on your database. The recommended path is directly above your platform path, but it can be anywhere.</p>
<p>Based on your server configuration we have determined that your path should be <code>@backup_path</code>,
but you can change this in the <a href="@provision_link">provisioning section</a>.</p>
<strong>To configure: </strong> Please enter the following commands :
<pre>@mkdir_cmd</pre>',$mkdir_cmd) . '</li>';
$output .= "</ol>";
return $output;
}
}
/**
* Page callback with in depth requirement documentation
*/
function provision_help_requirements() {
$output .= t('<p>Unfortunately, due to the requirements of some of the functionality, significantly more access than is usually allowed on a shared hosting solution is required,
and as such, a virtual server or dedicated hosting system will be required to run this system.</p>');
$output .= t('<p>Some of the features of the system also require the ability to create symlinks, which means that it needs to run on a unix-like operating system. There are no plans currently to add windows support.</p>');
$modules = module_implements('provision_service');
foreach ($modules as $module) {
$service = module_invoke($module, 'provision_service');
$name = current($service);
$help = module_invoke($module, 'help', 'admin/help/provision#requirements');
if ($name && $help) {
$output .= '<a href="requirements-$module"></a><h3>' . t($name) . '</h3>';
$output .= $help;
}
}
return $output;
}