provision.drush.inc 10.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
<?php
/**
 * Drush commands
 *
 *
 * This module provides a framework for a Drupal site to manage and install new Drupal sites, using the command line
 * Drush utility. 
 *
 * It allows for pluggable 'provisioning modules' that can extend and modify the tasks that are taken during installation.
 *
 * Each site has the following commands that can be run on it.
 *
 * Implemented : 
 *   install - Install a new Drupal site. The install command uses 3 separate hooks to do it's job, 
 *              namely hook_provision_pre_install(), hook_provision_install() and hook_provision_post_install()
 *   verify  - Recreate all configuration files, to be in synch with changes in the front end. And test that they are correct.
 *   stats   - Return an associated array of site statistics. (implemented in provision_stats module, is thus optional)
 *   import  - Import the details of an already existing site into the provisioning framework.
 *             This command inspects the settings.php and generates the site.php file that the framework uses for configuration.
 *   backup  - Generates a tarball containing the sites directory, the site data configuration and the database dump.
 *             This allows the tarball to act as a 'site package', which can be redeployed on other installations,
 *             or used for an upgrade.
 *   disable - Disable an installed Drupal site. Changes the virtual host config file so that it redirects to provision_disabled_site_redirect_url
 *   enable  - Re-enable a site that has already been disabled. Recreates the virtual host file.
 *   delete -  Generates a back up of the site, and then removes all references to it.
 *   restore - Revert to a previous backup of the site.
 *   cron - Run cron process for a site
 *
 *   upgrade - Accepts a site package (backup) as argument, and redeploys it, running the upgrade processes on it.
 *             Uses hook_provision_pre_upgrade(), hook_provision_upgrade() and hook_provision_post_upgrade() hooks,
 *             and allows clean roll back if any errors occur. Will include stringent checking of module versions,
 *             and allow unit tests to be run.
33
 * Not implemented yet :
34 35 36 37 38 39 40
 *   rename  - Change the url of a site. This requires moving of files, and numerous other issues.
 */

/**
 * @defgroup provisiondrush Command line interface for Provision.
 * @{
 */
41 42 43 44 45 46 47 48 49 50 51 52 53 54
include_once('provision.inc');
include_once('provision.path.inc');
provision_init();
/** 
 * Implementation of hook_init
 *
 * Provide defines for all the major paths and settings.
 * These are settings that must not be modified during the running of the
 * program, but are configurable.
 */
function provision_init() {
  // Do not allow the program to be run as the root user. ever
  $name = posix_getpwuid(posix_geteuid());
  if ($name['name'] == 'root') {
55
    return drush_set_error(PROVISION_IS_ROOT, dt('You are running the provision script as the root user. Exiting'));
56 57 58
  }

  // Set up defines for platform
59
  $docroot = drush_get_option(array("r", "root"), $_SERVER['PWD']);
60
  
61 62
  drush_set_default('provision_domain', $_SERVER['HTTP_HOST']);

63
  // Paths
64 65 66 67
  $path = drush_set_default('docroot_path', rtrim(($docroot) ? $docroot : $_SERVER['DOCUMENT_ROOT'], '/'));
  drush_set_default('sites_path', $path . '/sites');

  $parts = explode("/", $path);
68
  array_pop($parts);
69 70 71 72 73 74 75 76
  $parent_path = drush_set_default('parent_path', implode("/" , $parts));


  drush_set_default('backup_path', $parent_path . '/backups');
  drush_set_default('config_path', $parent_path . '/config');

  $config_path = drush_get_option('config_path');
  drush_set_default('vhost_path', $config_path . '/vhost.d');
77 78

  // Commands
79
  drush_set_default('restart_cmd', _provision_default_restart_cmd());
80 81

  // System account
82 83
  drush_set_default('web_group', _provision_default_web_group());
  drush_set_default('script_user', get_current_user());
84 85

  // Redirection urls
86 87 88 89
  drush_set_default('master_url', $GLOBALS['base_url']);
  $master_url = drush_get_option('master_url');
  drush_set_default('web_disable_url', $master_url .'/provision/disabled');
  drush_set_default('web_maintenence_url', $master_url .'/provision/maintenance');
90 91

  // Database
92 93 94 95 96 97 98 99 100
  drush_set_default('master_db', $GLOBALS['db_url']);

  $master_db = drush_get_option('master_db');
  $db = parse_url($master_db);
  drush_set_default('master_db_user', $db['user']);
  drush_set_default('master_db_passwd', $db['pass']);

  drush_set_default('master_db_host', $db['host']);
  drush_set_default('db_host', $db['host']);
101
 
102 103 104 105 106 107 108 109 110 111
  drush_set_default('master_db_type', $db['scheme']);
  drush_set_default('db_type', $db['scheme']);

  drush_set_default('publish_path', drush_get_option('docroot_path'));
  drush_set_default('site_url', $url); 
  drush_set_default('profile', 'default');
  drush_set_default('web_ip', '127.0.0.1');
  drush_set_default('web_port', 80); 
  drush_set_default('language', 'en');
  drush_set_default('aliases', array());
112 113
}

114 115 116 117 118

/**
 * Implementation of hook_drush_command().
 */
