Skip to content

Commit 6af848c

Browse files
committed
Tweaks to BackupRemoteUploadController.php
1 parent 63ac815 commit 6af848c

File tree

1 file changed

+48
-32
lines changed

1 file changed

+48
-32
lines changed

app/Http/Controllers/Api/Remote/Backups/BackupRemoteUploadController.php

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44

55
use Carbon\CarbonImmutable;
66
use Illuminate\Http\Request;
7+
use Pterodactyl\Models\Backup;
78
use Illuminate\Http\JsonResponse;
89
use League\Flysystem\AwsS3v3\AwsS3Adapter;
910
use Pterodactyl\Http\Controllers\Controller;
1011
use Pterodactyl\Extensions\Backups\BackupManager;
1112
use Pterodactyl\Repositories\Eloquent\BackupRepository;
13+
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
1214

1315
class BackupRemoteUploadController extends Controller
1416
{
@@ -37,25 +39,26 @@ public function __construct(BackupRepository $repository, BackupManager $backupM
3739
}
3840

3941
/**
40-
* ?
42+
* Returns the required presigned urls to upload a backup to S3 cloud storage.
4143
*
4244
* @param \Illuminate\Http\Request $request
4345
* @param string $backup
4446
*
4547
* @return \Illuminate\Http\JsonResponse
4648
*
47-
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
4849
* @throws \Exception
50+
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
4951
*/
5052
public function __invoke(Request $request, string $backup)
5153
{
54+
// Get the size query parameter.
5255
$size = $request->query('size', null);
53-
if ($size === null) {
54-
return new JsonResponse([], JsonResponse::HTTP_BAD_REQUEST);
56+
if (is_null($size)) {
57+
throw new BadRequestHttpException('Missing size query parameter.');
5558
}
5659

5760
/** @var \Pterodactyl\Models\Backup $model */
58-
$model = $this->repository->findFirstWhere([[ 'uuid', '=', $backup ]]);
61+
$model = Backup::query()->where([[ 'uuid', '=', $backup ]])->firstOrFail();
5962

6063
// Prevent backups that have already been completed from trying to
6164
// be uploaded again.
@@ -66,63 +69,76 @@ public function __invoke(Request $request, string $backup)
6669
// Ensure we are using the S3 adapter.
6770
$adapter = $this->backupManager->adapter();
6871
if (! $adapter instanceof AwsS3Adapter) {
69-
return new JsonResponse([], JsonResponse::HTTP);
72+
throw new BadRequestHttpException('Backups are not using the s3 storage driver');
7073
}
7174

75+
// The path where backup will be uploaded to
7276
$path = sprintf('%s/%s.tar.gz', $model->server->uuid, $model->uuid);
7377

78+
// Get the S3 client
7479
$client = $adapter->getClient();
7580

76-
$result = $client->execute($client->getCommand('CreateMultipartUpload', [
81+
// Params for generating the presigned urls
82+
$params = [
7783
'Bucket' => $adapter->getBucket(),
7884
'Key' => $path,
7985
'ContentType' => 'application/x-gzip',
80-
]));
86+
];
87+
88+
// Execute the CreateMultipartUpload request
89+
$result = $client->execute($client->getCommand('CreateMultipartUpload', $params));
90+
91+
// Get the UploadId from the CreateMultipartUpload request,
92+
// this is needed to create the other presigned urls
8193
$uploadId = $result->get('UploadId');
8294

95+
// Create a CompleteMultipartUpload presigned url
8396
$completeMultipartUpload = $client->createPresignedRequest(
84-
$client->getCommand('CompleteMultipartUpload', [
85-
'Bucket' => $adapter->getBucket(),
86-
'Key' => $path,
87-
'ContentType' => 'application/x-gzip',
88-
'UploadId' => $uploadId,
89-
]),
97+
$client->getCommand(
98+
'CompleteMultipartUpload',
99+
array_merge($params, [
100+
'UploadId' => $uploadId,
101+
])
102+
),
90103
CarbonImmutable::now()->addMinutes(30)
91104
);
92105

106+
// Create a AbortMultipartUpload presigned url
93107
$abortMultipartUpload = $client->createPresignedRequest(
94-
$client->getCommand('AbortMultipartUpload', [
95-
'Bucket' => $adapter->getBucket(),
96-
'Key' => $path,
97-
'ContentType' => 'application/x-gzip',
98-
'UploadId' => $uploadId,
99-
]),
108+
$client->getCommand(
109+
'AbortMultipartUpload',
110+
array_merge($params, [
111+
'UploadId' => $uploadId,
112+
])
113+
),
100114
CarbonImmutable::now()->addMinutes(45)
101115
);
102116

117+
// Calculate the number of parts needed to upload the backup
103118
$partCount = (int) $size / (self::PART_SIZE);
104119

120+
// Create as many UploadPart presigned urls as needed
105121
$parts = [];
106122
for ($i = 0; $i < $partCount; $i++) {
107123
$part = $client->createPresignedRequest(
108-
$client->getCommand('UploadPart', [
109-
'Bucket' => $adapter->getBucket(),
110-
'Key' => $path,
111-
'ContentType' => 'application/x-gzip',
112-
'UploadId' => $uploadId,
113-
'PartNumber' => $i + 1,
114-
]),
124+
$client->getCommand(
125+
'UploadPart',
126+
array_merge($params, [
127+
'UploadId' => $uploadId,
128+
'PartNumber' => $i + 1,
129+
])
130+
),
115131
CarbonImmutable::now()->addMinutes(30)
116132
);
117133

118134
array_push($parts, $part->getUri()->__toString());
119135
}
120136

121137
return new JsonResponse([
122-
'CompleteMultipartUpload' => $completeMultipartUpload->getUri()->__toString(),
123-
'AbortMultipartUpload' => $abortMultipartUpload->getUri()->__toString(),
124-
'Parts' => $parts,
125-
'PartSize' => self::PART_SIZE,
126-
], JsonResponse::HTTP_OK);
138+
'complete_multipart_upload' => $completeMultipartUpload->getUri()->__toString(),
139+
'abort_multipart_upload' => $abortMultipartUpload->getUri()->__toString(),
140+
'parts' => $parts,
141+
'part_size' => self::PART_SIZE,
142+
]);
127143
}
128144
}

0 commit comments

Comments
 (0)