Skip to content

Commit ec7231b

Browse files
authored
Lock resources more explicitly when creating databases or backups (#5613)
Addresses an issue where the concept of a lock was there, but no actual lock was acquired.
1 parent 56fe10f commit ec7231b

4 files changed

Lines changed: 10 additions & 10 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public function store(StoreBackupRequest $request, Server $server): array
7878
}
7979

8080
$backup = Activity::event('server:backup.start')->transaction(function ($log) use ($action, $server, $request) {
81-
$server->backups()->lockForUpdate();
81+
$server->backups()->lockForUpdate()->count();
8282

8383
$backup = $action->handle($server, $request->input('name'));
8484

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

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Pterodactyl\Models\Server;
77
use Pterodactyl\Models\Database;
88
use Pterodactyl\Facades\Activity;
9+
use Pterodactyl\Exceptions\DisplayException;
910
use Pterodactyl\Services\Databases\DatabasePasswordService;
1011
use Pterodactyl\Transformers\Api\Client\DatabaseTransformer;
1112
use Pterodactyl\Services\Databases\DatabaseManagementService;
@@ -49,7 +50,9 @@ public function index(GetDatabasesRequest $request, Server $server): array
4950
public function store(StoreDatabaseRequest $request, Server $server): array
5051
{
5152
$database = Activity::event('server:database.create')->transaction(function ($log) use ($request, $server) {
52-
$server->databases()->lockForUpdate();
53+
if ($server->databases()->lockForUpdate()->count() >= $server->database_limit) {
54+
throw new DisplayException('Cannot create additional databases on this server: limit has been reached.');
55+
}
5356

5457
$database = $this->deployDatabaseService->handle($server, $request->validated());
5558

@@ -75,11 +78,7 @@ public function rotatePassword(RotatePasswordRequest $request, Server $server, D
7578
Activity::event('server:database.rotate-password')
7679
->subject($database)
7780
->property('name', $database->database)
78-
->transaction(function () use ($database) {
79-
$database->lockForUpdate();
80-
81-
$this->passwordService->handle($database);
82-
});
81+
->transaction(fn () => $this->passwordService->handle($database));
8382

8483
return $this->fractal->item($database->refresh())
8584
->parseIncludes(['password'])

app/Services/Allocations/FindAssignableAllocationService.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public function handle(Server $server): Allocation
3939
// server.
4040
/** @var Allocation|null $allocation */
4141
$allocation = $server->node->allocations()
42+
->lockForUpdate()
4243
->where('ip', $server->allocation->ip)
4344
->whereNull('server_id')
4445
->inRandomOrder()
@@ -102,6 +103,7 @@ protected function createNewAllocation(Server $server): Allocation
102103

103104
/** @var Allocation $allocation */
104105
$allocation = $server->node->allocations()
106+
->lockForUpdate()
105107
->where('ip', $server->allocation->ip)
106108
->where('port', $port)
107109
->firstOrFail();

app/Services/Databases/DatabasePasswordService.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,11 @@ public function handle(Database|int $database): string
3232
$password = Utilities::randomStringWithSpecialCharacters(24);
3333

3434
$this->connection->transaction(function () use ($database, $password) {
35-
$this->dynamic->set('dynamic', $database->database_host_id);
36-
37-
$this->repository->withoutFreshModel()->update($database->id, [
35+
$database->sharedLock()->update([
3836
'password' => $this->encrypter->encrypt($password),
3937
]);
4038

39+
$this->dynamic->set('dynamic', $database->database_host_id);
4140
$this->repository->dropUser($database->username, $database->remote);
4241
$this->repository->createUser($database->username, $database->remote, $password, $database->max_connections);
4342
$this->repository->assignUserToDatabase($database->database, $database->username, $database->remote);

0 commit comments

Comments
 (0)