fix(parser): preserve file volume state (#10843)
This commit is contained in:
parent
08e0d02643
commit
67693acce7
2 changed files with 179 additions and 23 deletions
|
|
@ -370,8 +370,6 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
|||
$pullRequestId = $pull_request_id;
|
||||
$isPullRequest = $pullRequestId == 0 ? false : true;
|
||||
$server = data_get($resource, 'destination.server');
|
||||
$fileStorages = $resource->fileStorages();
|
||||
|
||||
try {
|
||||
$yaml = Yaml::parse($compose);
|
||||
} catch (Exception) {
|
||||
|
|
@ -703,14 +701,11 @@ 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 = $fileStorages->whereMountPath($target)->first();
|
||||
$foundConfig = $originalResource->fileStorages()->whereMountPath($target)->first();
|
||||
if (sourceIsLocal($source)) {
|
||||
$type = str('bind');
|
||||
if ($foundConfig) {
|
||||
$contentNotNull_temp = data_get($foundConfig, 'content');
|
||||
if ($contentNotNull_temp) {
|
||||
$content = $contentNotNull_temp;
|
||||
}
|
||||
$content = data_get($foundConfig, 'content');
|
||||
$isDirectory = data_get($foundConfig, 'is_directory');
|
||||
} else {
|
||||
// By default, we cannot determine if the bind is a directory or not, so we set it to directory
|
||||
|
|
@ -756,12 +751,9 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
|||
}
|
||||
}
|
||||
|
||||
$foundConfig = $fileStorages->whereMountPath($target)->first();
|
||||
$foundConfig = $originalResource->fileStorages()->whereMountPath($target)->first();
|
||||
if ($foundConfig) {
|
||||
$contentNotNull_temp = data_get($foundConfig, 'content');
|
||||
if ($contentNotNull_temp) {
|
||||
$content = $contentNotNull_temp;
|
||||
}
|
||||
$content = data_get($foundConfig, 'content');
|
||||
$isDirectory = data_get($foundConfig, 'is_directory');
|
||||
} else {
|
||||
// if isDirectory is not set (or false) & content is also not set, we assume it is a directory
|
||||
|
|
@ -2070,7 +2062,6 @@ function serviceParser(Service $resource): Collection
|
|||
'service_id' => $resource->id,
|
||||
]);
|
||||
}
|
||||
$fileStorages = $savedService->fileStorages();
|
||||
if ($savedService->image !== $image) {
|
||||
$savedService->image = $image;
|
||||
$savedService->save();
|
||||
|
|
@ -2090,14 +2081,11 @@ function serviceParser(Service $resource): Collection
|
|||
$source = $parsed['source'];
|
||||
$target = $parsed['target'];
|
||||
// Mode is available in $parsed['mode'] if needed
|
||||
$foundConfig = $fileStorages->whereMountPath($target)->first();
|
||||
$foundConfig = $originalResource->fileStorages()->whereMountPath($target)->first();
|
||||
if (sourceIsLocal($source)) {
|
||||
$type = str('bind');
|
||||
if ($foundConfig) {
|
||||
$contentNotNull_temp = data_get($foundConfig, 'content');
|
||||
if ($contentNotNull_temp) {
|
||||
$content = $contentNotNull_temp;
|
||||
}
|
||||
$content = data_get($foundConfig, 'content');
|
||||
$isDirectory = data_get($foundConfig, 'is_directory');
|
||||
} else {
|
||||
// By default, we cannot determine if the bind is a directory or not, so we set it to directory
|
||||
|
|
@ -2143,12 +2131,9 @@ function serviceParser(Service $resource): Collection
|
|||
}
|
||||
}
|
||||
|
||||
$foundConfig = $fileStorages->whereMountPath($target)->first();
|
||||
$foundConfig = $originalResource->fileStorages()->whereMountPath($target)->first();
|
||||
if ($foundConfig) {
|
||||
$contentNotNull_temp = data_get($foundConfig, 'content');
|
||||
if ($contentNotNull_temp) {
|
||||
$content = $contentNotNull_temp;
|
||||
}
|
||||
$content = data_get($foundConfig, 'content');
|
||||
$isDirectory = data_get($foundConfig, 'is_directory');
|
||||
} else {
|
||||
// if isDirectory is not set (or false) & content is also not set, we assume it is a directory
|
||||
|
|
|
|||
171
tests/Feature/FileStorageParserStateTest.php
Normal file
171
tests/Feature/FileStorageParserStateTest.php
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Application;
|
||||
use App\Models\Environment;
|
||||
use App\Models\LocalFileVolume;
|
||||
use App\Models\Project;
|
||||
use App\Models\Server;
|
||||
use App\Models\Service;
|
||||
use App\Models\ServiceApplication;
|
||||
use App\Models\StandaloneDocker;
|
||||
use App\Models\Team;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Bus;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
const TWO_FILE_COMPOSE = <<<'YAML'
|
||||
services:
|
||||
app:
|
||||
image: nginx:latest
|
||||
volumes:
|
||||
- ./wg_config.conf:/app/ps/wg0.conf
|
||||
- ./override_trays.json:/app/ps/override_tray.json
|
||||
YAML;
|
||||
|
||||
const DATA_DIR_COMPOSE = <<<'YAML'
|
||||
services:
|
||||
app:
|
||||
image: nginx:latest
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
YAML;
|
||||
|
||||
beforeEach(function () {
|
||||
Bus::fake();
|
||||
|
||||
$team = Team::factory()->create();
|
||||
$server = Server::factory()->create(['team_id' => $team->id]);
|
||||
$destination = StandaloneDocker::where('server_id', $server->id)->first();
|
||||
$project = Project::factory()->create(['team_id' => $team->id]);
|
||||
$environment = Environment::factory()->create(['project_id' => $project->id]);
|
||||
|
||||
$this->destination = $destination;
|
||||
$this->environment = $environment;
|
||||
});
|
||||
|
||||
function makeComposeApplication(string $dockerComposeRaw): Application
|
||||
{
|
||||
return Application::factory()->create([
|
||||
'environment_id' => test()->environment->id,
|
||||
'destination_id' => test()->destination->id,
|
||||
'destination_type' => test()->destination->getMorphClass(),
|
||||
'build_pack' => 'dockercompose',
|
||||
'docker_compose_raw' => $dockerComposeRaw,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{0: Service, 1: ServiceApplication}
|
||||
*/
|
||||
function makeComposeService(string $dockerComposeRaw): array
|
||||
{
|
||||
$service = Service::factory()->create([
|
||||
'environment_id' => test()->environment->id,
|
||||
'server_id' => test()->destination->server_id,
|
||||
'destination_id' => test()->destination->id,
|
||||
'destination_type' => test()->destination->getMorphClass(),
|
||||
'docker_compose_raw' => $dockerComposeRaw,
|
||||
]);
|
||||
|
||||
$serviceApplication = ServiceApplication::create([
|
||||
'name' => 'app',
|
||||
'service_id' => $service->id,
|
||||
]);
|
||||
|
||||
return [$service, $serviceApplication];
|
||||
}
|
||||
|
||||
function seedFileVolume($resource, string $baseDir, string $fileName, string $mountPath, string $content): void
|
||||
{
|
||||
LocalFileVolume::create([
|
||||
'fs_path' => "{$baseDir}/{$fileName}",
|
||||
'mount_path' => $mountPath,
|
||||
'content' => $content,
|
||||
'is_directory' => false,
|
||||
'resource_id' => $resource->id,
|
||||
'resource_type' => $resource->getMorphClass(),
|
||||
]);
|
||||
}
|
||||
|
||||
it('preserves existing application file volume content when reparsing compose bind mounts', function () {
|
||||
$application = makeComposeApplication(TWO_FILE_COMPOSE);
|
||||
$baseDir = application_configuration_dir()."/{$application->uuid}";
|
||||
|
||||
seedFileVolume($application, $baseDir, 'wg_config.conf', '/app/ps/wg0.conf', 'test-conf');
|
||||
seedFileVolume($application, $baseDir, 'override_trays.json', '/app/ps/override_tray.json', '0');
|
||||
|
||||
applicationParser($application);
|
||||
|
||||
$fileVolume = $application->fileStorages()->where('mount_path', '/app/ps/override_tray.json')->first();
|
||||
|
||||
expect($fileVolume->content)->toBe('0')
|
||||
->and($fileVolume->is_directory)->toBeFalse();
|
||||
});
|
||||
|
||||
it('keeps existing application file volumes as files when content is empty', function () {
|
||||
$application = makeComposeApplication(TWO_FILE_COMPOSE);
|
||||
$baseDir = application_configuration_dir()."/{$application->uuid}";
|
||||
|
||||
seedFileVolume($application, $baseDir, 'wg_config.conf', '/app/ps/wg0.conf', 'test-conf');
|
||||
seedFileVolume($application, $baseDir, 'override_trays.json', '/app/ps/override_tray.json', '');
|
||||
|
||||
applicationParser($application);
|
||||
|
||||
$fileVolume = $application->fileStorages()->where('mount_path', '/app/ps/override_tray.json')->first();
|
||||
|
||||
expect($fileVolume->content)->toBe('')
|
||||
->and($fileVolume->is_directory)->toBeFalse();
|
||||
});
|
||||
|
||||
it('defaults new application bind mounts to directories', function () {
|
||||
$application = makeComposeApplication(DATA_DIR_COMPOSE);
|
||||
|
||||
applicationParser($application);
|
||||
|
||||
$fileVolume = $application->fileStorages()->where('mount_path', '/app/data')->first();
|
||||
|
||||
expect($fileVolume->content)->toBeNull()
|
||||
->and($fileVolume->is_directory)->toBeTrue();
|
||||
});
|
||||
|
||||
it('preserves existing service file volume content when reparsing compose bind mounts', function () {
|
||||
[$service, $serviceApplication] = makeComposeService(TWO_FILE_COMPOSE);
|
||||
$baseDir = service_configuration_dir()."/{$service->uuid}";
|
||||
|
||||
seedFileVolume($serviceApplication, $baseDir, 'wg_config.conf', '/app/ps/wg0.conf', 'test-conf');
|
||||
seedFileVolume($serviceApplication, $baseDir, 'override_trays.json', '/app/ps/override_tray.json', '0');
|
||||
|
||||
serviceParser($service);
|
||||
|
||||
$fileVolume = $serviceApplication->fileStorages()->where('mount_path', '/app/ps/override_tray.json')->first();
|
||||
|
||||
expect($fileVolume->content)->toBe('0')
|
||||
->and($fileVolume->is_directory)->toBeFalse();
|
||||
});
|
||||
|
||||
it('keeps existing service file volumes as files when content is empty', function () {
|
||||
[$service, $serviceApplication] = makeComposeService(TWO_FILE_COMPOSE);
|
||||
$baseDir = service_configuration_dir()."/{$service->uuid}";
|
||||
|
||||
seedFileVolume($serviceApplication, $baseDir, 'wg_config.conf', '/app/ps/wg0.conf', 'test-conf');
|
||||
seedFileVolume($serviceApplication, $baseDir, 'override_trays.json', '/app/ps/override_tray.json', '');
|
||||
|
||||
serviceParser($service);
|
||||
|
||||
$fileVolume = $serviceApplication->fileStorages()->where('mount_path', '/app/ps/override_tray.json')->first();
|
||||
|
||||
expect($fileVolume->content)->toBe('')
|
||||
->and($fileVolume->is_directory)->toBeFalse();
|
||||
});
|
||||
|
||||
it('defaults new service bind mounts to directories', function () {
|
||||
[$service, $serviceApplication] = makeComposeService(DATA_DIR_COMPOSE);
|
||||
|
||||
serviceParser($service);
|
||||
|
||||
$fileVolume = $serviceApplication->fileStorages()->where('mount_path', '/app/data')->first();
|
||||
|
||||
expect($fileVolume->content)->toBeNull()
|
||||
->and($fileVolume->is_directory)->toBeTrue();
|
||||
});
|
||||
Loading…
Reference in a new issue