From f77b1576b130af627c13d6d4b8fd62a20445ddf7 Mon Sep 17 00:00:00 2001 From: Adrian Rossouw Date: Thu, 17 Jan 2008 03:53:42 +0000 Subject: [PATCH] fix #default_value in provision_drupal and add backup command --- provision.inc | 61 ++++++++++++++++++------------------ provision.module | 69 +++++++++++++++++++++++++++++++++++------ provision_apache.module | 4 +-- provision_drupal.info | 2 +- provision_drupal.module | 15 +++++++++ provision_mysql.module | 7 +++++ 6 files changed, 114 insertions(+), 44 deletions(-) diff --git a/provision.inc b/provision.inc index 4af71e7b..e342ad15 100644 --- a/provision.inc +++ b/provision.inc @@ -114,31 +114,10 @@ function provision_output($url, $data, $extra = null) { * on how to diagnose any problems that may have occurred. */ -/** -* @name Error status definitions -* @{ -* Bitmask values used to generate the error code to return. -* @see provision_set_error(), provision_get_error(), provision_cmp_error() -*/ - -/** Database could not be accessed, or configured */ -define('PROVISION_DB_ERROR', 1); -/** Drupal was unable to complete it's installation */ -define('PROVISION_INSTALL_ERROR', 2); -/** Could not create files due to permission error - potentially less severe */ -define('PROVISION_PERM_ERROR', 4); -/** Web server could not be restarted, or other server related issues - less severe */ -define('PROVISION_WEB_ERROR', 8); -/** To be used while testing if the provision framework is actually working. */ -define('PROVISION_FRAMEWORK_ERROR', 16); -/** When the site is not available on this platform, or has not been installed. */ -define('PROVISION_SITE_NOT_FOUND', 32); -/** When the site is already installed, ie: there is a conflict. */ -define('PROVISION_SITE_INSTALLED', 64); -/** - * @} End of "name Error status defintions". - */ +if (PROVISION_SUCCESS != -1) { + include_once('provision_errors.inc'); +} /** * Set an error code for the error handling system. @@ -338,7 +317,6 @@ function provision_save_site_data($url, $data) { fwrite($fp, $line); } } - fwrite($fp, "?>"); fclose($fp); } } @@ -389,12 +367,12 @@ function provision_token_list($type = 'all') { if ($type == 'site') { /** TODO: Complete the token list to allow the front end to more easily edit the settings. */ $tokens['site']['site-url'] = t("The domain name used to access the site."); - $tokens['site']['site-db-type'] = t(""); - $tokens['site']['site-db-username'] = t(""); - $tokens['site']['site-db-password'] = t(""); - $tokens['site']['site-db-name'] = t(""); - $tokens['site']['site-profile'] = t(""); - $tokens['site']['site-action-type'] = t(""); + $tokens['site']['site-db-type'] = t("The type of database server used"); + $tokens['site']['site-db-username'] = t("Username to access database for site"); + $tokens['site']['site-db-password'] = t("Password to access database for site"); + $tokens['site']['site-db-name'] = t("Database name for the site"); + $tokens['site']['site-profile'] = t("Installation Profile"); + $tokens['site']['site-action-type'] = t("What type of action has been used"); } return $tokens; } @@ -415,3 +393,24 @@ function _provision_confirm_drush() { #confirm that code is running through the command line. } +/** + * Get the root path of the Provision installation + */ +function _provision_root_path() { + return variable_get('provision_root', ereg_replace("/webroot$", "", $_SERVER['DOCUMENT_ROOT'])); +} + +/** + * Wrapper around drush_shell_exec to provide sprintf functionality with some more safety. + */ +function provision_shell_exec() { + $args = func_get_args(); + + #do not change the command itself, just the parameters. + for ($x = 1; $x < sizeof($args); $x++) { + $args[$x] = escapeshellcmd($args[$x]); + } + $command = call_user_func_array("sprintf", $args); + + return drush_shell_exec($command); +} \ No newline at end of file diff --git a/provision.module b/provision.module index 24776fa1..76799d40 100644 --- a/provision.module +++ b/provision.module @@ -53,7 +53,7 @@ function hook_perm() { /** * Implementation of hook_menu(). */ -function provision_menu($items, $may_cache = true) { +function provision_menu($may_cache = true) { if ($may_cache) { $items[] = array( 'path' => 'admin/settings/provision', @@ -149,6 +149,10 @@ function provision_drush_command() { $items['provision import'] = array( 'callback' => '_provision_import', 'description' => 'Turn an already running site into a provisioned site.' + ); + $items['provision backup'] = array( + 'callback' => '_provision_backup', + 'description' => 'Generate a back up for the site.' ); /* $items['provision enable'] = array( @@ -165,10 +169,7 @@ function provision_drush_command() { 'description' => 'Delete a site.' ); - $items['provision backup'] = array( - 'callback' => '_provision_backup', - 'description' => 'Generate a back up for the site.' - ); + $items['provision rollback'] = array( 'callback' => '_provision_rollback', 'description' => 'Roll back the site to a previous backup.' @@ -311,14 +312,14 @@ function _provision_post_install($url, &$data) { * @param url * The url of the site being synched. * @return - * Output of drupal_output() function. + * Output of provision_output() function. * Will exit with a PROVISION_SITE_NOT_FOUND error if the site does not exist. */ function _provision_synch($url) { if (!_provision_drupal_site_exists($url)) { provision_log("Error", "Site has not been installed yet."); drupal_set_error(PROVISION_SITE_NOT_FOUND); - drupal_output($url, $data); + provision_output($url, $data); } $data = provision_get_site_data($url); // This is the actual drupal provisioning requirements. @@ -327,7 +328,55 @@ function _provision_synch($url) { // Requires at least the database settings to complete. _provision_drupal_create_settings_file($url, $data); provision_save_site_data($url, $data); - drupal_output($url, $data); + provision_output($url, $data); +} + +/** + * Generate a backup of the site using a site package. + * + * @param url + * The url of the site being backed up. + * @return + * Output of provision_output() function. + * Will exit with a PROVISION_SITE_NOT_FOUND error if the site does not exist. + */ +function _provision_backup($url) { + if (!_provision_drupal_site_exists($url)) { + provision_log("Error", "Site has not been installed yet."); + provision_set_error(PROVISION_SITE_NOT_FOUND); + provision_output($url, $data); + } + $data = provision_get_site_data($url); + $backup_path = variable_get('provision_backup_path', _provision_root_path() . '/backups' ); + // This is the actual drupal provisioning requirements. + if (!is_dir($backup_path)) { + provision_log("Backup directory does not exist."); + provision_set_error(PROVISION_PERM_ERROR); + provision_output($url, $data); + } + $args = func_get_args(); + array_shift($args); + $file = array_shift($args); + if (is_file($file)) { + provision_log("File specified already exists."); + provision_set_error(PROVISION_PERM_ERROR); + provision_output($url, $data); + } + $suggested = "$backup_path/$url-" . date("Y-m-d",mktime()) . ".tar"; + + // Use format of mysite.com-2008-01-02, if already existing, add number. + while (is_file($suggested . '.gz')) { + $count++; + $suggested = "$backup_path/$url-" . date("Y-m-d", mktime()) . "_$count.tar"; + } + + $data['backup_file'] = (!empty($file)) ? $file : $suggested; + $rolled_back = provision_invoke("backup", $url, $data); + provision_shell_exec("gzip %s", $data['backup_file']); + $data['backup_file'] = $data['backup_file'] . '.gz'; + provision_save_site_data($url, $data); + + provision_output($url, $data); } /** @@ -338,14 +387,14 @@ function _provision_synch($url) { * @param url * The url of the site being synched. * @return - * Output of drupal_output() function. + * Output of provision_output() function. * Will exit with a PROVISION_SITE_NOT_FOUND error if the site does not exist. */ function _provision_import($url) { if (!_provision_drupal_site_exists($url)) { provision_log("Error", "Site directory is not present, and can not be imported."); drupal_set_error(PROVISION_SITE_NOT_FOUND); - drupal_output($url, $data); + provision_output($url, $data); } $data = provision_get_site_data($url); diff --git a/provision_apache.module b/provision_apache.module index f82ccac5..19a024f2 100644 --- a/provision_apache.module +++ b/provision_apache.module @@ -33,7 +33,7 @@ function provision_apache_provision_configure() { '#type' => 'textfield', '#title' => t('Path to the directory to store apache configuration files for hosted sites'), '#size' => 40, - '#value' => variable_get('provision_apache_vhost_path', $default_path), + '#default_value' => variable_get('provision_apache_vhost_path', $default_path), '#maxlength' => 255, ); $form['provision_apache_restart_cmd'] = array( @@ -106,7 +106,7 @@ function _provision_apache_restart_apache() { # 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')); - $code = drush_shell_exec($apache_restart_cmd); + $code = drush_shell_exec(escapeshellcmd($apache_restart_cmd)); if ($code) { provision_set_error(PROVISION_WEB_ERROR); provision_log("error", "Web server could not be restarted. Changes might not be available until this has been done."); diff --git a/provision_drupal.info b/provision_drupal.info index 8ff52e9e..ab6cccfa 100644 --- a/provision_drupal.info +++ b/provision_drupal.info @@ -1,4 +1,4 @@ name = Provision: Drupal description = Allows for Drupal sites to be provisioned using the provisioning framework. package = Provision -dependencies = drush provision_drupal provision_mysql provision_apache \ No newline at end of file +dependencies = drush provision \ No newline at end of file diff --git a/provision_drupal.module b/provision_drupal.module index d997bffb..369cb5ae 100644 --- a/provision_drupal.module +++ b/provision_drupal.module @@ -74,6 +74,21 @@ function _provision_drupal_site_exists($url) { return file_exists("sites/$url/settings.php"); } + +/** + * Implentation of hook_provision_backup() + */ +function provision_drupal_provision_backup($url, $data) { + // Adds the site directory into the backup file + provision_log("backup", "Adding sites directory to $data[backup_file].gz"); + $result = provision_shell_exec("cd %s; tar -rf %s * ", "sites/$url", $data['backup_file']); + + if (!$result) { + provision_log("error", "Could not back up sites directory for drupal"); + provision_set_error(PROVISION_FRAMEWORK_ERROR); + } +} + /** * The default template to use while generating config files. * diff --git a/provision_mysql.module b/provision_mysql.module index 538050c3..61ad81b6 100644 --- a/provision_mysql.module +++ b/provision_mysql.module @@ -99,3 +99,10 @@ function provision_mysql_provision_pre_install($url, &$data) { #TODO : Test to confirm that the database is actually writeable. Taking this on faith for now. } + +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("cd sites/%; tar -rf %s database.sql", $url, $data['backup_file']); + provision_shell_exec("rm sites/%s/database.sql", $url); +} -- GitLab