Basic backend support to at least store a backup model in the DB
This commit is contained in:
parent
6d426e45d9
commit
d27f0c6f2a
10 changed files with 138 additions and 18 deletions
|
@ -3,6 +3,7 @@
|
||||||
namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
|
namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
|
||||||
|
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
|
use Pterodactyl\Services\Backups\InitiateBackupService;
|
||||||
use Pterodactyl\Transformers\Api\Client\BackupTransformer;
|
use Pterodactyl\Transformers\Api\Client\BackupTransformer;
|
||||||
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
|
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
|
||||||
use Pterodactyl\Http\Requests\Api\Client\Servers\Backups\GetBackupsRequest;
|
use Pterodactyl\Http\Requests\Api\Client\Servers\Backups\GetBackupsRequest;
|
||||||
|
@ -10,9 +11,21 @@ use Pterodactyl\Http\Requests\Api\Client\Servers\Backups\StoreBackupRequest;
|
||||||
|
|
||||||
class BackupController extends ClientApiController
|
class BackupController extends ClientApiController
|
||||||
{
|
{
|
||||||
public function __construct()
|
/**
|
||||||
|
* @var \Pterodactyl\Services\Backups\InitiateBackupService
|
||||||
|
*/
|
||||||
|
private $initiateBackupService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BackupController constructor.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Services\Backups\InitiateBackupService $initiateBackupService
|
||||||
|
*/
|
||||||
|
public function __construct(InitiateBackupService $initiateBackupService)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->initiateBackupService = $initiateBackupService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,9 +48,19 @@ class BackupController extends ClientApiController
|
||||||
*
|
*
|
||||||
* @param \Pterodactyl\Http\Requests\Api\Client\Servers\Backups\StoreBackupRequest $request
|
* @param \Pterodactyl\Http\Requests\Api\Client\Servers\Backups\StoreBackupRequest $request
|
||||||
* @param \Pterodactyl\Models\Server $server
|
* @param \Pterodactyl\Models\Server $server
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function store(StoreBackupRequest $request, Server $server)
|
public function store(StoreBackupRequest $request, Server $server)
|
||||||
{
|
{
|
||||||
|
$backup = $this->initiateBackupService
|
||||||
|
->setIgnoredFiles($request->input('ignored'))
|
||||||
|
->handle($server, $request->input('name'));
|
||||||
|
|
||||||
|
return $this->fractal->item($backup)
|
||||||
|
->transformWith($this->getTransformer(BackupTransformer::class))
|
||||||
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function view()
|
public function view()
|
||||||
|
|
|
@ -21,7 +21,7 @@ class StoreBackupRequest extends ClientApiRequest
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'name' => 'nullable|string|max:255',
|
'name' => 'nullable|string|max:255|regex:/^[w\][\w\s_.-]*[\w]$/',
|
||||||
'ignore' => 'nullable|string',
|
'ignore' => 'nullable|string',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
* @property int $server_id
|
* @property int $server_id
|
||||||
* @property int $uuid
|
* @property int $uuid
|
||||||
* @property string $name
|
* @property string $name
|
||||||
* @property string $ignore
|
* @property string $ignored_files
|
||||||
* @property string $disk
|
* @property string $disk
|
||||||
* @property string|null $sha256_hash
|
* @property string|null $sha256_hash
|
||||||
* @property int $bytes
|
* @property int $bytes
|
||||||
|
@ -52,15 +52,25 @@ class Backup extends Model
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns dates from this model as immutable Carbon instances.
|
* @var array
|
||||||
*
|
|
||||||
* @param mixed $value
|
|
||||||
* @return \Carbon\CarbonImmutable
|
|
||||||
*/
|
*/
|
||||||
protected function asDateTime($value)
|
protected $attributes = [
|
||||||
{
|
'sha256_hash' => null,
|
||||||
return $this->asImmutableDateTime($value);
|
'bytes' => 0,
|
||||||
}
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public static $validationRules = [
|
||||||
|
'server_id' => 'bail|required|numeric|exists:servers,id',
|
||||||
|
'uuid' => 'required|uuid',
|
||||||
|
'name' => 'required|string|regex:/^[w\][\w\s_.-]*[\w]$/',
|
||||||
|
'ignored_files' => 'string',
|
||||||
|
'disk' => 'required|string',
|
||||||
|
'sha256_hash' => 'nullable|string',
|
||||||
|
'bytes' => 'numeric',
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
|
|
16
app/Repositories/Eloquent/BackupRepository.php
Normal file
16
app/Repositories/Eloquent/BackupRepository.php
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Repositories\Eloquent;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\Backup;
|
||||||
|
|
||||||
|
class BackupRepository extends EloquentRepository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function model()
|
||||||
|
{
|
||||||
|
return Backup::class;
|
||||||
|
}
|
||||||
|
}
|
69
app/Services/Backups/InitiateBackupService.php
Normal file
69
app/Services/Backups/InitiateBackupService.php
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Services\Backups;
|
||||||
|
|
||||||
|
use Ramsey\Uuid\Uuid;
|
||||||
|
use Carbon\CarbonImmutable;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use Pterodactyl\Models\Backup;
|
||||||
|
use Pterodactyl\Models\Server;
|
||||||
|
use Pterodactyl\Repositories\Eloquent\BackupRepository;
|
||||||
|
|
||||||
|
class InitiateBackupService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string|null
|
||||||
|
*/
|
||||||
|
private $ignoredFiles;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Repositories\Eloquent\BackupRepository
|
||||||
|
*/
|
||||||
|
private $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* InitiateBackupService constructor.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Repositories\Eloquent\BackupRepository $repository
|
||||||
|
*/
|
||||||
|
public function __construct(BackupRepository $repository)
|
||||||
|
{
|
||||||
|
$this->repository = $repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the files to be ignored by this backup.
|
||||||
|
*
|
||||||
|
* @param string|null $ignored
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setIgnoredFiles(?string $ignored)
|
||||||
|
{
|
||||||
|
$this->ignoredFiles = $ignored;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initiates the backup process for a server on the daemon.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Models\Server $server
|
||||||
|
* @param string|null $name
|
||||||
|
* @return \Pterodactyl\Models\Backup
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function handle(Server $server, string $name = null): Backup
|
||||||
|
{
|
||||||
|
/** @var \Pterodactyl\Models\Backup $backup */
|
||||||
|
$backup = $this->repository->create([
|
||||||
|
'server_id' => $server->id,
|
||||||
|
'uuid' => Uuid::uuid4()->toString(),
|
||||||
|
'name' => Str::lower(str_replace(' ', '_', trim($name))) ?: sprintf('backup_%s', CarbonImmutable::create()->format('YmdHis')),
|
||||||
|
'ignored_files' => $this->ignoredFiles ?? '',
|
||||||
|
'disk' => 'local',
|
||||||
|
], true, true);
|
||||||
|
|
||||||
|
return $backup;
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,11 +23,11 @@ class BackupTransformer extends BaseClientTransformer
|
||||||
return [
|
return [
|
||||||
'uuid' => $backup->uuid,
|
'uuid' => $backup->uuid,
|
||||||
'name' => $backup->name,
|
'name' => $backup->name,
|
||||||
'ignore' => $backup->ignore,
|
'ignored_files' => $backup->ignored_files,
|
||||||
'sha256_hash' => $backup->sha256_hash,
|
'sha256_hash' => $backup->sha256_hash,
|
||||||
'bytes' => $backup->bytes,
|
'bytes' => $backup->bytes,
|
||||||
'created_at' => $backup->created_at->toIso8601String(),
|
'created_at' => $backup->created_at->toIso8601String(),
|
||||||
'completed_at' => $backup->completed_at->toIso8601String(),
|
'completed_at' => $backup->completed_at ? $backup->completed_at->toIso8601String() : null,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ class CreateBackupsTable extends Migration
|
||||||
$table->unsignedInteger('server_id');
|
$table->unsignedInteger('server_id');
|
||||||
$table->char('uuid', 36);
|
$table->char('uuid', 36);
|
||||||
$table->string('name');
|
$table->string('name');
|
||||||
$table->text('ignored');
|
$table->text('ignored_files');
|
||||||
$table->string('disk');
|
$table->string('disk');
|
||||||
$table->string('sha256_hash')->nullable();
|
$table->string('sha256_hash')->nullable();
|
||||||
$table->integer('bytes')->default(0);
|
$table->integer('bytes')->default(0);
|
||||||
|
|
|
@ -6,7 +6,7 @@ export default (uuid: string, name?: string, ignore?: string): Promise<ServerBac
|
||||||
http.post(`/api/client/servers/${uuid}/backups`, {
|
http.post(`/api/client/servers/${uuid}/backups`, {
|
||||||
name, ignore,
|
name, ignore,
|
||||||
})
|
})
|
||||||
.then(({ data }) => resolve(rawDataToServerBackup(data.attributes)))
|
.then(({ data }) => resolve(rawDataToServerBackup(data)))
|
||||||
.catch(reject);
|
.catch(reject);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,7 +3,7 @@ import http, { FractalResponseData, getPaginationSet, PaginatedResult } from '@/
|
||||||
export interface ServerBackup {
|
export interface ServerBackup {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
name: string;
|
name: string;
|
||||||
contents: string;
|
ignoredFiles: string;
|
||||||
sha256Hash: string;
|
sha256Hash: string;
|
||||||
bytes: number;
|
bytes: number;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
@ -13,7 +13,7 @@ export interface ServerBackup {
|
||||||
export const rawDataToServerBackup = ({ attributes }: FractalResponseData): ServerBackup => ({
|
export const rawDataToServerBackup = ({ attributes }: FractalResponseData): ServerBackup => ({
|
||||||
uuid: attributes.uuid,
|
uuid: attributes.uuid,
|
||||||
name: attributes.name,
|
name: attributes.name,
|
||||||
contents: attributes.contents,
|
ignoredFiles: attributes.ignored_files,
|
||||||
sha256Hash: attributes.sha256_hash,
|
sha256Hash: attributes.sha256_hash,
|
||||||
bytes: attributes.bytes,
|
bytes: attributes.bytes,
|
||||||
createdAt: new Date(attributes.created_at),
|
createdAt: new Date(attributes.created_at),
|
||||||
|
|
|
@ -96,7 +96,9 @@ export default ({ onBackupGenerated }: Props) => {
|
||||||
onSubmit={submit}
|
onSubmit={submit}
|
||||||
initialValues={{ name: '', ignored: '' }}
|
initialValues={{ name: '', ignored: '' }}
|
||||||
validationSchema={object().shape({
|
validationSchema={object().shape({
|
||||||
name: string().max(255),
|
name: string().required()
|
||||||
|
.matches(/^[w\][\w\s_.-]*[\w]$/, 'Backup name must only contain alpha-numeric characters, spaces, underscores, dashes, and periods. The name must start and end with an alpha-numeric character.')
|
||||||
|
.max(255),
|
||||||
ignored: string(),
|
ignored: string(),
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
|
|
Loading…
Reference in a new issue