mirror of
https://github.com/pelican-dev/panel.git
synced 2025-05-20 12:14:45 +02:00
* add node cpu limit to backend * update makenodecommand * add node cpu limit to frontend * add migration and update mysql schema * run pint * fix typo in mysql schema * forgot this assert * forgot to setCpu here * run pint * adjust migration * Fix db migration * make cpu optional * set default value for cpu in node deployment * update mysql schema --------- Co-authored-by: notCharles <charles@pelican.dev>
This commit is contained in:
parent
eadaec1b30
commit
4dd833562b
@ -20,6 +20,8 @@ class MakeNodeCommand extends Command
|
|||||||
{--overallocateMemory= : Enter the amount of ram to overallocate (% or -1 to overallocate the maximum).}
|
{--overallocateMemory= : Enter the amount of ram to overallocate (% or -1 to overallocate the maximum).}
|
||||||
{--maxDisk= : Set the max disk amount.}
|
{--maxDisk= : Set the max disk amount.}
|
||||||
{--overallocateDisk= : Enter the amount of disk to overallocate (% or -1 to overallocate the maximum).}
|
{--overallocateDisk= : Enter the amount of disk to overallocate (% or -1 to overallocate the maximum).}
|
||||||
|
{--maxCpu= : Set the max cpu amount.}
|
||||||
|
{--overallocateCpu= : Enter the amount of cpu to overallocate (% or -1 to overallocate the maximum).}
|
||||||
{--uploadSize= : Enter the maximum upload filesize.}
|
{--uploadSize= : Enter the maximum upload filesize.}
|
||||||
{--daemonListeningPort= : Enter the daemon listening port.}
|
{--daemonListeningPort= : Enter the daemon listening port.}
|
||||||
{--daemonSFTPPort= : Enter the daemon SFTP listening port.}
|
{--daemonSFTPPort= : Enter the daemon SFTP listening port.}
|
||||||
@ -58,6 +60,8 @@ class MakeNodeCommand extends Command
|
|||||||
$data['memory_overallocate'] = $this->option('overallocateMemory') ?? $this->ask(__('commands.make_node.memory_overallocate'));
|
$data['memory_overallocate'] = $this->option('overallocateMemory') ?? $this->ask(__('commands.make_node.memory_overallocate'));
|
||||||
$data['disk'] = $this->option('maxDisk') ?? $this->ask(__('commands.make_node.disk'));
|
$data['disk'] = $this->option('maxDisk') ?? $this->ask(__('commands.make_node.disk'));
|
||||||
$data['disk_overallocate'] = $this->option('overallocateDisk') ?? $this->ask(__('commands.make_node.disk_overallocate'));
|
$data['disk_overallocate'] = $this->option('overallocateDisk') ?? $this->ask(__('commands.make_node.disk_overallocate'));
|
||||||
|
$data['cpu'] = $this->option('maxCpu') ?? $this->ask(__('commands.make_node.cpu'));
|
||||||
|
$data['cpu_overallocate'] = $this->option('overallocateCpu') ?? $this->ask(__('commands.make_node.cpu_overallocate'));
|
||||||
$data['upload_size'] = $this->option('uploadSize') ?? $this->ask(__('commands.make_node.upload_size'), '100');
|
$data['upload_size'] = $this->option('uploadSize') ?? $this->ask(__('commands.make_node.upload_size'), '100');
|
||||||
$data['daemon_listen'] = $this->option('daemonListeningPort') ?? $this->ask(__('commands.make_node.daemonListen'), '8080');
|
$data['daemon_listen'] = $this->option('daemonListeningPort') ?? $this->ask(__('commands.make_node.daemonListen'), '8080');
|
||||||
$data['daemon_sftp'] = $this->option('daemonSFTPPort') ?? $this->ask(__('commands.make_node.daemonSFTP'), '2022');
|
$data['daemon_sftp'] = $this->option('daemonSFTPPort') ?? $this->ask(__('commands.make_node.daemonSFTP'), '2022');
|
||||||
|
@ -311,6 +311,45 @@ class CreateNode extends CreateRecord
|
|||||||
->default(0)
|
->default(0)
|
||||||
->suffix('%'),
|
->suffix('%'),
|
||||||
]),
|
]),
|
||||||
|
Forms\Components\Grid::make()
|
||||||
|
->columns(6)
|
||||||
|
->columnSpanFull()
|
||||||
|
->schema([
|
||||||
|
Forms\Components\ToggleButtons::make('unlimited_cpu')
|
||||||
|
->label('CPU')->inlineLabel()->inline()
|
||||||
|
->live()
|
||||||
|
->afterStateUpdated(fn (Forms\Set $set) => $set('cpu', 0))
|
||||||
|
->afterStateUpdated(fn (Forms\Set $set) => $set('cpu_overallocate', 0))
|
||||||
|
->formatStateUsing(fn (Forms\Get $get) => $get('cpu') == 0)
|
||||||
|
->options([
|
||||||
|
true => 'Unlimited',
|
||||||
|
false => 'Limited',
|
||||||
|
])
|
||||||
|
->colors([
|
||||||
|
true => 'primary',
|
||||||
|
false => 'warning',
|
||||||
|
])
|
||||||
|
->columnSpan(2),
|
||||||
|
Forms\Components\TextInput::make('cpu')
|
||||||
|
->dehydratedWhenHidden()
|
||||||
|
->hidden(fn (Forms\Get $get) => $get('unlimited_cpu'))
|
||||||
|
->label('CPU Limit')->inlineLabel()
|
||||||
|
->suffix('%')
|
||||||
|
->columnSpan(2)
|
||||||
|
->numeric()
|
||||||
|
->minValue(0),
|
||||||
|
Forms\Components\TextInput::make('cpu_overallocate')
|
||||||
|
->dehydratedWhenHidden()
|
||||||
|
->hidden(fn (Forms\Get $get) => $get('unlimited_cpu'))
|
||||||
|
->label('Overallocate')->inlineLabel()
|
||||||
|
->hintIcon('tabler-question-mark')
|
||||||
|
->hintIconTooltip('The % allowable to go over the set limit.')
|
||||||
|
->columnSpan(2)
|
||||||
|
->numeric()
|
||||||
|
->minValue(-1)
|
||||||
|
->maxValue(100)
|
||||||
|
->suffix('%'),
|
||||||
|
]),
|
||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
|
@ -318,6 +318,47 @@ class EditNode extends EditRecord
|
|||||||
->maxValue(100)
|
->maxValue(100)
|
||||||
->suffix('%'),
|
->suffix('%'),
|
||||||
]),
|
]),
|
||||||
|
Forms\Components\Grid::make()
|
||||||
|
->columns(6)
|
||||||
|
->columnSpanFull()
|
||||||
|
->schema([
|
||||||
|
Forms\Components\ToggleButtons::make('unlimited_cpu')
|
||||||
|
->label('CPU')->inlineLabel()->inline()
|
||||||
|
->live()
|
||||||
|
->afterStateUpdated(fn (Forms\Set $set) => $set('cpu', 0))
|
||||||
|
->afterStateUpdated(fn (Forms\Set $set) => $set('cpu_overallocate', 0))
|
||||||
|
->formatStateUsing(fn (Forms\Get $get) => $get('cpu') == 0)
|
||||||
|
->options([
|
||||||
|
true => 'Unlimited',
|
||||||
|
false => 'Limited',
|
||||||
|
])
|
||||||
|
->colors([
|
||||||
|
true => 'primary',
|
||||||
|
false => 'warning',
|
||||||
|
])
|
||||||
|
->columnSpan(2),
|
||||||
|
Forms\Components\TextInput::make('cpu')
|
||||||
|
->dehydratedWhenHidden()
|
||||||
|
->hidden(fn (Forms\Get $get) => $get('unlimited_cpu'))
|
||||||
|
->label('CPU Limit')->inlineLabel()
|
||||||
|
->suffix('%')
|
||||||
|
->required()
|
||||||
|
->columnSpan(2)
|
||||||
|
->numeric()
|
||||||
|
->minValue(0),
|
||||||
|
Forms\Components\TextInput::make('cpu_overallocate')
|
||||||
|
->dehydratedWhenHidden()
|
||||||
|
->hidden(fn (Forms\Get $get) => $get('unlimited_cpu'))
|
||||||
|
->label('Overallocate')->inlineLabel()
|
||||||
|
->hintIcon('tabler-question-mark')
|
||||||
|
->hintIconTooltip('The % allowable to go over the set limit.')
|
||||||
|
->columnSpan(2)
|
||||||
|
->required()
|
||||||
|
->numeric()
|
||||||
|
->minValue(-1)
|
||||||
|
->maxValue(100)
|
||||||
|
->suffix('%'),
|
||||||
|
]),
|
||||||
]),
|
]),
|
||||||
Tabs\Tab::make('Configuration File')
|
Tabs\Tab::make('Configuration File')
|
||||||
->icon('tabler-code')
|
->icon('tabler-code')
|
||||||
|
@ -52,6 +52,12 @@ class ListNodes extends ListRecords
|
|||||||
->suffix(' GiB')
|
->suffix(' GiB')
|
||||||
->formatStateUsing(fn ($state) => number_format($state / 1024, 2))
|
->formatStateUsing(fn ($state) => number_format($state / 1024, 2))
|
||||||
->sortable(),
|
->sortable(),
|
||||||
|
Tables\Columns\TextColumn::make('cpu')
|
||||||
|
->visibleFrom('sm')
|
||||||
|
->icon('tabler-file')
|
||||||
|
->numeric()
|
||||||
|
->suffix(' %')
|
||||||
|
->sortable(),
|
||||||
Tables\Columns\IconColumn::make('scheme')
|
Tables\Columns\IconColumn::make('scheme')
|
||||||
->visibleFrom('xl')
|
->visibleFrom('xl')
|
||||||
->label('SSL')
|
->label('SSL')
|
||||||
|
@ -36,7 +36,7 @@ class NodeController extends ApplicationApiController
|
|||||||
{
|
{
|
||||||
$nodes = QueryBuilder::for(Node::query())
|
$nodes = QueryBuilder::for(Node::query())
|
||||||
->allowedFilters(['uuid', 'name', 'fqdn', 'daemon_token_id'])
|
->allowedFilters(['uuid', 'name', 'fqdn', 'daemon_token_id'])
|
||||||
->allowedSorts(['id', 'uuid', 'memory', 'disk'])
|
->allowedSorts(['id', 'uuid', 'memory', 'disk', 'cpu'])
|
||||||
->paginate($request->query('per_page') ?? 50);
|
->paginate($request->query('per_page') ?? 50);
|
||||||
|
|
||||||
return $this->fractal->collection($nodes)
|
return $this->fractal->collection($nodes)
|
||||||
|
@ -30,6 +30,7 @@ class NodeDeploymentController extends ApplicationApiController
|
|||||||
$nodes = $this->viableNodesService
|
$nodes = $this->viableNodesService
|
||||||
->setMemory($data['memory'])
|
->setMemory($data['memory'])
|
||||||
->setDisk($data['disk'])
|
->setDisk($data['disk'])
|
||||||
|
->setCpu($data['cpu'] ?? 0)
|
||||||
->handle((int) $request->query('per_page'), (int) $request->query('page'));
|
->handle((int) $request->query('per_page'), (int) $request->query('page'));
|
||||||
|
|
||||||
return $this->fractal->collection($nodes)
|
return $this->fractal->collection($nodes)
|
||||||
|
@ -10,6 +10,7 @@ class GetDeployableNodesRequest extends GetNodesRequest
|
|||||||
'page' => 'integer',
|
'page' => 'integer',
|
||||||
'memory' => 'required|integer|min:0',
|
'memory' => 'required|integer|min:0',
|
||||||
'disk' => 'required|integer|min:0',
|
'disk' => 'required|integer|min:0',
|
||||||
|
'cpu' => 'sometimes|integer|min:0',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,8 @@ class StoreNodeRequest extends ApplicationApiRequest
|
|||||||
'memory_overallocate',
|
'memory_overallocate',
|
||||||
'disk',
|
'disk',
|
||||||
'disk_overallocate',
|
'disk_overallocate',
|
||||||
|
'cpu',
|
||||||
|
'cpu_overallocate',
|
||||||
'upload_size',
|
'upload_size',
|
||||||
'daemon_listen',
|
'daemon_listen',
|
||||||
'daemon_sftp',
|
'daemon_sftp',
|
||||||
|
@ -26,6 +26,8 @@ use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
|||||||
* @property int $memory_overallocate
|
* @property int $memory_overallocate
|
||||||
* @property int $disk
|
* @property int $disk
|
||||||
* @property int $disk_overallocate
|
* @property int $disk_overallocate
|
||||||
|
* @property int $cpu
|
||||||
|
* @property int $cpu_overallocate
|
||||||
* @property int $upload_size
|
* @property int $upload_size
|
||||||
* @property string $daemon_token_id
|
* @property string $daemon_token_id
|
||||||
* @property string $daemon_token
|
* @property string $daemon_token
|
||||||
@ -63,6 +65,7 @@ class Node extends Model
|
|||||||
|
|
||||||
public int $sum_memory;
|
public int $sum_memory;
|
||||||
public int $sum_disk;
|
public int $sum_disk;
|
||||||
|
public int $sum_cpu;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fields that are mass assignable.
|
* Fields that are mass assignable.
|
||||||
@ -71,7 +74,8 @@ class Node extends Model
|
|||||||
'public', 'name',
|
'public', 'name',
|
||||||
'fqdn', 'scheme', 'behind_proxy',
|
'fqdn', 'scheme', 'behind_proxy',
|
||||||
'memory', 'memory_overallocate', 'disk',
|
'memory', 'memory_overallocate', 'disk',
|
||||||
'disk_overallocate', 'upload_size', 'daemon_base',
|
'disk_overallocate', 'cpu', 'cpu_overallocate',
|
||||||
|
'upload_size', 'daemon_base',
|
||||||
'daemon_sftp', 'daemon_listen',
|
'daemon_sftp', 'daemon_listen',
|
||||||
'description', 'maintenance_mode',
|
'description', 'maintenance_mode',
|
||||||
];
|
];
|
||||||
@ -87,6 +91,8 @@ class Node extends Model
|
|||||||
'memory_overallocate' => 'required|numeric|min:-1',
|
'memory_overallocate' => 'required|numeric|min:-1',
|
||||||
'disk' => 'required|numeric|min:0',
|
'disk' => 'required|numeric|min:0',
|
||||||
'disk_overallocate' => 'required|numeric|min:-1',
|
'disk_overallocate' => 'required|numeric|min:-1',
|
||||||
|
'cpu' => 'required|numeric|min:0',
|
||||||
|
'cpu_overallocate' => 'required|numeric|min:-1',
|
||||||
'daemon_base' => 'sometimes|required|regex:/^([\/][\d\w.\-\/]+)$/',
|
'daemon_base' => 'sometimes|required|regex:/^([\/][\d\w.\-\/]+)$/',
|
||||||
'daemon_sftp' => 'required|numeric|between:1,65535',
|
'daemon_sftp' => 'required|numeric|between:1,65535',
|
||||||
'daemon_listen' => 'required|numeric|between:1,65535',
|
'daemon_listen' => 'required|numeric|between:1,65535',
|
||||||
@ -104,6 +110,8 @@ class Node extends Model
|
|||||||
'memory_overallocate' => 0,
|
'memory_overallocate' => 0,
|
||||||
'disk' => 0,
|
'disk' => 0,
|
||||||
'disk_overallocate' => 0,
|
'disk_overallocate' => 0,
|
||||||
|
'cpu' => 0,
|
||||||
|
'cpu_overallocate' => 0,
|
||||||
'daemon_base' => '/var/lib/pelican/volumes',
|
'daemon_base' => '/var/lib/pelican/volumes',
|
||||||
'daemon_sftp' => 2022,
|
'daemon_sftp' => 2022,
|
||||||
'daemon_listen' => 8080,
|
'daemon_listen' => 8080,
|
||||||
@ -116,6 +124,7 @@ class Node extends Model
|
|||||||
return [
|
return [
|
||||||
'memory' => 'integer',
|
'memory' => 'integer',
|
||||||
'disk' => 'integer',
|
'disk' => 'integer',
|
||||||
|
'cpu' => 'integer',
|
||||||
'daemon_listen' => 'integer',
|
'daemon_listen' => 'integer',
|
||||||
'daemon_sftp' => 'integer',
|
'daemon_sftp' => 'integer',
|
||||||
'behind_proxy' => 'boolean',
|
'behind_proxy' => 'boolean',
|
||||||
@ -239,12 +248,13 @@ class Node extends Model
|
|||||||
/**
|
/**
|
||||||
* Returns a boolean if the node is viable for an additional server to be placed on it.
|
* Returns a boolean if the node is viable for an additional server to be placed on it.
|
||||||
*/
|
*/
|
||||||
public function isViable(int $memory, int $disk): bool
|
public function isViable(int $memory, int $disk, int $cpu): bool
|
||||||
{
|
{
|
||||||
$memoryLimit = $this->memory * (1 + ($this->memory_overallocate / 100));
|
$memoryLimit = $this->memory * (1 + ($this->memory_overallocate / 100));
|
||||||
$diskLimit = $this->disk * (1 + ($this->disk_overallocate / 100));
|
$diskLimit = $this->disk * (1 + ($this->disk_overallocate / 100));
|
||||||
|
$cpuLimit = $this->cpu * (1 + ($this->cpu_overallocate / 100));
|
||||||
|
|
||||||
return ($this->sum_memory + $memory) <= $memoryLimit && ($this->sum_disk + $disk) <= $diskLimit;
|
return ($this->sum_memory + $memory) <= $memoryLimit && ($this->sum_disk + $disk) <= $diskLimit && ($this->sum_cpu + $cpu) <= $cpuLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getForServerCreation()
|
public static function getForServerCreation()
|
||||||
|
@ -10,8 +10,20 @@ use App\Exceptions\Service\Deployment\NoViableNodeException;
|
|||||||
|
|
||||||
class FindViableNodesService
|
class FindViableNodesService
|
||||||
{
|
{
|
||||||
protected ?int $disk = null;
|
|
||||||
protected ?int $memory = null;
|
protected ?int $memory = null;
|
||||||
|
protected ?int $disk = null;
|
||||||
|
protected ?int $cpu = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the amount of memory that this server will be using. As with disk space, nodes that
|
||||||
|
* do not have enough free memory will be filtered out.
|
||||||
|
*/
|
||||||
|
public function setMemory(int $memory): self
|
||||||
|
{
|
||||||
|
$this->memory = $memory;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the amount of disk that will be used by the server being created. Nodes will be
|
* Set the amount of disk that will be used by the server being created. Nodes will be
|
||||||
@ -26,12 +38,13 @@ class FindViableNodesService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the amount of memory that this server will be using. As with disk space, nodes that
|
* Set the amount of cpu that will be used by the server being created. Nodes will be
|
||||||
* do not have enough free memory will be filtered out.
|
* filtered out if they do not have enough available free cpu for this server
|
||||||
|
* to be placed on.
|
||||||
*/
|
*/
|
||||||
public function setMemory(int $memory): self
|
public function setCpu(int $cpu): self
|
||||||
{
|
{
|
||||||
$this->memory = $memory;
|
$this->cpu = $cpu;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -41,8 +54,8 @@ class FindViableNodesService
|
|||||||
* be passed to the AllocationSelectionService to return a single allocation.
|
* be passed to the AllocationSelectionService to return a single allocation.
|
||||||
*
|
*
|
||||||
* This functionality is used for automatic deployments of servers and will
|
* This functionality is used for automatic deployments of servers and will
|
||||||
* attempt to find all nodes in the defined locations that meet the disk and
|
* attempt to find all nodes in the defined locations that meet the memory, disk
|
||||||
* memory availability requirements. Any nodes not meeting those requirements
|
* and cpu availability requirements. Any nodes not meeting those requirements
|
||||||
* are tossed out, as are any nodes marked as non-public, meaning automatic
|
* are tossed out, as are any nodes marked as non-public, meaning automatic
|
||||||
* deployments should not be done against them.
|
* deployments should not be done against them.
|
||||||
*
|
*
|
||||||
@ -55,18 +68,21 @@ class FindViableNodesService
|
|||||||
*/
|
*/
|
||||||
public function handle(int $perPage = null, int $page = null): LengthAwarePaginator|Collection
|
public function handle(int $perPage = null, int $page = null): LengthAwarePaginator|Collection
|
||||||
{
|
{
|
||||||
Assert::integer($this->disk, 'Disk space must be an int, got %s');
|
|
||||||
Assert::integer($this->memory, 'Memory usage must be an int, got %s');
|
Assert::integer($this->memory, 'Memory usage must be an int, got %s');
|
||||||
|
Assert::integer($this->disk, 'Disk space must be an int, got %s');
|
||||||
|
Assert::integer($this->cpu, 'CPU must be an int, got %s');
|
||||||
|
|
||||||
$query = Node::query()->select('nodes.*')
|
$query = Node::query()->select('nodes.*')
|
||||||
->selectRaw('IFNULL(SUM(servers.memory), 0) as sum_memory')
|
->selectRaw('IFNULL(SUM(servers.memory), 0) as sum_memory')
|
||||||
->selectRaw('IFNULL(SUM(servers.disk), 0) as sum_disk')
|
->selectRaw('IFNULL(SUM(servers.disk), 0) as sum_disk')
|
||||||
|
->selectRaw('IFNULL(SUM(servers.cpu), 0) as sum_cpu')
|
||||||
->leftJoin('servers', 'servers.node_id', '=', 'nodes.id')
|
->leftJoin('servers', 'servers.node_id', '=', 'nodes.id')
|
||||||
->where('nodes.public', 1);
|
->where('nodes.public', 1);
|
||||||
|
|
||||||
$results = $query->groupBy('nodes.id')
|
$results = $query->groupBy('nodes.id')
|
||||||
->havingRaw('(IFNULL(SUM(servers.memory), 0) + ?) <= (nodes.memory * (1 + (nodes.memory_overallocate / 100)))', [$this->memory])
|
->havingRaw('(IFNULL(SUM(servers.memory), 0) + ?) <= (nodes.memory * (1 + (nodes.memory_overallocate / 100)))', [$this->memory])
|
||||||
->havingRaw('(IFNULL(SUM(servers.disk), 0) + ?) <= (nodes.disk * (1 + (nodes.disk_overallocate / 100)))', [$this->disk]);
|
->havingRaw('(IFNULL(SUM(servers.disk), 0) + ?) <= (nodes.disk * (1 + (nodes.disk_overallocate / 100)))', [$this->disk])
|
||||||
|
->havingRaw('(IFNULL(SUM(servers.cpu), 0) + ?) <= (nodes.cpu * (1 + (nodes.cpu_overallocate / 100)))', [$this->cpu]);
|
||||||
|
|
||||||
if (!is_null($page)) {
|
if (!is_null($page)) {
|
||||||
$results = $results->paginate($perPage ?? 50, ['*'], 'page', $page);
|
$results = $results->paginate($perPage ?? 50, ['*'], 'page', $page);
|
||||||
|
@ -111,8 +111,9 @@ class ServerCreationService
|
|||||||
{
|
{
|
||||||
/** @var \Illuminate\Support\Collection $nodes */
|
/** @var \Illuminate\Support\Collection $nodes */
|
||||||
$nodes = $this->findViableNodesService
|
$nodes = $this->findViableNodesService
|
||||||
->setDisk(Arr::get($data, 'disk'))
|
|
||||||
->setMemory(Arr::get($data, 'memory'))
|
->setMemory(Arr::get($data, 'memory'))
|
||||||
|
->setDisk(Arr::get($data, 'disk'))
|
||||||
|
->setCpu(Arr::get($data, 'cpu'))
|
||||||
->handle();
|
->handle();
|
||||||
|
|
||||||
return $this->allocationSelectionService->setDedicated($deployment->isDedicated())
|
return $this->allocationSelectionService->setDedicated($deployment->isDedicated())
|
||||||
|
@ -57,13 +57,13 @@ class TransferServerService
|
|||||||
|
|
||||||
// Check if the node is viable for the transfer.
|
// Check if the node is viable for the transfer.
|
||||||
$node = Node::query()
|
$node = Node::query()
|
||||||
->select(['nodes.id', 'nodes.fqdn', 'nodes.scheme', 'nodes.daemon_token', 'nodes.daemon_listen', 'nodes.memory', 'nodes.disk', 'nodes.memory_overallocate', 'nodes.disk_overallocate'])
|
->select(['nodes.id', 'nodes.fqdn', 'nodes.scheme', 'nodes.daemon_token', 'nodes.daemon_listen', 'nodes.memory', 'nodes.disk', 'nodes.cpu', 'nodes.memory_overallocate', 'nodes.disk_overallocate', 'nodes.cpu_overallocate'])
|
||||||
->selectRaw('IFNULL(SUM(servers.memory), 0) as sum_memory, IFNULL(SUM(servers.disk), 0) as sum_disk')
|
->selectRaw('IFNULL(SUM(servers.memory), 0) as sum_memory, IFNULL(SUM(servers.disk), 0) as sum_disk, IFNULL(SUM(servers.cpu), 0) as sum_cpu')
|
||||||
->leftJoin('servers', 'servers.node_id', '=', 'nodes.id')
|
->leftJoin('servers', 'servers.node_id', '=', 'nodes.id')
|
||||||
->where('nodes.id', $node_id)
|
->where('nodes.id', $node_id)
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
if (!$node->isViable($server->memory, $server->disk)) {
|
if (!$node->isViable($server->memory, $server->disk, $server->cpu)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,11 +34,12 @@ class NodeTransformer extends BaseTransformer
|
|||||||
$response[$node->getUpdatedAtColumn()] = $this->formatTimestamp($node->updated_at);
|
$response[$node->getUpdatedAtColumn()] = $this->formatTimestamp($node->updated_at);
|
||||||
$response[$node->getCreatedAtColumn()] = $this->formatTimestamp($node->created_at);
|
$response[$node->getCreatedAtColumn()] = $this->formatTimestamp($node->created_at);
|
||||||
|
|
||||||
$resources = $node->servers()->select(['memory', 'disk'])->get();
|
$resources = $node->servers()->select(['memory', 'disk', 'cpu'])->get();
|
||||||
|
|
||||||
$response['allocated_resources'] = [
|
$response['allocated_resources'] = [
|
||||||
'memory' => $resources->sum('memory'),
|
'memory' => $resources->sum('memory'),
|
||||||
'disk' => $resources->sum('disk'),
|
'disk' => $resources->sum('disk'),
|
||||||
|
'cpu' => $resources->sum('cpu'),
|
||||||
];
|
];
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
|
@ -33,6 +33,8 @@ class NodeFactory extends Factory
|
|||||||
'memory_overallocate' => 0,
|
'memory_overallocate' => 0,
|
||||||
'disk' => 10240,
|
'disk' => 10240,
|
||||||
'disk_overallocate' => 0,
|
'disk_overallocate' => 0,
|
||||||
|
'cpu' => 100,
|
||||||
|
'cpu_overallocate' => 0,
|
||||||
'upload_size' => 100,
|
'upload_size' => 100,
|
||||||
'daemon_token_id' => Str::random(Node::DAEMON_TOKEN_ID_LENGTH),
|
'daemon_token_id' => Str::random(Node::DAEMON_TOKEN_ID_LENGTH),
|
||||||
'daemon_token' => Crypt::encrypt(Str::random(Node::DAEMON_TOKEN_LENGTH)),
|
'daemon_token' => Crypt::encrypt(Str::random(Node::DAEMON_TOKEN_LENGTH)),
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('nodes', function (Blueprint $table) {
|
||||||
|
$table->unsignedInteger('cpu')->default(0)->after('disk_overallocate');
|
||||||
|
$table->integer('cpu_overallocate')->default(0)->after('cpu');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('nodes', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('cpu');
|
||||||
|
$table->dropColumn('cpu_overallocate');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@ -359,6 +359,8 @@ CREATE TABLE `nodes` (
|
|||||||
`memory_overallocate` int NOT NULL DEFAULT '0',
|
`memory_overallocate` int NOT NULL DEFAULT '0',
|
||||||
`disk` int unsigned NOT NULL,
|
`disk` int unsigned NOT NULL,
|
||||||
`disk_overallocate` int NOT NULL DEFAULT '0',
|
`disk_overallocate` int NOT NULL DEFAULT '0',
|
||||||
|
`cpu` int unsigned NOT NULL DEFAULT '0',
|
||||||
|
`cpu_overallocate` int NOT NULL DEFAULT '0',
|
||||||
`upload_size` int unsigned NOT NULL DEFAULT '100',
|
`upload_size` int unsigned NOT NULL DEFAULT '100',
|
||||||
`daemon_token_id` char(16) COLLATE utf8mb4_unicode_ci NOT NULL,
|
`daemon_token_id` char(16) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||||
`daemon_token` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
`daemon_token` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||||
@ -845,3 +847,4 @@ INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (198,'2024_03_14_05
|
|||||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (201,'2024_04_20_214441_add_egg_var_sort',3);
|
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (201,'2024_04_20_214441_add_egg_var_sort',3);
|
||||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (203,'2024_04_14_002250_update_column_names',4);
|
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (203,'2024_04_14_002250_update_column_names',4);
|
||||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (204,'2024_05_08_094823_rename_oom_disabled_column_to_oom_killer',1);
|
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (204,'2024_05_08_094823_rename_oom_disabled_column_to_oom_killer',1);
|
||||||
|
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (205,'2024_05_16_091207_add_cpu_columns_to_nodes_table',1);
|
||||||
|
@ -31,7 +31,9 @@ return [
|
|||||||
'memory' => 'Enter the maximum amount of memory',
|
'memory' => 'Enter the maximum amount of memory',
|
||||||
'memory_overallocate' => 'Enter the amount of memory to over allocate by, -1 will disable checking and 0 will prevent creating new servers',
|
'memory_overallocate' => 'Enter the amount of memory to over allocate by, -1 will disable checking and 0 will prevent creating new servers',
|
||||||
'disk' => 'Enter the maximum amount of disk space',
|
'disk' => 'Enter the maximum amount of disk space',
|
||||||
'disk_overallocate' => 'Enter the amount of memory to over allocate by, -1 will disable checking and 0 will prevent creating new server',
|
'disk_overallocate' => 'Enter the amount of disk to over allocate by, -1 will disable checking and 0 will prevent creating new server',
|
||||||
|
'cpu' => 'Enter the maximum amount of cpu',
|
||||||
|
'cpu_overallocate' => 'Enter the amount of cpu to over allocate by, -1 will disable checking and 0 will prevent creating new server',
|
||||||
'upload_size' => "'Enter the maximum filesize upload",
|
'upload_size' => "'Enter the maximum filesize upload",
|
||||||
'daemonListen' => 'Enter the daemon listening port',
|
'daemonListen' => 'Enter the daemon listening port',
|
||||||
'daemonSFTP' => 'Enter the daemon SFTP listening port',
|
'daemonSFTP' => 'Enter the daemon SFTP listening port',
|
||||||
|
@ -19,20 +19,28 @@ class FindViableNodesServiceTest extends IntegrationTestCase
|
|||||||
Node::query()->delete();
|
Node::query()->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testExceptionIsThrownIfNoDiskSpaceHasBeenSet(): void
|
|
||||||
{
|
|
||||||
$this->expectException(\InvalidArgumentException::class);
|
|
||||||
$this->expectExceptionMessage('Disk space must be an int, got NULL');
|
|
||||||
|
|
||||||
$this->getService()->handle();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testExceptionIsThrownIfNoMemoryHasBeenSet(): void
|
public function testExceptionIsThrownIfNoMemoryHasBeenSet(): void
|
||||||
{
|
{
|
||||||
$this->expectException(\InvalidArgumentException::class);
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
$this->expectExceptionMessage('Memory usage must be an int, got NULL');
|
$this->expectExceptionMessage('Memory usage must be an int, got NULL');
|
||||||
|
|
||||||
$this->getService()->setDisk(10)->handle();
|
$this->getService()->setDisk(10)->setCpu(10)->handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testExceptionIsThrownIfNoDiskSpaceHasBeenSet(): void
|
||||||
|
{
|
||||||
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('Disk space must be an int, got NULL');
|
||||||
|
|
||||||
|
$this->getService()->setMemory(10)->setCpu(10)->handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testExceptionIsThrownIfNoCpuHasBeenSet(): void
|
||||||
|
{
|
||||||
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('CPU must be an int, got NULL');
|
||||||
|
|
||||||
|
$this->getService()->setMemory(10)->setDisk(10)->handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getService(): FindViableNodesService
|
private function getService(): FindViableNodesService
|
||||||
|
Loading…
x
Reference in New Issue
Block a user