2020-04-04 19:26:39 +00:00
< ? php
namespace Pterodactyl\Services\Backups ;
use Ramsey\Uuid\Uuid ;
use Carbon\CarbonImmutable ;
2020-04-19 06:26:59 +00:00
use Webmozart\Assert\Assert ;
2020-04-04 19:26:39 +00:00
use Pterodactyl\Models\Backup ;
use Pterodactyl\Models\Server ;
2020-04-05 03:09:33 +00:00
use Illuminate\Database\ConnectionInterface ;
2020-04-26 23:07:36 +00:00
use Pterodactyl\Extensions\Backups\BackupManager ;
2020-04-04 19:26:39 +00:00
use Pterodactyl\Repositories\Eloquent\BackupRepository ;
2020-04-05 03:09:33 +00:00
use Pterodactyl\Repositories\Wings\DaemonBackupRepository ;
2020-04-26 19:21:14 +00:00
use Pterodactyl\Exceptions\Service\Backup\TooManyBackupsException ;
2020-04-20 02:43:41 +00:00
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException ;
2020-04-04 19:26:39 +00:00
class InitiateBackupService
{
/**
2020-04-19 06:26:59 +00:00
* @ var string [] | null
2020-04-04 19:26:39 +00:00
*/
private $ignoredFiles ;
/**
* @ var \Pterodactyl\Repositories\Eloquent\BackupRepository
*/
private $repository ;
2020-04-05 03:09:33 +00:00
/**
* @ var \Illuminate\Database\ConnectionInterface
*/
private $connection ;
/**
* @ var \Pterodactyl\Repositories\Wings\DaemonBackupRepository
*/
private $daemonBackupRepository ;
2020-04-26 23:07:36 +00:00
/**
* @ var \Pterodactyl\Extensions\Backups\BackupManager
*/
private $backupManager ;
2020-11-09 23:35:57 +00:00
/**
* @ var \Pterodactyl\Services\Backups\DeleteBackupService
*/
private $deleteBackupService ;
2020-04-04 19:26:39 +00:00
/**
* InitiateBackupService constructor .
*
2020-11-09 23:35:57 +00:00
* @ param \Pterodactyl\Services\Backups\DeleteBackupService $deleteBackupService
2020-04-04 19:26:39 +00:00
*/
2020-04-05 03:09:33 +00:00
public function __construct (
BackupRepository $repository ,
ConnectionInterface $connection ,
2020-04-26 23:07:36 +00:00
DaemonBackupRepository $daemonBackupRepository ,
2020-11-09 23:35:57 +00:00
DeleteBackupService $deleteBackupService ,
2020-04-26 23:07:36 +00:00
BackupManager $backupManager
2020-04-05 03:09:33 +00:00
) {
2020-04-04 19:26:39 +00:00
$this -> repository = $repository ;
2020-04-05 03:09:33 +00:00
$this -> connection = $connection ;
$this -> daemonBackupRepository = $daemonBackupRepository ;
2020-04-26 23:07:36 +00:00
$this -> backupManager = $backupManager ;
2020-11-09 23:35:57 +00:00
$this -> deleteBackupService = $deleteBackupService ;
2020-04-04 19:26:39 +00:00
}
/**
* Sets the files to be ignored by this backup .
*
2020-04-19 06:26:59 +00:00
* @ param string [] | null $ignored
2021-01-23 20:33:34 +00:00
*
2020-04-04 19:26:39 +00:00
* @ return $this
*/
2020-04-19 06:26:59 +00:00
public function setIgnoredFiles ( ? array $ignored )
2020-04-04 19:26:39 +00:00
{
2020-04-19 06:26:59 +00:00
if ( is_array ( $ignored )) {
foreach ( $ignored as $value ) {
Assert :: string ( $value );
}
}
// Set the ignored files to be any values that are not empty in the array. Don't use
// the PHP empty function here incase anything that is "empty" by default (0, false, etc.)
// were passed as a file or folder name.
$this -> ignoredFiles = is_null ( $ignored ) ? [] : array_filter ( $ignored , function ( $value ) {
return strlen ( $value ) > 0 ;
});
2020-04-04 19:26:39 +00:00
return $this ;
}
/**
* Initiates the backup process for a server on the daemon .
*
2020-04-05 03:09:33 +00:00
* @ throws \Throwable
2020-04-26 19:21:14 +00:00
* @ throws \Pterodactyl\Exceptions\Service\Backup\TooManyBackupsException
* @ throws \Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException
2020-04-04 19:26:39 +00:00
*/
2020-11-10 00:14:47 +00:00
public function handle ( Server $server , string $name = null , bool $override = false ) : Backup
2020-04-04 19:26:39 +00:00
{
2020-12-28 00:41:53 +00:00
$limit = config ( 'backups.throttles.limit' );
$period = config ( 'backups.throttles.period' );
if ( $period > 0 ) {
$previous = $this -> repository -> getBackupsGeneratedDuringTimespan ( $server -> id , $period );
if ( $previous -> count () >= $limit ) {
2021-01-23 20:33:34 +00:00
throw new TooManyRequestsHttpException ( CarbonImmutable :: now () -> diffInSeconds ( $previous -> last () -> created_at -> addSeconds ( $period )), sprintf ( 'Only %d backups may be generated within a %d second span of time.' , $limit , $period ));
2020-12-28 00:41:53 +00:00
}
2020-12-06 20:55:45 +00:00
}
2020-04-20 02:43:41 +00:00
2020-11-10 00:14:47 +00:00
// Check if the server has reached or exceeded it's backup limit
2021-01-23 20:33:34 +00:00
if ( ! $server -> backup_limit || $server -> backups () -> where ( 'is_successful' , true ) -> count () >= $server -> backup_limit ) {
2020-11-11 13:52:28 +00:00
// Do not allow the user to continue if this server is already at its limit and can't override.
2021-01-23 20:33:34 +00:00
if ( ! $override || $server -> backup_limit <= 0 ) {
2020-11-09 23:35:57 +00:00
throw new TooManyBackupsException ( $server -> backup_limit );
}
2020-11-11 13:52:28 +00:00
2020-12-07 16:31:44 +00:00
// Get the oldest backup the server has.
/** @var \Pterodactyl\Models\Backup $oldestBackup */
$oldestBackup = $server -> backups () -> where ( 'is_successful' , true ) -> orderBy ( 'created_at' ) -> first ();
// Delete the oldest backup.
2020-11-11 19:03:57 +00:00
$this -> deleteBackupService -> handle ( $oldestBackup );
2020-11-11 13:52:28 +00:00
}
2020-11-09 23:35:57 +00:00
2020-04-05 03:09:33 +00:00
return $this -> connection -> transaction ( function () use ( $server , $name ) {
/** @var \Pterodactyl\Models\Backup $backup */
$backup = $this -> repository -> create ([
'server_id' => $server -> id ,
'uuid' => Uuid :: uuid4 () -> toString (),
'name' => trim ( $name ) ? : sprintf ( 'Backup at %s' , CarbonImmutable :: now () -> toDateTimeString ()),
2020-12-28 00:47:51 +00:00
'ignored_files' => array_values ( $this -> ignoredFiles ? ? []),
2020-04-26 23:07:36 +00:00
'disk' => $this -> backupManager -> getDefaultAdapter (),
2020-04-05 03:09:33 +00:00
], true , true );
2020-11-10 00:14:47 +00:00
$this -> daemonBackupRepository -> setServer ( $server )
-> setBackupAdapter ( $this -> backupManager -> getDefaultAdapter ())
-> backup ( $backup );
2020-04-04 19:26:39 +00:00
2020-04-05 03:09:33 +00:00
return $backup ;
});
2020-04-04 19:26:39 +00:00
}
}