'hosting-status-none', HOSTING_STATUS_SUCCESS => 'hosting-status-success', HOSTING_STATUS_WARNING => 'hosting-status-warning', HOSTING_STATUS_ERROR => 'hosting-status-error', ); } return $map[$status]; } /** * Constants used to configure contextual hosting help */ /** Display component of help **/ define('HOSTING_HELP_ENABLED', 1); /** Don't show help component **/ define('HOSTING_HELP_DISABLED', ~HOSTING_HELP_ENABLED); /** These are internally used to test against. Use the COLLAPSIBLE AND COLLAPSED instead **/ define('_HOSTING_HELP_CAN_COLLAPSE', 2); define('_HOSTING_HELP_HAS_COLLAPSED', 4); /** * Show help with the ability to collapse to save space. * This automatically enables the help component **/ define('HOSTING_HELP_COLLAPSIBLE', HOSTING_HELP_ENABLED | _HOSTING_HELP_CAN_COLLAPSE); /** * Display help component with an initial collapsed state. * This automatically enables and sets the help component to be collapsible */ define('HOSTING_HELP_COLLAPSED', HOSTING_HELP_COLLAPSIBLE | _HOSTING_HELP_HAS_COLLAPSED); /** * Returns a class name for the output of the form elementG */ function _hosting_help_class($state) { static $map; if (!sizeof($map)) { $map = array( HOSTING_HELP_ENABLED => 'hosting-help', HOSTING_HELP_COLLAPSIBLE => 'hosting-help-collapsible', HOSTING_HELP_COLLAPSED => 'hosting-help-collapsed' ); } return $map[$state]; } function hosting_hosting_service() { return array('hosting' => t("Basic configuration")); } /** * Implementation of hook_help() */ function hosting_help($section) { switch ($section) { case 'admin/help#hosting': $output .= t('

The Hostmaster system is a set of modules that provide an interface to the Provisioning framework.

', array('@hosting_help' => url('admin/help/provision'))); $output .= ''; $output .= '

' . t('Requirements') . '

'; // @TODO: make this more clear $output .= _hosting_requirements('provision'); $output .= _hosting_requirements('hosting_setup'); $output .= _hosting_requirements('cron'); $output .= '

' . t('Glossary') . '

'; $output .= '
'; $types = node_get_types(); foreach ($types as $type => $info) { if ($info->description) { $output .= "
" . $info->name . '
'; $output .= '
' . $info->description . '
'; } } $output .= '

' . t('Commands') . '

'; $commands = module_invoke_all('drush_command'); $output .= "
"; foreach ($commands as $command => $info) { if (preg_match('/^hosting/', $command)) { if (sizeof($info['arguments'])) { $command .= ' ' . implode(' ', (array) key($info['arguments'])); } if (sizeof($info['optional arguments'])) { $command .= ' [' . implode('] [', (array) key($info['optional arguments'])) . ']'; } $output .= '
' . "drush.php $command" . '
'; $output .= '
' . $info["description"] . '
'; } } $output .= "
"; return $output; case 'admin/help/provision#requirements' : $output .= _hosting_requirements('user'); $output .= _hosting_requirements('group'); $output .= _hosting_requirements('backup_path'); return $output; case 'admin/help#provision': $output .= t('

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.

'); $output .= t('

Additionally, the Provision framework is one component of the distributed hosting infrastructure provided by the hostmaster 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.

'); $output .= t('

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.

'); $output .= '

'. t('Requirements') .'

'; $output .= t('

For a more detailed breakdown of steps that need to be taken to configure Provisioning to run with your system, please read the in depth requirement documentation

', array('@url' => url('admin/help/provision/requirements'))); $output .= '

'. t('Commands') .'

'; $commands = module_invoke_all('drush_command'); $output .= "
"; 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 .= '
'."drush.php $command".'
'; $output .= '
'. $info["description"] .'
'; } } $output .= "
"; $output .= '

'. t('Options') .'

'; $options = module_invoke_all('value_list'); $output .= "
"; foreach ($options as $option => $description) { $output .= '
'."--$option".'
'; $output .= '
'. $description .'
'; } $output .= "
"; return $output; } } function _hosting_hosting_setup_requirements() { $node = node_load(HOSTING_OWN_WEB_SERVER); $drush_path = $node->drush_path; $docroot = HOSTING_DEFAULT_DOCROOT_PATH; $uri = HOSTING_DEFAULT_BASE_URL; $username = HOSTING_DEFAULT_SCRIPT_USER; $setup_cmd = <<Hosting Setup command'); $help['summary'][] = t('The hosting setup command performs several useful installation functions, but it\'s primary responsibility is adding the crontab entry for the queue dispatcher and ensuring that has been correctly installed.'); $help['summary'][] = t('The queue dispatcher runs every minute. It keeps track of what work needs to be done on the system and instructs the provisioning framework to perform the needed tasks in the task queue.'); $help['summary'][] = t('Otherwise said, without the dispatcher, changes on the front end will not translate in the required backend configuration preventing actual sites management.'); $help['configuration'] = t('Ensure that you are logged into the shell as %script_user, and then execute the following commands :
@setup_cmd
', array('%script_user' => $username, '@setup_cmd' => $setup_cmd)); return $help; } function _hosting_cron_requirements() { $cron_cmd['!queueconf'] = l(t("Queue administration"), "admin/settings/queues"); $cron_cmd['@cron_line'] = hosting_queues_cron_cmd(); $help['title'] = t('A cron entry for queue dispatcher.'); $help['summary'][] = t('Changes to this system are executed via a back end script which needs to be called by a user other than the web server user for security reasons at regular intervals.'); $help['summary'][] = t('The intervals at which these commands are run can be customised by going to the !queueconf section.', $cron_cmd); $help['summary'][] = t('The hosting setup command installs the required cron entry for you.', $cron_cmd); $help['configuration'] = t('Add the following line to your crontab : @cron_line', $cron_cmd); return $help; } function _hosting_platform_requirements() { $platform = node_load(HOSTING_OWN_PLATFORM); $web_server = node_load(HOSTING_OWN_WEB_SERVER); $db_server = node_load(HOSTING_OWN_DB_SERVER); $task = hosting_get_most_recent_task($platform->nid, 'verify'); $help['title'] = t('Provisioning framework status'); $help['summary'][] = t('In order for the hosting system to be able to create sites, it needs a platform to publish these sites on. A platform is a Drupal site that has the provision back end installed. Each platform also requires one correctly configured web server and one correctly configured database server. Once a new platform has been created, Hosting will automatically schedule a task that will verify the new platform is working properly.'); $help['summary'][] = t('As hosting is also running on a platform, it is suggested that you succesfully configure your primary platform before creating additional platforms and servers.', array('@platform' => url('node/' . HOSTING_OWN_PLATFORM))); $help['summary'][] = t('Each platform must be verified at least once, but if you find your platform is not being verified, look at the error log on the Verify platform task of this platform', array("@verify_link" => url("node/" . $task->nid))); return $help; } /** * TODO: replace. this is OLD OLD OLD */ function _hosting_introduction() { $default_message = t('

Please follow these steps to set up and start using your website:

'); $default_message .= '
    '; $default_message .= '
  1. '. t('Configure your website Once logged in, visit the administration section, where you can customize and configure all aspects of your website.', array('@admin' => url('admin'), '@config' => url('admin/settings'))) .'
  2. '; $default_message .= '
  3. '. t('Configure the Hosting framework. You now have a configured provisioning framework, but there are some additional configuration options for the hosting framework that can be set. Please visit the hosting administration section for more information.', array('@hosting_admin' => url('admin/hosting'))) .'
  4. '; $default_message .= '
  5. '. t('Create your first hosted site. This system uses special site posts to store information about your sites, so you can simple create a site post to get your first hosted site running.', array('@create_site' => url('node/add/site'))) .'
  6. '; $default_message .= '
'; $default_message .= '

'. t('For more information, please refer to the help section, or the online Drupal handbooks. You may also post at the Drupal forum, or view the wide range of other support options available.', array('@help' => url('admin/help'), '@handbook' => 'http://drupal.org/handbooks', '@forum' => 'http://drupal.org/forum', '@support' => 'http://drupal.org/support')) .'

'; $output = '
'. $default_message .'
'; return $output; } /** * Per node type description text. To be stored in the node_type table. * * @param type * The node type. * @return * Description text for the node type. */ function hosting_node_help($type) { switch ($type) { case 'site' : return t("An instance of a hosted site. It contains information relating to the site, most notably the domain name, database server and platform it is being published on. A site may also have several aliases for additional domains the site needs to be accessible on."); break; case 'platform' : return t("The file system location on a specific web server on which to publish sites. Multiple platforms can co-exist on the same web server, and need to do so for upgrades to be managed, as this is accomplished by moving the site a platform hosting an updated release. Platforms are most commonly built for specific releases of Drupal."); break; case 'client' : return t("The person or group that runs the site. This information is usually required for billing and access purposes, to assure that only certain people are able to view the information for sites they run. If you do not intend on having more than one client access the system, you will not need to create any additional clients for your purposes."); break; case 'web_server' : return t("The physical machine where files will be stored for publication. Each web server hosts one or more platforms, which act as publishing points for the hosted sites. If you are not intending to use Hostmaster in a distributed fashion, you will not need to create additional web servers for your purposes.."); break; case 'db_server' : return t("The database server on which sites will host their date. Most web servers and database servers are on the same machine, but for performance reasons external database servers might be required. It is not uncommon for one database server to be shared amongst all site instances. If you are not intending to use an external database server, or multiple database servers, you will not need to create any additional database servers for your purposes."); break; case 'task' : return t("The mechanism whereby Hostmaster keeps track of all changes that occurr to the system. Each task acts as a command for the back end, and contains a full log of all changes that have occurred. If an task should fail, the administrator will be notified with an explanation of exactly what went wrong, and how to fix it."); break; } } /** * Page callback with in depth requirement documentation */ function hosting_help_requirements() { $output .= _hosting_requirements("basic_drupal"); $output .= _hosting_requirements("basic_unix"); $output .= _hosting_requirements("basic_server"); $modules = module_implements('hosting_service'); foreach ($modules as $module) { $service = module_invoke($module, 'hosting_service'); $name = current($service); $help = module_invoke($module, 'help', 'admin/help/provision#requirements', null); if ($name && $help) { $output .= "

". t($name) .'

'; $output .= $help; } } return $output; } /** * Helper function for displaying contextual help when not used in a form. */ function _hosting_requirements($req, $section = 'all') { $item = _element_info('requirement_help'); $item['#requirement'] = $req; $item['#type'] = 'requirement_help'; /* foreach (array('#heading', '#summary', '#suggestion', '#configuration') as $key) { if (in_array($section, array('all', $key))) { $item['#'. $key] = HOSTING_HELP_ENABLED; } elseif ($section != 'all') { $item['#'. $key] = ($section == $key) ? HOSTING_HELP_ENABLED : HOSTING_HELP_DISABLED; } } */ $item = hosting_requirement_process($item); return theme("requirement_help", $item); } function hosting_get_requirement($req) { $func = '_hosting_'. $req .'_requirements'; if (function_exists($func)) { $help = $func(); } return $help; } function _hosting_backup_path_requirements() { $username = HOSTING_DEFAULT_SCRIPT_USER; $group = HOSTING_DEFAULT_WEB_GROUP; $backup_path = HOSTING_DEFAULT_BACKUP_PATH; $mkdir_cmd['@backup_path'] = $backup_path; $mkdir_cmd['@mkdir_cmd'] = <<http://drupal.org/project/drush) 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.'); $help['suggestion'] = t('Based on your server configuration we have determined that your path should be @backup_path', $mkdir_cmd); $help['configuration'] = t('Please enter the following commands :
@mkdir_cmd
', $mkdir_cmd); return $help; } function _hosting_user_requirements() { $username = HOSTING_DEFAULT_SCRIPT_USER; $path = HOSTING_DEFAULT_DOCROOT_PATH; $add_cmd = <<@script_user', array('@script_user' => HOSTING_DEFAULT_SCRIPT_USER)); $help['configuration'][] = t('If your system supports it, run the adduser command (if this command is unavailable, please consult your operating system documentation on how to add new system accounts) :
@cmd
', array('@cmd' => $add_cmd)); $help['configuration'][] = t('Once you have created the user account, you need to modify the ownership of the files. Use the following command :
@cmd
', array('@cmd' => $chmod_cmd)); return $help; } function _hosting_group_requirements() { $username = HOSTING_DEFAULT_SCRIPT_USER; $group = HOSTING_DEFAULT_WEB_GROUP; $vigr_cmd = <<@username" to the "@group" system group.', array("@username" => $username, "@group" => $group)); $help['configuration'] =t('If your system account is not a member of the web group, you can add them by using the adduser command:
@vigr_cmd
If that command is not available, you will need to edit the /etc/group file directly with your vigr or your favorite editor. Find the line that says :
@vigr1
Then add the username to the end of the line, so that it looks like :
@vigr2
If there were already users in the group, add your user to the group using a comma as separator :
@vigr3
Once you have changed this, you will need to log out and log bag into your terminal session for this setting to take effect. Alternatively you can get a new login shell by typing :
@su
', array('@vigr_cmd' => $vigr_cmd, '@vigr1' => $vigr1, '@vigr2' => $vigr2, '@vigr3' => $vigr3, '@su' => $su)); return $help; } /** * Implementation of hook_elements. * * Defines a number of form elements that are used for formatting the contextual help * in forms. */ function hosting_elements() { $type['requirement_help'] = array( '#requirement' => NULL, '#status' => HOSTING_STATUS_NONE, '#heading' => HOSTING_HELP_ENABLED, '#summary' => HOSTING_HELP_ENABLED, '#summary_prefix' => t("What is this?"), '#configuration' => HOSTING_HELP_COLLAPSED, '#configuration_prefix' => t("How do I configure this?"), '#default_messages' => array( HOSTING_STATUS_SUCCESS => t("You have met this requirement."), HOSTING_STATUS_WARNING => t("This requirement has a non critical error."), HOSTING_STATUS_ERROR => t("This requirement has a critical error. This system will not operate until it has been fixed")), '#process' => array('hosting_requirement_process' => array()), ); return $type; } /** * Places the various help components info the $element array */ function hosting_requirement_process(&$element) { if (!$element['#requirement']) { return element; } $element['#help'] = hosting_get_requirement($element['#requirement']); return $element; } /** * Theme function for displaying contextual help. * * Can control individual components of the help, for display in various places. */ function theme_requirement_help(&$element) { drupal_add_js(drupal_get_path('module', 'hosting') .'/hosting_help.js'); drupal_add_css(drupal_get_path('module', 'hosting') .'/hosting_help.css'); $req = $element['#requirement']; $help = $element['#help']; // this is just to make it easier to work with. //place anchor so user can be directed to right page. $output .= ""; $output .= '
'; if ($element['#status'] != HOSTING_STATUS_NONE) { $output .= "
". (($element['#message']) ? $element['#message'] : $element['#default_messages'][$element['#status']]) ."
"; } $components = array('summary', 'suggestion', 'configuration'); foreach ($components as $key) { if (($element["#$key"] & HOSTING_HELP_ENABLED) && !is_null($help[$key])) { $display_type = _hosting_help_class($element["#$key"]); $output .= "
"; if (!is_array($help[$key])) { // it is simpler if there's only one way to print the component $help[$key] = array($help[$key]); } if ($element["#$key".'_prefix'] && ($element["#$key"] & _HOSTING_HELP_CAN_COLLAPSE)) { $output .= ''. $element["#$key".'_prefix'] .''; } $output .= "

". implode("

", $help[$key]) ."

"; $output .= '
'; } } $output .= '
'; if (($element['#heading'] & HOSTING_HELP_ENABLED) && $help['title'] && !$element['#title']) { $element['#title'] = $help['title']; } $element['#value'] = $output; return theme('item', $element); } /** * @TODO: handle element children for requirement help function _hosting_basic_requirements() { $help['drupal'] = _hosting_basic_drupal_requirements(); $help['unix'] = _hosting_basic_unix_requirements(); $help['server'] = _hosting_basic_server_requirements(); return $help; } */ function _hosting_basic_drupal_requirements() { $help['title'] = t('A system capable of running Drupal'); $help['summary'] = t('If you are reading this via the inline help, this would be kind of obvious. This system is entirely Drupal based, and has the same base requirements that Drupal does.'); return $help; } function _hosting_basic_server_requirements() { $help['title'] = t('Your own server'); $help['summary'] = t('The level of access required to be able to configure this system is very far beyond what is commonly available to users with shared hosting.'); return $help; } function _hosting_basic_unix_requirements() { $help['title'] = t('A unix based operating system'); $help['summary'] = t('The majority of functionality in this system occurs in the back-end, through command line scripting. There are several features (such as symlinks), that are not available to users on Windows. There are no plans currently to add windows support.

'); return $help; }