Commit 6ecebc8a authored by Jon Pugh's avatar Jon Pugh

Load Services into Context classes, and load Configuration classes into...

Load Services into Context classes, and load Configuration classes into Services classes. Rewrite Configuration class from Provision_Config. Run write() method on all Configuration classes on `provision verify` command.
parent 819fc1c0
......@@ -6,12 +6,42 @@
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.
......@@ -23,13 +53,6 @@ class Configuration {
*/
public $data = array();
/**
* A Provision_Context object thie configuration relates to.
*
* @var Provision_Context
*/
public $context = NULL;
/**
* If set, replaces file name in log messages.
*/
......@@ -75,13 +98,15 @@ class Configuration {
* An associative array to potentially manipulate in process() and make
* available as variables to the template.
*/
function __construct($context, $data = array()) {
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 = is_object($context) ? $context : d($context);
$this->context = $context;
$this->service = $service;
$this->fs = new Filesystem();
if (sizeof($data)) {
$this->data = $data;
......@@ -122,51 +147,52 @@ class Configuration {
* @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;
// $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;
}
/**
......@@ -177,15 +203,15 @@ class Configuration {
// 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_command_invoke_all_ref('provision_config_variables_alter', $variables, $template, $this);
drush_errors_off();
// 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();
// drush_errors_on();
return $contents; // Return the contents
}
......@@ -200,12 +226,16 @@ class Configuration {
* 6. If $mode and/or $group are set, apply them for the new file.
*/
function write() {
$filename = $this->filename();
// Make directory structure if it does not exist.
if ($filename && !provision_file()->exists(dirname($filename))->status()) {
provision_file()->mkdir(dirname($filename))
->succeed('Created directory @path.')
->fail('Could not create directory @path.');
$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;
......@@ -215,26 +245,38 @@ class Configuration {
if ($template = $this->load_template()) {
// Make sure we can write to the file
if (!is_null($this->mode) && !($this->mode & 0200) && provision_file()->exists($filename)->status()) {
provision_file()->chmod($filename, $this->mode | 0200)
->succeed('Changed permissions of @path to @perm')
->fail('Could not change permissions of @path to @perm');
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);
}
}
$status = provision_file()->file_put_contents($filename, $this->render_template($template, $this->data))
->succeed('Generated config in write(): ' . (empty($this->description) ? $filename : $this->description . ' (' . $filename. ')'), 'success')
->fail('Could not generate in write(): ' . (empty($this->description) ? $filename : $this->description . ' (' . $filename. ')'))->status();
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)) {
provision_file()->chmod($filename, $this->mode)
->succeed('Changed permissions of @path to @perm')
->fail('Could not change permissions of @path to @perm');
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)) {
provision_file()->chgrp($filename, $this->group)
->succeed('Change group ownership of @path to @gid')
->fail('Could not change group ownership of @path to @gid');
try {
$this->fs->chgrp([$filename], $this->group);
}
catch (IOException $e) {
throw new \Exception('Could not change group ownership of ' . $filename . ' to ' . $this->group);
}
}
}
}
......
......@@ -45,8 +45,6 @@ class ServerContext extends Context implements ConfigurationInterface
else {
$this->services = [];
}
print_r($this->services);
}
/**
......@@ -208,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;
}
......
......@@ -21,6 +21,46 @@ class Service {
$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
*/
......@@ -74,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() {
......@@ -352,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.
......
<?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
<?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 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'] . '/' . $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
<?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
# 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; ?>
......@@ -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();
}
}
......@@ -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',
......
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