Commit 83f57f6e authored by Adrian Rossouw's avatar Adrian Rossouw Committed by adrian

In progress commit. Remove dependency on date module. Lots of help additions....

In progress commit. Remove dependency on date module. Lots of help additions. Added verify step so the back end (mostly) configures itself. Switched templating to use php instead of tokens (needed loops in templates). Turned options to use underscore instead of dash for separation (now consistent). Lots of validation and logging, including strict permission checking.
parent 6d99b240
This diff is collapsed.
This diff is collapsed.
......@@ -92,14 +92,15 @@ function provision_apache_provision_configure() {
'#rows' => 5,
);
$default_path = variable_get('provision_root', ereg_replace("/webroot$", "", $_SERVER['DOCUMENT_ROOT'])) . '/vhost.d';
$form['provision_apache_vhost_path'] = array(
$default_path = variable_get('provision_config_path', ereg_replace("/webroot$", "", $_SERVER['DOCUMENT_ROOT'])) . '/config';
$form['provision_apache_config_path'] = array(
'#type' => 'textfield',
'#title' => t('Path to the directory to store apache configuration files for hosted sites'),
'#title' => t('Path to the directory to store configuration files for hosted sites.'),
'#size' => 40,
'#default_value' => variable_get('provision_apache_vhost_path', $default_path),
'#default_value' => variable_get('provision_config_path', $default_path),
'#maxlength' => 255,
);
$form['provision_apache_restart_cmd'] = array(
'#type' => 'textfield',
'#title' => t('Apache restart command'),
......@@ -116,21 +117,7 @@ function provision_apache_provision_configure() {
* The default template provided for the virtual host configuration
*/
function _provision_apache_default_template() {
return <<<EOF
<VirtualHost *:80>
ServerAdmin [site-email]
DocumentRoot [site-document-root]
ServerName [site-url]
ServerAlias [site-temporary-url]
ServerAlias www.[site-url]
# Error handler for Drupal > 4.6.7
<Directory "[site-document-root]/sites/[site-url]/files">
SetHandler This_is_a_Drupal_security_line_do_not_remove
</Directory>
</VirtualHost>
EOF;
return file_get_contents(drupal_get_path('module', 'provision_apache') . "/templates/apache_vhost.tpl.php");
}
/**
......@@ -176,10 +163,7 @@ function provision_apache_provision_disable($url, &$data) {
/**
* Implementation of hook_provision_sync
*/
function provision_apache_provision_sync($url, &$data) {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
function provision_apache_provision_synch($url, &$data) {
_provision_apache_create_vhost_config($url, $data);
_provision_apache_restart_apache();
}
......@@ -188,42 +172,30 @@ function provision_apache_provision_sync($url, &$data) {
* Delete virtual host file
*/
function _provision_apache_delete_vhost_config($url, $data) {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
$vhost_path = variable_get('provision_apache_vhost_path', 'vhost.d');
if (file_exists()) {
unlink($vhost_path . '/' . $url);
}
provision_check_path(_provision_vhost_path() . "/$url", "unlink", true,
t("Removed apache virtual host configuration"));
}
/**
* Generate virtual host file
*/
function _provision_apache_create_vhost_config($url, $data) {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
$vhost_path = variable_get('provision_apache_vhost_path', 'vhost.d');
$file = fopen($vhost_path . '/' . $url, "w");
if (!$file) {
provision_log("error", "Could not create apache configuration file.");
provision_set_error(PROVISION_WEB_ERROR | PROVISION_PERM_ERROR);
return false;
}
$text = token_replace(variable_get('provision_apache_vhost_template', _provision_apache_default_template()) , 'site', $data);
fwrite($file, $text);
fclose($file);
$writable = provision_check_path(_provision_vhost_path(), "writable", true ,
t("Virtual host configuration path is writable."),
t("Virtual host configuration path is not writable."),
PROVISION_PERM_ERROR | PROVISION_FRAMEWORK_ERROR);
if ($writable) {
$file = fopen(_provision_vhost_path() . '/' . $url, "w");
$text = provision_render_config(variable_get('provision_apache_vhost_template', _provision_apache_default_template()), $data);
fwrite($file, $text);
fclose($file);
}
}
/**
* Restart Apache
*/
function _provision_apache_restart_apache() {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
# This is required to be configurable, due to the fact that different hosts might need to do this differently.
# TODO : add configuration / test for this
$apache_restart_cmd = escapeshellcmd(variable_get('provision_apache_restart_cmd', 'sudo apachectl graceful'));
......@@ -233,3 +205,32 @@ function _provision_apache_restart_apache() {
provision_log("error", "Web server could not be restarted. Changes might not be available until this has been done.");
}
}
function provision_apache_provision_verify() {
$path = _provision_vhost_path();
$exists = provision_check_path($path, "exists", true ,
t("Virtual Host configuration path exists."),
t("Virtual Host configuration path does not exist."));
if (!$exists) {
$made = provision_check_path($path, "mkdir", true,
t("Virtual host configuration path has been created."),
t("Virtual host configuration path could not be created."),
PROVISION_PERM_ERROR | PROVISION_FRAMEWORK_ERROR);
}
else {
$writable = provision_check_path($path, "writable", true ,
t("Virtual host configuration path is writable."),
t("Virtual host configuration path is not writable."),
PROVISION_PERM_ERROR | PROVISION_FRAMEWORK_ERROR);
if (!$writable) {
provision_check_path($path, "chown", provision_get_script_owner(),
t("Changed ownership of <code>%path</code>", array("%path" => $path)),
t("Could not change ownership <code>%path</code>", array("%path" => $path)),
PROVISION_PERM_ERROR);
provision_check_path($path, "chmod", 0700,
t("Changed permissions of <code>%path</code> to %perms", array("%path" => $path, '%perms' => 0700)),
t("Could not change ownership <code>%path</code> to %perms", array("%path" => $path, '%perms' => 0700)),
PROVISION_PERM_ERROR );
}
}
}
......@@ -102,17 +102,7 @@ function provision_drupal_provision_backup($url, $data) {
* The default template for the config file
*/
function _provision_drupal_default_template() {
return <<<END
<?php
\$db_url = "[site-db-type]://[site-db-username]:[site-db-passwd]@[site-db-host]/[site-db-name]";
\$profile = "[site-profile]";
# Additional host wide configuration settings. Useful for safely specifying configuration settings.
if (file_exists('includes/global.inc')) {
include_once('includes/global.inc');
}
?>
END;
return file_get_contents(drupal_get_path('module', 'provision_drupal') . '/templates/drupal_settings.tpl.php');
}
/**
......@@ -125,19 +115,16 @@ END;
* because the modules might provide additional information about the site.
*/
function _provision_drupal_create_settings_file($url, &$data) {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
$fp = fopen("sites/$url/settings.php", "w");
$text = variable_get('provision_settings_template', _provision_drupal_default_template());
fwrite($fp, token_replace($text, 'site', $data));
$text = variable_get('provision_drupal_settings_template', _provision_drupal_default_template());
fwrite($fp, "<?php\n" . provision_render_config($text, $data));
fclose($fp);
# Change the ownership of the file
#chown($path, variable_get('provision_user', 'hosting'), variable_get('provision_group', 'apache'));
# Change the permissions of the file
# system("chmod 0550 sites/$url/settings.php");
system("chmod 0550 sites/$url/settings.php");
# TODO: add md5 of the file created to $data
}
......@@ -146,31 +133,37 @@ function _provision_drupal_create_settings_file($url, &$data) {
*
* Also maintains permissions on existing directories.
*/
function _provision_drupal_create_directories($url, $profile = null) {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
function _provision_drupal_create_directories($url, $profile = null) {
$paths = array(
"sites/$url" => '0750',
"sites/$url/files" => '2750',
"sites/$url/files/tmp" => '2770',
"sites/$url/files/images" => '2770',
"sites/$url/files/pictures" => '2770',
"sites/$url/themes" => '2750',
"sites/$url/modules" => '2750',
"sites/$url" => 0750,
"sites/$url/files" => 2750,
"sites/$url/files/tmp" => 2770,
"sites/$url/files/images" => 2770,
"sites/$url/files/pictures" => 2770,
"sites/$url/themes" => 2750,
"sites/$url/modules" => 2750,
);
foreach ($paths as $path => $perm) {
if (!is_dir($path)) {
mkdir($path);
provision_check_path($path, "mkdir", true,
t("Created <code>%path</code>", array("%path" => $path)),
t("Could not create <code>%path</code>", array("%path" => $path)),
PROVISION_PERM_ERROR | PROVISION_INSTALL_ERROR );
}
# Change the ownership of the files so that they are owned by the user the script is running as, and the
# web server has access to them.
# chown($path, variable_get('provision_user', 'hosting'), variable_get('provision_group', 'apache'));
# Change the permissions to the optimal settings that were specified.
# system("chmod $perm $path");
provision_check_path($path, "chown", provision_get_script_owner(),
t("Changed ownership of <code>%path</code>", array("%path" => $path)),
t("Could not change ownership <code>%path</code>", array("%path" => $path)),
PROVISION_PERM_ERROR | PROVISION_INSTALL_ERROR );
provision_check_path($path, "chgrp", provision_get_group_name(),
t("Changed group ownership of <code>%path</code>", array("%path" => $path)),
t("Could not change group ownership <code>%path</code>", array("%path" => $path)),
PROVISION_PERM_ERROR | PROVISION_INSTALL_ERROR );
provision_check_path($path, "chmod", $perm,
t("Changed permissions of <code>%path</code> to %perms", array("%path" => $path, '%perms' => $perms)),
t("Could not change ownership <code>%path</code> to %perms", array("%path" => $path, '%perms' => $perms)),
PROVISION_PERM_ERROR | PROVISION_INSTALL_ERROR );
}
}
......@@ -183,9 +176,6 @@ function _provision_drupal_create_directories($url, $profile = null) {
* main provisioning site.
*/
function _provision_drupal_switch_active_site($url = null) {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
static $backups;
if ($url) {
/* Pretend to be the site being installed */
......@@ -257,9 +247,6 @@ function _provision_drupal_switch_active_site($url = null) {
* Force drupal to load the modules it expects to find on an uninstalled site
*/
function _provision_drupal_force_load_modules($url = null) {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
static $backup_list;
if ($url) {
$backup_list = module_list();
......@@ -284,9 +271,6 @@ function _provision_drupal_force_load_modules($url = null) {
* Install the drupal schema and install profile
*/
function _provision_drupal_install_schema($profile) {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
// Load the profile.
require_once "./profiles/$profile/$profile.profile";
......@@ -325,8 +309,32 @@ function _provision_drupal_install_schema($profile) {
/**
* implementation of provision_verify
*/
function provision_drupal_provision_verify() {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
function provision_drupal_provision_verify($url, &$data) {
provision_check_path("sites", "writable", true, t("Drupal sites directory is writable by the provisioning script"),
t("Drupal sites directory is not writable by the provisioning script"), PROVISION_PERM_ERROR);
$path = _provision_drushrc_path();
$exists = provision_check_path($path, "exists", true ,
t("Virtual Host configuration path exists."),
t("Virtual Host configuration path does not exist."));
if (!$exists) {
$made = provision_check_path($path, "mkdir", true,
t("Virtual host configuration path has been created."),
t("Virtual host configuration path could not be created."),
PROVISION_PERM_ERROR | PROVISION_FRAMEWORK_ERROR);
}
else {
$writable = provision_check_path($path, "writable", true ,
t("Virtual host configuration path is writable."),
t("Virtual host configuration path is not writable."),
PROVISION_PERM_ERROR | PROVISION_FRAMEWORK_ERROR);
if (!$writable) {
chmod($path, 0770);
}
}
$profiles = file_scan_directory('./profiles', '\.profile$', array('.', '..', 'CVS', '.svn'), 0, TRUE, 'name', 0);
$data['profiles'] = $profiles;
$data['modules'] = module_rebuild_cache();
}
\ No newline at end of file
......@@ -52,30 +52,30 @@ function provision_mysql_provision_service() {
* Implementation of provision_configure
*/
function provision_mysql_provision_configure() {
$form['provision_mysql_user'] = array(
$form['provision_db_user'] = array(
'#type' => 'textfield',
'#required' => TRUE,
'#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' => variable_get('provision_mysql_user', 'root'),
'#default_value' => variable_get('provision_db_user', 'root'),
'#maxlength' => 255,
);
$form['provision_mysql_password'] = array(
'#type' => 'password',
'#required' => TRUE,
$form['provision_db_password'] = array(
'#type' => 'password_confirm',
'#required' => (variable_get("provision_db_password", TRUE)) ? FALSE : TRUE,
'#title' => t('Mysql user password'),
'#description' => t('The user account that will be used to create new mysql users and databases for new sites'),
'#size' => 30,
'#maxlength' => 64,
);
$form['provision_mysql_host'] = array(
$form['provision_db_host'] = array(
'#type' => 'textfield',
'#title' => t('Mysql server hostname'),
'#description' => t('The mysql server to connect to.'),
'#size' => 30,
'#default_value' => variable_get('provision_mysql_host', 'localhost'),
'#default_value' => variable_get('provision_db_host', 'localhost'),
'#maxlength' => 64,
);
return $form;
......@@ -86,42 +86,39 @@ function provision_mysql_provision_configure() {
function provision_mysql_provision_pre_install($url, &$data) {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
$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_mysql_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.
$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_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_drop_database($data['site-db-name']);
if ( _provision_mysql_database_exists($data['site_db_name']) ) {
_provision_mysql_drop_database($data['site_db_name']);
}
_provision_create_database($data['site-db-name']);
_provision_mysql_create_database($data['site_db_name']);
if ( !_provision_mysql_database_exists($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;
}
_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']);
_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']);
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']);
}
_provision_mysql_flush();
provision_set_active_db();
......@@ -130,39 +127,24 @@ function provision_mysql_provision_pre_install($url, &$data) {
function provision_mysql_provision_backup($url, &$data) {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
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_username'], $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) {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
return db_result(db_query("SHOW DATABASES LIKE '%s'", $data['site-db-name']));
return db_result(db_query("SHOW DATABASES LIKE '%s'", $data['site_db_name']));
}
function _provision_mysql_drop_database($name) {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
db_query("DROP DATABASE %s", $name);
}
function _provision_mysql_create_database($name) {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
db_query("CREATE DATABASE %s", $name);
}
function _provision_mysql_can_create_database() {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
$test = 'provision_test';
_provision_mysql_create_database($test);
if (_provision_mysql_database_exists($test)) {
......@@ -173,30 +155,21 @@ function _provision_mysql_can_create_database() {
}
function _provision_mysql_grant($name, $username, $password, $host = '') {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
$host = ($host) ? $host : '%';
db_query("GRANT ALL PRIVILEGES ON %s.* TO %s@`%s` IDENTIFIED BY '%s'", $name, $username, $host, $password);
}
function _provision_mysql_old_password($username, $password, $host = '') {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
$host = ($host) ? $host : '%';
db_query("SET PASSWORD FOR '%s'@'%s' = OLD_PASSWORD('%s')", $username, $host, $password);
}
function _provision_mysql_flush() {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
db_query("FLUSH PRIVILEGES");
}
function _provision_master_db_url() {
return sprintf("mysql://%s:%s@%s/mysql", variable_get('provision_mysql_user', 'root'), variable_get('provision_mysql_password', 'root'), $data['site-db-host']);
function _provision_master_db_url($data = array()) {
return sprintf("mysql://%s:%s@%s/mysql", variable_get('provision_db_user', 'root'), variable_get('provision_db_password', 'root'), variable_get('provision_db_host', 'localhost'));
}
......@@ -204,13 +177,13 @@ function _provision_master_db_url() {
* Implementation of hook_provision_verify
*/
function provision_mysql_provision_verify() {
#safety mechanism to ensure back end calls are not made via the front end.
if (!provision_confirm_drush()) return null;
provision_set_active_db(_provision_master_db_url());
if (!_provision_mysql_can_create_database()) {
provision_set_error(PROVISION_DB_ERROR | PROVISION_FRAMEWORK_ERROR);
provision_log('error', t('Unable to create new databases.'));
}
else {
provision_log("message", t('Mysql can create new databases.'));
}
provision_set_active_db();
}
<VirtualHost *:80>
<?php if ($site_mail) : ?>
ServerAdmin <?php print $site_mail; ?>
<?php endif;?>
DocumentRoot <?php print $publish_path; ?>
ServerName <?php print $site_url; ?>
<?php if (is_array($site_aliases)) :
foreach ($site_aliases as $alias_url) : ?>
ServerAlias <?php print $alias_url; ?>
<?php
endforeach;
endif; ?>
# Error handler for Drupal > 4.6.7
<Directory "<?php print $site_document_root; ?>/sites/<?php print $site_url; ?>/files">
SetHandler This_is_a_Drupal_security_line_do_not_remove
</Directory>
</VirtualHost>
\ No newline at end of file
$db_url = '<?php print "$site_db_type://$site_db_username:$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.
if (file_exists('includes/global.inc')) {
include_once('includes/global.inc');
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment