wip: services

This commit is contained in:
Andras Bacsai 2023-09-22 21:31:47 +02:00
parent 3fc78bc760
commit 1752448050
9 changed files with 163 additions and 21 deletions

View File

@ -15,6 +15,7 @@ class Application extends Component
];
public function render()
{
ray($this->application->fileStorages()->get());
return view('livewire.project.service.application');
}
public function submit()

View File

@ -0,0 +1,21 @@
<?php
namespace App\Http\Livewire\Project\Service;
use App\Models\LocalFileVolume;
use Livewire\Component;
class FileStorage extends Component
{
public LocalFileVolume $fileStorage;
protected $rules = [
'fileStorage.fs_path' => 'required',
'fileStorage.mount_path' => 'required',
'fileStorage.content' => 'nullable',
];
public function render()
{
return view('livewire.project.service.file-storage');
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class LocalFileVolume extends BaseModel
{
use HasFactory;
protected $guarded = [];
public function service()
{
return $this->morphTo();
}
}

View File

@ -8,6 +8,7 @@
use Illuminate\Support\Collection;
use Symfony\Component\Yaml\Yaml;
use Illuminate\Support\Str;
use Spatie\Url\Url;
class Service extends BaseModel
{
@ -84,7 +85,11 @@ public function parse(bool $isNew = false): Collection
ray('parsing');
// ray()->clearAll();
if ($this->docker_compose_raw) {
$yaml = Yaml::parse($this->docker_compose_raw);
try {
$yaml = Yaml::parse($this->docker_compose_raw);
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
$composeVolumes = collect(data_get($yaml, 'volumes', []));
$composeNetworks = collect(data_get($yaml, 'networks', []));
@ -173,6 +178,26 @@ public function parse(bool $isNew = false): Collection
if ($serviceVolumes->count() > 0) {
LocalPersistentVolume::whereResourceId($savedService->id)->whereResourceType(get_class($savedService))->delete();
foreach ($serviceVolumes as $volume) {
if (is_string($volume) && Str::startsWith($volume, './')) {
// Local file
$fsPath = Str::before($volume, ':');
$volumePath = Str::of($volume)->after(':')->beforeLast(':');
ray($fsPath, $volumePath);
LocalFileVolume::updateOrCreate(
[
'mount_path' => $volumePath,
'resource_id' => $savedService->id,
'resource_type' => get_class($savedService)
],
[
'fs_path' => $fsPath,
'mount_path' => $volumePath,
'resource_id' => $savedService->id,
'resource_type' => get_class($savedService)
]
);
continue;
}
if (is_string($volume)) {
$volumeName = Str::before($volume, ':');
$volumePath = Str::after($volume, ':');
@ -352,7 +377,7 @@ public function parse(bool $isNew = false): Collection
} else {
$number = 0;
}
$fqdn = data_get($fqdns, $number);
$fqdn = getOnlyFqdn(data_get($fqdns, $number, $fqdns->first()));
$environments = collect(data_get($service, 'environment'));
$environments = $environments->map(function ($envValue) use ($value, $fqdn) {
$envValue = Str::of($envValue)->replace($value, $fqdn);
@ -361,9 +386,15 @@ public function parse(bool $isNew = false): Collection
$service['environment'] = $environments->toArray();
}
} else if ($variableName->startsWith('SERVICE_URL')) {
ray('url');
if ($fqdns) {
$url = Str::of($fqdns)->after('https://')->before('/');
$number = Str::of($variableName)->after('SERVICE_URL')->afterLast('_')->value();
if (is_numeric($number)) {
$number = (int) $number - 1;
} else {
$number = 0;
}
$fqdn = getOnlyFqdn(data_get($fqdns, $number, $fqdns->first()));
$url = Url::fromString($fqdn)->getHost();
$environments = collect(data_get($service, 'environment'));
$environments = $environments->map(function ($envValue) use ($value, $url) {
$envValue = Str::of($envValue)->replace($value, $url);

View File

@ -27,4 +27,8 @@ public function persistentStorages()
{
return $this->morphMany(LocalPersistentVolume::class, 'resource');
}
public function fileStorages()
{
return $this->morphMany(LocalFileVolume::class, 'resource');
}
}

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('local_file_volumes', function (Blueprint $table) {
$table->id();
$table->string('uuid');
$table->mediumText('fs_path');
$table->string('mount_path');
$table->mediumText('content')->nullable();
$table->nullableMorphs('resource');
$table->unique(['mount_path', 'resource_id', 'resource_type']);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('local_file_volumes');
}
};

View File

@ -0,0 +1,17 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class LocalFileVolumeSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
//
}
}

View File

@ -1,17 +1,27 @@
<form wire:submit.prevent='submit'>
<div class="flex items-center gap-2 pb-4">
@if ($application->human_name)
<h2>{{ Str::headline($application->human_name) }}</h2>
@else
<h2>{{ Str::headline($application->name) }}</h2>
@endif
<x-forms.button type="submit">Save</x-forms.button>
<a target="_blank" href="{{ $application->documentation() }}">Documentation <x-external-link /></a>
</div>
<div class="flex gap-2">
<x-forms.input label="Name" id="application.human_name" placeholder="Human readable name"></x-forms.input>
<x-forms.input label="Description" id="application.description"></x-forms.input>
<x-forms.input placeholder="https://app.coolify.io" label="Domains" required
id="application.fqdn"></x-forms.input>
</div>
</form>
<div>
<form wire:submit.prevent='submit'>
<div class="flex items-center gap-2 pb-4">
@if ($application->human_name)
<h2>{{ Str::headline($application->human_name) }}</h2>
@else
<h2>{{ Str::headline($application->name) }}</h2>
@endif
<x-forms.button type="submit">Save</x-forms.button>
<a target="_blank" href="{{ $application->documentation() }}">Documentation <x-external-link /></a>
</div>
<div class="flex gap-2">
<x-forms.input label="Name" id="application.human_name" placeholder="Human readable name"></x-forms.input>
<x-forms.input label="Description" id="application.description"></x-forms.input>
<x-forms.input placeholder="https://app.coolify.io" label="Domains" required
id="application.fqdn"></x-forms.input>
</div>
</form>
@if ($application->fileStorages()->get()->count() > 0)
<h3 class="py-4">File Storages</h3>
<div class="flex flex-col gap-4">
@foreach ($application->fileStorages()->get() as $fileStorage)
<livewire:project.service.file-storage :fileStorage="$fileStorage" wire:key="{{ $loop->index }}" />
@endforeach
</div>
@endif
</div>

View File

@ -0,0 +1,8 @@
<form wire:submit.prevent='submit' class="flex flex-col gap-2">
<div class="flex gap-2">
<x-forms.input readonly label="File Path" id="fileStorage.fs_path"></x-forms.input>
<x-forms.input readonly label="Mount Path (in container)" id="fileStorage.mount_path"></x-forms.input>
</div>
<x-forms.textarea label="Content" id="fileStorage.content"></x-forms.textarea>
<x-forms.button type="submit">Save</x-forms.button>
</form>