diff --git a/aegir.make b/aegir.make index 231d0d561db0674be824d5fc145ee0a8636fb9f2..d60ac548d9e974b2f4f77ce29326aac0e855944e 100644 --- a/aegir.make +++ b/aegir.make @@ -6,4 +6,4 @@ projects[drupal][type] = "core" projects[hostmaster][type] = "profile" projects[hostmaster][download][type] = "git" projects[hostmaster][download][url] = "http://git.drupal.org/project/hostmaster.git" -projects[hostmaster][download][tag] = "6.x-1.4" +projects[hostmaster][download][tag] = "6.x-1.5" diff --git a/db/db.drush.inc b/db/db.drush.inc index 616361e707165ff320c905af743aef8ff098c299..0bff9d49ee8c11059bb511add4778dc3e64f27a0 100644 --- a/db/db.drush.inc +++ b/db/db.drush.inc @@ -25,8 +25,8 @@ function db_drush_help($section) { return dt('Unable to connect to database server.'); case 'error:PROVISION_CREATE_DB_FAILED' : return dt('Unable to create new databases.'); - case 'error:PROVISION_CREATE_DB_USER_FAILED' : - return dt('Unable to create new database users.'); + case 'error:PROVISION_GRANT_DB_USER_FAILED' : + return dt('Unable to grant privileges to database users.'); case 'error:PROVISION_DROP_DB_FAILED' : return dt('Unable to drop database.'); } @@ -71,10 +71,10 @@ class provisionService_db extends provisionService { drush_set_error('PROVISION_CREATE_DB_FAILED'); } if ($this->can_grant_privileges()) { - drush_log(dt('Provision can create database users.'), 'message');; + drush_log(dt('Provision can grant privileges on database users.'), 'message');; } else { - drush_set_error('PROVISION_CREATE_DB_USER_FAILED'); + drush_set_error('PROVISION_GRANT_DB_USER_FAILED'); } } else { drush_set_error('PROVISION_CONNECT_DB_FAILED'); @@ -235,7 +235,11 @@ class provisionService_db extends provisionService { return FALSE; } - function can_create_database() { + function can_create_database() { + return FALSE; + } + + function can_grant_privileges() { return FALSE; } @@ -295,8 +299,10 @@ class provisionService_db_pdo extends provisionService_db { } function connect() { + $user = isset($this->creds['user']) ? $this->creds['user'] : ''; + $pass = isset($this->creds['pass']) ? $this->creds['pass'] : ''; try { - $this->conn = new PDO($this->dsn, $this->creds['user'], $this->creds['pass']); + $this->conn = new PDO($this->dsn, $user, $pass); return $this->conn; } catch (PDOException $e) { diff --git a/db/mysql/mysql_service.inc b/db/mysql/mysql_service.inc index d9a4ddd817a8b656bb4ac6a3b0bdd3fe76266595..0a133b25e0fb2c43ab27dd0ac657890d5cf1950f 100644 --- a/db/mysql/mysql_service.inc +++ b/db/mysql/mysql_service.inc @@ -36,17 +36,21 @@ class provisionService_db_mysql extends provisionService_db_pdo { } /** - * Verifies that Aegir can grant privileges to a user on a database + * Verifies that provision can grant privileges to a user on a database. * * @return - * boolean TRUE if the check was successful + * TRUE if the check was successful. */ function can_grant_privileges() { - $test = drush_get_option('aegir_db_prefix', 'site_'); - $status = $this->grant($test, $test . 'user', $test . 'password', $test . 'host'); + $dbname = drush_get_option('aegir_db_prefix', 'site_'); + $user = $dbname . '_user'; + $password = $dbname . '_password'; + $host = $dbname . '_host'; + if ($status = $this->grant($dbname, $user, $password, $host)) { + $this->revoke($dbname, $user, $host); + } return $status; } - function grant($name, $username, $password, $host = '') { $host = ($host) ? $host : '%'; @@ -114,7 +118,7 @@ class provisionService_db_mysql extends provisionService_db_pdo { // non-readable by the webserver. umask(0077); // Mixed copy-paste of drush_shell_exec and provision_shell_exec. - $cmd = sprintf("mysqldump --defaults-file=/dev/fd/3 %s | sed 's|/\\*!50001 CREATE ALGORITHM=UNDEFINED \\*/|/\\*!50001 CREATE \\*/|g; s|/\\*!50017 DEFINER=`[^`]*`@`[^`]*` \\*/||g' | sed '/\\*!50013 DEFINER=.*/ d' > %s/database.sql", escapeshellcmd(drush_get_option('db_name')), escapeshellcmd(d()->site_path)); + $cmd = sprintf("mysqldump --defaults-file=/dev/fd/3 %s | sed 's|/\\*!50001 CREATE ALGORITHM=UNDEFINED \\*/|/\\*!50001 CREATE \\*/|g; s|/\\*!50017 DEFINER=`[^`]*`@`[^`]*`\s*\\*/||g' | sed '/\\*!50013 DEFINER=.*/ d' > %s/database.sql", escapeshellcmd(drush_get_option('db_name')), escapeshellcmd(d()->site_path)); $success = $this->safe_shell_exec($cmd, drush_get_option('db_host'), urldecode(drush_get_option('db_user')), urldecode(drush_get_option('db_passwd'))); if (!$success && !drush_get_option('force', false)) { diff --git a/install.hostmaster.inc b/install.hostmaster.inc index 20717bcc996adc9bdc1bd8b2faf1b8dcef1006a6..1f79d014689acfe6e64bfea7c70fa83951508666 100644 --- a/install.hostmaster.inc +++ b/install.hostmaster.inc @@ -50,9 +50,9 @@ Don't worry: you will get to review those settings after the final install"); } else { $default_email = 'webmaster@' . drush_get_option('aegir_host'); } - while (!filter_var(drush_get_option('client_email'), FILTER_VALIDATE_EMAIL)) { - $client_email = drush_prompt(dt("Admin user e-mail"), $default_email); - drush_set_option('client_email', $client_email); + drush_set_default('client_email', $default_email); + while (!filter_var(drush_get_option('client_email'), FILTER_VALIDATE_EMAIL) && !drush_get_context('DRUSH_AFFIRMATIVE')) { + drush_set_option('client_email', drush_prompt(dt("Admin user e-mail"), $default_email)); } drush_print(dt(' @@ -108,6 +108,9 @@ The following settings will be used: return TRUE; } +/** + * Drush command to install hostmaster. + */ function drush_provision_hostmaster_install($site = NULL) { $version = drush_get_option('version'); $site = drush_get_option('site', provision_fqdn()); @@ -130,7 +133,7 @@ function drush_provision_hostmaster_install($site = NULL) { 'master_url' => "http://" . $site, ); - $master_db = sprintf("mysql://%s:%s@%s",$aegir_db_user, $aegir_db_pass, drush_get_option('aegir_db_host')); + $master_db = sprintf("mysql://%s:%s@%s", urlencode($aegir_db_user), urlencode($aegir_db_pass), drush_get_option('aegir_db_host')); if (drush_get_option('aegir_host') == drush_get_option('aegir_db_host')) { $master_context['db_service_type'] = 'mysql'; $master_context['master_db'] = $master_db; diff --git a/platform/deploy.provision.inc b/platform/deploy.provision.inc index a8b6219cb08f1dc1c2ad653bf5fa0aeb9108017a..aff2d27c1ac6f89699fe29a81c8cd036e0363806 100644 --- a/platform/deploy.provision.inc +++ b/platform/deploy.provision.inc @@ -81,25 +81,32 @@ function drush_provision_drupal_pre_provision_deploy($backup_file) { _provision_drupal_create_settings_file(); $site_packages = drush_get_option('packages', array(), 'site'); - $profiles = array_keys($site_packages['profiles']); - $profile = $profiles[0]; - $drupal_packages = drush_get_option('packages', array(), 'drupal'); - $merged_modules = array_merge($drupal_packages['base']['modules'], $drupal_packages['profiles'][$profile]['modules']); - foreach ($site_packages['modules'] as $name => $module) { - if ($module['status'] == 1) { - if (!array_key_exists($name, $merged_modules)) { - drush_log(dt("Could not find a version of the !name module", array('!name' => $name)), 'warning'); - } - else { - if (($merged_modules[$name]['schema_version'] > 0) && ($module['schema_version'] > $merged_modules[$name]['schema_version'])) { - drush_set_error('PROVISION_SCHEMA_UPGRADE_FAILURE', - dt("The version of the !name module found on this platform (!versionB) has a lower Schema version than the one the site has installed (!versionA)", - array('!name' => $name, '!versionA' => $module['schema_version'], '!versionB' => $merged_modules[$name]['schema_version']))); + $merged_modules = $drupal_packages['base']['modules']; + if (isset($site_packages['profiles'])) { + $profiles = array_keys($site_packages['profiles']); + $profile = $profiles[0]; + if (isset($drupal_packages['profiles'][$profile]['modules'])) { + $merged_modules = array_merge($merged_modules, $drupal_packages['profiles'][$profile]['modules']); + } + } + + if (isset($site_packages['modules']) && is_array($site_packages['modules'])) { + foreach ($site_packages['modules'] as $name => $module) { + if ($module['status'] == 1) { + if (!array_key_exists($name, $merged_modules)) { + drush_log(dt("Could not find a version of the !name module", array('!name' => $name)), 'warning'); } else { - drush_log(dt("Found a valid version of the !name module with schema version !schema_version", - array('!name' => $name, '!schema_version' => $merged_modules[$name]['schema_version']))); + if (($merged_modules[$name]['schema_version'] > 0) && ($module['schema_version'] > $merged_modules[$name]['schema_version'])) { + drush_set_error('PROVISION_SCHEMA_UPGRADE_FAILURE', + dt("The version of the !name module found on this platform (!versionB) has a lower Schema version than the one the site has installed (!versionA)", + array('!name' => $name, '!versionA' => $module['schema_version'], '!versionB' => $merged_modules[$name]['schema_version']))); + } + else { + drush_log(dt("Found a valid version of the !name module with schema version !schema_version", + array('!name' => $name, '!schema_version' => $merged_modules[$name]['schema_version']))); + } } } } diff --git a/platform/drupal/install_7.inc b/platform/drupal/install_7.inc index cd038553913b1785c443c837e141e38aff93df35..51f27a1bcb956cdc71a627e257cad4427173bec0 100644 --- a/platform/drupal/install_7.inc +++ b/platform/drupal/install_7.inc @@ -12,6 +12,7 @@ $GLOBALS['base_url'] = provision_get_base_url(); define('MAINTENANCE_MODE', 'install'); function install_send_welcome_mail($url, $account, $language, $client_email, $onetime) { + global $base_url; if ($client_email) { // Mail one time login URL and instructions. $from = variable_get('site_mail', ini_get('sendmail_from')); diff --git a/platform/drupal/packages_7.inc b/platform/drupal/packages_7.inc index 7e7f344debb2c021cba1c7fce33134a48c91cb87..c58b626f603fc55c0da6b2e6488ed239ad8a10ef 100644 --- a/platform/drupal/packages_7.inc +++ b/platform/drupal/packages_7.inc @@ -50,6 +50,7 @@ function _provision_drupal_find_themes($scope, $key = '') { */ function _provision_drupal_parse_info_file($filename) { $info = array(); + $constants = get_defined_constants(); if (!file_exists($filename)) { return $info; @@ -93,9 +94,9 @@ function _provision_drupal_parse_info_file($filename) { $parent = &$parent[$key]; } - // Handle PHP constants - if (defined($value)) { - $value = constant($value); + // Handle PHP constants. + if (isset($constants[$value])) { + $value = $constants[$value]; } // Insert actual value diff --git a/provision.config.inc b/provision.config.inc index 3ce70350e9fc7590d9ffdf34d51615b4e0ffc6f3..e07ac1ea9e50b10efa259fcaa0bb4e6fd9ea8b56 100644 --- a/provision.config.inc +++ b/provision.config.inc @@ -72,7 +72,7 @@ class provisionConfig { */ function __construct($context, $data = array()) { if (is_null($this->template)) { - throw(exception); + throw new Exception(dt("No template specified for: %class", array('%class' => get_class($this)))); } // Accept both a reference and an alias name for the context. diff --git a/provision.info b/provision.info index 498aaa6c6d4f1ed37fd9d54d174ff3213dc7c099..088a815ce35e513e9cbafa8ed757fe50a7fcbd9c 100644 --- a/provision.info +++ b/provision.info @@ -1,4 +1,4 @@ name=Provision description="Aegir backend" -version=6.x-1.4 +version=6.x-1.5 diff --git a/tests/makes/drupal5.build b/tests/makes/drupal5.build new file mode 100644 index 0000000000000000000000000000000000000000..28fedd8aa13b9b27c55f681b526551618ba8976e --- /dev/null +++ b/tests/makes/drupal5.build @@ -0,0 +1,4 @@ +api = 2 + +core = 5.x +projects[] = "drupal" diff --git a/tests/makes/drupal6.build b/tests/makes/drupal6.build new file mode 100644 index 0000000000000000000000000000000000000000..31803f8cbd35457469edc251346549cffa9f6c1d --- /dev/null +++ b/tests/makes/drupal6.build @@ -0,0 +1,4 @@ +api = 2 + +core = 6.x +projects[] = "drupal" diff --git a/tests/makes/drupal7.build b/tests/makes/drupal7.build new file mode 100644 index 0000000000000000000000000000000000000000..f421d1aef670c2a12a6e06630b29bb24887e0878 --- /dev/null +++ b/tests/makes/drupal7.build @@ -0,0 +1,4 @@ +api = 2 + +core = 7.x +projects[] = "drupal" diff --git a/tests/makes/openatrium.build b/tests/makes/openatrium.build new file mode 100644 index 0000000000000000000000000000000000000000..93017bfd27666378046601307872640c5f9dbc2f --- /dev/null +++ b/tests/makes/openatrium.build @@ -0,0 +1,7 @@ +api = 2 + +core = 6.x + +projects[atrium-1-0][type] = "core" +projects[atrium-1-0][download][type] = "get" +projects[atrium-1-0][download][url] = "http://openatrium.com/sites/openatrium.com/files/atrium_releases/atrium-1-0.tgz" diff --git a/tests/provision_tests.drush.inc b/tests/provision_tests.drush.inc new file mode 100644 index 0000000000000000000000000000000000000000..4cc0a63a794de67d8cbc0af0b74a91cc7f968741 --- /dev/null +++ b/tests/provision_tests.drush.inc @@ -0,0 +1,220 @@ + dt('Runs provision tests'), + 'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL, + // Although we're a provision command, we require hostmaster to be around to + // run the tests correctly + 'drupal dependencies' => array( + 'hosting', + ), + ); + + return $items; +} + +/** + * Drush command to run the provision tests. + */ +function drush_provision_tests_run() { + if (version_compare(PHP_VERSION, '5.3.0', '<')) { + $drupal5_tests = TRUE; + } + else { + $drupal5_tests = FALSE; + drush_log(dt('Please note that because you are running PHP 5.3 or greater, you cannot test installing Drupal 5 on this machine.'), 'warning'); + } + + if (!drush_confirm(dt('This command should only be run on a clean Aegir install, and data may be lost! Do you want to continue?'))) { + return drush_user_abort(); + } + + // Disable the tasks queue, we run them manually instead. + $queue_status_initial = variable_get('hosting_queue_tasks_enabled', '0'); + variable_set('hosting_queue_tasks_enabled', '0'); + + if ($drupal5_tests) { + drush_provision_tests_install_platform('drupal5'); + } + drush_provision_tests_install_platform('drupal6'); + drush_provision_tests_install_platform('drupal7'); + drush_provision_tests_install_platform('openatrium'); + + // Install some sites. + if ($drupal5_tests) { + drush_provision_tests_install_site('drupal5', 'drupal5-default', 'default'); + } + drush_provision_tests_install_site('drupal6', 'drupal6-default', 'default'); + drush_provision_tests_install_site('drupal7', 'drupal7-standard', 'standard'); + drush_provision_tests_install_site('drupal7', 'drupal7-minimal', 'minimal'); + drush_provision_tests_install_site('openatrium', 'openatrium-openatrium', 'openatrium'); + + // Remove the sites. + if ($drupal5_tests) { + drush_provision_tests_remove_site('drupal5-default', 'default'); + } + drush_provision_tests_remove_site('drupal6-default'); + drush_provision_tests_remove_site('drupal7-standard'); + drush_provision_tests_remove_site('drupal7-minimal'); + drush_provision_tests_remove_site('openatrium-openatrium'); + + // Create some sites and migrate them. + if ($drupal5_tests) { + drush_provision_tests_install_platform('drupal5', 'drupal5_other'); + drush_provision_tests_install_site('drupal5', 'drupal5-migrate-drupal5-other', 'default'); + drush_provision_tests_migrate_site('drupal5-migrate-drupal5-other', 'drupal5_other'); + drush_provision_tests_remove_site('drupal5-migrate-drupal5-other'); + drush_provision_tests_remove_platform('drupal5_other'); + } + drush_provision_tests_install_platform('drupal6', 'drupal6_other'); + drush_provision_tests_install_site('drupal6', 'drupal6-migrate-drupal6-other', 'default'); + drush_provision_tests_migrate_site('drupal6-migrate-drupal6-other', 'drupal6_other'); + drush_provision_tests_remove_site('drupal6-migrate-drupal6-other'); + drush_provision_tests_remove_platform('drupal6_other'); + drush_provision_tests_install_platform('drupal7', 'drupal7_other'); + drush_provision_tests_install_site('drupal7', 'drupal7-migrate-drupal7-other', 'standard'); + drush_provision_tests_migrate_site('drupal7-migrate-drupal7-other', 'drupal7_other'); + drush_provision_tests_remove_site('drupal7-migrate-drupal7-other'); + drush_provision_tests_remove_platform('drupal7_other'); + + + // Create some sites, and upgrade them + if ($drupal5_tests) { + drush_provision_tests_install_site('drupal5', 'drupal5-upgrade-drupal7', 'default'); + drush_provision_tests_migrate_site('drupal5-upgrade-drupal7', 'drupal6'); + drush_provision_tests_migrate_site('drupal5-upgrade-drupal7', 'drupal7'); + drush_provision_tests_remove_site('drupal5-upgrade-drupal7'); + } + drush_provision_tests_install_site('drupal6', 'drupal6-upgrade-drupal7', 'default'); + drush_provision_tests_migrate_site('drupal6-upgrade-drupal7', 'drupal7'); + drush_provision_tests_remove_site('drupal6-upgrade-drupal7'); + + // Clean up a little. + if ($drupal5_tests) { + drush_provision_tests_remove_platform('drupal5'); + } + drush_provision_tests_remove_platform('drupal6'); + drush_provision_tests_remove_platform('drupal7'); + drush_provision_tests_remove_platform('openatrium'); + + // Restore the tasks queue status: + variable_set('hosting_queue_tasks_enabled', $queue_status_initial); + + if (drush_get_error() != DRUSH_SUCCESS) { + return drush_set_error(drush_get_error(), 'Running tests failed'); + } + + drush_log(dt('Tests completed successfully'), 'success'); +} + +/** + * Helper function to install a platform. + */ +function drush_provision_tests_install_platform($platform_name, $platform_alias = NULL) { + if (is_null($platform_alias)) { + $platform_alias = $platform_name; + } + drush_log(dt('Building platform: @platform and adding to hostmaster.', array('@platform' => $platform_alias)), 'ok'); + $args = array( + PROVISION_TESTS_BUILDS_REPO . "/$platform_name.build", + "/var/aegir/platforms/$platform_alias" + ); + drush_backend_invoke('make', $args); + $args = array( + 'root' => "/var/aegir/platforms/$platform_alias", + "@platform_$platform_alias", + 'context_type' => 'platform', + ); + drush_backend_invoke('provision-save', $args); + provision_backend_invoke('@hostmaster', 'hosting-import', array("@platform_$platform_alias",)); + drush_provision_tests_run_remaining_tasks(); +} + +/** + * Helper function to remove a platform. + */ +function drush_provision_tests_remove_platform($platform_name) { + drush_log(dt('Removing platform: @platform.', array('@platform' => $platform_name)), 'ok'); + provision_backend_invoke('@hostmaster', 'hosting-task', array("@platform_$platform_name", 'delete')); + drush_provision_tests_run_remaining_tasks(); +} + +/** + * Helper function to install a site. + */ +function drush_provision_tests_install_site($platform_name, $site, $profile_name) { + drush_log(dt('Installing: @site on platform: @platform with profile: @profile.', array('@site' => "$site.aegir.example.com", '@platform' => $platform_name, '@profile' => $profile_name)), 'ok'); + $args = array( + 'uri' => "$site.aegir.example.com", + "@$site.aegir.example.com", + 'context_type' => 'site', + 'platform' => "@platform_$platform_name", + 'profile' => $profile_name, + 'db_server' => '@server_localhost', + 'root' => "/var/aegir/platforms/$platform_name", + ); + drush_backend_invoke('provision-save', $args); + provision_backend_invoke("@$site.aegir.example.com", 'provision-install'); + provision_backend_invoke('@hostmaster', 'hosting-task', array("@platform_$platform_name", 'verify')); + drush_provision_tests_run_remaining_tasks(); +} + +/** + * Helper function to delete a site. + */ +function drush_provision_tests_remove_site($site) { + drush_log(dt('Removing: @site.', array('@site' => "$site.aegir.example.com")), 'ok'); + provision_backend_invoke('@hostmaster', 'hosting-task', array("@$site.aegir.example.com", 'delete')); + drush_provision_tests_run_remaining_tasks(); +} + +/** + * Migrates a site from one platform to another. + * + * @param $site + * The site to migrate. + * @param $target + * The target platform to migrate to. + */ +function drush_provision_tests_migrate_site($site, $target) { + drush_log(dt('Migrating: @site to platform: @platform.', array('@site' => "$site.aegir.example.com", '@platform' => $target)), 'ok'); + // Do the migrate. + provision_backend_invoke("@$site.aegir.example.com", 'provision-migrate', array("@platform_$target",)); + // Import the site into the frontend. + provision_backend_invoke('@hostmaster', 'hosting-import', array("@$site.aegir.example.com",)); + // Verify the $target platform. + provision_backend_invoke('@hostmaster', 'hosting-task', array("@platform_$target", 'verify')); + // Import and verify the site. + provision_backend_invoke('@hostmaster', 'hosting-import', array("@$site.aegir.example.com",)); + provision_backend_invoke('@hostmaster', 'hosting-task', array("@$site.aegir.example.com", 'verify')); + drush_provision_tests_run_remaining_tasks(); +} + +/** + * Run all remaining hosting tasks. + */ +function drush_provision_tests_run_remaining_tasks() { + $tasks = array(); + $result = db_query("SELECT t.nid FROM {hosting_task} t INNER JOIN {node} n ON t.vid = n.vid WHERE t.task_status = %d ORDER BY n.changed, n.nid ASC", 0); + while ($node = db_fetch_object($result)) { + $tasks[$node->nid] = node_load($node->nid); + } + + foreach ($tasks as $task) { + provision_backend_invoke('@hostmaster', "hosting-task", array($task->nid)); + } +} diff --git a/upgrade.sh.txt b/upgrade.sh.txt index 6943a606041c11079bbf13f9a42626852620a37e..4e31d3cb02f1a8a8efe7cf533b711f72d35c98d5 100644 --- a/upgrade.sh.txt +++ b/upgrade.sh.txt @@ -15,7 +15,7 @@ msg() { } # basic variables, change before running -AEGIR_VERSION="6.x-1.4" +AEGIR_VERSION="6.x-1.5" DRUSH_DIR=$HOME/drush DRUSH=$DRUSH_DIR/drush.php if which drush 2> /dev/null > /dev/null && which drush | grep -v 'no drush in' > /dev/null; then