t("Web Server")); } /** * Implementation of hook_help(). */ function hosting_web_server_help($section) { switch ($section) { case 'admin/help/provision#requirements': $output .= _hosting_requirements('drush_path'); $output .= _hosting_requirements('config_path'); $output .= _hosting_requirements('httpd_conf'); $output .= _hosting_requirements('visudo'); return $output; break; } } function _hosting_config_path_requirements() { $username = HOSTING_DEFAULT_SCRIPT_USER; $group = HOSTING_DEFAULT_WEB_GROUP; $vhost_path = HOSTING_DEFAULT_CONFIG_PATH; $mkdir_cmd['@vhost_path'] = $vhost_path; $mkdir_cmd['@mkdir_cmd'] = <<@vhost_path.', $mkdir_cmd); $help['configuration'][] = t(' please enter the following commands :
@mkdir_cmd
', $mkdir_cmd); return $help; } function _hosting_drush_path_requirements() { $help['title'] = t('Full path to the Drush installation on this server.'); $help['summary'] = t('Drush is a command line script that is used to interact with Drupal sites through the unix shell.
To be able to use Aegir, you need to download Drush, and place it somewhere on your server that is accessible by the script user (eg: /home/!script_user/drush/drush.php).
Once Drush is installed, you are required to download Provision and place it in the .drush folder of the script user\'s home directory. (eg: /home/!script_user/.drush/provision).
', array('!script_user' => HOSTING_DEFAULT_SCRIPT_USER)); return $help; } function _hosting_httpd_conf_requirements() { $vhost_path = HOSTING_DEFAULT_VHOST_PATH; $vhost_line = << The location of this file differs between distributions, but is most commonly found in /etc/httpd or /etc/apache.'); $help['configuration'] = t('Once you have determined the location of your httpd.conf file, add the following line to it:
@vhost_line
', array('@vhost_line' => $vhost_line)); return $help; } function _hosting_visudo_requirements() { $username = HOSTING_DEFAULT_SCRIPT_USER; $cmd = trim(str_replace("sudo", '', HOSTING_DEFAULT_RESTART_CMD)); $cmd = substr($cmd, 0, strpos($cmd, " ")); $visudo_cmd['@visudo_cmd'] = <<@visudo_cmd Then add the following line to the file:
@visudo_line
', $visudo_cmd); return $help; } function hosting_web_server_node_info() { $types["web_server"] = array( "type" => 'web_server', "name" => 'Web server', "module" => 'hosting_web_server', "has_title" => true, "title_label" => t('Host name'), "description" => hosting_node_help("web_server"), "has_body" => 0, "body_label" => '', "min_word_count" => 0); return $types; } function hosting_web_server_hosting_feature() { $features['web_server'] = array( 'title' => t('Web servers'), 'description' => t('Allow for creation of multiple web server nodes, and for distributed management of sites.'), 'status' => HOSTING_FEATURE_DISABLED, 'node' => 'web_server', 'group' => 'experimental'); return $features; } function hosting_web_server_perm() { return array('create web server', 'view web server', 'edit web server', 'delete web server'); } function hosting_web_server_access($op, $node) { if (!hosting_feature('web_server')) { return FALSE; } switch ($op) { case 'create': return user_access('create web server'); break; case 'view': return user_access('view web server'); break; case 'update': return user_access('edit web server'); break; case 'delete': return user_access('delete web server'); break; default: break; } } /** * Small helper function to get web servers. */ function _hosting_get_web_servers() { $return = array(); $result = db_query("SELECT nid, title FROM {node} WHERE type='web_server' AND status=1"); while($server = db_fetch_object($result)) { $return[$server->nid] = $server->title; } return $return; } /** * Implementation of hook_form(). */ function hosting_web_server_form(&$node) { $type = node_get_types('type', $node); $form['title'] = array( '#type' => 'textfield', '#title' => t('Web server hostname'), '#required' => TRUE, '#default_value' => $node->title, '#description' => t('The host name of the server. This is the address that will be used by Hostmaster to connect to the web server to issue commands.
Be careful when changing the node title, it is used to create the SQL users if the IP address, below, is not set.'), '#weight' => -10 ); #TODO : rename to db_ip_address, to avoid confusion $form['ip_address'] = array( '#type' => 'textfield', '#title' => t('IP address'), '#default_value' => $node->ip_address, '#size' => 15, '#maxlength' => 15, '#description' => t("The IP address the server can be accessed by. This will be used to create database grants, amongst other things.
If this is empty, Hostmaster will attempt to resolve the hostname to get the address.
If that fails, the hostname (ie. the node title) will be used instead."), '#weight' => -9 ); $form['drush_path'] = array( '#type' => 'textfield', '#title' => t('Drush path'), '#required' => TRUE, '#size' => 40, '#default_value' => ($node->drush_path) ? $node->drush_path : '', '#description' => t("The full path to the drush.php script on this server."), '#maxlength' => 255, '#weight' => -8, ); $form['restart_cmd'] = array( '#type' => 'textfield', '#title' => t('Restart command'), '#required' => TRUE, '#description' => t('The command to run to restart the for new changes to take effect. This is required for the new site to become live'), '#default_value' => ($node->restart_cmd) ? $node->restart_cmd : HOSTING_DEFAULT_RESTART_CMD, '#size' => 40, '#maxlength' => 255, '#weight' => -7, ); $form['script_user'] = array( '#type' => 'textfield', '#title' => t('System account'), '#required' => TRUE, '#description' => t('The system account that the hosted files will belong to, for security reasons.
This should be a different to the account the web server is running as.'), '#default_value' => ($node->script_user) ? $node->script_user : HOSTING_DEFAULT_SCRIPT_USER, '#size' => 20, '#maxlength' => 255, '#weight' => -6, ); $form['web_group'] = array( '#type' => 'textfield', '#title' => t('Web server group'), '#required' => TRUE, '#description' => t('The group that the hosted files will belong to.
This should be the group the web server is running as.'), '#default_value' => ($node->web_group) ? $node->web_group : HOSTING_DEFAULT_WEB_GROUP, '#size' => 20, '#maxlength' => 75, '#weight' => -5, ); $form['config_path'] = array( '#type' => 'textfield', '#title' => t('Configuration path'), '#required' => TRUE, '#size' => 40, '#default_value' => ($node->config_path) ? $node->config_path : HOSTING_DEFAULT_CONFIG_PATH, '#description' => t("The path on the server where configuration files will be stored.
It is essential that this directory should not be accessible via a web browser."), '#maxlength' => 255, '#weight' => -4, ); $form['backup_path'] = array( '#type' => 'textfield', '#title' => t('Backup path'), '#required' => TRUE, '#size' => 40, '#default_value' => ($node->backup_path) ? $node->backup_path : HOSTING_DEFAULT_BACKUP_PATH, '#description' => t("The path on the server where backups will be stored.
It is essential that this directory should not be accessible via a web browser."), '#maxlength' => 255, '#weight' => -3, ); return $form; } /** * Implementation of hook_validate(). */ function hosting_web_server_validate(&$node, &$form) { if ($node->script_user == 'root') { form_set_error('script_user', t('For security reasons, you should not run drush commands as the root user. Please choose a different system account name.')); } if (!$node->ip_address) { if (!_hosting_valid_fqdn($node->title)) { form_set_error('title', t('Invalid valid domain name. Either choose a proper domain name or hardcode the IP address of the webserver.')); } $ip = gethostbyname($node->title); // setup IP only if resolution succeeded if ($ip != $node->title) { form_set_value($form['ip_address'], $ip); $node->ip_address = $ip; // required to fool the ip check below drupal_set_message(t('Initialized the webserver IP to %ip based on hostname %name', array('%ip' => $ip, '%name' => $node->title)), 'message'); } else { form_set_error('title', t('Could not resolve IP address of webserver %name. Either set the web server name to a FQDN (Fully Qualified Domain Name) or hardcode the IP here.', array('%name' => $node->title))); } } if (!_hosting_valid_ip($node->ip_address)) { form_set_error('ip_address', t('Invalid IP address')); } } /** * Implementation of hook_insert(). */ function hosting_web_server_insert($node) { db_query("INSERT INTO {hosting_web_server} (vid, nid, ip_address, script_user, web_group, config_path, backup_path, restart_cmd, drush_path) VALUES (%d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s')", $node->vid, $node->nid, $node->ip_address, $node->script_user, $node->web_group, $node->config_path, $node->backup_path, $node->restart_cmd, $node->drush_path); } /** * Implementation of hook_update(). * * As an existing node is being updated in the database, we need to do our own * database updates. */ function hosting_web_server_update($node) { // if this is a new node or we're adding a new revision, if ($node->revision) { hosting_web_server_insert($node); } else { db_query("UPDATE {hosting_web_server} SET ip_address = '%s', script_user = '%s', web_group = '%s', config_path = '%s', backup_path = '%s', restart_cmd = '%s', drush_path = '%s' WHERE vid = %d", $node->ip_address, $node->script_user, $node->web_group, $node->config_path, $node->backup_path, $node->restart_cmd, $node->drush_path, $node->vid); } } function hosting_nodeapi_web_server_delete_revision(&$node) { db_query('DELETE FROM {hosting_web_server} WHERE vid = %d', $node->vid); } /** * Implementation of hook_delete(). */ function hosting_web_server_delete($node) { db_query('DELETE FROM {hosting_web_server} WHERE nid = %d', $node->nid); } /** * Implementation of hook_load(). */ function hosting_web_server_load($node) { $additions = db_fetch_object(db_query('SELECT ip_address, script_user, web_group, config_path, backup_path, restart_cmd, drush_path FROM {hosting_web_server} WHERE vid = %d', $node->vid)); return $additions; } /** * Implementation of hook_view(). */ function hosting_web_server_view($node, $teaser = FALSE, $page = FALSE) { $node = node_prepare($node, $teaser); $node->content['info'] = array( '#prefix' => '
', '#suffix' => '
' ); if ($node->ip_address) { $node->content['info']['ip_address'] = array( '#type' => 'item', '#title' => t('IP address'), '#value' => filter_xss($node->ip_address), ); } $node->content['info']['drush_path'] = array( '#type' => 'item', '#title' => t('Drush path'), '#value' => filter_xss($node->drush_path), ); $node->content['info']['script_user'] = array( '#type' => 'item', '#title' => t('Script user'), '#value' => filter_xss($node->script_user), ); $node->content['info']['web_group'] = array( '#type' => 'item', '#title' => t('Web server group'), '#value' => filter_xss($node->web_group), ); $node->content['info']['config_path'] = array( '#type' => 'item', '#title' => t('Configuration path'), '#value' => filter_xss($node->config_path), ); $node->content['info']['backup_path'] = array( '#type' => 'item', '#title' => t('Backup path'), '#value' => filter_xss($node->backup_path), ); $node->content['info']['restart_cmd'] = array( '#type' => 'item', '#title' => t('Restart command'), '#value' => filter_xss($node->restart_cmd), ); return $node; } function hosting_web_server_hosting_summary() { $summary = array(); $web_servers = _hosting_get_web_servers(); $summary['web_servers'] = theme('item_list', array_map('_hosting_node_link', array_keys($web_servers)), t('Web servers')); return $summary; } function hosting_web_server_form_alter($form_id, &$form) { switch ($form_id) { case 'web_server_node_form': if ($form['#post']['op'] == 'Preview' && !$form['#post']['ip_address']) { $ip = gethostbyname($form['#post']['title']); // setup IP only if resolution succeeded if ($ip != $node->title) { drupal_set_message(t('Initialized the webserver IP to %ip based on hostname %name', array('%ip' => $ip, '%name' => $form['#post']['title'])), 'message'); $form['#post']['ip_address'] = $ip; } } break; } }