From 937892b3ea5dfb7885ab36858c233090e6ec56fd Mon Sep 17 00:00:00 2001
From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com>
Date: Wed, 19 Aug 2026 13:15:15 +0200
Subject: [PATCH] fix(storage): guard volume names and authorize source removal
---
app/Livewire/Project/Service/Storage.php | 7 +++----
.../views/livewire/project/shared/storages/all.blade.php | 1 +
tests/Feature/PersistentStorageVolumesLayoutTest.php | 8 ++++++++
3 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/app/Livewire/Project/Service/Storage.php b/app/Livewire/Project/Service/Storage.php
index bb8a39d2b..6880b5ab0 100644
--- a/app/Livewire/Project/Service/Storage.php
+++ b/app/Livewire/Project/Service/Storage.php
@@ -374,10 +374,9 @@ public function fileStorageHostPath(): string
private function generateDefaultVolumeName(): string
{
- return str($this->resource->name ?? 'volume')
- ->slug()
- ->append('-data')
- ->value();
+ $name = str($this->resource->name)->slug()->value();
+
+ return ($name ?: 'volume').'-data';
}
public function fileStoragePreviewPath(): string
diff --git a/resources/views/livewire/project/shared/storages/all.blade.php b/resources/views/livewire/project/shared/storages/all.blade.php
index 09377dac9..dbe21fd7b 100644
--- a/resources/views/livewire/project/shared/storages/all.blade.php
+++ b/resources/views/livewire/project/shared/storages/all.blade.php
@@ -160,6 +160,7 @@ class="volumes-col-actions volumes-cell-actions flex flex-wrap items-center just
not->toContain('Swarm Mode detected')
->and($volumesView)
+ ->toMatch('/]*canGate="update"[^>]*:canResource="\$resource"/')
->toContain('The next deployment will use a named Docker volume instead.')
->toContain('Data from the existing host directory will not be copied to the named volume.');
});
@@ -242,6 +243,13 @@ function createApplicationWithVolume(array $applicationAttributes = [], array $v
->assertSet('name', 'storage-app-data');
});
+it('uses a valid fallback default volume name when the resource name has no slug characters', function () {
+ [$application] = createApplicationWithVolume(['name' => '---']);
+
+ Livewire::test(Storage::class, ['resource' => $application])
+ ->assertSet('name', 'volume-data');
+});
+
it('removes existing bind mount source paths from the volume table', function () {
[$application, $volume] = createApplicationWithVolume(volumeAttributes: [
'host_path' => '/srv/storage',