summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Pugh2017-10-24 00:02:55 (GMT)
committerJon Pugh2017-10-24 00:02:55 (GMT)
commite71d2f638c4dceddb77e6f7b391deb5adf0c8657 (patch)
treed4138cdb42127fd8ace6956487f26d507f4eae5a
parentd2f9a63afe75f0a326f5931928b6c81f428e56dc (diff)
parent44c9546f63caaf2748e70b32f350cae139cfde57 (diff)
Merge branch '4.x-services' of git.drupal.org:project/provision into 4.x-services
-rw-r--r--src/Configuration.php299
-rw-r--r--src/Context.php7
-rw-r--r--src/Context/ServerContext.php29
-rw-r--r--src/Service.php72
-rw-r--r--src/Service/Http/Apache/Configuration/PlatformConfiguration.php31
-rw-r--r--src/Service/Http/Apache/Configuration/ServerConfiguration.php49
-rw-r--r--src/Service/Http/Apache/Configuration/SiteConfiguration.php53
-rw-r--r--src/Service/Http/Apache/Configuration/server.tpl.php46
-rw-r--r--src/Service/Http/HttpApacheService.php23
-rw-r--r--src/Service/HttpService.php3
10 files changed, 594 insertions, 18 deletions
diff --git a/src/Configuration.php b/src/Configuration.php
new file mode 100644
index 0000000..76f5414
--- /dev/null
+++ b/src/Configuration.php
@@ -0,0 +1,299 @@
+<?php
+/**
+ * @file
+ * Provision configuration generation classes.
+ */
+
+namespace Aegir\Provision;
+
+use Symfony\Component\Filesystem\Exception\IOException;
+use Symfony\Component\Filesystem\Filesystem;
+
+/**
+ * Class Configuration
+ *
+ * @package Aegir\Provision
+ */
+class Configuration {
+
+ /**
+ * Provision 4.x
+ */
+
+ /**
+ * A \Aegir\Provision\Context object this configuration relates to.
+ *
+ * @var \Aegir\Provision\Context
+ */
+ public $context = NULL;
+
+ /**
+ * A \Aegir\Provision\Service object this configuration relates to.
+ *
+ * @var \Aegir\Provision\Service
+ */
+ public $service = NULL;
+
+ /**
+ * @var Filesystem
+ */
+ public $fs;
+
+ /**
+ * LEGACY
+ */
+ /**
+ * Template file, a PHP file which will have access to $this and variables
+ * as defined in $data.
+ */
+ public $template = NULL;
+
+ /**
+ * Associate array of variables to make available to the template.
+ */
+ public $data = array();
+
+ /**
+ * If set, replaces file name in log messages.
+ */
+ public $description = NULL;
+
+ /**
+ * Octal Unix mode for permissons of the created file.
+ */
+ protected $mode = NULL;
+
+ /**
+ * Unix group name for the created file.
+ */
+ protected $group = NULL;
+
+ /**
+ * An optional data store class to instantiate for this config.
+ */
+ protected $data_store_class = NULL;
+
+ /**
+ * The data store.
+ */
+ public $store = NULL;
+
+ /**
+ * Forward $this->... to $this->context->...
+ * object.
+ */
+ function __get($name) {
+ if (isset($this->context)) {
+ return $this->context->$name;
+ }
+ }
+
+ /**
+ * Constructor, overriding not recommended.
+ *
+ * @param $context
+ * An alias name for d(), the Provision_Context that this configuration
+ * is relevant to.
+ * @param $data
+ * An associative array to potentially manipulate in process() and make
+ * available as variables to the template.
+ */
+ function __construct($context, $service, $data = array()) {
+ if (is_null($this->template)) {
+ throw new Exception(dt("No template specified for: %class", array('%class' => get_class($this))));
+ }
+
+ // Accept both a reference and an alias name for the context.
+ $this->context = $context;
+ $this->service = $service;
+ $this->fs = new Filesystem();
+
+ 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->store = new $class($context, $data);
+ }
+
+ }
+
+ /**
+ * Process and add to $data before writing the configuration.
+ *
+ * This is a stub to be implemented by subclasses.
+ */
+ function process() {
+ if (is_object($this->store)) {
+ $this->data['records'] = array_filter(array_merge($this->store->loaded_records, $this->store->records));
+ }
+ return TRUE;
+ }
+
+ /**
+ * The filename where the configuration is written.
+ *
+ * This is a stub to be implemented by subclasses.
+ */
+ function filename() {
+ return FALSE;
+ }
+
+ /**
+ * Load template from filename().
+ *
+ * @see hook_provision_config_load_templates()
+ * @see hook_provision_config_load_templates_alter()
+ */
+ private function load_template() {
+ return file_get_contents(__DIR__ . '/Service/' . ucfirst($this->service->getName()) . '/' . ucfirst($this->service->getType()) . '/Configuration/' . $this->template);
+
+ // Allow other Drush commands to change the template used first.
+// $templates = drush_command_invoke_all('provision_config_load_templates', $this);
+// // Ensure that templates is at least an array.
+// if (!is_array($templates)) {
+// $templates = array();
+// }
+// // Allow other Drush commands to alter the templates from other commands.
+//// drush_command_invoke_all_ref('provision_config_load_templates_alter', $templates, $this);
+// if (!empty($templates) && is_array($templates)) {
+// foreach ($templates as $file) {
+// if (is_readable($file)) {
+// drush_log(dt('Template loaded from hook(s): :file', array(
+// ':file' => $file,
+// )));
+// return file_get_contents($file);
+// }
+// }
+// }
+//
+// // If we've got this far, then try to find a template from this class or
+// // one of its parents.
+// if (isset($this->template)) {
+// $class_name = get_class($this);
+// while ($class_name) {
+// // Iterate through the config file's parent classes until we
+// // find the template file to use.
+// $base_dir = provision_class_directory($class_name);
+// $file = $base_dir . '/' . $this->template;
+//
+// if (is_readable($file)) {
+// drush_log(dt('Template loaded from Provision Config class :class_name: :file', array(
+// ':class_name' => $class_name,
+// ':file' => $file,
+// )));
+// return file_get_contents($file);
+// }
+//
+// $class_name = get_parent_class($class_name);
+// }
+// }
+//
+// // We've failed to find a template if we've reached this far.
+// drush_log(dt('No template found for Provision Config class: ', array(':class' => get_class($this))), 'warning');
+// return FALSE;
+ }
+
+ /**
+ * Render template, making variables available from $variables associative
+ * array.
+ */
+ private function render_template($template, $variables) {
+
+ // Allow modules to alter the variables before writing to the template.
+ // @see hook_provision_config_variables_alter()
+// drush_command_invoke_all_ref('provision_config_variables_alter', $variables, $template, $this);
+
+// drush_errors_off();
+ extract($variables, EXTR_SKIP); // Extract the variables to a local namespace
+ ob_start(); // Start output buffering
+ eval('?>' . $template); // Generate content
+ $contents = ob_get_contents(); // Get the contents of the buffer
+ ob_end_clean(); // End buffering and discard
+// drush_errors_on();
+ return $contents; // Return the contents
+ }
+
+ /**
+ * Write out this configuration.
+ *
+ * 1. Make sure parent directory exists and is writable.
+ * 2. Load template with load_template().
+ * 3. Process $data with process().
+ * 4. Make existing file writable if necessary and possible.
+ * 5. Render template with $this and $data and write out to filename().
+ * 6. If $mode and/or $group are set, apply them for the new file.
+ */
+ function write() {
+
+ // Make directory structure if it does not exist.
+ $filename = $this->filename();
+ if ($filename && !$this->fs->exists([dirname($filename)])) {
+ try {
+ $this->fs->mkdir([dirname($filename)]);
+ }
+ catch (IOException $e) {
+ throw new \Exception("Could not create directory " . dirname($filename) . ": " . $e->getMessage());
+ }
+ }
+
+ $status = FALSE;
+ if ($filename && is_writeable(dirname($filename))) {
+ // manipulate data before passing to template.
+ $this->process();
+
+ if ($template = $this->load_template()) {
+ // Make sure we can write to the file
+ if (!is_null($this->mode) && !($this->mode & 0200) && $this->fs->exists(($filename))) {
+ try {
+ $this->fs->chmod([$filename], $this->mode);
+ }
+ catch (IOException $e) {
+ throw new \Exception('Could not change permissions of ' . $filename . ' to ' . $this->mode);
+ }
+ }
+
+ try {
+ $this->fs->dumpFile($filename, $this->render_template($template, $this->data));
+ }
+ catch (IOException $e) {
+ throw new \Exception('Could not write file to ' . $filename);
+ }
+
+ // Change the permissions of the file if needed
+ if (!is_null($this->mode)) {
+ try {
+ $this->fs->chmod([$filename], $this->mode);
+ }
+ catch (IOException $e) {
+ throw new \Exception('Could not change permissions of ' . $filename . ' to ' . $this->mode);
+ }
+ }
+ if (!is_null($this->group)) {
+ try {
+ $this->fs->chgrp([$filename], $this->group);
+ }
+ catch (IOException $e) {
+ throw new \Exception('Could not change group ownership of ' . $filename . ' to ' . $this->group);
+ }
+ }
+ }
+ }
+ return $status;
+ }
+
+ // allow overriding w.r.t locking
+ function file_put_contents($filename, $text) {
+ provision_file()->file_put_contents($filename, $text)
+ ->succeed('Generated config in file_put_contents()' . (empty($this->description) ? $filename : $this->description), 'success');
+ }
+
+ /**
+ * Remove configuration file as specified by filename().
+ */
+ function unlink() {
+ return provision_file()->unlink($this->filename())->status();
+ }
+
+}
diff --git a/src/Context.php b/src/Context.php
index 9e9f8f7..7237efb 100644
--- a/src/Context.php
+++ b/src/Context.php
@@ -145,7 +145,12 @@ class Context
* @return array
*/
public function getProperty($name) {
- return $this->properties[$name];
+ if (isset($this->properties[$name])) {
+ return $this->properties[$name];
+ }
+ else {
+ return NULL;
+ }
}
/**
diff --git a/src/Context/ServerContext.php b/src/Context/ServerContext.php
index 39226d3..61c5e67 100644
--- a/src/Context/ServerContext.php
+++ b/src/Context/ServerContext.php
@@ -40,7 +40,22 @@ class ServerContext extends Context implements ConfigurationInterface
{
parent::__construct($name, $console_config, $options);
if (isset($this->config['services'])) {
- $this->services = $this->config['services'];
+ $this->prepareServices();
+ }
+ else {
+ $this->services = [];
+ }
+ }
+
+ /**
+ * Load Service classes from config into Context..
+ */
+ protected function prepareServices() {
+ foreach ($this->config['services'] as $service_name => $service) {
+ $service_name = ucfirst($service_name);
+ $service_type = ucfirst($service['type']);
+ $service_class = "\\Aegir\\Provision\\Service\\{$service_name}\\{$service_name}{$service_type}Service";
+ $this->services[strtolower($service_name)] = new $service_class($service, $this);
}
}
@@ -191,7 +206,11 @@ class ServerContext extends Context implements ConfigurationInterface
public function verify() {
-// parent::verify();
+ // Run verify method on all services.
+ foreach ($this->getServices() as $service) {
+ $service->verify();
+ }
+
return "Server Context Verified: " . $this->name;
}
@@ -202,11 +221,11 @@ class ServerContext extends Context implements ConfigurationInterface
if (!empty($this->getServices())) {
$rows = [];
foreach ($this->getServices() as $name => $service) {
- $rows[] = [$name, $service['type']];
+ $rows[] = [$name, $service->type];
// Show all properties.
- if (!empty($service['properties'] )) {
- foreach ($service['properties'] as $name => $value) {
+ if (!empty($service->properties )) {
+ foreach ($service->properties as $name => $value) {
$rows[] = [' ' . $name, $value];
}
}
diff --git a/src/Service.php b/src/Service.php
index f8fe385..c743a6f 100644
--- a/src/Service.php
+++ b/src/Service.php
@@ -11,7 +11,59 @@ namespace Aegir\Provision;
//require_once DRUSH_BASE_PATH . '/commands/core/rsync.core.inc';
class Service {
-
+
+ public $type;
+ public $properties;
+
+ function __construct($service_config, $context) {
+ $this->context = $context;
+ $this->type = $service_config['type'];
+ $this->properties = $service_config['properties'];
+ }
+
+ /**
+ * React to the `provision verify` command.
+ */
+ function verify() {
+ $this->writeConfigurations();
+ }
+
+ /**
+ * Write this service's configurations.
+ */
+ protected function writeConfigurations() {
+ foreach ($this->getConfigurations()[$this->context->type] as $configuration_class) {
+ $config = new $configuration_class($this->context, $this);
+ $config->write();
+ }
+ }
+
+ /**
+ * Stub for this services configurations.
+ */
+ protected function getConfigurations() {
+ return [];
+ }
+
+ /**
+ * Return the SERVICE_TYPE
+ * @return mixed
+ */
+ public function getType() {
+ return $this::SERVICE_TYPE;
+ }
+
+ /**
+ * Return the SERVICE_TYPE
+ * @return mixed
+ */
+ public function getName() {
+ return $this::SERVICE;
+ }
+
+ /**
+ * LEGACY
+ */
/**
* The server this service is associated to
*/
@@ -62,9 +114,9 @@ class Service {
* 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 __call($name, $args = array()) {
+// return provision::method_invoke($this, $name, $args);
+// }
function init() {
@@ -316,10 +368,6 @@ class Service {
return FALSE;
}
- function __construct($server) {
- $this->server = is_object($server) ? $server : d($server);
- }
-
/**
* Set the currently active context of the service.
*
@@ -344,10 +392,10 @@ class Service {
function fetch($path = NULL) {
return $this->server->fetch($path);
}
-
- function verify() {
- return TRUE;
- }
+//
+// function verify() {
+// return TRUE;
+// }
/**
* Return service-specific configuration options for help.
diff --git a/src/Service/Http/Apache/Configuration/PlatformConfiguration.php b/src/Service/Http/Apache/Configuration/PlatformConfiguration.php
new file mode 100644
index 0000000..096fd06
--- /dev/null
+++ b/src/Service/Http/Apache/Configuration/PlatformConfiguration.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * @file Server.php
+ *
+ * Apache Configuration for Server Context.
+ * @see \Provision_Config_Apache_Server
+ * @see \Provision_Config_Http_Server
+ * @see \Provision_Config_Http_Server
+ */
+
+namespace Aegir\Provision\Service\Http\Apache\Configuration;
+
+use Aegir\Provision\Configuration;
+
+class PlatformConfiguration extends Configuration {
+
+ const SERVICE_TYPE = 'apache';
+
+ public $template = 'server.tpl.php';
+ public $description = 'web server configuration file';
+
+ function filename() {
+ if (isset($this->data['application_name'])) {
+ $file = $this->data['application_name'] . '.conf';
+ return $this->data['server']->config_path . '/' . $file;
+ }
+ else {
+ return FALSE;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Service/Http/Apache/Configuration/ServerConfiguration.php b/src/Service/Http/Apache/Configuration/ServerConfiguration.php
new file mode 100644
index 0000000..000fdd1
--- /dev/null
+++ b/src/Service/Http/Apache/Configuration/ServerConfiguration.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * @file Server.php
+ *
+ * Apache Configuration for Server Context.
+ *
+ * This class represents the file at /var/aegir/config/apache.conf.
+ *
+ *
+ * @see \Provision_Config_Apache_Server
+ * @see \Provision_Config_Http_Server
+ * @see \Provision_Config_Http_Server
+ */
+
+namespace Aegir\Provision\Service\Http\Apache\Configuration;
+
+use Aegir\Provision\Configuration;
+
+class ServerConfiguration extends Configuration {
+
+ const SERVICE_TYPE = 'apache';
+
+ public $template = 'server.tpl.php';
+ public $description = 'web server configuration file';
+
+ function filename() {
+ if ($this->service->getType()) {
+ $file = $this->service->getType() . '.conf';
+ return $this->context->console_config['config_path'] . '/' . $this->context->name . '/' . $file;
+ }
+ else {
+ return FALSE;
+ }
+ }
+ function process()
+ {
+
+ $app_dir = $this->context->console_config['config_path'] . '/' . $this->service->getType();
+ $this->data['http_port'] = $this->service->properties['http_port'];
+ $this->data['include_statement'] = '# INCLUDE STATEMENT';
+ $this->data['http_pred_path'] = "{$app_dir}/pre.d";
+ $this->data['http_postd_path'] = "{$app_dir}/post.d";
+ $this->data['http_platformd_path'] = "{$app_dir}/platform.d";
+ $this->data['http_vhostd_path'] = "{$app_dir}/vhost.d";
+ $this->data['extra_config'] = "";
+
+ return parent::process();
+ }
+} \ No newline at end of file
diff --git a/src/Service/Http/Apache/Configuration/SiteConfiguration.php b/src/Service/Http/Apache/Configuration/SiteConfiguration.php
new file mode 100644
index 0000000..8781979
--- /dev/null
+++ b/src/Service/Http/Apache/Configuration/SiteConfiguration.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * @file Site.php
+ *
+ * Apache Configuration for Server Context.
+ * @see \Provision_Config_Apache_Site
+ * @see \Provision_Config_Http_Site
+ */
+
+namespace Aegir\Provision\Service\Http\Apache\Configuration;
+
+use Aegir\Provision\Configuration;
+
+class SiteConfiguration extends Configuration {
+
+ const SERVICE_TYPE = 'apache';
+
+ public $template = 'vhost.tpl.php';
+ // The template file to use when the site has been disabled.
+ public $disabled_template = 'vhost_disabled.tpl.php';
+ public $description = 'virtual host configuration file';
+
+
+ function filename() {
+ if (drush_get_option('provision_apache_conf_suffix', FALSE)) {
+ return $this->data['http_vhostd_path'] . '/' . $this->uri . '.conf';
+ }
+ else {
+ return $this->data['http_vhostd_path'] . '/' . $this->uri;
+ }
+ }
+
+ function process() {
+ parent::process();
+
+ if ($this->aliases && !is_array($this->aliases)) {
+ $this->aliases = explode(",", $this->aliases);
+ }
+
+ $this->aliases = array_filter($this->aliases, 'trim');
+
+ if ($this->drush_aliases && !is_array($this->drush_aliases)) {
+ $this->drush_aliases = explode(",", $this->drush_aliases);
+ }
+
+ $this->drush_aliases = array_filter($this->drush_aliases, 'trim');
+
+ if (!$this->site_enabled) {
+ $this->template = $this->disabled_template;
+ }
+
+ }
+} \ No newline at end of file
diff --git a/src/Service/Http/Apache/Configuration/server.tpl.php b/src/Service/Http/Apache/Configuration/server.tpl.php
new file mode 100644
index 0000000..8364473
--- /dev/null
+++ b/src/Service/Http/Apache/Configuration/server.tpl.php
@@ -0,0 +1,46 @@
+# Aegir web server configuration file
+
+NameVirtualHost *:<?php print $http_port; ?>
+
+
+<VirtualHost *:<?php print $http_port; ?>>
+ ServerName default
+ Redirect 404 /
+</VirtualHost>
+
+
+<IfModule !env_module>
+ LoadModule env_module modules/mod_env.so
+</IfModule>
+
+<IfModule !rewrite_module>
+ LoadModule rewrite_module modules/mod_rewrite.so
+</IfModule>
+
+<?php
+//if (drush_get_option('provision_apache_conf_suffix', FALSE)) {
+// $include_statement = 'IncludeOptional ';
+// $include_suffix = '/*.conf';
+//}
+//else {
+ $include_statement = 'Include ';
+ $include_suffix = '';
+//}
+
+?>
+
+# other configuration, not touched by aegir
+# this allows you to override aegir configuration, as it is included before
+<?php print $include_statement . $http_pred_path . $include_suffix ?>
+
+# virtual hosts
+<?php print $include_statement . $http_vhostd_path . $include_suffix ?>
+
+# platforms
+<?php print $include_statement . $http_platformd_path . $include_suffix ?>
+
+# other configuration, not touched by aegir
+# this allows to have default (for example during migrations) that are eventually overriden by aegir
+<?php print $include_statement . $http_postd_path . $include_suffix ?>
+
+<?php print $extra_config; ?>
diff --git a/src/Service/Http/HttpApacheService.php b/src/Service/Http/HttpApacheService.php
index 7e2812c..50e49ef 100644
--- a/src/Service/Http/HttpApacheService.php
+++ b/src/Service/Http/HttpApacheService.php
@@ -19,4 +19,27 @@ class HttpApacheService extends HttpService
{
const SERVICE_TYPE = 'apache';
const SERVICE_TYPE_NAME = 'Apache';
+
+ /**
+ * Returns array of Configuration classes for this service.
+ *
+ * @see Provision_Service_http_apache::init_server();
+ *
+ * @return array
+ */
+ public function getConfigurations()
+ {
+ $configs['server'][] = '\Aegir\Provision\Service\Http\Apache\Configuration\ServerConfiguration';
+ $configs['platform'][] = '\Aegir\Provision\Service\Http\Apache\Configuration\PlatformConfiguration';
+ $configs['site'][] = '\Aegir\Provision\Service\Http\Apache\Configuration\SiteConfiguration';
+ return $configs;
+ }
+
+ /**
+ * Respond to the `provision verify` command.
+ */
+ public function verify() {
+// print "VERIFY APACHE SERVER!";
+ parent::verify();
+ }
}
diff --git a/src/Service/HttpService.php b/src/Service/HttpService.php
index e2fea5f..17e1ddd 100644
--- a/src/Service/HttpService.php
+++ b/src/Service/HttpService.php
@@ -26,6 +26,9 @@ class HttpService extends Service {
static function option_documentation() {
return array(
+ 'http_port' => 'The port which the web service is running on.',
+ 'http_platformd_path' => 'The path to store platforms.',
+ 'http_postd_path' => 'The path to store post configuration.',
'web_group' => 'server with http: OS group for permissions; working default will be attempted',
'web_disable_url' => 'server with http: URL disabled sites are redirected to; default {master_url}/hosting/disabled',
'web_maintenance_url' => 'server with http: URL maintenance sites are redirected to; default {master_url}/hosting/maintenance',