summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Pugh2017-10-23 17:47:26 (GMT)
committerJon Pugh2017-10-23 17:47:26 (GMT)
commitd5a41dd4e24ec7830456984c79f639c32808634d (patch)
tree8e25df1343bae14be7680d031836875b68dd1c73
parent0a204e45210422db3821f5ddb5a892a39f5b8f11 (diff)
parentffc8a73c2497e4b5bec84c9e62199d22b500dc86 (diff)
Merge branch '4.x-services' of git.drupal.org:project/provision into 4.x-services
-rw-r--r--composer.json1
-rw-r--r--composer.lock102
-rw-r--r--src/Command/ServicesCommand.php55
-rw-r--r--src/Context/ServerContext.php125
-rw-r--r--src/Service.php14
-rw-r--r--src/Service/Db/DbMysqlService.php22
-rw-r--r--src/Service/DbService.php293
-rw-r--r--src/Service/Http/HttpApacheService.php22
-rw-r--r--src/Service/Http/HttpNginxService.php22
-rw-r--r--src/Service/HttpService.php16
10 files changed, 663 insertions, 9 deletions
diff --git a/composer.json b/composer.json
index 839851b..c3f078d 100644
--- a/composer.json
+++ b/composer.json
@@ -6,6 +6,7 @@
"type": "library",
"license": "GPL-2.0+",
"require": {
+ "consolidation/annotated-command": "~2",
"drupal/console-core": "1.0.2",
"psy/psysh": "^0.8.11",
"symfony/console": "^3.3",
diff --git a/composer.lock b/composer.lock
index e64fd73..02c47ed 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,9 +4,109 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "content-hash": "835ca80eb26b4d7e438015632aaeaaa2",
+ "content-hash": "c8f06b1cc28f9638bdc92415ed78c328",
"packages": [
{
+ "name": "consolidation/annotated-command",
+ "version": "2.8.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/consolidation/annotated-command.git",
+ "reference": "7f94009d732922d61408536f9228aca8f22e9135"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/7f94009d732922d61408536f9228aca8f22e9135",
+ "reference": "7f94009d732922d61408536f9228aca8f22e9135",
+ "shasum": ""
+ },
+ "require": {
+ "consolidation/output-formatters": "^3.1.12",
+ "php": ">=5.4.0",
+ "psr/log": "^1",
+ "symfony/console": "^2.8|~3",
+ "symfony/event-dispatcher": "^2.5|^3",
+ "symfony/finder": "^2.5|^3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8",
+ "satooshi/php-coveralls": "^1.0",
+ "squizlabs/php_codesniffer": "^2.7"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Consolidation\\AnnotatedCommand\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Greg Anderson",
+ "email": "greg.1.anderson@greenknowe.org"
+ }
+ ],
+ "description": "Initialize Symfony Console commands from annotated command class methods.",
+ "time": "2017-10-17T01:48:51+00:00"
+ },
+ {
+ "name": "consolidation/output-formatters",
+ "version": "3.1.12",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/consolidation/output-formatters.git",
+ "reference": "88ef346a1cefb92aab8b57a3214a6d5fc63f5d2a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/88ef346a1cefb92aab8b57a3214a6d5fc63f5d2a",
+ "reference": "88ef346a1cefb92aab8b57a3214a6d5fc63f5d2a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0",
+ "symfony/console": "^2.8|~3",
+ "symfony/finder": "~2.5|~3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8",
+ "satooshi/php-coveralls": "^1.0",
+ "squizlabs/php_codesniffer": "^2.7",
+ "victorjonsson/markdowndocs": "^1.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Consolidation\\OutputFormatters\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Greg Anderson",
+ "email": "greg.1.anderson@greenknowe.org"
+ }
+ ],
+ "description": "Format text by applying transformations provided by plug-in formatters.",
+ "time": "2017-10-12T19:38:03+00:00"
+ },
+ {
"name": "dflydev/dot-access-configuration",
"version": "v1.0.2",
"source": {
diff --git a/src/Command/ServicesCommand.php b/src/Command/ServicesCommand.php
index 1629650..89baac1 100644
--- a/src/Command/ServicesCommand.php
+++ b/src/Command/ServicesCommand.php
@@ -7,6 +7,7 @@ use Aegir\Provision\Context;
use Aegir\Provision\Context\PlatformContext;
use Aegir\Provision\Context\ServerContext;
use Aegir\Provision\Context\SiteContext;
+use Consolidation\AnnotatedCommand\CommandFileDiscovery;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputDefinition;
@@ -109,4 +110,58 @@ class ServicesCommand extends Command
$this->io->comment("List Services");
$this->context->showServices($this->io);
}
+
+ /**
+ * Add a new service to a server.
+ */
+ protected function execute_add(InputInterface $input, OutputInterface $output)
+ {
+ // Ask which service.
+ $this->io->comment("Add Services");
+ $service = $this->io->choice('Which service?', $this->context->getServiceOptions());
+
+ // Then ask which service type
+ $service_type = $this->io->choice('Which service type?', $this->context->getServiceTypeOptions($service));
+
+ // Then ask for all options.
+ $properties = $this->askForServiceProperties($service);
+
+ $this->io->info("Adding $service service $service_type...");
+
+ try {
+ $this->context->config['services'][$service] = [
+ 'type' => $service_type,
+ 'properties' => $properties,
+ ];
+ $this->context->save();
+ $this->io->success('Service saved to Context!');
+ }
+ catch (\Exception $e) {
+ throw new \Exception("Something went wrong when saving the context: " . $e->getMessage());
+ }
+ }
+
+ /**
+ * Loop through this context type's option_documentation() method and ask for each property.
+ *
+ * @return array
+ */
+ private function askForServiceProperties($service) {
+
+ $class = $this->context->getAvailableServices($service);
+
+ $options = $class::option_documentation();
+ $properties = [];
+ foreach ($options as $name => $description) {
+ // If option does not exist, ask for it.
+ if (!empty($this->input->hasOption($name))) {
+ $properties[$name] = $this->input->getOption($name);
+ $this->io->comment("Using option {$name}={$properties[$name]}");
+ }
+ else {
+ $properties[$name] = $this->io->ask("$name ($description)");
+ }
+ }
+ return $properties;
+ }
}
diff --git a/src/Context/ServerContext.php b/src/Context/ServerContext.php
index 58cacc1..39226d3 100644
--- a/src/Context/ServerContext.php
+++ b/src/Context/ServerContext.php
@@ -3,6 +3,7 @@
namespace Aegir\Provision\Context;
use Aegir\Provision\Context;
+use Consolidation\AnnotatedCommand\CommandFileDiscovery;
use Drupal\Console\Core\Style\DrupalStyle;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
@@ -56,6 +57,86 @@ class ServerContext extends Context implements ConfigurationInterface
}
/**
+ * Loads all available \Aegir\Provision\Service classes
+ *
+ * @return array
+ */
+ public function getAvailableServices($service = NULL) {
+
+ // Load all service classes
+ $classes = [];
+ $discovery = new CommandFileDiscovery();
+ $discovery->setSearchPattern('*Service.php');
+ $servicesFiles = $discovery->discover(__DIR__ .'/../Service', '\Aegir\Provision\Service');
+
+ foreach ($servicesFiles as $serviceClass) {
+ $classes[$serviceClass::SERVICE] = $serviceClass;
+ }
+
+ if ($service && isset($classes[$service])) {
+ return $classes[$service];
+ }
+ elseif ($service && !isset($classes[$service])) {
+ throw new \Exception("No service with name $service was found.");
+ }
+ else {
+ return $classes;
+ }
+ }
+
+ /**
+ * Lists all available services as a simple service => name array.
+ * @return array
+ */
+ public function getServiceOptions() {
+ $options = [];
+ $services = $this->getAvailableServices();
+ foreach ($services as $service => $class) {
+ $options[$service] = $class::SERVICE_NAME;
+ }
+ return $options;
+ }
+
+ /**
+ * @return array
+ */
+ protected function getAvailableServiceTypes($service, $service_type = NULL) {
+
+ // Load all service classes
+ $classes = [];
+ $discovery = new CommandFileDiscovery();
+ $discovery->setSearchPattern(ucfirst($service) . '*Service.php');
+ $serviceTypesFiles = $discovery->discover(__DIR__ .'/../Service/' . ucfirst($service), '\Aegir\Provision\Service\\' . ucfirst($service));
+ foreach ($serviceTypesFiles as $serviceTypeClass) {
+ $classes[$serviceTypeClass::SERVICE_TYPE] = $serviceTypeClass;
+ }
+
+ if ($service_type && isset($classes[$service_type])) {
+ return $classes[$service_type];
+ }
+ elseif ($service_type && !isset($classes[$service_type])) {
+ throw new \Exception("No service type with name $service_type was found.");
+ }
+ else {
+ return $classes;
+ }
+ }
+
+ /**
+ * Lists all available services as a simple service => name array.
+ * @return array
+ */
+ public function getServiceTypeOptions($service) {
+ $options = [];
+ $service_types = $this->getAvailableServiceTypes($service);
+ foreach ($service_types as $service_type => $class) {
+ $options[$service_type] = $class::SERVICE_TYPE_NAME;
+ }
+ return $options;
+ }
+
+
+ /**
* Return all services for this context.
*
* @return array
@@ -65,7 +146,7 @@ class ServerContext extends Context implements ConfigurationInterface
}
/**
- * {@inheritdoc}
+ * Pass server specific config to Context configTreeBuilder.
*/
public function configTreeBuilder(&$root_node)
{
@@ -74,11 +155,38 @@ class ServerContext extends Context implements ConfigurationInterface
->arrayNode('services')
->prototype('array')
->children()
- ->scalarNode('name')
+ ->scalarNode('type')
->isRequired(true)
->end()
- ->end()
- ->end();
+ ->append($this->addServiceProperties())
+ ->end()
+ ->end();
+ }
+
+ /**
+ * Append Service class options_documentation to config tree.
+ */
+ public function addServiceProperties()
+ {
+ $builder = new TreeBuilder();
+ $node = $builder->root('properties');
+
+ // Load config tree from Service type classes
+ if (!empty($this->getProperty('services')) && !empty($this->getProperty('services'))) {
+ foreach ($this->getProperty('services') as $service => $info) {
+ $service = ucfirst($service);
+ $service_type = ucfirst($info['type']);
+ $class = "\Aegir\Provision\Service\\{$service}\\{$service}{$service_type}Service";
+ foreach ($class::option_documentation() as $name => $description) {
+ $node
+ ->children()
+ ->scalarNode($name)->end()
+ ->end()
+ ->end();
+ }
+ }
+ }
+ return $node;
}
public function verify() {
@@ -94,7 +202,14 @@ class ServerContext extends Context implements ConfigurationInterface
if (!empty($this->getServices())) {
$rows = [];
foreach ($this->getServices() as $name => $service) {
- $rows[] = [$name, $service['name']];
+ $rows[] = [$name, $service['type']];
+
+ // Show all properties.
+ if (!empty($service['properties'] )) {
+ foreach ($service['properties'] as $name => $value) {
+ $rows[] = [' ' . $name, $value];
+ }
+ }
}
$io->table(['Services'], $rows);
}
diff --git a/src/Service.php b/src/Service.php
index 1ea8bdd..f8fe385 100644
--- a/src/Service.php
+++ b/src/Service.php
@@ -28,7 +28,19 @@ class Service {
*/
public $context;
- protected $service = NULL;
+ /**
+ * @var string
+ * The machine name of the service. ie. http, db
+ */
+ const SERVICE = 'service';
+
+ /**
+ * @var string
+ * A descriptive name of the service. ie. Web Server
+ */
+ const SERVICE_NAME = 'Service Name';
+
+
protected $application_name = NULL;
protected $has_restart_cmd = FALSE;
diff --git a/src/Service/Db/DbMysqlService.php b/src/Service/Db/DbMysqlService.php
new file mode 100644
index 0000000..f527697
--- /dev/null
+++ b/src/Service/Db/DbMysqlService.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * @file
+ * The Provision HttpNginxService class.
+ *
+ * @see \Provision_Service_http_Nginx
+ */
+
+namespace Aegir\Provision\Service\Db;
+
+use Aegir\Provision\Service\DbService;
+
+/**
+ * Class DbMysqlService
+ *
+ * @package Aegir\Provision\Service\Db
+ */
+class DbMysqlService extends DbService
+{
+ const SERVICE_TYPE = 'mysql';
+ const SERVICE_TYPE_NAME = 'MySQL';
+}
diff --git a/src/Service/DbService.php b/src/Service/DbService.php
new file mode 100644
index 0000000..31b28de
--- /dev/null
+++ b/src/Service/DbService.php
@@ -0,0 +1,293 @@
+<?php
+/**
+ * @file
+ * The base Provision DbService class.
+ *
+ * @see \Provision_Service_db
+ */
+
+namespace Aegir\Provision\Service;
+
+//require_once DRUSH_BASE_PATH . '/commands/core/rsync.core.inc';
+
+use Aegir\Provision\Service;
+
+/**
+ * Class DbService
+ *
+ * @package Aegir\Provision\Service
+ */
+class DbService extends Service {
+ const SERVICE = 'db';
+ const SERVICE_NAME = 'Database Server';
+
+ /**
+ * 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}',
+ 'db_grant_all_hosts' => 'Grant access to site database users from any web host. If set to TRUE, any host will be allowed to connect to MySQL site databases on this server using the generated username and password. If set to FALSE, web hosts will be granted access by their detected IP address.',
+ );
+ }
+
+ function init_server() {
+ parent::init_server();
+ $this->server->setProperty('master_db');
+ $this->server->setProperty('db_grant_all_hosts', FALSE);
+ $this->server->setProperty('utf8mb4_is_supported', FALSE);
+ $this->creds = array_map('urldecode', parse_url($this->server->master_db));
+
+ return TRUE;
+ }
+
+ function save_server() {
+ // Check database 4 byte UTF-8 support and save it for later.
+ $this->server->utf8mb4_is_supported = $this->utf8mb4_is_supported();
+ }
+
+ /**
+ * Verifies database connection and commands
+ */
+ function verify_server_cmd() {
+ if ($this->connect()) {
+ if ($this->can_create_database()) {
+ drush_log(dt('Provision can create new databases.'), 'success');
+ }
+ else {
+ drush_set_error('PROVISION_CREATE_DB_FAILED');
+ }
+ if ($this->can_grant_privileges()) {
+ drush_log(dt('Provision can grant privileges on database users.'), 'success');;
+ }
+ else {
+ drush_set_error('PROVISION_GRANT_DB_USER_FAILED');
+ }
+ if ($this->server->utf8mb4_is_supported) {
+ drush_log(dt('Provision can activate multi-byte UTF-8 support on Drupal 7 sites.'), 'success');
+ }
+ else {
+ drush_log(dt('Multi-byte UTF-8 for Drupal 7 is not supported on your system. See the <a href="@url">documentation on adding 4 byte UTF-8 support</a> for more information.', array('@url' => 'https://www.drupal.org/node/2754539')), 'warning');
+ }
+ } else {
+ drush_set_error('PROVISION_CONNECT_DB_FAILED');
+ }
+ }
+
+ /**
+ * Find a viable database name, based on the site's uri.
+ */
+ function suggest_db_name() {
+ $uri = $this->context->uri;
+
+ $suggest_base = substr(str_replace(array('.', '-'), '' , preg_replace('/^www\./', '', $uri)), 0, 16);
+
+ if (!$this->database_exists($suggest_base)) {
+ return $suggest_base;
+ }
+
+ for ($i = 0; $i < 100; $i++) {
+ $option = sprintf("%s_%d", substr($suggest_base, 0, 15 - strlen( (string) $i) ), $i);
+ if (!$this->database_exists($option)) {
+ return $option;
+ }
+ }
+
+ drush_set_error('PROVISION_CREATE_DB_FAILED', dt("Could not find a free database names after 100 attempts"));
+ return false;
+ }
+
+ /**
+ * Generate a new mysql database and user account for the specified credentials
+ */
+ function create_site_database($creds = array()) {
+ if (!sizeof($creds)) {
+ $creds = $this->generate_site_credentials();
+ }
+ extract($creds);
+
+ if (drush_get_error() || !$this->can_create_database()) {
+ drush_set_error('PROVISION_CREATE_DB_FAILED');
+ drush_log("Database could not be created.", 'error');
+ return FALSE;
+ }
+
+ foreach ($this->grant_host_list() as $db_grant_host) {
+ drush_log(dt("Granting privileges to %user@%client on %database", array('%user' => $db_user, '%client' => $db_grant_host, '%database' => $db_name)));
+ if (!$this->grant($db_name, $db_user, $db_passwd, $db_grant_host)) {
+ drush_set_error('PROVISION_CREATE_DB_FAILED', dt("Could not create database user @user", array('@user' => $db_user)));
+ }
+ drush_log(dt("Granted privileges to %user@%client on %database", array('%user' => $db_user, '%client' => $db_grant_host, '%database' => $db_name)), 'success');
+ }
+
+ $this->create_database($db_name);
+ $status = $this->database_exists($db_name);
+
+ if ($status) {
+ drush_log(dt('Created @name database', array("@name" => $db_name)), 'success');
+ }
+ else {
+ drush_set_error('PROVISION_CREATE_DB_FAILED', dt("Could not create @name database", array("@name" => $db_name)));
+ }
+ return $status;
+ }
+
+ /**
+ * Remove the database and user account for the supplied credentials
+ */
+ function destroy_site_database($creds = array()) {
+ if (!sizeof($creds)) {
+ $creds = $this->fetch_site_credentials();
+ }
+ extract($creds);
+
+ if ( $this->database_exists($db_name) ) {
+ drush_log(dt("Dropping database @dbname", array('@dbname' => $db_name)));
+ if (!$this->drop_database($db_name)) {
+ drush_log(dt("Failed to drop database @dbname", array('@dbname' => $db_name)), 'warning');
+ }
+ }
+
+ if ( $this->database_exists($db_name) ) {
+ drush_set_error('PROVISION_DROP_DB_FAILED');
+ return FALSE;
+ }
+
+ foreach ($this->grant_host_list() as $db_grant_host) {
+ drush_log(dt("Revoking privileges of %user@%client from %database", array('%user' => $db_user, '%client' => $db_grant_host, '%database' => $db_name)));
+ if (!$this->revoke($db_name, $db_user, $db_grant_host)) {
+ drush_log(dt("Failed to revoke user privileges"), 'warning');
+ }
+ }
+ }
+
+
+ function import_site_database($dump_file = null, $creds = array()) {
+ if (is_null($dump_file)) {
+ $dump_file = d()->site_path . '/database.sql';
+ }
+
+ if (!sizeof($creds)) {
+ $creds = $this->fetch_site_credentials();
+ }
+
+ $exists = provision_file()->exists($dump_file)
+ ->succeed('Found database dump at @path.')
+ ->fail('No database dump was found at @path.', 'PROVISION_DB_DUMP_NOT_FOUND')
+ ->status();
+ if ($exists) {
+ $readable = provision_file()->readable($dump_file)
+ ->succeed('Database dump at @path is readable')
+ ->fail('The database dump at @path could not be read.', 'PROVISION_DB_DUMP_NOT_READABLE')
+ ->status();
+ if ($readable) {
+ $this->import_dump($dump_file, $creds);
+ }
+ }
+ }
+
+ function generate_site_credentials() {
+ $creds = array();
+ // replace with service type
+ $db_type = drush_get_option('db_type', function_exists('mysqli_connect') ? 'mysqli' : 'mysql');
+ // As of Drupal 7 there is no more mysqli type
+ if (drush_drupal_major_version() >= 7) {
+ $db_type = ($db_type == 'mysqli') ? 'mysql' : $db_type;
+ }
+
+ //TODO - this should not be here at all
+ $creds['db_type'] = drush_set_option('db_type', $db_type, 'site');
+ $creds['db_host'] = drush_set_option('db_host', $this->server->remote_host, 'site');
+ $creds['db_port'] = drush_set_option('db_port', $this->server->db_port, 'site');
+ $creds['db_passwd'] = drush_set_option('db_passwd', provision_password(), 'site');
+ $creds['db_name'] = drush_set_option('db_name', $this->suggest_db_name(), 'site');
+ $creds['db_user'] = drush_set_option('db_user', $creds['db_name'], 'site');
+
+ return $creds;
+ }
+
+ function fetch_site_credentials() {
+ $creds = array();
+
+ $keys = array('db_type', 'db_port', 'db_user', 'db_name', 'db_host', 'db_passwd');
+ foreach ($keys as $key) {
+ $creds[$key] = drush_get_option($key, '', 'site');
+ }
+
+ return $creds;
+ }
+
+ function database_exists($name) {
+ return FALSE;
+ }
+
+ function drop_database($name) {
+ return FALSE;
+ }
+
+ function create_database($name) {
+ return FALSE;
+ }
+
+ function can_create_database() {
+ return FALSE;
+ }
+
+ function can_grant_privileges() {
+ return FALSE;
+ }
+
+ function grant($name, $username, $password, $host = '') {
+ return FALSE;
+ }
+
+ function revoke($name, $username, $host = '') {
+ return FALSE;
+ }
+
+ function import_dump($dump_file, $creds) {
+ return FALSE;
+ }
+
+ function generate_dump() {
+ return FALSE;
+ }
+
+ /**
+ * Return a list of hosts, as seen by the db server, which should be granted
+ * access to the site database. If server property 'db_grant_all_hosts' is
+ * TRUE, use the MySQL wildcard '%' instead of
+ */
+ function grant_host_list() {
+ if ($this->server->db_grant_all_hosts) {
+ return array('%');
+ }
+ else {
+ return array_unique(array_map(array($this, 'grant_host'), $this->context->service('http')->grant_server_list()));
+ }
+ }
+
+ /**
+ * Return a hostname suitable for database grants from a server object.
+ */
+ function grant_host(Provision_Context_server $server) {
+ return $server->remote_host;
+ }
+
+ /**
+ * Checks whether utf8mb4 support is available on the current database system.
+ *
+ * @return bool
+ */
+ function utf8mb4_is_supported() {
+ // By default we assume that the database backend may not support 4 byte
+ // UTF-8.
+ return FALSE;
+ }
+}
diff --git a/src/Service/Http/HttpApacheService.php b/src/Service/Http/HttpApacheService.php
new file mode 100644
index 0000000..7e2812c
--- /dev/null
+++ b/src/Service/Http/HttpApacheService.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * @file
+ * The Provision HttpApacheService class.
+ *
+ * @see \Provision_Service_http_apache
+ */
+
+namespace Aegir\Provision\Service\Http;
+
+use Aegir\Provision\Service\HttpService;
+
+/**
+ * Class HttpApacheService
+ *
+ * @package Aegir\Provision\Service\Http
+ */
+class HttpApacheService extends HttpService
+{
+ const SERVICE_TYPE = 'apache';
+ const SERVICE_TYPE_NAME = 'Apache';
+}
diff --git a/src/Service/Http/HttpNginxService.php b/src/Service/Http/HttpNginxService.php
new file mode 100644
index 0000000..6e837c4
--- /dev/null
+++ b/src/Service/Http/HttpNginxService.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * @file
+ * The Provision HttpNginxService class.
+ *
+ * @see \Provision_Service_http_Nginx
+ */
+
+namespace Aegir\Provision\Service\Http;
+
+use Aegir\Provision\Service\HttpService;
+
+/**
+ * Class HttpNginxService
+ *
+ * @package Aegir\Provision\Service\Http
+ */
+class HttpNginxService extends HttpService
+{
+ const SERVICE_TYPE = 'nginx';
+ const SERVICE_TYPE_NAME = 'NGINX';
+}
diff --git a/src/Service/HttpService.php b/src/Service/HttpService.php
index 0de52da..07a112f 100644
--- a/src/Service/HttpService.php
+++ b/src/Service/HttpService.php
@@ -11,6 +11,7 @@ namespace Aegir\Provision\Service;
//require_once DRUSH_BASE_PATH . '/commands/core/rsync.core.inc';
use Aegir\Provision\Service;
+use Consolidation\AnnotatedCommand\CommandFileDiscovery;
/**
* Class HttpService
@@ -18,10 +19,21 @@ use Aegir\Provision\Service;
* @package Aegir\Provision\Service
*/
class HttpService extends Service {
- public $service = 'http';
+ const SERVICE = 'http';
+ const SERVICE_NAME = 'Web Server';
+
protected $ssl_enabled = FALSE;
- /**
+ static function option_documentation() {
+ return array(
+ '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',
+ );
+ }
+
+
+ /**
* Support the ability to cloak the database credentials using environment variables.
*/
function cloaked_db_creds() {