Skip to content

Commit 1327bbb

Browse files
committed
Fix logic to update a daemon's configuration
1 parent 60f6e86 commit 1327bbb

File tree

2 files changed

+34
-51
lines changed

2 files changed

+34
-51
lines changed

app/Repositories/Wings/DaemonConfigurationRepository.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Pterodactyl\Repositories\Wings;
44

5+
use Pterodactyl\Models\Node;
56
use GuzzleHttp\Exception\TransferException;
67
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
78

@@ -25,17 +26,19 @@ public function getSystemInformation(): array
2526
}
2627

2728
/**
28-
* Updates the configuration information for a daemon.
29+
* Updates the configuration information for a daemon. Updates the information for
30+
* this instance using a passed-in model. This allows us to change plenty of information
31+
* in the model, and still use the old, pre-update model to actually make the HTTP request.
2932
*
30-
* @param array $attributes
33+
* @param \Pterodactyl\Models\Node $node
3134
* @return \Psr\Http\Message\ResponseInterface
3235
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
3336
*/
34-
public function update(array $attributes = [])
37+
public function update(?Node $node)
3538
{
3639
try {
3740
return $this->getHttpClient()->post(
38-
'/api/update', array_merge($this->node->getConfiguration(), $attributes)
41+
'/api/update', ['json' => $node->getConfiguration()]
3942
);
4043
} catch (TransferException $exception) {
4144
throw new DaemonConnectionException($exception);

app/Services/Nodes/NodeUpdateService.php

Lines changed: 27 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55
use Illuminate\Support\Str;
66
use Pterodactyl\Models\Node;
77
use GuzzleHttp\Exception\ConnectException;
8-
use GuzzleHttp\Exception\RequestException;
98
use Illuminate\Database\ConnectionInterface;
109
use Illuminate\Contracts\Encryption\Encrypter;
10+
use Pterodactyl\Repositories\Eloquent\NodeRepository;
1111
use Pterodactyl\Repositories\Daemon\ConfigurationRepository;
12-
use Pterodactyl\Contracts\Repository\NodeRepositoryInterface;
1312
use Pterodactyl\Repositories\Wings\DaemonConfigurationRepository;
1413
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
1514
use Pterodactyl\Exceptions\Service\Node\ConfigurationNotPersistedException;
@@ -21,11 +20,6 @@ class NodeUpdateService
2120
*/
2221
private $connection;
2322

24-
/**
25-
* @var \Pterodactyl\Contracts\Repository\NodeRepositoryInterface
26-
*/
27-
private $repository;
28-
2923
/**
3024
* @var \Pterodactyl\Repositories\Wings\DaemonConfigurationRepository
3125
*/
@@ -36,24 +30,29 @@ class NodeUpdateService
3630
*/
3731
private $encrypter;
3832

33+
/**
34+
* @var \Pterodactyl\Repositories\Eloquent\NodeRepository
35+
*/
36+
private $repository;
37+
3938
/**
4039
* UpdateService constructor.
4140
*
4241
* @param \Illuminate\Database\ConnectionInterface $connection
4342
* @param \Illuminate\Contracts\Encryption\Encrypter $encrypter
4443
* @param \Pterodactyl\Repositories\Wings\DaemonConfigurationRepository $configurationRepository
45-
* @param \Pterodactyl\Contracts\Repository\NodeRepositoryInterface $repository
44+
* @param \Pterodactyl\Repositories\Eloquent\NodeRepository $repository
4645
*/
4746
public function __construct(
4847
ConnectionInterface $connection,
4948
Encrypter $encrypter,
5049
DaemonConfigurationRepository $configurationRepository,
51-
NodeRepositoryInterface $repository
50+
NodeRepository $repository
5251
) {
5352
$this->connection = $connection;
54-
$this->repository = $repository;
5553
$this->configurationRepository = $configurationRepository;
5654
$this->encrypter = $encrypter;
55+
$this->repository = $repository;
5756
}
5857

5958
/**
@@ -64,55 +63,36 @@ public function __construct(
6463
* @param bool $resetToken
6564
*
6665
* @return \Pterodactyl\Models\Node
67-
*
68-
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
69-
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
70-
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
71-
* @throws \Pterodactyl\Exceptions\Service\Node\ConfigurationNotPersistedException
66+
* @throws \Throwable
7267
*/
7368
public function handle(Node $node, array $data, bool $resetToken = false)
7469
{
7570
if ($resetToken) {
76-
$data['daemon_token'] = Str::random(Node::DAEMON_TOKEN_LENGTH);
77-
$data['daemon_token_id'] = $this->encrypter->encrypt(
78-
Str::random(Node::DAEMON_TOKEN_ID_LENGTH)
79-
);
71+
$data['daemon_token'] = $this->encrypter->encrypt(Str::random(Node::DAEMON_TOKEN_LENGTH));
72+
$data['daemon_token_id'] = Str::random(Node::DAEMON_TOKEN_ID_LENGTH);
8073
}
8174

82-
$this->connection->beginTransaction();
75+
[$updated, $exception] = $this->connection->transaction(function () use ($data, $node) {
76+
/** @var \Pterodactyl\Models\Node $updated */
77+
$updated = $this->repository->withFreshModel()->update($node->id, $data, true, true);
8378

84-
/** @var \Pterodactyl\Models\Node $updatedModel */
85-
$updatedModel = $this->repository->update($node->id, $data);
79+
try {
80+
$this->configurationRepository->setNode($node)->update($updated);
81+
} catch (DaemonConnectionException $exception) {
82+
if (! is_null($exception->getPrevious()) && $exception->getPrevious() instanceof ConnectException) {
83+
return [$updated, true];
84+
}
8685

87-
try {
88-
if ($resetToken) {
89-
// We need to clone the new model and set it's authentication token to be the
90-
// old one so we can connect. Then we will pass the new token through as an
91-
// override on the call.
92-
$cloned = $updatedModel->replicate(['daemon_token']);
93-
$cloned->setAttribute('daemon_token', $node->getAttribute('daemon_token'));
94-
95-
$this->configurationRepository->setNode($cloned)->update([
96-
'daemon_token_id' => $updatedModel->daemon_token_id,
97-
'daemon_token' => $updatedModel->getDecryptedKey(),
98-
]);
99-
} else {
100-
$this->configurationRepository->setNode($updatedModel)->update();
86+
throw $exception;
10187
}
10288

103-
$this->connection->commit();
104-
} catch (RequestException $exception) {
105-
// Failed to connect to the Daemon. Let's go ahead and save the configuration
106-
// and let the user know they'll need to manually update.
107-
if ($exception instanceof ConnectException) {
108-
$this->connection->commit();
109-
110-
throw new ConfigurationNotPersistedException(trans('exceptions.node.daemon_off_config_updated'));
111-
}
89+
return [$updated, false];
90+
});
11291

113-
throw new DaemonConnectionException($exception);
92+
if ($exception) {
93+
throw new ConfigurationNotPersistedException(trans('exceptions.node.daemon_off_config_updated'));
11494
}
11595

116-
return $updatedModel;
96+
return $updated;
11797
}
11898
}

0 commit comments

Comments
 (0)