From 54df58d44b87f8341c7f919e8a7b9eed07ec0ee5 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 18 Jul 2023 12:50:07 +0200 Subject: [PATCH 01/76] version++ --- versions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions.json b/versions.json index 0e4f87627..04132c13c 100644 --- a/versions.json +++ b/versions.json @@ -1,7 +1,7 @@ { "coolify": { "main": { - "version": "3.12.32" + "version": "3.12.33" }, "v4": { "version": "4.0.0-beta.18" From 341f64839baa82be79ddb11dbd2474117af5d1e2 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 25 Jul 2023 14:43:32 +0200 Subject: [PATCH 02/76] fix: remove buggregator from dev --- docker-compose.dev.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index c520fabfd..41043aaa0 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -71,10 +71,10 @@ services: networks: - coolify - buggregator: - image: ghcr.io/buggregator/server:latest - container_name: coolify-debug - ports: - - 8001:8000 - networks: - - coolify + # buggregator: + # image: ghcr.io/buggregator/server:latest + # container_name: coolify-debug + # ports: + # - 8001:8000 + # networks: + # - coolify From 6cd29ad7e45752d0132806a8c76f3f0898ce6fdb Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 25 Jul 2023 14:43:49 +0200 Subject: [PATCH 03/76] fix: able to change localhost's private key --- app/Http/Livewire/PrivateKey/Change.php | 2 +- app/Http/Livewire/Server/Form.php | 21 +-- app/Http/Livewire/Server/PrivateKey.php | 14 +- bootstrap/helpers/remoteProcess.php | 42 ++++++ .../views/components/server/navbar.blade.php | 12 +- .../livewire/private-key/change.blade.php | 14 +- .../views/livewire/server/form.blade.php | 132 +++++++++--------- .../livewire/server/private-key.blade.php | 24 ++-- routes/web.php | 2 +- 9 files changed, 142 insertions(+), 121 deletions(-) diff --git a/app/Http/Livewire/PrivateKey/Change.php b/app/Http/Livewire/PrivateKey/Change.php index cbddfddf6..4f3ad4488 100644 --- a/app/Http/Livewire/PrivateKey/Change.php +++ b/app/Http/Livewire/PrivateKey/Change.php @@ -41,7 +41,7 @@ public function changePrivateKey() $this->private_key->private_key .= "\n"; } $this->private_key->save(); - session('currentTeam')->privateKeys = PrivateKey::where('team_id', session('currentTeam')->id)->get(); + refreshPrivateKey($this->private_key); } catch (\Exception $e) { return general_error_handler(err: $e, that: $this); } diff --git a/app/Http/Livewire/Server/Form.php b/app/Http/Livewire/Server/Form.php index eeb0df413..871102ada 100644 --- a/app/Http/Livewire/Server/Form.php +++ b/app/Http/Livewire/Server/Form.php @@ -49,26 +49,15 @@ public function installDocker() public function validateServer() { try { - $this->uptime = instant_remote_process(['uptime'], $this->server); - if ($this->uptime) { - $this->server->settings->is_reachable = true; - $this->server->settings->save(); - } else { - $this->uptime = 'Server not reachable.'; - throw new \Exception('Server not reachable.'); + ['uptime' => $uptime, 'dockerVersion' => $dockerVersion] = validateServer($this->server); + if ($uptime) { + $this->uptime = $uptime; } - $this->dockerVersion = instant_remote_process(['docker version|head -2|grep -i version'], $this->server, false); - if (!$this->dockerVersion) { - $this->dockerVersion = 'Not installed.'; - } else { - $this->server->settings->is_usable = true; - $this->server->settings->save(); + if ($dockerVersion) { + $this->dockerVersion = $dockerVersion; $this->emit('proxyStatusUpdated'); } } catch (\Exception $e) { - $this->server->settings->is_reachable = false; - $this->server->settings->is_usable = false; - $this->server->settings->save(); return general_error_handler(customErrorMessage: "Server is not reachable. Reason: {$e->getMessage()}", that: $this); } } diff --git a/app/Http/Livewire/Server/PrivateKey.php b/app/Http/Livewire/Server/PrivateKey.php index 36cc12bb8..54035efba 100644 --- a/app/Http/Livewire/Server/PrivateKey.php +++ b/app/Http/Livewire/Server/PrivateKey.php @@ -16,16 +16,14 @@ class PrivateKey extends Component public function checkConnection() { try { - $uptime = instant_remote_process(['uptime'], $this->server); + ['uptime' => $uptime, 'dockerVersion' => $dockerVersion] = validateServer($this->server); if ($uptime) { Toaster::success('Server is reachable with this private key.'); - $this->server->settings->is_reachable = true; - $this->server->settings->is_usable = true; + } + if ($dockerVersion) { + Toaster::success('Server is usable for Coolify.'); } } catch (\Exception $e) { - $this->server->settings->is_reachable = false; - $this->server->settings->is_usable = false; - $this->server->settings->save(); return general_error_handler(customErrorMessage: "Server is not reachable. Reason: {$e->getMessage()}", that: $this); } } @@ -34,9 +32,7 @@ public function setPrivateKey($private_key_id) $this->server->update([ 'private_key_id' => $private_key_id ]); - - // Delete the old ssh mux file to force a new one to be created - Storage::disk('ssh-mux')->delete($this->server->muxFilename()); + refreshPrivateKey($this->server->privateKey); $this->server->refresh(); $this->checkConnection(); } diff --git a/bootstrap/helpers/remoteProcess.php b/bootstrap/helpers/remoteProcess.php index cb718d8aa..93d48d77a 100644 --- a/bootstrap/helpers/remoteProcess.php +++ b/bootstrap/helpers/remoteProcess.php @@ -5,6 +5,7 @@ use App\Enums\ActivityTypes; use App\Models\Application; use App\Models\ApplicationDeploymentQueue; +use App\Models\PrivateKey; use App\Models\Server; use Carbon\Carbon; use Illuminate\Database\Eloquent\Model; @@ -148,3 +149,44 @@ function decode_remote_command_output(?ApplicationDeploymentQueue $application_d return $formatted; } + +function refreshPrivateKey(PrivateKey $private_key) +{ + foreach ($private_key->servers as $server) { + // Delete the old ssh mux file to force a new one to be created + Storage::disk('ssh-mux')->delete($server->muxFilename()); + if (session('currentTeam')->id) { + session('currentTeam')->privateKeys = PrivateKey::where('team_id', session('currentTeam')->id)->get(); + } + } +} + +function validateServer(Server $server) +{ + try { + refreshPrivateKey($server->privateKey); + $uptime = instant_remote_process(['uptime'], $server); + if (!$uptime) { + $uptime = 'Server not reachable.'; + throw new \Exception('Server not reachable.'); + } + $server->settings->is_reachable = true; + + $dockerVersion = instant_remote_process(['docker version|head -2|grep -i version'], $server, false); + if (!$dockerVersion) { + $dockerVersion = 'Not installed.'; + throw new \Exception('Docker not installed.'); + } + $server->settings->is_usable = true; + return [ + "uptime" => $uptime, + "dockerVersion" => $dockerVersion, + ]; + } catch (\Exception $e) { + $server->settings->is_reachable = false; + $server->settings->is_usable = false; + throw $e; + } finally { + $server->settings->save(); + } +} diff --git a/resources/views/components/server/navbar.blade.php b/resources/views/components/server/navbar.blade.php index dcfd76dbb..8158e45c8 100644 --- a/resources/views/components/server/navbar.blade.php +++ b/resources/views/components/server/navbar.blade.php @@ -8,18 +8,18 @@ ]) }}"> - - - + + +

Private Key

+ + Save + @if ($private_key->id > 0) - - Save - Delete @@ -21,7 +21,7 @@
Private Key *
- Show + Edit
@@ -38,11 +38,7 @@ disabled />
- @if ($private_key->id === 0) - - @else - - @endif +
diff --git a/resources/views/livewire/server/form.blade.php b/resources/views/livewire/server/form.blade.php index c69d530e9..ce8285c29 100644 --- a/resources/views/livewire/server/form.blade.php +++ b/resources/views/livewire/server/form.blade.php @@ -1,48 +1,48 @@
- - -

This server will be deleted. It is not reversible.
Please think again..

-
-
- -
-
-

General

- @if ($server->id === 0) - Save - @else - Save - @endif -
-
-
- - - - {{-- --}} -
-
+ @if ($server->settings->is_reachable) + + +

This server will be deleted. It is not reversible.
Please think again..

+
+
+ + +
+

General

@if ($server->id === 0) - + Save @else - + Save @endif -
- - +
+
+
+ + + + {{-- --}} +
+
+ @if ($server->id === 0) + + @else + + @endif +
+ + +
-
-

Settings

-
- -
-

Actions

- @if ($server->settings->is_reachable) +

Settings

+
+ +
+

Actions

Check Server Details @@ -57,35 +57,35 @@ @endif
- @else -
- - Validate Server - +
+
- @endif -
- + @isset($uptime) +

Server Info

+
+

Uptime: {{ $uptime }}

+ @isset($dockerVersion) +

Docker Engine {{ $dockerVersion }}

+ @endisset +
+ @endisset + +

Danger Zone

+
Woah. I hope you know what are you doing.
+

Delete Server

+
This will remove this server from Coolify. Beware! There is no coming + back!
- @isset($uptime) -

Server Info

-
-

Uptime: {{ $uptime }}

- @isset($dockerVersion) -

Docker Engine {{ $dockerVersion }}

- @endisset + @if ($server->id !== 0 || isDev()) + + Delete + + @endif + @else +
+
+ Validate Server
- @endisset - -

Danger Zone

-
Woah. I hope you know what are you doing.
-

Delete Server

-
This will remove this server from Coolify. Beware! There is no coming - back! -
- @if ($server->id !== 0 || isDev()) - - Delete - +
@endif
diff --git a/resources/views/livewire/server/private-key.blade.php b/resources/views/livewire/server/private-key.blade.php index 10696901b..ae5877e97 100644 --- a/resources/views/livewire/server/private-key.blade.php +++ b/resources/views/livewire/server/private-key.blade.php @@ -22,17 +22,15 @@ @endif
- @if ($server->id !== 0) -

Select a different Private Key

-
- @forelse ($privateKeys as $private_key) - {{ $private_key->name }} - - @empty -
No private keys found. - -
- @endforelse -
- @endif +

Select a different Private Key

+
+ @forelse ($privateKeys as $private_key) +
{{ $private_key->name }} +
+ @empty +
No private keys found. + +
+ @endforelse +
diff --git a/routes/web.php b/routes/web.php index 10e15d77d..d08aeac20 100644 --- a/routes/web.php +++ b/routes/web.php @@ -74,7 +74,7 @@ ]))->name('server.proxy'); Route::get('/server/{server_uuid}/private-key', fn () => view('server.private-key', [ 'server' => Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->firstOrFail(), - 'privateKeys' => PrivateKey::ownedByCurrentTeam()->where('id', '!=', 0)->get(), + 'privateKeys' => PrivateKey::ownedByCurrentTeam()->get(), ]))->name('server.private-key'); Route::get('/server/{server_uuid}/destinations', fn () => view('server.destinations', [ 'server' => Server::ownedByCurrentTeam(['name'])->whereUuid(request()->server_uuid)->firstOrFail() From ef065d480a9b0cf40b062ff4556ce34e290dd874 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 25 Jul 2023 14:49:20 +0200 Subject: [PATCH 04/76] version++ --- config/version.php | 2 +- versions.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/version.php b/config/version.php index 743126446..8ecc24277 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ Date: Tue, 25 Jul 2023 15:13:35 +0200 Subject: [PATCH 05/76] revert version --- versions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions.json b/versions.json index b4dda3576..04132c13c 100644 --- a/versions.json +++ b/versions.json @@ -4,7 +4,7 @@ "version": "3.12.33" }, "v4": { - "version": "4.0.0-beta.19" + "version": "4.0.0-beta.18" } } } \ No newline at end of file From 8deeb59d5c7612bc1f5e0f8ef975a9741b63a409 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 25 Jul 2023 15:23:16 +0200 Subject: [PATCH 06/76] fix: readonly input box --- resources/views/components/forms/input.blade.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/resources/views/components/forms/input.blade.php b/resources/views/components/forms/input.blade.php index 3631482e0..bab75c13c 100644 --- a/resources/views/components/forms/input.blade.php +++ b/resources/views/components/forms/input.blade.php @@ -14,7 +14,7 @@ class="flex items-center gap-1 mb-2 text-sm font-medium text-neutral-400">{{ $la merge(['class' => $defaultClass]) }} @required($required) wire:model.defer={{ $id }} wire:dirty.class.remove='text-white' wire:dirty.class="text-black bg-warning" wire:loading.attr="disabled" type="{{ $type }}" - @disabled($disabled) id="{{ $id }}" name="{{ $name }}"> + @disabled($readonly) @disabled($disabled) id="{{ $id }}" name="{{ $name }}"> @elseif ($type === 'password')
@if ($allowToPeak) @@ -31,7 +31,8 @@ class="absolute inset-y-0 left-0 flex items-center pl-2 cursor-pointer hover:tex merge(['class' => $defaultClass . ' pl-10']) }} @required($required) wire:model.defer={{ $id }} wire:dirty.class.remove='text-white' wire:dirty.class="text-black bg-warning" wire:loading.attr="disabled" type="{{ $type }}" - @disabled($disabled) id="{{ $id }}" name="{{ $name }}"> + @disabled($readonly) @disabled($disabled) id="{{ $id }}" + name="{{ $name }}">
@endif @if (!$label && $helper) From fd897355215f9d9f656c50a8fb600d443ebcba4a Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 26 Jul 2023 13:23:47 +0200 Subject: [PATCH 07/76] Added +add flows everywhere ui: changed vibrant button to not so vibrant --- app/Http/Controllers/ProjectController.php | 12 +- app/Http/Livewire/PrivateKey/Create.php | 2 +- app/Http/Livewire/Project/AddEmpty.php | 36 ++++ app/Http/Livewire/Project/AddEnvironment.php | 39 ++++ .../Project/New/GithubPrivateRepository.php | 2 + .../New/GithubPrivateRepositoryDeployKey.php | 2 + .../Project/New/PublicGitRepository.php | 2 + app/Http/Livewire/Project/New/Select.php | 47 +++++ app/Models/Project.php | 4 + app/View/Components/Forms/Button.php | 4 +- resources/css/app.css | 28 +-- .../{actions.blade.php => advanced.blade.php} | 37 +--- .../components/applications/navbar.blade.php | 37 +++- .../views/components/forms/select.blade.php | 2 +- resources/views/components/navbar.blade.php | 31 ++-- .../views/components/server/navbar.blade.php | 2 +- .../components/settings/navbar.blade.php | 2 +- .../views/components/team/navbar.blade.php | 2 +- .../views/components/use-magic-bar.blade.php | 12 +- .../livewire/private-key/change.blade.php | 2 +- .../livewire/project/add-empty.blade.php | 12 ++ .../project/add-environment.blade.php | 11 ++ .../project/application/source.blade.php | 13 +- .../project/delete-environment.blade.php | 2 +- .../livewire/project/delete-project.blade.php | 2 +- .../views/livewire/project/edit.blade.php | 3 + ...ub-private-repository-deploy-key.blade.php | 95 ++++++---- .../new/github-private-repository.blade.php | 168 ++++++++++-------- .../new/public-git-repository.blade.php | 15 +- .../livewire/project/new/select.blade.php | 87 +++++++++ .../views/livewire/server/form.blade.php | 40 +++-- .../livewire/source/github/change.blade.php | 9 +- resources/views/private-key/all.blade.php | 2 +- resources/views/project/new.blade.php | 2 + resources/views/project/resources.blade.php | 3 + resources/views/project/show.blade.php | 5 +- resources/views/projects.blade.php | 66 ++++--- resources/views/server/all.blade.php | 5 +- resources/views/server/create.blade.php | 4 +- tailwind.config.js | 3 +- 40 files changed, 578 insertions(+), 274 deletions(-) create mode 100644 app/Http/Livewire/Project/AddEmpty.php create mode 100644 app/Http/Livewire/Project/AddEnvironment.php create mode 100644 app/Http/Livewire/Project/New/Select.php rename resources/views/components/applications/{actions.blade.php => advanced.blade.php} (54%) create mode 100644 resources/views/livewire/project/add-empty.blade.php create mode 100644 resources/views/livewire/project/add-environment.blade.php create mode 100644 resources/views/livewire/project/new/select.blade.php diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php index 432e72f39..e56edf17b 100644 --- a/app/Http/Controllers/ProjectController.php +++ b/app/Http/Controllers/ProjectController.php @@ -3,15 +3,16 @@ namespace App\Http\Controllers; use App\Models\Project; +use App\Models\Server; class ProjectController extends Controller { public function all() { - $teamId = session('currentTeam')->id; - - $projects = Project::where('team_id', $teamId)->get(); - return view('projects', ['projects' => $projects]); + return view('projects', [ + 'projects' => Project::ownedByCurrentTeam()->get(), + 'servers' => Server::ownedByCurrentTeam()->count(), + ]); } public function edit() @@ -34,9 +35,6 @@ public function show() return redirect()->route('dashboard'); } $project->load(['environments']); - if (count($project->environments) == 1) { - return redirect()->route('project.resources', ['project_uuid' => $project->uuid, 'environment_name' => $project->environments->first()->name]); - } return view('project.show', ['project' => $project]); } diff --git a/app/Http/Livewire/PrivateKey/Create.php b/app/Http/Livewire/PrivateKey/Create.php index af147a9e3..bfbf72e18 100644 --- a/app/Http/Livewire/PrivateKey/Create.php +++ b/app/Http/Livewire/PrivateKey/Create.php @@ -7,7 +7,7 @@ class Create extends Component { - protected string|null $from = null; + public string|null $from = null; public string $name; public string|null $description = null; public string $value; diff --git a/app/Http/Livewire/Project/AddEmpty.php b/app/Http/Livewire/Project/AddEmpty.php new file mode 100644 index 000000000..98136fb86 --- /dev/null +++ b/app/Http/Livewire/Project/AddEmpty.php @@ -0,0 +1,36 @@ + 'required|string|min:3', + 'description' => 'nullable|string', + ]; + protected $validationAttributes = [ + 'name' => 'Project Name', + 'description' => 'Project Description', + ]; + public function submit() + { + try { + $this->validate(); + $project = Project::create([ + 'name' => $this->name, + 'description' => $this->description, + 'team_id' => auth()->user()->currentTeam()->id, + ]); + return redirect()->route('project.show', $project->uuid); + } catch (\Exception $e) { + general_error_handler($e, $this); + } finally { + $this->name = ''; + } + } +} diff --git a/app/Http/Livewire/Project/AddEnvironment.php b/app/Http/Livewire/Project/AddEnvironment.php new file mode 100644 index 000000000..3ca6d8de3 --- /dev/null +++ b/app/Http/Livewire/Project/AddEnvironment.php @@ -0,0 +1,39 @@ + 'required|string|min:3', + ]; + protected $validationAttributes = [ + 'name' => 'Environment Name', + ]; + public function submit() + { + try { + $this->validate(); + $environment = Environment::create([ + 'name' => $this->name, + 'project_id' => $this->project->id, + ]); + + return redirect()->route('project.resources', [ + 'project_uuid' => $this->project->uuid, + 'environment_name' => $environment->name, + ]); + } catch (\Exception $e) { + general_error_handler($e, $this); + } finally { + $this->name = ''; + } + } +} diff --git a/app/Http/Livewire/Project/New/GithubPrivateRepository.php b/app/Http/Livewire/Project/New/GithubPrivateRepository.php index 89dab6b72..d092670a3 100644 --- a/app/Http/Livewire/Project/New/GithubPrivateRepository.php +++ b/app/Http/Livewire/Project/New/GithubPrivateRepository.php @@ -15,6 +15,7 @@ class GithubPrivateRepository extends Component { + public $current_step = 'github_apps'; public $github_apps; public GithubApp $github_app; public $parameters; @@ -90,6 +91,7 @@ public function loadRepositories($github_app_id) } } $this->selected_repository_id = $this->repositories[0]['id']; + $this->current_step = 'repository'; } public function loadBranches() { diff --git a/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php b/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php index 8f8611c4d..cfb528f1e 100644 --- a/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php +++ b/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php @@ -14,6 +14,7 @@ class GithubPrivateRepositoryDeployKey extends Component { + public $current_step = 'private_keys'; public $parameters; public $query; public $private_keys; @@ -70,6 +71,7 @@ public function instantSave() public function setPrivateKey($private_key_id) { $this->private_key_id = $private_key_id; + $this->current_step = 'repository'; } private function get_git_source() { diff --git a/app/Http/Livewire/Project/New/PublicGitRepository.php b/app/Http/Livewire/Project/New/PublicGitRepository.php index 8fbaf62fb..181a308bd 100644 --- a/app/Http/Livewire/Project/New/PublicGitRepository.php +++ b/app/Http/Livewire/Project/New/PublicGitRepository.php @@ -82,7 +82,9 @@ public function load_branch() $this->get_git_source(); try { $this->get_branch(); + $this->selected_branch = $this->git_branch; } catch (\Exception $e) { + return general_error_handler(err: $e, that: $this); } if (!$this->branch_found && $this->git_branch == 'main') { diff --git a/app/Http/Livewire/Project/New/Select.php b/app/Http/Livewire/Project/New/Select.php new file mode 100644 index 000000000..3e6137891 --- /dev/null +++ b/app/Http/Livewire/Project/New/Select.php @@ -0,0 +1,47 @@ +parameters = getRouteParameters(); + } + public function set_type(string $type) + { + $this->type = $type; + $this->current_step = 'servers'; + } + public function set_server(Server $server) + { + $this->server_id = $server->id; + $this->destinations = $server->destinations(); + $this->current_step = 'destinations'; + } + public function set_destination(string $destination_uuid) + { + $this->destination_uuid = $destination_uuid; + redirect()->route('project.resources.new', [ + 'project_uuid' => $this->parameters['project_uuid'], + 'environment_name' => $this->parameters['environment_name'], + 'type' => $this->type, + 'destination' => $this->destination_uuid, + ]); + } + public function load_servers() + { + $this->servers = Server::ownedByCurrentTeam()->get(); + } +} diff --git a/app/Models/Project.php b/app/Models/Project.php index 073c654b6..a0a342755 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -15,6 +15,10 @@ protected static function booted() 'project_id' => $project->id, ]); }); + static::deleted(function ($project) { + $project->environments()->delete(); + $project->settings()->delete(); + }); } protected $fillable = [ 'name', diff --git a/app/View/Components/Forms/Button.php b/app/View/Components/Forms/Button.php index 0f33192f7..b347fefd1 100644 --- a/app/View/Components/Forms/Button.php +++ b/app/View/Components/Forms/Button.php @@ -15,7 +15,7 @@ public function __construct( public bool $disabled = false, public bool $isModal = false, public string|null $modalId = null, - public string $defaultClass = "btn btn-primary btn-xs text-white normal-case no-animation rounded border-none" + public string $defaultClass = "btn btn-primary btn-sm font-normal text-white normal-case no-animation rounded border-none" ) { // } @@ -27,4 +27,4 @@ public function render(): View|Closure|string { return view('components.forms.button'); } -} \ No newline at end of file +} diff --git a/resources/css/app.css b/resources/css/app.css index 5bca7271f..979bc99aa 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -9,7 +9,7 @@ body { @apply text-sm antialiased scrollbar; } button[isError] { - @apply bg-red-600 hover:bg-red-500; + @apply bg-red-600 hover:bg-red-700; } .scrollbar { @apply scrollbar-thumb-coollabs-100 scrollbar-track-coolgray-200 scrollbar-w-2; @@ -17,37 +17,17 @@ .scrollbar { .main { @apply max-w-screen-xl pt-4 pl-24 pr-10 mx-auto; } -/* input { - @apply w-full text-white rounded outline-none input input-sm h-7 placeholder:text-neutral-700 bg-coolgray-200 read-only:bg-coolgray-200/50 read-only:text-opacity-25; -} -input:not(input[type="checkbox"]) { - @apply border-none disabled:border-none; -} -input[type="checkbox"] { - @apply rounded toggle toggle-warning toggle-xs disabled:toggle-warning; -} */ - -/* textarea { - @apply text-xs leading-5 text-white rounded textarea read-only:bg-coolgray-200/50 disabled:border-none read-only:text-opacity-25 placeholder:text-neutral-700 scrollbar bg-coolgray-200; -} -select { - @apply font-normal text-white border-none rounded h-7 select select-xs disabled:bg-coolgray-200 disabled:opacity-50 placeholder:text-neutral-700 bg-coolgray-200; -} */ .label-text, label { @apply text-neutral-400; } +.navbar-main { + @apply flex items-end gap-6 py-2 border-b-2 border-solid border-coolgray-200; +} .loading { @apply w-4 text-warning; } - -/* button[isWarning] { - @apply bg-red-600 hover:bg-red-500; -} -button[isHighlighted] { - @apply text-white btn-primary; -} */ h1 { @apply text-3xl font-bold text-white; } diff --git a/resources/views/components/applications/actions.blade.php b/resources/views/components/applications/advanced.blade.php similarity index 54% rename from resources/views/components/applications/actions.blade.php rename to resources/views/components/applications/advanced.blade.php index fe5b235fc..38410a026 100644 --- a/resources/views/components/applications/actions.blade.php +++ b/resources/views/components/applications/advanced.blade.php @@ -1,23 +1,12 @@
- diff --git a/resources/views/livewire/project/delete-environment.blade.php b/resources/views/livewire/project/delete-environment.blade.php index ef9650af5..485a6cddb 100644 --- a/resources/views/livewire/project/delete-environment.blade.php +++ b/resources/views/livewire/project/delete-environment.blade.php @@ -1,7 +1,7 @@
- + Delete Environment
diff --git a/resources/views/livewire/project/delete-project.blade.php b/resources/views/livewire/project/delete-project.blade.php index 169586ed0..710c47641 100644 --- a/resources/views/livewire/project/delete-project.blade.php +++ b/resources/views/livewire/project/delete-project.blade.php @@ -1,7 +1,7 @@
- + Delete Project
diff --git a/resources/views/livewire/project/edit.blade.php b/resources/views/livewire/project/edit.blade.php index dfcab8d22..1d212956e 100644 --- a/resources/views/livewire/project/edit.blade.php +++ b/resources/views/livewire/project/edit.blade.php @@ -3,6 +3,9 @@

Project: {{ data_get($project, 'name') }}

Save + @if ($project->applications->count() === 0) + + @endif
Edit project details here.
diff --git a/resources/views/livewire/project/new/github-private-repository-deploy-key.blade.php b/resources/views/livewire/project/new/github-private-repository-deploy-key.blade.php index b82055dc7..d0501eb06 100644 --- a/resources/views/livewire/project/new/github-private-repository-deploy-key.blade.php +++ b/resources/views/livewire/project/new/github-private-repository-deploy-key.blade.php @@ -1,39 +1,64 @@

Create a new Application

-
Deploy any public or private GIT repositories through a Deploy Key.
-

Select a Private Key

- @foreach ($private_keys as $key) - @if ($private_key_id == $key->id) - - {{ $key->name }} - @else - {{ $key->name }} - +
Deploy any public or private Git repositories through a Deploy Key.
+
+ @if ($current_step === 'private_keys') +
    +
  • Select a Private Key
  • +
  • Select a Repository, Branch & Save
  • +
+
+ @foreach ($private_keys as $key) + @if ($private_key_id == $key->id) +
+
+
+ {{ $key->name }} +
+ +
+
+ @else +
+
+
+ {{ $key->name }} +
+ +
+
+ @endif + @endforeach +
@endif - @endforeach - - + - - @isset($private_key_id) -
-
- - - @if ($is_static) - - @else - - @endif -
-

Settings

-
- -
- - Save New Application - -
- @endisset + @if ($current_step === 'repository') +
    +
  • Select a Private Key
  • +
  • Select a Repository, Branch & Save
  • +
+
+
+ + + @if ($is_static) + + @else + + @endif +
+
+ +
+ + Save New Application + +
+ @endif +
diff --git a/resources/views/livewire/project/new/github-private-repository.blade.php b/resources/views/livewire/project/new/github-private-repository.blade.php index 93d090196..9d11f47ba 100644 --- a/resources/views/livewire/project/new/github-private-repository.blade.php +++ b/resources/views/livewire/project/new/github-private-repository.blade.php @@ -2,80 +2,106 @@

Create a new Application

Deploy any public or private git repositories through a GitHub App.
@if ($github_apps->count() > 0) -
-
-

Select a GitHub App

- @foreach ($github_apps as $ghapp) - @if ($selected_github_app_id == $ghapp->id) - - {{ $ghapp->name }} - - @else - - {{ $ghapp->name }} - - @endif - @endforeach -
- @if ($repositories->count() > 0) -
- - @foreach ($repositories as $repo) - @if ($loop->first) - - @else - - @endif - @endforeach - - Check - repository -
- @endif +
+ @if ($current_step === 'github_apps') +
    +
  • Select a GitHub App
  • +
  • Select a Repository, Branch & Save
  • +
+
+ @foreach ($github_apps as $ghapp) + @if ($selected_github_app_id == $ghapp->id) +
+
+
+ {{ $ghapp->name }} +
+ +
+
+ @else +
+
+
+ {{ $ghapp->name }} +
+ +
+
+ @endif + @endforeach
- @if ($branches->count() > 0) -
-
- - - @foreach ($branches as $branch) - @if ($loop->first) - - @else - - @endif - @endforeach - - @if ($is_static) - - @else - - @endif -
-

Settings

-
- -
+ @endif + @if ($current_step === 'repository') +
    +
  • Select a GitHub App
  • +
  • Select a Repository, Branch & Save
  • +
+ @if ($repositories->count() > 0) +
+ + @foreach ($repositories as $repo) + @if ($loop->first) + + @else + + @endif + @endforeach + + Check + repository
- - Save New Application - + @else +
No repositories found. Check your GitHub App configuration.
@endif -
- + @if ($branches->count() > 0) +

Details

+
+
+
+
+ + + @foreach ($branches as $branch) + @if ($loop->first) + + @else + + @endif + @endforeach + + @if ($is_static) + + @else + + @endif +
+
+ +
+
+ + Save New Application + + @endif + @endif +
@else
No Git App found.
diff --git a/resources/views/livewire/project/new/public-git-repository.blade.php b/resources/views/livewire/project/new/public-git-repository.blade.php index 21af86a2e..2b9ee568c 100644 --- a/resources/views/livewire/project/new/public-git-repository.blade.php +++ b/resources/views/livewire/project/new/public-git-repository.blade.php @@ -1,6 +1,6 @@

Create a new Application

-
Deploy any public git repositories.
+
Deploy any public Git repositories.
@@ -12,10 +12,14 @@
@if ($branch_found) -
-
Rate limit remaining: {{ $rate_limit_remaining }}
-
Rate limit reset at: {{ $rate_limit_reset }}
-
+ @if ($rate_limit_remaining && $rate_limit_reset) +
+
Rate Limit
+ +
+ @endif +

Details

@endif
-

Settings

diff --git a/resources/views/livewire/project/new/select.blade.php b/resources/views/livewire/project/new/select.blade.php new file mode 100644 index 000000000..7ee5806ee --- /dev/null +++ b/resources/views/livewire/project/new/select.blade.php @@ -0,0 +1,87 @@ +
+

New Resource

+
Deploy any Git repository from different sources.
+
+ @if ($current_step === 'type') +
    +
  • Application Type
  • +
  • Select a Server
  • +
  • Select a Destination
  • +
+
+
+
+
+ Public Repository +
+
+ You can deploy any kind of public repositories from the supported git servers.
+
+
+
+
+
+ Private Repository +
+
+ You can deploy public & private repositories through your GitHub Apps.
+
+
+
+
+
+ Private Repository (with deploy key) +
+
+ You can deploy public & private repositories with a simple deploy key.
+
+
+
+ @endif + @if ($current_step === 'servers') +
    +
  • Application Type
  • +
  • Select a Server
  • +
  • Select a Destination
  • +
+
+ @foreach ($servers as $server) +
+
+
+ {{ $server->name }} +
+
+ {{ $server->description }}
+
+
+ @endforeach +
+ @endif + @if ($current_step === 'destinations') +
    +
  • Application Type
  • +
  • Select a Server
  • +
  • Select a Destination
  • +
+
+ @foreach ($destinations as $destination) +
+
+
+ {{ $destination->name }} +
+
+ {{ $destination->description }}
+
+
+ @endforeach +
+ @endif +
+
diff --git a/resources/views/livewire/server/form.blade.php b/resources/views/livewire/server/form.blade.php index ce8285c29..19769195e 100644 --- a/resources/views/livewire/server/form.blade.php +++ b/resources/views/livewire/server/form.blade.php @@ -1,12 +1,14 @@
+ + +

This server will be deleted. It is not reversible.
Please think again..

+
+
+ @if ($server->settings->is_reachable) - - -

This server will be deleted. It is not reversible.
Please think again..

-
-
- + +

General

@@ -70,22 +72,22 @@
@endisset -

Danger Zone

-
Woah. I hope you know what are you doing.
-

Delete Server

-
This will remove this server from Coolify. Beware! There is no coming - back! -
- @if ($server->id !== 0 || isDev()) - - Delete - - @endif @else -
+
Validate Server
@endif +

Danger Zone

+
Woah. I hope you know what are you doing.
+

Delete Server

+
This will remove this server from Coolify. Beware! There is no coming + back! +
+ @if ($server->id !== 0 || isDev()) + + Delete + + @endif
diff --git a/resources/views/livewire/source/github/change.blade.php b/resources/views/livewire/source/github/change.blade.php index 733c3cdca..e0df502a9 100644 --- a/resources/views/livewire/source/github/change.blade.php +++ b/resources/views/livewire/source/github/change.blade.php @@ -7,9 +7,7 @@
@if ($github_app->app_id) Save - - Delete - + @if ($github_app->installation_id) @@ -21,9 +19,12 @@ @endif + + Delete + @else Save - + Delete diff --git a/resources/views/private-key/all.blade.php b/resources/views/private-key/all.blade.php index 89b50454b..2a99f75dc 100644 --- a/resources/views/private-key/all.blade.php +++ b/resources/views/private-key/all.blade.php @@ -12,7 +12,7 @@ @empty
No private keys found.
- +
@endforelse
diff --git a/resources/views/project/new.blade.php b/resources/views/project/new.blade.php index dbbce57cd..b3b13215e 100644 --- a/resources/views/project/new.blade.php +++ b/resources/views/project/new.blade.php @@ -5,5 +5,7 @@ @elseif ($type === 'private-deploy-key') + @else + @endif diff --git a/resources/views/project/resources.blade.php b/resources/views/project/resources.blade.php index e412f1014..0c4060a00 100644 --- a/resources/views/project/resources.blade.php +++ b/resources/views/project/resources.blade.php @@ -2,6 +2,9 @@

Resources

+ + + Add @if ($environment->applications->count() === 0) @endif diff --git a/resources/views/project/show.blade.php b/resources/views/project/show.blade.php index d2568c91f..05f9ae195 100644 --- a/resources/views/project/show.blade.php +++ b/resources/views/project/show.blade.php @@ -1,9 +1,8 @@

Environments

- @if ($project->applications->count() === 0) - - @endif + + Add +
{{ $project->name }}
diff --git a/resources/views/projects.blade.php b/resources/views/projects.blade.php index 51a99cd56..f8df0bf4f 100644 --- a/resources/views/projects.blade.php +++ b/resources/views/projects.blade.php @@ -1,34 +1,48 @@ -

Projects

+
+

Projects

+ @if ($servers > 0) + + Add + + @endif +
All Projects
- @forelse ($projects as $project) -
-
- {{ $project->name }} -
- {{ $project->description }}
-
-
- - - - - -
- @empty + @if ($servers === 0)
-
No project found.
- +
No servers found. Without a server, you won't be able to do much.
+
- @endforelse + @else + @forelse ($projects as $project) +
+
+ {{ $project->name }} +
+ {{ $project->description }}
+
+
+ + + + + +
+ @empty +
+
No project found.
+ +
+ @endforelse + @endif + + diff --git a/resources/views/team/storages/create.blade.php b/resources/views/team/storages/create.blade.php new file mode 100644 index 000000000..711c521e3 --- /dev/null +++ b/resources/views/team/storages/create.blade.php @@ -0,0 +1,3 @@ + + + diff --git a/resources/views/team/storages/show.blade.php b/resources/views/team/storages/show.blade.php new file mode 100644 index 000000000..75b81d9f5 --- /dev/null +++ b/resources/views/team/storages/show.blade.php @@ -0,0 +1,4 @@ + + + + diff --git a/routes/web.php b/routes/web.php index 18d57474b..91a4aa2ab 100644 --- a/routes/web.php +++ b/routes/web.php @@ -92,6 +92,9 @@ Route::get('/team', [Controller::class, 'team'])->name('team.show'); Route::get('/team/new', fn () => view('team.create'))->name('team.create'); Route::get('/team/notifications', fn () => view('team.notifications'))->name('team.notifications'); + Route::get('/team/storages', [Controller::class, 'storages'])->name('team.storages.all'); + Route::get('/team/storages/new', fn () => view('team.storages.create'))->name('team.storages.new'); + Route::get('/team/storages/{storage_uuid}', [Controller::class, 'storages_show'])->name('team.storages.show'); Route::get('/team/members', [Controller::class, 'members'])->name('team.members'); Route::get('/command-center', fn () => view('command-center', ['servers' => Server::isReachable()->get()]))->name('command-center'); Route::get('/invitations/{uuid}', [Controller::class, 'acceptInvitation'])->name('team.invitation.accept'); From 305bf188192a4183fd3dc69db0066dc53bf2329d Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 7 Aug 2023 15:36:03 +0200 Subject: [PATCH 34/76] remove do seeder --- database/seeders/S3StorageSeeder.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/database/seeders/S3StorageSeeder.php b/database/seeders/S3StorageSeeder.php index 348455cff..499510717 100644 --- a/database/seeders/S3StorageSeeder.php +++ b/database/seeders/S3StorageSeeder.php @@ -22,14 +22,5 @@ public function run(): void 'endpoint' => 'http://coolify-minio:9000', 'team_id' => 0, ]); - S3Storage::create([ - 'name' => 'DO Spaces', - 'description' => 'DO S3 Storage', - 'key' => 'DO003UBFTACPQGUXUANY', - 'secret' => 'eXDSco/04+5RHti19X8O/QE1aWIhZHAyyuOEs4J1JWA', - 'bucket' => 'files', - 'endpoint' => 'https://test-coolify.ams3.digitaloceanspaces.com', - 'team_id' => 0, - ]); } } \ No newline at end of file From 0a040a0531f2d8790bbaa96146a482da21951ef6 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 7 Aug 2023 16:28:07 +0200 Subject: [PATCH 35/76] fix: empty description --- app/Http/Livewire/Team/Storage/Create.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Livewire/Team/Storage/Create.php b/app/Http/Livewire/Team/Storage/Create.php index 5ac19d743..997b95015 100644 --- a/app/Http/Livewire/Team/Storage/Create.php +++ b/app/Http/Livewire/Team/Storage/Create.php @@ -56,7 +56,7 @@ public function submit() { $this->validate(); $this->storage = new S3Storage(); $this->storage->name = $this->name; - $this->storage->description = $this->description; + $this->storage->description = $this->description ?? null; $this->storage->region = $this->region; $this->storage->key = $this->key; $this->storage->secret = $this->secret; From a020bc872d74f54cc0461fbb6c020f792f5f6ee9 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 7 Aug 2023 18:46:40 +0200 Subject: [PATCH 36/76] feat: init postgresql database --- app/Actions/Database/StartPostgresql.php | 25 +++++++ .../Controllers/ApplicationController.php | 2 +- app/Http/Controllers/Controller.php | 2 + app/Http/Controllers/DatabaseController.php | 30 +++++++++ app/Http/Livewire/ActivityMonitor.php | 2 +- app/Http/Livewire/{ => Dev}/S3Test.php | 3 +- .../Livewire/Project/Application/General.php | 2 + .../{ => Project}/Application/Heading.php | 2 +- .../Livewire/Project/Database/Heading.php | 23 +++++++ .../Project/Database/Postgresql/General.php | 39 +++++++++++ app/Models/Environment.php | 12 +++- app/Models/Postgresql.php | 25 +++++++ app/Models/Project.php | 6 +- app/Models/S3Storage.php | 4 ++ app/Models/StandaloneDocker.php | 6 +- app/View/Components/Modal.php | 4 +- ..._08_07_073651_create_s3_storages_table.php | 2 +- ..._08_07_142950_create_postgresqls_table.php | 42 ++++++++++++ ...scription_field_to_applications_table.php} | 17 ++--- database/seeders/ApplicationSeeder.php | 10 ++- database/seeders/DatabaseSeeder.php | 1 + database/seeders/PostgresqlSeeder.php | 26 ++++++++ .../components/databases/navbar.blade.php | 41 ++++++++++++ resources/views/components/modal.blade.php | 11 +++- .../breadcrumbs.blade.php | 8 +-- resources/views/dashboard.blade.php | 2 +- .../livewire/{ => dev}/s3-test.blade.php | 0 .../project/application/general.blade.php | 29 +++++---- .../application/heading.blade.php | 2 +- .../project/database/heading.blade.php | 4 ++ .../database/postgresql/general.blade.php | 18 +++++ .../application/configuration.blade.php | 2 +- .../project/application/deployment.blade.php | 2 +- .../project/application/deployments.blade.php | 2 +- resources/views/project/database.blade.php | 5 -- .../project/database/configuration.blade.php | 65 +++++++++++++++++++ resources/views/project/resources.blade.php | 18 ++++- routes/web.php | 2 + 38 files changed, 430 insertions(+), 66 deletions(-) create mode 100644 app/Actions/Database/StartPostgresql.php create mode 100644 app/Http/Controllers/DatabaseController.php rename app/Http/Livewire/{ => Dev}/S3Test.php (94%) rename app/Http/Livewire/{ => Project}/Application/Heading.php (97%) create mode 100644 app/Http/Livewire/Project/Database/Heading.php create mode 100644 app/Http/Livewire/Project/Database/Postgresql/General.php create mode 100644 app/Models/Postgresql.php create mode 100644 database/migrations/2023_08_07_142950_create_postgresqls_table.php rename database/migrations/{2023_03_27_083620_create_databases_table.php => 2023_08_07_142951_add_description_field_to_applications_table.php} (51%) create mode 100644 database/seeders/PostgresqlSeeder.php create mode 100644 resources/views/components/databases/navbar.blade.php rename resources/views/components/{applications => resources}/breadcrumbs.blade.php (91%) rename resources/views/livewire/{ => dev}/s3-test.blade.php (100%) rename resources/views/livewire/{ => project}/application/heading.blade.php (63%) create mode 100644 resources/views/livewire/project/database/heading.blade.php create mode 100644 resources/views/livewire/project/database/postgresql/general.blade.php delete mode 100644 resources/views/project/database.blade.php create mode 100644 resources/views/project/database/configuration.blade.php diff --git a/app/Actions/Database/StartPostgresql.php b/app/Actions/Database/StartPostgresql.php new file mode 100644 index 000000000..d9f2c8846 --- /dev/null +++ b/app/Actions/Database/StartPostgresql.php @@ -0,0 +1,25 @@ + $deploymentUuid, ]); } -} +} \ No newline at end of file diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 60549c381..a37672983 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -43,7 +43,9 @@ public function dashboard() $s3s = S3Storage::ownedByCurrentTeam()->get(); $resources = 0; foreach ($projects as $project) { + ray($project->postgresqls); $resources += $project->applications->count(); + $resources += $project->postgresqls->count(); } return view('dashboard', [ diff --git a/app/Http/Controllers/DatabaseController.php b/app/Http/Controllers/DatabaseController.php new file mode 100644 index 000000000..7adb53f1f --- /dev/null +++ b/app/Http/Controllers/DatabaseController.php @@ -0,0 +1,30 @@ +load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); + if (!$project) { + return redirect()->route('dashboard'); + } + $environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']); + if (!$environment) { + return redirect()->route('dashboard'); + } + $database = $environment->databases->where('uuid', request()->route('database_uuid'))->first(); + if (!$database) { + return redirect()->route('dashboard'); + } + return view('project.database.configuration', ['database' => $database]); + } +} \ No newline at end of file diff --git a/app/Http/Livewire/ActivityMonitor.php b/app/Http/Livewire/ActivityMonitor.php index 4352b9dc9..b11bcdb38 100644 --- a/app/Http/Livewire/ActivityMonitor.php +++ b/app/Http/Livewire/ActivityMonitor.php @@ -51,4 +51,4 @@ protected function setStatus($status) ]); $this->activity->save(); } -} +} \ No newline at end of file diff --git a/app/Http/Livewire/S3Test.php b/app/Http/Livewire/Dev/S3Test.php similarity index 94% rename from app/Http/Livewire/S3Test.php rename to app/Http/Livewire/Dev/S3Test.php index 57ef3728e..7aaf732bc 100644 --- a/app/Http/Livewire/S3Test.php +++ b/app/Http/Livewire/Dev/S3Test.php @@ -1,6 +1,6 @@ s3 = S3Storage::first(); - ray($this->s3); } public function save() { try { diff --git a/app/Http/Livewire/Project/Application/General.php b/app/Http/Livewire/Project/Application/General.php index f632a4431..2d15489fb 100644 --- a/app/Http/Livewire/Project/Application/General.php +++ b/app/Http/Livewire/Project/Application/General.php @@ -33,6 +33,7 @@ class General extends Component protected $rules = [ 'application.name' => 'required', + 'application.description' => 'nullable', 'application.fqdn' => 'nullable', 'application.git_repository' => 'required', 'application.git_branch' => 'required', @@ -49,6 +50,7 @@ class General extends Component ]; protected $validationAttributes = [ 'application.name' => 'name', + 'application.description' => 'description', 'application.fqdn' => 'FQDN', 'application.git_repository' => 'Git repository', 'application.git_branch' => 'Git branch', diff --git a/app/Http/Livewire/Application/Heading.php b/app/Http/Livewire/Project/Application/Heading.php similarity index 97% rename from app/Http/Livewire/Application/Heading.php rename to app/Http/Livewire/Project/Application/Heading.php index b062862b5..8a52061ef 100644 --- a/app/Http/Livewire/Application/Heading.php +++ b/app/Http/Livewire/Project/Application/Heading.php @@ -1,6 +1,6 @@ parameters = getRouteParameters(); + } + public function start() { + if ($this->database->type() === 'postgresql') { + $activity = resolve(StartPostgresql::class)($this->database->destination->server, $this->database); + $this->emit('newMonitorActivity', $activity->id); + } + } +} \ No newline at end of file diff --git a/app/Http/Livewire/Project/Database/Postgresql/General.php b/app/Http/Livewire/Project/Database/Postgresql/General.php new file mode 100644 index 000000000..b3e2faa99 --- /dev/null +++ b/app/Http/Livewire/Project/Database/Postgresql/General.php @@ -0,0 +1,39 @@ + 'required', + 'database.description' => 'nullable', + 'database.postgres_user' => 'required', + 'database.postgres_password' => 'required', + 'database.postgres_db' => 'required', + 'database.postgres_initdb_args' => 'nullable', + 'database.postgres_host_auth_method' => 'nullable', + 'database.init_scripts' => 'nullable', + ]; + protected $validationAttributes = [ + 'database.name' => 'Name', + 'database.description' => 'Description', + 'database.postgres_user' => 'Postgres User', + 'database.postgres_password' => 'Postgres Password', + 'database.postgres_db' => 'Postgres DB', + 'database.postgres_initdb_args' => 'Postgres Initdb Args', + 'database.postgres_host_auth_method' => 'Postgres Host Auth Method', + 'database.init_scripts' => 'Init Scripts', + ]; + public function submit() { + try { + $this->validate(); + $this->database->save(); + $this->emit('success', 'Database updated successfully.'); + } catch (\Exception $e) { + return general_error_handler(err: $e, that: $this); + } + } +} \ No newline at end of file diff --git a/app/Models/Environment.php b/app/Models/Environment.php index c79472e88..e7139a5bd 100644 --- a/app/Models/Environment.php +++ b/app/Models/Environment.php @@ -17,6 +17,12 @@ protected function name(): Attribute set: fn (string $value) => strtolower($value), ); } + public function can_delete_environment() { + return $this->applications()->count() == 0 && $this->postgresqls()->count() == 0; + } + public function databases() { + return $this->postgresqls(); + } public function project() { return $this->belongsTo(Project::class); @@ -25,12 +31,12 @@ public function applications() { return $this->hasMany(Application::class); } - public function databases() + public function postgresqls() { - return $this->hasMany(Database::class); + return $this->hasMany(Postgresql::class); } public function services() { return $this->hasMany(Service::class); } -} +} \ No newline at end of file diff --git a/app/Models/Postgresql.php b/app/Models/Postgresql.php new file mode 100644 index 000000000..10e536685 --- /dev/null +++ b/app/Models/Postgresql.php @@ -0,0 +1,25 @@ + 'encrypted', + ]; + public function type() { + return 'postgresql'; + } + public function environment() + { + return $this->belongsTo(Environment::class); + } + public function destination() + { + return $this->morphTo(); + } +} \ No newline at end of file diff --git a/app/Models/Project.php b/app/Models/Project.php index a0a342755..791b8a7cc 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -46,4 +46,8 @@ public function applications() { return $this->hasManyThrough(Application::class, Environment::class); } -} + public function postgresqls() + { + return $this->hasManyThrough(Postgresql::class, Environment::class); + } +} \ No newline at end of file diff --git a/app/Models/S3Storage.php b/app/Models/S3Storage.php index 46fc37783..a6f6360ac 100644 --- a/app/Models/S3Storage.php +++ b/app/Models/S3Storage.php @@ -8,6 +8,10 @@ class S3Storage extends BaseModel { use HasFactory; protected $guarded = []; + protected $casts = [ + 'key' => 'encrypted', + 'secret' => 'encrypted', + ]; static public function ownedByCurrentTeam(array $select = ['*']) { diff --git a/app/Models/StandaloneDocker.php b/app/Models/StandaloneDocker.php index ea257dd60..e5f1cf3f3 100644 --- a/app/Models/StandaloneDocker.php +++ b/app/Models/StandaloneDocker.php @@ -13,9 +13,9 @@ public function applications() { return $this->morphMany(Application::class, 'destination'); } - public function databases() + public function postgresqls() { - return $this->morphMany(Database::class, 'destination'); + return $this->morphMany(Postgresql::class, 'destination'); } public function server() { @@ -25,4 +25,4 @@ public function attachedTo() { return $this->applications->count() > 0 || $this->databases->count() > 0; } -} +} \ No newline at end of file diff --git a/app/View/Components/Modal.php b/app/View/Components/Modal.php index b317d3c44..22c5a7bba 100644 --- a/app/View/Components/Modal.php +++ b/app/View/Components/Modal.php @@ -14,7 +14,7 @@ class Modal extends Component */ public function __construct( public string $modalId, - public string $modalTitle, + public string|null $modalTitle = null, public string|null $modalBody = null, public string|null $modalSubmit = null, public bool $yesOrNo = false, @@ -30,4 +30,4 @@ public function render(): View|Closure|string { return view('components.modal'); } -} +} \ No newline at end of file diff --git a/database/migrations/2023_08_07_073651_create_s3_storages_table.php b/database/migrations/2023_08_07_073651_create_s3_storages_table.php index 711707e9e..cdda367a2 100644 --- a/database/migrations/2023_08_07_073651_create_s3_storages_table.php +++ b/database/migrations/2023_08_07_073651_create_s3_storages_table.php @@ -14,7 +14,7 @@ public function up(): void Schema::create('s3_storages', function (Blueprint $table) { $table->id(); $table->string('uuid')->unique(); - $table->string('name')->nullable(); + $table->string('name'); $table->longText('description')->nullable(); $table->string('region')->default('us-east-1'); $table->longText('key'); diff --git a/database/migrations/2023_08_07_142950_create_postgresqls_table.php b/database/migrations/2023_08_07_142950_create_postgresqls_table.php new file mode 100644 index 000000000..8d126ce3e --- /dev/null +++ b/database/migrations/2023_08_07_142950_create_postgresqls_table.php @@ -0,0 +1,42 @@ +id(); + $table->string('uuid')->unique(); + $table->string('name'); + $table->string('description')->nullable(); + + $table->string('postgres_user')->default('postgres'); + $table->string('postgres_password'); + $table->string('postgres_db')->default('postgres'); + $table->string('postgres_initdb_args')->nullable(); + $table->string('postgres_host_auth_method')->nullable(); + $table->json('init_scripts')->nullable(); + + $table->timestamp('started_at')->nullable(); + $table->morphs('destination'); + + $table->foreignId('environment_id'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('postgresqls'); + } +}; \ No newline at end of file diff --git a/database/migrations/2023_03_27_083620_create_databases_table.php b/database/migrations/2023_08_07_142951_add_description_field_to_applications_table.php similarity index 51% rename from database/migrations/2023_03_27_083620_create_databases_table.php rename to database/migrations/2023_08_07_142951_add_description_field_to_applications_table.php index bfafb9c0c..02d4c5935 100644 --- a/database/migrations/2023_03_27_083620_create_databases_table.php +++ b/database/migrations/2023_08_07_142951_add_description_field_to_applications_table.php @@ -11,15 +11,8 @@ */ public function up(): void { - Schema::create('databases', function (Blueprint $table) { - $table->id(); - $table->string('uuid')->unique(); - $table->string('name'); - - $table->morphs('destination'); - - $table->foreignId('environment_id'); - $table->timestamps(); + Schema::table('applications', function (Blueprint $table) { + $table->string('description')->nullable(); }); } @@ -28,6 +21,8 @@ public function up(): void */ public function down(): void { - Schema::dropIfExists('databases'); + Schema::table('applications', function (Blueprint $table) { + $table->dropColumn('description'); + }); } -}; +}; \ No newline at end of file diff --git a/database/seeders/ApplicationSeeder.php b/database/seeders/ApplicationSeeder.php index 2859bed81..9cffe6fbe 100644 --- a/database/seeders/ApplicationSeeder.php +++ b/database/seeders/ApplicationSeeder.php @@ -19,13 +19,11 @@ class ApplicationSeeder extends Seeder */ public function run(): void { - $environment_1 = Environment::find(1); - $standalone_docker_1 = StandaloneDocker::find(1); - $github_public_source = GithubApp::where('name', 'Public GitHub')->first(); Application::create([ 'name' => 'coollabsio/coolify-examples:nodejs-fastify', + 'description' => 'NodeJS Fastify Example', 'fqdn' => 'http://foo.com', 'repository_project_id' => 603035348, 'git_repository' => 'coollabsio/coolify-examples', @@ -33,11 +31,11 @@ public function run(): void 'build_pack' => 'nixpacks', 'ports_exposes' => '3000', 'ports_mappings' => '3000:3000', - 'environment_id' => $environment_1->id, - 'destination_id' => $standalone_docker_1->id, + 'environment_id' => 1, + 'destination_id' => 1, 'destination_type' => StandaloneDocker::class, 'source_id' => $github_public_source->id, 'source_type' => GithubApp::class ]); } -} +} \ No newline at end of file diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index bba3978ac..7fa45e6b8 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -32,6 +32,7 @@ public function run(): void EnvironmentVariableSeeder::class, LocalPersistentVolumeSeeder::class, S3StorageSeeder::class, + PostgresqlSeeder::class, ]); } } \ No newline at end of file diff --git a/database/seeders/PostgresqlSeeder.php b/database/seeders/PostgresqlSeeder.php new file mode 100644 index 000000000..2568feb10 --- /dev/null +++ b/database/seeders/PostgresqlSeeder.php @@ -0,0 +1,26 @@ + 'Local PostgreSQL', + 'description' => 'Local PostgreSQL for testing', + 'postgres_password' => 'postgres', + 'environment_id' => 1, + 'destination_id' => 1, + 'destination_type' => StandaloneDocker::class, + ]); + } +} \ No newline at end of file diff --git a/resources/views/components/databases/navbar.blade.php b/resources/views/components/databases/navbar.blade.php new file mode 100644 index 000000000..fc8e7b68a --- /dev/null +++ b/resources/views/components/databases/navbar.blade.php @@ -0,0 +1,41 @@ + diff --git a/resources/views/components/modal.blade.php b/resources/views/components/modal.blade.php index 052c2b943..711515437 100644 --- a/resources/views/components/modal.blade.php +++ b/resources/views/components/modal.blade.php @@ -10,7 +10,9 @@
-

{{ $modalTitle }}

+ @isset($modalTitle) +

{{ $modalTitle }}

+ @endisset @isset($modalBody) {{ $modalBody }} @endisset @@ -31,8 +33,11 @@
@else -
- @if ($application->status === 'running') + @if ($resource->status === 'running') - @elseif($application->status === 'restarting') + @elseif($resource->status === 'restarting') @else diff --git a/resources/views/dashboard.blade.php b/resources/views/dashboard.blade.php index 609f487cd..17a1435af 100644 --- a/resources/views/dashboard.blade.php +++ b/resources/views/dashboard.blade.php @@ -23,6 +23,6 @@
@if (isDev()) - + @endif diff --git a/resources/views/livewire/s3-test.blade.php b/resources/views/livewire/dev/s3-test.blade.php similarity index 100% rename from resources/views/livewire/s3-test.blade.php rename to resources/views/livewire/dev/s3-test.blade.php diff --git a/resources/views/livewire/project/application/general.blade.php b/resources/views/livewire/project/application/general.blade.php index 76bb140b2..614446478 100644 --- a/resources/views/livewire/project/application/general.blade.php +++ b/resources/views/livewire/project/application/general.blade.php @@ -10,21 +10,22 @@
- - @if ($wildcard_domain) -
- @if ($global_wildcard_domain) - Set Global Wildcard - - @endif - @if ($server_wildcard_domain) - Set Server Wildcard - - @endif -
- @endif +
+ + @if ($wildcard_domain) +
+ @if ($global_wildcard_domain) + Set Global Wildcard + + @endif + @if ($server_wildcard_domain) + Set Server Wildcard + + @endif +
+ @endif diff --git a/resources/views/livewire/application/heading.blade.php b/resources/views/livewire/project/application/heading.blade.php similarity index 63% rename from resources/views/livewire/application/heading.blade.php rename to resources/views/livewire/project/application/heading.blade.php index c3d33543e..ca76d38e8 100644 --- a/resources/views/livewire/application/heading.blade.php +++ b/resources/views/livewire/project/application/heading.blade.php @@ -1,4 +1,4 @@ diff --git a/resources/views/livewire/project/database/heading.blade.php b/resources/views/livewire/project/database/heading.blade.php new file mode 100644 index 000000000..e1f51c332 --- /dev/null +++ b/resources/views/livewire/project/database/heading.blade.php @@ -0,0 +1,4 @@ + diff --git a/resources/views/livewire/project/database/postgresql/general.blade.php b/resources/views/livewire/project/database/postgresql/general.blade.php new file mode 100644 index 000000000..283fe7d47 --- /dev/null +++ b/resources/views/livewire/project/database/postgresql/general.blade.php @@ -0,0 +1,18 @@ +
+ +
+

General

+ + Save + +
+ + + + + + + + +
diff --git a/resources/views/project/application/configuration.blade.php b/resources/views/project/application/configuration.blade.php index 73a9ff805..d0c6e5cfa 100644 --- a/resources/views/project/application/configuration.blade.php +++ b/resources/views/project/application/configuration.blade.php @@ -1,6 +1,6 @@

Configuration

- +

Deployment

- + diff --git a/resources/views/project/application/deployments.blade.php b/resources/views/project/application/deployments.blade.php index b4fcd8982..46d731653 100644 --- a/resources/views/project/application/deployments.blade.php +++ b/resources/views/project/application/deployments.blade.php @@ -1,5 +1,5 @@

Deployments

- +
diff --git a/resources/views/project/database.blade.php b/resources/views/project/database.blade.php deleted file mode 100644 index f256fecb9..000000000 --- a/resources/views/project/database.blade.php +++ /dev/null @@ -1,5 +0,0 @@ - -

Database

- - -
diff --git a/resources/views/project/database/configuration.blade.php b/resources/views/project/database/configuration.blade.php new file mode 100644 index 000000000..ab75e7616 --- /dev/null +++ b/resources/views/project/database/configuration.blade.php @@ -0,0 +1,65 @@ + +

Configuration

+ + + + + + + + Close + + + +
+ +
+
+ @if ($database->getMorphClass() === 'App\Models\Postgresql') + + @endif +
+
+ {{-- --}} +
+
+ {{-- --}} +
+
+ {{-- --}} +
+
+ {{-- --}} +
+
+ {{-- --}} +
+
+ {{-- --}} +
+
+
+ diff --git a/resources/views/project/resources.blade.php b/resources/views/project/resources.blade.php index 0c4060a00..30e72bcc3 100644 --- a/resources/views/project/resources.blade.php +++ b/resources/views/project/resources.blade.php @@ -5,7 +5,7 @@ + Add - @if ($environment->applications->count() === 0) + @if ($environment->can_delete_environment()) @endif
@@ -31,14 +31,26 @@ class="font-normal text-white normal-case border-none rounded hover:no-underline
- @if ($environment->applications->count() === 0) + @if ($environment->can_delete_environment())

No resources found.

@endif
@foreach ($environment->applications->sortBy('name') as $application) - {{ $application->name }} +
+
{{ $application->name }}
+
{{ $application->description }}
+
+
+ @endforeach + @foreach ($environment->databases->sortBy('name') as $databases) + +
+
{{ $databases->name }}
+
{{ $databases->description }}
+
@endforeach
diff --git a/routes/web.php b/routes/web.php index 91a4aa2ab..d04c51d8f 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,6 +1,7 @@ name('project.resources.new'); Route::get('/project/{project_uuid}/{environment_name}', [ProjectController::class, 'resources'])->name('project.resources'); Route::get('/project/{project_uuid}/{environment_name}/application/{application_uuid}', [ApplicationController::class, 'configuration'])->name('project.application.configuration'); + Route::get('/project/{project_uuid}/{environment_name}/database/{database_uuid}', [DatabaseController::class, 'configuration'])->name('project.database.configuration'); Route::get('/project/{project_uuid}/{environment_name}/application/{application_uuid}/deployment', [ApplicationController::class, 'deployments'])->name('project.application.deployments'); Route::get( '/project/{project_uuid}/{environment_name}/application/{application_uuid}/deployment/{deployment_uuid}', From 20e1cd6d6b779affe4eea1e16c2c0e9573faae0f Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 7 Aug 2023 19:25:32 +0200 Subject: [PATCH 37/76] rename postgres to standalonepostgres --- app/Actions/Database/StartPostgresql.php | 4 ++-- app/Models/Environment.php | 2 +- app/Models/Project.php | 2 +- app/Models/StandaloneDocker.php | 2 +- .../{Postgresql.php => StandalonePostgres.php} | 2 +- ...142950_create_standalone_postgres_table.php} | 4 ++-- database/seeders/DatabaseSeeder.php | 2 +- ...lSeeder.php => StandalonePostgresSeeder.php} | 6 +++--- .../views/livewire/project/new/select.blade.php | 17 ++++++++++++++++- .../project/database/configuration.blade.php | 2 +- 10 files changed, 29 insertions(+), 14 deletions(-) rename app/Models/{Postgresql.php => StandalonePostgres.php} (91%) rename database/migrations/{2023_08_07_142950_create_postgresqls_table.php => 2023_08_07_142950_create_standalone_postgres_table.php} (89%) rename database/seeders/{PostgresqlSeeder.php => StandalonePostgresSeeder.php} (82%) diff --git a/app/Actions/Database/StartPostgresql.php b/app/Actions/Database/StartPostgresql.php index d9f2c8846..2ff91ce2f 100644 --- a/app/Actions/Database/StartPostgresql.php +++ b/app/Actions/Database/StartPostgresql.php @@ -5,11 +5,11 @@ use App\Models\Server; use App\Models\StandaloneDocker; use App\Models\Team; -use App\Models\Postgresql; +use App\Models\StandalonePostgres; class StartPostgresql { - public function __invoke(Server $server, Postgresql $database) + public function __invoke(Server $server, StandalonePostgres $database) { $activity = remote_process([ "echo 'Creating required Docker networks...'", diff --git a/app/Models/Environment.php b/app/Models/Environment.php index e7139a5bd..ca47fd292 100644 --- a/app/Models/Environment.php +++ b/app/Models/Environment.php @@ -33,7 +33,7 @@ public function applications() } public function postgresqls() { - return $this->hasMany(Postgresql::class); + return $this->hasMany(StandalonePostgres::class); } public function services() { diff --git a/app/Models/Project.php b/app/Models/Project.php index 791b8a7cc..129df3072 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -48,6 +48,6 @@ public function applications() } public function postgresqls() { - return $this->hasManyThrough(Postgresql::class, Environment::class); + return $this->hasManyThrough(StandalonePostgres::class, Environment::class); } } \ No newline at end of file diff --git a/app/Models/StandaloneDocker.php b/app/Models/StandaloneDocker.php index e5f1cf3f3..c14bb855d 100644 --- a/app/Models/StandaloneDocker.php +++ b/app/Models/StandaloneDocker.php @@ -15,7 +15,7 @@ public function applications() } public function postgresqls() { - return $this->morphMany(Postgresql::class, 'destination'); + return $this->morphMany(StandalonePostgres::class, 'destination'); } public function server() { diff --git a/app/Models/Postgresql.php b/app/Models/StandalonePostgres.php similarity index 91% rename from app/Models/Postgresql.php rename to app/Models/StandalonePostgres.php index 10e536685..df4295512 100644 --- a/app/Models/Postgresql.php +++ b/app/Models/StandalonePostgres.php @@ -4,7 +4,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; -class Postgresql extends BaseModel +class StandalonePostgres extends BaseModel { use HasFactory; protected $guarded = []; diff --git a/database/migrations/2023_08_07_142950_create_postgresqls_table.php b/database/migrations/2023_08_07_142950_create_standalone_postgres_table.php similarity index 89% rename from database/migrations/2023_08_07_142950_create_postgresqls_table.php rename to database/migrations/2023_08_07_142950_create_standalone_postgres_table.php index 8d126ce3e..43215a184 100644 --- a/database/migrations/2023_08_07_142950_create_postgresqls_table.php +++ b/database/migrations/2023_08_07_142950_create_standalone_postgres_table.php @@ -11,7 +11,7 @@ */ public function up(): void { - Schema::create('postgresqls', function (Blueprint $table) { + Schema::create('standalone_postgres', function (Blueprint $table) { $table->id(); $table->string('uuid')->unique(); $table->string('name'); @@ -37,6 +37,6 @@ public function up(): void */ public function down(): void { - Schema::dropIfExists('postgresqls'); + Schema::dropIfExists('standalone_postgres'); } }; \ No newline at end of file diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 7fa45e6b8..2bff4f36f 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -32,7 +32,7 @@ public function run(): void EnvironmentVariableSeeder::class, LocalPersistentVolumeSeeder::class, S3StorageSeeder::class, - PostgresqlSeeder::class, + StandalonePostgresSeeder::class, ]); } } \ No newline at end of file diff --git a/database/seeders/PostgresqlSeeder.php b/database/seeders/StandalonePostgresSeeder.php similarity index 82% rename from database/seeders/PostgresqlSeeder.php rename to database/seeders/StandalonePostgresSeeder.php index 2568feb10..c045d7358 100644 --- a/database/seeders/PostgresqlSeeder.php +++ b/database/seeders/StandalonePostgresSeeder.php @@ -4,17 +4,17 @@ use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; -use App\Models\Postgresql; +use App\Models\StandalonePostgres; use App\Models\StandaloneDocker; -class PostgresqlSeeder extends Seeder +class StandalonePostgresSeeder extends Seeder { /** * Run the database seeds. */ public function run(): void { - Postgresql::create([ + StandalonePostgres::create([ 'name' => 'Local PostgreSQL', 'description' => 'Local PostgreSQL for testing', 'postgres_password' => 'postgres', diff --git a/resources/views/livewire/project/new/select.blade.php b/resources/views/livewire/project/new/select.blade.php index e6b2511e5..042ff38d9 100644 --- a/resources/views/livewire/project/new/select.blade.php +++ b/resources/views/livewire/project/new/select.blade.php @@ -1,6 +1,6 @@

New Resource

-
Deploy any Git repository from different sources.
+
Deploy resources, like Applications, Databases, Services...
@if ($current_step === 'type')
    @@ -8,6 +8,7 @@
  • Select a Server
  • Select a Destination
+

Applications

@@ -40,6 +41,20 @@
+

Databases

+
+
+
+
+ PostgreSQL +
+
+ The most loved relational database in the world.
+
+
+ +
@endif @if ($current_step === 'servers')
    diff --git a/resources/views/project/database/configuration.blade.php b/resources/views/project/database/configuration.blade.php index ab75e7616..c01ffe248 100644 --- a/resources/views/project/database/configuration.blade.php +++ b/resources/views/project/database/configuration.blade.php @@ -38,7 +38,7 @@
- @if ($database->getMorphClass() === 'App\Models\Postgresql') + @if ($database->type() === 'postgresql') @endif
From bfc20ef21989ab066a0f8090e711f89b398181e1 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 7 Aug 2023 19:29:47 +0200 Subject: [PATCH 38/76] public database --- .../2023_08_07_142950_create_standalone_postgres_table.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/database/migrations/2023_08_07_142950_create_standalone_postgres_table.php b/database/migrations/2023_08_07_142950_create_standalone_postgres_table.php index 43215a184..3d2f1b7d3 100644 --- a/database/migrations/2023_08_07_142950_create_standalone_postgres_table.php +++ b/database/migrations/2023_08_07_142950_create_standalone_postgres_table.php @@ -24,6 +24,9 @@ public function up(): void $table->string('postgres_host_auth_method')->nullable(); $table->json('init_scripts')->nullable(); + $table->boolean('is_public')->default(false); + $table->integer('public_port')->nullable(); + $table->timestamp('started_at')->nullable(); $table->morphs('destination'); From 971d7f703d54995dbee8f7343fb2f0e33b2eb706 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 7 Aug 2023 22:14:21 +0200 Subject: [PATCH 39/76] lots of updates + refactoring --- app/Actions/Database/StartPostgresql.php | 65 ++++++++++++++++--- .../Controllers/ApplicationController.php | 3 +- app/Http/Controllers/DatabaseController.php | 3 +- app/Http/Livewire/ActivityMonitor.php | 1 + .../Application/EnvironmentVariable/All.php | 45 ------------- .../Livewire/Project/Application/Heading.php | 8 +-- .../Livewire/Project/Application/Previews.php | 6 +- .../Project/Application/ResourceLimits.php | 60 ----------------- .../Livewire/Project/Database/Heading.php | 31 ++++++++- .../Project/Database/Postgresql/General.php | 9 ++- .../{Application => Shared}/Danger.php | 11 ++-- .../{Application => Shared}/Destination.php | 2 +- .../EnvironmentVariable/Add.php | 2 +- .../Shared/EnvironmentVariable/All.php | 49 ++++++++++++++ .../EnvironmentVariable/Show.php | 2 +- .../Project/Shared/ResourceLimits.php | 59 +++++++++++++++++ .../{Application => Shared}/Storages/Add.php | 2 +- .../{Application => Shared}/Storages/All.php | 13 ++-- .../{Application => Shared}/Storages/Show.php | 2 +- ...erStatusJob.php => ContainerStatusJob.php} | 22 +++---- app/Jobs/InstanceApplicationsStatusJob.php | 4 +- app/Models/Application.php | 6 +- app/Models/Environment.php | 4 +- app/Models/EnvironmentVariable.php | 31 ++++----- app/Models/LocalPersistentVolume.php | 13 ++-- app/Models/Project.php | 4 +- app/Models/StandaloneDocker.php | 4 +- app/Models/StandalonePostgres.php | 25 ------- app/Models/StandalonePostgresql.php | 50 ++++++++++++++ .../Application/StatusChanged.php | 8 +-- ...0_create_standalone_postgresqls_table.php} | 18 ++++- ...remove_foreignId_environment_variables.php | 32 +++++++++ ...54_add_readonly_localpersistentvolumes.php | 28 ++++++++ database/seeders/DatabaseSeeder.php | 4 +- ...der.php => StandalonePostgresqlSeeder.php} | 8 +-- .../components/databases/navbar.blade.php | 11 ---- .../environment-variable/all.blade.php | 26 -------- .../application/storages/show.blade.php | 21 ------ .../project/database/heading.blade.php | 2 +- .../database/postgresql/general.blade.php | 30 +++++++-- .../{application => shared}/danger.blade.php | 6 +- .../project/shared/destination.blade.php | 8 +++ .../environment-variable/add.blade.php | 4 +- .../shared/environment-variable/all.blade.php | 26 ++++++++ .../environment-variable/show.blade.php | 4 +- .../resource-limits.blade.php | 14 ++-- .../storages/add.blade.php | 0 .../storages/all.blade.php | 8 +-- .../project/shared/storages/show.blade.php | 35 ++++++++++ .../application/configuration.blade.php | 10 +-- .../project/database/configuration.blade.php | 17 ++--- 51 files changed, 532 insertions(+), 324 deletions(-) delete mode 100644 app/Http/Livewire/Project/Application/EnvironmentVariable/All.php delete mode 100644 app/Http/Livewire/Project/Application/ResourceLimits.php rename app/Http/Livewire/Project/{Application => Shared}/Danger.php (58%) rename app/Http/Livewire/Project/{Application => Shared}/Destination.php (66%) rename app/Http/Livewire/Project/{Application => Shared}/EnvironmentVariable/Add.php (94%) create mode 100644 app/Http/Livewire/Project/Shared/EnvironmentVariable/All.php rename app/Http/Livewire/Project/{Application => Shared}/EnvironmentVariable/Show.php (93%) create mode 100644 app/Http/Livewire/Project/Shared/ResourceLimits.php rename app/Http/Livewire/Project/{Application => Shared}/Storages/Add.php (94%) rename app/Http/Livewire/Project/{Application => Shared}/Storages/All.php (68%) rename app/Http/Livewire/Project/{Application => Shared}/Storages/Show.php (93%) rename app/Jobs/{ApplicationContainerStatusJob.php => ContainerStatusJob.php} (59%) delete mode 100644 app/Models/StandalonePostgres.php create mode 100644 app/Models/StandalonePostgresql.php rename database/migrations/{2023_08_07_142950_create_standalone_postgres_table.php => 2023_08_07_142950_create_standalone_postgresqls_table.php} (62%) create mode 100644 database/migrations/2023_08_07_142952_remove_foreignId_environment_variables.php create mode 100644 database/migrations/2023_08_07_142954_add_readonly_localpersistentvolumes.php rename database/seeders/{StandalonePostgresSeeder.php => StandalonePostgresqlSeeder.php} (81%) delete mode 100644 resources/views/livewire/project/application/environment-variable/all.blade.php delete mode 100644 resources/views/livewire/project/application/storages/show.blade.php rename resources/views/livewire/project/{application => shared}/danger.blade.php (74%) create mode 100644 resources/views/livewire/project/shared/destination.blade.php rename resources/views/livewire/project/{application => shared}/environment-variable/add.blade.php (80%) create mode 100644 resources/views/livewire/project/shared/environment-variable/all.blade.php rename resources/views/livewire/project/{application => shared}/environment-variable/show.blade.php (83%) rename resources/views/livewire/project/{application => shared}/resource-limits.blade.php (75%) rename resources/views/livewire/project/{application => shared}/storages/add.blade.php (100%) rename resources/views/livewire/project/{application => shared}/storages/all.blade.php (71%) create mode 100644 resources/views/livewire/project/shared/storages/show.blade.php diff --git a/app/Actions/Database/StartPostgresql.php b/app/Actions/Database/StartPostgresql.php index 2ff91ce2f..2b7386904 100644 --- a/app/Actions/Database/StartPostgresql.php +++ b/app/Actions/Database/StartPostgresql.php @@ -5,21 +5,68 @@ use App\Models\Server; use App\Models\StandaloneDocker; use App\Models\Team; -use App\Models\StandalonePostgres; +use App\Models\StandalonePostgresql; +use Symfony\Component\Yaml\Yaml; class StartPostgresql { - public function __invoke(Server $server, StandalonePostgres $database) + public function __invoke(Server $server, StandalonePostgresql $database) { + $container_name = generate_container_name($database->uuid); + $destination = $database->destination; + $image = $database->image; + $docker_compose = [ + 'version' => '3.8', + 'services' => [ + $container_name => [ + 'image' => $image, + 'container_name' => $container_name, + 'environment'=> [ + 'POSTGRES_USER' => $database->postgres_user, + 'POSTGRES_PASSWORD' => $database->postgres_password, + 'POSTGRES_DB' => $database->postgres_db, + ], + 'restart' => 'always', + 'networks' => [ + $destination->network, + ], + 'healthcheck' => [ + 'test' => [ + 'CMD-SHELL', + 'pg_isready', + '-d', + $database->postgres_db, + ], + 'interval' => '5s', + 'timeout' => '5s', + 'retries' => 10, + 'start_period' => '5s' + ], + 'mem_limit' => $database->limits_memory, + 'memswap_limit' => $database->limits_memory_swap, + 'mem_swappiness' => $database->limits_memory_swappiness, + 'mem_reservation' => $database->limits_memory_reservation, + 'cpus' => $database->limits_cpus, + 'cpuset' => $database->limits_cpuset, + 'cpu_shares' => $database->limits_cpu_shares, + ] + ], + 'networks' => [ + $destination->network => [ + 'external' => false, + 'name' => $destination->network, + 'attachable' => true, + ] + ] + ]; + $docker_compose = Yaml::dump($docker_compose, 10); + $docker_compose_base64 = base64_encode($docker_compose); $activity = remote_process([ - "echo 'Creating required Docker networks...'", - "echo 'Creating required Docker networks...'", - "echo 'Creating required Docker networks...'", - "sleep 4", - "echo 'Creating required Docker networks...'", - "echo 'Creating required Docker networks...'", + "mkdir -p /tmp/{$container_name}", + "echo '{$docker_compose_base64}' | base64 -d > /tmp/{$container_name}/docker-compose.yml", + "docker compose -f /tmp/{$container_name}/docker-compose.yml up -d", ], $server); return $activity; } -} \ No newline at end of file +} diff --git a/app/Http/Controllers/ApplicationController.php b/app/Http/Controllers/ApplicationController.php index 84a6bc0ec..b6685276f 100644 --- a/app/Http/Controllers/ApplicationController.php +++ b/app/Http/Controllers/ApplicationController.php @@ -25,6 +25,7 @@ public function configuration() if (!$application) { return redirect()->route('dashboard'); } + ray($application->persistentStorages()->get()); return view('project.application.configuration', ['application' => $application]); } public function deployments() @@ -84,4 +85,4 @@ public function deployment() 'deployment_uuid' => $deploymentUuid, ]); } -} \ No newline at end of file +} diff --git a/app/Http/Controllers/DatabaseController.php b/app/Http/Controllers/DatabaseController.php index 7adb53f1f..6137c8a6b 100644 --- a/app/Http/Controllers/DatabaseController.php +++ b/app/Http/Controllers/DatabaseController.php @@ -25,6 +25,7 @@ public function configuration() if (!$database) { return redirect()->route('dashboard'); } + ray($database->persistentStorages()->get()); return view('project.database.configuration', ['database' => $database]); } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/ActivityMonitor.php b/app/Http/Livewire/ActivityMonitor.php index b11bcdb38..1ce763a0f 100644 --- a/app/Http/Livewire/ActivityMonitor.php +++ b/app/Http/Livewire/ActivityMonitor.php @@ -42,6 +42,7 @@ public function polling() $this->setStatus(ProcessStatus::ERROR); } $this->isPollingActive = false; + $this->emit('activityFinished'); } } protected function setStatus($status) diff --git a/app/Http/Livewire/Project/Application/EnvironmentVariable/All.php b/app/Http/Livewire/Project/Application/EnvironmentVariable/All.php deleted file mode 100644 index f1ac75917..000000000 --- a/app/Http/Livewire/Project/Application/EnvironmentVariable/All.php +++ /dev/null @@ -1,45 +0,0 @@ -modalId = new Cuid2(7); - } - public function refreshEnvs() - { - $this->application->refresh(); - } - public function submit($data) - { - try { - $found = $this->application->environment_variables()->where('key', $data['key'])->first(); - if ($found) { - $this->emit('error', 'Environment variable already exists.'); - return; - } - EnvironmentVariable::create([ - 'key' => $data['key'], - 'value' => $data['value'], - 'is_build_time' => $data['is_build_time'], - 'is_preview' => $data['is_preview'], - 'application_id' => $this->application->id, - ]); - $this->application->refresh(); - - $this->emit('success', 'Environment variable added successfully.'); - } catch (\Exception $e) { - return general_error_handler(err: $e, that: $this); - } - } -} diff --git a/app/Http/Livewire/Project/Application/Heading.php b/app/Http/Livewire/Project/Application/Heading.php index 8a52061ef..b3c3cd876 100644 --- a/app/Http/Livewire/Project/Application/Heading.php +++ b/app/Http/Livewire/Project/Application/Heading.php @@ -2,7 +2,7 @@ namespace App\Http\Livewire\Project\Application; -use App\Jobs\ApplicationContainerStatusJob; +use App\Jobs\ContainerStatusJob; use App\Models\Application; use App\Notifications\Application\StatusChanged; use Livewire\Component; @@ -22,8 +22,8 @@ public function mount() public function check_status() { - dispatch_sync(new ApplicationContainerStatusJob( - application: $this->application, + dispatch_sync(new ContainerStatusJob( + resource: $this->application, container_name: generate_container_name($this->application->uuid), )); $this->application->refresh(); @@ -62,4 +62,4 @@ protected function setDeploymentUuid() $this->deploymentUuid = new Cuid2(7); $this->parameters['deployment_uuid'] = $this->deploymentUuid; } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Project/Application/Previews.php b/app/Http/Livewire/Project/Application/Previews.php index 8b26b7bc2..a708a7098 100644 --- a/app/Http/Livewire/Project/Application/Previews.php +++ b/app/Http/Livewire/Project/Application/Previews.php @@ -2,7 +2,7 @@ namespace App\Http\Livewire\Project\Application; -use App\Jobs\ApplicationContainerStatusJob; +use App\Jobs\ContainerStatusJob; use App\Models\Application; use App\Models\ApplicationPreview; use Illuminate\Support\Collection; @@ -24,8 +24,8 @@ public function mount() } public function loadStatus($pull_request_id) { - dispatch(new ApplicationContainerStatusJob( - application: $this->application, + dispatch(new ContainerStatusJob( + resource: $this->application, container_name: generate_container_name($this->application->uuid, $pull_request_id), pull_request_id: $pull_request_id )); diff --git a/app/Http/Livewire/Project/Application/ResourceLimits.php b/app/Http/Livewire/Project/Application/ResourceLimits.php deleted file mode 100644 index 9db5626ac..000000000 --- a/app/Http/Livewire/Project/Application/ResourceLimits.php +++ /dev/null @@ -1,60 +0,0 @@ - 'required|string', - 'application.limits_memory_swap' => 'required|string', - 'application.limits_memory_swappiness' => 'required|integer|min:0|max:100', - 'application.limits_memory_reservation' => 'required|string', - 'application.limits_cpus' => 'nullable', - 'application.limits_cpuset' => 'nullable', - 'application.limits_cpu_shares' => 'nullable', - ]; - protected $validationAttributes = [ - 'application.limits_memory' => 'memory', - 'application.limits_memory_swap' => 'swap', - 'application.limits_memory_swappiness' => 'swappiness', - 'application.limits_memory_reservation' => 'reservation', - 'application.limits_cpus' => 'cpus', - 'application.limits_cpuset' => 'cpuset', - 'application.limits_cpu_shares' => 'cpu shares', - ]; - public function submit() - { - try { - if (!$this->application->limits_memory) { - $this->application->limits_memory = "0"; - } - if (!$this->application->limits_memory_swap) { - $this->application->limits_memory_swap = "0"; - } - if (!$this->application->limits_memory_swappiness) { - $this->application->limits_memory_swappiness = "60"; - } - if (!$this->application->limits_memory_reservation) { - $this->application->limits_memory_reservation = "0"; - } - if (!$this->application->limits_cpus) { - $this->application->limits_cpus = "0"; - } - if (!$this->application->limits_cpuset) { - $this->application->limits_cpuset = "0"; - } - if (!$this->application->limits_cpu_shares) { - $this->application->limits_cpu_shares = 1024; - } - $this->validate(); - $this->application->save(); - $this->emit('success', 'Resource limits updated successfully.'); - } catch (\Exception $e) { - return general_error_handler(err: $e, that: $this); - } - } -} diff --git a/app/Http/Livewire/Project/Database/Heading.php b/app/Http/Livewire/Project/Database/Heading.php index 8b653bc0a..f6dd7a12d 100644 --- a/app/Http/Livewire/Project/Database/Heading.php +++ b/app/Http/Livewire/Project/Database/Heading.php @@ -4,20 +4,47 @@ use Livewire\Component; use App\Actions\Database\StartPostgresql; +use App\Jobs\ContainerStatusJob; +use App\Notifications\Application\StatusChanged; class Heading extends Component { public $database; public array $parameters; + protected $listeners = ['activityFinished']; + public function activityFinished() { + $this->database->update([ + 'started_at' => now(), + ]); + $this->emit('refresh'); + $this->check_status(); + } + public function check_status() + { + dispatch_sync(new ContainerStatusJob( + resource: $this->database, + container_name: generate_container_name($this->database->uuid), + )); + $this->database->refresh(); + } public function mount() { $this->parameters = getRouteParameters(); } + public function stop() { + remote_process( + ["docker rm -f {$this->database->uuid}"], + $this->database->destination->server + ); + $this->database->status = 'stopped'; + $this->database->save(); + $this->database->environment->project->team->notify(new StatusChanged($this->database)); + } public function start() { - if ($this->database->type() === 'postgresql') { + if ($this->database->type() === 'standalone-postgresql') { $activity = resolve(StartPostgresql::class)($this->database->destination->server, $this->database); $this->emit('newMonitorActivity', $activity->id); } } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Project/Database/Postgresql/General.php b/app/Http/Livewire/Project/Database/Postgresql/General.php index b3e2faa99..8b1d6c40a 100644 --- a/app/Http/Livewire/Project/Database/Postgresql/General.php +++ b/app/Http/Livewire/Project/Database/Postgresql/General.php @@ -7,6 +7,8 @@ class General extends Component { public $database; + protected $listeners = ['refresh']; + protected $rules = [ 'database.name' => 'required', 'database.description' => 'nullable', @@ -16,6 +18,7 @@ class General extends Component 'database.postgres_initdb_args' => 'nullable', 'database.postgres_host_auth_method' => 'nullable', 'database.init_scripts' => 'nullable', + 'database.image' => 'required', ]; protected $validationAttributes = [ 'database.name' => 'Name', @@ -26,7 +29,11 @@ class General extends Component 'database.postgres_initdb_args' => 'Postgres Initdb Args', 'database.postgres_host_auth_method' => 'Postgres Host Auth Method', 'database.init_scripts' => 'Init Scripts', + 'database.image' => 'Image', ]; + public function refresh() { + $this->database->refresh(); + } public function submit() { try { $this->validate(); @@ -36,4 +43,4 @@ public function submit() { return general_error_handler(err: $e, that: $this); } } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Project/Application/Danger.php b/app/Http/Livewire/Project/Shared/Danger.php similarity index 58% rename from app/Http/Livewire/Project/Application/Danger.php rename to app/Http/Livewire/Project/Shared/Danger.php index 4af90927e..0bb5f8ef6 100644 --- a/app/Http/Livewire/Project/Application/Danger.php +++ b/app/Http/Livewire/Project/Shared/Danger.php @@ -1,14 +1,13 @@ application->destination->getMorphClass()::where('id', $this->application->destination->id)->first(); + $destination = $this->resource->destination->getMorphClass()::where('id', $this->resource->destination->id)->first(); - instant_remote_process(["docker rm -f {$this->application->uuid}"], $destination->server); - $this->application->delete(); + instant_remote_process(["docker rm -f {$this->resource->uuid}"], $destination->server); + $this->resource->delete(); return redirect()->route('project.resources', [ 'project_uuid' => $this->parameters['project_uuid'], 'environment_name' => $this->parameters['environment_name'] diff --git a/app/Http/Livewire/Project/Application/Destination.php b/app/Http/Livewire/Project/Shared/Destination.php similarity index 66% rename from app/Http/Livewire/Project/Application/Destination.php rename to app/Http/Livewire/Project/Shared/Destination.php index 571c81d9b..3bdb48af6 100644 --- a/app/Http/Livewire/Project/Application/Destination.php +++ b/app/Http/Livewire/Project/Shared/Destination.php @@ -1,6 +1,6 @@ modalId = new Cuid2(7); + } + public function refreshEnvs() + { + $this->resource->refresh(); + } + public function submit($data) + { + try { + $found = $this->resource->environment_variables()->where('key', $data['key'])->first(); + if ($found) { + $this->emit('error', 'Environment variable already exists.'); + return; + } + $environment = new EnvironmentVariable(); + $environment->key = $data['key']; + $environment->value = $data['value']; + $environment->is_build_time = $data['is_build_time']; + $environment->is_preview = $data['is_preview']; + + if($this->resource->type() === 'application') { + $environment->application_id = $this->resource->id; + } + if($this->resource->type() === 'standalone-postgresql') { + $environment->standalone_postgresql_id = $this->resource->id; + } + $environment->save(); + $this->resource->refresh(); + $this->emit('success', 'Environment variable added successfully.'); + } catch (\Exception $e) { + return general_error_handler(err: $e, that: $this); + } + } +} diff --git a/app/Http/Livewire/Project/Application/EnvironmentVariable/Show.php b/app/Http/Livewire/Project/Shared/EnvironmentVariable/Show.php similarity index 93% rename from app/Http/Livewire/Project/Application/EnvironmentVariable/Show.php rename to app/Http/Livewire/Project/Shared/EnvironmentVariable/Show.php index c5260e77c..1439e983d 100644 --- a/app/Http/Livewire/Project/Application/EnvironmentVariable/Show.php +++ b/app/Http/Livewire/Project/Shared/EnvironmentVariable/Show.php @@ -1,6 +1,6 @@ 'required|string', + 'resource.limits_memory_swap' => 'required|string', + 'resource.limits_memory_swappiness' => 'required|integer|min:0|max:100', + 'resource.limits_memory_reservation' => 'required|string', + 'resource.limits_cpus' => 'nullable', + 'resource.limits_cpuset' => 'nullable', + 'resource.limits_cpu_shares' => 'nullable', + ]; + protected $validationAttributes = [ + 'resource.limits_memory' => 'memory', + 'resource.limits_memory_swap' => 'swap', + 'resource.limits_memory_swappiness' => 'swappiness', + 'resource.limits_memory_reservation' => 'reservation', + 'resource.limits_cpus' => 'cpus', + 'resource.limits_cpuset' => 'cpuset', + 'resource.limits_cpu_shares' => 'cpu shares', + ]; + public function submit() + { + try { + if (!$this->resource->limits_memory) { + $this->resource->limits_memory = "0"; + } + if (!$this->resource->limits_memory_swap) { + $this->resource->limits_memory_swap = "0"; + } + if (!$this->resource->limits_memory_swappiness) { + $this->resource->limits_memory_swappiness = "60"; + } + if (!$this->resource->limits_memory_reservation) { + $this->resource->limits_memory_reservation = "0"; + } + if (!$this->resource->limits_cpus) { + $this->resource->limits_cpus = "0"; + } + if (!$this->resource->limits_cpuset) { + $this->resource->limits_cpuset = "0"; + } + if (!$this->resource->limits_cpu_shares) { + $this->resource->limits_cpu_shares = 1024; + } + $this->validate(); + $this->resource->save(); + $this->emit('success', 'Resource limits updated successfully.'); + } catch (\Exception $e) { + return general_error_handler(err: $e, that: $this); + } + } +} diff --git a/app/Http/Livewire/Project/Application/Storages/Add.php b/app/Http/Livewire/Project/Shared/Storages/Add.php similarity index 94% rename from app/Http/Livewire/Project/Application/Storages/Add.php rename to app/Http/Livewire/Project/Shared/Storages/Add.php index 818657a02..59a8213e1 100644 --- a/app/Http/Livewire/Project/Application/Storages/Add.php +++ b/app/Http/Livewire/Project/Shared/Storages/Add.php @@ -1,6 +1,6 @@ application->refresh(); + $this->resource->refresh(); } public function submit($data) { @@ -21,10 +20,10 @@ public function submit($data) 'name' => $data['name'], 'mount_path' => $data['mount_path'], 'host_path' => $data['host_path'], - 'resource_id' => $this->application->id, - 'resource_type' => Application::class, + 'resource_id' => $this->resource->id, + 'resource_type' => $this->resource->getMorphClass(), ]); - $this->application->refresh(); + $this->resource->refresh(); $this->emit('success', 'Storage added successfully'); $this->emit('clearAddStorage'); } catch (\Exception $e) { diff --git a/app/Http/Livewire/Project/Application/Storages/Show.php b/app/Http/Livewire/Project/Shared/Storages/Show.php similarity index 93% rename from app/Http/Livewire/Project/Application/Storages/Show.php rename to app/Http/Livewire/Project/Shared/Storages/Show.php index ef6042baf..6244537f7 100644 --- a/app/Http/Livewire/Project/Application/Storages/Show.php +++ b/app/Http/Livewire/Project/Shared/Storages/Show.php @@ -1,6 +1,6 @@ application = $application; + $this->resource = $resource; $this->container_name = $container_name; $this->pull_request_id = $pull_request_id; } @@ -34,21 +34,21 @@ public function uniqueId(): string public function handle(): void { try { - $status = get_container_status(server: $this->application->destination->server, container_id: $this->container_name, throwError: false); - if ($this->application->status === 'running' && $status === 'stopped') { - $this->application->environment->project->team->notify(new StatusChanged($this->application)); + $status = get_container_status(server: $this->resource->destination->server, container_id: $this->container_name, throwError: false); + if ($this->resource->status === 'running' && $status === 'stopped') { + $this->resource->environment->project->team->notify(new StatusChanged($this->resource)); } if ($this->pull_request_id) { - $preview = ApplicationPreview::findPreviewByApplicationAndPullId($this->application->id, $this->pull_request_id); + $preview = ApplicationPreview::findPreviewByApplicationAndPullId($this->resource->id, $this->pull_request_id); $preview->status = $status; $preview->save(); } else { - $this->application->status = $status; - $this->application->save(); + $this->resource->status = $status; + $this->resource->save(); } } catch (\Exception $e) { ray($e->getMessage()); } } -} \ No newline at end of file +} diff --git a/app/Jobs/InstanceApplicationsStatusJob.php b/app/Jobs/InstanceApplicationsStatusJob.php index a01883010..a7ab592b0 100644 --- a/app/Jobs/InstanceApplicationsStatusJob.php +++ b/app/Jobs/InstanceApplicationsStatusJob.php @@ -23,8 +23,8 @@ public function handle(): void { try { foreach ($this->applications as $application) { - dispatch(new ApplicationContainerStatusJob( - application: $application, + dispatch(new ContainerStatusJob( + resource: $application, container_name: generate_container_name($application->uuid), )); } diff --git a/app/Models/Application.php b/app/Models/Application.php index f56a55f79..2c395511b 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -43,7 +43,9 @@ protected static function booted() 'publish_directory', 'private_key_id' ]; - + public function type() { + return 'application'; + } public function publishDirectory(): Attribute { return Attribute::make( @@ -206,4 +208,4 @@ public function deploymentType() } throw new \Exception('No deployment type found'); } -} \ No newline at end of file +} diff --git a/app/Models/Environment.php b/app/Models/Environment.php index ca47fd292..3f8940cde 100644 --- a/app/Models/Environment.php +++ b/app/Models/Environment.php @@ -33,10 +33,10 @@ public function applications() } public function postgresqls() { - return $this->hasMany(StandalonePostgres::class); + return $this->hasMany(StandalonePostgresql::class); } public function services() { return $this->hasMany(Service::class); } -} \ No newline at end of file +} diff --git a/app/Models/EnvironmentVariable.php b/app/Models/EnvironmentVariable.php index 3847e1700..f3be6716b 100644 --- a/app/Models/EnvironmentVariable.php +++ b/app/Models/EnvironmentVariable.php @@ -9,26 +9,27 @@ class EnvironmentVariable extends Model { - protected static function booted() - { - static::created(function ($environment_variable) { - if (!$environment_variable->is_preview) { - ModelsEnvironmentVariable::create([ - 'key' => $environment_variable->key, - 'value' => $environment_variable->value, - 'is_build_time' => $environment_variable->is_build_time, - 'application_id' => $environment_variable->application_id, - 'is_preview' => true, - ]); - } - }); - } - protected $fillable = ['key', 'value', 'is_build_time', 'application_id', 'is_preview']; + protected $guarded = []; protected $casts = [ "key" => 'string', 'value' => 'encrypted', 'is_build_time' => 'boolean', ]; + protected static function booted() + { + static::created(function ($environment_variable) { + if ($environment_variable->application_id && !$environment_variable->is_preview) { + ModelsEnvironmentVariable::create([ + 'key' => $environment_variable->key, + 'value' => $environment_variable->value, + 'is_build_time' => $environment_variable->is_build_time, + 'application_id' => $environment_variable->application_id, + 'is_preview' => true, + ]); + } + }); + } + private function get_environment_variables(string $environment_variable): string|null { // $team_id = session('currentTeam')->id; diff --git a/app/Models/LocalPersistentVolume.php b/app/Models/LocalPersistentVolume.php index 96b550969..71546df4d 100644 --- a/app/Models/LocalPersistentVolume.php +++ b/app/Models/LocalPersistentVolume.php @@ -8,18 +8,15 @@ class LocalPersistentVolume extends Model { - protected $fillable = [ - 'name', - 'mount_path', - 'host_path', - 'container_id', - 'resource_id', - 'resource_type', - ]; + protected $guarded = []; public function application() { return $this->morphTo(); } + public function standalone_postgresql() + { + return $this->morphTo(); + } protected function name(): Attribute { return Attribute::make( diff --git a/app/Models/Project.php b/app/Models/Project.php index 129df3072..dbba240af 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -48,6 +48,6 @@ public function applications() } public function postgresqls() { - return $this->hasManyThrough(StandalonePostgres::class, Environment::class); + return $this->hasManyThrough(StandalonePostgresql::class, Environment::class); } -} \ No newline at end of file +} diff --git a/app/Models/StandaloneDocker.php b/app/Models/StandaloneDocker.php index c14bb855d..a21e22e45 100644 --- a/app/Models/StandaloneDocker.php +++ b/app/Models/StandaloneDocker.php @@ -15,7 +15,7 @@ public function applications() } public function postgresqls() { - return $this->morphMany(StandalonePostgres::class, 'destination'); + return $this->morphMany(StandalonePostgresql::class, 'destination'); } public function server() { @@ -25,4 +25,4 @@ public function attachedTo() { return $this->applications->count() > 0 || $this->databases->count() > 0; } -} \ No newline at end of file +} diff --git a/app/Models/StandalonePostgres.php b/app/Models/StandalonePostgres.php deleted file mode 100644 index df4295512..000000000 --- a/app/Models/StandalonePostgres.php +++ /dev/null @@ -1,25 +0,0 @@ - 'encrypted', - ]; - public function type() { - return 'postgresql'; - } - public function environment() - { - return $this->belongsTo(Environment::class); - } - public function destination() - { - return $this->morphTo(); - } -} \ No newline at end of file diff --git a/app/Models/StandalonePostgresql.php b/app/Models/StandalonePostgresql.php new file mode 100644 index 000000000..c2b8f37aa --- /dev/null +++ b/app/Models/StandalonePostgresql.php @@ -0,0 +1,50 @@ + 'postgres-data-' . $database->uuid, + 'mount_path' => '/var/lib/postgresql/data', + 'host_path' => null, + 'resource_id' => $database->id, + 'resource_type' => $database->getMorphClass(), + 'is_readonly' => true + ]); + }); + } + protected $guarded = []; + protected $casts = [ + 'postgres_password' => 'encrypted', + ]; + public function type() { + return 'standalone-postgresql'; + } + public function environment() + { + return $this->belongsTo(Environment::class); + } + public function destination() + { + return $this->morphTo(); + } + public function environment_variables(): HasMany + { + return $this->hasMany(EnvironmentVariable::class); + } + + public function persistentStorages() + { + return $this->morphMany(LocalPersistentVolume::class, 'resource'); + } +} diff --git a/app/Notifications/Application/StatusChanged.php b/app/Notifications/Application/StatusChanged.php index afa8839a2..4fb279d44 100644 --- a/app/Notifications/Application/StatusChanged.php +++ b/app/Notifications/Application/StatusChanged.php @@ -15,21 +15,21 @@ class StatusChanged extends Notification implements ShouldQueue { use Queueable; - public Application $application; + public $application; public string $application_name; public string|null $application_url = null; public string $project_uuid; public string $environment_name; - public string $fqdn; + public string|null $fqdn; - public function __construct(Application $application) + public function __construct($application) { $this->application = $application; $this->application_name = data_get($application, 'name'); $this->project_uuid = data_get($application, 'environment.project.uuid'); $this->environment_name = data_get($application, 'environment.name'); - $this->fqdn = data_get($application, 'fqdn'); + $this->fqdn = data_get($application, 'fqdn', null); if (Str::of($this->fqdn)->explode(',')->count() > 1) { $this->fqdn = Str::of($this->fqdn)->explode(',')->first(); } diff --git a/database/migrations/2023_08_07_142950_create_standalone_postgres_table.php b/database/migrations/2023_08_07_142950_create_standalone_postgresqls_table.php similarity index 62% rename from database/migrations/2023_08_07_142950_create_standalone_postgres_table.php rename to database/migrations/2023_08_07_142950_create_standalone_postgresqls_table.php index 3d2f1b7d3..c159434e6 100644 --- a/database/migrations/2023_08_07_142950_create_standalone_postgres_table.php +++ b/database/migrations/2023_08_07_142950_create_standalone_postgresqls_table.php @@ -11,7 +11,7 @@ */ public function up(): void { - Schema::create('standalone_postgres', function (Blueprint $table) { + Schema::create('standalone_postgresqls', function (Blueprint $table) { $table->id(); $table->string('uuid')->unique(); $table->string('name'); @@ -24,9 +24,21 @@ public function up(): void $table->string('postgres_host_auth_method')->nullable(); $table->json('init_scripts')->nullable(); + $table->string('status')->default('exited'); + + $table->string('image')->default('postgres:15-alpine'); $table->boolean('is_public')->default(false); $table->integer('public_port')->nullable(); + $table->string('limits_memory')->default("0"); + $table->string('limits_memory_swap')->default("0"); + $table->integer('limits_memory_swappiness')->default(60); + $table->string('limits_memory_reservation')->default("0"); + + $table->string('limits_cpus')->default("0"); + $table->string('limits_cpuset')->nullable()->default("0"); + $table->integer('limits_cpu_shares')->default(1024); + $table->timestamp('started_at')->nullable(); $table->morphs('destination'); @@ -40,6 +52,6 @@ public function up(): void */ public function down(): void { - Schema::dropIfExists('standalone_postgres'); + Schema::dropIfExists('standalone_postgresqls'); } -}; \ No newline at end of file +}; diff --git a/database/migrations/2023_08_07_142952_remove_foreignId_environment_variables.php b/database/migrations/2023_08_07_142952_remove_foreignId_environment_variables.php new file mode 100644 index 000000000..d24dbb446 --- /dev/null +++ b/database/migrations/2023_08_07_142952_remove_foreignId_environment_variables.php @@ -0,0 +1,32 @@ +dropColumn('service_id'); + $table->dropColumn('database_id'); + $table->foreignId('standalone_postgresql_id')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('environment_variables', function (Blueprint $table) { + $table->foreignId('service_id')->nullable(); + $table->foreignId('database_id')->nullable(); + $table->dropColumn('standalone_postgresql_id'); + }); + } +}; diff --git a/database/migrations/2023_08_07_142954_add_readonly_localpersistentvolumes.php b/database/migrations/2023_08_07_142954_add_readonly_localpersistentvolumes.php new file mode 100644 index 000000000..f0bce760d --- /dev/null +++ b/database/migrations/2023_08_07_142954_add_readonly_localpersistentvolumes.php @@ -0,0 +1,28 @@ +boolean('is_readonly')->default(false); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('local_persistent_volumes', function (Blueprint $table) { + $table->dropColumn('is_readonly'); + }); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 2bff4f36f..96209ade7 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -32,7 +32,7 @@ public function run(): void EnvironmentVariableSeeder::class, LocalPersistentVolumeSeeder::class, S3StorageSeeder::class, - StandalonePostgresSeeder::class, + StandalonePostgresqlSeeder::class, ]); } -} \ No newline at end of file +} diff --git a/database/seeders/StandalonePostgresSeeder.php b/database/seeders/StandalonePostgresqlSeeder.php similarity index 81% rename from database/seeders/StandalonePostgresSeeder.php rename to database/seeders/StandalonePostgresqlSeeder.php index c045d7358..126f159e7 100644 --- a/database/seeders/StandalonePostgresSeeder.php +++ b/database/seeders/StandalonePostgresqlSeeder.php @@ -4,17 +4,17 @@ use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; -use App\Models\StandalonePostgres; +use App\Models\StandalonePostgresql; use App\Models\StandaloneDocker; -class StandalonePostgresSeeder extends Seeder +class StandalonePostgresqlSeeder extends Seeder { /** * Run the database seeds. */ public function run(): void { - StandalonePostgres::create([ + StandalonePostgresql::create([ 'name' => 'Local PostgreSQL', 'description' => 'Local PostgreSQL for testing', 'postgres_password' => 'postgres', @@ -23,4 +23,4 @@ public function run(): void 'destination_type' => StandaloneDocker::class, ]); } -} \ No newline at end of file +} diff --git a/resources/views/components/databases/navbar.blade.php b/resources/views/components/databases/navbar.blade.php index fc8e7b68a..d6c85ffaa 100644 --- a/resources/views/components/databases/navbar.blade.php +++ b/resources/views/components/databases/navbar.blade.php @@ -8,17 +8,6 @@ {{-- --}} @if ($database->status === 'running') -
From a8ee779b3133bc0d8719b2c5e8d8821a0c89f089 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 7 Aug 2023 22:27:20 +0200 Subject: [PATCH 40/76] add env variables + volumes for postgresql --- app/Actions/Database/StartPostgresql.php | 92 +++++++++++++++++++----- app/Models/StandalonePostgresql.php | 5 +- 2 files changed, 80 insertions(+), 17 deletions(-) diff --git a/app/Actions/Database/StartPostgresql.php b/app/Actions/Database/StartPostgresql.php index 2b7386904..71d1132d3 100644 --- a/app/Actions/Database/StartPostgresql.php +++ b/app/Actions/Database/StartPostgresql.php @@ -7,25 +7,30 @@ use App\Models\Team; use App\Models\StandalonePostgresql; use Symfony\Component\Yaml\Yaml; +use Illuminate\Support\Str; class StartPostgresql { + public $database; public function __invoke(Server $server, StandalonePostgresql $database) { - $container_name = generate_container_name($database->uuid); - $destination = $database->destination; - $image = $database->image; + $this->database = $database; + + $container_name = generate_container_name($this->database->uuid); + $destination = $this->database->destination; + $image = $this->database->image; + + $persistent_storages = $this->generate_local_persistent_volumes(); + $volume_names = $this->generate_local_persistent_volumes_only_volume_names(); + $environment_variables = $this->generate_environment_variables(); + $docker_compose = [ 'version' => '3.8', 'services' => [ $container_name => [ 'image' => $image, 'container_name' => $container_name, - 'environment'=> [ - 'POSTGRES_USER' => $database->postgres_user, - 'POSTGRES_PASSWORD' => $database->postgres_password, - 'POSTGRES_DB' => $database->postgres_db, - ], + 'environment' => $environment_variables, 'restart' => 'always', 'networks' => [ $destination->network, @@ -35,20 +40,22 @@ public function __invoke(Server $server, StandalonePostgresql $database) 'CMD-SHELL', 'pg_isready', '-d', - $database->postgres_db, + $this->database->postgres_db, + '-U', + $this->database->postgres_user, ], 'interval' => '5s', 'timeout' => '5s', 'retries' => 10, 'start_period' => '5s' ], - 'mem_limit' => $database->limits_memory, - 'memswap_limit' => $database->limits_memory_swap, - 'mem_swappiness' => $database->limits_memory_swappiness, - 'mem_reservation' => $database->limits_memory_reservation, - 'cpus' => $database->limits_cpus, - 'cpuset' => $database->limits_cpuset, - 'cpu_shares' => $database->limits_cpu_shares, + 'mem_limit' => $this->database->limits_memory, + 'memswap_limit' => $this->database->limits_memory_swap, + 'mem_swappiness' => $this->database->limits_memory_swappiness, + 'mem_reservation' => $this->database->limits_memory_reservation, + 'cpus' => $this->database->limits_cpus, + 'cpuset' => $this->database->limits_cpuset, + 'cpu_shares' => $this->database->limits_cpu_shares, ] ], 'networks' => [ @@ -59,6 +66,13 @@ public function __invoke(Server $server, StandalonePostgresql $database) ] ] ]; + if (count($persistent_storages) > 0) { + $docker_compose['services'][$container_name]['volumes'] = $persistent_storages; + } + if (count($volume_names) > 0) { + $docker_compose['volumes'] = $volume_names; + } + $docker_compose = Yaml::dump($docker_compose, 10); $docker_compose_base64 = base64_encode($docker_compose); $activity = remote_process([ @@ -69,4 +83,50 @@ public function __invoke(Server $server, StandalonePostgresql $database) ], $server); return $activity; } + private function generate_environment_variables() + { + $environment_variables = collect(); + ray('Generate Environment Variables')->green(); + ray($this->database->runtime_environment_variables)->green(); + foreach ($this->database->runtime_environment_variables as $env) { + $environment_variables->push("$env->key=$env->value"); + } + + if ($environment_variables->filter(fn ($env) => Str::of($env)->contains('POSTGRES_USER'))->isEmpty()) { + $environment_variables->push("POSTGRES_USER={$this->database->postgres_user}"); + } + + if ($environment_variables->filter(fn ($env) => Str::of($env)->contains('POSTGRES_PASSWORD'))->isEmpty()) { + $environment_variables->push("POSTGRES_PASSWORD={$this->database->postgres_password}"); + } + + if ($environment_variables->filter(fn ($env) => Str::of($env)->contains('POSTGRES_DB'))->isEmpty()) { + $environment_variables->push("POSTGRES_DB={$this->database->postgres_db}"); + } + return $environment_variables->all(); + } + private function generate_local_persistent_volumes() + { + $local_persistent_volumes = []; + foreach ($this->database->persistentStorages as $persistentStorage) { + $volume_name = $persistentStorage->host_path ?? $persistentStorage->name; + $local_persistent_volumes[] = $volume_name . ':' . $persistentStorage->mount_path; + } + return $local_persistent_volumes; + } + private function generate_local_persistent_volumes_only_volume_names() + { + $local_persistent_volumes_names = []; + foreach ($this->database->persistentStorages as $persistentStorage) { + if ($persistentStorage->host_path) { + continue; + } + $name = $persistentStorage->name; + $local_persistent_volumes_names[$name] = [ + 'name' => $name, + 'external' => false, + ]; + } + return $local_persistent_volumes_names; + } } diff --git a/app/Models/StandalonePostgresql.php b/app/Models/StandalonePostgresql.php index c2b8f37aa..1fffb8b83 100644 --- a/app/Models/StandalonePostgresql.php +++ b/app/Models/StandalonePostgresql.php @@ -42,7 +42,10 @@ public function environment_variables(): HasMany { return $this->hasMany(EnvironmentVariable::class); } - + public function runtime_environment_variables(): HasMany + { + return $this->hasMany(EnvironmentVariable::class); + } public function persistentStorages() { return $this->morphMany(LocalPersistentVolume::class, 'resource'); From f2228cec7b0afa8df999abd97a43b4c654d3a617 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 8 Aug 2023 11:51:36 +0200 Subject: [PATCH 41/76] testing php storm code cleanup and styling --- .../CoolifyTask/PrepareCoolifyTask.php | 1 + app/Actions/CoolifyTask/RunRemoteProcess.php | 68 +- app/Actions/Database/StartPostgresql.php | 50 +- app/Actions/Fortify/CreateNewUser.php | 5 +- app/Actions/Fortify/ResetUserPassword.php | 2 +- app/Actions/Fortify/UpdateUserPassword.php | 2 +- .../Fortify/UpdateUserProfileInformation.php | 4 +- app/Actions/Proxy/CheckConfigurationSync.php | 4 +- app/Actions/Proxy/StartProxy.php | 5 +- app/Actions/Server/UpdateCoolify.php | 3 +- app/Console/Commands/Init.php | 2 + app/Console/Commands/NotifyDemo.php | 3 +- app/Console/Commands/SyncBunny.php | 6 +- app/Console/Kernel.php | 7 +- app/Data/CoolifyTaskArgs.php | 3 +- app/Data/ServerMetadata.php | 5 +- app/Enums/ProxyTypes.php | 1 + app/Exceptions/Handler.php | 6 +- .../Controllers/ApplicationController.php | 4 +- app/Http/Controllers/Controller.php | 22 +- app/Http/Controllers/DatabaseController.php | 4 +- app/Http/Controllers/MagicController.php | 7 +- app/Http/Controllers/ProjectController.php | 2 + app/Http/Livewire/ActivityMonitor.php | 15 +- app/Http/Livewire/CheckLicense.php | 2 + app/Http/Livewire/Destination/Form.php | 2 + .../Destination/New/StandaloneDocker.php | 21 +- app/Http/Livewire/Destination/Show.php | 1 + app/Http/Livewire/Dev/S3Test.php | 16 +- .../Notifications/DiscordSettings.php | 18 +- .../Livewire/Notifications/EmailSettings.php | 47 +- app/Http/Livewire/PrivateKey/Change.php | 2 + app/Http/Livewire/PrivateKey/Create.php | 1 + app/Http/Livewire/Profile/Form.php | 2 + app/Http/Livewire/Project/AddEmpty.php | 1 + app/Http/Livewire/Project/AddEnvironment.php | 1 + .../Project/Application/DeploymentLogs.php | 2 + .../Project/Application/DeploymentNavbar.php | 10 +- .../Project/Application/Deployments.php | 3 + .../Livewire/Project/Application/General.php | 8 +- .../Livewire/Project/Application/Heading.php | 18 +- .../Project/Application/Preview/Form.php | 4 + .../Livewire/Project/Application/Previews.php | 16 +- .../Livewire/Project/Application/Rollback.php | 4 +- .../Livewire/Project/Application/Source.php | 12 +- .../Livewire/Project/Database/Heading.php | 16 +- .../Project/Database/Postgresql/General.php | 8 +- .../Livewire/Project/DeleteEnvironment.php | 1 + app/Http/Livewire/Project/DeleteProject.php | 1 + .../Project/New/GithubPrivateRepository.php | 67 +- .../New/GithubPrivateRepositoryDeployKey.php | 55 +- .../Project/New/PublicGitRepository.php | 29 +- app/Http/Livewire/Project/New/Select.php | 4 + app/Http/Livewire/Project/Shared/Danger.php | 1 + .../Shared/EnvironmentVariable/Add.php | 3 + .../Shared/EnvironmentVariable/All.php | 9 +- .../Shared/EnvironmentVariable/Show.php | 3 + .../Project/Shared/ResourceLimits.php | 1 + .../Livewire/Project/Shared/Storages/Add.php | 3 + .../Livewire/Project/Shared/Storages/All.php | 2 + .../Livewire/Project/Shared/Storages/Show.php | 3 + app/Http/Livewire/RunCommand.php | 2 +- app/Http/Livewire/Server/Form.php | 8 +- app/Http/Livewire/Server/New/ByIp.php | 5 +- app/Http/Livewire/Server/PrivateKey.php | 21 +- app/Http/Livewire/Server/Proxy.php | 12 +- app/Http/Livewire/Server/Proxy/Deploy.php | 5 +- app/Http/Livewire/Server/Proxy/Status.php | 3 +- app/Http/Livewire/Settings/Configuration.php | 77 +- app/Http/Livewire/Settings/Email.php | 36 +- app/Http/Livewire/Source/Github/Change.php | 3 + app/Http/Livewire/Source/Github/Create.php | 1 + app/Http/Livewire/SwitchTeam.php | 2 + app/Http/Livewire/Team/Create.php | 1 + app/Http/Livewire/Team/Form.php | 3 +- app/Http/Livewire/Team/Invitations.php | 10 +- app/Http/Livewire/Team/InviteLink.php | 6 +- app/Http/Livewire/Team/Member.php | 3 + app/Http/Livewire/Team/Storage/Create.php | 32 +- app/Http/Livewire/Team/Storage/Form.php | 17 +- app/Http/Livewire/Upgrade.php | 5 +- .../Middleware/RedirectIfAuthenticated.php | 2 +- app/Http/Middleware/TrustProxies.php | 2 +- app/Jobs/ApplicationDeploymentJob.php | 583 +- app/Jobs/ApplicationPullRequestUpdateJob.php | 8 +- app/Jobs/CheckResaleLicenseJob.php | 4 - app/Jobs/ContainerStatusJob.php | 4 +- app/Jobs/CoolifyTask.php | 5 +- app/Jobs/DockerCleanupJob.php | 3 +- app/Jobs/InstanceApplicationsStatusJob.php | 2 + app/Jobs/InstanceAutoUpdateJob.php | 4 +- app/Jobs/ProxyCheckJob.php | 2 +- app/Jobs/ProxyContainerStatusJob.php | 14 +- app/Jobs/ProxyStartJob.php | 1 + app/Jobs/SendMessageToDiscordJob.php | 4 +- app/Models/Application.php | 95 +- app/Models/ApplicationPreview.php | 10 +- app/Models/ApplicationSetting.php | 2 + app/Models/BaseModel.php | 2 +- app/Models/Database.php | 1 + app/Models/Environment.php | 35 +- app/Models/EnvironmentVariable.php | 38 +- app/Models/GithubApp.php | 22 +- app/Models/GitlabApp.php | 2 + app/Models/InstanceSettings.php | 17 +- app/Models/LocalPersistentVolume.php | 9 +- app/Models/PrivateKey.php | 38 +- app/Models/Project.php | 35 +- app/Models/S3Storage.php | 11 +- app/Models/Server.php | 86 +- app/Models/ServerSetting.php | 1 + app/Models/Service.php | 1 + app/Models/StandaloneDocker.php | 4 + app/Models/StandalonePostgresql.php | 23 +- app/Models/Subscription.php | 2 +- app/Models/SwarmDocker.php | 1 + app/Models/Team.php | 55 +- app/Models/TeamInvitation.php | 1 + app/Models/User.php | 29 +- app/Models/Webhook.php | 3 +- .../Application/DeploymentFailed.php | 10 +- .../Application/DeploymentSuccess.php | 10 +- .../Application/StatusChanged.php | 11 +- app/Notifications/Channels/EmailChannel.php | 4 +- .../Channels/TransactionalEmailChannel.php | 4 +- app/Notifications/Test.php | 10 +- .../TransactionalEmails/InvitationLink.php | 3 +- .../TransactionalEmails/ResetPassword.php | 34 +- .../TransactionalEmails/Test.php | 5 +- app/Providers/AppServiceProvider.php | 1 - app/Providers/EventServiceProvider.php | 1 - app/Providers/FortifyServiceProvider.php | 5 +- app/Traits/ExecuteRemoteCommand.php | 2 +- app/View/Components/Forms/Button.php | 13 +- app/View/Components/Forms/Checkbox.php | 9 +- app/View/Components/Forms/Input.php | 16 +- app/View/Components/Forms/Select.php | 9 +- app/View/Components/Forms/Textarea.php | 13 +- app/View/Components/Modal.php | 12 +- bootstrap/app.php | 2 - bootstrap/helpers/applications.php | 2 +- bootstrap/helpers/docker.php | 7 +- bootstrap/helpers/github.php | 6 +- bootstrap/helpers/proxy.php | 85 +- bootstrap/helpers/remoteProcess.php | 11 +- bootstrap/helpers/s3.php | 25 +- bootstrap/helpers/shared.php | 9 +- bootstrap/helpers/subscriptions.php | 4 + config/app.php | 2 +- config/broadcasting.php | 2 +- config/logging.php | 2 +- database/factories/UserFactory.php | 2 +- .../2014_10_12_000000_create_users_table.php | 3 +- ...000_create_password_reset_tokens_table.php | 3 +- ..._add_two_factor_columns_to_users_table.php | 15 +- ...01_create_personal_access_tokens_table.php | 3 +- ...03_20_112410_create_activity_log_table.php | 4 +- ...add_event_column_to_activity_log_table.php | 4 +- ...atch_uuid_column_to_activity_log_table.php | 4 +- ...023_03_20_112809_create_sessions_table.php | 3 +- .../2023_03_20_112811_create_teams_table.php | 5 +- ...23_03_20_112812_create_team_user_table.php | 3 +- ...0_112813_create_team_invitations_table.php | 3 +- ..._112814_create_instance_settings_table.php | 3 +- ...2023_03_24_140711_create_servers_table.php | 3 +- ...24_140712_create_server_settings_table.php | 3 +- ...03_24_140853_create_private_keys_table.php | 3 +- ...023_03_27_075351_create_projects_table.php | 3 +- ...7_075443_create_project_settings_table.php | 3 +- ...03_27_075444_create_environments_table.php | 3 +- ...03_27_081716_create_applications_table.php | 3 +- ...1717_create_application_settings_table.php | 3 +- ...1718_create_application_previews_table.php | 3 +- ...023_03_27_083621_create_services_table.php | 3 +- ...085020_create_standalone_dockers_table.php | 3 +- ...3_27_085022_create_swarm_dockers_table.php | 3 +- ...3_03_28_062150_create_kubernetes_table.php | 3 +- ..._03_28_083723_create_github_apps_table.php | 3 +- ..._03_28_083726_create_gitlab_apps_table.php | 3 +- ..._create_local_persistent_volumes_table.php | 3 +- ...548_create_environment_variables_table.php | 3 +- ..._05_17_104039_create_failed_jobs_table.php | 3 +- ...te_application_deployment_queues_table.php | 3 +- ...3_06_22_131459_move_wildcard_to_server.php | 3 +- ..._wildcard_domain_from_instancesettings.php | 5 +- ...2023_06_23_110548_next_channel_updates.php | 3 +- ..._23_114131_change_env_var_value_length.php | 3 +- ...efault_redirect_from_instance_settings.php | 3 +- ...lication_deployment_queues_as_activity.php | 5 +- ...4_add_disk_usage_percentage_to_servers.php | 5 +- ...7_13_115117_create_subscriptions_table.php | 5 +- ...023_07_13_120719_create_webhooks_table.php | 3 +- ...20721_add_license_to_instance_settings.php | 3 +- ...2013_smtp_discord_schemaless_to_normal.php | 27 +- ..._08_07_073651_create_s3_storages_table.php | 5 +- ...50_create_standalone_postgresqls_table.php | 3 +- ...escription_field_to_applications_table.php | 5 +- ...remove_foreignId_environment_variables.php | 3 +- ...54_add_readonly_localpersistentvolumes.php | 3 +- database/seeders/ApplicationPreviewSeeder.php | 5 - database/seeders/ApplicationSeeder.php | 6 +- .../seeders/ApplicationSettingsSeeder.php | 5 - database/seeders/DBSeeder.php | 1 - database/seeders/DatabaseSeeder.php | 1 - database/seeders/EnvironmentSeeder.php | 3 - database/seeders/GitSeeder.php | 3 - database/seeders/GithubAppSeeder.php | 1 - database/seeders/GitlabAppSeeder.php | 1 - database/seeders/KubernetesSeeder.php | 1 - database/seeders/PrivateKeySeeder.php | 2 - database/seeders/S3StorageSeeder.php | 5 +- database/seeders/ServerSeeder.php | 3 - database/seeders/ServerSettingSeeder.php | 1 - database/seeders/ServiceSeeder.php | 1 - database/seeders/StandaloneDockerSeeder.php | 1 - .../seeders/StandalonePostgresqlSeeder.php | 5 +- database/seeders/SubscriptionSeeder.php | 1 - database/seeders/SwarmDockerSeeder.php | 2 - database/seeders/WebhookSeeder.php | 1 - other/logos/appwrite.svg | 16 +- public/index.php | 6 +- public/svgs/external-link.svg | 10 +- public/vendor/horizon/app-dark.css | 10114 +++++++++++++++- public/vendor/horizon/app.css | 10112 ++++++++++++++- public/vendor/horizon/img/horizon.svg | 6 +- public/vendor/horizon/img/sprite.svg | 478 +- .../views/auth/confirm-password.blade.php | 4 +- .../views/auth/forgot-password.blade.php | 8 +- resources/views/auth/login.blade.php | 52 +- resources/views/auth/register.blade.php | 44 +- resources/views/auth/reset-password.blade.php | 8 +- .../views/auth/two-factor-challenge.blade.php | 10 +- resources/views/command-center.blade.php | 4 +- .../applications/advanced.blade.php | 38 +- .../components/applications/links.blade.php | 75 +- .../components/applications/navbar.blade.php | 21 +- .../views/components/chevron-down.blade.php | 6 +- .../components/databases/navbar.blade.php | 15 +- .../views/components/forms/button.blade.php | 21 +- .../views/components/forms/checkbox.blade.php | 7 +- .../views/components/forms/input.blade.php | 34 +- .../views/components/forms/select.blade.php | 5 +- .../views/components/forms/textarea.blade.php | 10 +- resources/views/components/git-icon.blade.php | 30 +- resources/views/components/helper.blade.php | 2 +- .../views/components/layout-simple.blade.php | 46 +- .../components/layout-subscription.blade.php | 71 +- resources/views/components/layout.blade.php | 199 +- resources/views/components/modal.blade.php | 10 +- .../components/navbar-subscription.blade.php | 16 +- resources/views/components/navbar.blade.php | 111 +- .../views/components/pricing-plans.blade.php | 108 +- .../views/components/proxy/options.blade.php | 8 +- .../resources/breadcrumbs.blade.php | 93 +- .../views/components/server/navbar.blade.php | 12 +- .../components/settings/navbar.blade.php | 7 +- .../components/status/restarting.blade.php | 2 +- .../views/components/status/running.blade.php | 2 +- .../views/components/status/stopped.blade.php | 2 +- .../views/components/team/navbar.blade.php | 12 +- .../views/components/use-magic-bar.blade.php | 7 +- resources/views/components/version.blade.php | 2 +- resources/views/dashboard.blade.php | 2 +- resources/views/destination/all.blade.php | 6 +- resources/views/destination/new.blade.php | 2 +- resources/views/destination/show.blade.php | 2 +- .../emails/application-deployment-failed.php | 6 +- .../emails/application-deployment-success.php | 6 +- .../views/emails/invitation-link.blade.php | 3 +- resources/views/errors/404.blade.php | 5 +- resources/views/errors/419.blade.php | 5 +- resources/views/errors/layout.blade.php | 10 +- resources/views/errors/minimal.blade.php | 541 +- .../views/livewire/activity-monitor.blade.php | 6 +- .../views/livewire/check-license.blade.php | 7 +- .../views/livewire/destination/form.blade.php | 6 +- .../new/standalone-docker.blade.php | 4 +- .../views/livewire/dev/s3-test.blade.php | 2 +- .../notifications/discord-settings.blade.php | 15 +- .../notifications/email-settings.blade.php | 33 +- .../livewire/private-key/change.blade.php | 14 +- .../livewire/private-key/create.blade.php | 6 +- .../views/livewire/profile/form.blade.php | 4 +- .../livewire/project/add-empty.blade.php | 4 +- .../project/add-environment.blade.php | 2 +- .../application/deployment-logs.blade.php | 10 +- .../project/application/deployments.blade.php | 163 +- .../project/application/general.blade.php | 36 +- .../project/application/heading.blade.php | 4 +- .../application/preview/form.blade.php | 2 +- .../project/application/previews.blade.php | 65 +- .../project/application/source.blade.php | 12 +- .../project/database/heading.blade.php | 4 +- .../database/postgresql/general.blade.php | 30 +- .../project/delete-environment.blade.php | 2 +- .../views/livewire/project/edit.blade.php | 6 +- ...ub-private-repository-deploy-key.blade.php | 18 +- .../new/github-private-repository.blade.php | 41 +- .../new/public-git-repository.blade.php | 12 +- .../livewire/project/new/select.blade.php | 24 +- .../shared/environment-variable/add.blade.php | 6 +- .../shared/environment-variable/all.blade.php | 6 +- .../environment-variable/show.blade.php | 6 +- .../project/shared/resource-limits.blade.php | 14 +- .../project/shared/storages/add.blade.php | 6 +- .../project/shared/storages/all.blade.php | 6 +- .../project/shared/storages/show.blade.php | 15 +- .../views/livewire/run-command.blade.php | 4 +- .../views/livewire/server/form.blade.php | 18 +- .../views/livewire/server/new/by-ip.blade.php | 10 +- .../livewire/server/private-key.blade.php | 2 +- .../views/livewire/server/proxy.blade.php | 53 +- .../livewire/server/proxy/deploy.blade.php | 22 +- .../livewire/server/proxy/status.blade.php | 6 +- .../livewire/settings/configuration.blade.php | 10 +- .../views/livewire/settings/email.blade.php | 22 +- .../livewire/source/github/change.blade.php | 63 +- .../livewire/source/github/create.blade.php | 14 +- .../views/livewire/team/create.blade.php | 4 +- .../views/livewire/team/delete.blade.php | 6 +- resources/views/livewire/team/form.blade.php | 4 +- .../views/livewire/team/invitations.blade.php | 43 +- .../views/livewire/team/invite-link.blade.php | 2 +- .../livewire/team/storage/create.blade.php | 14 +- .../livewire/team/storage/form.blade.php | 14 +- resources/views/livewire/upgrade.blade.php | 52 +- resources/views/private-key/all.blade.php | 4 +- resources/views/private-key/new.blade.php | 2 +- resources/views/private-key/show.blade.php | 2 +- resources/views/profile.blade.php | 10 +- .../application/configuration.blade.php | 47 +- .../project/application/deployment.blade.php | 4 +- .../project/application/deployments.blade.php | 5 +- .../project/database/configuration.blade.php | 37 +- resources/views/project/edit.blade.php | 2 +- resources/views/project/new.blade.php | 8 +- resources/views/project/resources.blade.php | 18 +- resources/views/project/show.blade.php | 2 +- resources/views/projects.blade.php | 24 +- resources/views/server/all.blade.php | 4 +- resources/views/server/create.blade.php | 4 +- resources/views/server/destinations.blade.php | 4 +- resources/views/server/private-key.blade.php | 4 +- resources/views/server/proxy.blade.php | 4 +- resources/views/server/show.blade.php | 4 +- .../views/settings/configuration.blade.php | 4 +- resources/views/settings/emails.blade.php | 4 +- resources/views/settings/license.blade.php | 4 +- resources/views/source/all.blade.php | 10 +- resources/views/source/github/show.blade.php | 2 +- resources/views/source/new.blade.php | 10 +- resources/views/subscription.blade.php | 4 +- resources/views/team/create.blade.php | 2 +- resources/views/team/members.blade.php | 27 +- resources/views/team/notifications.blade.php | 10 +- resources/views/team/show.blade.php | 6 +- resources/views/team/storages/all.blade.php | 7 +- .../views/team/storages/create.blade.php | 2 +- resources/views/team/storages/show.blade.php | 4 +- resources/views/vendor/toaster/hub.blade.php | 68 +- routes/channels.php | 2 - routes/web.php | 42 +- routes/webhooks.php | 26 +- tests/Browser/ExampleTest.php | 3 +- tests/CreatesApplication.php | 2 +- tests/DuskTestCase.php | 22 +- tests/Feature/DockerCommandsTest.php | 4 +- tests/Pest.php | 2 +- 368 files changed, 23834 insertions(+), 2623 deletions(-) diff --git a/app/Actions/CoolifyTask/PrepareCoolifyTask.php b/app/Actions/CoolifyTask/PrepareCoolifyTask.php index 263cd329e..3b2f70014 100644 --- a/app/Actions/CoolifyTask/PrepareCoolifyTask.php +++ b/app/Actions/CoolifyTask/PrepareCoolifyTask.php @@ -15,6 +15,7 @@ class PrepareCoolifyTask { protected Activity $activity; protected CoolifyTaskArgs $remoteProcessArgs; + public function __construct(CoolifyTaskArgs $remoteProcessArgs) { $this->remoteProcessArgs = $remoteProcessArgs; diff --git a/app/Actions/CoolifyTask/RunRemoteProcess.php b/app/Actions/CoolifyTask/RunRemoteProcess.php index 2a9fc63a0..0a7892f98 100644 --- a/app/Actions/CoolifyTask/RunRemoteProcess.php +++ b/app/Actions/CoolifyTask/RunRemoteProcess.php @@ -49,6 +49,28 @@ public function __construct(Activity $activity, bool $hide_from_output = false, $this->ignore_errors = $ignore_errors; } + public static function decodeOutput(?Activity $activity = null): string + { + if (is_null($activity)) { + return ''; + } + + try { + $decoded = json_decode( + data_get($activity, 'description'), + associative: true, + flags: JSON_THROW_ON_ERROR + ); + } catch (\JsonException $exception) { + return ''; + } + + return collect($decoded) + ->sortBy(fn($i) => $i['order']) + ->map(fn($i) => $i['output']) + ->implode(""); + } + public function __invoke(): ProcessResult { $this->time_start = hrtime(true); @@ -83,15 +105,6 @@ public function __invoke(): ProcessResult return $processResult; } - protected function getLatestCounter(): int - { - $description = json_decode($this->activity->description, associative: true, flags: JSON_THROW_ON_ERROR); - if ($description === null || count($description) === 0) { - return 1; - } - return end($description)['order'] + 1; - } - protected function getCommand(): string { $user = $this->activity->getExtraProperty('user'); @@ -120,6 +133,13 @@ protected function handleOutput(string $type, string $output) } } + protected function elapsedTime(): int + { + $timeMs = (hrtime(true) - $this->time_start) / 1_000_000; + + return intval($timeMs); + } + public function encodeOutput($type, $output) { $outputStack = json_decode($this->activity->description, associative: true, flags: JSON_THROW_ON_ERROR); @@ -135,26 +155,13 @@ public function encodeOutput($type, $output) return json_encode($outputStack, flags: JSON_THROW_ON_ERROR); } - public static function decodeOutput(?Activity $activity = null): string + protected function getLatestCounter(): int { - if (is_null($activity)) { - return ''; + $description = json_decode($this->activity->description, associative: true, flags: JSON_THROW_ON_ERROR); + if ($description === null || count($description) === 0) { + return 1; } - - try { - $decoded = json_decode( - data_get($activity, 'description'), - associative: true, - flags: JSON_THROW_ON_ERROR - ); - } catch (\JsonException $exception) { - return ''; - } - - return collect($decoded) - ->sortBy(fn ($i) => $i['order']) - ->map(fn ($i) => $i['output']) - ->implode(""); + return end($description)['order'] + 1; } /** @@ -171,11 +178,4 @@ protected function isAfterLastThrottle() return ($this->current_time - $this->throttle_interval_ms) > $this->last_write_at; } - - protected function elapsedTime(): int - { - $timeMs = (hrtime(true) - $this->time_start) / 1_000_000; - - return intval($timeMs); - } } diff --git a/app/Actions/Database/StartPostgresql.php b/app/Actions/Database/StartPostgresql.php index 71d1132d3..b3e7dce5f 100644 --- a/app/Actions/Database/StartPostgresql.php +++ b/app/Actions/Database/StartPostgresql.php @@ -3,15 +3,14 @@ namespace App\Actions\Database; use App\Models\Server; -use App\Models\StandaloneDocker; -use App\Models\Team; use App\Models\StandalonePostgresql; -use Symfony\Component\Yaml\Yaml; use Illuminate\Support\Str; +use Symfony\Component\Yaml\Yaml; class StartPostgresql { public $database; + public function __invoke(Server $server, StandalonePostgresql $database) { $this->database = $database; @@ -83,28 +82,7 @@ public function __invoke(Server $server, StandalonePostgresql $database) ], $server); return $activity; } - private function generate_environment_variables() - { - $environment_variables = collect(); - ray('Generate Environment Variables')->green(); - ray($this->database->runtime_environment_variables)->green(); - foreach ($this->database->runtime_environment_variables as $env) { - $environment_variables->push("$env->key=$env->value"); - } - if ($environment_variables->filter(fn ($env) => Str::of($env)->contains('POSTGRES_USER'))->isEmpty()) { - $environment_variables->push("POSTGRES_USER={$this->database->postgres_user}"); - } - - if ($environment_variables->filter(fn ($env) => Str::of($env)->contains('POSTGRES_PASSWORD'))->isEmpty()) { - $environment_variables->push("POSTGRES_PASSWORD={$this->database->postgres_password}"); - } - - if ($environment_variables->filter(fn ($env) => Str::of($env)->contains('POSTGRES_DB'))->isEmpty()) { - $environment_variables->push("POSTGRES_DB={$this->database->postgres_db}"); - } - return $environment_variables->all(); - } private function generate_local_persistent_volumes() { $local_persistent_volumes = []; @@ -114,6 +92,7 @@ private function generate_local_persistent_volumes() } return $local_persistent_volumes; } + private function generate_local_persistent_volumes_only_volume_names() { $local_persistent_volumes_names = []; @@ -129,4 +108,27 @@ private function generate_local_persistent_volumes_only_volume_names() } return $local_persistent_volumes_names; } + + private function generate_environment_variables() + { + $environment_variables = collect(); + ray('Generate Environment Variables')->green(); + ray($this->database->runtime_environment_variables)->green(); + foreach ($this->database->runtime_environment_variables as $env) { + $environment_variables->push("$env->key=$env->value"); + } + + if ($environment_variables->filter(fn($env) => Str::of($env)->contains('POSTGRES_USER'))->isEmpty()) { + $environment_variables->push("POSTGRES_USER={$this->database->postgres_user}"); + } + + if ($environment_variables->filter(fn($env) => Str::of($env)->contains('POSTGRES_PASSWORD'))->isEmpty()) { + $environment_variables->push("POSTGRES_PASSWORD={$this->database->postgres_password}"); + } + + if ($environment_variables->filter(fn($env) => Str::of($env)->contains('POSTGRES_DB'))->isEmpty()) { + $environment_variables->push("POSTGRES_DB={$this->database->postgres_db}"); + } + return $environment_variables->all(); + } } diff --git a/app/Actions/Fortify/CreateNewUser.php b/app/Actions/Fortify/CreateNewUser.php index 71dbcf28f..77ae73fce 100644 --- a/app/Actions/Fortify/CreateNewUser.php +++ b/app/Actions/Fortify/CreateNewUser.php @@ -3,11 +3,8 @@ namespace App\Actions\Fortify; use App\Models\InstanceSettings; -use App\Models\Team; use App\Models\User; -use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; -use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Validator; use Illuminate\Validation\Rule; use Laravel\Fortify\Contracts\CreatesNewUsers; @@ -19,7 +16,7 @@ class CreateNewUser implements CreatesNewUsers /** * Validate and create a newly registered user. * - * @param array $input + * @param array $input */ public function create(array $input): User { diff --git a/app/Actions/Fortify/ResetUserPassword.php b/app/Actions/Fortify/ResetUserPassword.php index 7a57c5037..58d99b1b2 100644 --- a/app/Actions/Fortify/ResetUserPassword.php +++ b/app/Actions/Fortify/ResetUserPassword.php @@ -14,7 +14,7 @@ class ResetUserPassword implements ResetsUserPasswords /** * Validate and reset the user's forgotten password. * - * @param array $input + * @param array $input */ public function reset(User $user, array $input): void { diff --git a/app/Actions/Fortify/UpdateUserPassword.php b/app/Actions/Fortify/UpdateUserPassword.php index 700563905..5ebf31875 100644 --- a/app/Actions/Fortify/UpdateUserPassword.php +++ b/app/Actions/Fortify/UpdateUserPassword.php @@ -14,7 +14,7 @@ class UpdateUserPassword implements UpdatesUserPasswords /** * Validate and update the user's password. * - * @param array $input + * @param array $input */ public function update(User $user, array $input): void { diff --git a/app/Actions/Fortify/UpdateUserProfileInformation.php b/app/Actions/Fortify/UpdateUserProfileInformation.php index 0930ddf38..c8f2cce59 100644 --- a/app/Actions/Fortify/UpdateUserProfileInformation.php +++ b/app/Actions/Fortify/UpdateUserProfileInformation.php @@ -13,7 +13,7 @@ class UpdateUserProfileInformation implements UpdatesUserProfileInformation /** * Validate and update the given user's profile information. * - * @param array $input + * @param array $input */ public function update(User $user, array $input): void { @@ -43,7 +43,7 @@ public function update(User $user, array $input): void /** * Update the given verified user's profile information. * - * @param array $input + * @param array $input */ protected function updateVerifiedUser(User $user, array $input): void { diff --git a/app/Actions/Proxy/CheckConfigurationSync.php b/app/Actions/Proxy/CheckConfigurationSync.php index 3648aa388..af7804cb7 100644 --- a/app/Actions/Proxy/CheckConfigurationSync.php +++ b/app/Actions/Proxy/CheckConfigurationSync.php @@ -2,8 +2,6 @@ namespace App\Actions\Proxy; -use App\Actions\Proxy\SaveConfigurationSync; -use App\Enums\ProxyTypes; use App\Models\Server; use Illuminate\Support\Str; @@ -25,4 +23,4 @@ public function __invoke(Server $server, bool $reset = false) return $proxy_configuration; } -} \ No newline at end of file +} diff --git a/app/Actions/Proxy/StartProxy.php b/app/Actions/Proxy/StartProxy.php index cea5a2166..b9d9ab02b 100644 --- a/app/Actions/Proxy/StartProxy.php +++ b/app/Actions/Proxy/StartProxy.php @@ -2,12 +2,11 @@ namespace App\Actions\Proxy; -use App\Actions\Proxy\CheckConfigurationSync; use App\Enums\ProxyStatus; use App\Enums\ProxyTypes; use App\Models\Server; -use Spatie\Activitylog\Models\Activity; use Illuminate\Support\Str; +use Spatie\Activitylog\Models\Activity; class StartProxy { @@ -54,4 +53,4 @@ public function __invoke(Server $server): Activity return $activity; } -} \ No newline at end of file +} diff --git a/app/Actions/Server/UpdateCoolify.php b/app/Actions/Server/UpdateCoolify.php index 71231cd36..8b5644a1d 100644 --- a/app/Actions/Server/UpdateCoolify.php +++ b/app/Actions/Server/UpdateCoolify.php @@ -23,7 +23,7 @@ public function __invoke(bool $force) $this->server = Server::where('name', $localhost_name)->firstOrFail(); $this->latest_version = get_latest_version_of_coolify(); $this->current_version = config('version'); - ray('latest version:' . $this->latest_version . " current version: " . $this->current_version . ' force: ' . $force); + ray('latest version:' . $this->latest_version . " current version: " . $this->current_version . ' force: ' . $force); if ($settings->next_channel) { ray('next channel enabled'); $this->latest_version = 'next'; @@ -49,6 +49,7 @@ public function __invoke(bool $force) return; } } + private function update() { if (isDev()) { diff --git a/app/Console/Commands/Init.php b/app/Console/Commands/Init.php index 32ff31827..ae682e682 100644 --- a/app/Console/Commands/Init.php +++ b/app/Console/Commands/Init.php @@ -10,10 +10,12 @@ class Init extends Command { protected $signature = 'app:init'; protected $description = 'Cleanup instance related stuffs'; + public function handle() { $this->cleanup_in_progress_application_deployments(); } + private function cleanup_in_progress_application_deployments() { // Cleanup any failed deployments diff --git a/app/Console/Commands/NotifyDemo.php b/app/Console/Commands/NotifyDemo.php index 1d5906bd0..37b84d489 100644 --- a/app/Console/Commands/NotifyDemo.php +++ b/app/Console/Commands/NotifyDemo.php @@ -64,7 +64,8 @@ private function showHelp()
- HTML); + HTML + ); ask(<<<'HTML'
diff --git a/app/Console/Commands/SyncBunny.php b/app/Console/Commands/SyncBunny.php index dec92dd6e..131d20130 100644 --- a/app/Console/Commands/SyncBunny.php +++ b/app/Console/Commands/SyncBunny.php @@ -4,8 +4,8 @@ use Illuminate\Console\Command; use Illuminate\Http\Client\PendingRequest; -use Illuminate\Support\Facades\Http; use Illuminate\Http\Client\Pool; +use Illuminate\Support\Facades\Http; class SyncBunny extends Command { @@ -64,7 +64,7 @@ public function handle() ]); }); try { - Http::pool(fn (Pool $pool) => [ + Http::pool(fn(Pool $pool) => [ $pool->storage(file: "$parent_dir/$compose_file")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$compose_file"), $pool->storage(file: "$parent_dir/$compose_file_prod")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$compose_file_prod"), $pool->storage(file: "$parent_dir/$production_env")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$production_env"), @@ -73,7 +73,7 @@ public function handle() $pool->storage(file: "$parent_dir/$versions")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$versions"), ]); ray("{$bunny_cdn}/{$bunny_cdn_path}"); - Http::pool(fn (Pool $pool) => [ + Http::pool(fn(Pool $pool) => [ $pool->purge("$bunny_cdn/$bunny_cdn_path/$compose_file"), $pool->purge("$bunny_cdn/$bunny_cdn_path/$compose_file_prod"), $pool->purge("$bunny_cdn/$bunny_cdn_path/$production_env"), diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 8acfc53c8..0714a5d75 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -2,12 +2,12 @@ namespace App\Console; -use App\Jobs\InstanceApplicationsStatusJob; use App\Jobs\CheckResaleLicenseJob; +use App\Jobs\CheckResaleLicenseKeys; +use App\Jobs\DockerCleanupJob; +use App\Jobs\InstanceApplicationsStatusJob; use App\Jobs\InstanceAutoUpdateJob; use App\Jobs\ProxyCheckJob; -use App\Jobs\DockerCleanupJob; -use App\Jobs\CheckResaleLicenseKeys; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; @@ -31,6 +31,7 @@ protected function schedule(Schedule $schedule): void $schedule->job(new InstanceAutoUpdateJob)->everyTenMinutes(); } } + protected function commands(): void { $this->load(__DIR__ . '/Commands'); diff --git a/app/Data/CoolifyTaskArgs.php b/app/Data/CoolifyTaskArgs.php index 1b30126f0..d451faa00 100644 --- a/app/Data/CoolifyTaskArgs.php +++ b/app/Data/CoolifyTaskArgs.php @@ -22,6 +22,7 @@ public function __construct( public ?Model $model = null, public string $status = ProcessStatus::QUEUED->value, public bool $ignore_errors = false, - ) { + ) + { } } diff --git a/app/Data/ServerMetadata.php b/app/Data/ServerMetadata.php index b96efa622..18f734ce4 100644 --- a/app/Data/ServerMetadata.php +++ b/app/Data/ServerMetadata.php @@ -9,8 +9,9 @@ class ServerMetadata extends Data { public function __construct( - public ?ProxyTypes $type, + public ?ProxyTypes $type, public ?ProxyStatus $status - ) { + ) + { } } diff --git a/app/Enums/ProxyTypes.php b/app/Enums/ProxyTypes.php index e94792188..dfbf65c64 100644 --- a/app/Enums/ProxyTypes.php +++ b/app/Enums/ProxyTypes.php @@ -8,6 +8,7 @@ enum ProxyTypes: string case NGINX = 'NGINX'; case CADDY = 'CADDY'; } + enum ProxyStatus: string { case EXITED = 'exited'; diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 3fc20bd25..9d9dabab6 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -4,13 +4,12 @@ use App\Models\InstanceSettings; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; -use Throwable; use Sentry\Laravel\Integration; +use Throwable; class Handler extends ExceptionHandler { - private InstanceSettings $settings; /** * A list of exception types with their corresponding custom log levels. * @@ -19,7 +18,6 @@ class Handler extends ExceptionHandler protected $levels = [ // ]; - /** * A list of the exception types that are not reported. * @@ -28,7 +26,6 @@ class Handler extends ExceptionHandler protected $dontReport = [ // ]; - /** * A list of the inputs that are never flashed to the session on validation exceptions. * @@ -39,6 +36,7 @@ class Handler extends ExceptionHandler 'password', 'password_confirmation', ]; + private InstanceSettings $settings; /** * Register the exception handling callbacks for the application. diff --git a/app/Http/Controllers/ApplicationController.php b/app/Http/Controllers/ApplicationController.php index b6685276f..3eb638426 100644 --- a/app/Http/Controllers/ApplicationController.php +++ b/app/Http/Controllers/ApplicationController.php @@ -5,12 +5,11 @@ use App\Models\ApplicationDeploymentQueue; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Validation\ValidatesRequests; -use Illuminate\Http\Request; -use Spatie\Activitylog\Models\Activity; class ApplicationController extends Controller { use AuthorizesRequests, ValidatesRequests; + public function configuration() { $project = session('currentTeam')->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); @@ -28,6 +27,7 @@ public function configuration() ray($application->persistentStorages()->get()); return view('project.application.configuration', ['application' => $application]); } + public function deployments() { $project = session('currentTeam')->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index a37672983..0c4838a97 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -2,17 +2,15 @@ namespace App\Http\Controllers; -use App\Http\Livewire\Team\Invitations; use App\Models\InstanceSettings; use App\Models\Project; +use App\Models\S3Storage; use App\Models\Server; use App\Models\TeamInvitation; use App\Models\User; -use App\Models\S3Storage; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Routing\Controller as BaseController; -use Illuminate\Support\Facades\DB; class Controller extends BaseController { @@ -27,6 +25,7 @@ public function subscription() 'settings' => InstanceSettings::get() ]); } + public function license() { if (!isCloud()) { @@ -36,6 +35,7 @@ public function license() 'settings' => InstanceSettings::get() ]); } + public function dashboard() { $projects = Project::ownedByCurrentTeam()->get(); @@ -55,6 +55,7 @@ public function dashboard() 's3s' => $s3s, ]); } + public function settings() { if (auth()->user()->isInstanceAdmin()) { @@ -66,6 +67,7 @@ public function settings() return redirect()->route('dashboard'); } } + public function emails() { if (auth()->user()->isInstanceAdmin()) { @@ -77,6 +79,7 @@ public function emails() return redirect()->route('dashboard'); } } + public function team() { $invitations = []; @@ -87,18 +90,23 @@ public function team() 'invitations' => $invitations, ]); } - public function storages() { + + public function storages() + { $s3 = S3Storage::ownedByCurrentTeam()->get(); return view('team.storages.all', [ 's3' => $s3, ]); } - public function storages_show() { + + public function storages_show() + { $storage = S3Storage::ownedByCurrentTeam()->whereUuid(request()->storage_uuid)->firstOrFail(); return view('team.storages.show', [ 'storage' => $storage, ]); } + public function members() { $invitations = []; @@ -109,6 +117,7 @@ public function members() 'invitations' => $invitations, ]); } + public function acceptInvitation() { try { @@ -135,6 +144,7 @@ public function acceptInvitation() throw $th; } } + public function revokeInvitation() { try { @@ -152,4 +162,4 @@ public function revokeInvitation() throw $th; } } -} \ No newline at end of file +} diff --git a/app/Http/Controllers/DatabaseController.php b/app/Http/Controllers/DatabaseController.php index 6137c8a6b..33da43d83 100644 --- a/app/Http/Controllers/DatabaseController.php +++ b/app/Http/Controllers/DatabaseController.php @@ -2,15 +2,13 @@ namespace App\Http\Controllers; -use App\Models\ApplicationDeploymentQueue; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Validation\ValidatesRequests; -use Illuminate\Http\Request; -use Spatie\Activitylog\Models\Activity; class DatabaseController extends Controller { use AuthorizesRequests, ValidatesRequests; + public function configuration() { $project = session('currentTeam')->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); diff --git a/app/Http/Controllers/MagicController.php b/app/Http/Controllers/MagicController.php index c4f77805a..e461cc70c 100644 --- a/app/Http/Controllers/MagicController.php +++ b/app/Http/Controllers/MagicController.php @@ -2,7 +2,6 @@ namespace App\Http\Controllers; -use App\Http\Livewire\Server\PrivateKey; use App\Models\Environment; use App\Models\Project; use App\Models\Server; @@ -16,24 +15,28 @@ public function servers() 'servers' => Server::isUsable()->get() ]); } + public function destinations() { return response()->json([ 'destinations' => Server::destinationsByServer(request()->query('server_id'))->sortBy('name') ]); } + public function projects() { return response()->json([ 'projects' => Project::ownedByCurrentTeam()->get() ]); } + public function environments() { return response()->json([ 'environments' => Project::ownedByCurrentTeam()->whereUuid(request()->query('project_uuid'))->first()->environments ]); } + public function newProject() { $project = Project::firstOrCreate( @@ -44,6 +47,7 @@ public function newProject() 'project_uuid' => $project->uuid ]); } + public function newEnvironment() { $environment = Environment::firstOrCreate( @@ -54,6 +58,7 @@ public function newEnvironment() 'environment_name' => $environment->name, ]); } + public function newTeam() { $team = Team::create( diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php index e56edf17b..80cdc7b47 100644 --- a/app/Http/Controllers/ProjectController.php +++ b/app/Http/Controllers/ProjectController.php @@ -25,6 +25,7 @@ public function edit() } return view('project.edit', ['project' => $project]); } + public function show() { $projectUuid = request()->route('project_uuid'); @@ -55,6 +56,7 @@ public function new() 'type' => $type ]); } + public function resources() { $project = session('currentTeam')->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); diff --git a/app/Http/Livewire/ActivityMonitor.php b/app/Http/Livewire/ActivityMonitor.php index 1ce763a0f..339ae4df4 100644 --- a/app/Http/Livewire/ActivityMonitor.php +++ b/app/Http/Livewire/ActivityMonitor.php @@ -15,12 +15,6 @@ class ActivityMonitor extends Component protected $activity; protected $listeners = ['newMonitorActivity']; - public function hydrateActivity() - { - $this->activity = Activity::query() - ->find($this->activityId); - } - public function newMonitorActivity($activityId) { $this->activityId = $activityId; @@ -30,6 +24,12 @@ public function newMonitorActivity($activityId) $this->isPollingActive = true; } + public function hydrateActivity() + { + $this->activity = Activity::query() + ->find($this->activityId); + } + public function polling() { $this->hydrateActivity(); @@ -45,6 +45,7 @@ public function polling() $this->emit('activityFinished'); } } + protected function setStatus($status) { $this->activity->properties = $this->activity->properties->merge([ @@ -52,4 +53,4 @@ protected function setStatus($status) ]); $this->activity->save(); } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/CheckLicense.php b/app/Http/Livewire/CheckLicense.php index 7e6f07e26..3afefed34 100644 --- a/app/Http/Livewire/CheckLicense.php +++ b/app/Http/Livewire/CheckLicense.php @@ -19,11 +19,13 @@ class CheckLicense extends Component 'instance_id' => 'Instance Id (Do not change this)', 'settings.is_resale_license_active' => 'Is License Active', ]; + public function mount() { $this->instance_id = config('app.id'); $this->settings = InstanceSettings::get(); } + public function submit() { $this->validate(); diff --git a/app/Http/Livewire/Destination/Form.php b/app/Http/Livewire/Destination/Form.php index 4f400a670..56c7ba5ed 100644 --- a/app/Http/Livewire/Destination/Form.php +++ b/app/Http/Livewire/Destination/Form.php @@ -18,11 +18,13 @@ class Form extends Component 'destination.network' => 'network', 'destination.server.ip' => 'IP Address', ]; + public function submit() { $this->validate(); $this->destination->save(); } + public function delete() { try { diff --git a/app/Http/Livewire/Destination/New/StandaloneDocker.php b/app/Http/Livewire/Destination/New/StandaloneDocker.php index e43b1df6e..da4c453b7 100644 --- a/app/Http/Livewire/Destination/New/StandaloneDocker.php +++ b/app/Http/Livewire/Destination/New/StandaloneDocker.php @@ -5,9 +5,9 @@ use App\Models\Server; use App\Models\StandaloneDocker as ModelsStandaloneDocker; use Illuminate\Database\Eloquent\Collection; +use Illuminate\Support\Str; use Livewire\Component; use Visus\Cuid2\Cuid2; -use Illuminate\Support\Str; class StandaloneDocker extends Component { @@ -28,6 +28,7 @@ class StandaloneDocker extends Component 'network' => 'network', 'server_id' => 'server' ]; + public function mount() { if (request()->query('server_id')) { @@ -44,15 +45,13 @@ public function mount() } $this->name = Str::kebab("{$this->servers->first()->name}-{$this->network}"); } - public function generate_name() { + + public function generate_name() + { $this->server = Server::find($this->server_id); $this->name = Str::kebab("{$this->server->name}-{$this->network}"); } - private function createNetworkAndAttachToProxy() - { - instant_remote_process(['docker network create --attachable ' . $this->network], $this->server, throwError: false); - instant_remote_process(["docker network connect $this->network coolify-proxy"], $this->server, throwError: false); - } + public function submit() { $this->validate(); @@ -77,4 +76,10 @@ public function submit() return general_error_handler(err: $e); } } -} \ No newline at end of file + + private function createNetworkAndAttachToProxy() + { + instant_remote_process(['docker network create --attachable ' . $this->network], $this->server, throwError: false); + instant_remote_process(["docker network connect $this->network coolify-proxy"], $this->server, throwError: false); + } +} diff --git a/app/Http/Livewire/Destination/Show.php b/app/Http/Livewire/Destination/Show.php index df27e31df..d68537ac4 100644 --- a/app/Http/Livewire/Destination/Show.php +++ b/app/Http/Livewire/Destination/Show.php @@ -10,6 +10,7 @@ class Show extends Component { public Server $server; public Collection|array $networks = []; + public function scan() { $alreadyAddedNetworks = $this->server->standaloneDockers; diff --git a/app/Http/Livewire/Dev/S3Test.php b/app/Http/Livewire/Dev/S3Test.php index 7aaf732bc..0d67717fa 100644 --- a/app/Http/Livewire/Dev/S3Test.php +++ b/app/Http/Livewire/Dev/S3Test.php @@ -4,33 +4,39 @@ use App\Models\S3Storage; use Illuminate\Support\Facades\Storage; -use Livewire\WithFileUploads; use Livewire\Component; +use Livewire\WithFileUploads; class S3Test extends Component { use WithFileUploads; + public $s3; public $file; - public function mount() { + + public function mount() + { $this->s3 = S3Storage::first(); } - public function save() { + + public function save() + { try { $this->validate([ 'file' => 'required|max:150', // 1MB Max ]); set_s3_target($this->s3); - $this->file->storeAs('files', $this->file->getClientOriginalName(),'custom-s3'); + $this->file->storeAs('files', $this->file->getClientOriginalName(), 'custom-s3'); $this->emit('success', 'File uploaded successfully.'); } catch (\Throwable $th) { return general_error_handler($th, $this, false); } } + public function get_files() { set_s3_target($this->s3); dd(Storage::disk('custom-s3')->files('files')); } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Notifications/DiscordSettings.php b/app/Http/Livewire/Notifications/DiscordSettings.php index e7dab8036..ac64c9184 100644 --- a/app/Http/Livewire/Notifications/DiscordSettings.php +++ b/app/Http/Livewire/Notifications/DiscordSettings.php @@ -19,6 +19,7 @@ class DiscordSettings extends Component protected $validationAttributes = [ 'model.discord_webhook_url' => 'Discord Webhook', ]; + public function instantSave() { try { @@ -29,6 +30,14 @@ public function instantSave() $this->validate(); } } + + public function submit() + { + $this->resetErrorBag(); + $this->validate(); + $this->saveModel(); + } + public function saveModel() { ray($this->model); @@ -38,15 +47,10 @@ public function saveModel() } $this->emit('success', 'Settings saved.'); } - public function submit() - { - $this->resetErrorBag(); - $this->validate(); - $this->saveModel(); - } + public function sendTestNotification() { $this->model->notify(new Test); $this->emit('success', 'Test notification sent.'); } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Notifications/EmailSettings.php b/app/Http/Livewire/Notifications/EmailSettings.php index 243f147dc..8c7389afd 100644 --- a/app/Http/Livewire/Notifications/EmailSettings.php +++ b/app/Http/Livewire/Notifications/EmailSettings.php @@ -37,6 +37,13 @@ class EmailSettings extends Component 'model.smtp_username' => 'Username', 'model.smtp_password' => 'Password', ]; + + public function mount() + { + $this->decrypt(); + $this->emails = auth()->user()->email; + } + private function decrypt() { if (data_get($this->model, 'smtp_password')) { @@ -46,11 +53,7 @@ private function decrypt() } } } - public function mount() - { - $this->decrypt(); - $this->emails = auth()->user()->email; - } + public function copyFromInstanceSettings() { $settings = InstanceSettings::get(); @@ -78,6 +81,23 @@ public function copyFromInstanceSettings() $this->emit('error', 'Instance SMTP settings are not enabled.'); } } + + public function sendTestNotification() + { + $this->model->notify(new Test($this->emails)); + $this->emit('success', 'Test Email sent successfully.'); + } + + public function instantSave() + { + try { + $this->submit(); + } catch (\Exception $e) { + $this->model->smtp_enabled = false; + $this->validate(); + } + } + public function submit() { $this->resetErrorBag(); @@ -92,6 +112,7 @@ public function submit() $this->model->smtp_recipients = str_replace(' ', '', $this->model->smtp_recipients); $this->saveModel(); } + public function saveModel() { $this->model->save(); @@ -101,18 +122,4 @@ public function saveModel() } $this->emit('success', 'Settings saved.'); } - public function sendTestNotification() - { - $this->model->notify(new Test($this->emails)); - $this->emit('success', 'Test Email sent successfully.'); - } - public function instantSave() - { - try { - $this->submit(); - } catch (\Exception $e) { - $this->model->smtp_enabled = false; - $this->validate(); - } - } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/PrivateKey/Change.php b/app/Http/Livewire/PrivateKey/Change.php index 4f3ad4488..1274910b2 100644 --- a/app/Http/Livewire/PrivateKey/Change.php +++ b/app/Http/Livewire/PrivateKey/Change.php @@ -20,6 +20,7 @@ class Change extends Component 'private_key.description' => 'description', 'private_key.private_key' => 'private key' ]; + public function delete() { try { @@ -33,6 +34,7 @@ public function delete() return general_error_handler(err: $e, that: $this); } } + public function changePrivateKey() { try { diff --git a/app/Http/Livewire/PrivateKey/Create.php b/app/Http/Livewire/PrivateKey/Create.php index bfbf72e18..24e99cf85 100644 --- a/app/Http/Livewire/PrivateKey/Create.php +++ b/app/Http/Livewire/PrivateKey/Create.php @@ -19,6 +19,7 @@ class Create extends Component 'name' => 'name', 'value' => 'private Key', ]; + public function createPrivateKey() { $this->validate(); diff --git a/app/Http/Livewire/Profile/Form.php b/app/Http/Livewire/Profile/Form.php index 9075c4da2..926d638f1 100644 --- a/app/Http/Livewire/Profile/Form.php +++ b/app/Http/Livewire/Profile/Form.php @@ -17,12 +17,14 @@ class Form extends Component protected $validationAttributes = [ 'name' => 'name', ]; + public function mount() { $this->userId = auth()->user()->id; $this->name = auth()->user()->name; $this->email = auth()->user()->email; } + public function submit() { diff --git a/app/Http/Livewire/Project/AddEmpty.php b/app/Http/Livewire/Project/AddEmpty.php index 98136fb86..1024bc66f 100644 --- a/app/Http/Livewire/Project/AddEmpty.php +++ b/app/Http/Livewire/Project/AddEmpty.php @@ -17,6 +17,7 @@ class AddEmpty extends Component 'name' => 'Project Name', 'description' => 'Project Description', ]; + public function submit() { try { diff --git a/app/Http/Livewire/Project/AddEnvironment.php b/app/Http/Livewire/Project/AddEnvironment.php index 3ca6d8de3..ea38df073 100644 --- a/app/Http/Livewire/Project/AddEnvironment.php +++ b/app/Http/Livewire/Project/AddEnvironment.php @@ -17,6 +17,7 @@ class AddEnvironment extends Component protected $validationAttributes = [ 'name' => 'Environment Name', ]; + public function submit() { try { diff --git a/app/Http/Livewire/Project/Application/DeploymentLogs.php b/app/Http/Livewire/Project/Application/DeploymentLogs.php index b39cc47f7..ac3c4a6cf 100644 --- a/app/Http/Livewire/Project/Application/DeploymentLogs.php +++ b/app/Http/Livewire/Project/Application/DeploymentLogs.php @@ -10,10 +10,12 @@ class DeploymentLogs extends Component public ApplicationDeploymentQueue $application_deployment_queue; public $isKeepAliveOn = true; protected $listeners = ['refreshQueue']; + public function refreshQueue() { $this->application_deployment_queue->refresh(); } + public function polling() { $this->emit('deploymentFinished'); diff --git a/app/Http/Livewire/Project/Application/DeploymentNavbar.php b/app/Http/Livewire/Project/Application/DeploymentNavbar.php index 412f15956..1646d46e0 100644 --- a/app/Http/Livewire/Project/Application/DeploymentNavbar.php +++ b/app/Http/Livewire/Project/Application/DeploymentNavbar.php @@ -8,17 +8,16 @@ use App\Models\Server; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Process; -use Livewire\Component; use Illuminate\Support\Str; +use Livewire\Component; class DeploymentNavbar extends Component { - protected $listeners = ['deploymentFinished']; - public ApplicationDeploymentQueue $application_deployment_queue; public Application $application; public Server $server; public bool $is_debug_enabled = false; + protected $listeners = ['deploymentFinished']; public function mount() { @@ -26,10 +25,12 @@ public function mount() $this->server = $this->application->destination->server; $this->is_debug_enabled = $this->application->settings->is_debug_enabled; } + public function deploymentFinished() { $this->application_deployment_queue->refresh(); } + public function show_debug() { $this->application->settings->is_debug_enabled = !$this->application->settings->is_debug_enabled; @@ -37,6 +38,7 @@ public function show_debug() $this->is_debug_enabled = $this->application->settings->is_debug_enabled; $this->emit('refreshQueue'); } + public function cancel() { try { @@ -66,4 +68,4 @@ public function cancel() return general_error_handler(err: $e, that: $this); } } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Project/Application/Deployments.php b/app/Http/Livewire/Project/Application/Deployments.php index 16b40895b..1dd80d710 100644 --- a/app/Http/Livewire/Project/Application/Deployments.php +++ b/app/Http/Livewire/Project/Application/Deployments.php @@ -20,6 +20,7 @@ public function mount() $this->current_url = url()->current(); $this->show_more(); } + private function show_more() { if (count($this->deployments) !== 0) { @@ -30,10 +31,12 @@ private function show_more() return; } } + public function reload_deployments() { $this->load_deployments(); } + public function load_deployments(int|null $take = null) { if ($take) { diff --git a/app/Http/Livewire/Project/Application/General.php b/app/Http/Livewire/Project/Application/General.php index 2d15489fb..53416ae00 100644 --- a/app/Http/Livewire/Project/Application/General.php +++ b/app/Http/Livewire/Project/Application/General.php @@ -4,8 +4,8 @@ use App\Models\Application; use App\Models\InstanceSettings; -use Livewire\Component; use Illuminate\Support\Str; +use Livewire\Component; use Spatie\Url\Url; class General extends Component @@ -65,6 +65,7 @@ class General extends Component 'application.ports_exposes' => 'Ports exposes', 'application.ports_mappings' => 'Ports mappings', ]; + public function instantSave() { // @TODO: find another way - if possible @@ -86,6 +87,7 @@ public function instantSave() $this->emit('success', 'Application settings updated!'); $this->checkWildCardDomain(); } + protected function checkWildCardDomain() { $coolify_instance_settings = InstanceSettings::get(); @@ -93,6 +95,7 @@ protected function checkWildCardDomain() $this->global_wildcard_domain = data_get($coolify_instance_settings, 'wildcard_domain'); $this->wildcard_domain = $this->server_wildcard_domain ?? $this->global_wildcard_domain ?? null; } + public function mount() { $this->is_static = $this->application->settings->is_static; @@ -104,6 +107,7 @@ public function mount() $this->is_force_https_enabled = $this->application->settings->is_force_https_enabled; $this->checkWildCardDomain(); } + public function generateGlobalRandomDomain() { // Set wildcard domain based on Global wildcard domain @@ -115,6 +119,7 @@ public function generateGlobalRandomDomain() $this->application->save(); $this->emit('success', 'Application settings updated!'); } + public function generateServerRandomDomain() { // Set wildcard domain based on Server wildcard domain @@ -126,6 +131,7 @@ public function generateServerRandomDomain() $this->application->save(); $this->emit('success', 'Application settings updated!'); } + public function submit() { try { diff --git a/app/Http/Livewire/Project/Application/Heading.php b/app/Http/Livewire/Project/Application/Heading.php index b3c3cd876..41b84bb15 100644 --- a/app/Http/Livewire/Project/Application/Heading.php +++ b/app/Http/Livewire/Project/Application/Heading.php @@ -28,6 +28,12 @@ public function check_status() )); $this->application->refresh(); } + + public function force_deploy_without_cache() + { + $this->deploy(force_rebuild: true); + } + public function deploy(bool $force_rebuild = false) { $this->setDeploymentUuid(); @@ -43,10 +49,13 @@ public function deploy(bool $force_rebuild = false) 'environment_name' => $this->parameters['environment_name'], ]); } - public function force_deploy_without_cache() + + protected function setDeploymentUuid() { - $this->deploy(force_rebuild: true); + $this->deploymentUuid = new Cuid2(7); + $this->parameters['deployment_uuid'] = $this->deploymentUuid; } + public function stop() { remote_process( @@ -57,9 +66,4 @@ public function stop() $this->application->save(); $this->application->environment->project->team->notify(new StatusChanged($this->application)); } - protected function setDeploymentUuid() - { - $this->deploymentUuid = new Cuid2(7); - $this->parameters['deployment_uuid'] = $this->deploymentUuid; - } } diff --git a/app/Http/Livewire/Project/Application/Preview/Form.php b/app/Http/Livewire/Project/Application/Preview/Form.php index e17312005..f831b487d 100644 --- a/app/Http/Livewire/Project/Application/Preview/Form.php +++ b/app/Http/Livewire/Project/Application/Preview/Form.php @@ -17,6 +17,7 @@ class Form extends Component protected $validationAttributes = [ 'application.preview_url_template' => 'preview url template', ]; + public function resetToDefault() { $this->application->preview_url_template = '{{pr_id}}.{{domain}}'; @@ -24,6 +25,7 @@ public function resetToDefault() $this->application->save(); $this->generate_real_url(); } + public function generate_real_url() { if (data_get($this->application, 'fqdn')) { @@ -32,10 +34,12 @@ public function generate_real_url() $this->preview_url_template = Str::of($this->application->preview_url_template)->replace('{{domain}}', $host); } } + public function mount() { $this->generate_real_url(); } + public function submit() { $this->validate(); diff --git a/app/Http/Livewire/Project/Application/Previews.php b/app/Http/Livewire/Project/Application/Previews.php index a708a7098..f6f493827 100644 --- a/app/Http/Livewire/Project/Application/Previews.php +++ b/app/Http/Livewire/Project/Application/Previews.php @@ -22,6 +22,7 @@ public function mount() $this->pull_requests = collect(); $this->parameters = getRouteParameters(); } + public function loadStatus($pull_request_id) { dispatch(new ContainerStatusJob( @@ -30,11 +31,7 @@ public function loadStatus($pull_request_id) pull_request_id: $pull_request_id )); } - protected function setDeploymentUuid() - { - $this->deployment_uuid = new Cuid2(7); - $this->parameters['deployment_uuid'] = $this->deployment_uuid; - } + public function load_prs() { try { @@ -46,6 +43,7 @@ public function load_prs() return general_error_handler(err: $e, that: $this); } } + public function deploy(int $pull_request_id, string|null $pull_request_html_url = null) { try { @@ -74,6 +72,13 @@ public function deploy(int $pull_request_id, string|null $pull_request_html_url return general_error_handler(err: $e, that: $this); } } + + protected function setDeploymentUuid() + { + $this->deployment_uuid = new Cuid2(7); + $this->parameters['deployment_uuid'] = $this->deployment_uuid; + } + public function stop(int $pull_request_id) { try { @@ -87,6 +92,7 @@ public function stop(int $pull_request_id) return general_error_handler(err: $e, that: $this); } } + public function previewRefresh() { $this->application->previews->each(function ($preview) { diff --git a/app/Http/Livewire/Project/Application/Rollback.php b/app/Http/Livewire/Project/Application/Rollback.php index 2e708ec36..ee827b206 100644 --- a/app/Http/Livewire/Project/Application/Rollback.php +++ b/app/Http/Livewire/Project/Application/Rollback.php @@ -3,8 +3,8 @@ namespace App\Http\Livewire\Project\Application; use App\Models\Application; -use Livewire\Component; use Illuminate\Support\Str; +use Livewire\Component; use Visus\Cuid2\Cuid2; class Rollback extends Component @@ -18,6 +18,7 @@ public function mount() { $this->parameters = getRouteParameters(); } + public function rollbackImage($commit) { $deployment_uuid = new Cuid2(7); @@ -36,6 +37,7 @@ public function rollbackImage($commit) 'environment_name' => $this->parameters['environment_name'], ]); } + public function loadImages() { try { diff --git a/app/Http/Livewire/Project/Application/Source.php b/app/Http/Livewire/Project/Application/Source.php index 83b457ae5..1fec460d9 100644 --- a/app/Http/Livewire/Project/Application/Source.php +++ b/app/Http/Livewire/Project/Application/Source.php @@ -21,16 +21,19 @@ class Source extends Component 'application.git_branch' => 'branch', 'application.git_commit_sha' => 'commit sha', ]; + + public function mount() + { + $this->get_private_keys(); + } + private function get_private_keys() { $this->private_keys = PrivateKey::whereTeamId(session('currentTeam')->id)->get()->reject(function ($key) { return $key->id == $this->application->private_key_id; }); } - public function mount() - { - $this->get_private_keys(); - } + public function setPrivateKey(int $private_key_id) { $this->application->private_key_id = $private_key_id; @@ -38,6 +41,7 @@ public function setPrivateKey(int $private_key_id) $this->application->refresh(); $this->get_private_keys(); } + public function submit() { $this->validate(); diff --git a/app/Http/Livewire/Project/Database/Heading.php b/app/Http/Livewire/Project/Database/Heading.php index f6dd7a12d..300804bad 100644 --- a/app/Http/Livewire/Project/Database/Heading.php +++ b/app/Http/Livewire/Project/Database/Heading.php @@ -2,10 +2,10 @@ namespace App\Http\Livewire\Project\Database; -use Livewire\Component; use App\Actions\Database\StartPostgresql; use App\Jobs\ContainerStatusJob; use App\Notifications\Application\StatusChanged; +use Livewire\Component; class Heading extends Component { @@ -13,13 +13,16 @@ class Heading extends Component public array $parameters; protected $listeners = ['activityFinished']; - public function activityFinished() { + + public function activityFinished() + { $this->database->update([ 'started_at' => now(), ]); $this->emit('refresh'); $this->check_status(); } + public function check_status() { dispatch_sync(new ContainerStatusJob( @@ -28,11 +31,14 @@ public function check_status() )); $this->database->refresh(); } + public function mount() { $this->parameters = getRouteParameters(); } - public function stop() { + + public function stop() + { remote_process( ["docker rm -f {$this->database->uuid}"], $this->database->destination->server @@ -41,7 +47,9 @@ public function stop() { $this->database->save(); $this->database->environment->project->team->notify(new StatusChanged($this->database)); } - public function start() { + + public function start() + { if ($this->database->type() === 'standalone-postgresql') { $activity = resolve(StartPostgresql::class)($this->database->destination->server, $this->database); $this->emit('newMonitorActivity', $activity->id); diff --git a/app/Http/Livewire/Project/Database/Postgresql/General.php b/app/Http/Livewire/Project/Database/Postgresql/General.php index 8b1d6c40a..9a0e0d22f 100644 --- a/app/Http/Livewire/Project/Database/Postgresql/General.php +++ b/app/Http/Livewire/Project/Database/Postgresql/General.php @@ -31,10 +31,14 @@ class General extends Component 'database.init_scripts' => 'Init Scripts', 'database.image' => 'Image', ]; - public function refresh() { + + public function refresh(): void + { $this->database->refresh(); } - public function submit() { + + public function submit() + { try { $this->validate(); $this->database->save(); diff --git a/app/Http/Livewire/Project/DeleteEnvironment.php b/app/Http/Livewire/Project/DeleteEnvironment.php index 9e712d859..da08b5fc6 100644 --- a/app/Http/Livewire/Project/DeleteEnvironment.php +++ b/app/Http/Livewire/Project/DeleteEnvironment.php @@ -14,6 +14,7 @@ public function mount() { $this->parameters = getRouteParameters(); } + public function delete() { $this->validate([ diff --git a/app/Http/Livewire/Project/DeleteProject.php b/app/Http/Livewire/Project/DeleteProject.php index 1a22e6257..bfb1b683c 100644 --- a/app/Http/Livewire/Project/DeleteProject.php +++ b/app/Http/Livewire/Project/DeleteProject.php @@ -14,6 +14,7 @@ public function mount() { $this->parameters = getRouteParameters(); } + public function delete() { $this->validate([ diff --git a/app/Http/Livewire/Project/New/GithubPrivateRepository.php b/app/Http/Livewire/Project/New/GithubPrivateRepository.php index 535227ac9..dcd4b8c81 100644 --- a/app/Http/Livewire/Project/New/GithubPrivateRepository.php +++ b/app/Http/Livewire/Project/New/GithubPrivateRepository.php @@ -5,12 +5,9 @@ use App\Models\Application; use App\Models\GithubApp; use App\Models\Project; -use App\Models\Server; use App\Models\StandaloneDocker; use App\Models\SwarmDocker; -use Illuminate\Support\Collection; use Illuminate\Support\Facades\Http; -use Illuminate\Support\Facades\Log; use Livewire\Component; class GithubPrivateRepository extends Component @@ -30,18 +27,14 @@ class GithubPrivateRepository extends Component public string $selected_branch_name = 'main'; public string $token; - - protected int $page = 1; - public $repositories; public int $total_repositories_count = 0; - public $branches; public int $total_branches_count = 0; - public int $port = 3000; public bool $is_static = false; public string|null $publish_directory = null; + protected int $page = 1; public function mount() { @@ -50,32 +43,7 @@ public function mount() $this->repositories = $this->branches = collect(); $this->github_apps = GithubApp::private(); } - protected function loadRepositoryByPage() - { - $response = Http::withToken($this->token)->get("{$this->github_app->api_url}/installation/repositories?per_page=100&page={$this->page}"); - $json = $response->json(); - if ($response->status() !== 200) { - return $this->emit('error', $json['message']); - } - if ($json['total_count'] === 0) { - return; - } - $this->total_repositories_count = $json['total_count']; - $this->repositories = $this->repositories->concat(collect($json['repositories'])); - } - protected function loadBranchByPage() - { - ray('Loading page ' . $this->page); - $response = Http::withToken($this->token)->get("{$this->github_app->api_url}/repos/{$this->selected_repository_owner}/{$this->selected_repository_repo}/branches?per_page=100&page={$this->page}"); - $json = $response->json(); - if ($response->status() !== 200) { - return $this->emit('error', $json['message']); - } - - $this->total_branches_count = count($json); - $this->branches = $this->branches->concat(collect($json)); - } public function loadRepositories($github_app_id) { $this->repositories = collect(); @@ -93,6 +61,22 @@ public function loadRepositories($github_app_id) $this->selected_repository_id = $this->repositories[0]['id']; $this->current_step = 'repository'; } + + protected function loadRepositoryByPage() + { + $response = Http::withToken($this->token)->get("{$this->github_app->api_url}/installation/repositories?per_page=100&page={$this->page}"); + $json = $response->json(); + if ($response->status() !== 200) { + return $this->emit('error', $json['message']); + } + + if ($json['total_count'] === 0) { + return; + } + $this->total_repositories_count = $json['total_count']; + $this->repositories = $this->repositories->concat(collect($json['repositories'])); + } + public function loadBranches() { $this->selected_repository_owner = $this->repositories->where('id', $this->selected_repository_id)->first()['owner']['login']; @@ -107,6 +91,20 @@ public function loadBranches() } } } + + protected function loadBranchByPage() + { + ray('Loading page ' . $this->page); + $response = Http::withToken($this->token)->get("{$this->github_app->api_url}/repos/{$this->selected_repository_owner}/{$this->selected_repository_repo}/branches?per_page=100&page={$this->page}"); + $json = $response->json(); + if ($response->status() !== 200) { + return $this->emit('error', $json['message']); + } + + $this->total_branches_count = count($json); + $this->branches = $this->branches->concat(collect($json)); + } + public function submit() { try { @@ -136,7 +134,7 @@ public function submit() 'destination_id' => $destination->id, 'destination_type' => $destination_class, 'source_id' => $this->github_app->id, - 'source_type' => $this->github_app->getMorphClass() + 'source_type' => $this->github_app->getMorphClass() ]); $application->settings->is_static = $this->is_static; $application->settings->save(); @@ -150,6 +148,7 @@ public function submit() return general_error_handler(err: $e, that: $this); } } + public function instantSave() { if ($this->is_static) { diff --git a/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php b/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php index cfb528f1e..afc0062a0 100644 --- a/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php +++ b/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php @@ -27,14 +27,7 @@ class GithubPrivateRepositoryDeployKey extends Component public null|string $publish_directory = null; public string $repository_url; - private object $repository_url_parsed; public string $branch; - - private GithubApp|GitlabApp $git_source; - private string $git_host; - private string $git_repository; - private string $git_branch; - protected $rules = [ 'repository_url' => 'required|url', 'branch' => 'required|string', @@ -49,6 +42,12 @@ class GithubPrivateRepositoryDeployKey extends Component 'is_static' => 'Is static', 'publish_directory' => 'Publish directory', ]; + private object $repository_url_parsed; + private GithubApp|GitlabApp $git_source; + private string $git_host; + private string $git_repository; + private string $git_branch; + public function mount() { if (isDev()) { @@ -58,6 +57,7 @@ public function mount() $this->query = request()->query(); $this->private_keys = PrivateKey::where('team_id', session('currentTeam')->id)->where('id', '!=', 0)->get(); } + public function instantSave() { if ($this->is_static) { @@ -68,30 +68,13 @@ public function instantSave() $this->publish_directory = null; } } + public function setPrivateKey($private_key_id) { $this->private_key_id = $private_key_id; $this->current_step = 'repository'; } - private function get_git_source() - { - $this->repository_url_parsed = Url::fromString($this->repository_url); - $this->git_host = $this->repository_url_parsed->getHost(); - $this->git_repository = $this->repository_url_parsed->getSegment(1) . '/' . $this->repository_url_parsed->getSegment(2); - if ($this->branch) { - $this->git_branch = $this->branch; - } else { - $this->git_branch = $this->repository_url_parsed->getSegment(4) ?? 'main'; - } - if ($this->git_host == 'github.com') { - $this->git_source = GithubApp::where('name', 'Public GitHub')->first(); - } elseif ($this->git_host == 'gitlab.com') { - $this->git_source = GitlabApp::where('name', 'Public GitLab')->first(); - } elseif ($this->git_host == 'bitbucket.org') { - // Not supported yet - } - } public function submit() { $this->validate(); @@ -123,7 +106,7 @@ public function submit() 'destination_type' => $destination_class, 'private_key_id' => $this->private_key_id, 'source_id' => $this->git_source->id, - 'source_type' => $this->git_source->getMorphClass() + 'source_type' => $this->git_source->getMorphClass() ]; $application = Application::create($application_init); $application->settings->is_static = $this->is_static; @@ -138,4 +121,24 @@ public function submit() return general_error_handler(err: $e, that: $this); } } + + private function get_git_source() + { + $this->repository_url_parsed = Url::fromString($this->repository_url); + $this->git_host = $this->repository_url_parsed->getHost(); + $this->git_repository = $this->repository_url_parsed->getSegment(1) . '/' . $this->repository_url_parsed->getSegment(2); + if ($this->branch) { + $this->git_branch = $this->branch; + } else { + $this->git_branch = $this->repository_url_parsed->getSegment(4) ?? 'main'; + } + + if ($this->git_host == 'github.com') { + $this->git_source = GithubApp::where('name', 'Public GitHub')->first(); + } elseif ($this->git_host == 'gitlab.com') { + $this->git_source = GitlabApp::where('name', 'Public GitLab')->first(); + } elseif ($this->git_host == 'bitbucket.org') { + // Not supported yet + } + } } diff --git a/app/Http/Livewire/Project/New/PublicGitRepository.php b/app/Http/Livewire/Project/New/PublicGitRepository.php index 181a308bd..a610bf47b 100644 --- a/app/Http/Livewire/Project/New/PublicGitRepository.php +++ b/app/Http/Livewire/Project/New/PublicGitRepository.php @@ -15,13 +15,10 @@ class PublicGitRepository extends Component { public string $repository_url; - private object $repository_url_parsed; - public int $port = 3000; public string $type; public $parameters; public $query; - public bool $branch_found = false; public string $selected_branch = 'main'; public bool $is_static = false; @@ -29,11 +26,6 @@ class PublicGitRepository extends Component public string $git_branch = 'main'; public int $rate_limit_remaining = 0; public $rate_limit_reset = 0; - - private GithubApp|GitlabApp $git_source; - private string $git_host; - private string $git_repository; - protected $rules = [ 'repository_url' => 'required|url', 'port' => 'required|numeric', @@ -46,6 +38,11 @@ class PublicGitRepository extends Component 'is_static' => 'static', 'publish_directory' => 'publish directory', ]; + private object $repository_url_parsed; + private GithubApp|GitlabApp $git_source; + private string $git_host; + private string $git_repository; + public function mount() { if (isDev()) { @@ -67,12 +64,7 @@ public function instantSave() } $this->emit('success', 'Application settings updated!'); } - private function get_branch() - { - ['rate_limit_remaining' => $this->rate_limit_remaining, 'rate_limit_reset' => $this->rate_limit_reset] = git_api(source: $this->git_source, endpoint: "/repos/{$this->git_repository}/branches/{$this->git_branch}"); - $this->rate_limit_reset = Carbon::parse((int)$this->rate_limit_reset)->format('Y-M-d H:i:s'); - $this->branch_found = true; - } + public function load_branch() { $this->branch_found = false; @@ -96,6 +88,7 @@ public function load_branch() } } } + private function get_git_source() { $this->repository_url_parsed = Url::fromString($this->repository_url); @@ -111,6 +104,14 @@ private function get_git_source() // Not supported yet } } + + private function get_branch() + { + ['rate_limit_remaining' => $this->rate_limit_remaining, 'rate_limit_reset' => $this->rate_limit_reset] = git_api(source: $this->git_source, endpoint: "/repos/{$this->git_repository}/branches/{$this->git_branch}"); + $this->rate_limit_reset = Carbon::parse((int)$this->rate_limit_reset)->format('Y-M-d H:i:s'); + $this->branch_found = true; + } + public function submit() { try { diff --git a/app/Http/Livewire/Project/New/Select.php b/app/Http/Livewire/Project/New/Select.php index 3e6137891..e09862649 100644 --- a/app/Http/Livewire/Project/New/Select.php +++ b/app/Http/Livewire/Project/New/Select.php @@ -19,17 +19,20 @@ public function mount() { $this->parameters = getRouteParameters(); } + public function set_type(string $type) { $this->type = $type; $this->current_step = 'servers'; } + public function set_server(Server $server) { $this->server_id = $server->id; $this->destinations = $server->destinations(); $this->current_step = 'destinations'; } + public function set_destination(string $destination_uuid) { $this->destination_uuid = $destination_uuid; @@ -40,6 +43,7 @@ public function set_destination(string $destination_uuid) 'destination' => $this->destination_uuid, ]); } + public function load_servers() { $this->servers = Server::ownedByCurrentTeam()->get(); diff --git a/app/Http/Livewire/Project/Shared/Danger.php b/app/Http/Livewire/Project/Shared/Danger.php index 0bb5f8ef6..3b5283ef2 100644 --- a/app/Http/Livewire/Project/Shared/Danger.php +++ b/app/Http/Livewire/Project/Shared/Danger.php @@ -16,6 +16,7 @@ public function mount() $this->modalId = new Cuid2(7); $this->parameters = getRouteParameters(); } + public function delete() { $destination = $this->resource->destination->getMorphClass()::where('id', $this->resource->destination->id)->first(); diff --git a/app/Http/Livewire/Project/Shared/EnvironmentVariable/Add.php b/app/Http/Livewire/Project/Shared/EnvironmentVariable/Add.php index 1512277e9..783c52183 100644 --- a/app/Http/Livewire/Project/Shared/EnvironmentVariable/Add.php +++ b/app/Http/Livewire/Project/Shared/EnvironmentVariable/Add.php @@ -23,10 +23,12 @@ class Add extends Component 'value' => 'value', 'is_build_time' => 'build', ]; + public function mount() { $this->parameters = getRouteParameters(); } + public function submit() { ray('submitting'); @@ -39,6 +41,7 @@ public function submit() ]); $this->clear(); } + public function clear() { $this->key = ''; diff --git a/app/Http/Livewire/Project/Shared/EnvironmentVariable/All.php b/app/Http/Livewire/Project/Shared/EnvironmentVariable/All.php index ffbaaa59b..70bfd42a1 100644 --- a/app/Http/Livewire/Project/Shared/EnvironmentVariable/All.php +++ b/app/Http/Livewire/Project/Shared/EnvironmentVariable/All.php @@ -11,14 +11,17 @@ class All extends Component public $resource; public string|null $modalId = null; protected $listeners = ['refreshEnvs', 'submit']; + public function mount() { $this->modalId = new Cuid2(7); } + public function refreshEnvs() { $this->resource->refresh(); } + public function submit($data) { try { @@ -27,16 +30,16 @@ public function submit($data) $this->emit('error', 'Environment variable already exists.'); return; } - $environment = new EnvironmentVariable(); + $environment = new EnvironmentVariable(); $environment->key = $data['key']; $environment->value = $data['value']; $environment->is_build_time = $data['is_build_time']; $environment->is_preview = $data['is_preview']; - if($this->resource->type() === 'application') { + if ($this->resource->type() === 'application') { $environment->application_id = $this->resource->id; } - if($this->resource->type() === 'standalone-postgresql') { + if ($this->resource->type() === 'standalone-postgresql') { $environment->standalone_postgresql_id = $this->resource->id; } $environment->save(); diff --git a/app/Http/Livewire/Project/Shared/EnvironmentVariable/Show.php b/app/Http/Livewire/Project/Shared/EnvironmentVariable/Show.php index 1439e983d..f17ac8893 100644 --- a/app/Http/Livewire/Project/Shared/EnvironmentVariable/Show.php +++ b/app/Http/Livewire/Project/Shared/EnvironmentVariable/Show.php @@ -21,17 +21,20 @@ class Show extends Component 'value' => 'value', 'is_build_time' => 'build', ]; + public function mount() { $this->modalId = new Cuid2(7); $this->parameters = getRouteParameters(); } + public function submit() { $this->validate(); $this->env->save(); $this->emit('success', 'Environment variable updated successfully.'); } + public function delete() { $this->env->delete(); diff --git a/app/Http/Livewire/Project/Shared/ResourceLimits.php b/app/Http/Livewire/Project/Shared/ResourceLimits.php index 7ad60aa3b..6b4ae7e3a 100644 --- a/app/Http/Livewire/Project/Shared/ResourceLimits.php +++ b/app/Http/Livewire/Project/Shared/ResourceLimits.php @@ -25,6 +25,7 @@ class ResourceLimits extends Component 'resource.limits_cpuset' => 'cpuset', 'resource.limits_cpu_shares' => 'cpu shares', ]; + public function submit() { try { diff --git a/app/Http/Livewire/Project/Shared/Storages/Add.php b/app/Http/Livewire/Project/Shared/Storages/Add.php index 59a8213e1..afd7b408b 100644 --- a/app/Http/Livewire/Project/Shared/Storages/Add.php +++ b/app/Http/Livewire/Project/Shared/Storages/Add.php @@ -22,10 +22,12 @@ class Add extends Component 'mount_path' => 'mount', 'host_path' => 'host', ]; + public function mount() { $this->parameters = getRouteParameters(); } + public function submit() { $this->validate(); @@ -35,6 +37,7 @@ public function submit() 'host_path' => $this->host_path, ]); } + public function clear() { $this->name = ''; diff --git a/app/Http/Livewire/Project/Shared/Storages/All.php b/app/Http/Livewire/Project/Shared/Storages/All.php index f03cd4d04..ee016143b 100644 --- a/app/Http/Livewire/Project/Shared/Storages/All.php +++ b/app/Http/Livewire/Project/Shared/Storages/All.php @@ -9,10 +9,12 @@ class All extends Component { public $resource; protected $listeners = ['refreshStorages', 'submit']; + public function refreshStorages() { $this->resource->refresh(); } + public function submit($data) { try { diff --git a/app/Http/Livewire/Project/Shared/Storages/Show.php b/app/Http/Livewire/Project/Shared/Storages/Show.php index 6244537f7..7cbf322f7 100644 --- a/app/Http/Livewire/Project/Shared/Storages/Show.php +++ b/app/Http/Livewire/Project/Shared/Storages/Show.php @@ -19,16 +19,19 @@ class Show extends Component 'mount_path' => 'mount', 'host_path' => 'host', ]; + public function mount() { $this->modalId = new Cuid2(7); } + public function submit() { $this->validate(); $this->storage->save(); $this->emit('success', 'Storage updated successfully'); } + public function delete() { $this->storage->delete(); diff --git a/app/Http/Livewire/RunCommand.php b/app/Http/Livewire/RunCommand.php index 50462c52c..747ce9568 100755 --- a/app/Http/Livewire/RunCommand.php +++ b/app/Http/Livewire/RunCommand.php @@ -2,7 +2,6 @@ namespace App\Http\Livewire; -use App\Enums\ActivityTypes; use App\Models\Server; use Livewire\Component; @@ -20,6 +19,7 @@ class RunCommand extends Component 'server' => 'server', 'command' => 'command', ]; + public function mount($servers) { $this->servers = $servers; diff --git a/app/Http/Livewire/Server/Form.php b/app/Http/Livewire/Server/Form.php index ae7717967..d901dd2e6 100644 --- a/app/Http/Livewire/Server/Form.php +++ b/app/Http/Livewire/Server/Form.php @@ -5,7 +5,6 @@ use App\Actions\Server\InstallDocker; use App\Models\Server; use Livewire\Component; -use Visus\Cuid2\Cuid2; class Form extends Component { @@ -34,16 +33,19 @@ class Form extends Component 'server.settings.is_reachable' => 'is reachable', 'server.settings.is_part_of_swarm' => 'is part of swarm' ]; + public function mount() { $this->wildcard_domain = $this->server->settings->wildcard_domain; $this->cleanup_after_percentage = $this->server->settings->cleanup_after_percentage; } + public function installDocker() { $activity = resolve(InstallDocker::class)($this->server, session('currentTeam')); $this->emit('newMonitorActivity', $activity->id); } + public function validateServer() { try { @@ -59,6 +61,7 @@ public function validateServer() return general_error_handler(customErrorMessage: "Server is not reachable. Reason: {$e->getMessage()}", that: $this); } } + public function delete() { if (!$this->server->isEmpty()) { @@ -68,6 +71,7 @@ public function delete() $this->server->delete(); redirect()->route('server.all'); } + public function submit() { $this->validate(); @@ -88,4 +92,4 @@ public function submit() $this->server->save(); $this->emit('success', 'Server updated successfully.'); } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Server/New/ByIp.php b/app/Http/Livewire/Server/New/ByIp.php index 424f31e1b..923bae039 100644 --- a/app/Http/Livewire/Server/New/ByIp.php +++ b/app/Http/Livewire/Server/New/ByIp.php @@ -2,7 +2,6 @@ namespace App\Http\Livewire\Server\New; -use App\Models\PrivateKey; use App\Models\Server; use Livewire\Component; @@ -35,19 +34,23 @@ class ByIp extends Component 'user' => 'user', 'port' => 'port', ]; + public function mount() { $this->name = generate_random_name(); $this->private_key_id = $this->private_keys->first()->id; } + public function setPrivateKey(string $private_key_id) { $this->private_key_id = $private_key_id; } + public function instantSave() { $this->emit('success', 'Application settings updated!'); } + public function submit() { $this->validate(); diff --git a/app/Http/Livewire/Server/PrivateKey.php b/app/Http/Livewire/Server/PrivateKey.php index 54035efba..4f9a1e022 100644 --- a/app/Http/Livewire/Server/PrivateKey.php +++ b/app/Http/Livewire/Server/PrivateKey.php @@ -3,7 +3,6 @@ namespace App\Http\Livewire\Server; use App\Models\Server; -use Illuminate\Support\Facades\Storage; use Livewire\Component; use Masmerise\Toaster\Toaster; @@ -13,6 +12,16 @@ class PrivateKey extends Component public $privateKeys; public $parameters; + public function setPrivateKey($private_key_id) + { + $this->server->update([ + 'private_key_id' => $private_key_id + ]); + refreshPrivateKey($this->server->privateKey); + $this->server->refresh(); + $this->checkConnection(); + } + public function checkConnection() { try { @@ -27,15 +36,7 @@ public function checkConnection() return general_error_handler(customErrorMessage: "Server is not reachable. Reason: {$e->getMessage()}", that: $this); } } - public function setPrivateKey($private_key_id) - { - $this->server->update([ - 'private_key_id' => $private_key_id - ]); - refreshPrivateKey($this->server->privateKey); - $this->server->refresh(); - $this->checkConnection(); - } + public function mount() { $this->parameters = getRouteParameters(); diff --git a/app/Http/Livewire/Server/Proxy.php b/app/Http/Livewire/Server/Proxy.php index 4e8680419..1f51d1b1c 100644 --- a/app/Http/Livewire/Server/Proxy.php +++ b/app/Http/Livewire/Server/Proxy.php @@ -5,7 +5,6 @@ use App\Actions\Proxy\CheckConfigurationSync; use App\Actions\Proxy\SaveConfigurationSync; use App\Enums\ProxyTypes; -use Illuminate\Support\Str; use App\Models\Server; use Livewire\Component; @@ -17,21 +16,25 @@ class Proxy extends Component public $proxy_settings = null; public string|null $redirect_url = null; - protected $listeners = ['proxyStatusUpdated', 'saveConfiguration'=>'submit']; + protected $listeners = ['proxyStatusUpdated', 'saveConfiguration' => 'submit']; + public function mount() { $this->redirect_url = $this->server->proxy->redirect_url; } + public function proxyStatusUpdated() { $this->server->refresh(); } + public function change_proxy() { $this->server->proxy = null; $this->server->save(); $this->emit('proxyStatusUpdated'); } + public function select_proxy(string $proxy_type) { $this->server->proxy->type = $proxy_type; @@ -39,6 +42,7 @@ public function select_proxy(string $proxy_type) $this->server->save(); $this->emit('proxyStatusUpdated'); } + public function submit() { try { @@ -53,6 +57,7 @@ public function submit() return general_error_handler(err: $e); } } + public function reset_proxy_configuration() { try { @@ -61,6 +66,7 @@ public function reset_proxy_configuration() return general_error_handler(err: $e); } } + public function load_proxy_configuration() { try { @@ -69,4 +75,4 @@ public function load_proxy_configuration() return general_error_handler(err: $e); } } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Server/Proxy/Deploy.php b/app/Http/Livewire/Server/Proxy/Deploy.php index 6ca4bca4b..9ec3898f1 100644 --- a/app/Http/Livewire/Server/Proxy/Deploy.php +++ b/app/Http/Livewire/Server/Proxy/Deploy.php @@ -5,12 +5,12 @@ use App\Actions\Proxy\StartProxy; use App\Models\Server; use Livewire\Component; -use Str; class Deploy extends Component { public Server $server; public $proxy_settings = null; + public function start_proxy() { if ( @@ -22,6 +22,7 @@ public function start_proxy() $activity = resolve(StartProxy::class)($this->server); $this->emit('newMonitorActivity', $activity->id); } + public function stop() { instant_remote_process([ @@ -31,4 +32,4 @@ public function stop() $this->server->save(); $this->emit('proxyStatusUpdated'); } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Server/Proxy/Status.php b/app/Http/Livewire/Server/Proxy/Status.php index 8791e9cc4..a4a29b7c2 100644 --- a/app/Http/Livewire/Server/Proxy/Status.php +++ b/app/Http/Livewire/Server/Proxy/Status.php @@ -9,6 +9,7 @@ class Status extends Component { public Server $server; + public function get_status() { dispatch_sync(new ProxyContainerStatusJob( @@ -17,4 +18,4 @@ public function get_status() $this->server->refresh(); $this->emit('proxyStatusUpdated'); } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Settings/Configuration.php b/app/Http/Livewire/Settings/Configuration.php index 98371d136..e4b7eb3f6 100644 --- a/app/Http/Livewire/Settings/Configuration.php +++ b/app/Http/Livewire/Settings/Configuration.php @@ -31,6 +31,7 @@ class Configuration extends Component 'settings.public_port_min' => 'Public port min', 'settings.public_port_max' => 'Public port max', ]; + public function mount() { $this->do_not_track = $this->settings->do_not_track; @@ -38,6 +39,7 @@ public function mount() $this->is_registration_enabled = $this->settings->is_registration_enabled; $this->next_channel = $this->settings->next_channel; } + public function instantSave() { $this->settings->do_not_track = $this->do_not_track; @@ -47,6 +49,21 @@ public function instantSave() $this->settings->save(); $this->emit('success', 'Settings updated!'); } + + public function submit() + { + $this->resetErrorBag(); + if ($this->settings->public_port_min > $this->settings->public_port_max) { + $this->addError('settings.public_port_min', 'The minimum port must be lower than the maximum port.'); + return; + } + $this->validate(); + $this->settings->save(); + $this->server = Server::findOrFail(0); + $this->setup_instance_fqdn(); + $this->emit('success', 'Instance settings updated successfully!'); + } + private function setup_instance_fqdn() { $file = "$this->dynamic_config_path/coolify.yaml"; @@ -60,35 +77,35 @@ private function setup_instance_fqdn() $schema = $url->getScheme(); $traefik_dynamic_conf = [ 'http' => - [ - 'routers' => [ - 'coolify-http' => - [ - 'entryPoints' => [ - 0 => 'http', - ], - 'service' => 'coolify', - 'rule' => "Host(`{$host}`)", - ], - ], - 'services' => - [ - 'coolify' => - [ - 'loadBalancer' => + 'routers' => [ - 'servers' => - [ - 0 => + 'coolify-http' => [ - 'url' => 'http://coolify:80', + 'entryPoints' => [ + 0 => 'http', + ], + 'service' => 'coolify', + 'rule' => "Host(`{$host}`)", + ], + ], + 'services' => + [ + 'coolify' => + [ + 'loadBalancer' => + [ + 'servers' => + [ + 0 => + [ + 'url' => 'http://coolify:80', + ], + ], + ], ], - ], ], - ], ], - ], ]; if ($schema === 'https') { @@ -110,6 +127,7 @@ private function setup_instance_fqdn() dispatch(new ProxyStartJob($this->server)); } } + private function save_configuration_to_disk(array $traefik_dynamic_conf, string $file) { $yaml = Yaml::dump($traefik_dynamic_conf, 12, 2); @@ -128,17 +146,4 @@ private function save_configuration_to_disk(array $traefik_dynamic_conf, string ray($yaml); } } - public function submit() - { - $this->resetErrorBag(); - if ($this->settings->public_port_min > $this->settings->public_port_max) { - $this->addError('settings.public_port_min', 'The minimum port must be lower than the maximum port.'); - return; - } - $this->validate(); - $this->settings->save(); - $this->server = Server::findOrFail(0); - $this->setup_instance_fqdn(); - $this->emit('success', 'Instance settings updated successfully!'); - } } diff --git a/app/Http/Livewire/Settings/Email.php b/app/Http/Livewire/Settings/Email.php index cd096e194..a0ac3c904 100644 --- a/app/Http/Livewire/Settings/Email.php +++ b/app/Http/Livewire/Settings/Email.php @@ -4,7 +4,6 @@ use App\Models\InstanceSettings; use App\Notifications\TransactionalEmails\Test; -use Illuminate\Support\Facades\Notification; use Livewire\Component; class Email extends Component @@ -32,11 +31,23 @@ class Email extends Component 'settings.smtp_username' => 'Username', 'settings.smtp_password' => 'Password', ]; + public function mount() { $this->decrypt(); $this->emails = auth()->user()->email; } + + private function decrypt() + { + if (data_get($this->settings, 'smtp_password')) { + try { + $this->settings->smtp_password = decrypt($this->settings->smtp_password); + } catch (\Exception $e) { + } + } + } + public function instantSave() { try { @@ -47,20 +58,7 @@ public function instantSave() $this->validate(); } } - public function sendTestNotification() - { - $this->settings->notify(new Test($this->emails)); - $this->emit('success', 'Test email sent.'); - } - private function decrypt() - { - if (data_get($this->settings, 'smtp_password')) { - try { - $this->settings->smtp_password = decrypt($this->settings->smtp_password); - } catch (\Exception $e) { - } - } - } + public function submit() { $this->resetErrorBag(); @@ -75,4 +73,10 @@ public function submit() $this->emit('success', 'Transaction email settings updated successfully.'); $this->decrypt(); } -} \ No newline at end of file + + public function sendTestNotification() + { + $this->settings->notify(new Test($this->emails)); + $this->emit('success', 'Test email sent.'); + } +} diff --git a/app/Http/Livewire/Source/Github/Change.php b/app/Http/Livewire/Source/Github/Change.php index 7908b179c..b85575cd5 100644 --- a/app/Http/Livewire/Source/Github/Change.php +++ b/app/Http/Livewire/Source/Github/Change.php @@ -34,12 +34,14 @@ class Change extends Component 'github_app.webhook_secret' => 'nullable', 'github_app.is_system_wide' => 'required|bool', ]; + public function mount() { $this->webhook_endpoint = $this->ipv4; $this->parameters = getRouteParameters(); $this->is_system_wide = $this->github_app->is_system_wide; } + public function submit() { try { @@ -49,6 +51,7 @@ public function submit() return general_error_handler(err: $e, that: $this); } } + public function instantSave() { } diff --git a/app/Http/Livewire/Source/Github/Create.php b/app/Http/Livewire/Source/Github/Create.php index b95bde919..29ff37dfc 100644 --- a/app/Http/Livewire/Source/Github/Create.php +++ b/app/Http/Livewire/Source/Github/Create.php @@ -19,6 +19,7 @@ public function mount() { $this->name = generate_random_name(); } + public function createGitHubApp() { try { diff --git a/app/Http/Livewire/SwitchTeam.php b/app/Http/Livewire/SwitchTeam.php index 109167dfe..087a7ad84 100644 --- a/app/Http/Livewire/SwitchTeam.php +++ b/app/Http/Livewire/SwitchTeam.php @@ -8,10 +8,12 @@ class SwitchTeam extends Component { public string $selectedTeamId = 'default'; + public function updatedSelectedTeamId() { $this->switch_to($this->selectedTeamId); } + public function switch_to($team_id) { if (!auth()->user()->teams->contains($team_id)) { diff --git a/app/Http/Livewire/Team/Create.php b/app/Http/Livewire/Team/Create.php index 5aa07bc94..6c1c71580 100644 --- a/app/Http/Livewire/Team/Create.php +++ b/app/Http/Livewire/Team/Create.php @@ -18,6 +18,7 @@ class Create extends Component 'name' => 'name', 'description' => 'description', ]; + public function submit() { $this->validate(); diff --git a/app/Http/Livewire/Team/Form.php b/app/Http/Livewire/Team/Form.php index f60f72523..56bd21db6 100644 --- a/app/Http/Livewire/Team/Form.php +++ b/app/Http/Livewire/Team/Form.php @@ -4,7 +4,6 @@ use App\Models\Team; use Livewire\Component; -use Masmerise\Toaster\Toaster; class Form extends Component { @@ -17,10 +16,12 @@ class Form extends Component 'team.name' => 'name', 'team.description' => 'description', ]; + public function mount() { $this->team = session('currentTeam'); } + public function submit() { $this->validate(); diff --git a/app/Http/Livewire/Team/Invitations.php b/app/Http/Livewire/Team/Invitations.php index e61aca0e7..ba0b654aa 100644 --- a/app/Http/Livewire/Team/Invitations.php +++ b/app/Http/Livewire/Team/Invitations.php @@ -9,13 +9,15 @@ class Invitations extends Component { public $invitations; protected $listeners = ['refreshInvitations']; - public function refreshInvitations() - { - $this->invitations = TeamInvitation::whereTeamId(auth()->user()->currentTeam()->id)->get(); - } + public function deleteInvitation(int $invitation_id) { TeamInvitation::find($invitation_id)->delete(); $this->refreshInvitations(); } + + public function refreshInvitations() + { + $this->invitations = TeamInvitation::whereTeamId(auth()->user()->currentTeam()->id)->get(); + } } diff --git a/app/Http/Livewire/Team/InviteLink.php b/app/Http/Livewire/Team/InviteLink.php index b197334cb..66a8add4e 100644 --- a/app/Http/Livewire/Team/InviteLink.php +++ b/app/Http/Livewire/Team/InviteLink.php @@ -12,14 +12,17 @@ class InviteLink extends Component { public string $email; public string $role = 'member'; + public function mount() { $this->email = isDev() ? 'test3@example.com' : ''; } + public function viaEmail() { $this->generate_invite_link(isEmail: true); } + private function generate_invite_link(bool $isEmail = false) { try { @@ -72,8 +75,9 @@ private function generate_invite_link(bool $isEmail = false) return general_error_handler(err: $e, that: $this, customErrorMessage: $error_message); } } + public function viaLink() { $this->generate_invite_link(); } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Team/Member.php b/app/Http/Livewire/Team/Member.php index 5f037e444..c356de75d 100644 --- a/app/Http/Livewire/Team/Member.php +++ b/app/Http/Livewire/Team/Member.php @@ -8,16 +8,19 @@ class Member extends Component { public User $member; + public function makeAdmin() { $this->member->teams()->updateExistingPivot(session('currentTeam')->id, ['role' => 'admin']); $this->emit('reloadWindow'); } + public function makeReadonly() { $this->member->teams()->updateExistingPivot(session('currentTeam')->id, ['role' => 'member']); $this->emit('reloadWindow'); } + public function remove() { $this->member->teams()->detach(session('currentTeam')); diff --git a/app/Http/Livewire/Team/Storage/Create.php b/app/Http/Livewire/Team/Storage/Create.php index 997b95015..38aee59b5 100644 --- a/app/Http/Livewire/Team/Storage/Create.php +++ b/app/Http/Livewire/Team/Storage/Create.php @@ -2,8 +2,8 @@ namespace App\Http\Livewire\Team\Storage; -use Livewire\Component; use App\Models\S3Storage; +use Livewire\Component; class Create extends Component { @@ -33,7 +33,9 @@ class Create extends Component 'bucket' => 'Bucket', 'endpoint' => 'Endpoint', ]; - public function mount() { + + public function mount() + { if (isDev()) { $this->name = 'Local MinIO'; $this->description = 'Local MinIO'; @@ -43,15 +45,9 @@ public function mount() { $this->endpoint = 'http://coolify-minio:9000'; } } - private function test_s3_connection() { - try { - $this->storage->testConnection(); - return $this->emit('success', 'Connection is working. Tested with "ListObjectsV2" action.'); - } catch(\Throwable $th) { - return general_error_handler($th, $this); - } - } - public function submit() { + + public function submit() + { try { $this->validate(); $this->storage = new S3Storage(); @@ -71,9 +67,19 @@ public function submit() { $this->emit('success', 'Connection is working. Tested with "ListObjectsV2" action.'); $this->storage->save(); return redirect()->route('team.storages.show', $this->storage->uuid); - } catch(\Throwable $th) { + } catch (\Throwable $th) { return general_error_handler($th, $this); } } -} \ No newline at end of file + + private function test_s3_connection() + { + try { + $this->storage->testConnection(); + return $this->emit('success', 'Connection is working. Tested with "ListObjectsV2" action.'); + } catch (\Throwable $th) { + return general_error_handler($th, $this); + } + } +} diff --git a/app/Http/Livewire/Team/Storage/Form.php b/app/Http/Livewire/Team/Storage/Form.php index bb106e378..3bdbbc508 100644 --- a/app/Http/Livewire/Team/Storage/Form.php +++ b/app/Http/Livewire/Team/Storage/Form.php @@ -2,8 +2,8 @@ namespace App\Http\Livewire\Team\Storage; -use Livewire\Component; use App\Models\S3Storage; +use Livewire\Component; class Form extends Component { @@ -26,22 +26,27 @@ class Form extends Component 'storage.bucket' => 'Bucket', 'storage.endpoint' => 'Endpoint', ]; - public function test_s3_connection() { + + public function test_s3_connection() + { try { $this->storage->testConnection(); return $this->emit('success', 'Connection is working. Tested with "ListObjectsV2" action.'); - } catch(\Throwable $th) { + } catch (\Throwable $th) { return general_error_handler($th, $this); } } - public function delete() { + + public function delete() + { try { $this->storage->delete(); return redirect()->route('team.storages.all'); - } catch(\Throwable $th) { + } catch (\Throwable $th) { return general_error_handler($th, $this); } } + public function submit() { $this->validate(); @@ -54,4 +59,4 @@ public function submit() return general_error_handler($th, $this); } } -} \ No newline at end of file +} diff --git a/app/Http/Livewire/Upgrade.php b/app/Http/Livewire/Upgrade.php index 8bd647f1d..e79c73fb7 100644 --- a/app/Http/Livewire/Upgrade.php +++ b/app/Http/Livewire/Upgrade.php @@ -4,8 +4,8 @@ use App\Actions\Server\UpdateCoolify; use App\Models\InstanceSettings; -use Masmerise\Toaster\Toaster; use Livewire\Component; +use Masmerise\Toaster\Toaster; class Upgrade extends Component { @@ -27,6 +27,7 @@ public function checkUpdate() $this->latestVersion = 'next'; } } + public function upgrade() { try { @@ -40,4 +41,4 @@ public function upgrade() return general_error_handler(err: $e, that: $this); } } -} \ No newline at end of file +} diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php index afc78c4e5..dae8398b7 100644 --- a/app/Http/Middleware/RedirectIfAuthenticated.php +++ b/app/Http/Middleware/RedirectIfAuthenticated.php @@ -13,7 +13,7 @@ class RedirectIfAuthenticated /** * Handle an incoming request. * - * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next + * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next */ public function handle(Request $request, Closure $next, string ...$guards): Response { diff --git a/app/Http/Middleware/TrustProxies.php b/app/Http/Middleware/TrustProxies.php index c80ad531b..559dd2fc3 100644 --- a/app/Http/Middleware/TrustProxies.php +++ b/app/Http/Middleware/TrustProxies.php @@ -20,7 +20,7 @@ class TrustProxies extends Middleware * @var int */ protected $headers = - Request::HEADER_X_FORWARDED_FOR | + Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO | diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 945de85cb..2151219af 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -12,8 +12,8 @@ use App\Models\Server; use App\Models\StandaloneDocker; use App\Models\SwarmDocker; -use App\Notifications\Application\DeploymentSuccess; use App\Notifications\Application\DeploymentFailed; +use App\Notifications\Application\DeploymentSuccess; use App\Traits\ExecuteRemoteCommand; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; @@ -22,8 +22,8 @@ use Illuminate\Queue\SerializesModels; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Storage; -use Spatie\Url\Url; use Illuminate\Support\Str; +use Spatie\Url\Url; use Symfony\Component\Yaml\Yaml; use Throwable; use Visus\Cuid2\Cuid2; @@ -61,6 +61,7 @@ class ApplicationDeploymentJob implements ShouldQueue private $log_model; private Collection $saved_outputs; + public function __construct(int $application_deployment_queue_id) { ray()->clearScreen(); @@ -137,62 +138,7 @@ public function handle(): void // ray()->measure(); } } - public function failed(Throwable $exception): void - { - $this->execute_remote_command( - ["echo 'Oops something is not okay, are you okay? 😢'"], - ["echo '{$exception->getMessage()}'"] - ); - $this->next(ApplicationDeploymentStatus::FAILED->value); - } - private function execute_in_builder(string $command) - { - return "docker exec {$this->deployment_uuid} bash -c '{$command}'"; - // return "docker exec {$this->deployment_uuid} bash -c '{$command} |& tee -a /proc/1/fd/1; [ \$PIPESTATUS -eq 0 ] || exit \$PIPESTATUS'"; - } - private function deploy() - { - $this->execute_remote_command( - [ - "echo 'Starting deployment of {$this->application->git_repository}:{$this->application->git_branch}.'" - ], - ); - $this->prepare_builder_image(); - $this->clone_repository(); - - $tag = Str::of("{$this->commit}-{$this->application->id}-{$this->pull_request_id}"); - if (strlen($tag) > 128) { - $tag = $tag->substr(0, 128); - }; - - $this->build_image_name = "{$this->application->git_repository}:{$tag}-build"; - $this->production_image_name = "{$this->application->uuid}:{$tag}"; - ray('Build Image Name: ' . $this->build_image_name . ' & Production Image Name: ' . $this->production_image_name)->green(); - - if (!$this->force_rebuild) { - $this->execute_remote_command([ - "docker images -q {$this->production_image_name} 2>/dev/null", "hidden" => true, "save" => "local_image_found" - ]); - if (Str::of($this->saved_outputs->get('local_image_found'))->isNotEmpty()) { - $this->execute_remote_command([ - "echo 'Docker Image found locally with the same Git Commit SHA {$this->application->uuid}:{$this->commit}. Build step skipped...'" - ]); - $this->generate_compose_file(); - $this->stop_running_container(); - $this->start_by_compose_file(); - return; - } - } - $this->cleanup_git(); - $this->generate_buildpack(); - $this->generate_compose_file(); - $this->generate_build_env_variables(); - $this->add_build_env_variables_to_dockerfile(); - $this->build_image(); - $this->stop_running_container(); - $this->start_by_compose_file(); - } private function deploy_pull_request() { $this->build_image_name = "{$this->application->uuid}:pr-{$this->pull_request_id}-build"; @@ -214,117 +160,154 @@ private function deploy_pull_request() $this->start_by_compose_file(); } - private function next(string $status) - { - // If the deployment is cancelled by the user, don't update the status - if ($this->application_deployment_queue->status !== ApplicationDeploymentStatus::CANCELLED_BY_USER->value) { - $this->application_deployment_queue->update([ - 'status' => $status, - ]); - } - queue_next_deployment($this->application); - if ($status === ApplicationDeploymentStatus::FINISHED->value) { - $this->application->environment->project->team->notify(new DeploymentSuccess($this->application, $this->deployment_uuid, $this->preview)); - } - if ($status === ApplicationDeploymentStatus::FAILED->value) { - $this->application->environment->project->team->notify(new DeploymentFailed($this->application, $this->deployment_uuid, $this->preview)); - } - } - private function start_by_compose_file() + private function prepare_builder_image() { $this->execute_remote_command( - ["echo -n 'Starting new application... '"], - [$this->execute_in_builder("docker compose --project-directory {$this->workdir} up -d >/dev/null"), "hidden" => true], - ["echo 'Done. 🎉'"], + [ + "echo -n 'Pulling latest version of the builder image (ghcr.io/coollabsio/coolify-builder).'", + ], + [ + "docker run --pull=always -d --name {$this->deployment_uuid} --rm -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/coollabsio/coolify-builder", + "hidden" => true, + ], + [ + "command" => $this->execute_in_builder("mkdir -p {$this->workdir}") + ], ); } - private function stop_running_container() + + private function execute_in_builder(string $command) + { + return "docker exec {$this->deployment_uuid} bash -c '{$command}'"; + // return "docker exec {$this->deployment_uuid} bash -c '{$command} |& tee -a /proc/1/fd/1; [ \$PIPESTATUS -eq 0 ] || exit \$PIPESTATUS'"; + } + + private function clone_repository() { $this->execute_remote_command( - ["echo -n 'Removing old running application.'"], - [$this->execute_in_builder("docker rm -f $this->container_name >/dev/null 2>&1"), "hidden" => true], + [ + "echo -n 'Importing {$this->application->git_repository}:{$this->application->git_branch} to {$this->workdir}. '" + ], + [ + $this->importing_git_repository() + ], + [ + $this->execute_in_builder("cd {$this->workdir} && git rev-parse HEAD"), + "hidden" => true, + "save" => "git_commit_sha" + ], + ); + $this->commit = $this->saved_outputs->get('git_commit_sha'); + } + + private function importing_git_repository() + { + $commands = collect([]); + $git_clone_command = "git clone -q -b {$this->application->git_branch}"; + if ($this->pull_request_id !== 0) { + $pr_branch_name = "pr-{$this->pull_request_id}-coolify"; + } + + if ($this->application->deploymentType() === 'source') { + $source_html_url = data_get($this->application, 'source.html_url'); + $url = parse_url(filter_var($source_html_url, FILTER_SANITIZE_URL)); + $source_html_url_host = $url['host']; + $source_html_url_scheme = $url['scheme']; + + if ($this->source->getMorphClass() == 'App\Models\GithubApp') { + if ($this->source->is_public) { + $git_clone_command = "{$git_clone_command} {$this->source->html_url}/{$this->application->git_repository} {$this->workdir}"; + $git_clone_command = $this->set_git_import_settings($git_clone_command); + + $commands->push($this->execute_in_builder($git_clone_command)); + } else { + $github_access_token = generate_github_installation_token($this->source); + $commands->push($this->execute_in_builder("git clone -q -b {$this->application->git_branch} $source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$this->application->git_repository}.git {$this->workdir}")); + } + if ($this->pull_request_id !== 0) { + $commands->push($this->execute_in_builder("cd {$this->workdir} && git fetch origin pull/{$this->pull_request_id}/head:$pr_branch_name && git checkout $pr_branch_name")); + } + return $commands->implode(' && '); + } + } + if ($this->application->deploymentType() === 'deploy_key') { + $private_key = base64_encode($this->application->private_key->private_key); + $git_clone_command = "GIT_SSH_COMMAND=\"ssh -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" {$git_clone_command} {$this->application->git_full_url} {$this->workdir}"; + $git_clone_command = $this->set_git_import_settings($git_clone_command); + $commands = collect([ + $this->execute_in_builder("mkdir -p /root/.ssh"), + $this->execute_in_builder("echo '{$private_key}' | base64 -d > /root/.ssh/id_rsa"), + $this->execute_in_builder("chmod 600 /root/.ssh/id_rsa"), + $this->execute_in_builder($git_clone_command) + ]); + return $commands->implode(' && '); + } + } + + private function set_git_import_settings($git_clone_command) + { + if ($this->application->git_commit_sha !== 'HEAD') { + $git_clone_command = "{$git_clone_command} && cd {$this->workdir} && git -c advice.detachedHead=false checkout {$this->application->git_commit_sha} >/dev/null 2>&1"; + } + if ($this->application->settings->is_git_submodules_enabled) { + $git_clone_command = "{$git_clone_command} && cd {$this->workdir} && git submodule update --init --recursive"; + } + if ($this->application->settings->is_git_lfs_enabled) { + $git_clone_command = "{$git_clone_command} && cd {$this->workdir} && git lfs pull"; + } + return $git_clone_command; + } + + private function cleanup_git() + { + $this->execute_remote_command( + [$this->execute_in_builder("rm -fr {$this->workdir}/.git")], ); } - private function build_image() + + private function generate_buildpack() { - $this->execute_remote_command([ - "echo -n 'Building docker image.'", - ]); - - if ($this->application->settings->is_static) { - $this->execute_remote_command([ - $this->execute_in_builder("docker build -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t $this->build_image_name {$this->workdir}"), "hidden" => true - ]); - - $dockerfile = base64_encode("FROM {$this->application->static_image} -WORKDIR /usr/share/nginx/html/ -LABEL coolify.deploymentId={$this->deployment_uuid} -COPY --from=$this->build_image_name /app/{$this->application->publish_directory} . -COPY ./nginx.conf /etc/nginx/conf.d/default.conf"); - - $nginx_config = base64_encode("server { - listen 80; - listen [::]:80; - server_name localhost; - - location / { - root /usr/share/nginx/html; - index index.html; - try_files \$uri \$uri.html \$uri/index.html \$uri/ /index.html =404; - } - - error_page 500 502 503 504 /50x.html; - location = /50x.html { - root /usr/share/nginx/html; - } - }"); - $this->execute_remote_command( - [ - $this->execute_in_builder("echo '{$dockerfile}' | base64 -d > {$this->workdir}/Dockerfile-prod") - ], - [ - $this->execute_in_builder("echo '{$nginx_config}' | base64 -d > {$this->workdir}/nginx.conf") - ], - [ - $this->execute_in_builder("docker build -f {$this->workdir}/Dockerfile-prod {$this->build_args} --progress plain -t $this->production_image_name {$this->workdir}"), "hidden" => true - ] - ); - } else { - $this->execute_remote_command([ - $this->execute_in_builder("docker build -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t $this->production_image_name {$this->workdir}"), "hidden" => true - ]); - } + $this->execute_remote_command( + [ + "echo -n 'Generating nixpacks configuration.'", + ], + [$this->nixpacks_build_cmd()], + [$this->execute_in_builder("cp {$this->workdir}/.nixpacks/Dockerfile {$this->workdir}/Dockerfile")], + [$this->execute_in_builder("rm -f {$this->workdir}/.nixpacks/Dockerfile")] + ); } - private function add_build_env_variables_to_dockerfile() - { - $this->execute_remote_command([ - $this->execute_in_builder("cat {$this->workdir}/Dockerfile"), "hidden" => true, "save" => 'dockerfile' - ]); - $dockerfile = collect(Str::of($this->saved_outputs->get('dockerfile'))->trim()->explode("\n")); - foreach ($this->application->build_environment_variables as $env) { - $dockerfile->splice(1, 0, "ARG {$env->key}={$env->value}"); - } - $dockerfile_base64 = base64_encode($dockerfile->implode("\n")); - $this->execute_remote_command([ - $this->execute_in_builder("echo '{$dockerfile_base64}' | base64 -d > {$this->workdir}/Dockerfile"), - "hidden" => true - ]); - } - private function generate_build_env_variables() + private function nixpacks_build_cmd() { - $this->build_args = collect(["--build-arg SOURCE_COMMIT={$this->commit}"]); + $this->generate_env_variables(); + $nixpacks_command = "nixpacks build -o {$this->workdir} {$this->env_args} --no-error-without-start"; + if ($this->application->build_command) { + $nixpacks_command .= " --build-cmd \"{$this->application->build_command}\""; + } + if ($this->application->start_command) { + $nixpacks_command .= " --start-cmd \"{$this->application->start_command}\""; + } + if ($this->application->install_command) { + $nixpacks_command .= " --install-cmd \"{$this->application->install_command}\""; + } + $nixpacks_command .= " {$this->workdir}"; + return $this->execute_in_builder($nixpacks_command); + } + + private function generate_env_variables() + { + $this->env_args = collect([]); if ($this->pull_request_id === 0) { - foreach ($this->application->build_environment_variables as $env) { - $this->build_args->push("--build-arg {$env->key}={$env->value}"); + foreach ($this->application->nixpacks_environment_variables as $env) { + $this->env_args->push("--env {$env->key}={$env->value}"); } } else { - foreach ($this->application->build_environment_variables_preview as $env) { - $this->build_args->push("--build-arg {$env->key}={$env->value}"); + foreach ($this->application->nixpacks_environment_variables_preview as $env) { + $this->env_args->push("--env {$env->key}={$env->value}"); } } - $this->build_args = $this->build_args->implode(' '); + $this->env_args = $this->env_args->implode(' '); } private function generate_compose_file() @@ -388,6 +371,7 @@ private function generate_compose_file() $docker_compose_base64 = base64_encode($this->docker_compose); $this->execute_remote_command([$this->execute_in_builder("echo '{$docker_compose_base64}' | base64 -d > {$this->workdir}/docker-compose.yml"), "hidden" => true]); } + private function generate_local_persistent_volumes() { $local_persistent_volumes = []; @@ -400,6 +384,7 @@ private function generate_local_persistent_volumes() } return $local_persistent_volumes; } + private function generate_local_persistent_volumes_only_volume_names() { $local_persistent_volumes_names = []; @@ -420,6 +405,7 @@ private function generate_local_persistent_volumes_only_volume_names() } return $local_persistent_volumes_names; } + private function generate_environment_variables($ports) { $environment_variables = collect(); @@ -436,27 +422,12 @@ private function generate_environment_variables($ports) } } // Add PORT if not exists, use the first port as default - if ($environment_variables->filter(fn ($env) => Str::of($env)->contains('PORT'))->isEmpty()) { + if ($environment_variables->filter(fn($env) => Str::of($env)->contains('PORT'))->isEmpty()) { $environment_variables->push("PORT={$ports[0]}"); } return $environment_variables->all(); } - private function generate_healthcheck_commands() - { - if (!$this->application->health_check_port) { - $this->application->health_check_port = $this->application->ports_exposes_array[0]; - } - if ($this->application->health_check_path) { - $generated_healthchecks_commands = [ - "curl -s -X {$this->application->health_check_method} -f {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$this->application->health_check_port}{$this->application->health_check_path} > /dev/null" - ]; - } else { - $generated_healthchecks_commands = [ - "curl -s -X {$this->application->health_check_method} -f {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$this->application->health_check_port}/" - ]; - } - return implode(' ', $generated_healthchecks_commands); - } + private function set_labels_for_applications() { $labels = []; @@ -520,140 +491,192 @@ private function set_labels_for_applications() } return $labels; } - private function generate_buildpack() + + private function generate_healthcheck_commands() + { + if (!$this->application->health_check_port) { + $this->application->health_check_port = $this->application->ports_exposes_array[0]; + } + if ($this->application->health_check_path) { + $generated_healthchecks_commands = [ + "curl -s -X {$this->application->health_check_method} -f {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$this->application->health_check_port}{$this->application->health_check_path} > /dev/null" + ]; + } else { + $generated_healthchecks_commands = [ + "curl -s -X {$this->application->health_check_method} -f {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$this->application->health_check_port}/" + ]; + } + return implode(' ', $generated_healthchecks_commands); + } + + private function build_image() + { + $this->execute_remote_command([ + "echo -n 'Building docker image.'", + ]); + + if ($this->application->settings->is_static) { + $this->execute_remote_command([ + $this->execute_in_builder("docker build -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t $this->build_image_name {$this->workdir}"), "hidden" => true + ]); + + $dockerfile = base64_encode("FROM {$this->application->static_image} +WORKDIR /usr/share/nginx/html/ +LABEL coolify.deploymentId={$this->deployment_uuid} +COPY --from=$this->build_image_name /app/{$this->application->publish_directory} . +COPY ./nginx.conf /etc/nginx/conf.d/default.conf"); + + $nginx_config = base64_encode("server { + listen 80; + listen [::]:80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html; + try_files \$uri \$uri.html \$uri/index.html \$uri/ /index.html =404; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + }"); + $this->execute_remote_command( + [ + $this->execute_in_builder("echo '{$dockerfile}' | base64 -d > {$this->workdir}/Dockerfile-prod") + ], + [ + $this->execute_in_builder("echo '{$nginx_config}' | base64 -d > {$this->workdir}/nginx.conf") + ], + [ + $this->execute_in_builder("docker build -f {$this->workdir}/Dockerfile-prod {$this->build_args} --progress plain -t $this->production_image_name {$this->workdir}"), "hidden" => true + ] + ); + } else { + $this->execute_remote_command([ + $this->execute_in_builder("docker build -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t $this->production_image_name {$this->workdir}"), "hidden" => true + ]); + } + } + + private function stop_running_container() { $this->execute_remote_command( - [ - "echo -n 'Generating nixpacks configuration.'", - ], - [$this->nixpacks_build_cmd()], - [$this->execute_in_builder("cp {$this->workdir}/.nixpacks/Dockerfile {$this->workdir}/Dockerfile")], - [$this->execute_in_builder("rm -f {$this->workdir}/.nixpacks/Dockerfile")] + ["echo -n 'Removing old running application.'"], + [$this->execute_in_builder("docker rm -f $this->container_name >/dev/null 2>&1"), "hidden" => true], ); } - private function nixpacks_build_cmd() + + private function start_by_compose_file() { - $this->generate_env_variables(); - $nixpacks_command = "nixpacks build -o {$this->workdir} {$this->env_args} --no-error-without-start"; - if ($this->application->build_command) { - $nixpacks_command .= " --build-cmd \"{$this->application->build_command}\""; - } - if ($this->application->start_command) { - $nixpacks_command .= " --start-cmd \"{$this->application->start_command}\""; - } - if ($this->application->install_command) { - $nixpacks_command .= " --install-cmd \"{$this->application->install_command}\""; - } - $nixpacks_command .= " {$this->workdir}"; - return $this->execute_in_builder($nixpacks_command); + $this->execute_remote_command( + ["echo -n 'Starting new application... '"], + [$this->execute_in_builder("docker compose --project-directory {$this->workdir} up -d >/dev/null"), "hidden" => true], + ["echo 'Done. 🎉'"], + ); } - private function generate_env_variables() + + private function deploy() { - $this->env_args = collect([]); + + $this->execute_remote_command( + [ + "echo 'Starting deployment of {$this->application->git_repository}:{$this->application->git_branch}.'" + ], + ); + $this->prepare_builder_image(); + $this->clone_repository(); + + $tag = Str::of("{$this->commit}-{$this->application->id}-{$this->pull_request_id}"); + if (strlen($tag) > 128) { + $tag = $tag->substr(0, 128); + }; + + $this->build_image_name = "{$this->application->git_repository}:{$tag}-build"; + $this->production_image_name = "{$this->application->uuid}:{$tag}"; + ray('Build Image Name: ' . $this->build_image_name . ' & Production Image Name: ' . $this->production_image_name)->green(); + + if (!$this->force_rebuild) { + $this->execute_remote_command([ + "docker images -q {$this->production_image_name} 2>/dev/null", "hidden" => true, "save" => "local_image_found" + ]); + if (Str::of($this->saved_outputs->get('local_image_found'))->isNotEmpty()) { + $this->execute_remote_command([ + "echo 'Docker Image found locally with the same Git Commit SHA {$this->application->uuid}:{$this->commit}. Build step skipped...'" + ]); + $this->generate_compose_file(); + $this->stop_running_container(); + $this->start_by_compose_file(); + return; + } + } + $this->cleanup_git(); + $this->generate_buildpack(); + $this->generate_compose_file(); + $this->generate_build_env_variables(); + $this->add_build_env_variables_to_dockerfile(); + $this->build_image(); + $this->stop_running_container(); + $this->start_by_compose_file(); + } + + private function generate_build_env_variables() + { + $this->build_args = collect(["--build-arg SOURCE_COMMIT={$this->commit}"]); if ($this->pull_request_id === 0) { - foreach ($this->application->nixpacks_environment_variables as $env) { - $this->env_args->push("--env {$env->key}={$env->value}"); + foreach ($this->application->build_environment_variables as $env) { + $this->build_args->push("--build-arg {$env->key}={$env->value}"); } } else { - foreach ($this->application->nixpacks_environment_variables_preview as $env) { - $this->env_args->push("--env {$env->key}={$env->value}"); + foreach ($this->application->build_environment_variables_preview as $env) { + $this->build_args->push("--build-arg {$env->key}={$env->value}"); } } - $this->env_args = $this->env_args->implode(' '); + $this->build_args = $this->build_args->implode(' '); } - private function cleanup_git() - { - $this->execute_remote_command( - [$this->execute_in_builder("rm -fr {$this->workdir}/.git")], - ); - } - private function prepare_builder_image() - { - $this->execute_remote_command( - [ - "echo -n 'Pulling latest version of the builder image (ghcr.io/coollabsio/coolify-builder).'", - ], - [ - "docker run --pull=always -d --name {$this->deployment_uuid} --rm -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/coollabsio/coolify-builder", - "hidden" => true, - ], - [ - "command" => $this->execute_in_builder("mkdir -p {$this->workdir}") - ], - ); - } - private function set_git_import_settings($git_clone_command) - { - if ($this->application->git_commit_sha !== 'HEAD') { - $git_clone_command = "{$git_clone_command} && cd {$this->workdir} && git -c advice.detachedHead=false checkout {$this->application->git_commit_sha} >/dev/null 2>&1"; - } - if ($this->application->settings->is_git_submodules_enabled) { - $git_clone_command = "{$git_clone_command} && cd {$this->workdir} && git submodule update --init --recursive"; - } - if ($this->application->settings->is_git_lfs_enabled) { - $git_clone_command = "{$git_clone_command} && cd {$this->workdir} && git lfs pull"; - } - return $git_clone_command; - } - private function importing_git_repository() - { - $commands = collect([]); - $git_clone_command = "git clone -q -b {$this->application->git_branch}"; - if ($this->pull_request_id !== 0) { - $pr_branch_name = "pr-{$this->pull_request_id}-coolify"; - } - if ($this->application->deploymentType() === 'source') { - $source_html_url = data_get($this->application, 'source.html_url'); - $url = parse_url(filter_var($source_html_url, FILTER_SANITIZE_URL)); - $source_html_url_host = $url['host']; - $source_html_url_scheme = $url['scheme']; + private function add_build_env_variables_to_dockerfile() + { + $this->execute_remote_command([ + $this->execute_in_builder("cat {$this->workdir}/Dockerfile"), "hidden" => true, "save" => 'dockerfile' + ]); + $dockerfile = collect(Str::of($this->saved_outputs->get('dockerfile'))->trim()->explode("\n")); - if ($this->source->getMorphClass() == 'App\Models\GithubApp') { - if ($this->source->is_public) { - $git_clone_command = "{$git_clone_command} {$this->source->html_url}/{$this->application->git_repository} {$this->workdir}"; - $git_clone_command = $this->set_git_import_settings($git_clone_command); - - $commands->push($this->execute_in_builder($git_clone_command)); - } else { - $github_access_token = generate_github_installation_token($this->source); - $commands->push($this->execute_in_builder("git clone -q -b {$this->application->git_branch} $source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$this->application->git_repository}.git {$this->workdir}")); - } - if ($this->pull_request_id !== 0) { - $commands->push($this->execute_in_builder("cd {$this->workdir} && git fetch origin pull/{$this->pull_request_id}/head:$pr_branch_name && git checkout $pr_branch_name")); - } - return $commands->implode(' && '); - } + foreach ($this->application->build_environment_variables as $env) { + $dockerfile->splice(1, 0, "ARG {$env->key}={$env->value}"); } - if ($this->application->deploymentType() === 'deploy_key') { - $private_key = base64_encode($this->application->private_key->private_key); - $git_clone_command = "GIT_SSH_COMMAND=\"ssh -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" {$git_clone_command} {$this->application->git_full_url} {$this->workdir}"; - $git_clone_command = $this->set_git_import_settings($git_clone_command); - $commands = collect([ - $this->execute_in_builder("mkdir -p /root/.ssh"), - $this->execute_in_builder("echo '{$private_key}' | base64 -d > /root/.ssh/id_rsa"), - $this->execute_in_builder("chmod 600 /root/.ssh/id_rsa"), - $this->execute_in_builder($git_clone_command) + $dockerfile_base64 = base64_encode($dockerfile->implode("\n")); + $this->execute_remote_command([ + $this->execute_in_builder("echo '{$dockerfile_base64}' | base64 -d > {$this->workdir}/Dockerfile"), + "hidden" => true + ]); + } + + private function next(string $status) + { + // If the deployment is cancelled by the user, don't update the status + if ($this->application_deployment_queue->status !== ApplicationDeploymentStatus::CANCELLED_BY_USER->value) { + $this->application_deployment_queue->update([ + 'status' => $status, ]); - return $commands->implode(' && '); + } + queue_next_deployment($this->application); + if ($status === ApplicationDeploymentStatus::FINISHED->value) { + $this->application->environment->project->team->notify(new DeploymentSuccess($this->application, $this->deployment_uuid, $this->preview)); + } + if ($status === ApplicationDeploymentStatus::FAILED->value) { + $this->application->environment->project->team->notify(new DeploymentFailed($this->application, $this->deployment_uuid, $this->preview)); } } - private function clone_repository() + + public function failed(Throwable $exception): void { $this->execute_remote_command( - [ - "echo -n 'Importing {$this->application->git_repository}:{$this->application->git_branch} to {$this->workdir}. '" - ], - [ - $this->importing_git_repository() - ], - [ - $this->execute_in_builder("cd {$this->workdir} && git rev-parse HEAD"), - "hidden" => true, - "save" => "git_commit_sha" - ], + ["echo 'Oops something is not okay, are you okay? 😢'"], + ["echo '{$exception->getMessage()}'"] ); - $this->commit = $this->saved_outputs->get('git_commit_sha'); + $this->next(ApplicationDeploymentStatus::FAILED->value); } -} \ No newline at end of file +} diff --git a/app/Jobs/ApplicationPullRequestUpdateJob.php b/app/Jobs/ApplicationPullRequestUpdateJob.php index e0f51e0ee..2b84cbe5a 100755 --- a/app/Jobs/ApplicationPullRequestUpdateJob.php +++ b/app/Jobs/ApplicationPullRequestUpdateJob.php @@ -22,11 +22,13 @@ class ApplicationPullRequestUpdateJob implements ShouldQueue public function __construct( public string $application_id, - public int $pull_request_id, + public int $pull_request_id, public string $deployment_uuid, public string $status - ) { + ) + { } + public function handle() { try { @@ -61,6 +63,7 @@ public function handle() throw $e; } } + private function update_comment() { ['data' => $data] = git_api(source: $this->application->source, endpoint: "/repos/{$this->application->git_repository}/issues/comments/{$this->preview->pull_request_issue_comment_id}", method: 'patch', data: [ @@ -71,6 +74,7 @@ private function update_comment() $this->create_comment(); } } + private function create_comment() { ['data' => $data] = git_api(source: $this->application->source, endpoint: "/repos/{$this->application->git_repository}/issues/{$this->pull_request_id}/comments", method: 'post', data: [ diff --git a/app/Jobs/CheckResaleLicenseJob.php b/app/Jobs/CheckResaleLicenseJob.php index 0e925c569..f14214733 100644 --- a/app/Jobs/CheckResaleLicenseJob.php +++ b/app/Jobs/CheckResaleLicenseJob.php @@ -3,15 +3,11 @@ namespace App\Jobs; use App\Actions\License\CheckResaleLicense; -use App\Models\InstanceSettings; use Illuminate\Bus\Queueable; -use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -use Illuminate\Support\Facades\Http; -use Visus\Cuid2\Cuid2; class CheckResaleLicenseJob implements ShouldQueue { diff --git a/app/Jobs/ContainerStatusJob.php b/app/Jobs/ContainerStatusJob.php index 7db4dce72..083023929 100644 --- a/app/Jobs/ContainerStatusJob.php +++ b/app/Jobs/ContainerStatusJob.php @@ -2,7 +2,6 @@ namespace App\Jobs; -use App\Models\Application; use App\Models\ApplicationPreview; use App\Notifications\Application\StatusChanged; use Illuminate\Bus\Queueable; @@ -11,7 +10,6 @@ use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -use Illuminate\Support\Facades\Log; class ContainerStatusJob implements ShouldQueue, ShouldBeUnique { @@ -27,10 +25,12 @@ public function __construct($resource, string $container_name, string|null $pull $this->container_name = $container_name; $this->pull_request_id = $pull_request_id; } + public function uniqueId(): string { return $this->container_name; } + public function handle(): void { try { diff --git a/app/Jobs/CoolifyTask.php b/app/Jobs/CoolifyTask.php index d87468efc..10bc89358 100755 --- a/app/Jobs/CoolifyTask.php +++ b/app/Jobs/CoolifyTask.php @@ -19,8 +19,9 @@ class CoolifyTask implements ShouldQueue */ public function __construct( public Activity $activity, - public bool $ignore_errors = false, - ) { + public bool $ignore_errors = false, + ) + { } /** diff --git a/app/Jobs/DockerCleanupJob.php b/app/Jobs/DockerCleanupJob.php index 3eb1b939b..2c0a3fc06 100644 --- a/app/Jobs/DockerCleanupJob.php +++ b/app/Jobs/DockerCleanupJob.php @@ -8,13 +8,14 @@ use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -use Illuminate\Support\Facades\Log; use Illuminate\Support\Str; class DockerCleanupJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + public $timeout = 500; + /** * Create a new job instance. */ diff --git a/app/Jobs/InstanceApplicationsStatusJob.php b/app/Jobs/InstanceApplicationsStatusJob.php index a7ab592b0..fd173215b 100644 --- a/app/Jobs/InstanceApplicationsStatusJob.php +++ b/app/Jobs/InstanceApplicationsStatusJob.php @@ -15,10 +15,12 @@ class InstanceApplicationsStatusJob implements ShouldQueue, ShouldBeUnique use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; public $applications; + public function __construct() { $this->applications = Application::all(); } + public function handle(): void { try { diff --git a/app/Jobs/InstanceAutoUpdateJob.php b/app/Jobs/InstanceAutoUpdateJob.php index b0b19aef1..957b8fe23 100644 --- a/app/Jobs/InstanceAutoUpdateJob.php +++ b/app/Jobs/InstanceAutoUpdateJob.php @@ -3,9 +3,6 @@ namespace App\Jobs; use App\Actions\Server\UpdateCoolify; -use App\Models\InstanceSettings; -use App\Models\Server; -use Exception; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; @@ -22,6 +19,7 @@ class InstanceAutoUpdateJob implements ShouldQueue, ShouldBeUnique public function __construct(private bool $force = false) { } + public function handle(): void { resolve(UpdateCoolify::class)($this->force); diff --git a/app/Jobs/ProxyCheckJob.php b/app/Jobs/ProxyCheckJob.php index 87e7c9bda..7c498107d 100755 --- a/app/Jobs/ProxyCheckJob.php +++ b/app/Jobs/ProxyCheckJob.php @@ -3,7 +3,6 @@ namespace App\Jobs; use App\Actions\Proxy\StartProxy; -use App\Enums\ProxyTypes; use App\Models\Server; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; @@ -18,6 +17,7 @@ class ProxyCheckJob implements ShouldQueue public function __construct() { } + public function handle() { try { diff --git a/app/Jobs/ProxyContainerStatusJob.php b/app/Jobs/ProxyContainerStatusJob.php index 02cd37568..68372895a 100644 --- a/app/Jobs/ProxyContainerStatusJob.php +++ b/app/Jobs/ProxyContainerStatusJob.php @@ -9,8 +9,8 @@ use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; -use Illuminate\Queue\SerializesModels; use Illuminate\Queue\Middleware\WithoutOverlapping; +use Illuminate\Queue\SerializesModels; use Illuminate\Support\Str; class ProxyContainerStatusJob implements ShouldQueue, ShouldBeUnique @@ -20,18 +20,22 @@ class ProxyContainerStatusJob implements ShouldQueue, ShouldBeUnique public Server $server; public $tries = 1; public $timeout = 120; - public function middleware(): array - { - return [new WithoutOverlapping($this->server->id)]; - } + public function __construct(Server $server) { $this->server = $server; } + + public function middleware(): array + { + return [new WithoutOverlapping($this->server->id)]; + } + public function uniqueId(): int { return $this->server->id; } + public function handle(): void { try { diff --git a/app/Jobs/ProxyStartJob.php b/app/Jobs/ProxyStartJob.php index 074d21664..5119210fc 100755 --- a/app/Jobs/ProxyStartJob.php +++ b/app/Jobs/ProxyStartJob.php @@ -17,6 +17,7 @@ class ProxyStartJob implements ShouldQueue public function __construct(protected Server $server) { } + public function handle() { try { diff --git a/app/Jobs/SendMessageToDiscordJob.php b/app/Jobs/SendMessageToDiscordJob.php index 11122e7e3..577b3a907 100644 --- a/app/Jobs/SendMessageToDiscordJob.php +++ b/app/Jobs/SendMessageToDiscordJob.php @@ -3,7 +3,6 @@ namespace App\Jobs; use Illuminate\Bus\Queueable; -use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; @@ -29,7 +28,8 @@ class SendMessageToDiscordJob implements ShouldQueue public function __construct( public string $text, public string $webhookUrl - ) { + ) + { } /** diff --git a/app/Models/Application.php b/app/Models/Application.php index 2c395511b..664b695b6 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -2,28 +2,12 @@ namespace App\Models; -use Illuminate\Contracts\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Casts\Attribute; -use Spatie\Activitylog\Models\Activity; use Illuminate\Database\Eloquent\Relations\HasMany; -use Masmerise\Toaster\Toastable; -use Masmerise\Toaster\Toaster; -use Spatie\SchemalessAttributes\Casts\SchemalessAttributes; +use Spatie\Activitylog\Models\Activity; class Application extends BaseModel { - protected static function booted() - { - static::created(function ($application) { - ApplicationSetting::create([ - 'application_id' => $application->id, - ]); - }); - static::deleting(function ($application) { - $application->settings()->delete(); - $application->persistentStorages()->delete(); - }); - } protected $fillable = [ 'name', 'repository_project_id', @@ -43,15 +27,42 @@ protected static function booted() 'publish_directory', 'private_key_id' ]; - public function type() { + + protected static function booted() + { + static::created(function ($application) { + ApplicationSetting::create([ + 'application_id' => $application->id, + ]); + }); + static::deleting(function ($application) { + $application->settings()->delete(); + $application->persistentStorages()->delete(); + }); + } + + public function settings() + { + return $this->hasOne(ApplicationSetting::class); + } + + public function persistentStorages() + { + return $this->morphMany(LocalPersistentVolume::class, 'resource'); + } + + public function type() + { return 'application'; } + public function publishDirectory(): Attribute { return Attribute::make( - set: fn ($value) => $value ? '/' . ltrim($value, '/') : null, + set: fn($value) => $value ? '/' . ltrim($value, '/') : null, ); } + public function gitBranchLocation(): Attribute { return Attribute::make( @@ -63,6 +74,7 @@ public function gitBranchLocation(): Attribute ); } + public function gitCommits(): Attribute { return Attribute::make( @@ -73,99 +85,108 @@ public function gitCommits(): Attribute } ); } + public function baseDirectory(): Attribute { return Attribute::make( - set: fn ($value) => '/' . ltrim($value, '/'), + set: fn($value) => '/' . ltrim($value, '/'), ); } + public function portsMappings(): Attribute { return Attribute::make( - set: fn ($value) => $value === "" ? null : $value, + set: fn($value) => $value === "" ? null : $value, ); } + + // Normal Deployments + public function portsMappingsArray(): Attribute { return Attribute::make( - get: fn () => - is_null($this->ports_mappings) + get: fn() => is_null($this->ports_mappings) ? [] : explode(',', $this->ports_mappings), ); } + public function portsExposesArray(): Attribute { return Attribute::make( - get: fn () => - is_null($this->ports_exposes) + get: fn() => is_null($this->ports_exposes) ? [] : explode(',', $this->ports_exposes) ); } - // Normal Deployments + public function environment_variables(): HasMany { return $this->hasMany(EnvironmentVariable::class)->where('is_preview', false); } + public function runtime_environment_variables(): HasMany { return $this->hasMany(EnvironmentVariable::class)->where('is_preview', false)->where('key', 'not like', 'NIXPACKS_%'); } + + // Preview Deployments + public function build_environment_variables(): HasMany { return $this->hasMany(EnvironmentVariable::class)->where('is_preview', false)->where('is_build_time', true)->where('key', 'not like', 'NIXPACKS_%'); } + public function nixpacks_environment_variables(): HasMany { return $this->hasMany(EnvironmentVariable::class)->where('is_preview', false)->where('key', 'like', 'NIXPACKS_%'); } - // Preview Deployments + public function environment_variables_preview(): HasMany { return $this->hasMany(EnvironmentVariable::class)->where('is_preview', true); } + public function runtime_environment_variables_preview(): HasMany { return $this->hasMany(EnvironmentVariable::class)->where('is_preview', true)->where('key', 'not like', 'NIXPACKS_%'); } + public function build_environment_variables_preview(): HasMany { return $this->hasMany(EnvironmentVariable::class)->where('is_preview', true)->where('is_build_time', true)->where('key', 'not like', 'NIXPACKS_%'); } + public function nixpacks_environment_variables_preview(): HasMany { return $this->hasMany(EnvironmentVariable::class)->where('is_preview', true)->where('key', 'like', 'NIXPACKS_%'); } + public function private_key() { return $this->belongsTo(PrivateKey::class); } + public function environment() { return $this->belongsTo(Environment::class); } + public function previews() { return $this->hasMany(ApplicationPreview::class); } - public function settings() - { - return $this->hasOne(ApplicationSetting::class); - } + public function destination() { return $this->morphTo(); } + public function source() { return $this->morphTo(); } - public function persistentStorages() - { - return $this->morphMany(LocalPersistentVolume::class, 'resource'); - } public function deployments(int $skip = 0, int $take = 10) { @@ -177,10 +198,12 @@ public function deployments(int $skip = 0, int $take = 10) 'deployments' => $deployments ]; } + public function get_deployment(string $deployment_uuid) { return Activity::where('subject_id', $this->id)->where('properties->type_uuid', '=', $deployment_uuid)->first(); } + public function isDeployable(): bool { if ($this->settings->is_auto_deploy_enabled) { @@ -188,6 +211,7 @@ public function isDeployable(): bool } return false; } + public function isPRDeployable(): bool { if ($this->settings->is_preview_deployments_enabled) { @@ -195,6 +219,7 @@ public function isPRDeployable(): bool } return false; } + public function deploymentType() { if (data_get($this, 'private_key_id')) { diff --git a/app/Models/ApplicationPreview.php b/app/Models/ApplicationPreview.php index 910e9b73b..38ac5127d 100644 --- a/app/Models/ApplicationPreview.php +++ b/app/Models/ApplicationPreview.php @@ -13,12 +13,14 @@ class ApplicationPreview extends BaseModel 'status', 'application_id', ]; - public function application() - { - return $this->belongsTo(Application::class); - } + static function findPreviewByApplicationAndPullId(int $application_id, int $pull_request_id) { return self::where('application_id', $application_id)->where('pull_request_id', $pull_request_id)->firstOrFail(); } + + public function application() + { + return $this->belongsTo(Application::class); + } } diff --git a/app/Models/ApplicationSetting.php b/app/Models/ApplicationSetting.php index 3bdd6a7cd..1340c8fa0 100644 --- a/app/Models/ApplicationSetting.php +++ b/app/Models/ApplicationSetting.php @@ -26,6 +26,7 @@ class ApplicationSetting extends Model 'is_git_submodules_enabled', 'is_git_lfs_enabled', ]; + public function isStatic(): Attribute { return Attribute::make( @@ -42,6 +43,7 @@ public function isStatic(): Attribute } ); } + public function application() { return $this->belongsTo(Application::class); diff --git a/app/Models/BaseModel.php b/app/Models/BaseModel.php index 8f2ee86ae..be487a497 100644 --- a/app/Models/BaseModel.php +++ b/app/Models/BaseModel.php @@ -14,7 +14,7 @@ protected static function boot() static::creating(function (Model $model) { // Generate a UUID if one isn't set if (!$model->uuid) { - $model->uuid = (string) new Cuid2(7); + $model->uuid = (string)new Cuid2(7); } }); } diff --git a/app/Models/Database.php b/app/Models/Database.php index ab0476d27..85434feea 100644 --- a/app/Models/Database.php +++ b/app/Models/Database.php @@ -8,6 +8,7 @@ public function environment() { return $this->belongsTo(Environment::class); } + public function destination() { return $this->morphTo(); diff --git a/app/Models/Environment.php b/app/Models/Environment.php index 3f8940cde..458223ac9 100644 --- a/app/Models/Environment.php +++ b/app/Models/Environment.php @@ -11,32 +11,41 @@ class Environment extends Model 'name', 'project_id', ]; - protected function name(): Attribute + + public function can_delete_environment() { - return Attribute::make( - set: fn (string $value) => strtolower($value), - ); - } - public function can_delete_environment() { return $this->applications()->count() == 0 && $this->postgresqls()->count() == 0; } - public function databases() { - return $this->postgresqls(); - } - public function project() - { - return $this->belongsTo(Project::class); - } + public function applications() { return $this->hasMany(Application::class); } + public function postgresqls() { return $this->hasMany(StandalonePostgresql::class); } + + public function databases() + { + return $this->postgresqls(); + } + + public function project() + { + return $this->belongsTo(Project::class); + } + public function services() { return $this->hasMany(Service::class); } + + protected function name(): Attribute + { + return Attribute::make( + set: fn(string $value) => strtolower($value), + ); + } } diff --git a/app/Models/EnvironmentVariable.php b/app/Models/EnvironmentVariable.php index f3be6716b..23a420ef5 100644 --- a/app/Models/EnvironmentVariable.php +++ b/app/Models/EnvironmentVariable.php @@ -15,21 +15,30 @@ class EnvironmentVariable extends Model 'value' => 'encrypted', 'is_build_time' => 'boolean', ]; + protected static function booted() { static::created(function ($environment_variable) { - if ($environment_variable->application_id && !$environment_variable->is_preview) { - ModelsEnvironmentVariable::create([ - 'key' => $environment_variable->key, - 'value' => $environment_variable->value, - 'is_build_time' => $environment_variable->is_build_time, - 'application_id' => $environment_variable->application_id, - 'is_preview' => true, - ]); - } + if ($environment_variable->application_id && !$environment_variable->is_preview) { + ModelsEnvironmentVariable::create([ + 'key' => $environment_variable->key, + 'value' => $environment_variable->value, + 'is_build_time' => $environment_variable->is_build_time, + 'application_id' => $environment_variable->application_id, + 'is_preview' => true, + ]); + } }); } + protected function value(): Attribute + { + return Attribute::make( + get: fn(string $value) => $this->get_environment_variables($value), + set: fn(string $value) => $this->set_environment_variables($value), + ); + } + private function get_environment_variables(string $environment_variable): string|null { // $team_id = session('currentTeam')->id; @@ -45,6 +54,7 @@ private function get_environment_variables(string $environment_variable): string } return decrypt($environment_variable); } + private function set_environment_variables(string $environment_variable): string|null { $environment_variable = trim($environment_variable); @@ -53,17 +63,11 @@ private function set_environment_variables(string $environment_variable): string } return $environment_variable; } - protected function value(): Attribute - { - return Attribute::make( - get: fn (string $value) => $this->get_environment_variables($value), - set: fn (string $value) => $this->set_environment_variables($value), - ); - } + protected function key(): Attribute { return Attribute::make( - set: fn (string $value) => Str::of($value)->trim(), + set: fn(string $value) => Str::of($value)->trim(), ); } } diff --git a/app/Models/GithubApp.php b/app/Models/GithubApp.php index 54e68aa63..8db24b900 100644 --- a/app/Models/GithubApp.php +++ b/app/Models/GithubApp.php @@ -16,6 +16,17 @@ class GithubApp extends BaseModel 'client_secret', 'webhook_secret', ]; + + static public function public() + { + return GithubApp::whereTeamId(session('currentTeam')->id)->whereisPublic(true)->whereNotNull('app_id')->get(); + } + + static public function private() + { + return GithubApp::whereTeamId(session('currentTeam')->id)->whereisPublic(false)->whereNotNull('app_id')->get(); + } + protected static function booted(): void { static::deleting(function (GithubApp $github_app) { @@ -25,14 +36,17 @@ protected static function booted(): void } }); } + public function applications() { return $this->morphMany(Application::class, 'source'); } + public function privateKey() { return $this->belongsTo(PrivateKey::class); } + public function type(): Attribute { return Attribute::make( @@ -43,12 +57,4 @@ public function type(): Attribute }, ); } - static public function public() - { - return GithubApp::whereTeamId(session('currentTeam')->id)->whereisPublic(true)->whereNotNull('app_id')->get(); - } - static public function private() - { - return GithubApp::whereTeamId(session('currentTeam')->id)->whereisPublic(false)->whereNotNull('app_id')->get(); - } } diff --git a/app/Models/GitlabApp.php b/app/Models/GitlabApp.php index dbac3414b..a789a7e65 100644 --- a/app/Models/GitlabApp.php +++ b/app/Models/GitlabApp.php @@ -8,10 +8,12 @@ class GitlabApp extends BaseModel 'webhook_token', 'app_secret', ]; + public function applications() { return $this->morphMany(Application::class, 'source'); } + public function privateKey() { return $this->belongsTo(PrivateKey::class); diff --git a/app/Models/InstanceSettings.php b/app/Models/InstanceSettings.php index ef7859786..0fc892d92 100644 --- a/app/Models/InstanceSettings.php +++ b/app/Models/InstanceSettings.php @@ -3,28 +3,29 @@ namespace App\Models; use App\Notifications\Channels\SendsEmail; -use Illuminate\Contracts\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Notifications\Notifiable; -use Spatie\SchemalessAttributes\Casts\SchemalessAttributes; class InstanceSettings extends Model implements SendsEmail { use Notifiable; + protected $guarded = []; protected $casts = [ 'resale_license' => 'encrypted', ]; + + public static function get() + { + return InstanceSettings::findOrFail(0); + } + public function getRecepients($notification) { - $recipients = data_get($notification,'emails',null); + $recipients = data_get($notification, 'emails', null); if (is_null($recipients) || $recipients === '') { return []; } return explode(',', $recipients); } - public static function get() - { - return InstanceSettings::findOrFail(0); - } -} \ No newline at end of file +} diff --git a/app/Models/LocalPersistentVolume.php b/app/Models/LocalPersistentVolume.php index 71546df4d..68d6faded 100644 --- a/app/Models/LocalPersistentVolume.php +++ b/app/Models/LocalPersistentVolume.php @@ -9,26 +9,31 @@ class LocalPersistentVolume extends Model { protected $guarded = []; + public function application() { return $this->morphTo(); } + public function standalone_postgresql() { return $this->morphTo(); } + protected function name(): Attribute { return Attribute::make( - set: fn (string $value) => Str::of($value)->trim()->value, + set: fn(string $value) => Str::of($value)->trim()->value, ); } + protected function mountPath(): Attribute { return Attribute::make( - set: fn (string $value) => Str::of($value)->trim()->start('/')->value + set: fn(string $value) => Str::of($value)->trim()->start('/')->value ); } + protected function hostPath(): Attribute { return Attribute::make( diff --git a/app/Models/PrivateKey.php b/app/Models/PrivateKey.php index 82858ff22..795ede3b7 100644 --- a/app/Models/PrivateKey.php +++ b/app/Models/PrivateKey.php @@ -12,27 +12,13 @@ class PrivateKey extends BaseModel 'is_git_related', 'team_id', ]; + static public function ownedByCurrentTeam(array $select = ['*']) { $selectArray = collect($select)->concat(['id']); return PrivateKey::whereTeamId(session('currentTeam')->id)->select($selectArray->all()); } - public function applications() - { - return $this->hasMany(Application::class); - } - public function githubApps() - { - return $this->hasMany(GithubApp::class); - } - public function gitlabApps() - { - return $this->hasMany(GitlabApp::class); - } - public function servers() - { - return $this->hasMany(Server::class); - } + public function isEmpty() { if ($this->servers()->count() === 0 && $this->applications()->count() === 0 && $this->githubApps()->count() === 0 && $this->gitlabApps()->count() === 0) { @@ -40,4 +26,24 @@ public function isEmpty() } return false; } + + public function servers() + { + return $this->hasMany(Server::class); + } + + public function applications() + { + return $this->hasMany(Application::class); + } + + public function githubApps() + { + return $this->hasMany(GithubApp::class); + } + + public function gitlabApps() + { + return $this->hasMany(GitlabApp::class); + } } diff --git a/app/Models/Project.php b/app/Models/Project.php index dbba240af..55bc0a6cf 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -4,6 +4,18 @@ class Project extends BaseModel { + protected $fillable = [ + 'name', + 'description', + 'team_id', + 'project_id' + ]; + + static public function ownedByCurrentTeam() + { + return Project::whereTeamId(session('currentTeam')->id)->orderBy('name'); + } + protected static function booted() { static::created(function ($project) { @@ -20,32 +32,27 @@ protected static function booted() $project->settings()->delete(); }); } - protected $fillable = [ - 'name', - 'description', - 'team_id', - 'project_id' - ]; - static public function ownedByCurrentTeam() - { - return Project::whereTeamId(session('currentTeam')->id)->orderBy('name'); - } - public function team() - { - return $this->belongsTo(Team::class); - } + public function environments() { return $this->hasMany(Environment::class); } + public function settings() { return $this->hasOne(ProjectSetting::class); } + + public function team() + { + return $this->belongsTo(Team::class); + } + public function applications() { return $this->hasManyThrough(Application::class, Environment::class); } + public function postgresqls() { return $this->hasManyThrough(StandalonePostgresql::class, Environment::class); diff --git a/app/Models/S3Storage.php b/app/Models/S3Storage.php index a6f6360ac..754f53635 100644 --- a/app/Models/S3Storage.php +++ b/app/Models/S3Storage.php @@ -7,6 +7,7 @@ class S3Storage extends BaseModel { use HasFactory; + protected $guarded = []; protected $casts = [ 'key' => 'encrypted', @@ -18,12 +19,16 @@ static public function ownedByCurrentTeam(array $select = ['*']) $selectArray = collect($select)->concat(['id']); return S3Storage::whereTeamId(session('currentTeam')->id)->select($selectArray->all())->orderBy('name'); } - public function awsUrl() { + + public function awsUrl() + { return "{$this->endpoint}/{$this->bucket}"; } - public function testConnection() { + + public function testConnection() + { set_s3_target($this); return \Storage::disk('custom-s3')->files(); } -} \ No newline at end of file +} diff --git a/app/Models/Server.php b/app/Models/Server.php index 31e2d1e5c..5f24de02b 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -9,12 +9,47 @@ class Server extends BaseModel { use SchemalessAttributesTrait; - protected $schemalessAttributes = [ - 'proxy', - ]; + public $casts = [ 'proxy' => SchemalessAttributes::class, ]; + protected $schemalessAttributes = [ + 'proxy', + ]; + protected $fillable = [ + 'name', + 'ip', + 'user', + 'port', + 'team_id', + 'private_key_id', + 'proxy', + ]; + + static public function isReachable() + { + return Server::ownedByCurrentTeam()->whereRelation('settings', 'is_reachable', true); + } + + static public function ownedByCurrentTeam(array $select = ['*']) + { + $selectArray = collect($select)->concat(['id']); + return Server::whereTeamId(session('currentTeam')->id)->with('settings')->select($selectArray->all())->orderBy('name'); + } + + static public function isUsable() + { + return Server::ownedByCurrentTeam()->whereRelation('settings', 'is_reachable', true)->whereRelation('settings', 'is_usable', true); + } + + static public function destinationsByServer(string $server_id) + { + $server = Server::ownedByCurrentTeam()->get()->where('id', $server_id)->firstOrFail(); + $standaloneDocker = collect($server->standaloneDockers->all()); + $swarmDocker = collect($server->swarmDockers->all()); + return $standaloneDocker->concat($swarmDocker); + } + protected static function booted() { static::created(function ($server) { @@ -26,22 +61,17 @@ protected static function booted() $server->settings()->delete(); }); } - protected $fillable = [ - 'name', - 'ip', - 'user', - 'port', - 'team_id', - 'private_key_id', - 'proxy', - ]; - + public function settings() + { + return $this->hasOne(ServerSetting::class); + } public function scopeWithProxy(): Builder { return $this->proxy->modelScope(); } + public function isEmpty() { if ($this->applications()->count() === 0) { @@ -49,18 +79,21 @@ public function isEmpty() } return false; } + public function applications() { return $this->destinations()->map(function ($standaloneDocker) { return $standaloneDocker->applications; })->flatten(); } + public function destinations() { $standalone_docker = $this->hasMany(StandaloneDocker::class)->get(); $swarm_docker = $this->hasMany(SwarmDocker::class)->get(); return $standalone_docker->concat($swarm_docker); } + public function standaloneDockers() { return $this->hasMany(StandaloneDocker::class); @@ -76,38 +109,13 @@ public function privateKey() return $this->belongsTo(PrivateKey::class); } - public function settings() - { - return $this->hasOne(ServerSetting::class); - } public function muxFilename() { return "{$this->ip}_{$this->port}_{$this->user}"; } + public function team() { return $this->belongsTo(Team::class); } - static public function ownedByCurrentTeam(array $select = ['*']) - { - $selectArray = collect($select)->concat(['id']); - return Server::whereTeamId(session('currentTeam')->id)->with('settings')->select($selectArray->all())->orderBy('name'); - } - - static public function isReachable() - { - return Server::ownedByCurrentTeam()->whereRelation('settings', 'is_reachable', true); - } - static public function isUsable() - { - return Server::ownedByCurrentTeam()->whereRelation('settings', 'is_reachable', true)->whereRelation('settings', 'is_usable', true); - } - - static public function destinationsByServer(string $server_id) - { - $server = Server::ownedByCurrentTeam()->get()->where('id', $server_id)->firstOrFail(); - $standaloneDocker = collect($server->standaloneDockers->all()); - $swarmDocker = collect($server->swarmDockers->all()); - return $standaloneDocker->concat($swarmDocker); - } } diff --git a/app/Models/ServerSetting.php b/app/Models/ServerSetting.php index 6fdf931e7..198600735 100644 --- a/app/Models/ServerSetting.php +++ b/app/Models/ServerSetting.php @@ -10,6 +10,7 @@ class ServerSetting extends Model 'server_id', 'is_usable', ]; + public function server() { return $this->belongsTo(Server::class); diff --git a/app/Models/Service.php b/app/Models/Service.php index e3df5dfa7..fab754360 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -9,6 +9,7 @@ public function environment() { return $this->belongsTo(Environment::class); } + public function destination() { return $this->morphTo(); diff --git a/app/Models/StandaloneDocker.php b/app/Models/StandaloneDocker.php index a21e22e45..9d9f44454 100644 --- a/app/Models/StandaloneDocker.php +++ b/app/Models/StandaloneDocker.php @@ -9,18 +9,22 @@ class StandaloneDocker extends BaseModel 'network', 'server_id', ]; + public function applications() { return $this->morphMany(Application::class, 'destination'); } + public function postgresqls() { return $this->morphMany(StandalonePostgresql::class, 'destination'); } + public function server() { return $this->belongsTo(Server::class); } + public function attachedTo() { return $this->applications->count() > 0 || $this->databases->count() > 0; diff --git a/app/Models/StandalonePostgresql.php b/app/Models/StandalonePostgresql.php index 1fffb8b83..e48100c59 100644 --- a/app/Models/StandalonePostgresql.php +++ b/app/Models/StandalonePostgresql.php @@ -4,12 +4,16 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\HasMany; -use App\Models\EnvironmentVariable; -use App\Models\LocalPersistentVolume; class StandalonePostgresql extends BaseModel { use HasFactory; + + protected $guarded = []; + protected $casts = [ + 'postgres_password' => 'encrypted', + ]; + protected static function booted() { static::created(function ($database) { @@ -23,29 +27,32 @@ protected static function booted() ]); }); } - protected $guarded = []; - protected $casts = [ - 'postgres_password' => 'encrypted', - ]; - public function type() { + + public function type() + { return 'standalone-postgresql'; } + public function environment() { return $this->belongsTo(Environment::class); } + public function destination() { return $this->morphTo(); } - public function environment_variables(): HasMany + + public function environment_variables(): HasMany { return $this->hasMany(EnvironmentVariable::class); } + public function runtime_environment_variables(): HasMany { return $this->hasMany(EnvironmentVariable::class); } + public function persistentStorages() { return $this->morphMany(LocalPersistentVolume::class, 'resource'); diff --git a/app/Models/Subscription.php b/app/Models/Subscription.php index 380660b77..89c4264cb 100644 --- a/app/Models/Subscription.php +++ b/app/Models/Subscription.php @@ -2,12 +2,12 @@ namespace App\Models; -use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Subscription extends Model { protected $guarded = []; + public function team() { return $this->belongsTo(Team::class); diff --git a/app/Models/SwarmDocker.php b/app/Models/SwarmDocker.php index b0f341b9b..ea56f85bc 100644 --- a/app/Models/SwarmDocker.php +++ b/app/Models/SwarmDocker.php @@ -8,6 +8,7 @@ public function applications() { return $this->morphMany(Application::class, 'destination'); } + public function server() { return $this->belongsTo(Server::class); diff --git a/app/Models/Team.php b/app/Models/Team.php index 331c969d7..c377ca955 100644 --- a/app/Models/Team.php +++ b/app/Models/Team.php @@ -2,13 +2,10 @@ namespace App\Models; -use App\Notifications\Channels\SendsEmail; use App\Notifications\Channels\SendsDiscord; -use Illuminate\Database\Eloquent\Builder; +use App\Notifications\Channels\SendsEmail; use Illuminate\Database\Eloquent\Model; use Illuminate\Notifications\Notifiable; -use Spatie\SchemalessAttributes\Casts\SchemalessAttributes; -use Spatie\SchemalessAttributes\SchemalessAttributesTrait; class Team extends Model implements SendsDiscord, SendsEmail { @@ -23,9 +20,10 @@ public function routeNotificationForDiscord() { return data_get($this, 'discord_webhook_url', null); } + public function getRecepients($notification) { - $recipients = data_get($notification,'emails',null); + $recipients = data_get($notification, 'emails', null); if (is_null($recipients)) { $recipients = $this->members()->pluck('email')->toArray(); return $recipients; @@ -33,10 +31,34 @@ public function getRecepients($notification) return explode(',', $recipients); } + public function members() + { + return $this->belongsToMany(User::class, 'team_user', 'team_id', 'user_id')->withPivot('role'); + } + public function subscription() { return $this->hasOne(Subscription::class); } + + public function applications() + { + return $this->hasManyThrough(Application::class, Project::class); + } + + public function invitations() + { + return $this->hasMany(TeamInvitation::class); + } + + public function isEmpty() + { + if ($this->projects()->count() === 0 && $this->servers()->count() === 0 && $this->privateKeys()->count() === 0 && $this->sources()->count() === 0) { + return true; + } + return false; + } + public function projects() { return $this->hasMany(Project::class); @@ -47,23 +69,11 @@ public function servers() return $this->hasMany(Server::class); } - public function applications() - { - return $this->hasManyThrough(Application::class, Project::class); - } - public function privateKeys() { return $this->hasMany(PrivateKey::class); } - public function members() - { - return $this->belongsToMany(User::class, 'team_user', 'team_id', 'user_id')->withPivot('role'); - } - public function invitations() - { - return $this->hasMany(TeamInvitation::class); - } + public function sources() { $sources = collect([]); @@ -73,11 +83,4 @@ public function sources() $sources = $sources->merge($github_apps)->merge($gitlab_apps); return $sources; } - public function isEmpty() - { - if ($this->projects()->count() === 0 && $this->servers()->count() === 0 && $this->privateKeys()->count() === 0 && $this->sources()->count() === 0) { - return true; - } - return false; - } -} \ No newline at end of file +} diff --git a/app/Models/TeamInvitation.php b/app/Models/TeamInvitation.php index c326d7d40..a5c382b3b 100644 --- a/app/Models/TeamInvitation.php +++ b/app/Models/TeamInvitation.php @@ -14,6 +14,7 @@ class TeamInvitation extends Model 'link', 'via', ]; + public function team() { return $this->belongsTo(Team::class); diff --git a/app/Models/User.php b/app/Models/User.php index d9f1eaa6a..47ed5a995 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -3,18 +3,17 @@ namespace App\Models; use App\Notifications\Channels\SendsEmail; +use App\Notifications\TrnsactionalEmails\ResetPassword; use Illuminate\Database\Eloquent\Factories\HasFactory; -use Illuminate\Database\Eloquent\Model; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; -use Laravel\Sanctum\HasApiTokens; -use Visus\Cuid2\Cuid2; use Laravel\Fortify\TwoFactorAuthenticatable; -use App\Notifications\TrnsactionalEmails\ResetPassword; +use Laravel\Sanctum\HasApiTokens; class User extends Authenticatable implements SendsEmail { use HasApiTokens, HasFactory, Notifiable, TwoFactorAuthenticatable; + protected $fillable = [ 'id', 'name', @@ -28,6 +27,7 @@ class User extends Authenticatable implements SendsEmail protected $casts = [ 'email_verified_at' => 'datetime', ]; + protected static function boot() { parent::boot(); @@ -44,18 +44,27 @@ protected static function boot() $user->teams()->attach($new_team, ['role' => 'owner']); }); } + + public function teams() + { + return $this->belongsToMany(Team::class)->withPivot('role'); + } + public function getRecepients($notification) { return $this->email; } + public function sendPasswordResetNotification($token): void { $this->notify(new ResetPassword($token)); } + public function isAdmin() { return $this->pivot->role === 'admin' || $this->pivot->role === 'owner'; } + public function isAdminFromSession() { if (auth()->user()->id === 0) { @@ -73,6 +82,7 @@ public function isAdminFromSession() $role = $teams->where('id', session('currentTeam')->id)->first()->pivot->role; return $role === 'admin' || $role === 'owner'; } + public function isInstanceAdmin() { $found_root_team = auth()->user()->teams->filter(function ($team) { @@ -83,18 +93,17 @@ public function isInstanceAdmin() }); return $found_root_team->count() > 0; } + public function personalTeam() { return $this->teams()->where('personal_team', true)->first(); } - public function teams() - { - return $this->belongsToMany(Team::class)->withPivot('role'); - } + public function currentTeam() { return $this->teams()->where('team_id', session('currentTeam')->id)->first(); } + public function otherTeams() { $team_id = session('currentTeam')->id; @@ -102,6 +111,7 @@ public function otherTeams() return $team->id != $team_id; }); } + public function role() { if ($this->teams()->where('team_id', 0)->first()) { @@ -109,10 +119,11 @@ public function role() } return $this->teams()->where('team_id', session('currentTeam')->id)->first()->pivot->role; } + public function resources() { $team_id = session('currentTeam')->id; $data = Application::where('team_id', $team_id)->get(); return $data; } -} \ No newline at end of file +} diff --git a/app/Models/Webhook.php b/app/Models/Webhook.php index 079b926be..308f17370 100644 --- a/app/Models/Webhook.php +++ b/app/Models/Webhook.php @@ -2,7 +2,6 @@ namespace App\Models; -use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Webhook extends Model @@ -11,4 +10,4 @@ class Webhook extends Model protected $casts = [ 'payload' => 'encrypted', ]; -} \ No newline at end of file +} diff --git a/app/Notifications/Application/DeploymentFailed.php b/app/Notifications/Application/DeploymentFailed.php index 053f432eb..bc7f5dfde 100644 --- a/app/Notifications/Application/DeploymentFailed.php +++ b/app/Notifications/Application/DeploymentFailed.php @@ -4,9 +4,8 @@ use App\Models\Application; use App\Models\ApplicationPreview; -use App\Models\Team; -use App\Notifications\Channels\EmailChannel; use App\Notifications\Channels\DiscordChannel; +use App\Notifications\Channels\EmailChannel; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -16,6 +15,7 @@ class DeploymentFailed extends Notification implements ShouldQueue { use Queueable; + public Application $application; public string $deployment_uuid; public ApplicationPreview|null $preview; @@ -38,8 +38,9 @@ public function __construct(Application $application, string $deployment_uuid, A if (Str::of($this->fqdn)->explode(',')->count() > 1) { $this->fqdn = Str::of($this->fqdn)->explode(',')->first(); } - $this->deployment_url = base_url() . "/project/{$this->project_uuid}/{$this->environment_name}/application/{$this->application->uuid}/deployment/{$this->deployment_uuid}"; + $this->deployment_url = base_url() . "/project/{$this->project_uuid}/{$this->environment_name}/application/{$this->application->uuid}/deployment/{$this->deployment_uuid}"; } + public function via(object $notifiable): array { $channels = []; @@ -56,6 +57,7 @@ public function via(object $notifiable): array } return $channels; } + public function toMail(): MailMessage { $mail = new MailMessage(); @@ -88,4 +90,4 @@ public function toDiscord(): string } return $message; } -} \ No newline at end of file +} diff --git a/app/Notifications/Application/DeploymentSuccess.php b/app/Notifications/Application/DeploymentSuccess.php index 1821a1bde..99bd2532c 100644 --- a/app/Notifications/Application/DeploymentSuccess.php +++ b/app/Notifications/Application/DeploymentSuccess.php @@ -4,9 +4,8 @@ use App\Models\Application; use App\Models\ApplicationPreview; -use App\Models\Team; -use App\Notifications\Channels\EmailChannel; use App\Notifications\Channels\DiscordChannel; +use App\Notifications\Channels\EmailChannel; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -16,6 +15,7 @@ class DeploymentSuccess extends Notification implements ShouldQueue { use Queueable; + public Application $application; public string $deployment_uuid; public ApplicationPreview|null $preview = null; @@ -38,8 +38,9 @@ public function __construct(Application $application, string $deployment_uuid, A if (Str::of($this->fqdn)->explode(',')->count() > 1) { $this->fqdn = Str::of($this->fqdn)->explode(',')->first(); } - $this->deployment_url = base_url() . "/project/{$this->project_uuid}/{$this->environment_name}/application/{$this->application->uuid}/deployment/{$this->deployment_uuid}"; + $this->deployment_url = base_url() . "/project/{$this->project_uuid}/{$this->environment_name}/application/{$this->application->uuid}/deployment/{$this->deployment_uuid}"; } + public function via(object $notifiable): array { $channels = []; @@ -56,6 +57,7 @@ public function via(object $notifiable): array } return $channels; } + public function toMail(): MailMessage { $mail = new MailMessage(); @@ -97,4 +99,4 @@ public function toDiscord(): string } return $message; } -} \ No newline at end of file +} diff --git a/app/Notifications/Application/StatusChanged.php b/app/Notifications/Application/StatusChanged.php index 4fb279d44..9c6b99fc7 100644 --- a/app/Notifications/Application/StatusChanged.php +++ b/app/Notifications/Application/StatusChanged.php @@ -2,10 +2,8 @@ namespace App\Notifications\Application; -use App\Models\Application; -use App\Models\ApplicationPreview; -use App\Notifications\Channels\EmailChannel; use App\Notifications\Channels\DiscordChannel; +use App\Notifications\Channels\EmailChannel; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -15,6 +13,7 @@ class StatusChanged extends Notification implements ShouldQueue { use Queueable; + public $application; public string $application_name; @@ -33,8 +32,9 @@ public function __construct($application) if (Str::of($this->fqdn)->explode(',')->count() > 1) { $this->fqdn = Str::of($this->fqdn)->explode(',')->first(); } - $this->application_url = base_url() . "/project/{$this->project_uuid}/{$this->environment_name}/application/{$this->application->uuid}"; + $this->application_url = base_url() . "/project/{$this->project_uuid}/{$this->environment_name}/application/{$this->application->uuid}"; } + public function via(object $notifiable): array { $channels = []; @@ -51,6 +51,7 @@ public function via(object $notifiable): array } return $channels; } + public function toMail(): MailMessage { $mail = new MailMessage(); @@ -72,4 +73,4 @@ public function toDiscord(): string $message .= '[Application URL](' . $this->application_url . ')'; return $message; } -} \ No newline at end of file +} diff --git a/app/Notifications/Channels/EmailChannel.php b/app/Notifications/Channels/EmailChannel.php index 22b5e59a0..044bb9b07 100644 --- a/app/Notifications/Channels/EmailChannel.php +++ b/app/Notifications/Channels/EmailChannel.php @@ -22,7 +22,7 @@ public function send(SendsEmail $notifiable, Notification $notification): void Mail::send( [], [], - fn (Message $message) => $message + fn(Message $message) => $message ->from( data_get($notifiable, 'smtp_from_address'), data_get($notifiable, 'smtp_from_name'), @@ -50,4 +50,4 @@ private function bootConfigs($notifiable): void "local_domain" => null, ]); } -} \ No newline at end of file +} diff --git a/app/Notifications/Channels/TransactionalEmailChannel.php b/app/Notifications/Channels/TransactionalEmailChannel.php index 848bb1bc8..3d5328f81 100644 --- a/app/Notifications/Channels/TransactionalEmailChannel.php +++ b/app/Notifications/Channels/TransactionalEmailChannel.php @@ -25,7 +25,7 @@ public function send(User $notifiable, Notification $notification): void Mail::send( [], [], - fn (Message $message) => $message + fn(Message $message) => $message ->from( data_get($settings, 'smtp_from_address'), data_get($settings, 'smtp_from_name') @@ -40,4 +40,4 @@ private function bootConfigs(): void { set_transanctional_email_settings(); } -} \ No newline at end of file +} diff --git a/app/Notifications/Test.php b/app/Notifications/Test.php index c7fc9f714..4cec28cfd 100644 --- a/app/Notifications/Test.php +++ b/app/Notifications/Test.php @@ -2,8 +2,8 @@ namespace App\Notifications; -use App\Notifications\Channels\EmailChannel; use App\Notifications\Channels\DiscordChannel; +use App\Notifications\Channels\EmailChannel; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -12,8 +12,10 @@ class Test extends Notification implements ShouldQueue { use Queueable; + public function __construct(public string|null $emails = null) - {} + { + } public function via(object $notifiable): array { @@ -30,6 +32,7 @@ public function via(object $notifiable): array } return $channels; } + public function toMail(): MailMessage { $mail = new MailMessage(); @@ -37,6 +40,7 @@ public function toMail(): MailMessage $mail->view('emails.test'); return $mail; } + public function toDiscord(): string { $message = 'This is a test Discord notification from Coolify.'; @@ -44,4 +48,4 @@ public function toDiscord(): string $message .= '[Go to your dashboard](' . base_url() . ')'; return $message; } -} \ No newline at end of file +} diff --git a/app/Notifications/TransactionalEmails/InvitationLink.php b/app/Notifications/TransactionalEmails/InvitationLink.php index 7785f92cc..f08c36fbc 100644 --- a/app/Notifications/TransactionalEmails/InvitationLink.php +++ b/app/Notifications/TransactionalEmails/InvitationLink.php @@ -14,6 +14,7 @@ class InvitationLink extends Notification implements ShouldQueue { use Queueable; + public function via() { return [TransactionalEmailChannel::class]; @@ -33,4 +34,4 @@ public function toMail(User $user): MailMessage ]); return $mail; } -} \ No newline at end of file +} diff --git a/app/Notifications/TransactionalEmails/ResetPassword.php b/app/Notifications/TransactionalEmails/ResetPassword.php index 856d5b697..816c1a671 100644 --- a/app/Notifications/TransactionalEmails/ResetPassword.php +++ b/app/Notifications/TransactionalEmails/ResetPassword.php @@ -2,26 +2,36 @@ namespace App\Notifications\TransactionalEmails; +use App\Models\InstanceSettings; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Notification; -use Illuminate\Support\Facades\Lang; -use App\Models\InstanceSettings; class ResetPassword extends Notification { - public $token; - public InstanceSettings $settings; public static $createUrlCallback; public static $toMailCallback; + public $token; + public InstanceSettings $settings; public function __construct($token) { $this->settings = InstanceSettings::get(); $this->token = $token; } + + public static function createUrlUsing($callback) + { + static::$createUrlCallback = $callback; + } + + public static function toMailUsing($callback) + { + static::$toMailCallback = $callback; + } + public function via($notifiable) { - if ($this->settings->smtp_enabled){ + if ($this->settings->smtp_enabled) { $password = data_get($this->settings, 'smtp_password'); if ($password) $password = decrypt($password); @@ -50,6 +60,7 @@ public function toMail($notifiable) return $this->buildMailMessage($this->resetUrl($notifiable)); } + protected function buildMailMessage($url) { $mail = new MailMessage(); @@ -58,9 +69,10 @@ protected function buildMailMessage($url) data_get($this->settings, 'smtp_from_name'), ); $mail->subject('Reset Password'); - $mail->view('emails.reset-password', ['url' => $url,'count' => config('auth.passwords.'.config('auth.defaults.passwords').'.expire')]); + $mail->view('emails.reset-password', ['url' => $url, 'count' => config('auth.passwords.' . config('auth.defaults.passwords') . '.expire')]); return $mail; } + protected function resetUrl($notifiable) { if (static::$createUrlCallback) { @@ -72,12 +84,4 @@ protected function resetUrl($notifiable) 'email' => $notifiable->getEmailForPasswordReset(), ], false)); } - public static function createUrlUsing($callback) - { - static::$createUrlCallback = $callback; - } - public static function toMailUsing($callback) - { - static::$toMailCallback = $callback; - } -} \ No newline at end of file +} diff --git a/app/Notifications/TransactionalEmails/Test.php b/app/Notifications/TransactionalEmails/Test.php index a07130ad2..f5962fc2a 100644 --- a/app/Notifications/TransactionalEmails/Test.php +++ b/app/Notifications/TransactionalEmails/Test.php @@ -13,7 +13,8 @@ class Test extends Notification implements ShouldQueue use Queueable; public function __construct(public string $emails) - {} + { + } public function via(): array { @@ -27,4 +28,4 @@ public function toMail(): MailMessage $mail->view('emails.test'); return $mail; } -} \ No newline at end of file +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index b8c70b770..07d02cd03 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,7 +2,6 @@ namespace App\Providers; -use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Http; use Illuminate\Support\ServiceProvider; diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 2d65aac0e..87c58d172 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -5,7 +5,6 @@ use Illuminate\Auth\Events\Registered; use Illuminate\Auth\Listeners\SendEmailVerificationNotification; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; -use Illuminate\Support\Facades\Event; class EventServiceProvider extends ServiceProvider { diff --git a/app/Providers/FortifyServiceProvider.php b/app/Providers/FortifyServiceProvider.php index 0a3d02ff7..b3e67c255 100644 --- a/app/Providers/FortifyServiceProvider.php +++ b/app/Providers/FortifyServiceProvider.php @@ -23,8 +23,7 @@ class FortifyServiceProvider extends ServiceProvider */ public function register(): void { - $this->app->instance(RegisterResponse::class, new class implements RegisterResponse - { + $this->app->instance(RegisterResponse::class, new class implements RegisterResponse { public function toResponse($request) { // First user (root) will be redirected to /settings instead of / on registration. @@ -92,7 +91,7 @@ public function boot(): void }); RateLimiter::for('login', function (Request $request) { - $email = (string) $request->email; + $email = (string)$request->email; return Limit::perMinute(5)->by($email . $request->ip()); }); diff --git a/app/Traits/ExecuteRemoteCommand.php b/app/Traits/ExecuteRemoteCommand.php index 6e8c5b761..24e17a73d 100644 --- a/app/Traits/ExecuteRemoteCommand.php +++ b/app/Traits/ExecuteRemoteCommand.php @@ -3,7 +3,6 @@ namespace App\Traits; use App\Enums\ApplicationDeploymentStatus; -use App\Models\ApplicationDeploymentQueue; use App\Models\Server; use Carbon\Carbon; use Illuminate\Support\Collection; @@ -13,6 +12,7 @@ trait ExecuteRemoteCommand { public string|null $save = null; + public function execute_remote_command(...$commands) { static::$batch_counter++; diff --git a/app/View/Components/Forms/Button.php b/app/View/Components/Forms/Button.php index faa2632b7..e4df04cf6 100644 --- a/app/View/Components/Forms/Button.php +++ b/app/View/Components/Forms/Button.php @@ -12,12 +12,13 @@ class Button extends Component * Create a new component instance. */ public function __construct( - public bool $disabled = false, - public bool $isModal = false, - public bool $noStyle = false, + public bool $disabled = false, + public bool $isModal = false, + public bool $noStyle = false, public string|null $modalId = null, - public string $defaultClass = "btn btn-primary btn-sm font-normal text-white normal-case no-animation rounded border-none" - ) { + public string $defaultClass = "btn btn-primary btn-sm font-normal text-white normal-case no-animation rounded border-none" + ) + { if ($this->noStyle) { $this->defaultClass = ""; } @@ -30,4 +31,4 @@ public function render(): View|Closure|string { return view('components.forms.button'); } -} \ No newline at end of file +} diff --git a/app/View/Components/Forms/Checkbox.php b/app/View/Components/Forms/Checkbox.php index b79066775..e730266a3 100644 --- a/app/View/Components/Forms/Checkbox.php +++ b/app/View/Components/Forms/Checkbox.php @@ -17,10 +17,11 @@ public function __construct( public string|null $value = null, public string|null $label = null, public string|null $helper = null, - public bool $instantSave = false, - public bool $disabled = false, - public string $defaultClass = "toggle toggle-xs toggle-warning rounded disabled:bg-coolgray-200 disabled:opacity-50 placeholder:text-neutral-700" - ) { + public bool $instantSave = false, + public bool $disabled = false, + public string $defaultClass = "toggle toggle-xs toggle-warning rounded disabled:bg-coolgray-200 disabled:opacity-50 placeholder:text-neutral-700" + ) + { // } diff --git a/app/View/Components/Forms/Input.php b/app/View/Components/Forms/Input.php index 1e517ea3f..c74bfa2ec 100644 --- a/app/View/Components/Forms/Input.php +++ b/app/View/Components/Forms/Input.php @@ -6,7 +6,6 @@ use Illuminate\Contracts\View\View; use Illuminate\View\Component; use Visus\Cuid2\Cuid2; -use Illuminate\Support\Str; class Input extends Component { @@ -16,13 +15,14 @@ public function __construct( public string|null $type = 'text', public string|null $value = null, public string|null $label = null, - public bool $required = false, - public bool $disabled = false, - public bool $readonly = false, + public bool $required = false, + public bool $disabled = false, + public bool $readonly = false, public string|null $helper = null, - public bool $allowToPeak = true, - public string $defaultClass = "input input-sm bg-coolgray-200 rounded text-white w-full disabled:bg-coolgray-200/50 disabled:border-none placeholder:text-coolgray-500" - ) { + public bool $allowToPeak = true, + public string $defaultClass = "input input-sm bg-coolgray-200 rounded text-white w-full disabled:bg-coolgray-200/50 disabled:border-none placeholder:text-coolgray-500" + ) + { } public function render(): View|Closure|string @@ -33,4 +33,4 @@ public function render(): View|Closure|string // $this->label = Str::title($this->label); return view('components.forms.input'); } -} \ No newline at end of file +} diff --git a/app/View/Components/Forms/Select.php b/app/View/Components/Forms/Select.php index 8dfd43582..f74cd3109 100644 --- a/app/View/Components/Forms/Select.php +++ b/app/View/Components/Forms/Select.php @@ -4,9 +4,9 @@ use Closure; use Illuminate\Contracts\View\View; +use Illuminate\Support\Str; use Illuminate\View\Component; use Visus\Cuid2\Cuid2; -use Illuminate\Support\Str; class Select extends Component { @@ -18,9 +18,10 @@ public function __construct( public string|null $name = null, public string|null $label = null, public string|null $helper = null, - public bool $required = false, - public string $defaultClass = "select select-sm w-full rounded text-white text-sm bg-coolgray-200 font-normal disabled:bg-coolgray-200/50 disabled:border-none" - ) { + public bool $required = false, + public string $defaultClass = "select select-sm w-full rounded text-white text-sm bg-coolgray-200 font-normal disabled:bg-coolgray-200/50 disabled:border-none" + ) + { // } diff --git a/app/View/Components/Forms/Textarea.php b/app/View/Components/Forms/Textarea.php index f4d1f0bee..5a017c56b 100644 --- a/app/View/Components/Forms/Textarea.php +++ b/app/View/Components/Forms/Textarea.php @@ -4,9 +4,9 @@ use Closure; use Illuminate\Contracts\View\View; +use Illuminate\Support\Str; use Illuminate\View\Component; use Visus\Cuid2\Cuid2; -use Illuminate\Support\Str; class Textarea extends Component { @@ -20,12 +20,13 @@ public function __construct( public string|null $value = null, public string|null $label = null, public string|null $placeholder = null, - public bool $required = false, - public bool $disabled = false, - public bool $readonly = false, + public bool $required = false, + public bool $disabled = false, + public bool $readonly = false, public string|null $helper = null, - public string $defaultClass = "textarea bg-coolgray-200 rounded text-white scrollbar disabled:bg-coolgray-200/50 disabled:border-none" - ) { + public string $defaultClass = "textarea bg-coolgray-200 rounded text-white scrollbar disabled:bg-coolgray-200/50 disabled:border-none" + ) + { // } diff --git a/app/View/Components/Modal.php b/app/View/Components/Modal.php index 22c5a7bba..0b7d66dae 100644 --- a/app/View/Components/Modal.php +++ b/app/View/Components/Modal.php @@ -5,7 +5,6 @@ use Closure; use Illuminate\Contracts\View\View; use Illuminate\View\Component; -use Visus\Cuid2\Cuid2; class Modal extends Component { @@ -13,13 +12,14 @@ class Modal extends Component * Create a new component instance. */ public function __construct( - public string $modalId, + public string $modalId, public string|null $modalTitle = null, public string|null $modalBody = null, public string|null $modalSubmit = null, - public bool $yesOrNo = false, - public string $action = 'delete' - ) { + public bool $yesOrNo = false, + public string $action = 'delete' + ) + { // } @@ -30,4 +30,4 @@ public function render(): View|Closure|string { return view('components.modal'); } -} \ No newline at end of file +} diff --git a/bootstrap/app.php b/bootstrap/app.php index 55afdbffb..037e17df0 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -11,8 +11,6 @@ | */ -use Illuminate\Support\Facades\Artisan; - $app = new Illuminate\Foundation\Application( $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__) ); diff --git a/bootstrap/helpers/applications.php b/bootstrap/helpers/applications.php index fa57cebde..f1b4d9104 100644 --- a/bootstrap/helpers/applications.php +++ b/bootstrap/helpers/applications.php @@ -16,7 +16,7 @@ function queue_application_deployment(int $application_id, string $deployment_uu ]); $queued_deployments = ApplicationDeploymentQueue::where('application_id', $application_id)->where('status', 'queued')->get()->sortByDesc('created_at'); $running_deployments = ApplicationDeploymentQueue::where('application_id', $application_id)->where('status', 'in_progress')->get()->sortByDesc('created_at'); - ray('Q:' . $queued_deployments->count() . 'R:' . $running_deployments->count() . '| Queuing deployment: ' . $deployment_uuid . ' of applicationID: ' . $application_id . ' pull request: ' . $pull_request_id . ' with commit: ' . $commit . ' and is it forced: ' . $force_rebuild); + ray('Q:' . $queued_deployments->count() . 'R:' . $running_deployments->count() . '| Queuing deployment: ' . $deployment_uuid . ' of applicationID: ' . $application_id . ' pull request: ' . $pull_request_id . ' with commit: ' . $commit . ' and is it forced: ' . $force_rebuild); if ($queued_deployments->count() > 1) { $queued_deployments = $queued_deployments->skip(1); $queued_deployments->each(function ($queued_deployment, $key) { diff --git a/bootstrap/helpers/docker.php b/bootstrap/helpers/docker.php index a8bd2a2f7..18882647b 100644 --- a/bootstrap/helpers/docker.php +++ b/bootstrap/helpers/docker.php @@ -8,15 +8,16 @@ function format_docker_command_output_to_json($rawOutput): Collection $outputLines = explode(PHP_EOL, $rawOutput); return collect($outputLines) - ->reject(fn ($line) => empty($line)) - ->map(fn ($outputLine) => json_decode($outputLine, true, flags: JSON_THROW_ON_ERROR)); + ->reject(fn($line) => empty($line)) + ->map(fn($outputLine) => json_decode($outputLine, true, flags: JSON_THROW_ON_ERROR)); } + function format_docker_labels_to_json($rawOutput): Collection { $outputLines = explode(PHP_EOL, $rawOutput); return collect($outputLines) - ->reject(fn ($line) => empty($line)) + ->reject(fn($line) => empty($line)) ->map(function ($outputLine) { $outputArray = explode(',', $outputLine); return collect($outputArray) diff --git a/bootstrap/helpers/github.php b/bootstrap/helpers/github.php index 8d18e6290..5c36f091d 100644 --- a/bootstrap/helpers/github.php +++ b/bootstrap/helpers/github.php @@ -3,8 +3,8 @@ use App\Models\GithubApp; use App\Models\GitlabApp; use Carbon\Carbon; -use Illuminate\Support\Str; use Illuminate\Support\Facades\Http; +use Illuminate\Support\Str; use Lcobucci\JWT\Encoding\ChainedFormatter; use Lcobucci\JWT\Encoding\JoseEncoder; use Lcobucci\JWT\Signer\Key\InMemory; @@ -33,6 +33,7 @@ function generate_github_installation_token(GithubApp $source) } return $token->json()['token']; } + function generate_github_jwt_token(GithubApp $source) { $signingKey = InMemory::plainText($source->privateKey->private_key); @@ -65,7 +66,7 @@ function git_api(GithubApp|GitlabApp $source, string $endpoint, string $method = } $json = $response->json(); if ($response->failed() && $throwError) { - throw new \Exception("Failed to get data from {$source->name} with error:

" . $json['message'] . "

Rate Limit resets at: " . Carbon::parse((int)$response->header('X-RateLimit-Reset'))->format('Y-m-d H:i:s') . 'UTC'); + throw new \Exception("Failed to get data from {$source->name} with error:

" . $json['message'] . "

Rate Limit resets at: " . Carbon::parse((int)$response->header('X-RateLimit-Reset'))->format('Y-m-d H:i:s') . 'UTC'); } return [ 'rate_limit_remaining' => $response->header('X-RateLimit-Remaining'), @@ -73,6 +74,7 @@ function git_api(GithubApp|GitlabApp $source, string $endpoint, string $method = 'data' => collect($json) ]; } + function get_installation_path(GithubApp $source) { $github = GithubApp::where('uuid', $source->uuid)->first(); diff --git a/bootstrap/helpers/proxy.php b/bootstrap/helpers/proxy.php index 9d2cc7e45..1ae747686 100644 --- a/bootstrap/helpers/proxy.php +++ b/bootstrap/helpers/proxy.php @@ -1,15 +1,15 @@ - [ - 'routers' => [ - 'catchall' => - [ - 'entryPoints' => [ - 0 => 'http', - 1 => 'https', - ], - 'service' => 'noop', - 'rule' => "HostRegexp(`{catchall:.*}`)", - 'priority' => 1, - 'middlewares' => [ - 0 => 'redirect-regexp@file', - ], - ], - ], - 'services' => - [ - 'noop' => - [ - 'loadBalancer' => + 'routers' => [ - 'servers' => - [ - 0 => + 'catchall' => [ - 'url' => '', + 'entryPoints' => [ + 0 => 'http', + 1 => 'https', + ], + 'service' => 'noop', + 'rule' => "HostRegexp(`{catchall:.*}`)", + 'priority' => 1, + 'middlewares' => [ + 0 => 'redirect-regexp@file', + ], ], - ], ], - ], - ], - 'middlewares' => - [ - 'redirect-regexp' => - [ - 'redirectRegex' => + 'services' => [ - 'regex' => '(.*)', - 'replacement' => $redirect_url, - 'permanent' => false, + 'noop' => + [ + 'loadBalancer' => + [ + 'servers' => + [ + 0 => + [ + 'url' => '', + ], + ], + ], + ], + ], + 'middlewares' => + [ + 'redirect-regexp' => + [ + 'redirectRegex' => + [ + 'regex' => '(.*)', + 'replacement' => $redirect_url, + 'permanent' => false, + ], + ], ], - ], ], - ], ]; $yaml = Yaml::dump($traefik_dynamic_conf, 12, 2); $yaml = @@ -167,4 +168,4 @@ function setup_default_redirect_404(string|null $redirect_url, Server $server) ray($yaml); } } -} \ No newline at end of file +} diff --git a/bootstrap/helpers/remoteProcess.php b/bootstrap/helpers/remoteProcess.php index 93d48d77a..422b9c2ee 100644 --- a/bootstrap/helpers/remoteProcess.php +++ b/bootstrap/helpers/remoteProcess.php @@ -23,11 +23,12 @@ function remote_process( array $command, Server $server, - string $type = ActivityTypes::INLINE->value, + string $type = ActivityTypes::INLINE->value, ?string $type_uuid = null, ?Model $model = null, bool $ignore_errors = false, -): Activity { +): Activity +{ $command_string = implode("\n", $command); if (auth()->user()) { @@ -55,11 +56,13 @@ function remote_process( ), ])(); } + function get_private_key_for_server(Server $server) { $temp_file = "id.root@{$server->ip}"; return '/var/www/html/storage/app/ssh/keys/' . $temp_file; } + function save_private_key_for_server(Server $server) { if (data_get($server, 'privateKey.private_key') === null) { @@ -138,10 +141,10 @@ function decode_remote_command_output(?ApplicationDeploymentQueue $application_d } $formatted = collect($decoded); if (!$is_debug_enabled) { - $formatted = $formatted->filter(fn ($i) => $i['hidden'] === false ?? false); + $formatted = $formatted->filter(fn($i) => $i['hidden'] === false ?? false); } $formatted = $formatted - ->sortBy(fn ($i) => $i['order']) + ->sortBy(fn($i) => $i['order']) ->map(function ($i) { $i['timestamp'] = Carbon::parse($i['timestamp'])->format('Y-M-d H:i:s.u'); return $i; diff --git a/bootstrap/helpers/s3.php b/bootstrap/helpers/s3.php index 12f53cd02..4a2252016 100644 --- a/bootstrap/helpers/s3.php +++ b/bootstrap/helpers/s3.php @@ -3,20 +3,21 @@ use App\Models\S3Storage; use Illuminate\Support\Str; -function set_s3_target(S3Storage $s3) { +function set_s3_target(S3Storage $s3) +{ $is_digital_ocean = false; if ($s3->endpoint) { - $is_digital_ocean = Str::contains($s3->endpoint,'digitaloceanspaces.com'); + $is_digital_ocean = Str::contains($s3->endpoint, 'digitaloceanspaces.com'); } config()->set('filesystems.disks.custom-s3', [ - 'driver' => 's3', - 'region' => $s3['region'], - 'key' => $s3['key'], - 'secret' => $s3['secret'], - 'bucket' => $s3['bucket'], - 'endpoint' => $s3['endpoint'], - 'use_path_style_endpoint' => true, - 'bucket_endpoint' => $is_digital_ocean, - 'aws_url' => $s3->awsUrl(), + 'driver' => 's3', + 'region' => $s3['region'], + 'key' => $s3['key'], + 'secret' => $s3['secret'], + 'bucket' => $s3['bucket'], + 'endpoint' => $s3['endpoint'], + 'use_path_style_endpoint' => true, + 'bucket_endpoint' => $is_digital_ocean, + 'aws_url' => $s3->awsUrl(), ]); -} \ No newline at end of file +} diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index 69cfe6f4b..2954c37eb 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -4,9 +4,8 @@ use Illuminate\Database\QueryException; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Route; -use Illuminate\Support\Facades\URL; -use Visus\Cuid2\Cuid2; use Illuminate\Support\Str; +use Visus\Cuid2\Cuid2; function general_error_handler(\Throwable|null $err = null, $that = null, $isJson = false, $customErrorMessage = null) { @@ -62,6 +61,7 @@ function generate_random_name() $cuid = new Cuid2(7); return Str::kebab("{$generator->getName()}-{$cuid}"); } + function generate_application_name(string $git_repository, string $git_branch) { $cuid = new Cuid2(7); @@ -91,6 +91,7 @@ function set_transanctional_email_settings() "local_domain" => null, ]); } + function base_ip() { if (isDev()) { @@ -99,6 +100,7 @@ function base_ip() $settings = InstanceSettings::get(); return "http://{$settings->public_ipv4}"; } + function base_url(bool $withPort = true) { $settings = InstanceSettings::get(); @@ -131,7 +133,8 @@ function isDev() { return config('app.env') === 'local'; } + function isCloud() { return !config('coolify.self_hosted'); -} \ No newline at end of file +} diff --git a/bootstrap/helpers/subscriptions.php b/bootstrap/helpers/subscriptions.php index 1a5fc5ffe..8383bc51b 100644 --- a/bootstrap/helpers/subscriptions.php +++ b/bootstrap/helpers/subscriptions.php @@ -27,18 +27,22 @@ function getSubscriptionLink($id) } return $url; } + function getPaymentLink() { return auth()->user()->currentTeam()->subscription->lemon_update_payment_menthod_url; } + function getRenewDate() { return Carbon::parse(auth()->user()->currentTeam()->subscription->lemon_renews_at)->format('Y-M-d H:i:s'); } + function getEndDate() { return Carbon::parse(auth()->user()->currentTeam()->subscription->lemon_renews_at)->format('Y-M-d H:i:s'); } + function isSubscribed() { return diff --git a/config/app.php b/config/app.php index 78df1ec8a..690029fd6 100644 --- a/config/app.php +++ b/config/app.php @@ -43,7 +43,7 @@ | */ - 'debug' => (bool) env('APP_DEBUG', false), + 'debug' => (bool)env('APP_DEBUG', false), /* |-------------------------------------------------------------------------- diff --git a/config/broadcasting.php b/config/broadcasting.php index 9e4d4aa44..4dbd22c7e 100644 --- a/config/broadcasting.php +++ b/config/broadcasting.php @@ -36,7 +36,7 @@ 'secret' => env('PUSHER_APP_SECRET'), 'app_id' => env('PUSHER_APP_ID'), 'options' => [ - 'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com', + 'host' => env('PUSHER_HOST') ?: 'api-' . env('PUSHER_APP_CLUSTER', 'mt1') . '.pusher.com', 'port' => env('PUSHER_PORT', 443), 'scheme' => env('PUSHER_SCHEME', 'https'), 'encrypted' => true, diff --git a/config/logging.php b/config/logging.php index 4c3df4ce1..a97262cb3 100644 --- a/config/logging.php +++ b/config/logging.php @@ -85,7 +85,7 @@ 'handler_with' => [ 'host' => env('PAPERTRAIL_URL'), 'port' => env('PAPERTRAIL_PORT'), - 'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'), + 'connectionString' => 'tls://' . env('PAPERTRAIL_URL') . ':' . env('PAPERTRAIL_PORT'), ], ], diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index 31ddf8720..d874cd9dc 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -30,7 +30,7 @@ public function definition(): array */ public function unverified(): static { - return $this->state(fn (array $attributes) => [ + return $this->state(fn(array $attributes) => [ 'email_verified_at' => null, ]); } diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index 321128a8f..2b909d2e2 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php b/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php index 81a7229b0..1bc0eeeae 100644 --- a/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php +++ b/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php b/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php index 5cc9f78b1..eb46a82cc 100644 --- a/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php +++ b/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php @@ -5,8 +5,7 @@ use Illuminate\Support\Facades\Schema; use Laravel\Fortify\Fortify; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ @@ -14,17 +13,17 @@ public function up(): void { Schema::table('users', function (Blueprint $table) { $table->text('two_factor_secret') - ->after('password') - ->nullable(); + ->after('password') + ->nullable(); $table->text('two_factor_recovery_codes') - ->after('two_factor_secret') - ->nullable(); + ->after('two_factor_secret') + ->nullable(); if (Fortify::confirmsTwoFactorAuthentication()) { $table->timestamp('two_factor_confirmed_at') - ->after('two_factor_recovery_codes') - ->nullable(); + ->after('two_factor_recovery_codes') + ->nullable(); } }); } diff --git a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php index 954f7518f..5f7e6b53d 100644 --- a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php +++ b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_03_20_112410_create_activity_log_table.php b/database/migrations/2023_03_20_112410_create_activity_log_table.php index a6fa05393..c94274b31 100755 --- a/database/migrations/2023_03_20_112410_create_activity_log_table.php +++ b/database/migrations/2023_03_20_112410_create_activity_log_table.php @@ -1,8 +1,8 @@ string('wildcard_domain')->nullable(); }); } -}; \ No newline at end of file +}; diff --git a/database/migrations/2023_06_23_110548_next_channel_updates.php b/database/migrations/2023_06_23_110548_next_channel_updates.php index 83c4dacf3..1c2f705b9 100644 --- a/database/migrations/2023_06_23_110548_next_channel_updates.php +++ b/database/migrations/2023_06_23_110548_next_channel_updates.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_06_23_114131_change_env_var_value_length.php b/database/migrations/2023_06_23_114131_change_env_var_value_length.php index ca8bd1e0c..2b0a6e159 100644 --- a/database/migrations/2023_06_23_114131_change_env_var_value_length.php +++ b/database/migrations/2023_06_23_114131_change_env_var_value_length.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_06_23_114132_remove_default_redirect_from_instance_settings.php b/database/migrations/2023_06_23_114132_remove_default_redirect_from_instance_settings.php index 9c14b7c39..66d02e642 100644 --- a/database/migrations/2023_06_23_114132_remove_default_redirect_from_instance_settings.php +++ b/database/migrations/2023_06_23_114132_remove_default_redirect_from_instance_settings.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_06_23_114133_use_application_deployment_queues_as_activity.php b/database/migrations/2023_06_23_114133_use_application_deployment_queues_as_activity.php index 642184abc..440eca662 100644 --- a/database/migrations/2023_06_23_114133_use_application_deployment_queues_as_activity.php +++ b/database/migrations/2023_06_23_114133_use_application_deployment_queues_as_activity.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ @@ -27,4 +26,4 @@ public function down(): void $table->dropColumn('current_process_id'); }); } -}; \ No newline at end of file +}; diff --git a/database/migrations/2023_06_23_114134_add_disk_usage_percentage_to_servers.php b/database/migrations/2023_06_23_114134_add_disk_usage_percentage_to_servers.php index d2b0f892c..09e9a6093 100644 --- a/database/migrations/2023_06_23_114134_add_disk_usage_percentage_to_servers.php +++ b/database/migrations/2023_06_23_114134_add_disk_usage_percentage_to_servers.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ @@ -25,4 +24,4 @@ public function down(): void $table->dropColumn('cleanup_after_percentage'); }); } -}; \ No newline at end of file +}; diff --git a/database/migrations/2023_07_13_115117_create_subscriptions_table.php b/database/migrations/2023_07_13_115117_create_subscriptions_table.php index 08aeaaa17..5745c29e2 100644 --- a/database/migrations/2023_07_13_115117_create_subscriptions_table.php +++ b/database/migrations/2023_07_13_115117_create_subscriptions_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ @@ -36,4 +35,4 @@ public function down(): void { Schema::dropIfExists('subscriptions'); } -}; \ No newline at end of file +}; diff --git a/database/migrations/2023_07_13_120719_create_webhooks_table.php b/database/migrations/2023_07_13_120719_create_webhooks_table.php index 9376a10c9..f53d280c1 100644 --- a/database/migrations/2023_07_13_120719_create_webhooks_table.php +++ b/database/migrations/2023_07_13_120719_create_webhooks_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_07_13_120721_add_license_to_instance_settings.php b/database/migrations/2023_07_13_120721_add_license_to_instance_settings.php index c32cd0f9a..6ecd5d971 100644 --- a/database/migrations/2023_07_13_120721_add_license_to_instance_settings.php +++ b/database/migrations/2023_07_13_120721_add_license_to_instance_settings.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_07_27_182013_smtp_discord_schemaless_to_normal.php b/database/migrations/2023_07_27_182013_smtp_discord_schemaless_to_normal.php index 2faa9f9ba..207d5e081 100644 --- a/database/migrations/2023_07_27_182013_smtp_discord_schemaless_to_normal.php +++ b/database/migrations/2023_07_27_182013_smtp_discord_schemaless_to_normal.php @@ -1,13 +1,12 @@ boolean('discord_notifications_status_changes')->default(true); }); $teams = Team::all(); - foreach($teams as $team) { + foreach ($teams as $team) { $team->smtp_enabled = data_get($team, 'smtp.enabled', false); $team->smtp_from_address = data_get($team, 'smtp.from_address'); $team->smtp_from_name = data_get($team, 'smtp.from_name'); @@ -46,15 +45,15 @@ public function up(): void $team->smtp_username = data_get($team, 'smtp.username'); $team->smtp_password = data_get($team, 'smtp.password'); $team->smtp_timeout = data_get($team, 'smtp.timeout'); - $team->smtp_notifications_test = data_get($team, 'smtp_notifications.test',true); - $team->smtp_notifications_deployments = data_get($team, 'smtp_notifications.deployments',false); - $team->smtp_notifications_status_changes = data_get($team, 'smtp_notifications.status_changes',false); + $team->smtp_notifications_test = data_get($team, 'smtp_notifications.test', true); + $team->smtp_notifications_deployments = data_get($team, 'smtp_notifications.deployments', false); + $team->smtp_notifications_status_changes = data_get($team, 'smtp_notifications.status_changes', false); $team->discord_enabled = data_get($team, 'discord.enabled', false); $team->discord_webhook_url = data_get($team, 'discord.webhook_url'); - $team->discord_notifications_test = data_get($team, 'discord_notifications.test',true); - $team->discord_notifications_deployments = data_get($team, 'discord_notifications.deployments',true); - $team->discord_notifications_status_changes = data_get($team, 'discord_notifications.status_changes',true); + $team->discord_notifications_test = data_get($team, 'discord_notifications.test', true); + $team->discord_notifications_deployments = data_get($team, 'discord_notifications.deployments', true); + $team->discord_notifications_status_changes = data_get($team, 'discord_notifications.status_changes', true); $team->save(); } @@ -78,7 +77,7 @@ public function up(): void $table->integer('smtp_timeout')->nullable(); }); $instance_settings = InstanceSettings::all(); - foreach($instance_settings as $instance_setting) { + foreach ($instance_settings as $instance_setting) { $instance_setting->smtp_enabled = data_get($instance_setting, 'smtp.enabled', false); $instance_setting->smtp_from_address = data_get($instance_setting, 'smtp.from_address'); $instance_setting->smtp_from_name = data_get($instance_setting, 'smtp.from_name'); @@ -108,7 +107,7 @@ public function down(): void $table->schemalessAttributes('discord_notifications'); }); $teams = Team::all(); - foreach($teams as $team) { + foreach ($teams as $team) { $team->smtp = [ 'enabled' => $team->smtp_enabled, 'from_address' => $team->smtp_from_address, @@ -190,4 +189,4 @@ public function down(): void $table->dropColumn('smtp_timeout'); }); } -}; \ No newline at end of file +}; diff --git a/database/migrations/2023_08_07_073651_create_s3_storages_table.php b/database/migrations/2023_08_07_073651_create_s3_storages_table.php index cdda367a2..0a7415afb 100644 --- a/database/migrations/2023_08_07_073651_create_s3_storages_table.php +++ b/database/migrations/2023_08_07_073651_create_s3_storages_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ @@ -34,4 +33,4 @@ public function down(): void { Schema::dropIfExists('s3_storages'); } -}; \ No newline at end of file +}; diff --git a/database/migrations/2023_08_07_142950_create_standalone_postgresqls_table.php b/database/migrations/2023_08_07_142950_create_standalone_postgresqls_table.php index c159434e6..180d6382f 100644 --- a/database/migrations/2023_08_07_142950_create_standalone_postgresqls_table.php +++ b/database/migrations/2023_08_07_142950_create_standalone_postgresqls_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_08_07_142951_add_description_field_to_applications_table.php b/database/migrations/2023_08_07_142951_add_description_field_to_applications_table.php index 02d4c5935..2bd1c428c 100644 --- a/database/migrations/2023_08_07_142951_add_description_field_to_applications_table.php +++ b/database/migrations/2023_08_07_142951_add_description_field_to_applications_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ @@ -25,4 +24,4 @@ public function down(): void $table->dropColumn('description'); }); } -}; \ No newline at end of file +}; diff --git a/database/migrations/2023_08_07_142952_remove_foreignId_environment_variables.php b/database/migrations/2023_08_07_142952_remove_foreignId_environment_variables.php index d24dbb446..2adf41b90 100644 --- a/database/migrations/2023_08_07_142952_remove_foreignId_environment_variables.php +++ b/database/migrations/2023_08_07_142952_remove_foreignId_environment_variables.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_08_07_142954_add_readonly_localpersistentvolumes.php b/database/migrations/2023_08_07_142954_add_readonly_localpersistentvolumes.php index f0bce760d..1a693eee9 100644 --- a/database/migrations/2023_08_07_142954_add_readonly_localpersistentvolumes.php +++ b/database/migrations/2023_08_07_142954_add_readonly_localpersistentvolumes.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/seeders/ApplicationPreviewSeeder.php b/database/seeders/ApplicationPreviewSeeder.php index 512f1c990..764939073 100644 --- a/database/seeders/ApplicationPreviewSeeder.php +++ b/database/seeders/ApplicationPreviewSeeder.php @@ -2,11 +2,6 @@ namespace Database\Seeders; -use App\Models\Application; -use App\Models\ApplicationPreview; -use App\Models\Environment; -use App\Models\GithubApp; -use App\Models\StandaloneDocker; use Illuminate\Database\Seeder; class ApplicationPreviewSeeder extends Seeder diff --git a/database/seeders/ApplicationSeeder.php b/database/seeders/ApplicationSeeder.php index 9cffe6fbe..42997a708 100644 --- a/database/seeders/ApplicationSeeder.php +++ b/database/seeders/ApplicationSeeder.php @@ -4,12 +4,8 @@ use App\Data\ApplicationPreview; use App\Models\Application; -use App\Models\ApplicationSetting; -use App\Models\Environment; use App\Models\GithubApp; -use App\Models\LocalPersistentVolume; use App\Models\StandaloneDocker; -use App\Models\SwarmDocker; use Illuminate\Database\Seeder; class ApplicationSeeder extends Seeder @@ -38,4 +34,4 @@ public function run(): void 'source_type' => GithubApp::class ]); } -} \ No newline at end of file +} diff --git a/database/seeders/ApplicationSettingsSeeder.php b/database/seeders/ApplicationSettingsSeeder.php index 3ab5bd967..8e439fd16 100644 --- a/database/seeders/ApplicationSettingsSeeder.php +++ b/database/seeders/ApplicationSettingsSeeder.php @@ -3,11 +3,6 @@ namespace Database\Seeders; use App\Models\Application; -use App\Models\ApplicationSetting; -use App\Models\Environment; -use App\Models\GithubApp; -use App\Models\StandaloneDocker; -use App\Models\SwarmDocker; use Illuminate\Database\Seeder; class ApplicationSettingsSeeder extends Seeder diff --git a/database/seeders/DBSeeder.php b/database/seeders/DBSeeder.php index 35effa0c6..1e88129f8 100644 --- a/database/seeders/DBSeeder.php +++ b/database/seeders/DBSeeder.php @@ -2,7 +2,6 @@ namespace Database\Seeders; -use App\Models\Database; use App\Models\Environment; use App\Models\StandaloneDocker; use Illuminate\Database\Seeder; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 96209ade7..3ead195e4 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -2,7 +2,6 @@ namespace Database\Seeders; -use App\Models\Environment; use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder diff --git a/database/seeders/EnvironmentSeeder.php b/database/seeders/EnvironmentSeeder.php index 345bda5c5..0e980f22b 100644 --- a/database/seeders/EnvironmentSeeder.php +++ b/database/seeders/EnvironmentSeeder.php @@ -2,9 +2,6 @@ namespace Database\Seeders; -use App\Models\Environment; -use App\Models\Project; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class EnvironmentSeeder extends Seeder diff --git a/database/seeders/GitSeeder.php b/database/seeders/GitSeeder.php index ce426d162..c8dc3ab6d 100644 --- a/database/seeders/GitSeeder.php +++ b/database/seeders/GitSeeder.php @@ -3,9 +3,6 @@ namespace Database\Seeders; use App\Models\Git; -use App\Models\PrivateKey; -use App\Models\Project; -use App\Models\Team; use Illuminate\Database\Seeder; class GitSeeder extends Seeder diff --git a/database/seeders/GithubAppSeeder.php b/database/seeders/GithubAppSeeder.php index e2d1bb9c6..681017e6e 100644 --- a/database/seeders/GithubAppSeeder.php +++ b/database/seeders/GithubAppSeeder.php @@ -5,7 +5,6 @@ use App\Models\GithubApp; use App\Models\PrivateKey; use App\Models\Team; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class GithubAppSeeder extends Seeder diff --git a/database/seeders/GitlabAppSeeder.php b/database/seeders/GitlabAppSeeder.php index bf1833ae4..9a7165844 100644 --- a/database/seeders/GitlabAppSeeder.php +++ b/database/seeders/GitlabAppSeeder.php @@ -5,7 +5,6 @@ use App\Models\GitlabApp; use App\Models\PrivateKey; use App\Models\Team; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class GitlabAppSeeder extends Seeder diff --git a/database/seeders/KubernetesSeeder.php b/database/seeders/KubernetesSeeder.php index e43a8df60..f6a852e05 100644 --- a/database/seeders/KubernetesSeeder.php +++ b/database/seeders/KubernetesSeeder.php @@ -2,7 +2,6 @@ namespace Database\Seeders; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class KubernetesSeeder extends Seeder diff --git a/database/seeders/PrivateKeySeeder.php b/database/seeders/PrivateKeySeeder.php index 52785f164..d86f25fbc 100644 --- a/database/seeders/PrivateKeySeeder.php +++ b/database/seeders/PrivateKeySeeder.php @@ -3,9 +3,7 @@ namespace Database\Seeders; use App\Models\PrivateKey; -use App\Models\Server; use App\Models\Team; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class PrivateKeySeeder extends Seeder diff --git a/database/seeders/S3StorageSeeder.php b/database/seeders/S3StorageSeeder.php index 499510717..de7cef6dc 100644 --- a/database/seeders/S3StorageSeeder.php +++ b/database/seeders/S3StorageSeeder.php @@ -2,9 +2,8 @@ namespace Database\Seeders; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; -use Illuminate\Database\Seeder; use App\Models\S3Storage; +use Illuminate\Database\Seeder; class S3StorageSeeder extends Seeder { @@ -23,4 +22,4 @@ public function run(): void 'team_id' => 0, ]); } -} \ No newline at end of file +} diff --git a/database/seeders/ServerSeeder.php b/database/seeders/ServerSeeder.php index 82ab2552b..a781ca1de 100644 --- a/database/seeders/ServerSeeder.php +++ b/database/seeders/ServerSeeder.php @@ -2,9 +2,6 @@ namespace Database\Seeders; -use App\Data\ServerMetadata; -use App\Enums\ProxyStatus; -use App\Enums\ProxyTypes; use App\Models\PrivateKey; use App\Models\Server; use App\Models\Team; diff --git a/database/seeders/ServerSettingSeeder.php b/database/seeders/ServerSettingSeeder.php index fe366ba77..59fe07c99 100644 --- a/database/seeders/ServerSettingSeeder.php +++ b/database/seeders/ServerSettingSeeder.php @@ -3,7 +3,6 @@ namespace Database\Seeders; use App\Models\Server; -use App\Models\Team; use Illuminate\Database\Seeder; class ServerSettingSeeder extends Seeder diff --git a/database/seeders/ServiceSeeder.php b/database/seeders/ServiceSeeder.php index 360c946c5..c016d89e6 100644 --- a/database/seeders/ServiceSeeder.php +++ b/database/seeders/ServiceSeeder.php @@ -3,7 +3,6 @@ namespace Database\Seeders; use App\Models\Environment; -use App\Models\Service; use App\Models\StandaloneDocker; use Illuminate\Database\Seeder; diff --git a/database/seeders/StandaloneDockerSeeder.php b/database/seeders/StandaloneDockerSeeder.php index cbf32759f..8b1bfa76a 100644 --- a/database/seeders/StandaloneDockerSeeder.php +++ b/database/seeders/StandaloneDockerSeeder.php @@ -5,7 +5,6 @@ use App\Models\Destination; use App\Models\Server; use App\Models\StandaloneDocker; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class StandaloneDockerSeeder extends Seeder diff --git a/database/seeders/StandalonePostgresqlSeeder.php b/database/seeders/StandalonePostgresqlSeeder.php index 126f159e7..51f249f2a 100644 --- a/database/seeders/StandalonePostgresqlSeeder.php +++ b/database/seeders/StandalonePostgresqlSeeder.php @@ -2,10 +2,9 @@ namespace Database\Seeders; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; -use Illuminate\Database\Seeder; -use App\Models\StandalonePostgresql; use App\Models\StandaloneDocker; +use App\Models\StandalonePostgresql; +use Illuminate\Database\Seeder; class StandalonePostgresqlSeeder extends Seeder { diff --git a/database/seeders/SubscriptionSeeder.php b/database/seeders/SubscriptionSeeder.php index e76d793a3..03a5ed8f3 100644 --- a/database/seeders/SubscriptionSeeder.php +++ b/database/seeders/SubscriptionSeeder.php @@ -2,7 +2,6 @@ namespace Database\Seeders; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class SubscriptionSeeder extends Seeder diff --git a/database/seeders/SwarmDockerSeeder.php b/database/seeders/SwarmDockerSeeder.php index a9662a969..dc2934ead 100644 --- a/database/seeders/SwarmDockerSeeder.php +++ b/database/seeders/SwarmDockerSeeder.php @@ -4,9 +4,7 @@ use App\Models\Destination; use App\Models\Server; -use App\Models\StandaloneDocker; use App\Models\SwarmDocker; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class SwarmDockerSeeder extends Seeder diff --git a/database/seeders/WebhookSeeder.php b/database/seeders/WebhookSeeder.php index f226c715a..1d2ef1357 100644 --- a/database/seeders/WebhookSeeder.php +++ b/database/seeders/WebhookSeeder.php @@ -2,7 +2,6 @@ namespace Database\Seeders; -use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class WebhookSeeder extends Seeder diff --git a/other/logos/appwrite.svg b/other/logos/appwrite.svg index 7128b7b73..b5b8e4ab7 100644 --- a/other/logos/appwrite.svg +++ b/other/logos/appwrite.svg @@ -1,2 +1,14 @@ - - \ No newline at end of file + + + + + + diff --git a/public/index.php b/public/index.php index 1d69f3a28..f3c2ebcd3 100644 --- a/public/index.php +++ b/public/index.php @@ -16,7 +16,7 @@ | */ -if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) { +if (file_exists($maintenance = __DIR__ . '/../storage/framework/maintenance.php')) { require $maintenance; } @@ -31,7 +31,7 @@ | */ -require __DIR__.'/../vendor/autoload.php'; +require __DIR__ . '/../vendor/autoload.php'; /* |-------------------------------------------------------------------------- @@ -44,7 +44,7 @@ | */ -$app = require_once __DIR__.'/../bootstrap/app.php'; +$app = require_once __DIR__ . '/../bootstrap/app.php'; $kernel = $app->make(Kernel::class); diff --git a/public/svgs/external-link.svg b/public/svgs/external-link.svg index e0e47d694..c3c982ff0 100644 --- a/public/svgs/external-link.svg +++ b/public/svgs/external-link.svg @@ -1,6 +1,6 @@ -
Coolify
- +
@@ -16,13 +16,15 @@
@csrf + label="{{ __('input.email') }}" autofocus/> {{ __('auth.forgot_password_send_email') }} @else
Transactional emails are not active on this instance.
See how to set it in our docs, or how to manually reset password.
+ href="https://docs.coollabs.io/coolify">docs, or how to + manually reset password. +
@endif @if ($errors->any())
diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php index 0a66be609..d1a8fefd7 100644 --- a/resources/views/auth/login.blade.php +++ b/resources/views/auth/login.blade.php @@ -3,7 +3,7 @@
Coolify
- +

{{ __('auth.login') }}

@@ -17,33 +17,33 @@
@csrf @env('local') - + - - - {{ __('auth.forgot_password') }}? - - @else - - - @endenv + + + {{ __('auth.forgot_password') }}? + + @else + + + @endenv - {{ __('auth.login') }} - @if (!$is_registration_enabled) -
{{ __('auth.registration_disabled') }}
- @endif - @if ($errors->any()) -
- {{ __('auth.failed') }} -
- @endif - @if (session('status')) -
- {{ session('status') }} -
- @endif + {{ __('auth.login') }} + @if (!$is_registration_enabled) +
{{ __('auth.registration_disabled') }}
+ @endif + @if ($errors->any()) +
+ {{ __('auth.failed') }} +
+ @endif + @if (session('status')) +
+ {{ session('status') }} +
+ @endif
diff --git a/resources/views/auth/register.blade.php b/resources/views/auth/register.blade.php index 31003d2a9..3fafe8c3d 100644 --- a/resources/views/auth/register.blade.php +++ b/resources/views/auth/register.blade.php @@ -3,38 +3,38 @@
Coolify
- +
@csrf @env('local') - - -
- - -
- @else - - -
- - -
- @endenv - {{ __('auth.register') }} + + +
+ + +
+ @else + + +
+ + +
+ @endenv + {{ __('auth.register') }} @if ($errors->any())
diff --git a/resources/views/auth/reset-password.blade.php b/resources/views/auth/reset-password.blade.php index c5e1ab850..5a601f648 100644 --- a/resources/views/auth/reset-password.blade.php +++ b/resources/views/auth/reset-password.blade.php @@ -5,7 +5,7 @@
Coolify
- +

{{ __('auth.reset_password') }}

@@ -15,12 +15,12 @@ @csrf + label="{{ __('input.email') }}"/>
+ label="{{ __('input.password') }}" autofocus/> + label="{{ __('input.password.again') }}"/>
{{ __('auth.reset_password') }} diff --git a/resources/views/auth/two-factor-challenge.blade.php b/resources/views/auth/two-factor-challenge.blade.php index a5e645d7e..3bd7c8452 100644 --- a/resources/views/auth/two-factor-challenge.blade.php +++ b/resources/views/auth/two-factor-challenge.blade.php @@ -3,7 +3,7 @@
Coolify
- +
@@ -11,9 +11,9 @@