backups: support Cloudflare R2 by listing uploaded parts from Wings
This commit is contained in:
parent
0dc77aec25
commit
2dcc46ecd6
2 changed files with 21 additions and 6 deletions
|
@ -66,7 +66,7 @@ class BackupStatusController extends Controller
|
||||||
// being completed in S3 correctly.
|
// being completed in S3 correctly.
|
||||||
$adapter = $this->backupManager->adapter();
|
$adapter = $this->backupManager->adapter();
|
||||||
if ($adapter instanceof AwsS3Adapter) {
|
if ($adapter instanceof AwsS3Adapter) {
|
||||||
$this->completeMultipartUpload($model, $adapter, $successful);
|
$this->completeMultipartUpload($model, $adapter, $successful, $request->input('parts'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ class BackupStatusController extends Controller
|
||||||
*
|
*
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function restore(Request $request, string $backup)
|
public function restore(Request $request, string $backup): JsonResponse
|
||||||
{
|
{
|
||||||
/** @var \Pterodactyl\Models\Backup $model */
|
/** @var \Pterodactyl\Models\Backup $model */
|
||||||
$model = Backup::query()->where('uuid', $backup)->firstOrFail();
|
$model = Backup::query()->where('uuid', $backup)->firstOrFail();
|
||||||
|
@ -101,23 +101,24 @@ class BackupStatusController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marks a multipart upload in a given S3-compatiable instance as failed or successful for
|
* Marks a multipart upload in a given S3-compatible instance as failed or successful for
|
||||||
* the given backup.
|
* the given backup.
|
||||||
*
|
*
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||||
*/
|
*/
|
||||||
protected function completeMultipartUpload(Backup $backup, AwsS3Adapter $adapter, bool $successful)
|
protected function completeMultipartUpload(Backup $backup, AwsS3Adapter $adapter, bool $successful, ?array $parts): void
|
||||||
{
|
{
|
||||||
// This should never really happen, but if it does don't let us fall victim to Amazon's
|
// This should never really happen, but if it does don't let us fall victim to Amazon's
|
||||||
// wildly fun error messaging. Just stop the process right here.
|
// wildly fun error messaging. Just stop the process right here.
|
||||||
if (empty($backup->upload_id)) {
|
if (empty($backup->upload_id)) {
|
||||||
// A failed backup doesn't need to error here, this can happen if the backup encouters
|
// A failed backup doesn't need to error here, this can happen if the backup encounters
|
||||||
// an error before we even start the upload. AWS gives you tooling to clear these failed
|
// an error before we even start the upload. AWS gives you tooling to clear these failed
|
||||||
// multipart uploads as needed too.
|
// multipart uploads as needed too.
|
||||||
if (!$successful) {
|
if (!$successful) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new DisplayException('Cannot complete backup request: no upload_id present on model.');
|
throw new DisplayException('Cannot complete backup request: no upload_id present on model.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,9 +137,20 @@ class BackupStatusController extends Controller
|
||||||
|
|
||||||
// Otherwise send a CompleteMultipartUpload request.
|
// Otherwise send a CompleteMultipartUpload request.
|
||||||
$params['MultipartUpload'] = [
|
$params['MultipartUpload'] = [
|
||||||
'Parts' => $client->execute($client->getCommand('ListParts', $params))['Parts'],
|
'Parts' => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if (is_null($parts)) {
|
||||||
|
$params['MultipartUpload']['Parts'] = $client->execute($client->getCommand('ListParts', $params))['Parts'];
|
||||||
|
} else {
|
||||||
|
foreach ($parts as $part) {
|
||||||
|
$params['MultipartUpload']['Parts'][] = [
|
||||||
|
'ETag' => $part['etag'],
|
||||||
|
'PartNumber' => $part['part_number'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$client->execute($client->getCommand('CompleteMultipartUpload', $params));
|
$client->execute($client->getCommand('CompleteMultipartUpload', $params));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,9 @@ class ReportBackupCompleteRequest extends FormRequest
|
||||||
'checksum' => 'nullable|string|required_if:successful,true',
|
'checksum' => 'nullable|string|required_if:successful,true',
|
||||||
'checksum_type' => 'nullable|string|required_if:successful,true',
|
'checksum_type' => 'nullable|string|required_if:successful,true',
|
||||||
'size' => 'nullable|numeric|required_if:successful,true',
|
'size' => 'nullable|numeric|required_if:successful,true',
|
||||||
|
'parts' => 'nullable|array',
|
||||||
|
'parts.*.etag' => 'required|string',
|
||||||
|
'parts.*.part_number' => 'required|numeric',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue