mirror of
https://github.com/coollabsio/coolify.git
synced 2026-08-24 02:24:11 -05:00
fix(file-mounts): preserve sibling mount configuration
This commit is contained in:
@@ -742,7 +742,7 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
||||
$source = $parsed['source'];
|
||||
$target = $parsed['target'];
|
||||
// Mode is available in $parsed['mode'] if needed
|
||||
$foundConfig = $originalResource->fileStorages()->whereMountPath($target)->first();
|
||||
$foundConfig = findLocalFileVolumeConfig($originalResource, $source, $target, $pull_request_id);
|
||||
if (sourceIsLocal($source)) {
|
||||
$type = str('bind');
|
||||
if ($foundConfig) {
|
||||
@@ -792,7 +792,7 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
||||
}
|
||||
}
|
||||
|
||||
$foundConfig = $originalResource->fileStorages()->whereMountPath($target)->first();
|
||||
$foundConfig = findLocalFileVolumeConfig($originalResource, $source, $target, $pull_request_id);
|
||||
if ($foundConfig) {
|
||||
$content = data_get($foundConfig, 'content');
|
||||
$isDirectory = data_get($foundConfig, 'is_directory');
|
||||
@@ -2135,7 +2135,7 @@ function serviceParser(Service $resource): Collection
|
||||
$source = $parsed['source'];
|
||||
$target = $parsed['target'];
|
||||
// Mode is available in $parsed['mode'] if needed
|
||||
$foundConfig = $originalResource->fileStorages()->whereMountPath($target)->first();
|
||||
$foundConfig = findLocalFileVolumeConfig($originalResource, $source, $target);
|
||||
if (sourceIsLocal($source)) {
|
||||
$type = str('bind');
|
||||
if ($foundConfig) {
|
||||
@@ -2185,7 +2185,7 @@ function serviceParser(Service $resource): Collection
|
||||
}
|
||||
}
|
||||
|
||||
$foundConfig = $originalResource->fileStorages()->whereMountPath($target)->first();
|
||||
$foundConfig = findLocalFileVolumeConfig($originalResource, $source, $target);
|
||||
if ($foundConfig) {
|
||||
$content = data_get($foundConfig, 'content');
|
||||
$isDirectory = data_get($foundConfig, 'is_directory');
|
||||
|
||||
@@ -1666,6 +1666,39 @@ function replaceLocalSource(Stringable $source, Stringable $replacedWith)
|
||||
return $source;
|
||||
}
|
||||
|
||||
function findLocalFileVolumeConfig(
|
||||
Application|ServiceApplication|ServiceDatabase $resource,
|
||||
Stringable $source,
|
||||
Stringable $target,
|
||||
int $pullRequestId = 0,
|
||||
): ?LocalFileVolume {
|
||||
if ($resource instanceof Application) {
|
||||
$mainDirectory = str(base_configuration_dir()."/applications/{$resource->uuid}");
|
||||
} else {
|
||||
$service = $resource->service;
|
||||
if (! $service) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$baseDirectory = (int) $service->compose_parsing_version >= 4 ? 'services' : 'applications';
|
||||
$mainDirectory = str(base_configuration_dir()."/{$baseDirectory}/{$service->uuid}");
|
||||
}
|
||||
|
||||
$resolvedSource = replaceLocalSource($source, $mainDirectory)->value();
|
||||
|
||||
return $resource->fileStorages()
|
||||
->where('mount_path', $target->value())
|
||||
->get()
|
||||
->first(function (LocalFileVolume $volume) use ($pullRequestId, $resolvedSource): bool {
|
||||
$expectedSource = $resolvedSource;
|
||||
if ($pullRequestId !== 0 && $volume->is_preview_suffix_enabled) {
|
||||
$expectedSource = addPreviewDeploymentSuffix($expectedSource, $pullRequestId);
|
||||
}
|
||||
|
||||
return $volume->fs_path === $expectedSource;
|
||||
});
|
||||
}
|
||||
|
||||
function convertToArray($collection)
|
||||
{
|
||||
if ($collection instanceof Collection) {
|
||||
@@ -2687,7 +2720,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
$target = data_get_str($volume, 'target');
|
||||
$content = data_get($volume, 'content');
|
||||
$isDirectory = (bool) data_get($volume, 'isDirectory', null) || (bool) data_get($volume, 'is_directory', null);
|
||||
$foundConfig = $savedService->fileStorages()->whereMountPath($target)->first();
|
||||
$foundConfig = findLocalFileVolumeConfig($savedService, $source, $target);
|
||||
if ($foundConfig) {
|
||||
$contentNotNull = data_get($foundConfig, 'content');
|
||||
if ($contentNotNull) {
|
||||
|
||||
@@ -78,6 +78,32 @@ it('stores sibling file mounts with different host paths and the same container
|
||||
]);
|
||||
});
|
||||
|
||||
it('finds existing file mount configuration by source and target', function () {
|
||||
$application = new Application(['uuid' => 'source-aware-config-test']);
|
||||
$application->id = fake()->unique()->numberBetween(10000, 99999);
|
||||
|
||||
foreach (['first', 'second'] as $name) {
|
||||
$volume = new LocalFileVolume([
|
||||
'fs_path' => base_configuration_dir()."/applications/source-aware-config-test/{$name}.html",
|
||||
'mount_path' => '/usr/share/nginx/html/index.html',
|
||||
'content' => "{$name} content",
|
||||
'is_directory' => false,
|
||||
]);
|
||||
$volume->resource_type = Application::class;
|
||||
$volume->resource_id = $application->id;
|
||||
$volume->save();
|
||||
}
|
||||
|
||||
$found = findLocalFileVolumeConfig(
|
||||
$application,
|
||||
str('./second.html'),
|
||||
str('/usr/share/nginx/html/index.html'),
|
||||
);
|
||||
|
||||
expect($found?->fs_path)->toEndWith('/second.html')
|
||||
->and($found?->content)->toBe('second content');
|
||||
});
|
||||
|
||||
function makeReadOnlyVolumeFixture(string $compose, string $fsPath, string $mountPath, ?string $appUuid = 'test-app-uuid'): LocalFileVolume
|
||||
{
|
||||
$app = new Application([
|
||||
|
||||
Reference in New Issue
Block a user