From c19c13b4e279b17cfeb370867e4ebbcebe7452ef Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 20 Oct 2023 12:34:53 +0200 Subject: [PATCH] feat: cloning project --- app/Http/Livewire/Project/CloneProject.php | 143 ++++++++++++++++++ database/seeders/ApplicationSeeder.php | 2 +- .../livewire/project/clone-project.blade.php | 57 +++++++ resources/views/project/resources.blade.php | 4 + routes/web.php | 5 +- 5 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 app/Http/Livewire/Project/CloneProject.php create mode 100644 resources/views/livewire/project/clone-project.blade.php diff --git a/app/Http/Livewire/Project/CloneProject.php b/app/Http/Livewire/Project/CloneProject.php new file mode 100644 index 000000000..b271a7970 --- /dev/null +++ b/app/Http/Livewire/Project/CloneProject.php @@ -0,0 +1,143 @@ + 'Please select a server.', + 'newProjectName' => 'Please enter a name for the new project.', + ]; + public function mount($project_uuid) + { + $this->project_uuid = $project_uuid; + $this->project = Project::where('uuid', $project_uuid)->firstOrFail(); + $this->environment = $this->project->environments->where('name', $this->environment_name)->first(); + $this->project_id = $this->project->id; + $this->servers = currentTeam()->servers; + $this->newProjectName = $this->project->name . ' (clone)'; + } + + public function render() + { + return view('livewire.project.clone-project'); + } + + public function selectServer($server_id) + { + $this->selectedServer = $server_id; + $this->server = $this->servers->where('id', $server_id)->first(); + } + + public function clone() + { + try { + $this->validate([ + 'selectedServer' => 'required', + 'newProjectName' => 'required', + ]); + $newProject = Project::create([ + 'name' => $this->newProjectName, + 'team_id' => currentTeam()->id, + 'description' => $this->project->description . ' (clone)', + ]); + if ($this->environment->id !== 1) { + $newProject->environments()->create([ + 'name' => $this->environment->name, + ]); + $newProject->environments()->find(1)->delete(); + } + $newEnvironment = $newProject->environments->first(); + // Clone Applications + $applications = $this->environment->applications; + $databases = $this->environment->databases(); + $services = $this->environment->services; + foreach ($applications as $application) { + $uuid = (string)new Cuid2(7); + $newApplication = $application->replicate()->fill([ + 'uuid' => $uuid, + 'fqdn' => generateFqdn($this->server, $uuid), + 'status' => 'exited', + 'environment_id' => $newEnvironment->id, + 'destination_id' => $this->selectedServer, + ]); + $newApplication->environment_id = $newProject->environments->first()->id; + $newApplication->save(); + $environmentVaribles = $application->environment_variables()->get(); + foreach ($environmentVaribles as $environmentVarible) { + $newEnvironmentVariable = $environmentVarible->replicate()->fill([ + 'application_id' => $newApplication->id, + ]); + $newEnvironmentVariable->save(); + } + $persistentVolumes = $application->persistentStorages()->get(); + foreach ($persistentVolumes as $volume) { + $newPersistentVolume = $volume->replicate()->fill([ + 'name' => $newApplication->uuid . '-' . str($volume->name)->afterLast('-'), + 'resource_id' => $newApplication->id, + ]); + $newPersistentVolume->save(); + } + } + foreach ($databases as $database) { + $uuid = (string)new Cuid2(7); + $newDatabase = $database->replicate()->fill([ + 'uuid' => $uuid, + 'environment_id' => $newEnvironment->id, + 'destination_id' => $this->selectedServer, + ]); + $newDatabase->environment_id = $newProject->environments->first()->id; + $newDatabase->save(); + $environmentVaribles = $database->environment_variables()->get(); + foreach ($environmentVaribles as $environmentVarible) { + $payload = []; + if ($database->type() === 'standalone-postgres') { + $payload['standalone_postgresql_id'] = $newDatabase->id; + } else if ($database->type() === 'standalone_redis') { + $payload['standalone_redis_id'] = $newDatabase->id; + } else if ($database->type() === 'standalone_mongodb') { + $payload['standalone_mongodb_id'] = $newDatabase->id; + } + $newEnvironmentVariable = $environmentVarible->replicate()->fill($payload); + $newEnvironmentVariable->save(); + } + } + foreach ($services as $service) { + $uuid = (string)new Cuid2(7); + $newService = $service->replicate()->fill([ + 'uuid' => $uuid, + 'environment_id' => $newEnvironment->id, + 'destination_id' => $this->selectedServer, + ]); + $newService->environment_id = $newProject->environments->first()->id; + $newService->save(); + $newService->parse(); + } + return redirect()->route('project.resources', [ + 'project_uuid' => $newProject->uuid, + 'environment_name' => $newEnvironment->name, + ]); + } catch (\Exception $e) { + return handleError($e, $this); + } + } +} diff --git a/database/seeders/ApplicationSeeder.php b/database/seeders/ApplicationSeeder.php index 2d2d00cb7..54863f2d6 100644 --- a/database/seeders/ApplicationSeeder.php +++ b/database/seeders/ApplicationSeeder.php @@ -37,7 +37,7 @@ public function run(): void 'git_repository' => 'coollabsio/coolify-examples', 'git_branch' => 'dockerfile', 'build_pack' => 'dockerfile', - 'ports_exposes' => '3000', + 'ports_exposes' => '80', 'environment_id' => 1, 'destination_id' => 0, 'destination_type' => StandaloneDocker::class, diff --git a/resources/views/livewire/project/clone-project.blade.php b/resources/views/livewire/project/clone-project.blade.php new file mode 100644 index 000000000..2e79d8892 --- /dev/null +++ b/resources/views/livewire/project/clone-project.blade.php @@ -0,0 +1,57 @@ +
+
+
+

Clone

+ Clone to a New Project +
+
Quickly clone a project
+
+ +

Servers

+
+ @foreach ($servers as $srv) +
+
+
{{ $srv->name }}
+ @isset($selectedServer) +
+ {{ $srv->description }}
+ @else +
+ {{ $srv->description }}
+ @endisset + +
+
+ @endforeach +
+

Resources

+
+ @foreach ($environment->applications->sortBy('name') as $application) +
+
+
{{ $application->name }}
+
{{ $application->description }}
+
+
+ @endforeach + @foreach ($environment->databases()->sortBy('name') as $database) +
+
+
{{ $database->name }}
+
{{ $database->description }}
+
+
+ @endforeach + @foreach ($environment->services->sortBy('name') as $service) +
+
+
{{ $service->name }}
+
{{ $service->description }}
+
+
+ @endforeach +
+ diff --git a/resources/views/project/resources.blade.php b/resources/views/project/resources.blade.php index 775e95588..da726e658 100644 --- a/resources/views/project/resources.blade.php +++ b/resources/views/project/resources.blade.php @@ -9,6 +9,10 @@ class="font-normal text-white normal-case border-none rounded hover:no-underline btn btn-primary btn-sm no-animation">+ New @endif + + Clone +