This commit is contained in:
Rafa de Castro 2026-03-10 11:45:31 +01:00 committed by GitHub
commit e16b4ead8c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 123 additions and 15 deletions

View file

@ -822,10 +822,10 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
} elseif ($type->value() === 'volume') {
if ($topLevel->get('volumes')->has($source->value())) {
$temp = $topLevel->get('volumes')->get($source->value());
if (data_get($temp, 'driver_opts.type') === 'cifs') {
continue;
}
if (data_get($temp, 'driver_opts.type') === 'nfs') {
if (data_get($temp, 'driver_opts.type') === 'cifs' || data_get($temp, 'driver_opts.type') === 'nfs') {
dispatch(new ServerFilesFromServerJob($originalResource));
$volumesParsed->put($index, $volume);
continue;
}
}
@ -868,6 +868,7 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
$volumesParsed->put($index, $volume);
}
}
$volumesParsed = $volumesParsed->values();
if ($depends_on?->count() > 0) {
if ($isPullRequest) {
@ -2173,10 +2174,10 @@ function serviceParser(Service $resource): Collection
} elseif ($type->value() === 'volume') {
if ($topLevel->get('volumes')->has($source->value())) {
$temp = $topLevel->get('volumes')->get($source->value());
if (data_get($temp, 'driver_opts.type') === 'cifs') {
continue;
}
if (data_get($temp, 'driver_opts.type') === 'nfs') {
if (data_get($temp, 'driver_opts.type') === 'cifs' || data_get($temp, 'driver_opts.type') === 'nfs') {
dispatch(new ServerFilesFromServerJob($originalResource));
$volumesParsed->put($index, $volume);
continue;
}
}
@ -2216,6 +2217,7 @@ function serviceParser(Service $resource): Collection
$volumesParsed->put($index, $volume);
}
}
$volumesParsed = $volumesParsed->values();
if (! $use_network_mode) {
if ($topLevel->get('networks')?->count() > 0) {

View file

@ -1967,7 +1967,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
} elseif ($type->value() === 'volume') {
if ($topLevelVolumes->has($source->value())) {
$v = $topLevelVolumes->get($source->value());
if (data_get($v, 'driver_opts.type') === 'cifs') {
if (data_get($v, 'driver_opts.type') === 'cifs' || data_get($v, 'driver_opts.type') === 'nfs') {
return $volume;
}
}
@ -2542,7 +2542,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$volume = str("$name:$mount");
if ($topLevelVolumes->has($name)) {
$v = $topLevelVolumes->get($name);
if (data_get($v, 'driver_opts.type') === 'cifs') {
if (data_get($v, 'driver_opts.type') === 'cifs' || data_get($v, 'driver_opts.type') === 'nfs') {
// Do nothing
} else {
if (is_null(data_get($v, 'name'))) {
@ -2558,7 +2558,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
} else {
if ($topLevelVolumes->has($name->value())) {
$v = $topLevelVolumes->get($name->value());
if (data_get($v, 'driver_opts.type') === 'cifs') {
if (data_get($v, 'driver_opts.type') === 'cifs' || data_get($v, 'driver_opts.type') === 'nfs') {
// Do nothing
} else {
if (is_null(data_get($v, 'name'))) {
@ -2615,7 +2615,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
if (! str($source)->startsWith('/')) {
if ($topLevelVolumes->has($source)) {
$v = $topLevelVolumes->get($source);
if (data_get($v, 'driver_opts.type') === 'cifs') {
if (data_get($v, 'driver_opts.type') === 'cifs' || data_get($v, 'driver_opts.type') === 'nfs') {
// Do nothing
} else {
if (is_null(data_get($v, 'name'))) {
@ -2667,7 +2667,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$volume = str("$name:$mount");
if ($topLevelVolumes->has($name)) {
$v = $topLevelVolumes->get($name);
if (data_get($v, 'driver_opts.type') === 'cifs') {
if (data_get($v, 'driver_opts.type') === 'cifs' || data_get($v, 'driver_opts.type') === 'nfs') {
// Do nothing
} else {
if (is_null(data_get($v, 'name'))) {
@ -2686,7 +2686,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$volume = str("$name:$mount");
if ($topLevelVolumes->has($name->value())) {
$v = $topLevelVolumes->get($name->value());
if (data_get($v, 'driver_opts.type') === 'cifs') {
if (data_get($v, 'driver_opts.type') === 'cifs' || data_get($v, 'driver_opts.type') === 'nfs') {
// Do nothing
} else {
if (is_null(data_get($v, 'name'))) {
@ -2743,7 +2743,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
if (! str($source)->startsWith('/')) {
if ($topLevelVolumes->has($source)) {
$v = $topLevelVolumes->get($source);
if (data_get($v, 'driver_opts.type') === 'cifs') {
if (data_get($v, 'driver_opts.type') === 'cifs' || data_get($v, 'driver_opts.type') === 'nfs') {
// Do nothing
} else {
if (is_null(data_get($v, 'name'))) {

View file

@ -0,0 +1,106 @@
<?php
use Symfony\Component\Yaml\Yaml;
test('non-sequential collection keys produce invalid YAML mapping for volumes', function () {
$volumesParsed = collect([]);
$volumesParsed->put(0, 'uuid_test-cache:/cache');
$volumesParsed->put(3, '/data/coolify/applications/uuid/configs/config.yml:/config.yml');
$volumesParsed->put(4, '/etc/localtime:/etc/localtime:ro');
$payload = ['volumes' => $volumesParsed->toArray()];
$yaml = Yaml::dump($payload, 10, 2);
expect($yaml)->toContain('0:');
expect($yaml)->not->toContain('- uuid_test-cache');
});
test('sequential collection keys produce valid YAML list for volumes', function () {
$volumesParsed = collect([]);
$volumesParsed->put(0, 'uuid_test-cache:/cache');
$volumesParsed->put(3, '/data/coolify/applications/uuid/configs/config.yml:/config.yml');
$volumesParsed->put(4, '/etc/localtime:/etc/localtime:ro');
$volumesParsed = $volumesParsed->values();
$payload = ['volumes' => $volumesParsed->toArray()];
$yaml = Yaml::dump($payload, 10, 2);
expect($yaml)->toContain("- 'uuid_test-cache:/cache'");
expect($yaml)->toContain("- '/data/coolify/applications/uuid/configs/config.yml:/config.yml'");
expect($yaml)->toContain("- '/etc/localtime:/etc/localtime:ro'");
expect($yaml)->not->toContain('0:');
});
test('NFS volumes are preserved when mixed with persistent and bind volumes', function () {
$volumes = [
'test_cache:/cache',
'test_stores:/stores',
'test_backups:/backups',
'./configs/config.yml:/config.yml',
'/etc/localtime:/etc/localtime:ro',
];
$topLevelVolumes = collect([
'test_cache' => ['driver' => 'local'],
'test_stores' => ['driver_opts' => ['type' => 'nfs', 'o' => 'addr=192.168.68.61', 'device' => ':/mnt/stores']],
'test_backups' => ['driver_opts' => ['type' => 'nfs', 'o' => 'addr=192.168.68.61', 'device' => ':/mnt/backups']],
]);
$volumesParsed = collect([]);
foreach ($volumes as $index => $volume) {
$parsed = parseDockerVolumeString($volume);
$source = $parsed['source'];
if (sourceIsLocal($source)) {
$volumesParsed->put($index, 'transformed_bind_'.$index);
} else {
if ($topLevelVolumes->has($source->value())) {
$temp = $topLevelVolumes->get($source->value());
if (data_get($temp, 'driver_opts.type') === 'cifs' || data_get($temp, 'driver_opts.type') === 'nfs') {
$volumesParsed->put($index, $volume);
continue;
}
}
$volumesParsed->put($index, 'uuid_transformed_'.$source->value().':'.$parsed['target']->value());
}
}
$volumesParsed = $volumesParsed->values();
expect($volumesParsed)->toHaveCount(5);
expect($volumesParsed->contains('test_stores:/stores'))->toBeTrue();
expect($volumesParsed->contains('test_backups:/backups'))->toBeTrue();
expect(array_keys($volumesParsed->toArray()))->toBe([0, 1, 2, 3, 4]);
$yaml = Yaml::dump(['volumes' => $volumesParsed->toArray()], 10, 2);
expect($yaml)->toContain("- 'test_stores:/stores'");
expect($yaml)->toContain("- 'test_backups:/backups'");
expect($yaml)->not->toContain('0:');
expect($yaml)->not->toContain('1:');
});
test('CIFS volumes are preserved the same way as NFS volumes', function () {
$topLevelVolumes = collect([
'cifs_share' => ['driver_opts' => ['type' => 'cifs', 'o' => 'addr=192.168.1.1', 'device' => '//server/share']],
]);
$volumesParsed = collect([]);
$volume = 'cifs_share:/data';
$parsed = parseDockerVolumeString($volume);
$source = $parsed['source'];
if ($topLevelVolumes->has($source->value())) {
$temp = $topLevelVolumes->get($source->value());
if (data_get($temp, 'driver_opts.type') === 'cifs' || data_get($temp, 'driver_opts.type') === 'nfs') {
$volumesParsed->put(0, $volume);
}
}
$volumesParsed = $volumesParsed->values();
expect($volumesParsed)->toHaveCount(1);
expect($volumesParsed->first())->toBe('cifs_share:/data');
});