From 1266810c4d8edfd2522ba8a7ab703f522c0e34cd Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 25 Jun 2024 10:34:56 +0200 Subject: [PATCH] fix: better parsign performance for huge compose files fix: env parsing --- app/Livewire/Project/Service/EditCompose.php | 13 ++- .../Shared/EnvironmentVariable/Show.php | 2 +- app/Models/Service.php | 23 +----- bootstrap/helpers/shared.php | 81 ++++++++++++------- 4 files changed, 66 insertions(+), 53 deletions(-) diff --git a/app/Livewire/Project/Service/EditCompose.php b/app/Livewire/Project/Service/EditCompose.php index c9bdf12fc..f67b95a8a 100644 --- a/app/Livewire/Project/Service/EditCompose.php +++ b/app/Livewire/Project/Service/EditCompose.php @@ -11,7 +11,7 @@ class EditCompose extends Component public $serviceId; - protected $listeners = ['refreshEnvs' => 'mount']; + protected $listeners = ['refreshEnvs', 'envsUpdated']; protected $rules = [ 'service.docker_compose_raw' => 'required', @@ -19,6 +19,17 @@ class EditCompose extends Component 'service.is_container_label_escape_enabled' => 'required', ]; + public function envsUpdated() + { + $this->dispatch('saveCompose', $this->service->docker_compose_raw); + $this->refreshEnvs(); + } + + public function refreshEnvs() + { + $this->service = Service::find($this->serviceId); + } + public function mount() { $this->service = Service::find($this->serviceId); diff --git a/app/Livewire/Project/Shared/EnvironmentVariable/Show.php b/app/Livewire/Project/Shared/EnvironmentVariable/Show.php index e77c05d6b..c21d899e5 100644 --- a/app/Livewire/Project/Shared/EnvironmentVariable/Show.php +++ b/app/Livewire/Project/Shared/EnvironmentVariable/Show.php @@ -112,7 +112,7 @@ public function submit() $this->serialize(); $this->env->save(); $this->dispatch('success', 'Environment variable updated.'); - $this->dispatch('refreshEnvs'); + $this->dispatch('envsUpdated'); } catch (\Exception $e) { return handleError($e); } diff --git a/app/Models/Service.php b/app/Models/Service.php index 05c380a4c..cc6a20749 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -839,33 +839,13 @@ public function saveComposeConfigs() $commands[] = "cd $workdir"; $json = Yaml::parse($this->docker_compose); - $envs_from_coolify = $this->environment_variables()->get(); - // foreach ($json['services'] as $service => $config) { - // if (data_get($config, 'environment') === null) { - // data_set($json, "services.$service.environment", []); - // $envs = collect([]); - // } else { - // $envs = collect($config['environment']); - // } - // // $envs->put('COOLIFY_CONTAINER_NAME', "$service-{$this->uuid}"); - // foreach ($envs_from_coolify as $env) { - // $envs = $envs->map(function ($value) use ($env) { - // if (str($value)->startsWith($env->key)) { - // return "{$env->key}={$env->real_value}"; - // } - - // return $value; - // }); - // } - // $envs = $envs->unique(); - // data_set($json, "services.$service.environment", $envs->toArray()); - // } $this->docker_compose = Yaml::dump($json, 10, 2, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK); $docker_compose_base64 = base64_encode($this->docker_compose); $commands[] = "echo $docker_compose_base64 | base64 -d | tee docker-compose.yml > /dev/null"; $commands[] = 'rm -f .env || true'; + $envs_from_coolify = $this->environment_variables()->get(); foreach ($envs_from_coolify as $env) { $commands[] = "echo '{$env->key}={$env->real_value}' >> .env"; } @@ -884,7 +864,6 @@ public function networks() { $networks = getTopLevelNetworks($this); - // ray($networks); return $networks; } } diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index aef362491..fe51f78ac 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -469,7 +469,7 @@ function data_get_str($data, $key, $default = null): Stringable { $str = data_get($data, $key, $default) ?? $default; - return Str::of($str); + return str($str); } function generateFqdn(Server $server, string $random) @@ -933,12 +933,12 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal $content = null; $isDirectory = false; if (is_string($volume)) { - $source = Str::of($volume)->before(':'); - $target = Str::of($volume)->after(':')->beforeLast(':'); + $source = str($volume)->before(':'); + $target = str($volume)->after(':')->beforeLast(':'); if ($source->startsWith('./') || $source->startsWith('/') || $source->startsWith('~')) { - $type = Str::of('bind'); + $type = str('bind'); } else { - $type = Str::of('volume'); + $type = str('volume'); } } elseif (is_array($volume)) { $type = data_get_str($volume, 'type'); @@ -987,8 +987,8 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal $slugWithoutUuid = Str::slug($source, '-'); $name = "{$savedService->service->uuid}_{$slugWithoutUuid}"; if (is_string($volume)) { - $source = Str::of($volume)->before(':'); - $target = Str::of($volume)->after(':')->beforeLast(':'); + $source = str($volume)->before(':'); + $target = str($volume)->after(':')->beforeLast(':'); $source = $name; $volume = "$source:$target"; } elseif (is_array($volume)) { @@ -1032,7 +1032,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal // Get variables from the service foreach ($serviceVariables as $variableName => $variable) { if (is_numeric($variableName)) { - $variable = Str::of($variable); + $variable = str($variable); if ($variable->contains('=')) { // - SESSION_SECRET=123 // - SESSION_SECRET= @@ -1046,8 +1046,8 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal } else { // SESSION_SECRET: 123 // SESSION_SECRET: - $key = Str::of($variableName); - $value = Str::of($variable); + $key = str($variableName); + $value = str($variable); } if ($key->startsWith('SERVICE_FQDN')) { if ($isNew || $savedService->fqdn === null) { @@ -1137,7 +1137,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal 'key' => $key, 'service_id' => $resource->id, ])->first(); - $value = Str::of(replaceVariables($value)); + $value = str(replaceVariables($value)); $key = $value; if ($value->startsWith('SERVICE_')) { $foundEnv = EnvironmentVariable::where([ @@ -1170,7 +1170,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal // } } else { if ($command->value() === 'URL') { - $fqdn = Str::of($fqdn)->after('://')->value(); + $fqdn = str($fqdn)->after('://')->value(); } EnvironmentVariable::create([ 'key' => $key, @@ -1254,18 +1254,6 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal ]); } } - $envs_from_coolify = $resource->environment_variables()->get(); - $serviceVariables = $serviceVariables->map(function ($variable) use ($envs_from_coolify) { - $env_variable_key = str($variable)->before('='); - $env_variable_value = str($variable)->after('='); - $found_env = $envs_from_coolify->where('key', $env_variable_key)->first(); - if ($found_env) { - $env_variable_value = $found_env->value; - } - - return "$env_variable_key=$env_variable_value"; - }); - } // Add labels to the service if ($savedService->serviceType()) { @@ -1333,6 +1321,41 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal data_set($service, 'environment', $serviceVariables->toArray()); updateCompose($savedService); + return $service; + + }); + + $envs_from_coolify = $resource->environment_variables()->get(); + $services = collect($services)->map(function ($service, $serviceName) use ($resource, $envs_from_coolify) { + $serviceVariables = collect(data_get($service, 'environment', [])); + $parsedServiceVariables = collect([]); + foreach ($serviceVariables as $key => $value) { + if (is_numeric($key)) { + $value = str($value); + if ($value->contains('=')) { + $key = $value->before('=')->value(); + $value = $value->after('=')->value(); + } else { + $key = $value->value(); + $value = null; + } + $parsedServiceVariables->put($key, $value); + } else { + $parsedServiceVariables->put($key, $value); + } + } + $parsedServiceVariables->put('COOLIFY_CONTAINER_NAME', "$serviceName-{$resource->uuid}"); + $parsedServiceVariables = $parsedServiceVariables->map(function ($value, $key) use ($envs_from_coolify) { + $found_env = $envs_from_coolify->where('key', $key)->first(); + if ($found_env) { + return $found_env->value; + } + + return $value; + }); + + data_set($service, 'environment', $parsedServiceVariables->toArray()); + return $service; }); $finalServices = [ @@ -1637,7 +1660,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal // Get variables from the service foreach ($serviceVariables as $variableName => $variable) { if (is_numeric($variableName)) { - $variable = Str::of($variable); + $variable = str($variable); if ($variable->contains('=')) { // - SESSION_SECRET=123 // - SESSION_SECRET= @@ -1651,8 +1674,8 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal } else { // SESSION_SECRET: 123 // SESSION_SECRET: - $key = Str::of($variableName); - $value = Str::of($variable); + $key = str($variableName); + $value = str($variable); } if ($key->startsWith('SERVICE_FQDN')) { if ($isNew) { @@ -1696,7 +1719,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal 'application_id' => $resource->id, 'is_preview' => false, ])->first(); - $value = Str::of(replaceVariables($value)); + $value = str(replaceVariables($value)); $key = $value; if ($value->startsWith('SERVICE_')) { $foundEnv = EnvironmentVariable::where([ @@ -1718,7 +1741,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal $fqdn = data_get($foundEnv, 'value'); } else { if ($command?->value() === 'URL') { - $fqdn = Str::of($fqdn)->after('://')->value(); + $fqdn = str($fqdn)->after('://')->value(); } EnvironmentVariable::create([ 'key' => $key,