Allow sendCommand on Starting
or Running
Server
s (#1061)
* Replace `string` with `enum` * Add title * Allow sendCommand on `Starting` or `Running` servers * refactor: Use Filament interfaces * Use `getLabel` instead of `str->headline` Co-authored-by: Boy132 <Boy132@users.noreply.github.com> --------- Co-authored-by: Boy132 <Boy132@users.noreply.github.com>
This commit is contained in:
parent
a9e4495c91
commit
1fdc428f3e
@ -2,7 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Enums;
|
namespace App\Enums;
|
||||||
|
|
||||||
enum ContainerStatus: string
|
use Filament\Support\Contracts\HasColor;
|
||||||
|
use Filament\Support\Contracts\HasIcon;
|
||||||
|
use Filament\Support\Contracts\HasLabel;
|
||||||
|
|
||||||
|
enum ContainerStatus: string implements HasColor, HasIcon, HasLabel
|
||||||
{
|
{
|
||||||
// Docker Based
|
// Docker Based
|
||||||
case Created = 'created';
|
case Created = 'created';
|
||||||
@ -19,7 +23,7 @@ enum ContainerStatus: string
|
|||||||
// HTTP Based
|
// HTTP Based
|
||||||
case Missing = 'missing';
|
case Missing = 'missing';
|
||||||
|
|
||||||
public function icon(): string
|
public function getIcon(): string
|
||||||
{
|
{
|
||||||
return match ($this) {
|
return match ($this) {
|
||||||
|
|
||||||
@ -36,8 +40,17 @@ enum ContainerStatus: string
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public function color(): string
|
public function getColor(bool $hex = false): string
|
||||||
{
|
{
|
||||||
|
if ($hex) {
|
||||||
|
return match ($this) {
|
||||||
|
self::Created, self::Restarting => '#2563EB',
|
||||||
|
self::Starting, self::Paused, self::Removing, self::Stopping => '#D97706',
|
||||||
|
self::Running => '#22C55E',
|
||||||
|
self::Exited, self::Missing, self::Dead, self::Offline => '#EF4444',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return match ($this) {
|
return match ($this) {
|
||||||
self::Created => 'primary',
|
self::Created => 'primary',
|
||||||
self::Starting => 'warning',
|
self::Starting => 'warning',
|
||||||
@ -53,14 +66,19 @@ enum ContainerStatus: string
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public function colorHex(): string
|
public function getLabel(): string
|
||||||
{
|
{
|
||||||
return match ($this) {
|
return str($this->value)->title();
|
||||||
self::Created, self::Restarting => '#2563EB',
|
}
|
||||||
self::Starting, self::Paused, self::Removing, self::Stopping => '#D97706',
|
|
||||||
self::Running => '#22C55E',
|
public function isOffline(): bool
|
||||||
self::Exited, self::Missing, self::Dead, self::Offline => '#EF4444',
|
{
|
||||||
};
|
return in_array($this, [ContainerStatus::Offline, ContainerStatus::Missing]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isStartingOrRunning(): bool
|
||||||
|
{
|
||||||
|
return in_array($this, [ContainerStatus::Starting, ContainerStatus::Running]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isStartingOrStopping(): bool
|
public function isStartingOrStopping(): bool
|
||||||
|
@ -2,7 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Enums;
|
namespace App\Enums;
|
||||||
|
|
||||||
enum ServerState: string
|
use Filament\Support\Contracts\HasColor;
|
||||||
|
use Filament\Support\Contracts\HasIcon;
|
||||||
|
use Filament\Support\Contracts\HasLabel;
|
||||||
|
|
||||||
|
enum ServerState: string implements HasColor, HasIcon, HasLabel
|
||||||
{
|
{
|
||||||
case Normal = 'normal';
|
case Normal = 'normal';
|
||||||
case Installing = 'installing';
|
case Installing = 'installing';
|
||||||
@ -11,7 +15,7 @@ enum ServerState: string
|
|||||||
case Suspended = 'suspended';
|
case Suspended = 'suspended';
|
||||||
case RestoringBackup = 'restoring_backup';
|
case RestoringBackup = 'restoring_backup';
|
||||||
|
|
||||||
public function icon(): string
|
public function getIcon(): string
|
||||||
{
|
{
|
||||||
return match ($this) {
|
return match ($this) {
|
||||||
self::Normal => 'tabler-heart',
|
self::Normal => 'tabler-heart',
|
||||||
@ -23,7 +27,7 @@ enum ServerState: string
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public function color(): string
|
public function getColor(): string
|
||||||
{
|
{
|
||||||
return match ($this) {
|
return match ($this) {
|
||||||
self::Normal => 'primary',
|
self::Normal => 'primary',
|
||||||
@ -34,4 +38,9 @@ enum ServerState: string
|
|||||||
self::RestoringBackup => 'primary',
|
self::RestoringBackup => 'primary',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getLabel(): string
|
||||||
|
{
|
||||||
|
return str($this->value)->headline();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
namespace App\Filament\Admin\Resources\ServerResource\Pages;
|
namespace App\Filament\Admin\Resources\ServerResource\Pages;
|
||||||
|
|
||||||
use App\Enums\ContainerStatus;
|
|
||||||
use App\Enums\ServerState;
|
|
||||||
use App\Enums\SuspendAction;
|
use App\Enums\SuspendAction;
|
||||||
use App\Filament\Admin\Resources\ServerResource;
|
use App\Filament\Admin\Resources\ServerResource;
|
||||||
use App\Filament\Admin\Resources\ServerResource\RelationManagers\AllocationsRelationManager;
|
use App\Filament\Admin\Resources\ServerResource\RelationManagers\AllocationsRelationManager;
|
||||||
@ -127,16 +125,9 @@ class EditServer extends EditRecord
|
|||||||
ToggleButtons::make('condition')
|
ToggleButtons::make('condition')
|
||||||
->label(trans('admin/server.server_status'))
|
->label(trans('admin/server.server_status'))
|
||||||
->formatStateUsing(fn (Server $server) => $server->condition)
|
->formatStateUsing(fn (Server $server) => $server->condition)
|
||||||
->options(fn ($state) => collect(array_merge(ContainerStatus::cases(), ServerState::cases()))
|
->options(fn ($state) => [$state->value => $state->getLabel()])
|
||||||
->filter(fn ($condition) => $condition->value === $state)
|
->colors(fn ($state) => [$state->value => $state->getColor()])
|
||||||
->mapWithKeys(fn ($state) => [$state->value => str($state->value)->replace('_', ' ')->ucwords()])
|
->icons(fn ($state) => [$state->value => $state->getIcon()])
|
||||||
)
|
|
||||||
->colors(collect(array_merge(ContainerStatus::cases(), ServerState::cases()))->mapWithKeys(
|
|
||||||
fn ($status) => [$status->value => $status->color()]
|
|
||||||
))
|
|
||||||
->icons(collect(array_merge(ContainerStatus::cases(), ServerState::cases()))->mapWithKeys(
|
|
||||||
fn ($status) => [$status->value => $status->icon()]
|
|
||||||
))
|
|
||||||
->columnSpan([
|
->columnSpan([
|
||||||
'default' => 2,
|
'default' => 2,
|
||||||
'sm' => 1,
|
'sm' => 1,
|
||||||
|
@ -34,8 +34,8 @@ class ListServers extends ListRecords
|
|||||||
->label(trans('admin/server.condition'))
|
->label(trans('admin/server.condition'))
|
||||||
->default('unknown')
|
->default('unknown')
|
||||||
->badge()
|
->badge()
|
||||||
->icon(fn (Server $server) => $server->conditionIcon())
|
->icon(fn (Server $server) => $server->condition->getIcon())
|
||||||
->color(fn (Server $server) => $server->conditionColor()),
|
->color(fn (Server $server) => $server->condition->getColor()),
|
||||||
TextColumn::make('uuid')
|
TextColumn::make('uuid')
|
||||||
->hidden()
|
->hidden()
|
||||||
->label('UUID')
|
->label('UUID')
|
||||||
|
@ -75,7 +75,7 @@ class ServerConsole extends Widget
|
|||||||
|
|
||||||
protected function canSendCommand(): bool
|
protected function canSendCommand(): bool
|
||||||
{
|
{
|
||||||
return $this->authorizeSendCommand() && !$this->server->isInConflictState() && $this->server->retrieveStatus() === 'running';
|
return $this->authorizeSendCommand() && !$this->server->isInConflictState() && $this->server->retrieveStatus()->isStartingOrRunning();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function up(): void
|
public function up(): void
|
||||||
|
@ -9,7 +9,6 @@ use App\Models\Server;
|
|||||||
use Carbon\CarbonInterface;
|
use Carbon\CarbonInterface;
|
||||||
use Filament\Widgets\StatsOverviewWidget;
|
use Filament\Widgets\StatsOverviewWidget;
|
||||||
use Illuminate\Support\Number;
|
use Illuminate\Support\Number;
|
||||||
use Illuminate\Support\Str;
|
|
||||||
|
|
||||||
class ServerOverview extends StatsOverviewWidget
|
class ServerOverview extends StatsOverviewWidget
|
||||||
{
|
{
|
||||||
@ -38,7 +37,7 @@ class ServerOverview extends StatsOverviewWidget
|
|||||||
|
|
||||||
private function status(): string
|
private function status(): string
|
||||||
{
|
{
|
||||||
$status = Str::title($this->server->condition);
|
$status = $this->server->condition->getLabel();
|
||||||
$uptime = collect(cache()->get("servers.{$this->server->id}.uptime"))->last() ?? 0;
|
$uptime = collect(cache()->get("servers.{$this->server->id}.uptime"))->last() ?? 0;
|
||||||
|
|
||||||
if ($uptime === 0) {
|
if ($uptime === 0) {
|
||||||
@ -52,10 +51,10 @@ class ServerOverview extends StatsOverviewWidget
|
|||||||
|
|
||||||
public function cpuUsage(): string
|
public function cpuUsage(): string
|
||||||
{
|
{
|
||||||
$status = ContainerStatus::tryFrom($this->server->retrieveStatus());
|
$status = $this->server->retrieveStatus();
|
||||||
|
|
||||||
if ($status === ContainerStatus::Offline || $status === ContainerStatus::Missing) {
|
if ($status->isOffline()) {
|
||||||
return 'Offline';
|
return ContainerStatus::Offline->getLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = collect(cache()->get("servers.{$this->server->id}.cpu_absolute"))->last(default: 0);
|
$data = collect(cache()->get("servers.{$this->server->id}.cpu_absolute"))->last(default: 0);
|
||||||
@ -66,10 +65,10 @@ class ServerOverview extends StatsOverviewWidget
|
|||||||
|
|
||||||
public function memoryUsage(): string
|
public function memoryUsage(): string
|
||||||
{
|
{
|
||||||
$status = ContainerStatus::tryFrom($this->server->retrieveStatus());
|
$status = $this->server->retrieveStatus();
|
||||||
|
|
||||||
if ($status === ContainerStatus::Offline || $status === ContainerStatus::Missing) {
|
if ($status->isOffline()) {
|
||||||
return 'Offline';
|
return ContainerStatus::Offline->getLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
$latestMemoryUsed = collect(cache()->get("servers.{$this->server->id}.memory_bytes"))->last(default: 0);
|
$latestMemoryUsed = collect(cache()->get("servers.{$this->server->id}.memory_bytes"))->last(default: 0);
|
||||||
|
@ -114,7 +114,7 @@ use App\Services\Subusers\SubuserDeletionService;
|
|||||||
*
|
*
|
||||||
* @property string[]|null $docker_labels
|
* @property string[]|null $docker_labels
|
||||||
* @property string|null $ports
|
* @property string|null $ports
|
||||||
* @property-read mixed $condition
|
* @property-read ContainerStatus|ServerState $condition
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\EggVariable> $eggVariables
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\EggVariable> $eggVariables
|
||||||
* @property-read int|null $egg_variables_count
|
* @property-read int|null $egg_variables_count
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ServerVariable> $serverVariables
|
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ServerVariable> $serverVariables
|
||||||
@ -438,17 +438,17 @@ class Server extends Model implements Validatable
|
|||||||
])->toPsrResponse();
|
])->toPsrResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function retrieveStatus(): string
|
public function retrieveStatus(): ContainerStatus
|
||||||
{
|
{
|
||||||
$status = cache()->get("servers.$this->uuid.container.status");
|
$status = cache()->get("servers.$this->uuid.container.status");
|
||||||
|
|
||||||
if ($status) {
|
if ($status === null) {
|
||||||
return $status;
|
$this->node->serverStatuses();
|
||||||
|
|
||||||
|
$status = cache()->get("servers.$this->uuid.container.status");
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->node->serverStatuses();
|
return ContainerStatus::tryFrom($status) ?? ContainerStatus::Missing;
|
||||||
|
|
||||||
return cache()->get("servers.$this->uuid.container.status") ?? 'missing';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -474,7 +474,7 @@ class Server extends Model implements Validatable
|
|||||||
return 'Suspended';
|
return 'Suspended';
|
||||||
}
|
}
|
||||||
if ($resourceAmount === 0) {
|
if ($resourceAmount === 0) {
|
||||||
return 'Offline';
|
return ContainerStatus::Offline->getLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
return now()->subMillis($resourceAmount)->diffForHumans(syntax: CarbonInterface::DIFF_ABSOLUTE, short: true, parts: 4);
|
return now()->subMillis($resourceAmount)->diffForHumans(syntax: CarbonInterface::DIFF_ABSOLUTE, short: true, parts: 4);
|
||||||
@ -499,34 +499,7 @@ class Server extends Model implements Validatable
|
|||||||
public function condition(): Attribute
|
public function condition(): Attribute
|
||||||
{
|
{
|
||||||
return Attribute::make(
|
return Attribute::make(
|
||||||
get: fn () => $this->isSuspended() ? ServerState::Suspended->value : $this->status->value ?? $this->retrieveStatus(),
|
get: fn () => $this->isSuspended() ? ServerState::Suspended : $this->status ?? $this->retrieveStatus(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function conditionIcon(): string
|
|
||||||
{
|
|
||||||
if ($this->status === null) {
|
|
||||||
$containerStatus = ContainerStatus::from($this->retrieveStatus());
|
|
||||||
|
|
||||||
return $containerStatus->icon();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->status->icon();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function conditionColor(): string
|
|
||||||
{
|
|
||||||
if ($this->status === null) {
|
|
||||||
$containerStatus = ContainerStatus::from($this->retrieveStatus());
|
|
||||||
|
|
||||||
return $containerStatus->color();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->status->color();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function conditionColorHex(): string
|
|
||||||
{
|
|
||||||
return ContainerStatus::from($this->retrieveStatus())->colorHex();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Services\Schedules;
|
namespace App\Services\Schedules;
|
||||||
|
|
||||||
|
use App\Enums\ContainerStatus;
|
||||||
use App\Models\Task;
|
use App\Models\Task;
|
||||||
use Exception;
|
use Exception;
|
||||||
use App\Models\Schedule;
|
use App\Models\Schedule;
|
||||||
@ -41,10 +42,10 @@ class ProcessScheduleService
|
|||||||
// Check that the server is currently in a starting or running state before executing
|
// Check that the server is currently in a starting or running state before executing
|
||||||
// this schedule if this option has been set.
|
// this schedule if this option has been set.
|
||||||
try {
|
try {
|
||||||
$details = $this->serverRepository->setServer($schedule->server)->getDetails();
|
$state = fluent($this->serverRepository->setServer($schedule->server)->getDetails())->get('state') ?? ContainerStatus::Offline;
|
||||||
$state = $details['state'] ?? 'offline';
|
|
||||||
// If the server is stopping or offline just do nothing with this task.
|
// If the server is stopping or offline just do nothing with this task.
|
||||||
if (in_array($state, ['offline', 'stopping'])) {
|
if ($state->isOffline()) {
|
||||||
$job->failed();
|
$job->failed();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<!-- Status Strip Outside the Box -->
|
<!-- Status Strip Outside the Box -->
|
||||||
<div
|
<div
|
||||||
class="absolute left-0 top-1 bottom-0 w-1 rounded-lg"
|
class="absolute left-0 top-1 bottom-0 w-1 rounded-lg"
|
||||||
style="background-color: {{ $server->conditionColorHex() }};">
|
style="background-color: {{ $server->condition->getColor(true) }};">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Card Component -->
|
<!-- Card Component -->
|
||||||
@ -26,9 +26,9 @@
|
|||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="flex items-center mb-5 gap-2">
|
<div class="flex items-center mb-5 gap-2">
|
||||||
<x-filament::icon-button
|
<x-filament::icon-button
|
||||||
:icon="$server->conditionIcon()"
|
:icon="$server->condition->getIcon()"
|
||||||
:color="$server->conditionColor()"
|
:color="$server->condition->getColor()"
|
||||||
:tooltip="\Illuminate\Support\Str::title($server->condition)"
|
:tooltip="$server->condition->getLabel()"
|
||||||
size="xl"
|
size="xl"
|
||||||
/>
|
/>
|
||||||
<h2 class="text-xl font-bold">
|
<h2 class="text-xl font-bold">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user