From a9cc5cc351dcf3f3e6b950b03c359f0e5ec51c03 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 9 Apr 2024 08:46:00 +0200 Subject: [PATCH] Fix server functionality check and cleanup SSH keys --- app/Jobs/ApplicationDeploymentJob.php | 6 ++++- app/Models/Server.php | 38 ++++++++++++++++----------- bootstrap/helpers/remoteProcess.php | 28 +++++++++++++++++--- config/sentry.php | 2 +- config/version.php | 2 +- versions.json | 2 +- 6 files changed, 54 insertions(+), 24 deletions(-) diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index c767daa31..6ad87e07f 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -179,6 +179,11 @@ public function __construct(int $application_deployment_queue_id) public function handle(): void { + if (!$this->server->isFunctional()) { + $this->application_deployment_queue->addLogEntry("Server is not functional."); + $this->fail("Server is not functional."); + return; + } try { // Generate custom host<->ip mapping $allContainers = instant_remote_process(["docker network inspect {$this->destination->network} -f '{{json .Containers}}' "], $this->server); @@ -1809,7 +1814,6 @@ private function next(string $status) public function failed(Throwable $exception): void { - $this->next(ApplicationDeploymentStatus::FAILED->value); $this->application_deployment_queue->addLogEntry("Oops something is not okay, are you okay? 😢", 'stderr'); if (str($exception->getMessage())->isNotEmpty()) { diff --git a/app/Models/Server.php b/app/Models/Server.php index cbe895936..bcb06954a 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -550,21 +550,21 @@ public function startUnmanaged($id) } public function loadUnmanagedContainers() { - if ($this->isFunctional()) { - $containers = instant_remote_process(["docker ps -a --format '{{json .}}' "], $this); - $containers = format_docker_command_output_to_json($containers); - $containers = $containers->map(function ($container) { - $labels = data_get($container, 'Labels'); - if (!str($labels)->contains("coolify.managed")) { - return $container; - } - return null; - }); - $containers = $containers->filter(); - return collect($containers); - } else { - return collect([]); - } + if ($this->isFunctional()) { + $containers = instant_remote_process(["docker ps -a --format '{{json .}}' "], $this); + $containers = format_docker_command_output_to_json($containers); + $containers = $containers->map(function ($container) { + $labels = data_get($container, 'Labels'); + if (!str($labels)->contains("coolify.managed")) { + return $container; + } + return null; + }); + $containers = $containers->filter(); + return collect($containers); + } else { + return collect([]); + } } public function hasDefinedResources() { @@ -690,7 +690,13 @@ public function isProxyShouldRun() } public function isFunctional() { - return $this->settings->is_reachable && $this->settings->is_usable && !$this->settings->force_disabled; + $isFunctional = $this->settings->is_reachable && $this->settings->is_usable && !$this->settings->force_disabled; + ['private_key_filename' => $private_key_filename, 'mux_filename' => $mux_filename] = server_ssh_configuration($this); + if (!$isFunctional) { + Storage::disk('ssh-keys')->delete($private_key_filename); + Storage::disk('ssh-mux')->delete($mux_filename); + } + return $isFunctional; } public function isLogDrainEnabled() { diff --git a/bootstrap/helpers/remoteProcess.php b/bootstrap/helpers/remoteProcess.php index 0aba82ea1..0a51b3ffc 100644 --- a/bootstrap/helpers/remoteProcess.php +++ b/bootstrap/helpers/remoteProcess.php @@ -55,17 +55,30 @@ function remote_process( ), ])(); } - +function server_ssh_configuration(Server $server) +{ + $uuid = data_get($server, 'uuid'); + if (is_null($uuid)) { + throw new \Exception("Server does not have a uuid"); + } + $private_key_filename = "id.root@{$server->uuid}"; + $location = '/var/www/html/storage/app/ssh/keys/' . $private_key_filename; + $mux_filename = '/var/www/html/storage/app/ssh/mux/' . $server->muxFilename(); + return [ + 'location' => $location, + 'mux_filename' => $mux_filename, + 'private_key_filename' => $private_key_filename + ]; +} function savePrivateKeyToFs(Server $server) { if (data_get($server, 'privateKey.private_key') === null) { throw new \Exception("Server {$server->name} does not have a private key"); } - $sshKeyFileLocation = "id.root@{$server->uuid}"; + ['location' => $location, 'private_key_filename' => $private_key_filename] = server_ssh_configuration($server); Storage::disk('ssh-keys')->makeDirectory('.'); Storage::disk('ssh-mux')->makeDirectory('.'); - Storage::disk('ssh-keys')->put($sshKeyFileLocation, $server->privateKey->private_key); - $location = '/var/www/html/storage/app/ssh/keys/' . $sshKeyFileLocation; + Storage::disk('ssh-keys')->put($private_key_filename, $server->privateKey->private_key); return $location; } @@ -223,6 +236,13 @@ function remove_iip($text) $text = preg_replace('/x-access-token:.*?(?=@)/', "x-access-token:" . REDACTED, $text); return preg_replace('/\x1b\[[0-9;]*m/', '', $text); } +function remove_mux_and_private_key(Server $server) +{ + $muxFilename = $server->muxFilename(); + $privateKeyLocation = savePrivateKeyToFs($server); + Storage::disk('ssh-mux')->delete($muxFilename); + Storage::disk('ssh-keys')->delete($privateKeyLocation); +} function refresh_server_connection(?PrivateKey $private_key = null) { if (is_null($private_key)) { diff --git a/config/sentry.php b/config/sentry.php index 5250d3547..f1d8aa314 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.252', + 'release' => '4.0.0-beta.253', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index a0ca28c13..e92f47087 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@