From 21b60e0708191c47b03684a04e747ba6b30584a3 Mon Sep 17 00:00:00 2001 From: James Brooks Date: Fri, 29 Apr 2016 13:20:17 +0100 Subject: [PATCH] Take a backup before calling app commands. Closes #1730 --- .../Providers/ConsoleServiceProvider.php | 45 ++++++ app/Subscribers/CommandSubscriber.php | 117 +++++++++++++++ composer.json | 5 +- composer.lock | 138 +++++++++++++++++- config/app.php | 2 + config/backup-manager.php | 70 +++++++++ database/backups/.gitignore | 1 + 7 files changed, 368 insertions(+), 10 deletions(-) create mode 100644 app/Foundation/Providers/ConsoleServiceProvider.php create mode 100644 app/Subscribers/CommandSubscriber.php create mode 100644 config/backup-manager.php create mode 100644 database/backups/.gitignore diff --git a/app/Foundation/Providers/ConsoleServiceProvider.php b/app/Foundation/Providers/ConsoleServiceProvider.php new file mode 100644 index 00000000..54d2b92b --- /dev/null +++ b/app/Foundation/Providers/ConsoleServiceProvider.php @@ -0,0 +1,45 @@ + + */ +class ConsoleServiceProvider extends ServiceProvider +{ + /** + * Boot the service provider. + * + * @return void + */ + public function boot() + { + $subscriber = $this->app->make(CommandSubscriber::class); + + $this->app->events->subscribe($subscriber); + } + + /** + * Register the service provider. + * + * @return void + */ + public function register() + { + // + } +} diff --git a/app/Subscribers/CommandSubscriber.php b/app/Subscribers/CommandSubscriber.php new file mode 100644 index 00000000..6e46c032 --- /dev/null +++ b/app/Subscribers/CommandSubscriber.php @@ -0,0 +1,117 @@ + + */ +class CommandSubscriber +{ + /** + * The config repository. + * + * @var \Illuminate\Contracts\Config\Repository + */ + protected $config; + + /** + * Create a new command subscriber instance. + * + * @param \Illuminate\Contracts\Config\Repository $config + * + * @return void + */ + public function __construct(Repository $config) + { + $this->config = $config; + } + + /** + * Register the listeners for the subscriber. + * + * @param \Illuminate\Contracts\Events\Dispatcher $events + * + * @return void + */ + public function subscribe(Dispatcher $events) + { + $events->listen('command.installing', __CLASS__.'@onInstalling', 5); + $events->listen('command.updating', __CLASS__.'@onUpdating', 5); + $events->listen('command.resetting', __CLASS__.'@onResetting', 5); + } + + /** + * Handle a command.installing event. + * + * @param \Illuminate\Console\Command $command + * + * @return void + */ + public function onInstalling(Command $command) + { + $this->backupDatabases($command); + } + + /** + * Handle a command.updating event. + * + * @param \Illuminate\Console\Command $command + * + * @return void + */ + public function onUpdating(Command $command) + { + $this->backupDatabases($command); + } + + /** + * Handle a command.resetting event. + * + * @param \Illuminate\Console\Command $command + * + * @return void + */ + public function onResetting(Command $command) + { + $this->backupDatabases($command); + } + + /** + * Backup the databases. + * + * @param \Illuminate\Console\Command $command + * + * @return void + */ + protected function backupDatabases(Command $command) + { + $command->line('Backing up database...'); + + $date = Carbon::now()->format('Y-m-d H.i.s'); + + $command->call('db:backup', [ + '--database' => $this->config->get('database.default'), + '--destination' => 'local', + '--destinationPath' => $date, + '--compression' => 'gzip', + ]); + + $command->line('Backup completed...'); + } +} diff --git a/composer.json b/composer.json index a587395c..7d66d347 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,7 @@ "doctrine/dbal": "^2.5", "fideloper/proxy": "^3.1", "graham-campbell/binput": "^3.4", - "graham-campbell/core": "^4.3", + "graham-campbell/core": "^5.0", "graham-campbell/markdown": "^6.1", "graham-campbell/exceptions": "^8.4", "guzzlehttp/guzzle": "^6.2", @@ -37,7 +37,8 @@ "mccool/laravel-auto-presenter": "^4.2", "pragmarx/google2fa": "^0.7.1", "rcrowe/twigbridge": "^0.9.2", - "roumen/feed": "^2.10" + "roumen/feed": "^2.10", + "backup-manager/laravel": "^1.1" }, "require-dev": { "alt-three/testbench": "^1.1", diff --git a/composer.lock b/composer.lock index e797e899..61d1586b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "e63067b7d2535cd6ebf2116d79b62d82", - "content-hash": "65ecacdd5c4d863b2af57ba8baec431d", + "hash": "c536395b4f295e266e96f1e1db0878ee", + "content-hash": "5751c0ab3f8417284e92bd23bb1ff835", "packages": [ { "name": "alt-three/badger", @@ -261,6 +261,128 @@ ], "time": "2016-04-22 17:26:22" }, + { + "name": "backup-manager/backup-manager", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/backup-manager/backup-manager.git", + "reference": "e793277e6f6efae6a31c7abbd8028cae7e151201" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/backup-manager/backup-manager/zipball/e793277e6f6efae6a31c7abbd8028cae7e151201", + "reference": "e793277e6f6efae6a31c7abbd8028cae7e151201", + "shasum": "" + }, + "require": { + "league/flysystem": "~1.0", + "php": ">=5.5.9", + "symfony/process": "~2.1||~3.0" + }, + "require-dev": { + "aws/aws-sdk-php": "~3.0", + "dropbox/dropbox-sdk": "~1.1", + "league/flysystem-aws-s3-v3": "~1.0", + "league/flysystem-dropbox": "~1.0", + "league/flysystem-rackspace": "~1.0", + "league/flysystem-sftp": "~1.0", + "mockery/mockery": "~0.9", + "phpspec/phpspec": "~2.1", + "satooshi/php-coveralls": "~0.6" + }, + "suggest": { + "league/flysystem-aws-s3-v3": "AwsS3 and GoogleCS adapter support.", + "league/flysystem-dropbox": "Dropbox adapter support.", + "league/flysystem-rackspace": "Rackspace adapter support.", + "league/flysystem-sftp": "Sftp adapter support." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "BackupManager\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Shawn McCool", + "email": "shawn@heybigname.com", + "homepage": "http://heybigname.com/" + }, + { + "name": "Mitchell van Wijngaarden", + "email": "mitchell@kooding.nl", + "homepage": "http://heybigname.com/" + } + ], + "description": "A framework agnostic database backup manager with user-definable procedures and support for S3, Dropbox, FTP, SFTP, and more with drivers for popular frameworks.", + "time": "2016-02-05 10:01:19" + }, + { + "name": "backup-manager/laravel", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/backup-manager/laravel.git", + "reference": "d7e6d12d24b8a27f58cf5eccb1ac943104c09856" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/backup-manager/laravel/zipball/d7e6d12d24b8a27f58cf5eccb1ac943104c09856", + "reference": "d7e6d12d24b8a27f58cf5eccb1ac943104c09856", + "shasum": "" + }, + "require": { + "backup-manager/backup-manager": "^1.0", + "illuminate/console": "^4.0||^5.0", + "illuminate/container": "^4.0||^5.0", + "illuminate/support": "^4.0||^5.0", + "php": ">=5.5.0", + "symfony/process": "^2.0||^3.0" + }, + "require-dev": { + "mockery/mockery": "dev-master", + "satooshi/php-coveralls": "~0.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "BackupManager\\Laravel\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Shawn McCool", + "email": "shawn@heybigname.com", + "homepage": "http://heybigname.com/" + }, + { + "name": "Mitchell van Wijngaarden", + "email": "mitchell@kooding.nl", + "homepage": "http://heybigname.com/" + } + ], + "description": "Database backup manager seamlessly integrated with Laravel 4 or 5 with user-definable procedures and support for S3, Dropbox, FTP, SFTP, and more.", + "time": "2016-02-22 10:52:12" + }, { "name": "bacon/bacon-qr-code", "version": "1.0.1", @@ -1082,16 +1204,16 @@ }, { "name": "graham-campbell/core", - "version": "v4.3.0", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/GrahamCampbell/Laravel-Core.git", - "reference": "feb7c112bf09a7a01b12695ed9d81700be8f59f1" + "reference": "99e01720b3db50ca9aa2eac89a3a9e3c377e6444" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/GrahamCampbell/Laravel-Core/zipball/feb7c112bf09a7a01b12695ed9d81700be8f59f1", - "reference": "feb7c112bf09a7a01b12695ed9d81700be8f59f1", + "url": "https://api.github.com/repos/GrahamCampbell/Laravel-Core/zipball/99e01720b3db50ca9aa2eac89a3a9e3c377e6444", + "reference": "99e01720b3db50ca9aa2eac89a3a9e3c377e6444", "shasum": "" }, "require": { @@ -1108,7 +1230,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -1138,7 +1260,7 @@ "laravel", "starter" ], - "time": "2016-04-26 14:18:59" + "time": "2016-05-06 13:42:15" }, { "name": "graham-campbell/exceptions", diff --git a/config/app.php b/config/app.php index 460f1977..ad28809c 100644 --- a/config/app.php +++ b/config/app.php @@ -162,6 +162,7 @@ return [ */ 'AltThree\Badger\BadgerServiceProvider', 'AltThree\Emoji\EmojiServiceProvider', + 'BackupManager\Laravel\Laravel5ServiceProvider', 'Barryvdh\Cors\ServiceProvider', 'Fideloper\Proxy\TrustedProxyServiceProvider', 'GrahamCampbell\Binput\BinputServiceProvider', @@ -180,6 +181,7 @@ return [ */ 'CachetHQ\Cachet\Foundation\Providers\AppServiceProvider', 'CachetHQ\Cachet\Foundation\Providers\ComposerServiceProvider', + 'CachetHQ\Cachet\Foundation\Providers\ConsoleServiceProvider', 'CachetHQ\Cachet\Foundation\Providers\ConfigServiceProvider', 'CachetHQ\Cachet\Foundation\Providers\EventServiceProvider', 'CachetHQ\Cachet\Foundation\Providers\GitHubServiceProvider', diff --git a/config/backup-manager.php b/config/backup-manager.php new file mode 100644 index 00000000..40c8539b --- /dev/null +++ b/config/backup-manager.php @@ -0,0 +1,70 @@ + [ + 'type' => 'Local', + 'root' => database_path('backups'), + ], + 's3' => [ + 'type' => 'AwsS3', + 'key' => '', + 'secret' => '', + 'region' => 'us-east-1', + 'bucket' => '', + 'root' => '', + ], + 'gcs' => [ + 'type' => 'Gcs', + 'key' => '', + 'secret' => '', + 'bucket' => '', + 'root' => '', + ], + 'rackspace' => [ + 'type' => 'Rackspace', + 'username' => '', + 'key' => '', + 'container' => '', + 'zone' => '', + 'endpoint' => 'https://identity.api.rackspacecloud.com/v2.0/', + 'root' => '', + ], + 'dropbox' => [ + 'type' => 'Dropbox', + 'token' => '', + 'key' => '', + 'secret' => '', + 'app' => '', + 'root' => '', + ], + 'ftp' => [ + 'type' => 'Ftp', + 'host' => '', + 'username' => '', + 'password' => '', + 'port' => 21, + 'passive' => true, + 'ssl' => true, + 'timeout' => 30, + 'root' => '', + ], + 'sftp' => [ + 'type' => 'Sftp', + 'host' => '', + 'username' => '', + 'password' => '', + 'port' => 21, + 'timeout' => 10, + 'privateKey' => '', + 'root' => '', + ], +]; diff --git a/database/backups/.gitignore b/database/backups/.gitignore new file mode 100644 index 00000000..72e8ffc0 --- /dev/null +++ b/database/backups/.gitignore @@ -0,0 +1 @@ +*