Skip to content

Commit 8ad3554

Browse files
committed
Implement singlestore:prune-backups command
1 parent 8c37eec commit 8ad3554

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
<?php
2+
3+
namespace Miguilim\LaravelSinglestoreBackup\Console;
4+
5+
use Carbon\Carbon;
6+
use Illuminate\Console\Command;
7+
use Illuminate\Contracts\Filesystem\Filesystem;
8+
use Illuminate\Support\Facades\Storage;
9+
10+
class SinglestorePruneBackupsCommand extends Command
11+
{
12+
/**
13+
* The name and signature of the console command.
14+
*
15+
* @var string
16+
*/
17+
protected $signature = 'singlestore:prune-backups {--incremental} {--older-than-days=} {--older-than-date=}';
18+
19+
/**
20+
* The console command description.
21+
*
22+
* @var string
23+
*/
24+
protected $description;
25+
26+
/**
27+
* Execute the console command.
28+
*
29+
* @return int
30+
*/
31+
public function handle()
32+
{
33+
if (config('singlestore-backup.driver') !== 's3') {
34+
$this->error('This command can only be executed with "s3" driver.');
35+
36+
return Command::FAILURE;
37+
}
38+
39+
if ($this->option('incremental') && ($this->option('older-than-days') || $this->option('older-than-date'))) {
40+
$this->error('You can\'t use --incremental and --older-than-days or --older-than-date options at the same time.');
41+
42+
return Command::FAILURE;
43+
}
44+
45+
if ($this->option('older-than-days') && $this->option('older-than-date')) {
46+
$this->error('You can\'t use --older-than-days and --older-than-date options at the same time.');
47+
48+
return Command::FAILURE;
49+
}
50+
51+
/*
52+
* Start backup pruning command
53+
*/
54+
$this->warn('Starting backup pruning... This might take a while.');
55+
56+
$disk = Storage::build([
57+
'driver' => config('singlestore-backup.driver'),
58+
'key' => config('singlestore-backup.public_key'),
59+
'secret' => config('singlestore-backup.secret_key'),
60+
'region' => config('singlestore-backup.region') ?? 'us-east-1',
61+
'bucket' => config('singlestore-backup.bucket'),
62+
'endpoint' => config('singlestore-backup.endpoint'),
63+
'use_path_style_endpoint' => config('singlestore-backup.force_path_style'),
64+
]);
65+
66+
if ($this->option('incremental')) {
67+
if ($disk->exists($this->getBackupName(incremental: true))) {
68+
$disk->deleteDirectory($this->getBackupName(incremental: true));
69+
} else {
70+
$this->error('No incremental backup to prune found.');
71+
72+
return Command::FAILURE;
73+
}
74+
} else {
75+
if ($olderThan = $this->getOlderThan()) {
76+
if (! $this->pruneDateOrTimeBackups($disk, $olderThan)) {
77+
$this->error('No backup with date or time older than '.$olderThan->format('Y-m-d H:i:s').' to prune found.');
78+
79+
return Command::FAILURE;
80+
}
81+
} else {
82+
if ($disk->exists($this->getBackupName())) {
83+
$disk->deleteDirectory($this->getBackupName());
84+
} else {
85+
$this->error('No backup to prune found.');
86+
87+
return Command::FAILURE;
88+
}
89+
}
90+
}
91+
92+
$this->info('Backups pruned successfully.');
93+
94+
return Command::SUCCESS;
95+
}
96+
97+
protected function getOlderThan(): ?Carbon
98+
{
99+
if ($date = $this->option('older-than-date')) {
100+
return Carbon::parse($date);
101+
}
102+
103+
if ($days = $this->option('older-than-days')) {
104+
return Carbon::today()->subDays($days);
105+
}
106+
107+
return null;
108+
}
109+
110+
protected function pruneDateOrTimeBackups(Filesystem $disk, Carbon $olderThan): int
111+
{
112+
$directories = $disk->directories(config('singlestore-backup.path'));
113+
114+
$found = 0;
115+
foreach ($directories as $directory) {
116+
$isBackupDirectory = preg_match('/'.preg_quote(config('database.connections.singlestore.database').'_', '/').'(.*?)\.backup/', $directory, $matches);
117+
118+
if (! $isBackupDirectory) {
119+
continue;
120+
}
121+
122+
$directoryDate = (str_contains($matches[1], '_'))
123+
? Carbon::createFromFormat('Y-m-d_H-i-s', $matches[1])
124+
: Carbon::createFromFormat('Y-m-d', $matches[1]);
125+
126+
if ($directoryDate->isBefore($olderThan)) {
127+
$disk->deleteDirectory($directory);
128+
129+
$found++;
130+
}
131+
}
132+
133+
return $found > 0;
134+
}
135+
136+
protected function getBackupName(bool $incremental = false): string
137+
{
138+
$path = config('singlestore-backup.path');
139+
$database = config('database.connections.singlestore.database');
140+
141+
return ($path ? "{$path}/" : '').$database.($incremental ? '.incr_backup' : '.backup');
142+
}
143+
}

src/LaravelSinglestoreBackupServiceProvider.php

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ protected function configureCommands(): void
4848

4949
$this->commands([
5050
Console\SinglestoreBackupCommand::class,
51+
Console\SinglestorePruneBackupsCommand::class,
5152
]);
5253
}
5354
}

0 commit comments

Comments
 (0)