mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
fix(logs): show container lookup errors and reload containers after status checks
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
e62658467f
commit
d59bcf5ae3
@@ -28,6 +28,9 @@ class Logs extends Component
|
||||
|
||||
public array $serverContainers = [];
|
||||
|
||||
/** @var array<int, string> */
|
||||
public array $serverErrors = [];
|
||||
|
||||
public $container = [];
|
||||
|
||||
public $parameters;
|
||||
@@ -47,7 +50,7 @@ class Logs extends Component
|
||||
$teamId = auth()->user()->currentTeam()->id;
|
||||
|
||||
return [
|
||||
"echo-private:team.{$teamId},ServiceChecked" => '$refresh',
|
||||
"echo-private:team.{$teamId},ServiceChecked" => 'loadAllContainers',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -55,6 +58,7 @@ class Logs extends Component
|
||||
{
|
||||
try {
|
||||
foreach ($this->servers as $server) {
|
||||
unset($this->serverErrors[$server->id]);
|
||||
$this->serverContainers[$server->id] = $this->getContainersForServer($server);
|
||||
}
|
||||
$this->containersLoaded = true;
|
||||
@@ -107,7 +111,8 @@ class Logs extends Component
|
||||
|
||||
return [];
|
||||
} catch (\Exception $e) {
|
||||
// Log error but don't fail the entire operation
|
||||
// Keep the error for this server so the page does not report it as "no containers".
|
||||
$this->serverErrors[$server->id] = $e->getMessage();
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -56,6 +56,10 @@
|
||||
<x-empty size="lg" title="Runtime logs unavailable"
|
||||
description="No functional servers are available, so container logs cannot be loaded."
|
||||
icon-name="file-content" />
|
||||
@elseif (count($serverErrors) > 0)
|
||||
<x-empty size="lg" title="Runtime logs unavailable"
|
||||
description="Could not load containers: {{ collect($serverErrors)->first() }}"
|
||||
icon-name="file-content" />
|
||||
@else
|
||||
<x-empty size="lg" title="Runtime logs unavailable"
|
||||
description="No containers are running, so there are no runtime logs to show."
|
||||
@@ -68,6 +72,10 @@
|
||||
<x-callout type="warning" title="Server unavailable">
|
||||
{{ $server->name }} is not functional, so its container logs cannot be loaded.
|
||||
</x-callout>
|
||||
@elseif (isset($serverErrors[$server->id]))
|
||||
<x-callout type="warning" title="Could not load containers">
|
||||
{{ $server->name }}: {{ $serverErrors[$server->id] }}
|
||||
</x-callout>
|
||||
@elseif (isset($serverContainers[$server->id]) && count($serverContainers[$server->id]) > 0)
|
||||
@if ($servers->count() > 1)
|
||||
<div class="flex items-center gap-2 px-1">
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
use App\Livewire\Project\Shared\Logs;
|
||||
use App\Models\Application;
|
||||
use App\Models\Environment;
|
||||
use App\Models\Project;
|
||||
use App\Models\Server;
|
||||
use App\Models\Team;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
function runtimeLogsApplication(): array
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$team = Team::factory()->create();
|
||||
$user->teams()->attach($team, ['role' => 'owner']);
|
||||
test()->actingAs($user);
|
||||
session(['currentTeam' => $team]);
|
||||
|
||||
$server = Server::factory()->create(['team_id' => $team->id]);
|
||||
$server->settings->update(['is_reachable' => true, 'is_usable' => true]);
|
||||
$destination = $server->standaloneDockers()->firstOrFail();
|
||||
$environment = Environment::factory()->create([
|
||||
'project_id' => Project::factory()->create(['team_id' => $team->id])->id,
|
||||
]);
|
||||
$application = Application::factory()->create([
|
||||
'environment_id' => $environment->id,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_type' => $destination->getMorphClass(),
|
||||
]);
|
||||
|
||||
return [$team, $server, $application];
|
||||
}
|
||||
|
||||
it('reloads containers after a status check when the first load found none', function () {
|
||||
[$team, $server, $application] = runtimeLogsApplication();
|
||||
$server->settings->update(['is_swarm_manager' => true]);
|
||||
|
||||
$component = new Logs;
|
||||
$component->resource = $application;
|
||||
$component->servers = collect([$server]);
|
||||
|
||||
// The first load happened while no container was running (for example during a redeploy).
|
||||
$component->serverContainers = [$server->id => []];
|
||||
$component->containersLoaded = true;
|
||||
|
||||
$listener = $component->getListeners()["echo-private:team.{$team->id},ServiceChecked"];
|
||||
expect($listener)->toBe('loadAllContainers');
|
||||
|
||||
$component->{$listener}();
|
||||
|
||||
expect($component->serverContainers[$server->id])->toHaveCount(1)
|
||||
->and($component->serverContainers[$server->id][0]['Names'])->toBe($application->uuid.'_'.$application->uuid);
|
||||
});
|
||||
|
||||
it('keeps the container lookup error instead of reporting no running containers', function () {
|
||||
Storage::fake('ssh-keys');
|
||||
Storage::fake('ssh-mux');
|
||||
[, $server, $application] = runtimeLogsApplication();
|
||||
// A server without its private key fails the SSH lookup before any command runs.
|
||||
$server->updateQuietly(['private_key_id' => 999999]);
|
||||
|
||||
$component = new Logs;
|
||||
$component->resource = $application;
|
||||
$component->servers = collect([$server]);
|
||||
$component->loadAllContainers();
|
||||
|
||||
expect($component->serverContainers[$server->id])->toBe([])
|
||||
->and($component->serverErrors[$server->id])->toContain('No query results for model [App\\Models\\PrivateKey]');
|
||||
|
||||
$html = view('livewire.project.shared.logs', [
|
||||
'type' => null,
|
||||
'resource' => $application,
|
||||
'servers' => $component->servers,
|
||||
'serverContainers' => $component->serverContainers,
|
||||
'serverErrors' => $component->serverErrors,
|
||||
'containersLoaded' => true,
|
||||
])->render();
|
||||
|
||||
expect($html)->toContain('Could not load containers')
|
||||
->and($html)->toContain('No query results for model [App\\Models\\PrivateKey]')
|
||||
->and($html)->not->toContain('No containers are running');
|
||||
});
|
||||
Reference in New Issue
Block a user