From b594812b105caa7a4937abd4ff47bd6a9217d75a Mon Sep 17 00:00:00 2001 From: Benjamin Calef Date: Mon, 18 May 2020 18:54:10 +0200 Subject: [PATCH] [init] zero downtime deployment module --- LICENSE | 21 +++++++++++ Model/Plugin/ChangeDetector.php | 62 ++++++++++++++++++++++++++++++++ Plugin/DbStatusValidator.php | 63 +++++++++++++++++++++++++++++++++ README.md | 29 +++++++++++++++ composer.json | 24 +++++++++++++ etc/di.xml | 30 ++++++++++++++++ etc/module.xml | 20 +++++++++++ registration.php | 7 ++++ 8 files changed, 256 insertions(+) create mode 100644 LICENSE create mode 100644 Model/Plugin/ChangeDetector.php create mode 100644 Plugin/DbStatusValidator.php create mode 100644 README.md create mode 100644 composer.json create mode 100644 etc/di.xml create mode 100644 etc/module.xml create mode 100644 registration.php diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5a4dbcf --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Zepgram - Benjamin Calef + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/Model/Plugin/ChangeDetector.php b/Model/Plugin/ChangeDetector.php new file mode 100644 index 0000000..1877239 --- /dev/null +++ b/Model/Plugin/ChangeDetector.php @@ -0,0 +1,62 @@ + + * @copyright 2020 Zepgram Copyright (c) (https://github.com/zepgram) + * @license MIT License + */ + +declare(strict_types=1); + +namespace Zepgram\ZeroDowntimeDeployment\Model\Plugin; + +use Magento\Deploy\Model\DeploymentConfig\ChangeDetector as MagentoChangeDetector; +use Magento\Deploy\Model\DeploymentConfig\DataCollector; +use Magento\Deploy\Model\DeploymentConfig\Hash; +use Magento\Deploy\Model\DeploymentConfig\Hash\Generator as HashGenerator; +use Magento\Framework\App\State; + +/** + * Class ChangeDetector + * Disable change detection in configuration. + */ +class ChangeDetector extends MagentoChangeDetector +{ + /** @var State */ + private $state; + + /** + * ChangeDetector constructor. + * @param Hash $configHash + * @param HashGenerator $hashGenerator + * @param DataCollector $dataConfigCollector + * @param State $state + */ + public function __construct( + Hash $configHash, + HashGenerator $hashGenerator, + DataCollector $dataConfigCollector, + State $state + ) { + $this->state = $state; + parent::__construct($configHash, $hashGenerator, $dataConfigCollector); + } + + /** + * @param null $sectionName + * @return bool + */ + public function hasChanges($sectionName = null) + { + if ($this->state->getMode() === State::MODE_PRODUCTION) { + return false; + } + + return parent::hasChanges($sectionName); + } +} diff --git a/Plugin/DbStatusValidator.php b/Plugin/DbStatusValidator.php new file mode 100644 index 0000000..9453b51 --- /dev/null +++ b/Plugin/DbStatusValidator.php @@ -0,0 +1,63 @@ + + * @copyright 2020 Zepgram Copyright (c) (https://github.com/zepgram) + * @license MIT License + */ + +declare(strict_types=1); + +namespace Zepgram\ZeroDowntimeDeployment\Plugin; + +use Magento\Framework\App\FrontController; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\App\State; +use Magento\Framework\Cache\FrontendInterface as FrontendCacheInterface; +use Magento\Framework\Module\Plugin\DbStatusValidator as MagentoDbStatusValidator; + +/** + * Class DbStatusValidator + * Disable change detection in module version. + */ +class DbStatusValidator +{ + /** @var FrontendCacheInterface */ + private $cache; + + /** @var State */ + private $state; + + /** + * DbStatusValidator constructor. + * @param FrontendCacheInterface $cache + * @param State $state + */ + public function __construct( + FrontendCacheInterface $cache, + State $state + ) { + $this->cache = $cache; + $this->state = $state; + } + + /** + * @param MagentoDbStatusValidator $subject + * @param FrontController $frontController + * @param RequestInterface $request + */ + public function beforeBeforeDispatch( + MagentoDbStatusValidator $subject, + FrontController $frontController, + RequestInterface $request + ) { + if ($this->state->getMode() === State::MODE_PRODUCTION) { + $this->cache->save('true', 'db_is_up_to_date'); + } + } +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..335f694 --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# Zero Downtime Deployment # + +Disable native change detection when Magento2 is on production mode to allow Zero Downtime Deployment (ZDD). + +## Installation +``` +composer require zepgram/module-zero-downtime-deployment +bin/magento module:enable Zepgram_ZeroDowntimeDeployment +bin/magento setup:upgrade +``` + +## Server + +ZDD enables you to deploy your website without any downtime. +However, this module contains only necessary changes to make it possible on Magento2. + +To be able to perform a complete ZDD you'll need a +blue/green deployment strategy. +Which depends on your hosting provider. + +For example: +- AWS: https://aws.amazon.com/fr/quickstart/architecture/blue-green-deployment/ +- Kubernetes: https://kubernetes.io/blog/2018/04/30/zero-downtime-deployment-kubernetes-jenkins/ + +The mainly steps to reach the ZDD with Magento2: +1. Start the deployment: green pods are the old one, for now they must stay active while creating blue pods. +1. Run `bin/magento setup:upgrade --keep-generated` to upgrade your database. +1. Upgrading is done: now green pods must be killed and replaced by blue pods based on health check statement. +1. Even if cache has been already cleared by `bin/magento setup:upgrade` you must clean it again with `bin/magento cache:flush` because old pods may corrupt your cache. diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..7ac5ace --- /dev/null +++ b/composer.json @@ -0,0 +1,24 @@ +{ + "name": "zepgram/module-zero-downtime-deployment", + "description": "Disable native change detection when Magento2 is on production mode to allow Zero Downtime Deployment (ZDD)", + "type": "magento2-module", + "version": "0.0.1", + "require": { + "magento/framework": "^101.0.7|^102.0.0" + }, + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Zepgram\\ZeroDowntimeDeployment\\": "" + } + }, + "license": "proprietary", + "repositories": { + "repo.magento.com": { + "type": "composer", + "url": "https://repo.magento.com/" + } + } +} diff --git a/etc/di.xml b/etc/di.xml new file mode 100644 index 0000000..6b76853 --- /dev/null +++ b/etc/di.xml @@ -0,0 +1,30 @@ + + + + + + + Zepgram\ZeroDowntimeDeployment\Model\Plugin\ChangeDetector + + + + + + + + + Magento\Framework\App\Cache\Type\Config + + + diff --git a/etc/module.xml b/etc/module.xml new file mode 100644 index 0000000..828baf0 --- /dev/null +++ b/etc/module.xml @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/registration.php b/registration.php new file mode 100644 index 0000000..2f8aeb7 --- /dev/null +++ b/registration.php @@ -0,0 +1,7 @@ +