provision.drush.inc 8.88 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
<?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.
25
 *   delete  - Generates a back up of the site, and then removes all references to it.
26 27
 *   restore - Revert to a previous backup of the site.
 *
28
 *   deploy  - Accepts a site package (backup) as argument, and redeploys it, running the upgrade processes on it.
29 30 31
 *             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.
32 33
 *   login_reset - Generate a one-time login reset URL.
 *
34
 * Not implemented yet :
35 36 37
 *   rename  - Change the url of a site. This requires moving of files, and numerous other issues.
 */

38 39 40
// Do not allow the program to be run as the root user. ever
$name = posix_getpwuid(posix_geteuid());
if ($name['name'] == 'root') {
41
  return drush_set_error('PROVISION_IS_ROOT', dt('You are running the provision script as the root user. Exiting'));
42 43
}

44 45 46 47
/**
 * @defgroup provisiondrush Command line interface for Provision.
 * @{
 */
48 49
include_once('provision.inc');
include_once('provision.path.inc');
50 51 52 53 54

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

56
  $items['provision-install'] = array(
57 58
    'arguments' => array('domain.com' => dt('The domain of the site to install.')),
    'description' => dt('Provision a new site using the provided data.'),
59
    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT
60 61
  );

62
  $items['provision-import'] = array(
63 64
    'arguments' => array('domain.com' => dt('The domain of the site to import.')),
    'description' => dt('Turn an already running site into a provisioned site.'),
65
    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT
66 67
  );

68
  $items['provision-backup'] = array(
69 70
    '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.')),
71
    'description' => dt('Generate a back up for the site.'),
72
    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT
73 74
  );
  
75
  $items['provision-enable'] = array(
76
    'arguments' => array('domain.com' => dt('The domain of the site to enable (only if enabled).')),
77
    'description' => 'Enable a disabled site.',
78
    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT
79
  );
80
  $items['provision-disable'] = array(
81
    'arguments' => array('domain.com' => dt('The domain of the site to disable (only if disabled).')),    
82
    'description' => 'Disable a site.',
83
    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT
84 85
  );

86
  $items['provision-verify'] = array(
87 88
    'arguments' => array('domain.com' => dt('The domain of the site to verify).')),    
    'description' => 'Verify that the provisioning framework is correctly installed.',
89
    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT, 
90 91
  );
 
92
  $items['provision-restore'] = array(
93
    'description' => 'Restore the site to a previous backup. This will also generate a backup of the site as it was.',
94
    'arguments' => array('domain.com' => dt('The domain of the site to be restored'),
95
      'site_backup.tar.gz' => dt('The backup to restore the site to.')),
96
    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT
97 98
  );

99
  $items['provision-deploy'] = array(
100 101 102
    '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.')),
103
    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT
104
  );
105

106
  $items['provision-migrate'] = array(
107 108 109
    '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.')),
110
    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT
111
  );
112

113
  $items['provision-clone'] = array(
114 115 116 117 118 119
    'description' => 'Clone a site between platforms.',
    'arguments' => array('domain.com' => dt('The domain to clone. Any outstanding updates will be run.'),
      'new.domain.com' => dt('The new domain name to use.'),
      '/path/to/platform' => dt('The platform to clone the site to.')),
    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT
  );
120
 
121
  $items['provision-delete'] = array(
122
    'description' => 'Delete a site.',
123
    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT
124 125
  );

126
  $items['provision-login_reset'] = array(
127 128 129 130 131
    'description' => 'Generate a one-time login reset URL.',
    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT
  );
  

132
  $items['hostmaster-migrate'] = array(
133 134 135 136 137 138 139 140
    'description' => dt('Migrate an instance of the Hostmaster front end to a new platform'),
    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT,
    'arguments' => array(
      'example.com' => dt('The name of the site to migrate'),
      '/path/to/platform' => dt('The platform to migrate the site to.')
    ),
  );

141
  $items['hostmaster-make'] = array(
142 143 144 145 146 147 148 149
    'description' => dt('Build a platform containing the Hostmaster user interface for provision.'),
    'bootstrap' => DRUSH_BOOTSTRAP_DRUSH,
    'arguments' => array(
      '/path/to/platform' => dt('The path to create the platform in.')
    ),
  );

  
150
  $items['hostmaster-pause'] = array(
151 152 153 154 155
    'description' => dt('Prepare the site to be migrated to a new platform.'),
    'arguments' => array(
      'example.com' => dt('The url of the site being migrated.')),
  );

156
  $items['hostmaster-resume'] = array(
157 158 159 160 161 162
    'description' => dt('Complete the migration of the site to a new platform.'),
    'arguments' => array(
      'example.com' => dt('The url of the site being migrated.')),
  );


163 164 165 166
  return $items;
}


167 168 169 170
function drush_provision_hostmaster_make($platform) {
  drush_backend_invoke('make', array(dirname(__FILE__) . '/aegir.make', $platform));
}

171 172 173 174
/**
 * Generate a provision.settings.php file to configure provision
 */
function _provision_generate_config() {
175 176 177 178 179 180 181 182 183 184
  $exists = provision_path_exists(drush_get_option('docroot_path') . '/drushrc.php');
  if ($exists) {
    drush_log(dt("Found existing drushrc.php file"));
    provision_path("chmod", drush_get_option('docroot_path') . '/drushrc.php', 0600,
       dt('Changed permissions of drushrc.php to @confirm'),
        dt('Could not change permissions of drushrc.php to @confirm'));
  }
  else {
    drush_log(dt("Generating drushrc.php file"));
  }
185
  provision_save_platform_data();
186
  provision_path("chmod", drush_get_option('docroot_path') . '/drushrc.php', 0400,
187 188 189 190 191 192 193 194 195
    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
196 197 198 199 200 201 202 203 204 205
  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) {
206 207
    if (is_executable($test)) {
      $command = $test;
208
      break;
209 210 211 212 213 214
    }
  }

  return "sudo $command graceful";
}

215
function _provision_default_web_group() {
216
  $info = posix_getgrgid(posix_getgid());
217 218 219 220 221 222
  $common_groups = array(
    'httpd',
    'www-data', 
    'apache',
    'nogroup',
    'nobody',
223
    $info['name']);
224 225 226 227 228 229 230 231 232 233

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