fix(server): show the SSH error when a new private key cannot connect

Closes #7980

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai
2026-11-03 22:37:38 +01:00
co-authored by Claude Opus 5.5
parent e0ae59deca
commit b83b97f7e6
3 changed files with 26 additions and 7 deletions
+9 -3
View File
@@ -62,7 +62,7 @@ class Show extends Component
$this->server->save();
['uptime' => $uptime, 'error' => $error] = $this->server->validateConnection(justCheckingNewKey: true);
if (! $uptime) {
throw new \Exception($error);
throw new \Exception($this->unreachableMessage($error));
}
});
$this->loadPrivateKeys();
@@ -113,8 +113,7 @@ class Show extends Component
$this->dispatch('success', 'Server is reachable.');
$this->dispatch('refreshServerShow');
} else {
$sanitizedError = htmlspecialchars($error ?? '', ENT_QUOTES, 'UTF-8');
$this->dispatch('error', 'Server is not reachable.<br><br>Check this <a target="_blank" class="underline" href="https://coolify.io/docs/knowledge-base/server/openssh">documentation</a> for further help.<br><br>Error: '.$sanitizedError);
$this->dispatch('error', $this->unreachableMessage($error));
return;
}
@@ -123,6 +122,13 @@ class Show extends Component
}
}
private function unreachableMessage(?string $error): string
{
$sanitizedError = htmlspecialchars($error ?? '', ENT_QUOTES, 'UTF-8');
return 'Server is not reachable.<br><br>Check this <a target="_blank" class="underline" href="https://coolify.io/docs/knowledge-base/server/openssh">documentation</a> for further help.<br><br>Error: '.$sanitizedError;
}
public function render()
{
return view('livewire.server.private-key.show');
+1 -4
View File
@@ -2539,10 +2539,7 @@ $siteAddress {
return ['uptime' => true, 'error' => null];
} catch (\Throwable $e) {
if ($justCheckingNewKey) {
return ['uptime' => false, 'error' => 'This key is not valid for this server.'];
}
if ($this->settings->is_reachable === true) {
if (! $justCheckingNewKey && $this->settings->is_reachable === true) {
$this->settings->is_reachable = false;
$this->settings->save();
ServerReachabilityChanged::dispatch($this);
@@ -145,3 +145,19 @@ describe('after the user switches the session team', function () {
->and($keys->pluck('id'))->toContain($this->currentPrivateKey->id);
});
});
test('shows the SSH error when the new key cannot connect and keeps the old key', function () {
Process::fake(['*' => Process::result(errorOutput: 'root@host.docker.internal: Permission denied (publickey,password).', exitCode: 255)]);
Storage::fake('ssh-mux');
$newKey = PrivateKey::factory()->create([
'team_id' => $this->team->id,
'private_key' => PrivateKey::generateNewKeyPair('ed25519')['private_key'],
]);
Livewire::test(Show::class, ['server_uuid' => $this->server->uuid])
->call('setPrivateKey', $newKey->id)
->assertDispatched('error', fn (string $event, array $params): bool => str_contains($params[0], 'Permission denied (publickey,password).')
&& str_contains($params[0], 'https://coolify.io/docs/knowledge-base/server/openssh'));
expect($this->server->fresh()->private_key_id)->toBe($this->currentPrivateKey->id);
});