Commit 66e8f0f2 authored by anarcat's avatar anarcat

Merge branch 'hostmaster-0.4' into prod-koumbit

Conflicts:
	modules/hosting/package/hosting_package.install
parents 096e68cc 9e3ce463
......@@ -11,7 +11,7 @@ function hostmaster_profile_modules() {
return array(
/* core */ 'block', 'color', 'filter', 'help', 'menu', 'node', 'system', 'user',
/* aegir contrib */ 'hosting', 'hosting_task', 'hosting_client', 'hosting_db_server', 'hosting_package', 'hosting_platform', 'hosting_site', 'hosting_web_server', 'hosting_server',
/* other contrib */ 'install_profile_api' /* needs >= 2.1 */, 'jquery_ui', 'modalframe'
/* other contrib */ 'install_profile_api' /* needs >= 2.1 */, 'jquery_ui', 'modalframe', 'admin_menu',
);
}
......@@ -105,10 +105,10 @@ function hostmaster_bootstrap() {
'available' => 1,
));
drupal_set_message('creating master server node');
drupal_set_message(st('Creating master server node'));
node_save($node);
if ($db_server->remote_host != $master_server->remote_host) {
drupal_set_message('creating db server node');
drupal_set_message(st('Creating db server node'));
node_save($db_node);
}
variable_set('hosting_default_web_server', $node->nid);
......@@ -182,47 +182,9 @@ function hostmaster_bootstrap() {
variable_set('install_url' , $GLOBALS['base_url']);
}
/**
* Enable optional modules, if present
*/
function hostmaster_setup_modules() {
$modules = array('admin_menu');
foreach ($modules as $name) {
drupal_install_modules(array($name));
drupal_set_message(st("Enabling module !module", array('!module' => $name)));
$func = "_hostmaster_setup_" . $name;
if (function_exists($func)) {
$func();
}
}
}
function _hostmaster_setup_admin_menu() {
variable_set('admin_menu_margin_top', 1);
variable_set('admin_menu_position_fixed', 1);
variable_set('admin_menu_tweak_menu', 0);
variable_set('admin_menu_tweak_modules', 0);
variable_set('admin_menu_tweak_tabs', 0);
$menu_name = install_menu_create_menu(t('Administration'));
$admin = install_menu_get_items('admin');
$admin = install_menu_get_item($admin[0]['mlid']);
$admin['menu_name'] = $menu_name;
$admin['customized'] = 1;
$admin['hidden'] = 0;
menu_link_save($admin);
menu_rebuild();
}
function hostmaster_task_finalize() {
variable_set('install_profile', 'hostmaster');
drupal_set_title(st("Configuring roles, blocks and theme"));
drupal_set_message(st('Configuring menu items'));
install_include(array('menu'));
$menu_name = variable_get('menu_primary_links_source', 'primary-links');
......@@ -253,17 +215,17 @@ function hostmaster_task_finalize() {
$theme = 'eldir';
drupal_set_message(st("Enabling Eldir theme"));
drupal_set_message(st('Configuring Eldir theme'));
install_disable_theme('garland');
install_default_theme('eldir');
system_theme_data();
db_query("DELETE FROM {cache}");
drupal_set_message(st('Adding default blocks'));
drupal_set_message(st('Configuring default blocks'));
install_add_block('hosting', 'hosting_queues', $theme, 1, 5, 'right', 1);
drupal_set_message(st('Setting up roles'));
drupal_set_message(st('Configuring roles'));
install_remove_permissions(install_get_rid('anonymous user'), array('access content', 'access all views'));
install_remove_permissions(install_get_rid('authenticated user'), array('access content', 'access all views'));
install_add_permissions(install_get_rid('anonymous user'), array('access disabled sites'));
......@@ -274,10 +236,6 @@ function hostmaster_task_finalize() {
install_add_role('aegir account manager');
install_add_permissions(install_get_rid('aegir account manager'), array('create client', 'edit client users', 'view client'));
drupal_set_message(st('Enabling optional, yet recommended modules'));
hostmaster_setup_modules();
node_access_rebuild();
}
......@@ -84,6 +84,9 @@ function hosting_client_schema() {
function hosting_client_install() {
// Create tables.
drupal_install_schema('hosting_client');
$ret = array();
$ret[] = update_sql("INSERT INTO {hosting_client_user} (user, client) VALUES (1, 1)");
return $ret;
}
/**
......@@ -197,3 +200,15 @@ function hosting_client_update_8() {
return $ret;
}
/**
* Add uid 1 with client 1 to the hosting_client_user table if it wasn't there already.
* Was not happening on fresh installs via hook_install()
*/
function hosting_client_update_9() {
$ret = array();
$result = db_query("SELECT user, client FROM {hosting_client_user} WHERE user = 1 AND client = 1");
if (!db_affected_rows($result)) {
$ret[] = update_sql("INSERT INTO {hosting_client_user} (user, client) VALUES (1, 1)");
}
return $ret;
}
......@@ -43,7 +43,7 @@ function hosting_package_schema() {
),
),
'primary key' => array('vid'),
'indexes' => array('hosting_package_nid_idx', array('nid')),
'indexes' => array('hosting_package_nid_idx' => array('nid')),
);
$schema['hosting_package_instance'] = array(
......
......@@ -307,7 +307,7 @@ function hosting_package_view($node, $teaser = FALSE, $page = FALSE) {
if ($node->package_type == 'profile') {
$node->content['sites_view'] = array(
'#type' => 'item',
'#value' => hosting_site_list("profile", $node->nid),
'#value' => drupal_get_form('hosting_site_list_form', 'profile', $node->nid),
'#prefix' => '<div id="hosting-site-list">',
'#suffix' => '</div>',
'#weight' => 10
......
......@@ -58,7 +58,7 @@ function hosting_platform_post_hosting_verify_task($task, $data) {
}
foreach ($context['sites'] as $url) {
if (!($site = hosting_get_site_by_url($url))) {
if (hosting_domain_allowed($url)) {
// Import any sites that have not been created yet.
$site = new StdClass();
$site->type = 'site';
......
......@@ -154,21 +154,32 @@ function hosting_platform_form(&$node) {
'#type' => 'textfield',
'#title' => t('Name'),
'#required' => TRUE,
'#description' => t('Choose a descriptive name for your platform. You very likely want this to be something like "Drupal 6.10".'),
'#description' => t('Choose a unique descriptive name for your platform. You very likely want this to be something like "Drupal 6.20".'),
'#size' => 40,
'#default_value' => $node->title,
'#maxlength' => 255,
);
$form['publish_path'] = array(
'#type' => 'textfield',
'#title' => t('Publish path'),
'#required' => TRUE,
'#description' => t('The absolute path on the filesystem where the sites will be hosted. This needs to be created manually and initialized before your platform works properly.<br />For example, run the following shell commands:<pre>%commands</pre>Your publish path is the absolute path to the directory that gets created.<br />Alternatively, you can specify a makefile below, and the platform will be created automatically if the path specified here does not exist.<br />You are still required to enter the absolute path above, as it will be treated as the target directory by the makefile.', array('%commands' => "cd /var/aegir\n./drush/drush.php dl drupal\n")),
'#size' => 40,
'#default_value' => $node->publish_path,
'#maxlength' => 255,
);
if (!$node->nid) {
$form['publish_path'] = array(
'#type' => 'textfield',
'#title' => t('Publish path'),
'#required' => TRUE,
'#description' => t('The absolute path on the filesystem where the sites will be hosted. This needs to be created manually and initialized before your platform works properly. It also needs to be a unique path not already in use by a platform on any server.<br />For example, run the following shell commands:<pre>%commands</pre>Your publish path is the absolute path to the directory that gets created.<br />Alternatively, you can specify a makefile below, and the platform will be created automatically if the path specified here does not exist.<br />You are still required to enter the absolute path above, as it will be treated as the target directory by the makefile.', array('%commands' => "cd /var/aegir\n./drush/drush.php dl drupal\n")),
'#size' => 40,
'#default_value' => $node->publish_path,
'#maxlength' => 255,
);
}
else {
// display it
$form['info']['publish_path'] = array(
'#type' => 'item',
'#title' => t('Publish path'),
'#value' => $node->publish_path
);
// send it on form submission
$form['publish_path'] = array('#type' => 'hidden', '#value' => $node->publish_path);
}
$form['makefile'] = array(
'#type' => 'textfield',
......@@ -278,8 +289,13 @@ function hosting_platform_delete($node) {
* Implementation of hook_validate()
*/
function hosting_platform_validate($node, &$form) {
if ($node->op != t('Delete') && $result = db_fetch_object(db_query("SELECT n.title AS name FROM {hosting_platform} AS h INNER JOIN {node} AS n ON n.nid = h.nid WHERE publish_path = '%s' AND web_server = %d AND n.nid <> %d AND h.status >= %d", hosting_path_normalize($node->publish_path), $node->web_server, $node->nid, HOSTING_PLATFORM_QUEUED))) {
form_set_error('publish_path', t('Path already defined in platform %name', array('%name' => $result->name)));
// Make sure the platform name is unique, to avoid context clashes.
if ($node->op != t('Delete') && $result = db_fetch_object(db_query("SELECT n.title AS name FROM {hosting_platform} AS h INNER JOIN {node} AS n ON n.nid = h.nid WHERE n.title = '%s' AND n.nid <> %d AND h.status >= %d", $node->title, $node->nid, HOSTING_PLATFORM_QUEUED))) {
form_set_error('title', t('Platform name %name is already defined. Platform names must be unique across all servers.', array('%name' => $result->name)));
}
// Make sure the path is unique. Remote servers can't have the same path to a platform that is in use by another server.
if ($node->op != t('Delete') && $result = db_fetch_object(db_query("SELECT n.title AS name FROM {hosting_platform} AS h INNER JOIN {node} AS n ON n.nid = h.nid WHERE publish_path = '%s' AND n.nid <> %d AND h.status >= %d", hosting_path_normalize($node->publish_path), $node->nid, HOSTING_PLATFORM_QUEUED))) {
form_set_error('publish_path', t('Path is already in use by platform %name. Platform paths must be unique across all servers.', array('%name' => $result->name)));
}
}
......
......@@ -267,10 +267,10 @@ function hosting_nodeapi_server_presave(&$node) {
// this returns an array or FALSE
$ips = gethostbynamel($node->title);
if ($ips) {
drupal_set_message(t('Initialized the webserver IP to %ip based on hostname %name. This will be used to create database grants so make sure it is the right address, as seen from the database server.', array('%ip' => join(',', $ips), '%name' => $node->title)), 'message');
drupal_set_message(t('Initialized the IP to %ip based on hostname %name. If an HTTP service is enabled, this will be used to create database grants so make sure it is the right address, as seen from the database server.', array('%ip' => join(',', $ips), '%name' => $node->title)), 'message');
$node->ip_addresses = $ips;
} else {
drupal_set_message(t("Could not resolve IP address of server %name, not automatically setting IP address. DNS may fail."));
drupal_set_message(t("Could not resolve IP address of server %name, not automatically setting IP address. DNS may fail.", array('%name' => $node->title)));
}
}
hosting_server_services_from_post($node);
......@@ -283,7 +283,11 @@ function hosting_server_validate(&$node, &$form) {
hosting_ip_validate($node);
if (!_hosting_valid_fqdn($node->title)) {
form_set_error('title', t('Invalid domain name. Use a proper domain name or an IP address.'));
form_set_error('title', t('Invalid hostname. Use a proper hostname or an IP address.'));
}
if (!$node->nid && db_result(db_query("SELECT COUNT(nid) FROM {node} WHERE type='server' AND title='%s'", $node->title))) {
form_set_error('title', t("The hostname you have specified is already in use."));
}
hosting_server_services_from_post($node);
......
......@@ -22,9 +22,9 @@ function hosting_task_backup_form($node) {
*
* Builds a list of backups of the site that have been generated.
*/
function hosting_site_add_backup($site, $web_server, $filename, $description = '') {
db_query("INSERT INTO {hosting_site_backups} (site, web_server, filename, description, timestamp) VALUES (%d, %d, '%s', '%s', %d)",
$site, $web_server, $filename, $description, mktime());
function hosting_site_add_backup($site, $web_server, $filename, $description = '', $size = '') {
db_query("INSERT INTO {hosting_site_backups} (site, web_server, filename, description, size, timestamp) VALUES (%d, %d, '%s', '%s', %d, %d)",
$site, $web_server, $filename, $description, $size, mktime());
$bid = db_last_insert_id('hosting_site_backups', 'bid');
return $bid;
}
......@@ -40,7 +40,7 @@ function hosting_site_delete_backup($bid) {
* Get a site backup record
*/
function hosting_site_get_backup($bid) {
return db_fetch_array(db_query("SELECT bid, site, web_server, filename, description, timestamp FROM {hosting_site_backups} WHERE bid = %d", $bid));
return db_fetch_array(db_query("SELECT bid, site, web_server, filename, description, size, timestamp FROM {hosting_site_backups} WHERE bid = %d", $bid));
}
/**
......@@ -52,10 +52,10 @@ function hosting_site_get_backup($bid) {
* An associative array of backups existing for the site, indexed by bid and sorted reverse chronologically.
*/
function hosting_site_backup_list($site) {
$result = db_query("SELECT bid, description, timestamp FROM {hosting_site_backups} WHERE site=%d ORDER BY timestamp DESC", $site);
$result = db_query("SELECT bid, description, size, timestamp FROM {hosting_site_backups} WHERE site=%d ORDER BY timestamp DESC", $site);
while ($object = db_fetch_object($result)) {
#needs to be cleaned up. but i am NOT generating a theme func for this right now.
$backups[$object->bid] = '<strong>' . format_date($object->timestamp) . '</strong> - ' . filter_xss($object->description);
$backups[$object->bid] = '<strong>' . format_date($object->timestamp) . '</strong> - ' . format_size($object->size) . ' - ' . filter_xss($object->description);
}
return $backups;
}
......
......@@ -119,7 +119,7 @@ function hosting_site_hosting_install_task_rollback($task, $data) {
function hosting_site_post_hosting_disable_task($task, $data) {
if ($data['context']['backup_file'] && $data->ref->type == 'site') {
$platform = node_load($task->ref->platform);
hosting_site_add_backup($task->ref->nid, $platform->web_server, $data['context']['backup_file'], t('Generated before being disabled'));
hosting_site_add_backup($task->ref->nid, $platform->web_server, $data['context']['backup_file'], t('Generated before being disabled'), $data['context']['backup_file_size']);
}
$task->ref->site_status = HOSTING_SITE_DISABLED;
$task->ref->no_verify = TRUE;
......@@ -133,7 +133,7 @@ function hosting_site_post_hosting_disable_task($task, $data) {
function hosting_site_post_hosting_restore_task($task, $data) {
if ($data['context']['backup_file'] && $task->ref->type == 'site') {
$platform = node_load($task->ref->platform);
hosting_site_add_backup($task->ref->nid, $platform->web_server, $data['context']['backup_file'], t('Generated before being restored to a previous version'));
hosting_site_add_backup($task->ref->nid, $platform->web_server, $data['context']['backup_file'], t('Generated before being restored to a previous version'), $data['context']['backup_file_size']);
}
}
......@@ -170,7 +170,7 @@ function hosting_site_post_hosting_backup_task($task, $data) {
$desc = $task->task_args['description'];
$desc = ($desc) ? $desc : t('Generated on request');
hosting_site_add_backup($task->ref->nid, $platform->web_server, $data['context']['backup_file'], $desc);
hosting_site_add_backup($task->ref->nid, $platform->web_server, $data['context']['backup_file'], $desc, $data['context']['backup_file_size']);
}
}
......
......@@ -295,8 +295,9 @@ function hosting_site_validate($node, &$form) {
form_set_error('title', t("The domain name you have specified is already in use."));
}
// If the quota module is loaded, check the site quota
if (function_exists('hosting_site_quota_exceeded')) {
// If the quota module is loaded and this is a new node, check
// the site quota
if (!$node->nid && function_exists('hosting_site_quota_exceeded')) {
$quota_error = hosting_site_quota_exceeded((array) $node);
if ($quota_error) {
form_set_error('title', $quota_error);
......
......@@ -91,6 +91,10 @@ function hosting_site_schema() {
'size' => 'big',
'not null' => FALSE,
),
'size' => array(
'type' => 'int',
'not null' => FALSE,
),
'timestamp' => array(
'type' => 'int',
'not null' => FALSE,
......@@ -242,3 +246,13 @@ function hosting_site_update_6006() {
db_drop_field($ret, "hosting_site", "ssl_redirect");
return $ret;
}
/**
* Add backup size to hosting_site_backups table
*/
function hosting_site_update_6007() {
$ret = array();
$ret[] = update_sql("ALTER TABLE {hosting_site_backups} ADD COLUMN size INT");
return $ret;
}
......@@ -298,7 +298,13 @@ function hosting_get_sites_by_status($platform, $status) {
* Retrieve a node based on the url
*/
function hosting_get_site_by_url($url) {
$nid = db_result(db_query("SELECT n.nid FROM {node} n JOIN {hosting_site} h ON n.nid = h.nid WHERE n.title='%s' AND n.type = 'site' AND NOT (h.status=%d)", $url, HOSTING_SITE_DELETED));
// If the Aliases feature is enabled, try and get the site by its alias too
if (hosting_feature('alias')) {
$nid = db_result(db_query("SELECT n.nid FROM {node} n JOIN {hosting_site} h ON n.nid = h.nid LEFT JOIN {hosting_site_alias} ha ON h.vid = ha.vid WHERE (n.title = '%s' OR ha.alias = '%s') AND n.type = 'site' AND NOT (h.status = %d)", $url, $url, HOSTING_SITE_DELETED));
}
else {
$nid = db_result(db_query("SELECT n.nid FROM {node} n JOIN {hosting_site} h ON n.nid = h.nid WHERE n.title='%s' AND n.type = 'site' AND NOT (h.status=%d)", $url, HOSTING_SITE_DELETED));
}
if ($nid) {
return node_load($nid);
}
......@@ -460,10 +466,25 @@ function hosting_site_list_form($form_state, $filter_by = NULL, $filter_value =
$options = array();
foreach (hosting_available_tasks('site') as $task => $array) {
// skip hidden tasks
if ($array['hidden']) {
continue;
}
// At this stage we only want to handle simple tasks, the presense of a
// specific task form means there are other options for this tasks.
// a form that requires input from the user means that this task cannot
// be done as a bulk operation.
$func = 'hosting_task_' . $task . '_form';
if (!function_exists($func) && user_access('create '. $task .' task')) {
$interactive = FALSE;
if (function_exists($func)) {
// load the task form
$task_form = $func(new stdClass());
foreach (element_children($task_form) as $key) {
if (!isset($task_form[$key]['#required']) || $task_form[$key]['#required']) {
$interactive = TRUE;
}
}
}
if (!$interactive && user_access('create '. $task .' task')) {
$options[$task] = $array['title'];
}
}
......@@ -568,13 +589,12 @@ function hosting_site_list_form_submit($form, &$form_state) {
$operations = array();
foreach ($sites as $site) {
$operations[] = array('_hosting_sites_batch_process',
array($site, $task, $form_state));
$operations[] = array('hosting_sites_batch_process',
array($site, $task));
}
if (sizeof($operations)) {
$batch = array(
'operations' => $operations,
'finished' => '_hosting_sites_batch_finished',
'title' => t('Processing'),
'progress_message' => t('Evaluated @current out of @total sites.'),
'error_message' => t('The update has encountered an error.'),
......@@ -595,7 +615,7 @@ function hosting_site_list_form_submit($form, &$form_state) {
$form_state['storage']['step'] = $step + 1;
}
function _hosting_sites_batch_process($site_id, $task, &$context) {
function hosting_sites_batch_process($site_id, $task, &$context) {
if (!isset($context['sandbox']['progress'])) {
$context['sandbox']['progress'] = 0;
}
......
......@@ -67,12 +67,12 @@ function drush_hosting_task() {
// On install/verify, save the named context
if ($task->task_type === 'install' || $task->task_type === 'verify' || $task->task_type === 'import') {
// we copy module_invoke_all() here because it doesn't pass by
// XXX: we copy module_invoke_all() here because it doesn't pass by
// reference and it breaks under PHP 5.3
$hook = 'hosting_' . $task->ref->type . '_context_options';
foreach (module_implements($hook) as $module) {
$function = $module . '_' . $hook;
call_user_func($function, &$task);
call_user_func($function, $task);
}
$output = drush_backend_invoke_args('provision-save', array('@' . $task->ref->hosting_name), $task->context_options, $mode);
......
......@@ -363,6 +363,27 @@ function hosting_task_restore_form($node) {
return $form;
}
/**
* Implementation of hook_form_alter()
*/
function hosting_task_restore_form_validate($form, &$form_state) {
if ($form['parameters']['no_backups']) {
form_set_error('no_backups', t('There are no valid backups available.'));
}
}
/**
* Implementation of hook_form_alter()
*/
function hosting_task_backup_delete_form_validate($form, &$form_state) {
if ($form['parameters']['no_backups']) {
form_set_error('no_backups', t('There are no valid backups available.'));
}
if (!$form['parameters']['#post']['parameters']) {
form_set_error('no_backups', t('No backups were selected for deletion.'));
}
}
function hosting_task_backup_delete_form($node) {
$list = hosting_site_backup_list($node->nid);
if (sizeof($list)) {
......@@ -860,7 +881,7 @@ function hosting_task_queue_block() {
foreach ($nodes as $node) {
$row = array();
$row['type'] = array(
'data' => drupal_ucfirst($node->task_type) . ' ' . _hosting_node_link($node->rid),
'data' => drupal_ucfirst(str_replace('_', ' ', $node->task_type)) . ' ' . _hosting_node_link($node->rid),
'class' => 'hosting-status'
);
......
......@@ -9,3 +9,4 @@ regions[left] = Left sidebar
regions[right] = Right sidebar
regions[content] = Content
regions[header] = Header
regions[footer] = Footer
......@@ -53,6 +53,7 @@
</div></div>
<div id="footer" class='reverse'><div class='limiter clear-block'>
<?php print $footer; ?>
<?php if ($secondary_links) print theme('links', $secondary_links, array('class' => 'links secondary-links')) ?>
<div class='footer-message'><?php print $footer_message ?></div>
</div></div>
......
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