fix(parsers): enhance volume string handling by preserving mode in application and service parsers. Update related unit tests for validation.
This commit is contained in:
@@ -551,8 +551,14 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
|||||||
if ($type->value() === 'bind') {
|
if ($type->value() === 'bind') {
|
||||||
if ($source->value() === '/var/run/docker.sock') {
|
if ($source->value() === '/var/run/docker.sock') {
|
||||||
$volume = $source->value().':'.$target->value();
|
$volume = $source->value().':'.$target->value();
|
||||||
|
if (isset($parsed['mode']) && $parsed['mode']) {
|
||||||
|
$volume .= ':'.$parsed['mode']->value();
|
||||||
|
}
|
||||||
} elseif ($source->value() === '/tmp' || $source->value() === '/tmp/') {
|
} elseif ($source->value() === '/tmp' || $source->value() === '/tmp/') {
|
||||||
$volume = $source->value().':'.$target->value();
|
$volume = $source->value().':'.$target->value();
|
||||||
|
if (isset($parsed['mode']) && $parsed['mode']) {
|
||||||
|
$volume .= ':'.$parsed['mode']->value();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((int) $resource->compose_parsing_version >= 4) {
|
if ((int) $resource->compose_parsing_version >= 4) {
|
||||||
$mainDirectory = str(base_configuration_dir().'/applications/'.$uuid);
|
$mainDirectory = str(base_configuration_dir().'/applications/'.$uuid);
|
||||||
@@ -586,6 +592,9 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$volume = "$source:$target";
|
$volume = "$source:$target";
|
||||||
|
if (isset($parsed['mode']) && $parsed['mode']) {
|
||||||
|
$volume .= ':'.$parsed['mode']->value();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} elseif ($type->value() === 'volume') {
|
} elseif ($type->value() === 'volume') {
|
||||||
if ($topLevel->get('volumes')->has($source->value())) {
|
if ($topLevel->get('volumes')->has($source->value())) {
|
||||||
@@ -609,6 +618,9 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
|||||||
$target = $parsed['target'];
|
$target = $parsed['target'];
|
||||||
$source = $name;
|
$source = $name;
|
||||||
$volume = "$source:$target";
|
$volume = "$source:$target";
|
||||||
|
if (isset($parsed['mode']) && $parsed['mode']) {
|
||||||
|
$volume .= ':'.$parsed['mode']->value();
|
||||||
|
}
|
||||||
} elseif (is_array($volume)) {
|
} elseif (is_array($volume)) {
|
||||||
data_set($volume, 'source', $name);
|
data_set($volume, 'source', $name);
|
||||||
}
|
}
|
||||||
@@ -1562,8 +1574,14 @@ function serviceParser(Service $resource): Collection
|
|||||||
if ($type->value() === 'bind') {
|
if ($type->value() === 'bind') {
|
||||||
if ($source->value() === '/var/run/docker.sock') {
|
if ($source->value() === '/var/run/docker.sock') {
|
||||||
$volume = $source->value().':'.$target->value();
|
$volume = $source->value().':'.$target->value();
|
||||||
|
if (isset($parsed['mode']) && $parsed['mode']) {
|
||||||
|
$volume .= ':'.$parsed['mode']->value();
|
||||||
|
}
|
||||||
} elseif ($source->value() === '/tmp' || $source->value() === '/tmp/') {
|
} elseif ($source->value() === '/tmp' || $source->value() === '/tmp/') {
|
||||||
$volume = $source->value().':'.$target->value();
|
$volume = $source->value().':'.$target->value();
|
||||||
|
if (isset($parsed['mode']) && $parsed['mode']) {
|
||||||
|
$volume .= ':'.$parsed['mode']->value();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((int) $resource->compose_parsing_version >= 4) {
|
if ((int) $resource->compose_parsing_version >= 4) {
|
||||||
$mainDirectory = str(base_configuration_dir().'/services/'.$uuid);
|
$mainDirectory = str(base_configuration_dir().'/services/'.$uuid);
|
||||||
@@ -1594,6 +1612,9 @@ function serviceParser(Service $resource): Collection
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$volume = "$source:$target";
|
$volume = "$source:$target";
|
||||||
|
if (isset($parsed['mode']) && $parsed['mode']) {
|
||||||
|
$volume .= ':'.$parsed['mode']->value();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} elseif ($type->value() === 'volume') {
|
} elseif ($type->value() === 'volume') {
|
||||||
if ($topLevel->get('volumes')->has($source->value())) {
|
if ($topLevel->get('volumes')->has($source->value())) {
|
||||||
@@ -1614,6 +1635,9 @@ function serviceParser(Service $resource): Collection
|
|||||||
$target = $parsed['target'];
|
$target = $parsed['target'];
|
||||||
$source = $name;
|
$source = $name;
|
||||||
$volume = "$source:$target";
|
$volume = "$source:$target";
|
||||||
|
if (isset($parsed['mode']) && $parsed['mode']) {
|
||||||
|
$volume .= ':'.$parsed['mode']->value();
|
||||||
|
}
|
||||||
} elseif (is_array($volume)) {
|
} elseif (is_array($volume)) {
|
||||||
data_set($volume, 'source', $name);
|
data_set($volume, 'source', $name);
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,8 @@
|
|||||||
:resource="$resource" :isFirst="$loop->first" isReadOnly='true' isService='true' />
|
:resource="$resource" :isFirst="$loop->first" isReadOnly='true' isService='true' />
|
||||||
@else
|
@else
|
||||||
<livewire:project.shared.storages.show wire:key="storage-{{ $storage->id }}" :storage="$storage"
|
<livewire:project.shared.storages.show wire:key="storage-{{ $storage->id }}" :storage="$storage"
|
||||||
:resource="$resource" isReadOnly="{{ data_get($storage, 'is_readonly') }}"
|
:resource="$resource"
|
||||||
|
isReadOnly="{{ data_get($storage, 'is_readonly') || $resource?->build_pack === 'dockercompose' ? true : false }}"
|
||||||
startedAt="{{ data_get($resource, 'started_at') }}" />
|
startedAt="{{ data_get($resource, 'started_at') }}" />
|
||||||
@endif
|
@endif
|
||||||
@endforeach
|
@endforeach
|
||||||
|
@@ -191,3 +191,31 @@ test('parses complex real-world examples', function () {
|
|||||||
expect($result['target']->value())->toBe('/var/lib/app-data');
|
expect($result['target']->value())->toBe('/var/lib/app-data');
|
||||||
expect($result['mode'])->toBeNull();
|
expect($result['mode'])->toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('preserves mode when reconstructing volume strings', function () {
|
||||||
|
// Test cases that specifically verify mode preservation
|
||||||
|
$testCases = [
|
||||||
|
'/var/run/docker.sock:/var/run/docker.sock:ro' => ['source' => '/var/run/docker.sock', 'target' => '/var/run/docker.sock', 'mode' => 'ro'],
|
||||||
|
'/etc/localtime:/etc/localtime:ro' => ['source' => '/etc/localtime', 'target' => '/etc/localtime', 'mode' => 'ro'],
|
||||||
|
'/tmp:/tmp:rw' => ['source' => '/tmp', 'target' => '/tmp', 'mode' => 'rw'],
|
||||||
|
'gitea-data:/data:ro' => ['source' => 'gitea-data', 'target' => '/data', 'mode' => 'ro'],
|
||||||
|
'./config:/app/config:cached' => ['source' => './config', 'target' => '/app/config', 'mode' => 'cached'],
|
||||||
|
'volume:/data:delegated' => ['source' => 'volume', 'target' => '/data', 'mode' => 'delegated'],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($testCases as $input => $expected) {
|
||||||
|
$result = parseDockerVolumeString($input);
|
||||||
|
|
||||||
|
// Verify parsing
|
||||||
|
expect($result['source']->value())->toBe($expected['source']);
|
||||||
|
expect($result['target']->value())->toBe($expected['target']);
|
||||||
|
expect($result['mode']->value())->toBe($expected['mode']);
|
||||||
|
|
||||||
|
// Verify reconstruction would preserve the mode
|
||||||
|
$reconstructed = $result['source']->value().':'.$result['target']->value();
|
||||||
|
if ($result['mode']) {
|
||||||
|
$reconstructed .= ':'.$result['mode']->value();
|
||||||
|
}
|
||||||
|
expect($reconstructed)->toBe($input);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Reference in New Issue
Block a user