From 3723c846249409971f36ab8cee48a4ce1d5d05c6 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Wed, 8 Jan 2025 23:13:05 +0100 Subject: [PATCH] feat: docker volume data cloning - UI implementation - functional implementation for databases - volume gets cloned successfully --- app/Livewire/Project/CloneMe.php | 49 +++++++++++++++++++ .../views/livewire/project/clone-me.blade.php | 36 +++++++++++++- 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/app/Livewire/Project/CloneMe.php b/app/Livewire/Project/CloneMe.php index 5c577b24a..bcecbc76f 100644 --- a/app/Livewire/Project/CloneMe.php +++ b/app/Livewire/Project/CloneMe.php @@ -2,6 +2,10 @@ namespace App\Livewire\Project; +use App\Actions\Application\StopApplication; +use App\Actions\Database\StartDatabase; +use App\Actions\Database\StopDatabase; +use App\Jobs\VolumeCloneJob; use App\Models\Environment; use App\Models\Project; use App\Models\Server; @@ -34,6 +38,8 @@ class CloneMe extends Component public string $newName = ''; + public bool $cloneVolumeData = false; + protected $messages = [ 'selectedServer' => 'Please select a server.', 'selectedDestination' => 'Please select a server & destination.', @@ -50,6 +56,12 @@ class CloneMe extends Component $this->newName = str($this->project->name.'-clone-'.(string) new Cuid2)->slug(); } + public function toggleVolumeCloning(bool $value) + { + $this->cloneVolumeData = $value; + $this->dispatch('refresh'); + } + public function render() { return view('livewire.project.clone-me'); @@ -192,6 +204,27 @@ class CloneMe extends Component 'resource_id' => $newApplication->id, ]); $newPersistentVolume->save(); + + if ($this->cloneVolumeData) { + try { + StopApplication::dispatch($application, false, false); + $sourceVolume = $volume->name; + $targetVolume = $newPersistentVolume->name; + $server = $application->destination->server; + + VolumeCloneJob::dispatch($sourceVolume, $targetVolume, $server, $newPersistentVolume); + + queue_application_deployment( + deployment_uuid: (string) new Cuid2, + application: $application, + server: $server, + destination: $application->destination, + no_questions_asked: true + ); + } catch (\Exception $e) { + logger()->error("Failed to copy volume data for {$volume->name}: ".$e->getMessage()); + } + } } $fileStorages = $application->fileStorages()->get(); @@ -276,6 +309,22 @@ class CloneMe extends Component 'resource_id' => $newDatabase->id, ]); $newPersistentVolume->save(); + + if ($this->cloneVolumeData) { + try { + StopDatabase::dispatch($database); + $sourceVolume = $volume->name; + $targetVolume = $newPersistentVolume->name; + $server = $database->destination->server; + + VolumeCloneJob::dispatch($sourceVolume, $targetVolume, $server, $newPersistentVolume); + + StartDatabase::dispatch($database); + } catch (\Exception $e) { + // Log error but continue with cloning + logger()->error("Failed to copy volume data for {$volume->name}: ".$e->getMessage()); + } + } } $fileStorages = $database->fileStorages()->get(); diff --git a/resources/views/livewire/project/clone-me.blade.php b/resources/views/livewire/project/clone-me.blade.php index 1246af050..da7c8aa84 100644 --- a/resources/views/livewire/project/clone-me.blade.php +++ b/resources/views/livewire/project/clone-me.blade.php @@ -9,7 +9,39 @@ Clone to a new Project Clone to a new Environment -

Servers

+ +
+

Clone Volume Data

+
+ Clone your volume data to the new resources volumes. This process requires a brief container downtime to ensure data consistency. +
+
+ @if(!$cloneVolumeData) +
+ +
+ @else +
+ +
+ @endif +
+
+ +

Servers

Choose the server and network to clone the resources to.
@foreach ($servers->sortBy('id') as $server) @@ -29,7 +61,7 @@ @endforeach
-

Resources

+

Resources

These will be cloned to the new project
@foreach ($environment->applications->sortBy('name') as $application)