Repository URL to install this package:
|
Version:
2.2.4 ▾
|
<?php
namespace MeltConsole\App\Commands;
use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\ConfirmationQuestion;
/**
* Handles functionality to remove environments from server.
*
* @package MeltConsole\App\Commands
*/
class RemoveEnvironmentCommand extends MeltCommand {
/**
* Environments to exclude from removal.
*
* If these need to be removed, then that should be done on the server.
*
* @var array
*/
private $excludedEnvs = ['dev', 'qa', 'stage', 'uat', 'prod'];
/**
* {@inheritdoc}
*/
protected function configure() {
// Initial config for command.
$this
->setName('melt:remove-environment')
->setAliases(['melt:re'])
->setDescription('Removes environment on the remote server.')
->setHelp('This command allows you to remove an environment...')
->addOption('env', 'e', InputOption::VALUE_REQUIRED, 'Environment e.g dev, qa, stage');
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output) {
parent::interact($input, $output);
if (!$input->getOption('env')) {
$current_envs = $this->getEnvironmentsFromServer();
if (!empty($current_envs)) {
// Ask the user if their 100% sure they want to create the environment.
$output->writeln([
'-----------------------------',
' NOTICE',
'-----------------------------',
'FYI, we won\'t actually remove the environment immediately.',
'We\'ll first create a backup of the database and files and store them',
'at in the <info>/opt/backups</info> directory in case we need to restore.',
'-----------------------------',
]);
// Ask the user some stuff.
$helper = $this->getHelper('question');
$question = new ChoiceQuestion('Choose the environment you\'d like to slaughter!', $current_envs);
$env = $helper->ask($input, $output, $question);
if (empty($env)) {
throw new LogicException('Please enter a value for environment name.');
}
if (in_array($env, $this->excludedEnvs)) {
throw new LogicException("The {$env} environment can not be removed by {$this->appName}. The environment should be removed on the server.");
}
// Set options based on users answer.
$input->setOption('env', $env);
}
else {
throw new LogicException('There are no environments available for removal.');
}
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output) {
$env = $input->getOption('env');
if ($this->validateEnvironmentExistsOnServer($env)) {
$dirname = "{$this->projectName}-{$env}";
$helper = $this->getHelper('question');
$question = new ConfirmationQuestion(sprintf(
'Exterminate <info>%s</info> environment? (y/N)',
$dirname
), FALSE);
if ($helper->ask($input, $output, $question)) {
// Remove env from server.
$output->writeln('Exterimination in progress...');
$this->removeEnvironment($env);
$output->writeln("{$dirname} environment has been exterminated! Muhahahaha!!");
if ($this->environmentHasDrushAlias($env)) {
$output->writeln("To be nice, I'm also going to annihilate the drush alias for <info>${dirname}</info>...");
$this->removeDrushAlias($env);
$output->writeln("BOOM! alias has been annihilated from <info>{$this->pathToDrushAlias}</info>!!!");
}
}
}
else {
throw new LogicException(sprintf(
'Whaaaaa??? It appears the %s environment doesn\'t exists on the server. Skipping.',
$env
));
}
}
/**
* Create's new directory on server by cloning the git repo.
*
* @param string $env
* Directory name.
*/
protected function removeEnvironment(string $env) {
$projectName = "{$this->projectName}-{$env}";
$timestamp = date('Ymdhi');
$backup_name = "{$projectName}-{$timestamp}";
$backup_dir = '/opt/backups';
$filesDir = 'docroot/sites/default/files/';
$dbName = str_replace('-', '_', $projectName);
$dbUser = $this->getServerEnvVar('MELT_DB_USER');
$dbPass = $this->getServerEnvVar('MELT_DB_PASS');
// Backup files
$this->runServerCommands([
// Change into src directory.
"cd /{$this->serverRoot}/{$projectName}",
// Make sure `files` dir exists before rsyncing
"[ -d {$filesDir} ]", // Make sure `files` dir exists before rsyncing
// Zip `docroot/sites/default/files` and move to backup directory
"tar -czf {$backup_dir}/{$backup_name}.tar.gz {$filesDir}",
]);
// Backup database
$this->runServerCommands([
// Change into src directory.
"cd /{$this->serverRoot}/{$projectName}",
// Add to backups directory
"drush sql:dump --gzip --result-file={$backup_dir}/{$backup_name}.sql",
]);
// Time to remove files related to environment
$this->runServerCommands([
// Remove SSL config
"sudo rm /etc/nginx/ssl/ssl_{$projectName}.conf",
// Remove nginx sites-available config
"sudo rm /etc/nginx/sites-available/{$projectName}",
// Remove nginx sites-enabled symbolic link
"sudo rm /etc/nginx/sites-enabled/{$projectName}",
// Drop database
"sudo mysql -u{$dbUser} -p{$dbPass} -e 'DROP DATABASE {$dbName}'",
// Remove project directory
"sudo rm -rf /{$this->serverRoot}/{$projectName}",
// Test nginx
'sudo nginx -t',
// Reload nginx
'sudo systemctl reload nginx',
// Reload php
'sudo systemctl reload php7.2-fpm'
]);
}
/**
* Removes drush alias from @var $pathToDrushAlias.
*
* @param string $env
* Environment name.
*/
protected function removeDrushAlias(string $env) {
$aliases = $this->getDrushAliases();
if (isset($aliases[$env])) {
// Delete alias.
unset($aliases[$env]);
// Create a YAML string to pass off to our @var $pathToDrushAlias.
$this->writeToYamlFile($aliases, $this->pathToDrushAlias);
}
else {
$this->logger->log('warning', 'No alias not found to remove. Skipping.');
}
}
}