From a7d67e44cae560b49c1e3eac31785eb4f0009a43 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 3 Sep 2024 11:47:30 +0200 Subject: [PATCH 1/4] fix: copy large compose files through scp (not ssh) --- app/Models/Service.php | 19 ++++++++++++------- bootstrap/helpers/shared.php | 1 - 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/app/Models/Service.php b/app/Models/Service.php index e55c0bea5..df44bb231 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -7,9 +7,10 @@ use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Storage; use OpenApi\Attributes as OA; use Spatie\Url\Url; -use Symfony\Component\Yaml\Yaml; +use Visus\Cuid2\Cuid2; #[OA\Schema( description: 'Service model', @@ -999,14 +1000,18 @@ public function workdir() public function saveComposeConfigs() { $workdir = $this->workdir(); - $commands[] = "mkdir -p $workdir"; - $commands[] = "cd $workdir"; - $json = Yaml::parse($this->docker_compose); - $this->docker_compose = Yaml::dump($json, 10, 2, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK); - $docker_compose_base64 = base64_encode($this->docker_compose); + instant_remote_process([ + "mkdir -p $workdir", + "cd $workdir", + ], $this->server); + + $filename = new Cuid2.'-docker-compose.yml'; + Storage::disk('local')->put("tmp/{$filename}", $this->docker_compose); + $path = Storage::path("tmp/{$filename}"); + instant_scp($path, "{$workdir}/docker-compose.yml", $this->server); + Storage::disk('local')->delete("tmp/{$filename}"); - $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(); diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index e7b42ea2c..aa114dec1 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -3544,7 +3544,6 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int $parsedServices->put($serviceName, $payload); } - ray($parsedServices); $topLevel->put('services', $parsedServices); $customOrder = ['services', 'volumes', 'networks', 'configs', 'secrets']; From 8d9a7f0b3c519394e062732148bae212a5cc0516 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 3 Sep 2024 11:48:06 +0200 Subject: [PATCH 2/4] chore: Update Coolify version to 4.0.0-beta.326 --- config/sentry.php | 2 +- config/version.php | 2 +- versions.json | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/sentry.php b/config/sentry.php index 53f5848ba..54e39e887 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.325', + 'release' => '4.0.0-beta.326', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index e82b0fd02..f567ea5da 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ Date: Tue, 3 Sep 2024 17:04:56 +0200 Subject: [PATCH 3/4] fix: check if array is associative or not --- bootstrap/helpers/shared.php | 48 ++++++++++++++++++++--------- tests/Feature/ConvertArraysTest.php | 7 +++++ 2 files changed, 41 insertions(+), 14 deletions(-) create mode 100644 tests/Feature/ConvertArraysTest.php diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index aa114dec1..24d7e4045 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -3573,6 +3573,23 @@ function generate_fluentd_configuration(): array ]; } +function isAssociativeArray($array) +{ + if ($array instanceof Collection) { + $array = $array->toArray(); + } + + if (! is_array($array)) { + throw new \InvalidArgumentException('Input must be an array or a Collection.'); + } + + if ($array === []) { + return false; + } + + return array_keys($array) !== range(0, count($array) - 1); +} + /** * This method adds the default environment variables to the resource. * - COOLIFY_APP_NAME @@ -3584,42 +3601,45 @@ function generate_fluentd_configuration(): array */ function add_coolify_default_environment_variables(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|StandaloneKeydb|StandaloneDragonfly|StandaloneClickhouse|Application|Service $resource, Collection &$where_to_add, ?Collection $where_to_check = null) { + if ($resource instanceof Service) { + $ip = $resource->server->ip; + } else { + $ip = $resource->destination->server->ip; + } + if (isAssociativeArray($where_to_add)) { + $isAssociativeArray = true; + } else { + $isAssociativeArray = false; + } if ($where_to_check != null && $where_to_check->where('key', 'COOLIFY_APP_NAME')->isEmpty()) { - if ($resource instanceof Application && $resource->build_pack === 'dockercompose') { - $where_to_add->put('COOLIFY_APP_NAME', $resource->name); - } elseif ($resource instanceof Service) { + if ($isAssociativeArray) { $where_to_add->put('COOLIFY_APP_NAME', $resource->name); } else { $where_to_add->push("COOLIFY_APP_NAME={$resource->name}"); } } if ($where_to_check != null && $where_to_check->where('key', 'COOLIFY_SERVER_IP')->isEmpty()) { - if ($resource instanceof Application && $resource->build_pack === 'dockercompose') { - $where_to_add->put('COOLIFY_SERVER_IP', $resource->destination->server->ip); - } elseif ($resource instanceof Service) { - $where_to_add->put('COOLIFY_SERVER_IP', $resource->server->ip); + if ($isAssociativeArray) { + $where_to_add->put('COOLIFY_SERVER_IP', $ip); } else { - $where_to_add->push("COOLIFY_SERVER_IP={$resource->destination->server->ip}"); + $where_to_add->push("COOLIFY_SERVER_IP={$ip}"); } } if ($where_to_check != null && $where_to_check->where('key', 'COOLIFY_ENVIRONMENT_NAME')->isEmpty()) { - if ($resource instanceof Application && $resource->build_pack === 'dockercompose') { - $where_to_add->put('COOLIFY_ENVIRONMENT_NAME', $resource->environment->name); - } elseif ($resource instanceof Service) { + if ($isAssociativeArray) { $where_to_add->put('COOLIFY_ENVIRONMENT_NAME', $resource->environment->name); } else { $where_to_add->push("COOLIFY_ENVIRONMENT_NAME={$resource->environment->name}"); } } if ($where_to_check != null && $where_to_check->where('key', 'COOLIFY_PROJECT_NAME')->isEmpty()) { - if ($resource instanceof Application && $resource->build_pack === 'dockercompose') { - $where_to_add->put('COOLIFY_PROJECT_NAME', $resource->project()->name); - } elseif ($resource instanceof Service) { + if ($isAssociativeArray) { $where_to_add->put('COOLIFY_PROJECT_NAME', $resource->project()->name); } else { $where_to_add->push("COOLIFY_PROJECT_NAME={$resource->project()->name}"); } } + ray($where_to_add); } function convertComposeEnvironmentToArray($environment) diff --git a/tests/Feature/ConvertArraysTest.php b/tests/Feature/ConvertArraysTest.php new file mode 100644 index 000000000..97cfe101d --- /dev/null +++ b/tests/Feature/ConvertArraysTest.php @@ -0,0 +1,7 @@ +toBeFalse(); + expect(isAssociativeArray(collect([1, 2, 3])))->toBeFalse(); + expect(isAssociativeArray(collect(['a' => 1, 'b' => 2, 'c' => 3])))->toBeTrue(); +}); From 7b041f3f222908407457d8e1bb2c5eb5f69bec3b Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 3 Sep 2024 17:13:13 +0200 Subject: [PATCH 4/4] refactor: Improve handling of COOLIFY_URL in shared.php --- bootstrap/helpers/shared.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index 24d7e4045..7ef02fff9 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -3425,7 +3425,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int $defaultLabels = defaultLabels($resource->id, $containerName, type: 'service', subType: $isDatabase ? 'database' : 'application', subId: $savedService->id); } // Add COOLIFY_FQDN & COOLIFY_URL to environment - if (! $isDatabase && $fqdns?->count() > 0) { + if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) { $environment->put('COOLIFY_URL', $fqdns->implode(',')); $urls = $fqdns->map(function ($fqdn) { @@ -3436,7 +3436,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int add_coolify_default_environment_variables($resource, $environment, $resource->environment_variables); $serviceLabels = $labels->merge($defaultLabels); - if (! $isDatabase && $fqdns?->count() > 0) { + if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) { if ($isApplication) { $shouldGenerateLabelsExactly = $resource->destination->server->settings->generate_exact_labels; $uuid = $resource->uuid; @@ -3667,7 +3667,9 @@ function convertComposeEnvironmentToArray($environment) } } } - $convertedServiceVariables->put($key->value(), $value?->value() ?? null); + if ($key) { + $convertedServiceVariables->put($key->value(), $value?->value() ?? null); + } } return $convertedServiceVariables;