Cleanup SoftwareVersionService (#704)

* cleanup SoftwareVersionService

* fix old admin area

* show latest wings version on EditNode page

* even more cleanup
This commit is contained in:
Boy132 2024-11-13 22:26:10 +01:00 committed by GitHub
parent 9491322d8c
commit 9717aa4b5f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 45 additions and 118 deletions

View File

@ -26,8 +26,8 @@ class InfoCommand extends Command
{ {
$this->output->title('Version Information'); $this->output->title('Version Information');
$this->table([], [ $this->table([], [
['Panel Version', $this->versionService->versionData()['version']], ['Panel Version', $this->versionService->currentPanelVersion()],
['Latest Version', $this->versionService->getPanel()], ['Latest Version', $this->versionService->latestPanelVersion()],
['Up-to-Date', $this->versionService->isLatestPanel() ? 'Yes' : $this->formatText('No', 'bg=red')], ['Up-to-Date', $this->versionService->isLatestPanel() ? 'Yes' : $this->formatText('No', 'bg=red')],
], 'compact'); ], 'compact');

View File

@ -2,6 +2,7 @@
namespace App\Filament\Pages; namespace App\Filament\Pages;
use App\Filament\Resources\NodeResource\Pages\CreateNode;
use App\Filament\Resources\NodeResource\Pages\ListNodes; use App\Filament\Resources\NodeResource\Pages\ListNodes;
use App\Models\Egg; use App\Models\Egg;
use App\Models\Node; use App\Models\Node;
@ -39,8 +40,8 @@ class Dashboard extends Page
{ {
return [ return [
'inDevelopment' => config('app.version') === 'canary', 'inDevelopment' => config('app.version') === 'canary',
'version' => $this->softwareVersionService->versionData()['version'], 'version' => $this->softwareVersionService->currentPanelVersion(),
'latestVersion' => $this->softwareVersionService->getPanel(), 'latestVersion' => $this->softwareVersionService->latestPanelVersion(),
'isLatest' => $this->softwareVersionService->isLatestPanel(), 'isLatest' => $this->softwareVersionService->isLatestPanel(),
'eggsCount' => Egg::query()->count(), 'eggsCount' => Egg::query()->count(),
'nodesList' => ListNodes::getUrl(), 'nodesList' => ListNodes::getUrl(),
@ -65,13 +66,13 @@ class Dashboard extends Page
CreateAction::make() CreateAction::make()
->label(trans('dashboard/index.sections.intro-first-node.button_label')) ->label(trans('dashboard/index.sections.intro-first-node.button_label'))
->icon('tabler-server-2') ->icon('tabler-server-2')
->url(route('filament.admin.resources.nodes.create')), ->url(CreateNode::getUrl()),
], ],
'supportActions' => [ 'supportActions' => [
CreateAction::make() CreateAction::make()
->label(trans('dashboard/index.sections.intro-support.button_donate')) ->label(trans('dashboard/index.sections.intro-support.button_donate'))
->icon('tabler-cash') ->icon('tabler-cash')
->url($this->softwareVersionService->getDonations(), true) ->url('https://pelican.dev/donate', true)
->color('success'), ->color('success'),
], ],
'helpActions' => [ 'helpActions' => [

View File

@ -4,6 +4,7 @@ namespace App\Filament\Resources\NodeResource\Pages;
use App\Filament\Resources\NodeResource; use App\Filament\Resources\NodeResource;
use App\Models\Node; use App\Models\Node;
use App\Services\Helpers\SoftwareVersionService;
use App\Services\Nodes\NodeAutoDeployService; use App\Services\Nodes\NodeAutoDeployService;
use App\Services\Nodes\NodeUpdateService; use App\Services\Nodes\NodeUpdateService;
use Filament\Actions; use Filament\Actions;
@ -55,7 +56,7 @@ class EditNode extends EditRecord
->schema([ ->schema([
Placeholder::make('') Placeholder::make('')
->label('Wings Version') ->label('Wings Version')
->content(fn (Node $node) => $node->systemInformation()['version'] ?? 'Unknown'), ->content(fn (Node $node, SoftwareVersionService $versionService) => ($node->systemInformation()['version'] ?? 'Unknown') . ' (Latest: ' . $versionService->latestWingsVersion() . ')'),
Placeholder::make('') Placeholder::make('')
->label('CPU Threads') ->label('CPU Threads')
->content(fn (Node $node) => $node->systemInformation()['cpu_count'] ?? 0), ->content(fn (Node $node) => $node->systemInformation()['cpu_count'] ?? 0),

View File

@ -2,146 +2,71 @@
namespace App\Services\Helpers; namespace App\Services\Helpers;
use GuzzleHttp\Client; use Exception;
use Carbon\CarbonImmutable; use Illuminate\Support\Facades\Http;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Arr;
use Illuminate\Contracts\Cache\Repository as CacheRepository;
class SoftwareVersionService class SoftwareVersionService
{ {
public const VERSION_CACHE_KEY = 'panel:versioning_data'; public function latestPanelVersion(): string
private static array $result;
/**
* SoftwareVersionService constructor.
*/
public function __construct(
protected CacheRepository $cache,
protected Client $client
) {
self::$result = $this->cacheVersionData();
}
/**
* Get the latest version of the panel from the CDN servers.
*/
public function getPanel(): string
{ {
return Arr::get(self::$result, 'panel') ?? 'error'; return cache()->remember('wings:latest_version', now()->addMinutes(config('panel.cdn.cache_time', 60)), function () {
try {
$response = Http::timeout(5)->connectTimeout(1)->get('https://api.github.com/repos/pelican-dev/panel/releases/latest')->throw()->json();
return trim($response['tag_name'], 'v');
} catch (Exception) {
return 'error';
}
});
} }
/** public function latestWingsVersion(): string
* Get the latest version of the daemon from the CDN servers.
*/
public function getDaemon(): string
{ {
return Arr::get(self::$result, 'daemon') ?? 'error'; return cache()->remember('wings:latest_version', now()->addMinutes(config('panel.cdn.cache_time', 60)), function () {
try {
$response = Http::timeout(5)->connectTimeout(1)->get('https://api.github.com/repos/pelican-dev/wings/releases/latest')->throw()->json();
return trim($response['tag_name'], 'v');
} catch (Exception) {
return 'error';
}
});
} }
/**
* Get the URL to the discord server.
*/
public function getDiscord(): string
{
return Arr::get(self::$result, 'discord') ?? 'https://pelican.dev/discord';
}
/**
* Get the donation URL.
*/
public function getDonations(): string
{
return Arr::get(self::$result, 'donate') ?? 'https://pelican.dev/donate';
}
/**
* Determine if the current version of the panel is the latest.
*/
public function isLatestPanel(): bool public function isLatestPanel(): bool
{ {
if (config('app.version') === 'canary') { if (config('app.version') === 'canary') {
return true; return true;
} }
return version_compare(config('app.version'), $this->getPanel()) >= 0; return version_compare(config('app.version'), $this->latestPanelVersion()) >= 0;
} }
/** public function isLatestWings(string $version): bool
* Determine if a passed daemon version string is the latest.
*/
public function isLatestDaemon(string $version): bool
{ {
if ($version === 'develop') { if ($version === 'develop') {
return true; return true;
} }
return version_compare($version, $this->getDaemon()) >= 0; return version_compare($version, $this->latestWingsVersion()) >= 0;
} }
/** public function currentPanelVersion(): string
* Keeps the versioning cache up-to-date with the latest results from the CDN.
*/
protected function cacheVersionData(): array
{ {
return $this->cache->remember(self::VERSION_CACHE_KEY, CarbonImmutable::now()->addMinutes(config('panel.cdn.cache_time', 60)), function () { return cache()->remember('panel:current_version', now()->addMinutes(5), function () {
$versionData = [];
try {
$response = $this->client->request('GET', 'https://api.github.com/repos/pelican-dev/panel/releases/latest',
[
'timeout' => config('panel.guzzle.timeout'),
'connect_timeout' => config('panel.guzzle.connect_timeout'),
]
);
if ($response->getStatusCode() === 200) {
$panelData = json_decode($response->getBody(), true);
$versionData['panel'] = trim($panelData['tag_name'], 'v');
}
$response = $this->client->request('GET', 'https://api.github.com/repos/pelican-dev/wings/releases/latest',
[
'timeout' => config('panel.guzzle.timeout'),
'connect_timeout' => config('panel.guzzle.connect_timeout'),
]
);
if ($response->getStatusCode() === 200) {
$wingsData = json_decode($response->getBody(), true);
$versionData['daemon'] = trim($wingsData['tag_name'], 'v');
}
} catch (GuzzleException $e) {
}
$versionData['discord'] = 'https://pelican.dev/discord';
$versionData['donate'] = 'https://pelican.dev/donate';
return $versionData;
});
}
public function versionData(): array
{
return cache()->remember('git-version', 5, function () {
if (file_exists(base_path('.git/HEAD'))) { if (file_exists(base_path('.git/HEAD'))) {
$head = explode(' ', file_get_contents(base_path('.git/HEAD'))); $head = explode(' ', file_get_contents(base_path('.git/HEAD')));
if (array_key_exists(1, $head)) { if (array_key_exists(1, $head)) {
$path = base_path('.git/' . trim($head[1])); $path = base_path('.git/' . trim($head[1]));
if (file_exists($path)) {
return 'canary (' . substr(file_get_contents($path), 0, 7) . ')';
}
} }
} }
if (isset($path) && file_exists($path)) { return config('app.version');
return [
'version' => 'canary (' . substr(file_get_contents($path), 0, 8) . ')',
'is_git' => true,
];
}
return [
'version' => config('app.version'),
'is_git' => false,
];
}); });
} }
} }

View File

@ -31,7 +31,7 @@
@else @else
Your panel is <strong>not up-to-date!</strong> The latest version is Your panel is <strong>not up-to-date!</strong> The latest version is
<a> <a>
<code>{{ $version->getPanel() }}</code> <code>{{ $version->latestPanelVersion() }}</code>
</a> </a>
and you are currently running version <code>{{ config('app.version') }}</code>. and you are currently running version <code>{{ config('app.version') }}</code>.
@endif @endif
@ -41,7 +41,7 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-xs-6 col-sm-3 text-center"> <div class="col-xs-6 col-sm-3 text-center">
<a href="{{ $version->getDiscord() }}"><button class="btn btn-warning" style="width:100%;"><i class="fa fa-fw fa-support"></i> Get Help <small>(via Discord)</small></button></a> <a href="https://pelican.dev/discord"><button class="btn btn-warning" style="width:100%;"><i class="fa fa-fw fa-support"></i> Get Help <small>(via Discord)</small></button></a>
</div> </div>
<div class="col-xs-6 col-sm-3 text-center"> <div class="col-xs-6 col-sm-3 text-center">
<a href="https://pelican.dev"><button class="btn btn-primary" style="width:100%;"><i class="fa fa-fw fa-link"></i> Documentation</button></a> <a href="https://pelican.dev"><button class="btn btn-primary" style="width:100%;"><i class="fa fa-fw fa-link"></i> Documentation</button></a>
@ -51,7 +51,7 @@
<a href="https://github.com/pelican-dev/panel"><button class="btn btn-primary" style="width:100%;"><i class="fa fa-fw fa-support"></i> Github</button></a> <a href="https://github.com/pelican-dev/panel"><button class="btn btn-primary" style="width:100%;"><i class="fa fa-fw fa-support"></i> Github</button></a>
</div> </div>
<div class="col-xs-6 col-sm-3 text-center"> <div class="col-xs-6 col-sm-3 text-center">
<a href="{{ $version->getDonations() }}"><button class="btn btn-success" style="width:100%;"><i class="fa fa-fw fa-money"></i> Support the Project</button></a> <a href="https://pelican.dev/donate"><button class="btn btn-success" style="width:100%;"><i class="fa fa-fw fa-money"></i> Support the Project</button></a>
</div> </div>
</div> </div>
@endsection @endsection

View File

@ -39,7 +39,7 @@
<table class="table table-hover"> <table class="table table-hover">
<tr> <tr>
<td>Daemon Version</td> <td>Daemon Version</td>
<td><code data-attr="info-version"><i class="fa fa-refresh fa-fw fa-spin"></i></code> (Latest: <code>{{ $version->getDaemon() }}</code>)</td> <td><code data-attr="info-version"><i class="fa fa-refresh fa-fw fa-spin"></i></code> (Latest: <code>{{ $version->currentWingsVersion() }}</code>)</td>
</tr> </tr>
<tr> <tr>
<td>System Information</td> <td>System Information</td>