Skip to content

Commit d27f0c6

Browse files
committed
Basic backend support to at least store a backup model in the DB
1 parent 6d426e4 commit d27f0c6

File tree

10 files changed

+138
-18
lines changed

10 files changed

+138
-18
lines changed

app/Http/Controllers/Api/Client/Servers/BackupController.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,29 @@
33
namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
44

55
use Pterodactyl\Models\Server;
6+
use Pterodactyl\Services\Backups\InitiateBackupService;
67
use Pterodactyl\Transformers\Api\Client\BackupTransformer;
78
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
89
use Pterodactyl\Http\Requests\Api\Client\Servers\Backups\GetBackupsRequest;
910
use Pterodactyl\Http\Requests\Api\Client\Servers\Backups\StoreBackupRequest;
1011

1112
class BackupController extends ClientApiController
1213
{
13-
public function __construct()
14+
/**
15+
* @var \Pterodactyl\Services\Backups\InitiateBackupService
16+
*/
17+
private $initiateBackupService;
18+
19+
/**
20+
* BackupController constructor.
21+
*
22+
* @param \Pterodactyl\Services\Backups\InitiateBackupService $initiateBackupService
23+
*/
24+
public function __construct(InitiateBackupService $initiateBackupService)
1425
{
1526
parent::__construct();
27+
28+
$this->initiateBackupService = $initiateBackupService;
1629
}
1730

1831
/**
@@ -35,9 +48,19 @@ public function index(GetBackupsRequest $request, Server $server)
3548
*
3649
* @param \Pterodactyl\Http\Requests\Api\Client\Servers\Backups\StoreBackupRequest $request
3750
* @param \Pterodactyl\Models\Server $server
51+
* @return array
52+
*
53+
* @throws \Exception
3854
*/
3955
public function store(StoreBackupRequest $request, Server $server)
4056
{
57+
$backup = $this->initiateBackupService
58+
->setIgnoredFiles($request->input('ignored'))
59+
->handle($server, $request->input('name'));
60+
61+
return $this->fractal->item($backup)
62+
->transformWith($this->getTransformer(BackupTransformer::class))
63+
->toArray();
4164
}
4265

4366
public function view()

app/Http/Requests/Api/Client/Servers/Backups/StoreBackupRequest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public function permission()
2121
public function rules(): array
2222
{
2323
return [
24-
'name' => 'nullable|string|max:255',
24+
'name' => 'nullable|string|max:255|regex:/^[w\][\w\s_.-]*[\w]$/',
2525
'ignore' => 'nullable|string',
2626
];
2727
}

app/Models/Backup.php

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* @property int $server_id
1010
* @property int $uuid
1111
* @property string $name
12-
* @property string $ignore
12+
* @property string $ignored_files
1313
* @property string $disk
1414
* @property string|null $sha256_hash
1515
* @property int $bytes
@@ -52,15 +52,25 @@ class Backup extends Model
5252
];
5353

5454
/**
55-
* Returns dates from this model as immutable Carbon instances.
56-
*
57-
* @param mixed $value
58-
* @return \Carbon\CarbonImmutable
55+
* @var array
5956
*/
60-
protected function asDateTime($value)
61-
{
62-
return $this->asImmutableDateTime($value);
63-
}
57+
protected $attributes = [
58+
'sha256_hash' => null,
59+
'bytes' => 0,
60+
];
61+
62+
/**
63+
* @var array
64+
*/
65+
public static $validationRules = [
66+
'server_id' => 'bail|required|numeric|exists:servers,id',
67+
'uuid' => 'required|uuid',
68+
'name' => 'required|string|regex:/^[w\][\w\s_.-]*[\w]$/',
69+
'ignored_files' => 'string',
70+
'disk' => 'required|string',
71+
'sha256_hash' => 'nullable|string',
72+
'bytes' => 'numeric',
73+
];
6474

