Skip to content

Commit

Permalink
Prevent cache collisions in multisite db-update tasks (acquia#3166)
Browse files Browse the repository at this point in the history
* Add drush cache dir utility script.

* Enhanced Factory Hook to isolate db-update tasks to tempoary drush cache.

* Update Factory Hooks from BLT template.

* Remove redundant cache clear and rebuild to preserve drush context of current request.

* Style tweaks and setting update version number to 9.2.
  • Loading branch information
lcatlett committed Oct 20, 2018
1 parent 888bad7 commit 3aeae33
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 16 deletions.
29 changes: 29 additions & 0 deletions scripts/blt/drush/cache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

/**
* @file
* Creates a unique temporary cache directory given a site, env, and uri.
* This is used for every blt command invocation on site install and update.
*/

$site = $argv[1];
$env = $argv[2];
$uri = $argv[3];


if (empty($argv[3])) {
echo "Error: Not enough arguments. Site, environment, and uri are required.\n";
exit(1);
}

// Create a temporary cache directory for this drush process only.
$cache_directory = sprintf('/mnt/tmp/%s.%s/drush_tmp_cache/%s', $site, $env, md5($uri));
shell_exec(sprintf('mkdir -p %s', escapeshellarg($cache_directory)));

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";
}
24 changes: 15 additions & 9 deletions scripts/factory-hooks/db-update/db-update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,27 @@ db_role="$3"
domain="$4"

# BLT executable:
blt="/var/www/html/$site.$env/vendor/acquia/blt/bin/blt"
blt="/mnt/www/html/$site.$env/vendor/acquia/blt/bin/blt"

# You need the URI of the site factory website in order for drush to target that
# site. Without it, the drush command will fail. Use the uri.php file provided by the acsf module to
# locate the URI based on the site, environment and db role arguments.
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."

# Create array with site name fragments from ACSF uri.
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.
# @see https://github.com/acquia/blt/pull/2922
export DRUSH_PATHS_CACHE_DIRECTORY=/tmp/.drush/${db_role}
# Create and set Drush cache to unique local temporary storage per site.
# This approach isolates drush processes to completely avoid race conditions
# that persist after initial attempts at addressing in BLT: https://github.com/acquia/blt/pull/2922

cacheDir=`/usr/bin/env php /mnt/www/html/$site.$env/vendor/acquia/blt/scripts/blt/drush/cache.php $site $env $uri`

# Print to cloud task log.
echo "Generated temporary drush cache directory: $cacheDir."

# Print to cloud task log.
echo "Running BLT deploy tasks on $uri domain in $env environment on the $site subscription."

DRUSH_PATHS_CACHE_DIRECTORY=$cacheDir $blt drupal:update --environment=$env --site=${name[0]} --define drush.uri=$domain --verbose --yes --no-interaction

$blt drupal:update --environment=$env --site=${name[0]} --define drush.uri=$domain --verbose --yes
5 changes: 0 additions & 5 deletions src/Robo/Commands/Setup/ConfigCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
25 changes: 23 additions & 2 deletions src/Update/Updates.php
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ public function update_9001000() {
// Update composer.json to include new BLT required/suggested files.
// Pulls in wikimedia/composer-merge-plugin and composer/installers settings.
$project_composer_json = $this->updater->getRepoRoot() . '/composer.json';
$template_composer_json = $this->updater->getBltRoot() . '/subtree-splits/blt-project/composer.json';
$template_composer_json = $this->updater->getBltRoot() . '/template/composer.json';
$munged_json = ComposerMunge::mungeFiles($project_composer_json, $template_composer_json);
$bytes = file_put_contents($project_composer_json, $munged_json);
if (!$bytes) {
Expand Down Expand Up @@ -606,6 +606,28 @@ public function update_9001001() {
$this->updater->getOutput()->writeln("");
}

/**
* 9.2.0.
*
* @Update(
* version = "9002000",
* description = "Factory Hooks Drush 9 bug fixes and enhancements."
* )
*/
public function update_9002000() {
if (file_exists($this->updater->getRepoRoot() . '/factory-hooks')) {
$messages = [
"This update will update the files in your existing factory hooks directory.",
"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("");
}

/**
* 10.0.0.
*
Expand All @@ -632,7 +654,6 @@ public function update_10000000() {
$composer_json[$sync_composer_key] = ArrayManipulator::arrayMergeRecursiveDistinct( $composer_json[$sync_composer_key], $template_composer_json[$sync_composer_key]);
}
$composer_json['require-dev']['acquia/blt-require-dev'] = $template_composer_json['require']['acquia/blt-require-dev'];

$this->updater->writeComposerJson($composer_json);
$messages = [
"Your composer.json file has been modified to remove the Composer merge plugin.",
Expand Down

0 comments on commit 3aeae33

Please sign in to comment.