diff --git a/app/Http/Livewire/Project/Service/FileStorage.php b/app/Http/Livewire/Project/Service/FileStorage.php index 4341c6f51..e4103f600 100644 --- a/app/Http/Livewire/Project/Service/FileStorage.php +++ b/app/Http/Livewire/Project/Service/FileStorage.php @@ -33,12 +33,20 @@ public function mount() } public function submit() { + $original = $this->fileStorage->getOriginal(); try { $this->validate(); + if ($this->fileStorage->is_directory) { + $this->fileStorage->content = null; + } $this->fileStorage->save(); - $this->service->saveFileVolumes(); + $this->fileStorage->saveStorageOnServer($this->service); + // ray($this->fileStorage); + // $this->service->saveFileVolumes(); $this->emit('success', 'File updated successfully.'); } catch (\Throwable $e) { + $this->fileStorage->setRawAttributes($original); + $this->fileStorage->save(); return handleError($e, $this); } } diff --git a/app/Http/Livewire/Project/Service/Show.php b/app/Http/Livewire/Project/Service/Show.php index 656adff0a..6f48a1389 100644 --- a/app/Http/Livewire/Project/Service/Show.php +++ b/app/Http/Livewire/Project/Service/Show.php @@ -27,8 +27,10 @@ public function mount() $service = $this->service->applications()->whereName($this->parameters['service_name'])->first(); if ($service) { $this->serviceApplication = $service; + $this->serviceApplication->getFilesFromServer(); } else { $this->serviceDatabase = $this->service->databases()->whereName($this->parameters['service_name'])->first(); + $this->serviceDatabase->getFilesFromServer(); } } public function generateDockerCompose() diff --git a/app/Models/LocalFileVolume.php b/app/Models/LocalFileVolume.php index 9077a36d5..ebd64c6a2 100644 --- a/app/Models/LocalFileVolume.php +++ b/app/Models/LocalFileVolume.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Support\Str; class LocalFileVolume extends BaseModel { @@ -13,4 +14,40 @@ public function service() { return $this->morphTo('resource'); } + public function saveStorageOnServer(ServiceApplication|ServiceDatabase $service) + { + $workdir = $service->service->workdir(); + $server = $service->service->server; + $commands = collect([ + "mkdir -p $workdir > /dev/null 2>&1 || true", + "cd $workdir" + ]); + $fileVolume = $this; + $path = Str::of(data_get($fileVolume, 'fs_path')); + $content = data_get($fileVolume, 'content'); + if ($path->startsWith('.')) { + $path = $path->after('.'); + $path = $workdir . $path; + } + $isFile = instant_remote_process(["test -f $path && echo OK || echo NOK"], $server); + $isDir = instant_remote_process(["test -d $path && echo OK || echo NOK"], $server); + ray($path); + if ($isFile == 'OK' && $fileVolume->is_directory) { + throw new \Exception("File $path is a file on the server, but you are trying to mark it as a directory. Please delete the file on the server or mark it as directory."); + } else if ($isDir == 'OK' && !$fileVolume->is_directory) { + throw new \Exception("File $path is a directory on the server, but you are trying to mark it as a file. Please delete the directory on the server or mark it as directory."); + } + if (($isFile == 'NOK' && !$fileVolume->is_directory) || $isFile == 'OK') { + $rootDir = Str::of($path)->dirname(); + $commands->push("mkdir -p $rootDir > /dev/null 2>&1 || true"); + $commands->push("touch $path > /dev/null 2>&1 || true"); + if ($content) { + $content = base64_encode($content); + $commands->push("echo '$content' | base64 -d > $path"); + } + } else if ($isDir == 'NOK' && $fileVolume->is_directory) { + $commands->push("mkdir -p $path > /dev/null 2>&1 || true"); + } + return instant_remote_process($commands, $server); + } } diff --git a/app/Models/Service.php b/app/Models/Service.php index cc60a8cad..364e59248 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -306,7 +306,7 @@ public function parse(bool $isNew = false): Collection ] ); } - $savedService->saveFileVolumes(); + $savedService->getFilesFromServer(); } } diff --git a/app/Models/ServiceApplication.php b/app/Models/ServiceApplication.php index f835ab753..58569b6bd 100644 --- a/app/Models/ServiceApplication.php +++ b/app/Models/ServiceApplication.php @@ -36,8 +36,8 @@ public function fqdns(): Attribute ); } - public function saveFileVolumes() + public function getFilesFromServer() { - saveFileVolumesHelper($this); + getFilesystemVolumesFromServer($this); } } diff --git a/app/Models/ServiceDatabase.php b/app/Models/ServiceDatabase.php index 09b216219..a94bca40a 100644 --- a/app/Models/ServiceDatabase.php +++ b/app/Models/ServiceDatabase.php @@ -26,8 +26,8 @@ public function fileStorages() { return $this->morphMany(LocalFileVolume::class, 'resource'); } - public function saveFileVolumes() + public function getFilesFromServer() { - saveFileVolumesHelper($this); + getFilesystemVolumesFromServer($this); } } diff --git a/bootstrap/helpers/services.php b/bootstrap/helpers/services.php index 353e6853b..56a4445e7 100644 --- a/bootstrap/helpers/services.php +++ b/bootstrap/helpers/services.php @@ -64,40 +64,48 @@ function serviceStatus(Service $service) } return 'exited'; } -function saveFileVolumesHelper(ServiceApplication|ServiceDatabase $oneService) +function getFilesystemVolumesFromServer(ServiceApplication|ServiceDatabase $oneService) { + // TODO: make this async try { $workdir = $oneService->service->workdir(); $server = $oneService->service->server; - $applicationFileVolume = $oneService->fileStorages()->get(); + $fileVolumes = $oneService->fileStorages()->get(); $commands = collect([ "mkdir -p $workdir > /dev/null 2>&1 || true", "cd $workdir" ]); - foreach ($applicationFileVolume as $fileVolume) { - $path = Str::of($fileVolume->fs_path); - if ($fileVolume->is_directory) { - $commands->push("test -f $path && rm -f $path > /dev/null 2>&1 || true"); - $commands->push("mkdir -p $path > /dev/null 2>&1 || true"); - continue; + instant_remote_process($commands, $server); + foreach ($fileVolumes as $fileVolume) { + $path = Str::of(data_get($fileVolume, 'fs_path')); + $content = data_get($fileVolume, 'content'); + $isFile = instant_remote_process(["test -f $path && echo OK || echo NOK"], $server); + $isDir = instant_remote_process(["test -d $path && echo OK || echo NOK"], $server); + + if ($isFile == 'OK') { + $filesystemContent = instant_remote_process(["cat $path"], $server); + if (base64_encode($filesystemContent) != base64_encode($content)) { + $fileVolume->content = $filesystemContent; + $fileVolume->save(); + } + } else { + if ($isDir == 'OK') { + $fileVolume->content = null; + $fileVolume->is_directory = true; + $fileVolume->save(); + } else { + $fileVolume->content = null; + $fileVolume->is_directory = false; + $fileVolume->save(); + } } - $content = $fileVolume->content; - $dir = $path->beforeLast('/'); - if ($dir->startsWith('.')) { - $dir = $dir->after('.'); - $dir = $workdir . $dir; - } - $content = base64_encode($content); - $commands->push("test -d $path && rm -rf $path > /dev/null 2>&1 || true"); - $commands->push("mkdir -p $dir > /dev/null 2>&1 || true"); - $commands->push("echo '$content' | base64 -d > $path"); } - return instant_remote_process($commands, $server); } catch (\Throwable $e) { return handleError($e); } } -function updateCompose($resource) { +function updateCompose($resource) +{ try { $name = data_get($resource, 'name'); $dockerComposeRaw = data_get($resource, 'service.docker_compose_raw'); @@ -111,7 +119,7 @@ function updateCompose($resource) { $variableName = "SERVICE_FQDN_" . Str::of($resource->name)->upper(); ray($variableName); $generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first(); - if ($generatedEnv){ + if ($generatedEnv) { $generatedEnv->value = $resource->fqdn; $generatedEnv->save(); } diff --git a/resources/views/livewire/project/service/file-storage.blade.php b/resources/views/livewire/project/service/file-storage.blade.php index e38ab5f05..43f55bbf6 100644 --- a/resources/views/livewire/project/service/file-storage.blade.php +++ b/resources/views/livewire/project/service/file-storage.blade.php @@ -1,23 +1,25 @@ -
{{ $fileStorage->mount_path }}
+
{{ $fileStorage->fs_path }} -> {{ $fileStorage->mount_path }}
- @if ($fileStorage->is_directory) + {{-- @if ($fileStorage->is_directory) - @else -
+ @else --}} + {{--
- + --}} + @if (!$fileStorage->is_directory) Save @endif + {{-- @endif --}} diff --git a/resources/views/livewire/project/service/show.blade.php b/resources/views/livewire/project/service/show.blade.php index 7db827fcc..e0ab934a2 100644 --- a/resources/views/livewire/project/service/show.blade.php +++ b/resources/views/livewire/project/service/show.blade.php @@ -22,7 +22,7 @@ @if ($serviceApplication->fileStorages()->get()->count() > 0)

Mounted Files (binds)

- @foreach ($serviceApplication->fileStorages()->get() as $fileStorage) + @foreach ($serviceApplication->fileStorages()->get()->sort() as $fileStorage) @endforeach
@@ -39,7 +39,7 @@ @if ($serviceDatabase->fileStorages()->get()->count() > 0)

Mounted Files (binds)

- @foreach ($serviceDatabase->fileStorages()->get() as $fileStorage) + @foreach ($serviceDatabase->fileStorages()->get()->sort() as $fileStorage) @endforeach