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->table([], [
['Panel Version', $this->versionService->versionData()['version']],
['Latest Version', $this->versionService->getPanel()],
['Panel Version', $this->versionService->currentPanelVersion()],
['Latest Version', $this->versionService->latestPanelVersion()],
['Up-to-Date', $this->versionService->isLatestPanel() ? 'Yes' : $this->formatText('No', 'bg=red')],
], 'compact');

View File

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

View File

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

View File

@ -2,146 +2,71 @@
namespace App\Services\Helpers;
use GuzzleHttp\Client;
use Carbon\CarbonImmutable;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Arr;
use Illuminate\Contracts\Cache\Repository as CacheRepository;
use Exception;
use Illuminate\Support\Facades\Http;
class SoftwareVersionService
{
public const VERSION_CACHE_KEY = 'panel:versioning_data';
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
public function latestPanelVersion(): 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';
}
});
}
/**
* Get the latest version of the daemon from the CDN servers.
*/
public function getDaemon(): string
public function latestWingsVersion(): 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
{
if (config('app.version') === 'canary') {
return true;
}
return version_compare(config('app.version'), $this->getPanel()) >= 0;
return version_compare(config('app.version'), $this->latestPanelVersion()) >= 0;
}
/**
* Determine if a passed daemon version string is the latest.
*/
public function isLatestDaemon(string $version): bool
public function isLatestWings(string $version): bool
{
if ($version === 'develop') {
return true;
}
return version_compare($version, $this->getDaemon()) >= 0;
return version_compare($version, $this->latestWingsVersion()) >= 0;
}
/**
* Keeps the versioning cache up-to-date with the latest results from the CDN.
*/
protected function cacheVersionData(): array
public function currentPanelVersion(): string
{
return $this->cache->remember(self::VERSION_CACHE_KEY, CarbonImmutable::now()->addMinutes(config('panel.cdn.cache_time', 60)), 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 () {
return cache()->remember('panel:current_version', now()->addMinutes(5), function () {
if (file_exists(base_path('.git/HEAD'))) {
$head = explode(' ', file_get_contents(base_path('.git/HEAD')));
if (array_key_exists(1, $head)) {
$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 [
'version' => 'canary (' . substr(file_get_contents($path), 0, 8) . ')',
'is_git' => true,
];
}
return [
'version' => config('app.version'),
'is_git' => false,
];
return config('app.version');
});
}
}

View File

@ -31,7 +31,7 @@
@else
Your panel is <strong>not up-to-date!</strong> The latest version is
<a>
<code>{{ $version->getPanel() }}</code>
<code>{{ $version->latestPanelVersion() }}</code>
</a>
and you are currently running version <code>{{ config('app.version') }}</code>.
@endif
@ -41,7 +41,7 @@
</div>
<div class="row">
<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 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>
@ -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>
</div>
<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>
@endsection

View File

@ -39,7 +39,7 @@
<table class="table table-hover">
<tr>
<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>
<td>System Information</td>