feat: cloning project
This commit is contained in:
parent
266b99bc25
commit
c19c13b4e2
143
app/Http/Livewire/Project/CloneProject.php
Normal file
143
app/Http/Livewire/Project/CloneProject.php
Normal file
@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Project;
|
||||
|
||||
use App\Models\Environment;
|
||||
use App\Models\Project;
|
||||
use App\Models\Server;
|
||||
use Livewire\Component;
|
||||
use Visus\Cuid2\Cuid2;
|
||||
|
||||
class CloneProject extends Component
|
||||
{
|
||||
public string $project_uuid;
|
||||
public string $environment_name;
|
||||
public int $project_id;
|
||||
|
||||
public Project $project;
|
||||
public $environments;
|
||||
public $servers;
|
||||
public ?Environment $environment = null;
|
||||
public ?int $selectedServer = null;
|
||||
public ?Server $server = null;
|
||||
public $resources = [];
|
||||
public string $newProjectName = '';
|
||||
|
||||
protected $messages = [
|
||||
'selectedServer' => '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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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,
|
||||
|
57
resources/views/livewire/project/clone-project.blade.php
Normal file
57
resources/views/livewire/project/clone-project.blade.php
Normal file
@ -0,0 +1,57 @@
|
||||
<form wire:submit.prevent='clone'>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex gap-2">
|
||||
<h1>Clone</h1>
|
||||
<x-forms.button type="submit">Clone to a New Project</x-forms.button>
|
||||
</div>
|
||||
<div class="subtitle ">Quickly clone a project</div>
|
||||
</div>
|
||||
<x-forms.input required id="newProjectName" label="New Project Name" />
|
||||
<h3 class="pt-4 pb-2">Servers</h3>
|
||||
<div class="grid gap-2 lg:grid-cols-3">
|
||||
@foreach ($servers as $srv)
|
||||
<div wire:click="selectServer('{{ $srv->id }}')"
|
||||
class="cursor-pointer box-without-bg bg-coolgray-200 group"
|
||||
:class="'{{ $selectedServer === $srv->id }}' && 'bg-coollabs'">
|
||||
<div class="flex flex-col mx-6">
|
||||
<div :class="'{{ $selectedServer === $srv->id }}' && 'text-white'"> {{ $srv->name }}</div>
|
||||
@isset($selectedServer)
|
||||
<div :class="'{{ $selectedServer === $srv->id }}' && 'text-white pt-2 text-xs font-bold'">
|
||||
{{ $srv->description }}</div>
|
||||
@else
|
||||
<div class="description">
|
||||
{{ $srv->description }}</div>
|
||||
@endisset
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
<h3 class="pt-4 pb-2">Resources</h3>
|
||||
<div class="grid grid-cols-1 gap-2">
|
||||
@foreach ($environment->applications->sortBy('name') as $application)
|
||||
<div class="p-2 border border-coolgray-200">
|
||||
<div class="flex flex-col">
|
||||
<div class="font-bold text-white">{{ $application->name }}</div>
|
||||
<div class="description">{{ $application->description }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
@foreach ($environment->databases()->sortBy('name') as $database)
|
||||
<div class="p-2 border border-coolgray-200">
|
||||
<div class="flex flex-col">
|
||||
<div class="font-bold text-white">{{ $database->name }}</div>
|
||||
<div class="description">{{ $database->description }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
@foreach ($environment->services->sortBy('name') as $service)
|
||||
<div class="p-2 border border-coolgray-200">
|
||||
<div class="flex flex-col">
|
||||
<div class="font-bold text-white">{{ $service->name }}</div>
|
||||
<div class="description">{{ $service->description }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</form>
|
@ -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</a>
|
||||
@endif
|
||||
<a class="font-normal text-white normal-case border-none rounded hover:no-underline btn btn-primary btn-sm no-animation"
|
||||
href="{{ route('project.clone', ['project_uuid' => data_get($project, 'uuid'), 'environment_name' => request()->route('environment_name')]) }}">
|
||||
Clone
|
||||
</a>
|
||||
</div>
|
||||
<nav class="flex pt-2 pb-10">
|
||||
<ol class="flex items-center">
|
||||
|
@ -10,6 +10,7 @@
|
||||
use App\Http\Livewire\Project\Service\Show as ServiceShow;
|
||||
use App\Http\Livewire\Dev\Compose as Compose;
|
||||
use App\Http\Livewire\Dashboard;
|
||||
use App\Http\Livewire\Project\CloneProject;
|
||||
use App\Http\Livewire\Project\Shared\Logs;
|
||||
use App\Http\Livewire\Server\All;
|
||||
use App\Http\Livewire\Server\Create;
|
||||
@ -91,8 +92,10 @@
|
||||
|
||||
Route::middleware(['auth', 'verified'])->group(function () {
|
||||
Route::get('/projects', [ProjectController::class, 'all'])->name('projects');
|
||||
Route::get('/project/{project_uuid}/edit', [ProjectController::class, 'edit'])->name('project.edit');
|
||||
Route::get('/project/{project_uuid}', [ProjectController::class, 'show'])->name('project.show');
|
||||
Route::get('/project/{project_uuid}/edit', [ProjectController::class, 'edit'])->name('project.edit');
|
||||
Route::get('/project/{project_uuid}/{environment_name}/clone', CloneProject::class)->name('project.clone');
|
||||
|
||||
Route::get('/project/{project_uuid}/{environment_name}/new', [ProjectController::class, 'new'])->name('project.resources.new');
|
||||
Route::get('/project/{project_uuid}/{environment_name}', [ProjectController::class, 'resources'])->name('project.resources');
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user