/[drupal]/contributions/modules/hosting/hosting_help.inc
ViewVC logotype

Contents of /contributions/modules/hosting/hosting_help.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.45 - (show annotations) (download) (as text)
Wed Oct 14 11:42:24 2009 UTC (6 weeks, 4 days ago) by mig5
Branch: MAIN
Changes since 1.44: +2 -2 lines
File MIME type: text/x-php
prepend drush hosting_setup command with 'php' now that drush.php will no longer be directly executable
1 <?php
2
3 // $Id: hosting_help.inc,v 1.44 2009/10/13 11:52:56 mig5 Exp $
4
5 /**
6 * @file Hosting help subsystem
7 */
8
9 /**
10 * Constants used to generate the requirement help documentation.
11 */
12
13 /**
14 * Status is irrelevant. Can't be checked
15 */
16 define('HOSTING_STATUS_NONE', 0);
17
18 /**
19 * Requirement is met
20 */
21 define('HOSTING_STATUS_SUCCESS', 1);
22
23 /**
24 * Requirement not met. Less severe than an error.
25 */
26 define('HOSTING_STATUS_WARNING', 2);
27
28 /**
29 * Requirement failed. Fix before site will function
30 */
31 define('HOSTING_STATUS_ERROR', 4);
32
33 /**
34 * Returns a class name for the output of the form element.
35 */
36 function _hosting_status_class($status) {
37 static $map;
38
39 if (!sizeof($map)) {
40 $map = array(
41 HOSTING_STATUS_NONE => 'hosting-status-none',
42 HOSTING_STATUS_SUCCESS => 'hosting-status-success',
43 HOSTING_STATUS_WARNING => 'hosting-status-warning',
44 HOSTING_STATUS_ERROR => 'hosting-status-error',
45 );
46 }
47
48 return $map[$status];
49 }
50
51 /**
52 * Constants used to configure contextual hosting help
53 */
54
55 /**
56 * Display component of help
57 **/
58 define('HOSTING_HELP_ENABLED', 1);
59
60 /**
61 * Don't show help component
62 **/
63 define('HOSTING_HELP_DISABLED', ~HOSTING_HELP_ENABLED);
64
65 /**
66 * These are internally used to test against. Use the COLLAPSIBLE AND
67 * COLLAPSED instead
68 **/
69 define('_HOSTING_HELP_CAN_COLLAPSE', 2);
70 define('_HOSTING_HELP_HAS_COLLAPSED', 4);
71
72 /**
73 * Show help with the ability to collapse to save space.
74 * This automatically enables the help component
75 **/
76 define('HOSTING_HELP_COLLAPSIBLE', HOSTING_HELP_ENABLED | _HOSTING_HELP_CAN_COLLAPSE);
77
78 /**
79 * Display help component with an initial collapsed state.
80 * This automatically enables and sets the help component to be collapsible
81 */
82 define('HOSTING_HELP_COLLAPSED', HOSTING_HELP_COLLAPSIBLE | _HOSTING_HELP_HAS_COLLAPSED);
83
84
85 /**
86 * Returns a class name for the output of the form element
87 */
88 function _hosting_help_class($state) {
89 static $map;
90
91 if (!sizeof($map)) {
92 $map = array(
93 HOSTING_HELP_ENABLED => 'hosting-help',
94 HOSTING_HELP_COLLAPSIBLE => 'hosting-help-collapsible',
95 HOSTING_HELP_COLLAPSED => 'hosting-help-collapsed'
96 );
97 }
98 return $map[$state];
99 }
100
101 /**
102 * Implementation of hook_hosting_service()
103 */
104 function hosting_hosting_service() {
105 return array('hosting' => t("Basic configuration"));
106 }
107
108 /**
109 * Implementation of hook_help()
110 */
111 function hosting_help($path, $arg) {
112 switch ($path) {
113 case 'admin/help/hosting':
114 $output .= '<p>' . t('The Hostmaster system is a set of modules that provide an interface to the Provisioning framework.') . '</p>';
115 $output .= '</dl>';
116 $output .= '<a name="requirements"></a><h3>' . t('Requirements') . '</h3></a>';
117 // @TODO: make this more clear
118 $output .= _hosting_requirements('provision');
119 $output .= _hosting_requirements('hosting_setup');
120 $output .= _hosting_requirements('cron');
121 $output .= _hosting_requirements('user');
122 $output .= _hosting_requirements('group');
123 $output .= _hosting_requirements('backup_path');
124
125 $output .= '<a name="glossary"></<h3>' . t('Glossary') . '</h3></a>';
126 $output .= '<dl>';
127 $types = node_get_types();
128
129 foreach ($types as $type => $info) {
130 if ($info->description) {
131 $output .= "<dt><a name=\"glossary-$type\"></a>" . $info->name . '</dt>';
132 $output .= '<dd>' . $info->description . '</dd>';
133 }
134 }
135 return $output;
136 }
137 }
138
139 /**
140 * TODO: replace. this is OLD OLD OLD
141 */
142 function _hosting_introduction() {
143 $default_message = t('<p>Please follow these steps to set up and start using your website:</p>');
144 $default_message .= '<ol>';
145
146 $default_message .= '<li>'. t('<strong>Configure your website</strong>
147 Once logged in, visit the <a href="@admin">administration section</a>,
148 where you can <a href="@config">customize and configure</a> all aspects of your website.',
149 array('@admin' => url('admin'), '@config' => url('admin/settings'))) .'</li>';
150 $default_message .= '<li>'. t('<strong>Configure the Hosting framework.</strong>
151 You now have a configured provisioning framework, but there are some additional configuration options for the hosting framework that can be set.
152 Please visit the <a href="@hosting_admin">hosting administration</a> section for more information.', array('@hosting_admin' => url('admin/hosting'))) .'</li>';
153 $default_message .= '<li>'. t('<strong>Create your first hosted site.</strong> This system uses special site posts to store information about your sites, so you can simple <a href="@create_site">create a site post</a> to get your first hosted site running.', array('@create_site' => url('node/add/site'))) .'</li>';
154 $default_message .= '</ol>';
155 $default_message .= '<p>'. t('For more information, please refer to the <a href="@help">help section</a>, or the <a href="@handbook">online Drupal handbooks</a>. You may also post at the <a href="@forum">Drupal forum</a>, or view the wide range of <a href="@support">other support options</a> available.', array('@help' => url('admin/help'), '@handbook' => 'http://drupal.org/handbooks', '@forum' => 'http://drupal.org/forum', '@support' => 'http://drupal.org/support')) .'</p>';
156
157 $output = '<div id="first-time">'. $default_message .'</div>';
158
159 return $output;
160
161 }
162
163 /**
164 * Per node type description text. To be stored in the node_type table.
165 *
166 * @param type
167 * The node type.
168 * @return
169 * Description text for the node type.
170 */
171 function hosting_node_help($type) {
172 switch ($type) {
173 case 'site' :
174 return t("<strong>An instance of a hosted site.</strong>
175 It contains information relating to the site, most notably the domain name, database server
176 and platform it is being published on. A site may also have several aliases for additional
177 domains the site needs to be accessible on.");
178 break;
179 case 'platform' :
180 return t("<strong>The file system location on a specific web server on which to publish sites.</strong>
181 Multiple platforms can co-exist on the same web server, and need to do so for
182 upgrades to be managed, as this is accomplished by moving the site a platform
183 hosting an updated release.
184 Platforms are most commonly built for specific releases of Drupal.");
185 break;
186 case 'client' :
187 return t("<strong>The person or group that runs the site.</strong>
188 This information is usually required for billing and access purposes, to assure
189 that only certain people are able to view the information for sites they run.
190 If you do not intend on having more than one client access the system,
191 you will not need to create any additional clients for your purposes.");
192 break;
193 case 'web_server' :
194 return t("<strong>The physical machine where files will be stored for publication.</strong>
195 Each web server hosts one or more platforms, which act as publishing points for the hosted sites.
196 If you are not intending to use Hostmaster in a distributed fashion, you will not need to create
197 additional web servers for your purposes..");
198 break;
199 case 'db_server' :
200 return t("<strong>The database server on which sites will host their date.</strong>
201 Most web servers and database servers are on the same machine, but for performance reasons
202 external database servers might be required. It is not uncommon for one database server
203 to be shared amongst all site instances.
204 If you are not intending to use an external database server, or multiple database servers, you
205 will not need to create any additional database servers for your purposes.");
206 break;
207 case 'task' :
208 return t("<strong>The mechanism whereby Hostmaster keeps track of all changes that occurr to the system.</strong>
209 Each task acts as a command for the back end, and contains a full log of all changes that have occurred.
210 If an task should fail, the administrator will be notified with an explanation of exactly what went wrong,
211 and how to fix it.");
212 break;
213 }
214 }
215
216 /**
217 * Page callback with in depth requirement documentation
218 *
219 * This will invoke hook_help() for every module implementing
220 * hook_hosting_service()
221 *
222 * @see hook_hosting_service()
223 * @see hook_hosting_help()
224 */
225 function hosting_help_requirements() {
226 $output .= _hosting_requirements("basic_drupal");
227 $output .= _hosting_requirements("basic_unix");
228 $output .= _hosting_requirements("basic_server");
229 $modules = module_implements('hosting_service');
230 foreach ($modules as $module) {
231 $service = module_invoke($module, 'hosting_service');
232 $name = current($service);
233 $help = module_invoke($module, 'help', 'admin/help/provision#requirements', null);
234 if ($name && $help) {
235 $output .= "<a href='requirements-$module'></a><h3>". t($name) .'</h3>';
236 $output .= $help;
237 }
238 }
239 return $output;
240 }
241
242 /**
243 * Helper function for displaying contextual help when not used in a form.
244 */
245 function _hosting_requirements($req, $section = 'all') {
246 $item = _element_info('requirement_help');
247 $item['#requirement'] = $req;
248 $item['#type'] = 'requirement_help';
249 /*
250 foreach (array('#heading', '#summary', '#suggestion', '#configuration') as $key) {
251 if (in_array($section, array('all', $key))) {
252 $item['#'. $key] = HOSTING_HELP_ENABLED;
253 }
254 elseif ($section != 'all') {
255 $item['#'. $key] = ($section == $key) ? HOSTING_HELP_ENABLED : HOSTING_HELP_DISABLED;
256 }
257 }
258 */
259 return theme("requirement_help", hosting_requirement_process($item));
260 }
261
262 /**
263 * Find the requirements help document for the given element
264 *
265 * This will call hook_requirements() for the given element. The
266 * function name should be _hosting_$req_requirements() for this to
267 * function properly.
268 *
269 * @see hook_requirements()
270 * @see _hosting_requirements()
271 */
272 function hosting_get_requirement($req) {
273 $func = '_hosting_'. $req .'_requirements';
274 if (function_exists($func)) {
275 $help = $func();
276 }
277 return $help;
278 }
279
280 /**
281 * Places the various help components info the $element array
282 *
283 * @see hosting_get_requirement()
284 * @return array a form item with '#help' properly filled in with hosting_get_requirement() analysis
285 */
286 function hosting_requirement_process(&$element) {
287 if (!$element['#requirement']) {
288 return $element;
289 }
290
291 $element['#help'] = hosting_get_requirement($element['#requirement']);
292 return $element;
293 }
294
295 /**
296 * Implementation of hook_elements.
297 *
298 * Defines a number of form elements that are used for formatting the contextual help
299 * in forms.
300 */
301 function hosting_elements() {
302 $type['requirement_help'] = array(
303 '#requirement' => NULL,
304 '#input' => FALSE,
305 '#status' => HOSTING_STATUS_NONE,
306 '#heading' => HOSTING_HELP_ENABLED,
307 '#summary' => HOSTING_HELP_ENABLED,
308 '#summary_prefix' => t("What is this?"),
309 '#configuration' => HOSTING_HELP_COLLAPSED,
310 '#configuration_prefix' => t("How do I configure this?"),
311 '#default_messages' => array(
312 HOSTING_STATUS_SUCCESS => t("You have met this requirement."),
313 HOSTING_STATUS_WARNING => t("This requirement has a non critical error."),
314 HOSTING_STATUS_ERROR => t("This requirement has a critical error. This system will not operate until it has been fixed")),
315 '#process' => array('hosting_requirement_process'),
316 );
317 return $type;
318 }
319
320 /**
321 * Theme function for displaying contextual help.
322 *
323 * Can control individual components of the help, for display in various places.
324 */
325 function theme_requirement_help(&$element) {
326 drupal_add_js(drupal_get_path('module', 'hosting') .'/hosting_help.js');
327 drupal_add_css(drupal_get_path('module', 'hosting') .'/hosting_help.css');
328 $req = $element['#requirement'];
329 $help = $element['#help']; // this is just to make it easier to work with.
330
331 //place anchor so user can be directed to right page.
332 $output .= "<a name='hosting-help-$req'></a>";
333
334 $output .= '<div class="hosting-requirement-help' .
335 ' '. _hosting_status_class($element['#status']) .'">';
336
337 if ($element['#status'] != HOSTING_STATUS_NONE) {
338 $output .= "<div class='message'>". (($element['#message']) ? $element['#message'] : $element['#default_messages'][$element['#status']]) ."</div>";
339 }
340
341 $components = array('summary', 'suggestion', 'configuration');
342 foreach ($components as $key) {
343 if (($element["#$key"] & HOSTING_HELP_ENABLED) && !is_null($help[$key])) {
344 $display_type = _hosting_help_class($element["#$key"]);
345 $output .= "<div class='hosting-help-$key $display_type'>";
346 if (!is_array($help[$key])) {
347 // it is simpler if there's only one way to print the component
348 $help[$key] = array($help[$key]);
349 }
350 if ($element["#$key".'_prefix'] && ($element["#$key"] & _HOSTING_HELP_CAN_COLLAPSE)) {
351 $output .= '<a href="javascript:void(0)" class="hosting-help-toggle">'. $element["#$key".'_prefix'] .'</a>';
352 }
353
354 $output .= "<div class='hosting-help'><p>". implode("</p><p>", $help[$key]) ."</p></div>";
355 $output .= '</div>';
356 }
357 }
358 $output .= '</div>';
359 if (($element['#heading'] & HOSTING_HELP_ENABLED) && $help['title'] && !$element['#title']) {
360 $element['#title'] = $help['title'];
361 }
362 $element['#value'] = $output;
363 return theme('item', $element);
364 }
365
366 /**
367 * @TODO: handle element children for requirement help
368 function _hosting_basic_requirements() {
369 $help['drupal'] = _hosting_basic_drupal_requirements();
370 $help['unix'] = _hosting_basic_unix_requirements();
371 $help['server'] = _hosting_basic_server_requirements();
372
373 return $help;
374 }
375 */
376
377 function _hosting_backup_path_requirements() {
378 $username = HOSTING_DEFAULT_SCRIPT_USER;
379 $group = HOSTING_DEFAULT_WEB_GROUP;
380 $backup_path = HOSTING_DEFAULT_BACKUP_PATH;
381 $mkdir_cmd['@backup_path'] = $backup_path;
382 $mkdir_cmd['@mkdir_cmd'] = <<<EOF
383 mkdir $backup_path
384 chown $username:$username $backup_path
385 chmod 0700 $backup_path
386 EOF;
387 $help['title'] = t('Write access to a directory to store backups');
388 $help['summary'] = t('The drush user (<a href="http://drupal.org/project/drush">http://drupal.org/project/drush</a>) needs to be able to maintain the backups repository to ensure that your site is backed up successfully.
389 It is incredibly important that this path is not accessible via the web server, so that no undesirables can get their
390 hands on your database. The recommended path is directly above your platform path, but it can be anywhere.');
391
392 $help['suggestion'] = t('Based on your server configuration we have determined that your path should be <code>@backup_path</code>', $mkdir_cmd);
393 $help['configuration'] = t('Please enter the following commands : <pre>@mkdir_cmd</pre>', $mkdir_cmd);
394 return $help;
395 }
396
397
398 function _hosting_user_requirements() {
399 $username = HOSTING_DEFAULT_SCRIPT_USER;
400 $path = HOSTING_DEFAULT_DOCROOT_PATH;
401 $add_cmd = <<<EOF
402 sudo adduser $username
403 EOF;
404 $chmod_cmd = <<<EOF
405 sudo chown -R $username $path
406 EOF;
407 $help['title'] = t('A separate system account for the scripts');
408 $help['summary'] = t('The provision framework requires that the scripts run as a non-root system account, to ensure that
409 it can correctly set the file permissions on the hosted files. All existing files need to be changed to belong to this
410 new system account.');
411 $help['suggestion'] = t('Based on your server configuration, we have determined that your user account should be <code>@script_user</code>', array('@script_user' => HOSTING_DEFAULT_SCRIPT_USER));
412 $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) : <pre>@cmd</pre>', array('@cmd' => $add_cmd));
413 $help['configuration'][] = t('Once you have created the user account, you need to modify the ownership of the files. Use the following command : <pre>@cmd</pre>', array('@cmd' => $chmod_cmd));
414 return $help;
415 }
416
417 function _hosting_group_requirements() {
418
419 $username = HOSTING_DEFAULT_SCRIPT_USER;
420 $group = HOSTING_DEFAULT_WEB_GROUP;
421
422
423 $vigr_cmd = <<<EOF
424 sudo adduser $username $group
425 EOF;
426 $vigr1 = <<<EOF
427 $group::99:
428 EOF;
429 $vigr2 = <<<EOF
430 $group::99:$username
431 EOF;
432 $vigr3 = <<<EOF
433 $group::99:anotheruser,$username
434 EOF;
435
436 $su = <<<EOF
437 su -
438 EOF;
439
440 $help['title'] = t('The system group of the web server');
441 $help['summary'] = t('For the provision framework to be able to ensure that the file permissions of the
442 hosted sites are always as safe as can be, and especially to make sure that the web server does
443 not have the ability to modify the code of the site, the configured system account needs to be a member
444 of the web server group, in order to be able to correctly set the file permissions.');
445
446 $help['suggestion'] = t('Based on your server configuration we have determined that you should add the
447 system account "<code>@username</code>" to the "<code>@group</code>" system group.', array("@username" => $username, "@group" => $group));
448
449 $help['configuration'] =t('If your system account is not a member of the web group, you can add them by using the
450 <code>adduser</code> command:
451 <pre>@vigr_cmd</pre>
452 If that command is not available, you will need to edit the /etc/group file directly with
453 your vigr or your favorite editor.
454 Find the line that says : <pre>@vigr1</pre>
455 Then add the username to the end of the line, so that it looks like : <pre>@vigr2</pre>
456 If there were already users in the group, add your user to the group using a comma as separator :
457 <pre>@vigr3</pre>
458 Once you have changed this, you will need to log out and log back into your terminal session for this
459 setting to take effect. Alternatively you
460 can get a new login shell by typing : <pre>@su</pre>',
461 array('@vigr_cmd' => $vigr_cmd, '@vigr1' => $vigr1, '@vigr2' => $vigr2, '@vigr3' => $vigr3, '@su' => $su));
462 return $help;
463
464 }
465
466 /**
467 * Implementation of hook_requirements()
468 */
469 function _hosting_basic_drupal_requirements() {
470 $help['title'] = t('A system capable of running Drupal');
471 $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.');
472 return $help;
473 }
474
475 /**
476 * Implementation of hook_requirements()
477 */
478 function _hosting_basic_server_requirements() {
479 $help['title'] = t('Your own server');
480 $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.');
481 return $help;
482 }
483
484 /**
485 * Implementation of hook_requirements()
486 */
487 function _hosting_basic_unix_requirements() {
488 $help['title'] = t('A unix based operating system');
489 $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.</p>');
490 return $help;
491 }
492
493 /**
494 * Implementation of hook_requirements()
495 */
496 function _hosting_hosting_setup_requirements() {
497 $node = node_load(HOSTING_OWN_WEB_SERVER);
498 $drush_path = $node->drush_path;
499 $docroot = HOSTING_DEFAULT_DOCROOT_PATH;
500 $uri = HOSTING_DEFAULT_BASE_URL;
501 $username = HOSTING_DEFAULT_SCRIPT_USER;
502 $login_cmd = <<<EOF
503 su -s /bin/sh $username
504 EOF;
505 $setup_cmd = <<<EOF
506 cd $docroot
507 php $drush_path --uri=$uri hosting setup
508 EOF;
509 $help['title'] = t('Perform initial configuration by running the <code>Hosting Setup</code> command');
510
511 $help['summary'][] = t('The hosting setup command performs several useful installation functions, but its primary responsibility
512 is adding the crontab entry for the queue dispatcher and ensuring that has been correctly installed.');
513
514 $help['summary'][] = t('The queue dispatcher runs every minute. It keeps track of what work needs to be done on the system
515 and instructs the provisioning framework to perform the needed tasks in the task queue.');
516 $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.');
517 $help['configuration'][] = t('If you are not logged in as %script_user user, log in with command : <pre>@login_cmd</pre>',
518 array('%script_user' => $username, '@login_cmd' => $login_cmd));
519 $help['configuration'][] = t('Now execute the following commands : <pre>@setup_cmd</pre>',
520 array('%script_user' => $username, '@setup_cmd' => $setup_cmd));
521
522 return $help;
523 }
524
525 /**
526 * Implementation of hook_requirements()
527 */
528 function _hosting_cron_requirements() {
529 $cron_cmd['!queueconf'] = l(t("Queue administration"), "admin/settings/queues");
530 $cron_cmd['@cron_line'] = hosting_queues_cron_cmd();
531 $help['title'] = t('A cron entry for queue dispatcher.');
532 $help['summary'][] = t('Changes to this system are executed via a back end script which needs to be called by a user other than
533 the web server user for security reasons at regular intervals.');
534 $help['summary'][] = t('The intervals at which these commands are run can be customised by going to the !queueconf section.', $cron_cmd);
535 $help['summary'][] = t('The <code>hosting setup</code> command installs the required cron entry for you.', $cron_cmd);
536 $help['configuration'] = t('Add the following line to your crontab : <code>@cron_line</code>', $cron_cmd);
537 return $help;
538 }
539
540 /**
541 * Implementation of hook_requirements()
542 */
543 function _hosting_platform_requirements() {
544 $platform = node_load(HOSTING_OWN_PLATFORM);
545 $web_server = node_load(HOSTING_OWN_WEB_SERVER);
546 $db_server = node_load(HOSTING_OWN_DB_SERVER);
547
548 $task = hosting_get_most_recent_task($platform->nid, 'verify');
549
550 $help['title'] = t('Provisioning framework status');
551 $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 backend 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.');
552 $help['summary'][] = t('As hosting is also running on a platform, it is suggested that you successfully configure your <a href="@platform">primary platform</a>
553 before creating additional platforms and servers.', array('@platform' => url('node/' . HOSTING_OWN_PLATFORM)));
554 $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 <a href="@verify_link">Verify platform task of this platform</a>', array("@verify_link" => url("node/" . $task->nid)));
555
556 return $help;
557
558 }

  ViewVC Help
Powered by ViewVC 1.1.2