function provision_drush_command() {
119

120 121 122
  $items['provision install'] = array(
    'callback' => 'provision_command',
    'callback arguments' => array('install'),
123 124
    'arguments' => array('domain.com' => dt('The domain of the site to install.')),
    'description' => dt('Provision a new site using the provided data.'),
125
    'bootstrap' => -1
126 127 128 129 130
  );

  $items['provision import'] = array(
    'callback' => 'provision_command',
    'callback arguments' => array('import'),
131 132
    'arguments' => array('domain.com' => dt('The domain of the site to import.')),
    'description' => dt('Turn an already running site into a provisioned site.'),
133
    'bootstrap' => -1
134 135 136 137 138
  );

  $items['provision update'] = array(
    'callback' => 'provision_command',
    'callback arguments' => array('update'),
139
    'arguments' => array('domain.com' => dt('The domain of the site to update.')),
140 141
    'description' => dt('Run any outstanding updates on the site.'),
    'bootstrap' => -1
142 143 144 145 146
  );
  
  $items['provision backup'] = array(
    'callback' => 'provision_command',
    'callback arguments' => array('backup'),
147 148
    'arguments' => array('domain.com' => dt('The domain of the site to back up.')),
    'optional arguments' => array('backup-file' => dt('The file to save the backup to. This will be a gzipped tarball.')),
149 150
    'description' => dt('Generate a back up for the site.'),
    'bootstrap' => -1
151 152 153 154 155
  );
  
  $items['provision enable'] = array(
    'callback' => 'provision_command',
    'callback arguments' => array('enable'), 
156
    'arguments' => array('domain.com' => dt('The domain of the site to enable (only if enabled).')),
157 158
    'description' => 'Enable a disabled site.',
    'bootstrap' => -1
159 160 161 162
  );
  $items['provision disable'] = array(
    'callback' => 'provision_command',
    'callback arguments' => array('disable'), 
163
    'arguments' => array('domain.com' => dt('The domain of the site to disable (only if disabled).')),    
164 165
    'description' => 'Disable a site.',
    'bootstrap' => -1
166 167 168 169 170
  );

  $items['provision verify'] = array(
    'callback' => 'provision_command',
    'callback arguments' => array('verify'),
171 172
    'arguments' => array('domain.com' => dt('The domain of the site to verify).')),    
    'description' => 'Verify that the provisioning framework is correctly installed.',
173
    'bootstrap' => -1
174 175 176 177 178 179
  );
 
  $items['provision restore'] = array(
    'callback' => 'provision_command',
    'callback arguments' => array('restore'),
    'description' => 'Restore the site to a previous backup. This will also generate a backup of the site as it was.',
180
    'arguments' => array('domain.com' => dt('The domain of the site to be restored'),
181 182 183 184 185 186 187 188 189 190
      'site_backup.tar.gz' => dt('The backup to restore the site to.')),
    'bootstrap' => -1
  );

  $items['provision deploy'] = array(
    'callback' => 'provision_command',
    'callback arguments' => array('deploy'),
    'description' => 'Deploy an existing backup to a new url.',
    'arguments' => array('domain.com' => dt('The domain to deploy the site package to.'),
      'site_backup.tar.gz' => dt('The backup to deploy.')),
191
    'bootstrap' => -1
192
  );
193 194 195 196 197 198 199 200 201

  $items['provision migrate'] = array(
    'callback' => 'provision_command',
    'callback arguments' => array('migrate'),
    'description' => 'Migrate a site between platforms.',
    'arguments' => array('domain.com' => dt('The domain to migrate. Any outstanding updates will be run.'),
      '/path/to/platform' => dt('The platform to migrate the site to.')),
    'bootstrap' => -1
  );
202 203 204 205
 
  $items['provision delete'] = array(
    'callback' => 'provision_command',
    'callback arguments' => array('delete'),
206 207
    'description' => 'Delete a site.',
    'bootstrap' => -1
208 209 210 211 212 213
  );

  $items['provision cron'] = array(
    'callback' => 'provision_command',
    'callback arguments' => array('cron'),
    'description' => 'Run cron process for site.',
214 215
    'arguments' => array('domain.com' => dt('The domain of the site to be processed')),
    'bootstrap' => -1
216 217 218 219 220 221
  );
 
  return $items;
}


222 223 224 225
/**
 * Generate a provision.settings.php file to configure provision
 */
function _provision_generate_config() {
226
  drush_log(dt("Generating drushrc.php file"));
227
  provision_path("chmod", drush_get_option('docroot_path') . '/drushrc.php', 0600,
228 229 230 231
     dt('Changed permissions of drushrc.php to @confirm'),
      dt('Could not change permissions of drushrc.php to @confirm'));

  provision_save_platform_data();
232
  provision_path("chmod", drush_get_option('docroot_path') . '/drushrc.php', 0400,
233 234 235 236 237 238 239 240 241
    dt('Changed permissions of drushrc.php to @confirm'),
    dt('Could not change permissions of drushrc.php to @confirm'));
  return TRUE;
}



function _provision_default_restart_cmd() {
  $command = '/usr/sbin/apachectl'; # a proper default for most of the world
242 243 244 245 246 247 248 249 250 251
  foreach (explode(':', $_SERVER['PATH']) as $path) {
    $options[] = "$path/apache2ctl";
    $options[] = "$path/apachectl";
  }
  # try to detect the apache restart command
  $options[] = '/usr/local/sbin/apachectl'; # freebsd
  $options[] = '/usr/sbin/apache2ctl'; # debian + apache2
  $options[] = $command;

  foreach ($options as $test) {
252 253
    if (is_executable($test)) {
      $command = $test;
254
      break;
255 256 257 258 259 260
    }
  }

  return "sudo $command graceful";
}

261
function _provision_default_web_group() {
262
  $info = posix_getgrgid(posix_getgid());
263 264 265 266 267 268
  $common_groups = array(
    'httpd',
    'www-data', 
    'apache',
    'nogroup',
    'nobody',
269
    $info['name']);
270 271 272 273 274 275 276 277 278 279

  foreach ($common_groups as $group) {
    if (provision_posix_groupname($group)) {
      return $group;
      break;
    }
  }
  return null;
}