From 5818c9cf6bfe9f2a10c03e6d22eee9fd442a1d8b Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 17 Sep 2024 11:30:29 +0200 Subject: [PATCH 1/9] chore: Add validation to prevent selecting 'default' server or container in RunCommand.php --- app/Livewire/RunCommand.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/Livewire/RunCommand.php b/app/Livewire/RunCommand.php index 290618bef..4eae773e1 100644 --- a/app/Livewire/RunCommand.php +++ b/app/Livewire/RunCommand.php @@ -90,6 +90,12 @@ class RunCommand extends Component #[On('connectToContainer')] public function connectToContainer() { + if ($this->selected_uuid === 'default') { + $this->dispatch('error', 'Please select a server or a container.'); + + return; + } + $container = collect($this->containers)->firstWhere('uuid', $this->selected_uuid); $this->dispatch('send-terminal-command', From ea877f3623a3fafc1780a7e27b25657078166e6c Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 17 Sep 2024 11:30:37 +0200 Subject: [PATCH 2/9] Update version numbers to 4.0.0-beta.338 --- config/sentry.php | 2 +- config/version.php | 2 +- other/nightly/versions.json | 4 ++-- versions.json | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config/sentry.php b/config/sentry.php index 8fb0e5cdd..e112bf260 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ return [ // 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.337', + 'release' => '4.0.0-beta.338', // 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 aac06d60d..16bc6b80e 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ Date: Tue, 17 Sep 2024 11:30:46 +0200 Subject: [PATCH 3/9] fix: Handle WebSocket connection close in terminal.blade.php --- .../views/livewire/project/shared/terminal.blade.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/resources/views/livewire/project/shared/terminal.blade.php b/resources/views/livewire/project/shared/terminal.blade.php index 5c7560367..31887120d 100644 --- a/resources/views/livewire/project/shared/terminal.blade.php +++ b/resources/views/livewire/project/shared/terminal.blade.php @@ -67,6 +67,12 @@ socket.onerror = (e) => { console.error('WebSocket error:', e); }; + socket.onclose = () => { + console.log('WebSocket connection closed'); + setInterval(() => { + $wire.dispatch('error', 'Connection to terminal lost, please refresh the page.'); + }, 2000); + }; } } @@ -209,8 +215,8 @@ term.resize(termWidth, termHeight); socket.send(JSON.stringify({ resize: { - cols: termWidth, - rows: termHeight + cols: 600, + rows: 600 } })); } From 35b9b7fdf29588578b8878891e6fa2aeb67692bb Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 17 Sep 2024 11:54:25 +0200 Subject: [PATCH 4/9] fix/feat: able to open terminal to any containers --- app/Livewire/RunCommand.php | 67 +++++++++---------------------------- app/Models/Server.php | 12 +++++++ 2 files changed, 27 insertions(+), 52 deletions(-) diff --git a/app/Livewire/RunCommand.php b/app/Livewire/RunCommand.php index 4eae773e1..0aaf321af 100644 --- a/app/Livewire/RunCommand.php +++ b/app/Livewire/RunCommand.php @@ -15,6 +15,9 @@ class RunCommand extends Component public function mount($servers) { + if (! auth()->user()->isAdmin()) { + abort(403); + } $this->servers = $servers; $this->containers = $this->getAllActiveContainers(); } @@ -26,63 +29,25 @@ class RunCommand extends Component return []; } - return $server->definedResources() - ->filter(function ($resource) { - $status = method_exists($resource, 'realStatus') ? $resource->realStatus() : (method_exists($resource, 'status') ? $resource->status() : 'exited'); - - return str_starts_with($status, 'running:'); - }) - ->map(function ($resource) use ($server) { - if (isDev()) { - if (data_get($resource, 'name') === 'coolify-db') { - $container_name = 'coolify-db'; - - return [ - 'name' => $resource->name, - 'connection_name' => $container_name, - 'uuid' => $resource->uuid, - 'status' => 'running', - 'server' => $server, - 'server_uuid' => $server->uuid, - ]; - } - } - - if (class_basename($resource) === 'Application') { - if (! $server->isSwarm()) { - $current_containers = getCurrentApplicationContainerStatus($server, $resource->id, includePullrequests: true); - } - $status = $resource->status; - } elseif (class_basename($resource) === 'Service') { - $current_containers = getCurrentServiceContainerStatus($server, $resource->id); - $status = $resource->status(); - } else { - $status = getContainerStatus($server, $resource->uuid); - if ($status === 'running') { - $current_containers = collect([ - 'Names' => $resource->name, - ]); - } - } - if ($server->isSwarm()) { - $container_name = $resource->uuid.'_'.$resource->uuid; - } else { - $container_name = data_get($current_containers->first(), 'Names'); - } - + return $server->loadAllContainers()->map(function ($container) use ($server) { + $state = data_get_str($container, 'State')->lower(); + if ($state->contains('running')) { return [ - 'name' => $resource->name, - 'connection_name' => $container_name, - 'uuid' => $resource->uuid, - 'status' => $status, + 'name' => data_get($container, 'Names'), + 'connection_name' => data_get($container, 'Names'), + 'uuid' => data_get($container, 'Names'), + 'status' => data_get_str($container, 'State')->lower(), 'server' => $server, 'server_uuid' => $server->uuid, ]; - }); + } + + return null; + })->filter(); }); } - public function updatedSelectedUuid($value) + public function updatedSelectedUuid() { $this->connectToContainer(); } @@ -95,9 +60,7 @@ class RunCommand extends Component return; } - $container = collect($this->containers)->firstWhere('uuid', $this->selected_uuid); - $this->dispatch('send-terminal-command', isset($container), $container['connection_name'] ?? $this->selected_uuid, diff --git a/app/Models/Server.php b/app/Models/Server.php index 3a11c2206..e2f52b4e1 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -775,6 +775,18 @@ $schema://$host { } } + public function loadAllContainers(): Collection + { + if ($this->isFunctional()) { + $containers = instant_remote_process(["docker ps -a --format '{{json .}}'"], $this); + $containers = format_docker_command_output_to_json($containers); + + return collect($containers); + } + + return collect([]); + } + public function loadUnmanagedContainers(): Collection { if ($this->isFunctional()) { From cbc2f1f0159ebbead94b6e08288868c67ea82b32 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 17 Sep 2024 11:58:28 +0200 Subject: [PATCH 5/9] chore: Update versions.json to reflect latest version of realtime container --- docker/coolify-realtime/terminal-server.js | 1 - versions.json | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/docker/coolify-realtime/terminal-server.js b/docker/coolify-realtime/terminal-server.js index daa09a6f8..6dfbe3531 100755 --- a/docker/coolify-realtime/terminal-server.js +++ b/docker/coolify-realtime/terminal-server.js @@ -123,7 +123,6 @@ async function handleCommand(ws, command, userId) { cols: 80, rows: 30, cwd: process.env.HOME, - env: process.env }; // NOTE: - Initiates a process within the Terminal container diff --git a/versions.json b/versions.json index 14388185f..d4cdd3886 100644 --- a/versions.json +++ b/versions.json @@ -10,7 +10,7 @@ "version": "1.0.1" }, "realtime": { - "version": "1.0.0" + "version": "1.0.1" } } } \ No newline at end of file From a2ea8814cfb321c6dc794d439a353433b0ab6cb4 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 17 Sep 2024 12:00:57 +0200 Subject: [PATCH 6/9] chore: Update soketi image to version 1.0.1 --- docker-compose.prod.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index c5513af40..3eb270a2a 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -110,7 +110,7 @@ services: retries: 10 timeout: 2s soketi: - image: 'ghcr.io/coollabsio/coolify-realtime:1.0.0' + image: 'ghcr.io/coollabsio/coolify-realtime:1.0.1' ports: - "${SOKETI_PORT:-6001}:6001" - "6002:6002" @@ -123,7 +123,7 @@ services: SOKETI_DEFAULT_APP_KEY: "${PUSHER_APP_KEY}" SOKETI_DEFAULT_APP_SECRET: "${PUSHER_APP_SECRET}" healthcheck: - test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:6001/ready && wget -qO- http://127.0.0.1:6002/ready || exit 1"] + test: [ "CMD-SHELL", "wget -qO- http://127.0.0.1:6001/ready && wget -qO- http://127.0.0.1:6002/ready || exit 1" ] interval: 5s retries: 10 timeout: 2s From 4bdb5c90302e281b688d974ac698c9c18058e762 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 17 Sep 2024 12:08:09 +0200 Subject: [PATCH 7/9] chore: nightly - Update soketi image to version 1.0.1 and versions.json to reflect latest version of realtime container --- other/nightly/docker-compose.prod.yml | 4 ++-- other/nightly/versions.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/other/nightly/docker-compose.prod.yml b/other/nightly/docker-compose.prod.yml index c5513af40..3eb270a2a 100644 --- a/other/nightly/docker-compose.prod.yml +++ b/other/nightly/docker-compose.prod.yml @@ -110,7 +110,7 @@ services: retries: 10 timeout: 2s soketi: - image: 'ghcr.io/coollabsio/coolify-realtime:1.0.0' + image: 'ghcr.io/coollabsio/coolify-realtime:1.0.1' ports: - "${SOKETI_PORT:-6001}:6001" - "6002:6002" @@ -123,7 +123,7 @@ services: SOKETI_DEFAULT_APP_KEY: "${PUSHER_APP_KEY}" SOKETI_DEFAULT_APP_SECRET: "${PUSHER_APP_SECRET}" healthcheck: - test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:6001/ready && wget -qO- http://127.0.0.1:6002/ready || exit 1"] + test: [ "CMD-SHELL", "wget -qO- http://127.0.0.1:6001/ready && wget -qO- http://127.0.0.1:6002/ready || exit 1" ] interval: 5s retries: 10 timeout: 2s diff --git a/other/nightly/versions.json b/other/nightly/versions.json index 14388185f..d4cdd3886 100644 --- a/other/nightly/versions.json +++ b/other/nightly/versions.json @@ -10,7 +10,7 @@ "version": "1.0.1" }, "realtime": { - "version": "1.0.0" + "version": "1.0.1" } } } \ No newline at end of file From 162fb7bfc51110b6d6b989adf6c301865d546319 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 17 Sep 2024 12:27:20 +0200 Subject: [PATCH 8/9] fix: refactor run-command --- app/Livewire/RunCommand.php | 5 +++-- app/Livewire/Terminal/Index.php | 8 -------- resources/views/livewire/terminal/index.blade.php | 8 +------- 3 files changed, 4 insertions(+), 17 deletions(-) diff --git a/app/Livewire/RunCommand.php b/app/Livewire/RunCommand.php index 0aaf321af..3650f2e41 100644 --- a/app/Livewire/RunCommand.php +++ b/app/Livewire/RunCommand.php @@ -2,6 +2,7 @@ namespace App\Livewire; +use App\Models\Server; use Livewire\Attributes\On; use Livewire\Component; @@ -13,12 +14,12 @@ class RunCommand extends Component public $containers = []; - public function mount($servers) + public function mount() { if (! auth()->user()->isAdmin()) { abort(403); } - $this->servers = $servers; + $this->servers = Server::isReachable()->get(); $this->containers = $this->getAllActiveContainers(); } diff --git a/app/Livewire/Terminal/Index.php b/app/Livewire/Terminal/Index.php index 3f777a8ff..8c59bdcbf 100644 --- a/app/Livewire/Terminal/Index.php +++ b/app/Livewire/Terminal/Index.php @@ -2,18 +2,10 @@ namespace App\Livewire\Terminal; -use App\Models\Server; use Livewire\Component; class Index extends Component { - public $servers = []; - - public function mount() - { - $this->servers = Server::isReachable()->get(); - } - public function render() { return view('livewire.terminal.index'); diff --git a/resources/views/livewire/terminal/index.blade.php b/resources/views/livewire/terminal/index.blade.php index e2f1c82e4..34a2d4c21 100644 --- a/resources/views/livewire/terminal/index.blade.php +++ b/resources/views/livewire/terminal/index.blade.php @@ -8,11 +8,5 @@ - @if ($servers->count() > 0) - - @else -
-
No servers found. Without a server, you won't be able to do much.
-
- @endif + From 8967315c49bee04249c7e8a8ab4e94ed5819cd21 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 17 Sep 2024 12:29:36 +0200 Subject: [PATCH 9/9] refactor: terminal / run command --- app/Livewire/RunCommand.php | 71 ------------------- app/Livewire/Terminal/Index.php | 63 ++++++++++++++++ .../views/livewire/run-command.blade.php | 22 ------ .../views/livewire/terminal/index.blade.php | 24 ++++++- 4 files changed, 86 insertions(+), 94 deletions(-) delete mode 100644 app/Livewire/RunCommand.php delete mode 100644 resources/views/livewire/run-command.blade.php diff --git a/app/Livewire/RunCommand.php b/app/Livewire/RunCommand.php deleted file mode 100644 index 3650f2e41..000000000 --- a/app/Livewire/RunCommand.php +++ /dev/null @@ -1,71 +0,0 @@ -user()->isAdmin()) { - abort(403); - } - $this->servers = Server::isReachable()->get(); - $this->containers = $this->getAllActiveContainers(); - } - - private function getAllActiveContainers() - { - return collect($this->servers)->flatMap(function ($server) { - if (! $server->isFunctional()) { - return []; - } - - return $server->loadAllContainers()->map(function ($container) use ($server) { - $state = data_get_str($container, 'State')->lower(); - if ($state->contains('running')) { - return [ - 'name' => data_get($container, 'Names'), - 'connection_name' => data_get($container, 'Names'), - 'uuid' => data_get($container, 'Names'), - 'status' => data_get_str($container, 'State')->lower(), - 'server' => $server, - 'server_uuid' => $server->uuid, - ]; - } - - return null; - })->filter(); - }); - } - - public function updatedSelectedUuid() - { - $this->connectToContainer(); - } - - #[On('connectToContainer')] - public function connectToContainer() - { - if ($this->selected_uuid === 'default') { - $this->dispatch('error', 'Please select a server or a container.'); - - return; - } - $container = collect($this->containers)->firstWhere('uuid', $this->selected_uuid); - $this->dispatch('send-terminal-command', - isset($container), - $container['connection_name'] ?? $this->selected_uuid, - $container['server_uuid'] ?? $this->selected_uuid - ); - } -} diff --git a/app/Livewire/Terminal/Index.php b/app/Livewire/Terminal/Index.php index 8c59bdcbf..945b25714 100644 --- a/app/Livewire/Terminal/Index.php +++ b/app/Livewire/Terminal/Index.php @@ -2,10 +2,73 @@ namespace App\Livewire\Terminal; +use App\Models\Server; +use Livewire\Attributes\On; use Livewire\Component; class Index extends Component { + public $selected_uuid = 'default'; + + public $servers = []; + + public $containers = []; + + public function mount() + { + if (! auth()->user()->isAdmin()) { + abort(403); + } + $this->servers = Server::isReachable()->get(); + $this->containers = $this->getAllActiveContainers(); + } + + private function getAllActiveContainers() + { + return collect($this->servers)->flatMap(function ($server) { + if (! $server->isFunctional()) { + return []; + } + + return $server->loadAllContainers()->map(function ($container) use ($server) { + $state = data_get_str($container, 'State')->lower(); + if ($state->contains('running')) { + return [ + 'name' => data_get($container, 'Names'), + 'connection_name' => data_get($container, 'Names'), + 'uuid' => data_get($container, 'Names'), + 'status' => data_get_str($container, 'State')->lower(), + 'server' => $server, + 'server_uuid' => $server->uuid, + ]; + } + + return null; + })->filter(); + }); + } + + public function updatedSelectedUuid() + { + $this->connectToContainer(); + } + + #[On('connectToContainer')] + public function connectToContainer() + { + if ($this->selected_uuid === 'default') { + $this->dispatch('error', 'Please select a server or a container.'); + + return; + } + $container = collect($this->containers)->firstWhere('uuid', $this->selected_uuid); + $this->dispatch('send-terminal-command', + isset($container), + $container['connection_name'] ?? $this->selected_uuid, + $container['server_uuid'] ?? $this->selected_uuid + ); + } + public function render() { return view('livewire.terminal.index'); diff --git a/resources/views/livewire/run-command.blade.php b/resources/views/livewire/run-command.blade.php deleted file mode 100644 index 4330e94cf..000000000 --- a/resources/views/livewire/run-command.blade.php +++ /dev/null @@ -1,22 +0,0 @@ -
-
- - @foreach ($servers as $server) - @if ($loop->first) - - @endif - - @foreach ($containers as $container) - @if ($container['server_uuid'] == $server->uuid) - - @endif - @endforeach - @endforeach - - Connect -
- -
diff --git a/resources/views/livewire/terminal/index.blade.php b/resources/views/livewire/terminal/index.blade.php index 34a2d4c21..357295002 100644 --- a/resources/views/livewire/terminal/index.blade.php +++ b/resources/views/livewire/terminal/index.blade.php @@ -8,5 +8,27 @@ - +
+
+ + @foreach ($servers as $server) + @if ($loop->first) + + @endif + + @foreach ($containers as $container) + @if ($container['server_uuid'] == $server->uuid) + + @endif + @endforeach + @endforeach + + Connect +
+ +
+