From 87164a495599517438c3d0b2650cd08d86eabd32 Mon Sep 17 00:00:00 2001 From: Lindsey Catlett Date: Mon, 13 Aug 2018 06:02:31 -0400 Subject: [PATCH 01/10] Update drush to pinned dev-master to use DRUSH_PATHS_CACHE_DIRECTORY env variable. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 782445c8a..8a8d66eb0 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "doctrine/common": "^2.5", "doctrine/inflector": "~1.1.0", "drupal/coder": "^8.2.11", - "drush/drush": "^9.3.0", + "drush/drush": "dev-master#e30df96a53e51b8abb278cf1c25cd29ee30af63c as 9.3.0", "grasmash/drupal-security-warning": "^1.0.0", "grasmash/yaml-cli": "^1.0.0", "grasmash/yaml-expander": "^1.2.0", From 7404038812647586ee12d003ba2f11e2e8227f76 Mon Sep 17 00:00:00 2001 From: Lindsey Catlett Date: Mon, 13 Aug 2018 06:06:56 -0400 Subject: [PATCH 02/10] Add cache directory utility to use in update and post install tasks. --- scripts/blt/cache.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 scripts/blt/cache.php diff --git a/scripts/blt/cache.php b/scripts/blt/cache.php new file mode 100644 index 000000000..7ec14e866 --- /dev/null +++ b/scripts/blt/cache.php @@ -0,0 +1,28 @@ + Date: Mon, 13 Aug 2018 06:08:45 -0400 Subject: [PATCH 03/10] Remove deprecated _ENV and server globals from post install hooks. --- .../post-install/post-install.php | 97 ++++++++++++++++--- 1 file changed, 86 insertions(+), 11 deletions(-) diff --git a/scripts/factory-hooks/post-install/post-install.php b/scripts/factory-hooks/post-install/post-install.php index d44634936..70826e846 100755 --- a/scripts/factory-hooks/post-install/post-install.php +++ b/scripts/factory-hooks/post-install/post-install.php @@ -8,20 +8,95 @@ * in your subscription. Unlike most API-based hooks, this hook does not * take arguments, but instead executes the PHP code it is provided. * - * This is used so that an ACSF site install will match a local BLT site - * install. After a local site install, the update functions are run. + * This is used so that an ACSF site install is identical to the local BLT site + * install, with the environment, site, and uri CLI runtime arguments overriding + * all other configuration. * */ -$site = $_ENV['AH_SITE_GROUP']; -$env = $_ENV['AH_SITE_ENVIRONMENT']; -$target_env = $site . $env; +use Drush\Drush; +use Drupal\Component\FileCache\FileCacheFactory; +use Drupal\Core\Database\Database; +use Drupal\Core\Site\Settings; + + +// Acquia hosting site / environment names +$site = getenv('AH_SITE_GROUP'); +$env = getenv('AH_SITE_ENVIRONMENT'); +$uri = FALSE; + +// ACSF Database Role + if (!empty($GLOBALS['gardens_site_settings']['conf']['acsf_db_name'])) { + $db_role = $GLOBALS['gardens_site_settings']['conf']['acsf_db_name']; + } + +$docroot = sprintf('/var/www/html/%s.%s/docroot', $site, $env); + +// BLT executable +$blt = sprintf('/var/www/html/%s.%s/vendor/bin/blt', $site, $env); + +global $acsf_site_name; + +/** + * Exit on error. + * + * @param string $message + * A message to write to sdderr. + */ +function error($message) { + fwrite(STDERR, $message); + exit(1); +} + +fwrite(STDERR, sprintf("Running updates on: site: %s; env: %s; db_role: %s; name: %s;\n", $site, $env, $db_role, $acsf_site_name)); + +include_once $docroot . '/sites/g/sites.inc'; +$sites_json = gardens_site_data_load_file(); +if (!$sites_json) { + error('The ACSF site registry could not be loaded from the server.'); +} + +foreach ($sites_json['sites'] as $site_domain => $site_info) { + if ($site_info['conf']['acsf_db_name'] === $db_role && !empty($site_info['flags']['preferred_domain'])) { + $uri = $site_domain; + fwrite(STDERR, "Site domain: $uri;\n"); + break; + } +} +if (!$uri) { + error('Could not find the preferred domain that belongs to the site.'); +} + +$docroot = sprintf('/var/www/html/%s.%s/docroot', $site, $env); + +// Create a temporary cache directory for this drush process. +// @TODO: use the cache.php helper script. +$cache_directory = sprintf('/mnt/tmp/%s.%s/drush_tmp_cache/%s', $site, $env, md5($uri)); +shell_exec(sprintf('mkdir -p %s', escapeshellarg($cache_directory))); + +// Execute the updates +$command = sprintf( + 'DRUSH_PATHS_CACHE_DIRECTORY=%s %s drupal:update --environment=%s --site=%s --define drush.uri=%s --verbose --yes --no-interaction', + escapeshellarg($cache_directory), + escapeshellarg($blt), + escapeshellarg($env), + escapeshellarg($acsf_site_name), + escapeshellarg($uri) +); +fwrite(STDERR, "Executing: $command with cache dir $cache_directory;\n"); + +$result = 0; +$output = array(); +exec($command, $output, $result); +print join("\n", $output); + +// Clean up the drush cache directory. +shell_exec(sprintf('rm -rf %s', escapeshellarg($cache_directory))); + +if ($result) { + fwrite(STDERR, "Command execution returned status code: $result!\n"); + exit($result); +} -// The public domain name of the website. -// Run updates against requested domain rather than acsf primary domain. -$domain = $_SERVER['HTTP_HOST']; -$domain_fragments = explode('.', $_SERVER['HTTP_HOST']); -$site_name = array_shift($domain_fragments); -exec("/mnt/www/html/$site.$env/vendor/acquia/blt/bin/blt drupal:update --environment=$env --site=$site_name --define drush.uri=$domain --verbose --yes"); From a83b8e033d383da5c02cf339b9856095e2a602d0 Mon Sep 17 00:00:00 2001 From: Lindsey Catlett Date: Mon, 13 Aug 2018 06:11:43 -0400 Subject: [PATCH 04/10] Remove redundant cache clears from config update commands. --- src/Robo/Commands/Setup/ConfigCommand.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Robo/Commands/Setup/ConfigCommand.php b/src/Robo/Commands/Setup/ConfigCommand.php index 74bb6f5bc..33341a238 100644 --- a/src/Robo/Commands/Setup/ConfigCommand.php +++ b/src/Robo/Commands/Setup/ConfigCommand.php @@ -53,11 +53,6 @@ public function import() { $task = $this->taskDrush() ->stopOnFail() - // Sometimes drush forgets where to find its aliases. - ->drush("cc")->arg('drush') - // Rebuild caches in case service definitions have changed. - // @see https://www.drupal.org/node/2826466 - ->drush("cache-rebuild") // Execute db updates. // This must happen before features are imported or configuration is // imported. For instance, if you add a dependency on a new extension to From c31df3f2adad643093bbe76fcc3953bfd24e51a9 Mon Sep 17 00:00:00 2001 From: Lindsey Catlett Date: Mon, 13 Aug 2018 06:15:46 -0400 Subject: [PATCH 05/10] Set default value for drush file based cache dir config. --- template/drush/drush.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/template/drush/drush.yml b/template/drush/drush.yml index cf82eed8e..64e57f226 100644 --- a/template/drush/drush.yml +++ b/template/drush/drush.yml @@ -11,3 +11,5 @@ drush: include: - '${env.home}/.drush' - /usr/share/drush/commands + # Override file-based cache default of $HOME/.drush. + cache-directory: /tmp/.drush From d57600fc4e80b7a8eb5caa750e2c67d034d38c2f Mon Sep 17 00:00:00 2001 From: Lindsey Catlett Date: Mon, 13 Aug 2018 06:19:09 -0400 Subject: [PATCH 06/10] Update db update factory hook DRUSH_PATHS_CACHE_DIRECTORY to use per-process dir. --- scripts/factory-hooks/db-update/db-update.sh | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/scripts/factory-hooks/db-update/db-update.sh b/scripts/factory-hooks/db-update/db-update.sh index b10fef38c..c37903813 100755 --- a/scripts/factory-hooks/db-update/db-update.sh +++ b/scripts/factory-hooks/db-update/db-update.sh @@ -1,4 +1,4 @@ -#!/bin/bash +##!/bin/bash # # Factory Hook: db-update # @@ -26,13 +26,16 @@ blt="/var/www/html/$site.$env/vendor/acquia/blt/bin/blt" uri=`/usr/bin/env php /mnt/www/html/$site.$env/hooks/acquia/uri.php $site $env $db_role` # Print a statement to the cloud log. -echo "$site.$target_env: Running BLT deploy tasks on $uri domain in $env environment on the $site subscription." +echo "Running BLT deploy tasks on $uri domain in $env environment on the $site subscription." IFS='.' read -a name <<< "${uri}" -# Set Drush cache to local ephemeral storage to avoid race conditions. This is -# done on a per site basis to completely avoid race conditions. +# Create and set Drush cache to local ephemeral storage to avoid race conditions. This is +# done on a per site process basis to completely avoid race conditions. # @see https://github.com/acquia/blt/pull/2922 -export DRUSH_PATHS_CACHE_DIRECTORY=/tmp/.drush/${db_role} -$blt drupal:update --environment=$env --site=${name[0]} --define drush.uri=$domain --verbose --yes +cacheDir=`/usr/bin/env php /mnt/www/html/$site.$env/vendor/acquia/blt/scripts/blt/cache.php $site $env $uri` + +DRUSH_PATHS_CACHE_DIRECTORY=$cacheDir $blt drupal:update --environment=$env --site=${name[0]} --define drush.uri=$domain --verbose --yes --no-interaction + + From dfe18102bd601331ada31f454fc7580f53280303 Mon Sep 17 00:00:00 2001 From: Lindsey Catlett Date: Mon, 13 Aug 2018 06:27:44 -0400 Subject: [PATCH 07/10] Add update hook to refresh factory hook templates. --- src/Update/Updates.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/Update/Updates.php b/src/Update/Updates.php index 03b9fe166..2c27a6e53 100644 --- a/src/Update/Updates.php +++ b/src/Update/Updates.php @@ -606,4 +606,23 @@ public function update_9001001() { $this->updater->getOutput()->writeln(""); } + /** + * 9.1.2. + * + * @Update( + * version = "9001002", + * description = "Factory Hooks Drush 9 bug fixes and enhancements." + * ) + */ + public function update_9001002() { + if (file_exists($this->updater->getRepoRoot() . '/factory-hooks')) { + $messages[] = "This update will update the files in your existing factory hooks directory."; + $messages[] = "Review the resulting files and ensure that any customizations have been re-added."; + $this->updater->executeCommand("./vendor/bin/blt recipes:acsf:init:hooks"); + } + $formattedBlock = $this->updater->getFormatter()->formatBlock($messages, 'ice'); + $this->updater->getOutput()->writeln(""); + $this->updater->getOutput()->writeln($formattedBlock); + $this->updater->getOutput()->writeln(""); + } } From 7da0fbe3a5c2fe0acd53f1cce15906379bcb8432 Mon Sep 17 00:00:00 2001 From: Lindsey Catlett Date: Mon, 13 Aug 2018 06:35:10 -0400 Subject: [PATCH 08/10] Add exception for projects not using Factory hooks. --- src/Update/Updates.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Update/Updates.php b/src/Update/Updates.php index 2c27a6e53..835b5ed22 100644 --- a/src/Update/Updates.php +++ b/src/Update/Updates.php @@ -619,6 +619,8 @@ public function update_9001002() { $messages[] = "This update will update the files in your existing factory hooks directory."; $messages[] = "Review the resulting files and ensure that any customizations have been re-added."; $this->updater->executeCommand("./vendor/bin/blt recipes:acsf:init:hooks"); + } else { + $messages = ["Updated BLT. Review and commit any changes to project files."]; } $formattedBlock = $this->updater->getFormatter()->formatBlock($messages, 'ice'); $this->updater->getOutput()->writeln(""); From 6c0d1714874d71a81200a34c309f721453bc3994 Mon Sep 17 00:00:00 2001 From: Lindsey Catlett Date: Mon, 13 Aug 2018 06:42:52 -0400 Subject: [PATCH 09/10] Style and syntax clean up. --- scripts/blt/cache.php | 7 ++++--- src/Update/Updates.php | 6 ++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/scripts/blt/cache.php b/scripts/blt/cache.php index 7ec14e866..fc9a2fee0 100644 --- a/scripts/blt/cache.php +++ b/scripts/blt/cache.php @@ -23,6 +23,7 @@ if (!file_exists($cache_directory)) { syslog(LOG_ERR, sprintf('Drush updates could not be executed, as the required cache directory [%s] is missing.', $cache_directory)); die('Missing or corrupted drush cache for this process.'); -} else { - echo "$cache_directory"; -} \ No newline at end of file +} +else { + echo "$cache_directory"; +} diff --git a/src/Update/Updates.php b/src/Update/Updates.php index 835b5ed22..8ff896235 100644 --- a/src/Update/Updates.php +++ b/src/Update/Updates.php @@ -615,11 +615,12 @@ public function update_9001001() { * ) */ public function update_9001002() { - if (file_exists($this->updater->getRepoRoot() . '/factory-hooks')) { + if (file_exists($this->updater->getRepoRoot() . '/factory-hooks')) { $messages[] = "This update will update the files in your existing factory hooks directory."; $messages[] = "Review the resulting files and ensure that any customizations have been re-added."; $this->updater->executeCommand("./vendor/bin/blt recipes:acsf:init:hooks"); - } else { + } + else { $messages = ["Updated BLT. Review and commit any changes to project files."]; } $formattedBlock = $this->updater->getFormatter()->formatBlock($messages, 'ice'); @@ -627,4 +628,5 @@ public function update_9001002() { $this->updater->getOutput()->writeln($formattedBlock); $this->updater->getOutput()->writeln(""); } + } From b002c4bf8c1a083bc043c22e19b9daa8b8d4777f Mon Sep 17 00:00:00 2001 From: Lindsey Catlett Date: Tue, 14 Aug 2018 09:39:13 -0400 Subject: [PATCH 10/10] Add updated host forwarding, remove globals. --- settings/blt.settings.php | 72 +++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 25 deletions(-) diff --git a/settings/blt.settings.php b/settings/blt.settings.php index 26f4f31fa..e278fa674 100644 --- a/settings/blt.settings.php +++ b/settings/blt.settings.php @@ -5,28 +5,57 @@ * Setup BLT utility variables, include required files. */ - use Acquia\Blt\Robo\Config\ConfigInitializer; +use Acquia\Blt\Robo\Config\ConfigInitializer; use Drupal\Component\Utility\Bytes; -use Drupal\Core\DrupalKernel; use Symfony\Component\Console\Input\ArgvInput; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; -/** - * Host detection. - */ -if (!empty($_SERVER['HTTP_X_FORWARDED_HOST'])) { - $forwarded_host = $_SERVER['HTTP_X_FORWARDED_HOST']; -} -elseif (!empty($_SERVER['HTTP_HOST'])) { - $forwarded_host = $_SERVER['HTTP_HOST']; +/******************************************************************************* + * Host forwarding. + ******************************************************************************/ + +// Drupal 8 aliasing/importing. +// Must be declared in global scope. +$http_host = getenv('HTTP_HOST'); +$request_method = getenv('REQUEST_METHOD'); +$request_uri = getenv('REQUEST_URI'); +$http_x_request_id = getenv('HTTP_X_REQUEST_ID'); + +// Tell Drupal whether the client arrived via HTTPS. Ensure the +// request is coming from our load balancers by checking the IP address. +if (getenv('HTTP_X_FORWARDED_PROTO') == 'https' + && getenv('REMOTE_ADDR') + && in_array(getenv('REMOTE_ADDR'), $trusted_reverse_proxy_ips)) { + $_ENV['HTTPS'] = 'on'; + $_SERVER['HTTPS'] = 'on'; + putenv('HTTPS=on'); } -else { - $forwarded_host = NULL; +$x_ips = getenv('HTTP_X_FORWARDED_FOR') ? explode(',', getenv('HTTP_X_FORWARDED_FOR')) : array(); +$x_ips = array_map('trim', $x_ips); + +// Add REMOTE_ADDR to the X-Forwarded-For in case it's an internal AWS address. +if (getenv('REMOTE_ADDR')) { + $x_ips[] = getenv('REMOTE_ADDR'); } -$server_protocol = empty($_SERVER['HTTPS']) ? 'http' : 'https'; -$forwarded_protocol = !empty($_ENV['HTTP_X_FORWARDED_PROTO']) ? $_ENV['HTTP_X_FORWARDED_PROTO'] : $server_protocol; +// Check firstly for the bal and then check for an internal IP immediately. +$settings['reverse_proxy_addresses'] = array(); +if ($ip = array_pop($x_ips)) { + if (in_array($ip, $trusted_reverse_proxy_ips)) { + if (!in_array($ip, $settings['reverse_proxy_addresses'])) { + $settings['reverse_proxy_addresses'][] = $ip; + } + // We have a reverse proxy so turn the setting on. + $settings['reverse_proxy'] = TRUE; + + // Get the next IP to test if it is internal. + $ip = array_pop($x_ips); + if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)) { + if (!in_array($ip, $settings['reverse_proxy_addresses'])) { + $settings['reverse_proxy_addresses'][] = $ip; + } + } + } +} /******************************************************************************* * Environment detection. @@ -92,12 +121,7 @@ * Site directory detection. */ if (!isset($site_path)) { - try { - $site_path = DrupalKernel::findSitePath(Request::createFromGlobals()); - } - catch (BadRequestHttpException $e) { - $site_path = 'sites/default'; - } + $site_path = \Drupal::service('site.path'); } $site_dir = str_replace('sites/', '', $site_path); @@ -116,7 +140,7 @@ // The hostname must match the pattern local.[sitename].com, where // [sitename] is a value in the multisites array. - $domain_fragments = explode('.', $_SERVER['HTTP_HOST']); + $domain_fragments = explode('.', $http_host); $name = array_slice($domain_fragments, 1); $acsf_sites = $blt_config->get('multisites'); if (in_array($name, $acsf_sites)) { @@ -135,8 +159,6 @@ ******************************************************************************/ if ($is_ah_env) { - // Tempoary fix for CL-21595. - $_SERVER['PWD'] = DRUPAL_ROOT; $group_settings_file = "/var/www/site-php/$ah_group/$ah_group-settings.inc"; $site_settings_file = "/var/www/site-php/$ah_group/$site_dir-settings.inc"; if (!$is_acsf_env && file_exists($group_settings_file)) {