mirror of
https://github.com/tiennm99/coolify.git
synced 2026-08-20 06:23:23 +00:00
fix(servers): isolate cloud status checks from SSH checks
Track provider state independently, skip SSH work for placeholder IPs, and clean up failed cloud server provisioning.
This commit is contained in:
@@ -6,7 +6,6 @@ use App\Events\ServerReachabilityChanged;
|
||||
use App\Helpers\SshMultiplexingHelper;
|
||||
use App\Models\Server;
|
||||
use App\Services\ConfigurationRepository;
|
||||
use App\Services\HetznerService;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
@@ -42,8 +41,12 @@ class ServerConnectionCheckJob implements ShouldBeEncrypted, ShouldQueue
|
||||
$configRepository->disableSshMux();
|
||||
}
|
||||
|
||||
public function handle()
|
||||
public function handle(): void
|
||||
{
|
||||
if ($this->server->hasPlaceholderIp()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$wasReachable = (bool) $this->server->settings->is_reachable;
|
||||
$wasNotified = (bool) $this->server->unreachable_notification_sent;
|
||||
|
||||
@@ -62,19 +65,6 @@ class ServerConnectionCheckJob implements ShouldBeEncrypted, ShouldQueue
|
||||
return;
|
||||
}
|
||||
|
||||
// Check Hetzner server status if applicable
|
||||
if ($this->server->hetzner_server_id && $this->server->cloudProviderToken) {
|
||||
$this->checkHetznerStatus();
|
||||
}
|
||||
|
||||
if ($this->server->vultr_instance_id && $this->server->cloudProviderToken) {
|
||||
$this->checkVultrStatus();
|
||||
}
|
||||
|
||||
if ($this->server->digitalocean_droplet_id && $this->server->cloudProviderToken) {
|
||||
$this->checkDigitalOceanStatus();
|
||||
}
|
||||
|
||||
// Temporarily disable mux if requested
|
||||
if ($this->disableMux) {
|
||||
$this->disableSshMux();
|
||||
@@ -136,17 +126,6 @@ class ServerConnectionCheckJob implements ShouldBeEncrypted, ShouldQueue
|
||||
public function failed(?\Throwable $exception): void
|
||||
{
|
||||
if ($exception instanceof TimeoutExceededException) {
|
||||
$wasReachable = (bool) $this->server->settings->is_reachable;
|
||||
$wasNotified = (bool) $this->server->unreachable_notification_sent;
|
||||
|
||||
$this->server->settings->update([
|
||||
'is_reachable' => false,
|
||||
'is_usable' => false,
|
||||
]);
|
||||
$this->server->increment('unreachable_count');
|
||||
|
||||
$this->dispatchReachabilityChangedIfNeeded($wasReachable, $wasNotified, false);
|
||||
|
||||
// Delete the queue job so it doesn't appear in Horizon's failed list.
|
||||
$this->job?->delete();
|
||||
}
|
||||
@@ -171,63 +150,6 @@ class ServerConnectionCheckJob implements ShouldBeEncrypted, ShouldQueue
|
||||
}
|
||||
}
|
||||
|
||||
private function checkHetznerStatus(): void
|
||||
{
|
||||
$status = null;
|
||||
|
||||
try {
|
||||
$hetznerService = new HetznerService($this->server->cloudProviderToken->token);
|
||||
$serverData = $hetznerService->getServer($this->server->hetzner_server_id);
|
||||
$status = $serverData['status'] ?? null;
|
||||
|
||||
} catch (\Throwable) {
|
||||
// Silently ignore — server may have been deleted from Hetzner.
|
||||
}
|
||||
if ($this->server->hetzner_server_status !== $status) {
|
||||
$this->server->update(['hetzner_server_status' => $status]);
|
||||
$this->server->hetzner_server_status = $status;
|
||||
if ($status === 'off') {
|
||||
throw new \Exception('Server is powered off');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function checkVultrStatus(): void
|
||||
{
|
||||
try {
|
||||
$status = $this->server->refreshVultrState();
|
||||
} catch (\Throwable) {
|
||||
// Silently ignore transient Vultr API errors.
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (in_array($status, ['stopped', 'suspended', 'deleted'], true)) {
|
||||
throw new \Exception('Vultr instance is not running');
|
||||
}
|
||||
}
|
||||
|
||||
private function checkDigitalOceanStatus(): void
|
||||
{
|
||||
try {
|
||||
$status = $this->server->refreshDigitalOceanState();
|
||||
} catch (\Throwable $e) {
|
||||
Log::debug('ServerConnectionCheck: DigitalOcean status check failed', [
|
||||
'server_id' => $this->server->id,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->server->digitalocean_droplet_status = $status;
|
||||
|
||||
if (in_array($status, ['off', 'archive', 'deleted'], true)) {
|
||||
throw new \Exception('DigitalOcean droplet is not running');
|
||||
}
|
||||
}
|
||||
|
||||
private function checkConnection(): bool
|
||||
{
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user