6575
/**
6676
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Pterodactyl\Repositories\Eloquent;
4+
5+
use Pterodactyl\Models\Backup;
6+
7+
class BackupRepository extends EloquentRepository
8+
{
9+
/**
10+
* @return string
11+
*/
12+
public function model()
13+
{
14+
return Backup::class;
15+
}
16+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
namespace Pterodactyl\Services\Backups;
4+
5+
use Ramsey\Uuid\Uuid;
6+
use Carbon\CarbonImmutable;
7+
use Illuminate\Support\Str;
8+
use Pterodactyl\Models\Backup;
9+
use Pterodactyl\Models\Server;
10+
use Pterodactyl\Repositories\Eloquent\BackupRepository;
11+
12+
class InitiateBackupService
13+
{
14+
/**
15+
* @var string|null
16+
*/
17+
private $ignoredFiles;
18+
19+
/**
20+
* @var \Pterodactyl\Repositories\Eloquent\BackupRepository
21+
*/
22+
private $repository;
23+
24+
/**
25+
* InitiateBackupService constructor.
26+
*
27+
* @param \Pterodactyl\Repositories\Eloquent\BackupRepository $repository
28+
*/
29+
public function __construct(BackupRepository $repository)
30+
{
31+
$this->repository = $repository;
32+
}
33+
34+
/**
35+
* Sets the files to be ignored by this backup.
36+
*
37+
* @param string|null $ignored
38+
* @return $this
39+
*/
40+
public function setIgnoredFiles(?string $ignored)
41+
{
42+
$this->ignoredFiles = $ignored;
43+
44+
return $this;
45+
}
46+
47+
/**
48+
* Initiates the backup process for a server on the daemon.
49+
*
50+
* @param \Pterodactyl\Models\Server $server
51+
* @param string|null $name
52+
* @return \Pterodactyl\Models\Backup
53+
*
54+
* @throws \Exception
55+
*/
56+
public function handle(Server $server, string $name = null): Backup
57+
{
58+
/** @var \Pterodactyl\Models\Backup $backup */
59+
$backup = $this->repository->create([
60+
'server_id' => $server->id,
61+
'uuid' => Uuid::uuid4()->toString(),
62+
'name' => Str::lower(str_replace(' ', '_', trim($name))) ?: sprintf('backup_%s', CarbonImmutable::create()->format('YmdHis')),
63+
'ignored_files' => $this->ignoredFiles ?? '',
64+
'disk' => 'local',
65+
], true, true);
66+
67+
return $backup;
68+
}
69+
}

app/Transformers/Api/Client/BackupTransformer.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ public function transform(Backup $backup)
2323
return [
2424
'uuid' => $backup->uuid,
2525
'name' => $backup->name,
26-
'ignore' => $backup->ignore,
26+
'ignored_files' => $backup->ignored_files,
2727
'sha256_hash' => $backup->sha256_hash,
2828
'bytes' => $backup->bytes,
2929
'created_at' => $backup->created_at->toIso8601String(),
30-
'completed_at' => $backup->completed_at->toIso8601String(),
30+
'completed_at' => $backup->completed_at ? $backup->completed_at->toIso8601String() : null,
3131
];
3232
}
3333
}

database/migrations/2020_04_03_230614_create_backups_table.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public function up()
1818
$table->unsignedInteger('server_id');
1919
$table->char('uuid', 36);
2020
$table->string('name');
21-
$table->text('ignored');
21+
$table->text('ignored_files');
2222
$table->string('disk');
2323
$table->string('sha256_hash')->nullable();
2424
$table->integer('bytes')->default(0);

resources/scripts/api/server/backups/createServerBackup.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export default (uuid: string, name?: string, ignore?: string): Promise<ServerBac
66
http.post(`/api/client/servers/${uuid}/backups`, {
77
name, ignore,
88
})
9-
.then(({ data }) => resolve(rawDataToServerBackup(data.attributes)))
9+
.then(({ data }) => resolve(rawDataToServerBackup(data)))
1010
.catch(reject);
1111
});
1212
};

resources/scripts/api/server/backups/getServerBackups.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import http, { FractalResponseData, getPaginationSet, PaginatedResult } from '@/
33
export interface ServerBackup {
44
uuid: string;
55
name: string;
6-
contents: string;
6+
ignoredFiles: string;
77
sha256Hash: string;
88
bytes: number;
99
createdAt: Date;
@@ -13,7 +13,7 @@ export interface ServerBackup {
1313
export const rawDataToServerBackup = ({ attributes }: FractalResponseData): ServerBackup => ({
1414
uuid: attributes.uuid,
1515
name: attributes.name,
16-
contents: attributes.contents,
16+
ignoredFiles: attributes.ignored_files,
1717
sha256Hash: attributes.sha256_hash,
1818
bytes: attributes.bytes,
1919
createdAt: new Date(attributes.created_at),

resources/scripts/components/server/backups/CreateBackupButton.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ export default ({ onBackupGenerated }: Props) => {
9696
onSubmit={submit}
9797
initialValues={{ name: '', ignored: '' }}
9898
validationSchema={object().shape({
99-
name: string().max(255),
99+
name: string().required()
100+
.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.')
101+
.max(255),
100102
ignored: string(),
101103
})}
102104
>

0 commit comments

Comments
 (0)