Commit cd53f8c0 authored by Adrian Rossouw's avatar Adrian Rossouw

Merge branch 'dev-newhooks' into dns_merge

Conflicts:
	provision.config.inc
	provision.environment.inc
	provision.service.inc
parents 4fdd1d38 5fc7742b
......@@ -32,29 +32,36 @@ function db_drush_help($section) {
class provisionService_db extends provisionService {
protected $service = 'db';
/**
* Register the db handler for sites, based on the db_server option.
*/
static function subscribe_site($context) {
$context->setProperty('db_server', '@server_master');
$context->is_oid('db_server');
$context->service_subscribe('db', $context->db_server->name);
}
static function option_documentation() {
return array(
'--master_db' => 'server with db: Master database connection info, {type}://{user}:{password}@{host}',
);
}
function init() {
parent::init();
function init_server() {
parent::init_server();
$this->server->setProperty('master_db');
$this->creds = array_map('urldecode', parse_url($this->server->master_db));
return TRUE;
}
function verify() {
if ($this->context->type == 'server') {
$this->connect();
if ($this->can_create_database()) {
drush_log(dt('Provision can create new databases.'), 'message');
}
else {
drush_set_error('PROVISION_CREATE_DB_FAILED');
}
function verify_server_cmd() {
$this->connect();
if ($this->can_create_database()) {
drush_log(dt('Provision can create new databases.'), 'message');
}
else {
drush_set_error('PROVISION_CREATE_DB_FAILED');
}
}
......@@ -258,8 +265,8 @@ class provisionService_db_pdo extends provisionService_db {
protected $creds;
private $dsn;
function init() {
parent::init();
function init_server() {
parent::init_server();
$this->dsn = sprintf("%s:host=%s", $this->PDO_type, $this->creds['host']);
}
......
......@@ -12,8 +12,8 @@ class provisionService_http_apache extends provisionService_http_public {
return TRUE;
}
function init() {
parent::init();
function init_server() {
parent::init_server();
$this->configs['server'][] = 'provisionConfig_apache_server';
$this->configs['platform'][] = 'provisionConfig_apache_platform';
$this->configs['site'][] = 'provisionConfig_apache_site';
......
......@@ -28,6 +28,15 @@ class provisionService_http extends provisionService {
$this->parse_configs();
}
/**
* Register the http handler for platforms, based on the web_server option.
*/
static function subscribe_platform($context) {
$context->setProperty('web_server', '@server_master');
$context->is_oid('web_server');
$context->service_subscribe('http', $context->web_server->name);
}
}
// Public http service , as in non-encrypted and listening on a port.
......@@ -70,8 +79,8 @@ class provisionService_http_public extends provisionService_http {
return $data;
}
function init() {
parent::init();
function init_server() {
parent::init_server();
// System account
if ($this->server->name == '@server_master') {
$this->server->setProperty('web_group', _provision_default_web_group());
......@@ -104,25 +113,34 @@ class provisionService_http_public extends provisionService_http {
}
function verify() {
if ($this->context->type === 'server') {
if (!is_null($this->application_name)) {
provision_file()->create_dir($this->server->http_confd_path, dt("Webserver custom configuration"), 0700);
$this->sync($this->server->http_confd_path);
provision_file()->create_dir($this->server->http_platformd_path, dt("Webserver platform configuration"), 0700);
$this->sync($this->server->http_platformd_path, array(
'exclude' => $this->server->http_platformd_path . '/*', // Make sure remote directory is created
));
provision_file()->create_dir($this->server->http_vhostd_path , dt("Webserver virtual host configuration"), 0700);
$this->sync($this->server->http_vhostd_path, array(
'exclude' => $this->server->http_vhostd_path . '/*', // Make sure remote directory is created
));
}
}
function verify_server_cmd() {
if (!is_null($this->application_name)) {
provision_file()->create_dir($this->server->http_confd_path, dt("Webserver custom configuration"), 0700);
$this->sync($this->server->http_confd_path);
parent::verify();
provision_file()->create_dir($this->server->http_platformd_path, dt("Webserver platform configuration"), 0700);
$this->sync($this->server->http_platformd_path, array(
'exclude' => $this->server->http_platformd_path . '/*', // Make sure remote directory is created
));
provision_file()->create_dir($this->server->http_vhostd_path , dt("Webserver virtual host configuration"), 0700);
$this->sync($this->server->http_vhostd_path, array(
'exclude' => $this->server->http_vhostd_path . '/*', // Make sure remote directory is created
));
}
$this->create_config($this->context->type);
$this->parse_configs();
}
function verify_site_cmd() {
$this->create_config($this->context->type);
$this->parse_configs();
}
function verify_platform_cmd() {
$this->create_config($this->context->type);
$this->parse_configs();
}
/**
......
......@@ -18,8 +18,8 @@ class provisionService_http_ssl extends provisionService_http_public {
return 443;
}
function init() {
parent::init();
function init_server() {
parent::init_server();
// SSL Port.
$this->server->setProperty('http_ssl_port', $this->default_ssl_port());
......@@ -34,6 +34,13 @@ class provisionService_http_ssl extends provisionService_http_public {
$this->server->http_ssld_path = "{$this->server->config_path}/ssl.d";
}
function init_site() {
parent::init_site();
$this->context->setProperty('ssl_enabled', 0);
$this->context->setProperty('ssl_key', null);
}
function config_data($config = null, $class = null) {
$data = parent::config_data($config, $class);
......
......@@ -19,9 +19,9 @@ class provisionConfig {
public $data = array();
/**
* A provisionEnvironment object thie configuration relates to.
* A provisionContext object thie configuration relates to.
*
* @var provisionEnvironment
* @var provisionContext
*/
public $context = null;
......@@ -64,7 +64,7 @@ class provisionConfig {
* Constructor, overriding not recommended.
*
* @param $context
* An alias name for d(), the provisionEnvironment that this configuration
* An alias name for d(), the provisionContext that this configuration
* is relevant to.
* @param $data
* An associative array to potentiall manipulate in process() and make
......@@ -81,7 +81,6 @@ class provisionConfig {
if (sizeof($data)) {
$this->data = $data;
}
if (!is_null($this->data_store_class) && class_exists($this->data_store_class)) {
$class = $this->data_store_class;
......
This diff is collapsed.
<?php
// $Id$
/**
* @file Provision named context platform class.
*/
/**
* Class for the platform context.
*/
class provisionContext_platform extends provisionContext {
public $parent_key = 'server';
static function option_documentation() {
return array(
'--root' => 'platform: path to a Drupal installation',
'--server' => 'drush backend server; default @server_master',
'--web_server' => 'web server hosting the platform; default @server_master',
);
}
function init_platform() {
$this->setProperty('root');
$this->setProperty('makefile', '');
}
}
<?php
// $Id$
/**
* @file Provision named context server class.
*/
/**
* Server context class.
*
* This class bootstraps the Service API by generating server
* objects for each of the available service types.
*/
class provisionContext_server extends provisionContext {
/**
* Associative array of services for this server.
*
* @see provisionService
*/
protected $services = array();
static function option_documentation() {
$options = array(
'--remote_host' => 'server: host name; default localhost',
'--script_user' => 'server: OS user name; default current user',
'--aegir_root' => 'server: Aegir root; default ' . getenv('HOME'),
'--master_url' => 'server: Hostmaster URL',
);
foreach (drush_command_invoke_all('provision_services') as $service => $default) {
$reflect = new reflectionClass('provisionService_' . $service);
$base_dir = dirname($reflect->getFilename());
$types = array();
$options['--' . $service . '_service_type'] = 'placeholder';
foreach (array_keys(drush_scan_directory($base_dir, '%.*_service\.inc%')) as $service_file) {
if (preg_match('%^' . $base_dir . '/([a-z]+)/(?:\1)_service.inc$%', $service_file, $match)) {
$types[] = $match[1];
include_once($service_file);
$options = array_merge($options, call_user_func(array(sprintf('provisionService_%s_%s', $service, $match[1]), 'option_documentation')));
}
}
$options['--' . $service . '_service_type'] = 'server: ' . implode(', ', $types) . ', or null; default ' . (empty($default) ? 'null' : $default);
}
return $options;
}
function init_server() {
$this->setProperty('remote_host', 'localhost');
if ($this->name == '@server_master') {
$this->setProperty('aegir_root', getenv('HOME'));
$this->setProperty('script_user', provision_current_user());
}
else {
$this->aegir_root = d('@server_master')->aegir_root;
$this->script_user = d('@server_master')->script_user;
}
$this->setProperty('ip_addresses', array(), true);
$this->backup_path = $this->aegir_root . '/backups';
$this->config_path = $this->aegir_root . '/config/' . ltrim($this->name, '@');
$this->include_path = $this->aegir_root . '/config/includes';
$this->setProperty('master_url');
$this->setProperty('admin_email', 'admin@' . $this->remote_host);
$this->load_services();
}
/**
* Iterate through the available service types and spawn a handler for each type.
*/
function load_services() {
$service_list = drush_command_invoke_all('provision_services');
foreach ($service_list as $service => $default) {
$this->spawn_service($service, $default);
}
}
/**
* Spawn an instance for a specific service type and associate it to the owner.
*/
function spawn_service($service, $default = null) {
$reflect = new reflectionClass('provisionService_' . $service);
$base_dir = dirname($reflect->getFilename());
$type_option = "{$service}_service_type";
$type = isset($this->options[$type_option]) ? $this->options[$type_option] : $default;
if ($service === 'file') {
// Force provision-save local
$command = drush_get_command();
if (preg_match("/^provision-save\b/", $command['command'])) {
$type = 'local';
}
}
if ($type) {
$file = sprintf("%s/%s/%s_service.inc", $base_dir, $type, $type);
$className = sprintf("provisionService_%s_%s", $service, $type);
if (file_exists($file)) {
drush_log("Loading $type driver for the $service service");
include_once($file);
$object = new $className($this->name);
$this->services[$service] = $object;
$this->setProperty($type_option, $type);
}
}
else {
$this->services[$service] = new provisionService_null($this->name);
}
}
/**
* Retrieve a service of a specific type from the context.
*/
function service($service, $name = null) {
$this->services[$service]->setContext(($name) ? $name : $this->name);
return $this->services[$service];
}
/**
* Retrieve a list of service objects associated with this server.
*/
function get_services() {
$services = array();
foreach ($this->services as $service => $object) {
$services[$service] = $this->name;
}
return $services;
}
function verify() {
$this->type_invoke('verify');
}
/**
* Execute $command on this server, using SSH if necessary.
*
* @param $command
* Shell command to execute.
*
* @return
* Same as drush_shell_exec(). Use drush_shell_exec_output() for standard
* out and error.
*/
function shell_exec($command) {
if (provision_is_local_host($this->remote_host)) {
return drush_shell_exec(escapeshellcmd($command));
}
else {
return drush_shell_exec('ssh ' . drush_get_option('ssh-options', '-o PasswordAuthentication=no') . ' %s %s', $this->script_user . '@' . $this->remote_host, escapeshellcmd($command));
}
}
/**
* If necessary, sync files out to a remote server.
*
* @param $path
* Full path to sync.
* @param $additional_options
* An array of options that overrides whatever was passed in on the command
* line (like the 'process' context, but only for the scope of this one
* call).
*/
function sync($path = NULL, $additional_options = array()) {
if (!provision_is_local_host($this->remote_host)) {
if (is_null($path)) {
$path = $this->config_path;
}
if (provision_file()->exists($path)->status()) {
$options = array_merge(array(
'relative' => TRUE,
'omit-dir-times' => TRUE,
'delete' => TRUE,
), $additional_options);
// We need to do this due to how drush creates the rsync command.
// If the option is present at all , even if false or null, it will
// add it to the command.
if (!isset($additional_options['no-delete'])) {
$options['delete'] = TRUE;
}
if (drush_core_call_rsync(escapeshellarg($path), escapeshellarg($this->script_user . '@' . $this->remote_host . ':/'), $options, TRUE, FALSE)) {
drush_log(dt('@path has been synced to remote server @remote_host.', array('@path' => $path, '@remote_host' => $this->remote_host)));
}
else {
drush_set_error('PROVISION_FILE_SYNC_FAILED', dt('@path could not be synced to remote server @remote_host. Changes might not be available until this has been done. (error: %msg)', array('@path' => $path, '@remote_host' => $this->remote_host, '%msg' => join("\n", drush_shell_exec_output()))));
}
}
else { // File does not exist, remove it.
if ($this->shell_exec('rm -rf ' . escapeshellarg($path))) {
drush_log(dt('@path has been removed from remote server @remote_host.', array('@path' => $path, '@remote_host' => $this->remote_host)));
}
else {
drush_set_error('PROVISION_FILE_SYNC_FAILED', dt('@path could not be removed from remote server @remote_host. Changes might not be available until this has been done. (error: %msg)', array('@path' => $path, '@remote_host' => $this->remote_host, '%msg' => join("\n", drush_shell_exec_output()))));
}
}
}
}
/**
* If necessary, fetch file from a remote server.
*
* @param $path
* Full path to fetch.
*/
function fetch($path) {
if (!provision_is_local_host($this->remote_host)) {
if (provision_file()->exists($path)->status()) {
$options = array(
'omit-dir-times' => TRUE,
);
if (drush_core_call_rsync(escapeshellarg($this->script_user . '@' . $this->remote_host . ':/') . $path, $path, $options, TRUE, FALSE)) {
drush_log(dt('@path has been fetched from remote server @remote_host.', array(
'@path' => $path,
'@remote_host' => $this->remote_host))
);
}
else {
drush_set_error('PROVISION_FILE_SYNC_FAILED', dt('@path could not be fetched from remote server @remote_host.' .
' Changes might not be available until this has been done. (error: %msg)', array(
'@path' => $path,
'@remote_host' => $this->remote_host,
'%msg' => join("\n", drush_shell_exec_output())))
);
}
}
}
}
}
<?php
// $Id$
/**
* @file Provision named context site class.
*/
class provisionContext_site extends provisionContext {
public $parent_key = 'platform';
static function option_documentation() {
return array(
'--platform' => 'site: the platform the site is run on',
'--db_server' => 'site: the db server the site is run on',
'--uri' => 'site: example.com URI, no http:// or trailing /',
'--language' => 'site: site language; default en',
'--aliases' => 'site: comma-separated URIs',
'--redirection' => 'site: boolean for whether --aliases should redirect; default false',
'--client_email' => 'site: email for the site owner',
'--profile' => 'site: Drupal profile to use; default default',
);
}
function init_site() {
$this->setProperty('uri');
// we need to set the alias root to the platform root, otherwise drush will cause problems.
$this->root = $this->platform->root;
// set this because this path is accessed a lot in the code, especially in config files.
$this->site_path = $this->root . '/sites/' . $this->uri;
$this->setProperty('site_enabled', true);
$this->setProperty('language', 'en');
$this->setProperty('client_email');
$this->setProperty('aliases', array(), TRUE);
$this->setProperty('redirection', FALSE);
// this can potentially be handled by a Drupal sub class
$this->setProperty('profile', 'default');
}
}
......@@ -78,7 +78,7 @@ function provision_drush_command() {
'options' => array_merge(array(
'--context_type' => 'server, platform, or site; default server',
'--delete' => 'Remove the alias.',
), provisionServer::option_documentation(), provisionPlatform::option_documentation(), provisionSite::option_documentation()),
), provisionContext_server::option_documentation(), provisionContext_platform::option_documentation(), provisionContext_site::option_documentation()),
'bootstrap' => DRUSH_BOOTSTRAP_DRUSH,
);
$items['provision-install'] = array(
......@@ -220,13 +220,15 @@ function drush_provision_save($alias = null) {
$config->unlink();
}
else {
// trigger additional logic that should happen only on save.
d($alias)->type_invoke('save');
// create or update the record
d($alias)->write_alias();
}
}
function drush_provision_verify() {
d()->verify();
d()->command_invoke('verify');
}
function _provision_default_web_group() {
......
This diff is collapsed.
......@@ -372,8 +372,31 @@ class provisionException_continue extends provisionException {
}
/**
* Provision class.
*
* This is just a container for some useful static methods.
*/
class provision {
/**
* The actual body of the method_invoke function.
*
* This is a static method so it can be re-used by some other classes
* that aren't contexts. (notably services and configs).
*/
static function method_invoke($object, $func, $args = array()) {
if (method_exists($object, $func)) {
return call_user_func_array(array($object, $func), $args);
}
}
}
include_once('provision.environment.inc');
include_once('provision.context.inc');
include_once('provision.context.server.inc');
include_once('provision.context.platform.inc');
include_once('provision.context.site.inc');
include_once('provision.service.inc');
include_once('provision.file.inc');
include_once('provision.config.inc');
......
......@@ -21,8 +21,27 @@ class provisionService extends provisionChainedState {
protected $config_cache = array();
private $_config = null;
// All services have the ability to have an associated restart command and listen port.
/**
* Implement the __call magic method.
*
* This implementation is really simple. It simply return null if the
* method doesn't exist.
*
* This is used so that we can create methods for drush commands, and
* can fail safely.
*/
function __call($name, $args = array()) {
return provision::method_invoke($this, $name, $args);
}
function init() {
}
// All services have the ability to have an associated restart command and listen port.
function init_server() {
if (!is_null($this->service)) {
if ($this->has_port) {
$this->server->setProperty($this->service . '_port', $this->default_port());
......@@ -34,6 +53,15 @@ class provisionService extends provisionChainedState {
return TRUE;
}
function init_platform() {
}
function init_site() {
}
function default_port() {
return false;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment