Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pterodactyl
GitHub Repository: pterodactyl/panel
Path: blob/1.0-develop/app/Services/Backups/DeleteBackupService.php
10260 views
1
<?php
2
3
namespace Pterodactyl\Services\Backups;
4
5
use Illuminate\Http\Response;
6
use Pterodactyl\Models\Backup;
7
use GuzzleHttp\Exception\ClientException;
8
use Illuminate\Database\ConnectionInterface;
9
use Pterodactyl\Extensions\Backups\BackupManager;
10
use Pterodactyl\Repositories\Wings\DaemonBackupRepository;
11
use Pterodactyl\Exceptions\Service\Backup\BackupLockedException;
12
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
13
14
class DeleteBackupService
15
{
16
public function __construct(
17
private ConnectionInterface $connection,
18
private BackupManager $manager,
19
private DaemonBackupRepository $daemonBackupRepository,
20
) {
21
}
22
23
/**
24
* Deletes a backup from the system. If the backup is stored in S3 a request
25
* will be made to delete that backup from the disk as well.
26
*
27
* @throws \Throwable
28
*/
29
public function handle(Backup $backup): void
30
{
31
// If the backup is marked as failed it can still be deleted, even if locked
32
// since the UI doesn't allow you to unlock a failed backup in the first place.
33
//
34
// I also don't really see any reason you'd have a locked, failed backup to keep
35
// around. The logic that updates the backup to the failed state will also remove
36
// the lock, so this condition should really never happen.
37
if ($backup->is_locked && ($backup->is_successful && !is_null($backup->completed_at))) {
38
throw new BackupLockedException();
39
}
40
41
if ($backup->disk === Backup::ADAPTER_AWS_S3) {
42
$this->deleteFromS3($backup);
43
44
return;
45
}
46
47
$this->connection->transaction(function () use ($backup) {
48
try {
49
$this->daemonBackupRepository->setServer($backup->server)->delete($backup);
50
} catch (DaemonConnectionException $exception) {
51
$previous = $exception->getPrevious();
52
// Don't fail the request if the Daemon responds with a 404, just assume the backup
53
// doesn't actually exist and remove its reference from the Panel as well.
54
if (!$previous instanceof ClientException || $previous->getResponse()->getStatusCode() !== Response::HTTP_NOT_FOUND) {
55
throw $exception;
56
}
57
}
58
59
$backup->delete();
60
});
61
}
62
63
/**
64
* Deletes a backup from an S3 disk.
65
*
66
* @throws \Throwable
67
*/
68
protected function deleteFromS3(Backup $backup): void
69
{
70
$this->connection->transaction(function () use ($backup) {
71
$backup->delete();
72
73
/** @var \Pterodactyl\Extensions\Filesystem\S3Filesystem $adapter */
74
$adapter = $this->manager->adapter(Backup::ADAPTER_AWS_S3);
75
76
// @phpstan-ignore-next-line method.notFound
77
$adapter->getClient()->deleteObject([
78
'Bucket' => $adapter->getBucket(),
79
'Key' => sprintf('%s/%s.tar.gz', $backup->server->uuid, $backup->uuid),
80
]);
81
});
82
}
83
}
84
85