From 47277a68ec8dd2be18877af1e698ed7a4de00ff1 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 13 Sep 2024 18:24:37 +0200 Subject: [PATCH 01/31] Create remove-labels-assignees-on-close.yml --- .../remove-labels-assignees-on-close.yml | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/workflows/remove-labels-assignees-on-close.yml diff --git a/.github/workflows/remove-labels-assignees-on-close.yml b/.github/workflows/remove-labels-assignees-on-close.yml new file mode 100644 index 000000000..584842290 --- /dev/null +++ b/.github/workflows/remove-labels-assignees-on-close.yml @@ -0,0 +1,38 @@ +name: Remove Labels and Assignees on Issue Close + +on: + issues: + types: [closed] + pull_request: + types: [closed] + +jobs: + remove-labels-and-assignees: + runs-on: ubuntu-latest + steps: + - name: Remove all labels and assignees + uses: actions/github-script@v6 + with: + github-token: ${{secrets.GITHUB_TOKEN}} + script: | + const issue = context.payload.issue || context.payload.pull_request; + const repo = context.repo; + + // Remove all labels + await github.rest.issues.removeAllLabels({ + owner: repo.owner, + repo: repo.name, + issue_number: issue.number + }); + + // Remove all assignees + if (issue.assignees && issue.assignees.length > 0) { + await github.rest.issues.removeAssignees({ + owner: repo.owner, + repo: repo.name, + issue_number: issue.number, + assignees: issue.assignees.map(assignee => assignee.login) + }); + } + + console.log(`Removed all labels and assignees from issue/PR #${issue.number}`); \ No newline at end of file From 7948a0309fbff8a1f3615170ff9a532b22e21706 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 13 Sep 2024 18:42:38 +0200 Subject: [PATCH 02/31] Feat: remove labels and assignees on issue close --- .../remove-labels-and-assignees-on-close.yml | 57 +++++++++++++++++++ .../remove-labels-assignees-on-close.yml | 38 ------------- 2 files changed, 57 insertions(+), 38 deletions(-) create mode 100644 .github/workflows/remove-labels-and-assignees-on-close.yml delete mode 100644 .github/workflows/remove-labels-assignees-on-close.yml diff --git a/.github/workflows/remove-labels-and-assignees-on-close.yml b/.github/workflows/remove-labels-and-assignees-on-close.yml new file mode 100644 index 000000000..a2291f7f9 --- /dev/null +++ b/.github/workflows/remove-labels-and-assignees-on-close.yml @@ -0,0 +1,57 @@ +name: Remove Labels and Assignees on Issue Close + +on: + issues: + types: [closed] + pull_request: + types: [closed] + +jobs: + remove-labels-and-assignees: + runs-on: ubuntu-latest + steps: + - name: Remove labels and assignees + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const issue = context.payload.issue || context.payload.pull_request; + const { owner, repo } = context.repo; + + try { + const { data: currentLabels } = await github.rest.issues.listLabelsOnIssue({ + owner, + repo, + issue_number: issue.number + }); + + const labelsToKeep = currentLabels + .filter(label => label.name === '⏱︎ Stale') + .map(label => label.name); + + await github.rest.issues.setLabels({ + owner, + repo, + issue_number: issue.number, + labels: labelsToKeep + }); + } catch (error) { + if (error.status !== 404) { + throw error; + } + } + + if (issue.assignees && issue.assignees.length > 0) { + try { + await github.rest.issues.removeAssignees({ + owner, + repo, + issue_number: issue.number, + assignees: issue.assignees.map(assignee => assignee.login) + }); + } catch (error) { + if (error.status !== 404) { + throw error; + } + } + } diff --git a/.github/workflows/remove-labels-assignees-on-close.yml b/.github/workflows/remove-labels-assignees-on-close.yml deleted file mode 100644 index 584842290..000000000 --- a/.github/workflows/remove-labels-assignees-on-close.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Remove Labels and Assignees on Issue Close - -on: - issues: - types: [closed] - pull_request: - types: [closed] - -jobs: - remove-labels-and-assignees: - runs-on: ubuntu-latest - steps: - - name: Remove all labels and assignees - uses: actions/github-script@v6 - with: - github-token: ${{secrets.GITHUB_TOKEN}} - script: | - const issue = context.payload.issue || context.payload.pull_request; - const repo = context.repo; - - // Remove all labels - await github.rest.issues.removeAllLabels({ - owner: repo.owner, - repo: repo.name, - issue_number: issue.number - }); - - // Remove all assignees - if (issue.assignees && issue.assignees.length > 0) { - await github.rest.issues.removeAssignees({ - owner: repo.owner, - repo: repo.name, - issue_number: issue.number, - assignees: issue.assignees.map(assignee => assignee.login) - }); - } - - console.log(`Removed all labels and assignees from issue/PR #${issue.number}`); \ No newline at end of file From 1c6450da24557dbdffd513db3af3a8fae14bd248 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 16 Sep 2024 10:23:05 +0200 Subject: [PATCH 03/31] Feat: Make sure this action is also triggered on PR issue close --- .../remove-labels-and-assignees-on-close.yml | 87 ++++++++++++------- 1 file changed, 58 insertions(+), 29 deletions(-) diff --git a/.github/workflows/remove-labels-and-assignees-on-close.yml b/.github/workflows/remove-labels-and-assignees-on-close.yml index a2291f7f9..81f7d35f3 100644 --- a/.github/workflows/remove-labels-and-assignees-on-close.yml +++ b/.github/workflows/remove-labels-and-assignees-on-close.yml @@ -5,6 +5,11 @@ on: types: [closed] pull_request: types: [closed] + pull_request_target: + types: [closed] + workflow_run: + workflows: ["*"] + types: [completed] jobs: remove-labels-and-assignees: @@ -15,43 +20,67 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const issue = context.payload.issue || context.payload.pull_request; const { owner, repo } = context.repo; - try { - const { data: currentLabels } = await github.rest.issues.listLabelsOnIssue({ - owner, - repo, - issue_number: issue.number - }); - - const labelsToKeep = currentLabels - .filter(label => label.name === '⏱︎ Stale') - .map(label => label.name); - - await github.rest.issues.setLabels({ - owner, - repo, - issue_number: issue.number, - labels: labelsToKeep - }); - } catch (error) { - if (error.status !== 404) { - throw error; - } - } - - if (issue.assignees && issue.assignees.length > 0) { + async function processIssue(issueNumber) { try { - await github.rest.issues.removeAssignees({ + const { data: currentLabels } = await github.rest.issues.listLabelsOnIssue({ owner, repo, - issue_number: issue.number, - assignees: issue.assignees.map(assignee => assignee.login) + issue_number: issueNumber }); + + const labelsToKeep = currentLabels + .filter(label => label.name === '⏱︎ Stale') + .map(label => label.name); + + await github.rest.issues.setLabels({ + owner, + repo, + issue_number: issueNumber, + labels: labelsToKeep + }); + + const { data: issue } = await github.rest.issues.get({ + owner, + repo, + issue_number: issueNumber + }); + + if (issue.assignees && issue.assignees.length > 0) { + await github.rest.issues.removeAssignees({ + owner, + repo, + issue_number: issueNumber, + assignees: issue.assignees.map(assignee => assignee.login) + }); + } } catch (error) { if (error.status !== 404) { - throw error; + console.error(`Error processing issue ${issueNumber}:`, error); } } } + + if (context.eventName === 'issues' || context.eventName === 'pull_request' || context.eventName === 'pull_request_target') { + const issue = context.payload.issue || context.payload.pull_request; + await processIssue(issue.number); + } else if (context.eventName === 'workflow_run') { + const { data: closedIssues } = await github.rest.search.issuesAndPullRequests({ + q: `repo:${owner}/${repo} is:issue is:closed closed:${context.payload.workflow_run.updated_at}`, + per_page: 100 + }); + for (const issue of closedIssues.items) { + await processIssue(issue.number); + } + } + + if (context.eventName === 'pull_request' || context.eventName === 'pull_request_target') { + const { data: closedIssues } = await github.rest.search.issuesAndPullRequests({ + q: `repo:${owner}/${repo} is:issue is:closed linked:${context.payload.pull_request.number}`, + per_page: 100 + }); + for (const issue of closedIssues.items) { + await processIssue(issue.number); + } + } From 7037c779e2e1be4be95d72ea4326be45b0d02833 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 16 Sep 2024 11:13:56 +0200 Subject: [PATCH 04/31] Update remove-labels-and-assignees-on-close.yml --- .../remove-labels-and-assignees-on-close.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.github/workflows/remove-labels-and-assignees-on-close.yml b/.github/workflows/remove-labels-and-assignees-on-close.yml index 81f7d35f3..04d62623c 100644 --- a/.github/workflows/remove-labels-and-assignees-on-close.yml +++ b/.github/workflows/remove-labels-and-assignees-on-close.yml @@ -7,9 +7,6 @@ on: types: [closed] pull_request_target: types: [closed] - workflow_run: - workflows: ["*"] - types: [completed] jobs: remove-labels-and-assignees: @@ -65,14 +62,6 @@ jobs: if (context.eventName === 'issues' || context.eventName === 'pull_request' || context.eventName === 'pull_request_target') { const issue = context.payload.issue || context.payload.pull_request; await processIssue(issue.number); - } else if (context.eventName === 'workflow_run') { - const { data: closedIssues } = await github.rest.search.issuesAndPullRequests({ - q: `repo:${owner}/${repo} is:issue is:closed closed:${context.payload.workflow_run.updated_at}`, - per_page: 100 - }); - for (const issue of closedIssues.items) { - await processIssue(issue.number); - } } if (context.eventName === 'pull_request' || context.eventName === 'pull_request_target') { From 5818c9cf6bfe9f2a10c03e6d22eee9fd442a1d8b Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 17 Sep 2024 11:30:29 +0200 Subject: [PATCH 05/31] 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 06/31] 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 07/31] 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 08/31] 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 09/31] 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 10/31] 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 11/31] 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 12/31] 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 13/31] 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 +
+ +
+ From 428c40aab5fe87c1ae17d9547e1161c9a4136957 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 17 Sep 2024 12:54:23 +0200 Subject: [PATCH 14/31] chore: Update version numbers to 4.0.0-beta.339 --- 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 e112bf260..bc1a242c3 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.338', + 'release' => '4.0.0-beta.339', // 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 16bc6b80e..c67609376 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ Date: Tue, 17 Sep 2024 16:28:28 +0200 Subject: [PATCH 15/31] refactor: Add authorization check in ExecuteContainerCommand mount method --- app/Livewire/Project/Shared/ExecuteContainerCommand.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/Livewire/Project/Shared/ExecuteContainerCommand.php b/app/Livewire/Project/Shared/ExecuteContainerCommand.php index 79f32ab8b..d95443621 100644 --- a/app/Livewire/Project/Shared/ExecuteContainerCommand.php +++ b/app/Livewire/Project/Shared/ExecuteContainerCommand.php @@ -33,6 +33,9 @@ class ExecuteContainerCommand extends Component public function mount() { + if (! auth()->user()->isAdmin()) { + abort(403); + } $this->parameters = get_route_parameters(); $this->containers = collect(); $this->servers = collect(); @@ -130,7 +133,6 @@ class ExecuteContainerCommand extends Component { try { $container_name = data_get($this->container, 'container.Names'); - ray($this->container); if (is_null($container_name)) { throw new \RuntimeException('Container not found.'); } From 07ed726c88c6da5069a47f597e23bc5d3f8e0c03 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 17 Sep 2024 16:48:30 +0200 Subject: [PATCH 16/31] refactor: Remove unnecessary code in Terminal.php --- app/Livewire/Project/Shared/Terminal.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/Livewire/Project/Shared/Terminal.php b/app/Livewire/Project/Shared/Terminal.php index 7c23c291d..802e65a30 100644 --- a/app/Livewire/Project/Shared/Terminal.php +++ b/app/Livewire/Project/Shared/Terminal.php @@ -14,13 +14,6 @@ class Terminal extends Component $server = Server::ownedByCurrentTeam()->whereUuid($serverUuid)->firstOrFail(); - // if (auth()->user()) { - // $teams = auth()->user()->teams->pluck('id'); - // if (! $teams->contains($server->team_id) && ! $teams->contains(0)) { - // throw new \Exception('User is not part of the team that owns this server'); - // } - // } - if ($isContainer) { $status = getContainerStatus($server, $identifier); if ($status !== 'running') { From 595a2414b133d66922e279abf87e5e2cb5a0e69c Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 17 Sep 2024 16:48:58 +0200 Subject: [PATCH 17/31] fix: if you exit a container manually, it should close the underlying tty as well --- resources/views/livewire/project/shared/terminal.blade.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/resources/views/livewire/project/shared/terminal.blade.php b/resources/views/livewire/project/shared/terminal.blade.php index 31887120d..3c485c286 100644 --- a/resources/views/livewire/project/shared/terminal.blade.php +++ b/resources/views/livewire/project/shared/terminal.blade.php @@ -118,9 +118,8 @@ socket.send(JSON.stringify({ message: data })); - // Type CTRL + D or exit in the terminal - if (data === '\x04' || (data === '\r' && stripAnsiCommands(commandBuffer).trim() === 'exit')) { + if (data === '\x04' || (data === '\r' && stripAnsiCommands(commandBuffer).trim().includes('exit'))) { checkIfProcessIsRunningAndKillIt(); setTimeout(() => { $data.terminalActive = false; @@ -215,8 +214,8 @@ term.resize(termWidth, termHeight); socket.send(JSON.stringify({ resize: { - cols: 600, - rows: 600 + cols: termWidth, + rows: termHeight } })); } From e937d30545c4a16dd4e6a5c57e9f7d624a864aa2 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 17 Sep 2024 17:15:34 +0200 Subject: [PATCH 18/31] fix: move terminal to separate view on services --- app/Livewire/Project/Service/Navbar.php | 2 ++ .../livewire/project/service/configuration.blade.php | 7 ------- .../views/livewire/project/service/navbar.blade.php | 12 ++++++++---- .../shared/execute-container-command.blade.php | 2 +- routes/web.php | 2 +- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/app/Livewire/Project/Service/Navbar.php b/app/Livewire/Project/Service/Navbar.php index 674182df5..e6bb6d9bf 100644 --- a/app/Livewire/Project/Service/Navbar.php +++ b/app/Livewire/Project/Service/Navbar.php @@ -20,6 +20,8 @@ class Navbar extends Component public $isDeploymentProgress = false; + public $title = 'Configuration'; + public function mount() { if (str($this->service->status())->contains('running') && is_null($this->service->config_hash)) { diff --git a/resources/views/livewire/project/service/configuration.blade.php b/resources/views/livewire/project/service/configuration.blade.php index c5ac0412f..4b692f9a9 100644 --- a/resources/views/livewire/project/service/configuration.blade.php +++ b/resources/views/livewire/project/service/configuration.blade.php @@ -23,10 +23,6 @@ @click.prevent="activeTab = 'scheduled-tasks'; window.location.hash = 'scheduled-tasks'" href="#">Scheduled Tasks - Terminal -
- -
diff --git a/resources/views/livewire/project/service/navbar.blade.php b/resources/views/livewire/project/service/navbar.blade.php index 125f9121a..8193fba57 100644 --- a/resources/views/livewire/project/service/navbar.blade.php +++ b/resources/views/livewire/project/service/navbar.blade.php @@ -6,17 +6,21 @@ -

Configuration

+

{{ $title }}