mirror of
https://github.com/pterodactyl/panel.git
synced 2024-11-22 17:12:30 +01:00
Cleanup auto-deployment functions substantially
Also cleans up ServerRepository to use named models more clearly.
This commit is contained in:
parent
c59cfce72c
commit
b3e5565f85
30
app/Exceptions/AutoDeploymentException.php
Normal file
30
app/Exceptions/AutoDeploymentException.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* Pterodactyl - Panel
|
||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
namespace Pterodactyl\Exceptions;
|
||||
|
||||
class AutoDeploymentException extends \Exception
|
||||
{
|
||||
//
|
||||
}
|
@ -34,6 +34,7 @@ use Pterodactyl\Exceptions\DisplayException;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Repositories\ServerRepository;
|
||||
use Pterodactyl\Repositories\DatabaseRepository;
|
||||
use Pterodactyl\Exceptions\AutoDeploymentException;
|
||||
use Pterodactyl\Exceptions\DisplayValidationException;
|
||||
|
||||
class ServersController extends Controller
|
||||
@ -97,6 +98,8 @@ class ServersController extends Controller
|
||||
return redirect()->route('admin.servers.new')->withErrors(json_decode($ex->getMessage()))->withInput();
|
||||
} catch (DisplayException $ex) {
|
||||
Alert::danger($ex->getMessage())->flash();
|
||||
} catch (AutoDeploymentException $ex) {
|
||||
Alert::danger('Auto-Deployment Exception: ' . $ex->getMessage())->flash();
|
||||
} catch (TransferException $ex) {
|
||||
Log::warning($ex);
|
||||
Alert::danger('A TransferException was encountered while trying to contact the daemon, please ensure it is online and accessible. This error has been logged.')->flash();
|
||||
|
@ -27,8 +27,16 @@ namespace Pterodactyl\Repositories;
|
||||
use DB;
|
||||
use Crypt;
|
||||
use Validator;
|
||||
use Pterodactyl\Models;
|
||||
use Pterodactyl\Models\Pack;
|
||||
use Pterodactyl\Models\User;
|
||||
use Pterodactyl\Models\Node;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Pterodactyl\Models\Service;
|
||||
use Pterodactyl\Models\Allocation;
|
||||
use Pterodactyl\Services\UuidService;
|
||||
use Pterodactyl\Models\ServiceOption;
|
||||
use Pterodactyl\Models\ServerVariable;
|
||||
use Pterodactyl\Models\ServiceVariable;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use GuzzleHttp\Exception\TransferException;
|
||||
use Pterodactyl\Services\DeploymentService;
|
||||
@ -80,12 +88,11 @@ class ServerRepository
|
||||
* @return \Pterodactyl\Models\Server
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @throws \Pterodactyl\Exceptions\AutoDeploymentException
|
||||
* @throws \Pterodactyl\Exceptions\DisplayValidationException
|
||||
*/
|
||||
public function create(array $data)
|
||||
{
|
||||
|
||||
// Validate Fields
|
||||
$validator = Validator::make($data, [
|
||||
'user_id' => 'required|exists:users,id',
|
||||
'name' => 'required|regex:/^([\w .-]{1,200})$/',
|
||||
@ -124,25 +131,27 @@ class ServerRepository
|
||||
throw new DisplayValidationException(json_encode($validator->errors()));
|
||||
}
|
||||
|
||||
$user = Models\User::findOrFail($data['user_id']);
|
||||
$user = User::findOrFail($data['user_id']);
|
||||
|
||||
$autoDeployed = false;
|
||||
if (isset($data['auto_deploy']) && $data['auto_deploy']) {
|
||||
// This is an auto-deployment situation
|
||||
// Ignore any other passed node data
|
||||
unset($data['node_id'], $data['allocation_id']);
|
||||
$deployment = false;
|
||||
if (isset($data['auto_deploy'])) {
|
||||
$deployment = new DeploymentService;
|
||||
|
||||
$autoDeployed = true;
|
||||
$node = DeploymentService::smartRandomNode($data['memory'], $data['disk'], $data['location_id']);
|
||||
$allocation = DeploymentService::randomAllocation($node->id);
|
||||
} else {
|
||||
$node = Models\Node::findOrFail($data['node_id']);
|
||||
if (isset($data['location_id'])) {
|
||||
$deployment->setLocation($data['location_id']);
|
||||
}
|
||||
|
||||
$deployment->setMemory($data['memory'])->setDisk($data['disk'])->select();
|
||||
}
|
||||
|
||||
$node = (! $deployment) ? Node::findOrFail($data['node_id']) : $deployment->node();
|
||||
|
||||
// Verify IP & Port are a.) free and b.) assigned to the node.
|
||||
// We know the node exists because of 'exists:nodes,id' in the validation
|
||||
if (! $autoDeployed) {
|
||||
$allocation = Models\Allocation::where('id', $data['allocation_id'])->where('node_id', $data['node_id'])->whereNull('server_id')->first();
|
||||
if (! $deployment) {
|
||||
$allocation = Allocation::where('id', $data['allocation_id'])->where('node_id', $data['node_id'])->whereNull('server_id')->first();
|
||||
} else {
|
||||
$allocation = $deployment->allocation();
|
||||
}
|
||||
|
||||
// Something failed in the query, either that combo doesn't exist, or it is in use.
|
||||
@ -154,7 +163,7 @@ class ServerRepository
|
||||
// We know the service and option exists because of the validation.
|
||||
// We need to verify that the option exists for the service, and then check for
|
||||
// any required variable fields. (fields are labeled env_<env_variable>)
|
||||
$option = Models\ServiceOption::where('id', $data['option_id'])->where('service_id', $data['service_id'])->first();
|
||||
$option = ServiceOption::where('id', $data['option_id'])->where('service_id', $data['service_id'])->first();
|
||||
if (! $option) {
|
||||
throw new DisplayException('The requested service option does not exist for the specified service.');
|
||||
}
|
||||
@ -163,17 +172,17 @@ class ServerRepository
|
||||
if (! isset($data['pack_id']) || (int) $data['pack_id'] < 1) {
|
||||
$data['pack_id'] = null;
|
||||
} else {
|
||||
$pack = Models\Pack::where('id', $data['pack_id'])->where('option_id', $data['option_id'])->first();
|
||||
$pack = Pack::where('id', $data['pack_id'])->where('option_id', $data['option_id'])->first();
|
||||
if (! $pack) {
|
||||
throw new DisplayException('The requested service pack does not seem to exist for this combination.');
|
||||
}
|
||||
}
|
||||
|
||||
// Load up the Service Information
|
||||
$service = Models\Service::find($option->service_id);
|
||||
$service = Service::find($option->service_id);
|
||||
|
||||
// Check those Variables
|
||||
$variables = Models\ServiceVariable::where('option_id', $data['option_id'])->get();
|
||||
$variables = ServiceVariable::where('option_id', $data['option_id'])->get();
|
||||
$variableList = [];
|
||||
if ($variables) {
|
||||
foreach ($variables as $variable) {
|
||||
@ -206,9 +215,9 @@ class ServerRepository
|
||||
}
|
||||
|
||||
// Check Overallocation
|
||||
if (! $autoDeployed) {
|
||||
if (! $deployment) {
|
||||
if (is_numeric($node->memory_overallocate) || is_numeric($node->disk_overallocate)) {
|
||||
$totals = Models\Server::select(DB::raw('SUM(memory) as memory, SUM(disk) as disk'))->where('node_id', $node->id)->first();
|
||||
$totals = Server::select(DB::raw('SUM(memory) as memory, SUM(disk) as disk'))->where('node_id', $node->id)->first();
|
||||
|
||||
// Check memory limits
|
||||
if (is_numeric($node->memory_overallocate)) {
|
||||
@ -236,7 +245,7 @@ class ServerRepository
|
||||
$uuid = new UuidService;
|
||||
|
||||
// Add Server to the Database
|
||||
$server = new Models\Server;
|
||||
$server = new Server;
|
||||
$genUuid = $uuid->generate('servers', 'uuid');
|
||||
$genShortUuid = $uuid->generateShort('servers', 'uuidShort', $genUuid);
|
||||
|
||||
@ -278,7 +287,7 @@ class ServerRepository
|
||||
// Add Additional Allocations
|
||||
if (isset($data['allocation_additional']) && is_array($data['allocation_additional'])) {
|
||||
foreach ($data['allocation_additional'] as $allocation) {
|
||||
$model = Models\Allocation::where('id', $allocation)->where('node_id', $data['node_id'])->whereNull('server_id')->first();
|
||||
$model = Allocation::where('id', $allocation)->where('node_id', $data['node_id'])->whereNull('server_id')->first();
|
||||
if (! $model) {
|
||||
continue;
|
||||
}
|
||||
@ -296,7 +305,7 @@ class ServerRepository
|
||||
foreach ($variableList as $item) {
|
||||
$environmentVariables[$item['env']] = $item['val'];
|
||||
|
||||
Models\ServerVariable::create([
|
||||
ServerVariable::create([
|
||||
'server_id' => $server->id,
|
||||
'variable_id' => $item['id'],
|
||||
'variable_value' => $item['val'],
|
||||
@ -379,7 +388,7 @@ class ServerRepository
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
$server = Models\Server::with('user')->findOrFail($id);
|
||||
$server = Server::with('user')->findOrFail($id);
|
||||
|
||||
// Update daemon secret if it was passed.
|
||||
if (isset($data['reset_token']) || (isset($data['owner_id']) && (int) $data['owner_id'] !== $server->user->id)) {
|
||||
@ -445,7 +454,7 @@ class ServerRepository
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$server = Models\Server::findOrFail($id);
|
||||
$server = Server::findOrFail($id);
|
||||
|
||||
$server->image = $data['docker_image'];
|
||||
$server->save();
|
||||
@ -502,7 +511,7 @@ class ServerRepository
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
$server = Models\Server::with('allocation', 'allocations')->findOrFail($id);
|
||||
$server = Server::with('allocation', 'allocations')->findOrFail($id);
|
||||
$newBuild = [];
|
||||
$newAllocations = [];
|
||||
|
||||
@ -525,7 +534,7 @@ class ServerRepository
|
||||
// Add Assignments
|
||||
if (isset($data['add_allocations'])) {
|
||||
foreach ($data['add_allocations'] as $allocation) {
|
||||
$model = Models\Allocation::where('id', $allocation)->whereNull('server_id')->first();
|
||||
$model = Allocation::where('id', $allocation)->whereNull('server_id')->first();
|
||||
if (! $model) {
|
||||
continue;
|
||||
}
|
||||
@ -555,7 +564,7 @@ class ServerRepository
|
||||
}
|
||||
|
||||
$newPorts = true;
|
||||
Models\Allocation::where('id', $allocation)->where('server_id', $server->id)->update([
|
||||
Allocation::where('id', $allocation)->where('server_id', $server->id)->update([
|
||||
'server_id' => null,
|
||||
]);
|
||||
}
|
||||
@ -637,7 +646,7 @@ class ServerRepository
|
||||
{
|
||||
}
|
||||
|
||||
protected function processVariables(Models\Server $server, $data, $admin = false)
|
||||
protected function processVariables(Server $server, $data, $admin = false)
|
||||
{
|
||||
$server->load('option.variables');
|
||||
|
||||
@ -671,7 +680,7 @@ class ServerRepository
|
||||
));
|
||||
}
|
||||
|
||||
$svar = Models\ServerVariable::firstOrNew([
|
||||
$svar = ServerVariable::firstOrNew([
|
||||
'server_id' => $server->id,
|
||||
'variable_id' => $variable->id,
|
||||
]);
|
||||
@ -716,7 +725,7 @@ class ServerRepository
|
||||
*/
|
||||
public function updateStartup($id, array $data, $admin = false)
|
||||
{
|
||||
$server = Models\Server::with('variables', 'option.variables')->findOrFail($id);
|
||||
$server = Server::with('variables', 'option.variables')->findOrFail($id);
|
||||
$hasServiceChanges = false;
|
||||
|
||||
if ($admin) {
|
||||
@ -771,7 +780,7 @@ class ServerRepository
|
||||
// We know the service and option exists because of the validation.
|
||||
// We need to verify that the option exists for the service, and then check for
|
||||
// any required variable fields. (fields are labeled env_<env_variable>)
|
||||
$option = Models\ServiceOption::where('id', $data['option_id'])->where('service_id', $data['service_id'])->first();
|
||||
$option = ServiceOption::where('id', $data['option_id'])->where('service_id', $data['service_id'])->first();
|
||||
if (! $option) {
|
||||
throw new DisplayException('The requested service option does not exist for the specified service.');
|
||||
}
|
||||
@ -780,7 +789,7 @@ class ServerRepository
|
||||
if (! isset($data['pack_id']) || (int) $data['pack_id'] < 1) {
|
||||
$data['pack_id'] = null;
|
||||
} else {
|
||||
$pack = Models\Pack::where('id', $data['pack_id'])->where('option_id', $data['option_id'])->first();
|
||||
$pack = Pack::where('id', $data['pack_id'])->where('option_id', $data['option_id'])->first();
|
||||
if (! $pack) {
|
||||
throw new DisplayException('The requested service pack does not seem to exist for this combination.');
|
||||
}
|
||||
@ -833,7 +842,7 @@ class ServerRepository
|
||||
*/
|
||||
public function delete($id, $force = false)
|
||||
{
|
||||
$server = Models\Server::with('node', 'allocations', 'variables')->findOrFail($id);
|
||||
$server = Server::with('node', 'allocations', 'variables')->findOrFail($id);
|
||||
|
||||
// Due to MySQL lockouts if the daemon response fails, we need to
|
||||
// delete the server from the daemon first. If it succeedes and then
|
||||
@ -903,7 +912,7 @@ class ServerRepository
|
||||
*/
|
||||
public function toggleInstall($id)
|
||||
{
|
||||
$server = Models\Server::findOrFail($id);
|
||||
$server = Server::findOrFail($id);
|
||||
if ($server->installed > 1) {
|
||||
throw new DisplayException('This server was marked as having a failed install or being deleted, you cannot override this.');
|
||||
}
|
||||
@ -921,7 +930,7 @@ class ServerRepository
|
||||
*/
|
||||
public function toggleAccess($id, $unsuspend = true)
|
||||
{
|
||||
$server = Models\Server::with('node')->findOrFail($id);
|
||||
$server = Server::with('node')->findOrFail($id);
|
||||
|
||||
DB::transaction(function () use ($server, $unsuspend) {
|
||||
if (
|
||||
@ -952,7 +961,7 @@ class ServerRepository
|
||||
*/
|
||||
public function updateSFTPPassword($id, $password)
|
||||
{
|
||||
$server = Models\Server::with('node')->findOrFail($id);
|
||||
$server = Server::with('node')->findOrFail($id);
|
||||
|
||||
$validator = Validator::make(['password' => $password], [
|
||||
'password' => 'required|regex:/^((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,})$/',
|
||||
@ -983,7 +992,7 @@ class ServerRepository
|
||||
*/
|
||||
public function reinstall($id)
|
||||
{
|
||||
$server = Models\Server::with('node')->findOrFail($id);
|
||||
$server = Server::with('node')->findOrFail($id);
|
||||
|
||||
DB::transaction(function () use ($server) {
|
||||
$server->installed = 0;
|
||||
|
@ -25,114 +25,230 @@
|
||||
namespace Pterodactyl\Services;
|
||||
|
||||
use DB;
|
||||
use Pterodactyl\Models;
|
||||
use Pterodactyl\Exceptions\DisplayException;
|
||||
use Pterodactyl\Models\Node;
|
||||
use Pterodactyl\Models\Server;
|
||||
use Pterodactyl\Models\Location;
|
||||
use Pterodactyl\Exceptions\AutoDeploymentException;
|
||||
|
||||
class DeploymentService
|
||||
{
|
||||
/**
|
||||
* Return a random location model. DO NOT USE.
|
||||
* Eloquent model representing the allocation to use.
|
||||
*
|
||||
* @return \Pterodactyl\Models\Node
|
||||
* @todo Actually make this smarter. If we're selecting a random location
|
||||
* but then it has no nodes we should probably continue attempting all locations
|
||||
* until we hit one.
|
||||
* @var \Pterodactyl\Models\Allocation
|
||||
*/
|
||||
public static function randomLocation()
|
||||
protected $allocation;
|
||||
|
||||
/**
|
||||
* Amount of disk to be used by the server.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $disk;
|
||||
|
||||
/**
|
||||
* Amount of memory to be used by the sever.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $memory;
|
||||
|
||||
/**
|
||||
* Eloquent model representing the location to use.
|
||||
*
|
||||
* @var \Pterodactyl\Models\Location
|
||||
*/
|
||||
protected $location;
|
||||
|
||||
/**
|
||||
* Eloquent model representing the node to use.
|
||||
*
|
||||
* @var \Pterodactyl\Models\Node
|
||||
*/
|
||||
protected $node;
|
||||
|
||||
/**
|
||||
* Set the location to use when auto-deploying.
|
||||
*
|
||||
* @param int|\Pterodactyl\Models\Location $location
|
||||
* @return void
|
||||
*/
|
||||
public function setLocation($location)
|
||||
{
|
||||
return Models\Location::inRandomOrder()->first();
|
||||
$this->location = ($location instanceof Location) ? $location : Location::with('nodes')->findOrFail($location);
|
||||
if (! $this->location->relationLoaded('nodes')) {
|
||||
$this->location->load('nodes');
|
||||
}
|
||||
|
||||
if (count($this->location->nodes) < 1) {
|
||||
throw new AutoDeploymentException('The location provided does not contain any nodes and cannot be used.');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the node to use when auto-deploying.
|
||||
*
|
||||
* @param int|\Pterodactyl\Models\Node $node
|
||||
* @return void
|
||||
*/
|
||||
public function setNode($node)
|
||||
{
|
||||
$this->node = ($node instanceof Node) ? $node : Node::findOrFail($node);
|
||||
if (! $this->node->relationLoaded('allocations')) {
|
||||
$this->node->load('allocations');
|
||||
}
|
||||
|
||||
$this->setLocation($this->node->location);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the amount of disk space to be used by the new server.
|
||||
*
|
||||
* @param int $disk
|
||||
* @return void
|
||||
*/
|
||||
public function setDisk(int $disk)
|
||||
{
|
||||
$this->disk = $disk;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the amount of memory to be used by the new server.
|
||||
*
|
||||
* @param int $memory
|
||||
* @return void
|
||||
*/
|
||||
public function setMemory(int $memory)
|
||||
{
|
||||
$this->memory = $memory;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a random location model.
|
||||
*
|
||||
* @param array $exclude
|
||||
* @return void;
|
||||
*/
|
||||
protected function findLocation(array $exclude = [])
|
||||
{
|
||||
$location = Location::with('nodes')->whereNotIn('id', $exclude)->inRandomOrder()->first();
|
||||
|
||||
if (! $location) {
|
||||
throw new AutoDeploymentException('Unable to locate a suitable location to select a node from.');
|
||||
}
|
||||
|
||||
if (count($location->nodes) < 1) {
|
||||
return $this->findLocation(array_merge($exclude, [$location->id]));
|
||||
}
|
||||
|
||||
$this->setLocation($location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a model instance of a random node.
|
||||
* @param int $location
|
||||
* @param array $not
|
||||
* @return \Pterodactyl\Models\Node
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @return void;
|
||||
*/
|
||||
public static function randomNode($location, array $not = [])
|
||||
protected function findNode(array $exclude = [])
|
||||
{
|
||||
$useLocation = Models\Location::where('id', $location)->first();
|
||||
if (! $useLocation) {
|
||||
throw new DisplayException('The location passed was not valid and could not be found.');
|
||||
if (! $this->location) {
|
||||
$this->setLocation($this->findLocation());
|
||||
}
|
||||
|
||||
$node = Models\Node::where('location_id', $useLocation->id)->where('public', 1)->whereNotIn('id', $not)->inRandomOrder()->first();
|
||||
if (! $node) {
|
||||
throw new DisplayException("Unable to find a node in location {$useLocation->short} (id: {$useLocation->id}) that is available and has space.");
|
||||
$select = $this->location->nodes->whereNotIn('id', $exclude);
|
||||
if (count($select) < 1) {
|
||||
throw new AutoDeploymentException('Unable to find a suitable node within the assigned location with enough space.');
|
||||
}
|
||||
|
||||
return $node;
|
||||
// Check usage, select new node if necessary
|
||||
$this->setNode($select->random());
|
||||
if (! $this->checkNodeUsage()) {
|
||||
return $this->findNode(array_merge($exclude, [$this->node()->id]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects a random node ensuring it does not put the node
|
||||
* over allocation limits.
|
||||
* @param int $memory
|
||||
* @param int $disk
|
||||
* @param null|int $location
|
||||
* @return \Pterodactyl\Models\Node
|
||||
* Checks that a node's allocation limits will not be passed
|
||||
* with the assigned limits.
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||
* @return bool
|
||||
*/
|
||||
public static function smartRandomNode($memory, $disk, $location = null)
|
||||
protected function checkNodeUsage()
|
||||
{
|
||||
$node = self::randomNode($location);
|
||||
$notIn = [];
|
||||
do {
|
||||
$return = self::checkNodeAllocation($node, $memory, $disk);
|
||||
if (! $return) {
|
||||
$notIn = array_merge($notIn, [
|
||||
$node->id,
|
||||
]);
|
||||
$node = self::randomNode($location, $notIn);
|
||||
}
|
||||
} while (! $return);
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random allocation for a node.
|
||||
* @param int $node
|
||||
* @return \Models\Pterodactyl\Allocation
|
||||
*/
|
||||
public static function randomAllocation($node)
|
||||
{
|
||||
$allocation = Models\Allocation::where('node_id', $node)->whereNull('server_id')->inRandomOrder()->first();
|
||||
if (! $allocation) {
|
||||
throw new DisplayException('No available allocation could be found for the assigned node.');
|
||||
if (! $this->disk && ! $this->memory) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $allocation;
|
||||
$totals = Server::select(DB::raw('SUM(memory) as memory, SUM(disk) as disk'))->where('node_id', $this->node()->id)->first();
|
||||
|
||||
if ($this->memory) {
|
||||
$limit = ($this->node()->memory * (1 + ($this->node()->memory_overallocate / 100)));
|
||||
|
||||
if (($totals->memory + $this->memory) > $limit) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->disk) {
|
||||
$limit = ($this->node()->disk * (1 + ($this->node()->disk_overallocate / 100)));
|
||||
|
||||
if (($totals->disk + $this->disk) > $limit) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a node's allocation limits will not be passed with the given information.
|
||||
* @param \Pterodactyl\Models\Node $node
|
||||
* @param int $memory
|
||||
* @param int $disk
|
||||
* @return bool Returns true if this information would not put the node over it's limit.
|
||||
* Return the assigned node for this auto-deployment.
|
||||
*
|
||||
* @return \Pterodactyl\Models\Node
|
||||
*/
|
||||
protected static function checkNodeAllocation(Models\Node $node, $memory, $disk)
|
||||
{
|
||||
if (is_numeric($node->memory_overallocate) || is_numeric($node->disk_overallocate)) {
|
||||
$totals = Models\Server::select(DB::raw('SUM(memory) as memory, SUM(disk) as disk'))->where('node_id', $node->id)->first();
|
||||
public function node() {
|
||||
return $this->node;
|
||||
}
|
||||
|
||||
// Check memory limits
|
||||
if (is_numeric($node->memory_overallocate)) {
|
||||
$limit = ($node->memory * (1 + ($node->memory_overallocate / 100)));
|
||||
$memoryLimitReached = (($totals->memory + $memory) > $limit);
|
||||
}
|
||||
/**
|
||||
* Return the assigned location for this auto-deployment.
|
||||
*
|
||||
* @return \Pterodactyl\Models\Location
|
||||
*/
|
||||
public function location() {
|
||||
return $this->location;
|
||||
}
|
||||
|
||||
// Check Disk Limits
|
||||
if (is_numeric($node->disk_overallocate)) {
|
||||
$limit = ($node->disk * (1 + ($node->disk_overallocate / 100)));
|
||||
$diskLimitReached = (($totals->disk + $disk) > $limit);
|
||||
}
|
||||
/**
|
||||
* Return the assigned location for this auto-deployment.
|
||||
*
|
||||
* @return \Pterodactyl\Models\Allocation
|
||||
*/
|
||||
public function allocation() {
|
||||
return $this->allocation;
|
||||
}
|
||||
|
||||
return ! $diskLimitReached && ! $memoryLimitReached;
|
||||
/**
|
||||
* Select and return the node to be used by the auto-deployment system.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function select() {
|
||||
if (! $this->node) {
|
||||
$this->findNode();
|
||||
}
|
||||
|
||||
// Set the Allocation
|
||||
$this->allocation = $this->node()->allocations->where('server_id', null)->random();
|
||||
if (! $this->allocation) {
|
||||
throw new AutoDeploymentException('Unable to find a suitable allocation to assign to this server.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user