backups: add S3 part size configuration (#4382)

This commit is contained in:
Pascal Zarrad 2022-09-25 22:38:49 +02:00 committed by GitHub
parent 68e9100e57
commit 1ca4b08b48
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 3 deletions

View file

@ -15,7 +15,7 @@ use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class BackupRemoteUploadController extends Controller class BackupRemoteUploadController extends Controller
{ {
public const PART_SIZE = 5 * 1024 * 1024 * 1024; public const DEFAULT_MAX_PART_SIZE = 5 * 1024 * 1024 * 1024;
/** /**
* @var \Pterodactyl\Repositories\Eloquent\BackupRepository * @var \Pterodactyl\Repositories\Eloquent\BackupRepository
@ -89,9 +89,12 @@ class BackupRemoteUploadController extends Controller
// the other presigned urls. // the other presigned urls.
$params['UploadId'] = $result->get('UploadId'); $params['UploadId'] = $result->get('UploadId');
// Retrieve configured part size
$maxPartSize = $this->getConfiguredMaxPartSize();
// Create as many UploadPart presigned urls as needed // Create as many UploadPart presigned urls as needed
$parts = []; $parts = [];
for ($i = 0; $i < ($size / self::PART_SIZE); ++$i) { for ($i = 0; $i < ($size / $maxPartSize); ++$i) {
$parts[] = $client->createPresignedRequest( $parts[] = $client->createPresignedRequest(
$client->getCommand('UploadPart', array_merge($params, ['PartNumber' => $i + 1])), $client->getCommand('UploadPart', array_merge($params, ['PartNumber' => $i + 1])),
$expires $expires
@ -103,7 +106,30 @@ class BackupRemoteUploadController extends Controller
return new JsonResponse([ return new JsonResponse([
'parts' => $parts, 'parts' => $parts,
'part_size' => self::PART_SIZE, 'part_size' => $maxPartSize,
]); ]);
} }
/**
* Get the configured maximum size of a single part in the multipart uplaod.
*
* The function tries to retrieve a configured value from the configuration.
* If no value is specified, a fallback value will be used.
*
* Note if the received config cannot be converted to int (0), is zero or is negative,
* the fallback value will be used too.
*
* The fallback value is {@see BackupRemoteUploadController::DEFAULT_MAX_PART_SIZE}.
*
* @return int
*/
private function getConfiguredMaxPartSize()
{
$maxPartSize = (int) config('backups.max_part_size', self::DEFAULT_MAX_PART_SIZE);
if ($maxPartSize <= 0) {
$maxPartSize = self::DEFAULT_MAX_PART_SIZE;
}
return $maxPartSize;
}
} }

View file

@ -12,6 +12,11 @@ return [
// uses to upload backups to S3 storage. Value is in minutes, so this would default to an hour. // uses to upload backups to S3 storage. Value is in minutes, so this would default to an hour.
'presigned_url_lifespan' => env('BACKUP_PRESIGNED_URL_LIFESPAN', 60), 'presigned_url_lifespan' => env('BACKUP_PRESIGNED_URL_LIFESPAN', 60),
// This value defines the maximal size of a single part for the S3 multipart upload during backups
// The maximal part size must be given in bytes. The default value is 5GB.
// Note that 5GB is the maximum for a single part when using AWS S3.
'max_part_size' => env('BACKUP_MAX_PART_SIZE', 5 * 1024 * 1024 * 1024),
// The time to wait before automatically failing a backup, time is in minutes and defaults // The time to wait before automatically failing a backup, time is in minutes and defaults
// to 6 hours. To disable this feature, set the value to `0`. // to 6 hours. To disable this feature, set the value to `0`.
'prune_age' => env('BACKUP_PRUNE_AGE', 360), 'prune_age' => env('BACKUP_PRUNE_AGE', 360),