33namespace Pterodactyl \Http \Controllers \Api \Remote \Backups ;
44
55use Carbon \CarbonImmutable ;
6+ use Pterodactyl \Models \Backup ;
67use Illuminate \Http \JsonResponse ;
8+ use League \Flysystem \AwsS3v3 \AwsS3Adapter ;
79use Pterodactyl \Http \Controllers \Controller ;
10+ use Pterodactyl \Extensions \Backups \BackupManager ;
811use Pterodactyl \Repositories \Eloquent \BackupRepository ;
912use Symfony \Component \HttpKernel \Exception \BadRequestHttpException ;
1013use Pterodactyl \Http \Requests \Api \Remote \ReportBackupCompleteRequest ;
@@ -16,24 +19,33 @@ class BackupStatusController extends Controller
1619 */
1720 private $ repository ;
1821
22+ /**
23+ * @var \Pterodactyl\Extensions\Backups\BackupManager
24+ */
25+ private $ backupManager ;
26+
1927 /**
2028 * BackupStatusController constructor.
2129 *
2230 * @param \Pterodactyl\Repositories\Eloquent\BackupRepository $repository
31+ * @param \Pterodactyl\Extensions\Backups\BackupManager $backupManager
2332 */
24- public function __construct (BackupRepository $ repository )
33+ public function __construct (BackupRepository $ repository, BackupManager $ backupManager )
2534 {
2635 $ this ->repository = $ repository ;
36+ $ this ->backupManager = $ backupManager ;
2737 }
2838
2939 /**
3040 * Handles updating the state of a backup.
3141 *
3242 * @param \Pterodactyl\Http\Requests\Api\Remote\ReportBackupCompleteRequest $request
3343 * @param string $backup
44+ *
3445 * @return \Illuminate\Http\JsonResponse
3546 *
3647 * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
48+ * @throws \Exception
3749 */
3850 public function __invoke (ReportBackupCompleteRequest $ request , string $ backup )
3951 {
@@ -47,13 +59,42 @@ public function __invoke(ReportBackupCompleteRequest $request, string $backup)
4759 }
4860
4961 $ successful = $ request ->input ('successful ' ) ? true : false ;
62+
63+ // TODO: Still run s3 code even if this fails.
5064 $ model ->forceFill ([
5165 'is_successful ' => $ successful ,
5266 'checksum ' => $ successful ? ($ request ->input ('checksum_type ' ) . ': ' . $ request ->input ('checksum ' )) : null ,
5367 'bytes ' => $ successful ? $ request ->input ('size ' ) : 0 ,
5468 'completed_at ' => CarbonImmutable::now (),
5569 ])->save ();
5670
71+ // Check if we are using the s3 backup adapter.
72+ $ adapter = $ this ->backupManager ->adapter ();
73+ if ($ adapter instanceof AwsS3Adapter) {
74+ /** @var \Pterodactyl\Models\Backup $backup */
75+ $ backup = Backup::query ()->where ('uuid ' , $ backup )->firstOrFail ();
76+
77+ $ client = $ adapter ->getClient ();
78+
79+ $ params = [
80+ 'Bucket ' => $ adapter ->getBucket (),
81+ 'Key ' => sprintf ('%s/%s.tar.gz ' , $ backup ->server ->uuid , $ backup ->uuid ),
82+ 'UploadId ' => $ request ->input ('upload_id ' ),
83+ ];
84+
85+ // If the backup was not successful, send an AbortMultipartUpload request.
86+ if (! $ successful ) {
87+ $ client ->execute ($ client ->getCommand ('AbortMultipartUpload ' , $ params ));
88+ return new JsonResponse ([], JsonResponse::HTTP_NO_CONTENT );
89+ }
90+
91+ // Otherwise send a CompleteMultipartUpload request.
92+ $ params ['MultipartUpload ' ] = [
93+ 'Parts ' => $ client ->execute ($ client ->getCommand ('ListParts ' , $ params ))['Parts ' ],
94+ ];
95+ $ client ->execute ($ client ->getCommand ('CompleteMultipartUpload ' , $ params ));
96+ }
97+
5798 return new JsonResponse ([], JsonResponse::HTTP_NO_CONTENT );
5899 }
59100}
0 commit comments