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 @@