From 62b84add36e14df16f211a42d5b3f43ba7ae34a0 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 11 Jul 2024 10:55:15 +0200 Subject: [PATCH] feat: compose parser v2 --- app/Models/Application.php | 3 + bootstrap/helpers/shared.php | 357 ++++++++++++------ ...11_083719_application_compose_versions.php | 28 ++ 3 files changed, 277 insertions(+), 111 deletions(-) create mode 100644 database/migrations/2024_07_11_083719_application_compose_versions.php diff --git a/app/Models/Application.php b/app/Models/Application.php index 47487d1f8..592607698 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -94,6 +94,7 @@ 'created_at' => ['type' => 'string', 'format' => 'date-time', 'description' => 'The date and time when the application was created.'], 'updated_at' => ['type' => 'string', 'format' => 'date-time', 'description' => 'The date and time when the application was last updated.'], 'deleted_at' => ['type' => 'string', 'format' => 'date-time', 'nullable' => true, 'description' => 'The date and time when the application was deleted.'], + 'compose_parsing_version' => ['type' => 'string', 'description' => 'How Coolify parse the compose file.'], ] )] @@ -122,6 +123,8 @@ protected static function booted() ApplicationSetting::create([ 'application_id' => $application->id, ]); + $application->compose_parsing_version = '2'; + $application->save(); }); static::deleting(function ($application) { $application->update(['fqdn' => null]); diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index 8cee3e4c6..1efe99436 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -1482,128 +1482,263 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal $baseName = generateApplicationContainerName($resource, $pull_request_id); $containerName = "$serviceName-$baseName"; - if (count($serviceVolumes) > 0) { - $serviceVolumes = $serviceVolumes->map(function ($volume) use ($resource, $topLevelVolumes, $pull_request_id) { - if (is_string($volume)) { - $volume = str($volume); - if ($volume->contains(':') && ! $volume->startsWith('/')) { - $name = $volume->before(':'); - $mount = $volume->after(':'); - if ($name->startsWith('.') || $name->startsWith('~')) { - $dir = base_configuration_dir().'/applications/'.$resource->uuid; - if ($name->startsWith('.')) { - $name = $name->replaceFirst('.', $dir); - } - if ($name->startsWith('~')) { - $name = $name->replaceFirst('~', $dir); - } - if ($pull_request_id !== 0) { - $name = $name."-pr-$pull_request_id"; - } - $volume = str("$name:$mount"); - } else { - if ($pull_request_id !== 0) { - $name = $name."-pr-$pull_request_id"; - $volume = str("$name:$mount"); - if ($topLevelVolumes->has($name)) { - $v = $topLevelVolumes->get($name); - if (data_get($v, 'driver_opts.type') === 'cifs') { - // Do nothing - } else { - if (is_null(data_get($v, 'name'))) { - data_set($v, 'name', $name); - data_set($topLevelVolumes, $name, $v); - } - } - } else { - $topLevelVolumes->put($name, [ - 'name' => $name, - ]); - } - } else { - if ($topLevelVolumes->has($name->value())) { - $v = $topLevelVolumes->get($name->value()); - if (data_get($v, 'driver_opts.type') === 'cifs') { - // Do nothing - } else { - if (is_null(data_get($v, 'name'))) { - data_set($topLevelVolumes, $name->value(), $v); - } - } - } else { - $topLevelVolumes->put($name->value(), [ - 'name' => $name->value(), - ]); - } - } - } - } else { - if ($volume->startsWith('/')) { + if ($resource->compose_parsing_version === '1') { + if (count($serviceVolumes) > 0) { + $serviceVolumes = $serviceVolumes->map(function ($volume) use ($resource, $topLevelVolumes, $pull_request_id) { + if (is_string($volume)) { + $volume = str($volume); + if ($volume->contains(':') && ! $volume->startsWith('/')) { $name = $volume->before(':'); $mount = $volume->after(':'); - if ($pull_request_id !== 0) { - $name = $name."-pr-$pull_request_id"; - } - $volume = str("$name:$mount"); - } - } - } elseif (is_array($volume)) { - $source = data_get($volume, 'source'); - $target = data_get($volume, 'target'); - $read_only = data_get($volume, 'read_only'); - if ($source && $target) { - if ((str($source)->startsWith('.') || str($source)->startsWith('~'))) { - $dir = base_configuration_dir().'/applications/'.$resource->uuid; - if (str($source, '.')) { - $source = str($source)->replaceFirst('.', $dir); - } - if (str($source, '~')) { - $source = str($source)->replaceFirst('~', $dir); - } - if ($pull_request_id !== 0) { - $source = $source."-pr-$pull_request_id"; - } - if ($read_only) { - data_set($volume, 'source', $source.':'.$target.':ro'); + if ($name->startsWith('.') || $name->startsWith('~')) { + $dir = base_configuration_dir().'/applications/'.$resource->uuid; + if ($name->startsWith('.')) { + $name = $name->replaceFirst('.', $dir); + } + if ($name->startsWith('~')) { + $name = $name->replaceFirst('~', $dir); + } + if ($pull_request_id !== 0) { + $name = $name."-pr-$pull_request_id"; + } + $volume = str("$name:$mount"); } else { - data_set($volume, 'source', $source.':'.$target); - } - } else { - if ($pull_request_id !== 0) { - $source = $source."-pr-$pull_request_id"; - } - if ($read_only) { - data_set($volume, 'source', $source.':'.$target.':ro'); - } else { - data_set($volume, 'source', $source.':'.$target); - } - if (! str($source)->startsWith('/')) { - if ($topLevelVolumes->has($source)) { - $v = $topLevelVolumes->get($source); - if (data_get($v, 'driver_opts.type') === 'cifs') { - // Do nothing - } else { - if (is_null(data_get($v, 'name'))) { - data_set($v, 'name', $source); - data_set($topLevelVolumes, $source, $v); + if ($pull_request_id !== 0) { + $name = $name."-pr-$pull_request_id"; + $volume = str("$name:$mount"); + if ($topLevelVolumes->has($name)) { + $v = $topLevelVolumes->get($name); + if (data_get($v, 'driver_opts.type') === 'cifs') { + // Do nothing + } else { + if (is_null(data_get($v, 'name'))) { + data_set($v, 'name', $name); + data_set($topLevelVolumes, $name, $v); + } } + } else { + $topLevelVolumes->put($name, [ + 'name' => $name, + ]); } } else { - $topLevelVolumes->put($source, [ - 'name' => $source, - ]); + if ($topLevelVolumes->has($name->value())) { + $v = $topLevelVolumes->get($name->value()); + if (data_get($v, 'driver_opts.type') === 'cifs') { + // Do nothing + } else { + if (is_null(data_get($v, 'name'))) { + data_set($topLevelVolumes, $name->value(), $v); + } + } + } else { + $topLevelVolumes->put($name->value(), [ + 'name' => $name->value(), + ]); + } + } + } + } else { + if ($volume->startsWith('/')) { + $name = $volume->before(':'); + $mount = $volume->after(':'); + if ($pull_request_id !== 0) { + $name = $name."-pr-$pull_request_id"; + } + $volume = str("$name:$mount"); + } + } + } elseif (is_array($volume)) { + $source = data_get($volume, 'source'); + $target = data_get($volume, 'target'); + $read_only = data_get($volume, 'read_only'); + if ($source && $target) { + if ((str($source)->startsWith('.') || str($source)->startsWith('~'))) { + $dir = base_configuration_dir().'/applications/'.$resource->uuid; + if (str($source, '.')) { + $source = str($source)->replaceFirst('.', $dir); + } + if (str($source, '~')) { + $source = str($source)->replaceFirst('~', $dir); + } + if ($pull_request_id !== 0) { + $source = $source."-pr-$pull_request_id"; + } + if ($read_only) { + data_set($volume, 'source', $source.':'.$target.':ro'); + } else { + data_set($volume, 'source', $source.':'.$target); + } + } else { + if ($pull_request_id !== 0) { + $source = $source."-pr-$pull_request_id"; + } + if ($read_only) { + data_set($volume, 'source', $source.':'.$target.':ro'); + } else { + data_set($volume, 'source', $source.':'.$target); + } + if (! str($source)->startsWith('/')) { + if ($topLevelVolumes->has($source)) { + $v = $topLevelVolumes->get($source); + if (data_get($v, 'driver_opts.type') === 'cifs') { + // Do nothing + } else { + if (is_null(data_get($v, 'name'))) { + data_set($v, 'name', $source); + data_set($topLevelVolumes, $source, $v); + } + } + } else { + $topLevelVolumes->put($source, [ + 'name' => $source, + ]); + } } } } } - } - if (is_array($volume)) { - return data_get($volume, 'source'); - } + if (is_array($volume)) { + return data_get($volume, 'source'); + } - return $volume->value(); - }); - data_set($service, 'volumes', $serviceVolumes->toArray()); + return $volume->value(); + }); + data_set($service, 'volumes', $serviceVolumes->toArray()); + } + } elseif ($resource->compose_parsing_version === '2') { + if (count($serviceVolumes) > 0) { + $serviceVolumes = $serviceVolumes->map(function ($volume) use ($resource, $topLevelVolumes, $pull_request_id) { + if (is_string($volume)) { + $volume = str($volume); + if ($volume->contains(':') && ! $volume->startsWith('/')) { + $name = $volume->before(':'); + $mount = $volume->after(':'); + if ($name->startsWith('.') || $name->startsWith('~')) { + $dir = base_configuration_dir().'/applications/'.$resource->uuid; + if ($name->startsWith('.')) { + $name = $name->replaceFirst('.', $dir); + } + if ($name->startsWith('~')) { + $name = $name->replaceFirst('~', $dir); + } + if ($pull_request_id !== 0) { + $name = $name."-pr-$pull_request_id"; + } + $volume = str("$name:$mount"); + } else { + if ($pull_request_id !== 0) { + $uuid = $resource->uuid; + $name = $uuid."-$name-pr-$pull_request_id"; + $volume = str("$name:$mount"); + if ($topLevelVolumes->has($name)) { + $v = $topLevelVolumes->get($name); + if (data_get($v, 'driver_opts.type') === 'cifs') { + // Do nothing + } else { + if (is_null(data_get($v, 'name'))) { + data_set($v, 'name', $name); + data_set($topLevelVolumes, $name, $v); + } + } + } else { + $topLevelVolumes->put($name, [ + 'name' => $name, + ]); + } + } else { + $uuid = $resource->uuid; + $name = str($uuid."-$name"); + $volume = str("$name:$mount"); + if ($topLevelVolumes->has($name->value())) { + $v = $topLevelVolumes->get($name->value()); + if (data_get($v, 'driver_opts.type') === 'cifs') { + // Do nothing + } else { + if (is_null(data_get($v, 'name'))) { + data_set($topLevelVolumes, $name->value(), $v); + } + } + } else { + $topLevelVolumes->put($name->value(), [ + 'name' => $name->value(), + ]); + } + } + } + } else { + if ($volume->startsWith('/')) { + $name = $volume->before(':'); + $mount = $volume->after(':'); + if ($pull_request_id !== 0) { + $name = $name."-pr-$pull_request_id"; + } + $volume = str("$name:$mount"); + } + } + } elseif (is_array($volume)) { + $source = data_get($volume, 'source'); + $target = data_get($volume, 'target'); + $read_only = data_get($volume, 'read_only'); + if ($source && $target) { + $uuid = $resource->uuid; + if ((str($source)->startsWith('.') || str($source)->startsWith('~'))) { + $dir = base_configuration_dir().'/applications/'.$resource->uuid; + if (str($source, '.')) { + $source = str($source)->replaceFirst('.', $dir); + } + if (str($source, '~')) { + $source = str($source)->replaceFirst('~', $dir); + } + if ($pull_request_id === 0) { + $source = $uuid."-$source"; + } else { + $source = $uuid."-$source-pr-$pull_request_id"; + } + if ($read_only) { + data_set($volume, 'source', $source.':'.$target.':ro'); + } else { + data_set($volume, 'source', $source.':'.$target); + } + } else { + if ($pull_request_id === 0) { + $source = $uuid."-$source"; + } else { + $source = $uuid."-$source-pr-$pull_request_id"; + } + if ($read_only) { + data_set($volume, 'source', $source.':'.$target.':ro'); + } else { + data_set($volume, 'source', $source.':'.$target); + } + if (! str($source)->startsWith('/')) { + if ($topLevelVolumes->has($source)) { + $v = $topLevelVolumes->get($source); + if (data_get($v, 'driver_opts.type') === 'cifs') { + // Do nothing + } else { + if (is_null(data_get($v, 'name'))) { + data_set($v, 'name', $source); + data_set($topLevelVolumes, $source, $v); + } + } + } else { + $topLevelVolumes->put($source, [ + 'name' => $source, + ]); + } + } + } + } + } + if (is_array($volume)) { + return data_get($volume, 'source'); + } + + return $volume->value(); + }); + data_set($service, 'volumes', $serviceVolumes->toArray()); + } } if ($pull_request_id !== 0 && count($serviceDependencies) > 0) { diff --git a/database/migrations/2024_07_11_083719_application_compose_versions.php b/database/migrations/2024_07_11_083719_application_compose_versions.php new file mode 100644 index 000000000..9cdbb98d7 --- /dev/null +++ b/database/migrations/2024_07_11_083719_application_compose_versions.php @@ -0,0 +1,28 @@ +string('compose_parsing_version')->default('1'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('applications', function (Blueprint $table) { + $table->dropColumn('compose_parsing_version'); + }); + } +};