2017-07-24 00:57:43 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Pterodactyl\Services\Servers;
|
|
|
|
|
2019-12-22 05:01:38 +00:00
|
|
|
use Illuminate\Support\Arr;
|
2017-08-05 22:26:30 +00:00
|
|
|
use Pterodactyl\Models\Server;
|
2017-07-24 00:57:43 +00:00
|
|
|
use GuzzleHttp\Exception\RequestException;
|
|
|
|
use Illuminate\Database\ConnectionInterface;
|
|
|
|
use Pterodactyl\Exceptions\DisplayException;
|
2019-11-24 23:08:54 +00:00
|
|
|
use Pterodactyl\Repositories\Wings\DaemonServerRepository;
|
2017-07-24 00:57:43 +00:00
|
|
|
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
|
2017-08-05 22:26:30 +00:00
|
|
|
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
|
|
|
|
use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface;
|
2018-01-21 22:02:03 +00:00
|
|
|
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
|
2017-07-24 00:57:43 +00:00
|
|
|
|
|
|
|
class BuildModificationService
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @var \Pterodactyl\Contracts\Repository\AllocationRepositoryInterface
|
|
|
|
*/
|
2018-01-21 22:02:03 +00:00
|
|
|
private $allocationRepository;
|
2017-07-24 00:57:43 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var \Illuminate\Database\ConnectionInterface
|
|
|
|
*/
|
2018-01-21 22:02:03 +00:00
|
|
|
private $connection;
|
2017-07-24 00:57:43 +00:00
|
|
|
|
|
|
|
/**
|
2019-11-24 23:08:54 +00:00
|
|
|
* @var \Pterodactyl\Repositories\Wings\DaemonServerRepository
|
2017-07-24 00:57:43 +00:00
|
|
|
*/
|
2018-01-21 22:02:03 +00:00
|
|
|
private $daemonServerRepository;
|
2017-07-24 00:57:43 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
|
|
|
|
*/
|
2018-01-21 22:02:03 +00:00
|
|
|
private $repository;
|
2017-07-24 00:57:43 +00:00
|
|
|
|
2019-12-22 05:01:38 +00:00
|
|
|
/**
|
|
|
|
* @var \Pterodactyl\Services\Servers\ServerConfigurationStructureService
|
|
|
|
*/
|
|
|
|
private $structureService;
|
|
|
|
|
2017-07-24 00:57:43 +00:00
|
|
|
/**
|
|
|
|
* BuildModificationService constructor.
|
|
|
|
*
|
2019-09-06 04:32:57 +00:00
|
|
|
* @param \Pterodactyl\Contracts\Repository\AllocationRepositoryInterface $allocationRepository
|
2019-12-22 05:01:38 +00:00
|
|
|
* @param \Pterodactyl\Services\Servers\ServerConfigurationStructureService $structureService
|
2019-09-06 04:32:57 +00:00
|
|
|
* @param \Illuminate\Database\ConnectionInterface $connection
|
2019-11-24 23:08:54 +00:00
|
|
|
* @param \Pterodactyl\Repositories\Wings\DaemonServerRepository $daemonServerRepository
|
2019-09-06 04:32:57 +00:00
|
|
|
* @param \Pterodactyl\Contracts\Repository\ServerRepositoryInterface $repository
|
2017-07-24 00:57:43 +00:00
|
|
|
*/
|
|
|
|
public function __construct(
|
|
|
|
AllocationRepositoryInterface $allocationRepository,
|
2019-12-22 05:01:38 +00:00
|
|
|
ServerConfigurationStructureService $structureService,
|
2018-01-21 22:02:03 +00:00
|
|
|
ConnectionInterface $connection,
|
2019-11-24 23:08:54 +00:00
|
|
|
DaemonServerRepository $daemonServerRepository,
|
2018-01-21 22:02:03 +00:00
|
|
|
ServerRepositoryInterface $repository
|
2017-07-24 00:57:43 +00:00
|
|
|
) {
|
|
|
|
$this->allocationRepository = $allocationRepository;
|
|
|
|
$this->daemonServerRepository = $daemonServerRepository;
|
2018-01-21 22:02:03 +00:00
|
|
|
$this->connection = $connection;
|
2017-07-24 00:57:43 +00:00
|
|
|
$this->repository = $repository;
|
2019-12-22 05:01:38 +00:00
|
|
|
$this->structureService = $structureService;
|
2017-07-24 00:57:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Change the build details for a specified server.
|
|
|
|
*
|
2018-01-21 22:02:03 +00:00
|
|
|
* @param \Pterodactyl\Models\Server $server
|
2019-09-06 04:32:57 +00:00
|
|
|
* @param array $data
|
2018-01-21 22:02:03 +00:00
|
|
|
* @return \Pterodactyl\Models\Server
|
2017-07-24 00:57:43 +00:00
|
|
|
*
|
|
|
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
2018-01-01 18:32:33 +00:00
|
|
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
2020-06-24 03:24:09 +00:00
|
|
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
2017-07-24 00:57:43 +00:00
|
|
|
*/
|
2018-01-21 22:02:03 +00:00
|
|
|
public function handle(Server $server, array $data)
|
2017-07-24 00:57:43 +00:00
|
|
|
{
|
2018-01-21 22:02:03 +00:00
|
|
|
$this->connection->beginTransaction();
|
2017-07-24 00:57:43 +00:00
|
|
|
|
|
|
|
$this->processAllocations($server, $data);
|
2019-11-24 23:08:54 +00:00
|
|
|
|
2017-07-24 00:57:43 +00:00
|
|
|
if (isset($data['allocation_id']) && $data['allocation_id'] != $server->allocation_id) {
|
|
|
|
try {
|
2019-11-24 23:08:54 +00:00
|
|
|
$this->allocationRepository->findFirstWhere([
|
2017-07-24 00:57:43 +00:00
|
|
|
['id', '=', $data['allocation_id']],
|
|
|
|
['server_id', '=', $server->id],
|
|
|
|
]);
|
|
|
|
} catch (RecordNotFoundException $ex) {
|
|
|
|
throw new DisplayException(trans('admin/server.exceptions.default_allocation_not_found'));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 03:24:09 +00:00
|
|
|
/* @var \Pterodactyl\Models\Server $server */
|
2018-01-21 22:02:03 +00:00
|
|
|
$server = $this->repository->withFreshModel()->update($server->id, [
|
2019-08-03 20:41:24 +00:00
|
|
|
'oom_disabled' => array_get($data, 'oom_disabled'),
|
2018-01-21 22:02:03 +00:00
|
|
|
'memory' => array_get($data, 'memory'),
|
|
|
|
'swap' => array_get($data, 'swap'),
|
|
|
|
'io' => array_get($data, 'io'),
|
|
|
|
'cpu' => array_get($data, 'cpu'),
|
2020-03-29 18:41:55 +00:00
|
|
|
'threads' => array_get($data, 'threads'),
|
2018-01-21 22:02:03 +00:00
|
|
|
'disk' => array_get($data, 'disk'),
|
|
|
|
'allocation_id' => array_get($data, 'allocation_id'),
|
2020-04-26 19:12:29 +00:00
|
|
|
'database_limit' => array_get($data, 'database_limit', 0),
|
|
|
|
'allocation_limit' => array_get($data, 'allocation_limit', 0),
|
|
|
|
'backup_limit' => array_get($data, 'backup_limit', 0),
|
2017-07-25 02:34:10 +00:00
|
|
|
]);
|
|
|
|
|
2019-12-22 05:01:38 +00:00
|
|
|
$updateData = $this->structureService->handle($server);
|
2017-07-24 00:57:43 +00:00
|
|
|
|
|
|
|
try {
|
2019-12-22 21:45:40 +00:00
|
|
|
$this->daemonServerRepository
|
|
|
|
->setServer($server)
|
|
|
|
->update(Arr::only($updateData, ['build']));
|
|
|
|
|
2018-01-21 22:02:03 +00:00
|
|
|
$this->connection->commit();
|
2017-07-24 00:57:43 +00:00
|
|
|
} catch (RequestException $exception) {
|
2018-01-21 22:02:03 +00:00
|
|
|
throw new DaemonConnectionException($exception);
|
2017-07-24 00:57:43 +00:00
|
|
|
}
|
2018-01-21 22:02:03 +00:00
|
|
|
|
|
|
|
return $server;
|
2017-07-24 00:57:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-01-21 22:02:03 +00:00
|
|
|
* Process the allocations being assigned in the data and ensure they
|
|
|
|
* are available for a server.
|
2017-07-24 00:57:43 +00:00
|
|
|
*
|
|
|
|
* @param \Pterodactyl\Models\Server $server
|
2019-09-06 04:32:57 +00:00
|
|
|
* @param array $data
|
2017-07-24 00:57:43 +00:00
|
|
|
*
|
|
|
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
|
|
|
*/
|
2018-01-21 22:02:03 +00:00
|
|
|
private function processAllocations(Server $server, array &$data)
|
2017-07-24 00:57:43 +00:00
|
|
|
{
|
2018-01-21 22:02:03 +00:00
|
|
|
$firstAllocationId = null;
|
|
|
|
|
2017-07-24 00:57:43 +00:00
|
|
|
if (! array_key_exists('add_allocations', $data) && ! array_key_exists('remove_allocations', $data)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-01-21 22:02:03 +00:00
|
|
|
// Handle the addition of allocations to this server.
|
2017-07-24 00:57:43 +00:00
|
|
|
if (array_key_exists('add_allocations', $data) && ! empty($data['add_allocations'])) {
|
2018-01-21 22:02:03 +00:00
|
|
|
$unassigned = $this->allocationRepository->getUnassignedAllocationIds($server->node_id);
|
2017-07-24 00:57:43 +00:00
|
|
|
|
2018-01-21 22:02:03 +00:00
|
|
|
$updateIds = [];
|
2017-07-24 00:57:43 +00:00
|
|
|
foreach ($data['add_allocations'] as $allocation) {
|
|
|
|
if (! in_array($allocation, $unassigned)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-01-21 22:02:03 +00:00
|
|
|
$firstAllocationId = $firstAllocationId ?? $allocation;
|
|
|
|
$updateIds[] = $allocation;
|
2017-07-24 00:57:43 +00:00
|
|
|
}
|
|
|
|
|
2018-01-21 22:02:03 +00:00
|
|
|
if (! empty($updateIds)) {
|
|
|
|
$this->allocationRepository->updateWhereIn('id', $updateIds, ['server_id' => $server->id]);
|
2017-07-24 00:57:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-21 22:02:03 +00:00
|
|
|
// Handle removal of allocations from this server.
|
2017-07-24 00:57:43 +00:00
|
|
|
if (array_key_exists('remove_allocations', $data) && ! empty($data['remove_allocations'])) {
|
2018-01-21 22:02:03 +00:00
|
|
|
$assigned = $this->allocationRepository->getAssignedAllocationIds($server->id);
|
2017-07-24 00:57:43 +00:00
|
|
|
|
2018-01-21 22:02:03 +00:00
|
|
|
$updateIds = [];
|
2017-07-24 00:57:43 +00:00
|
|
|
foreach ($data['remove_allocations'] as $allocation) {
|
|
|
|
if (! in_array($allocation, $assigned)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($allocation == $data['allocation_id']) {
|
2018-01-21 22:02:03 +00:00
|
|
|
if (is_null($firstAllocationId)) {
|
2017-07-24 00:57:43 +00:00
|
|
|
throw new DisplayException(trans('admin/server.exceptions.no_new_default_allocation'));
|
|
|
|
}
|
|
|
|
|
2018-01-21 22:02:03 +00:00
|
|
|
$data['allocation_id'] = $firstAllocationId;
|
2017-07-24 00:57:43 +00:00
|
|
|
}
|
|
|
|
|
2018-01-21 22:02:03 +00:00
|
|
|
$updateIds[] = $allocation;
|
2017-07-24 00:57:43 +00:00
|
|
|
}
|
|
|
|
|
2018-01-21 22:02:03 +00:00
|
|
|
if (! empty($updateIds)) {
|
|
|
|
$this->allocationRepository->updateWhereIn('id', $updateIds, ['server_id' => null]);
|
2017-07-24 00:57:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|