From 4b74ca56c387ee469797e3217ae1d4f55e20fd92 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 21 Jan 2025 14:09:07 +0100 Subject: [PATCH] feat(core): wip version of coolify.json --- app/Livewire/Project/Application/General.php | 1 + app/Models/Application.php | 45 ++-- app/Services/ConfigurationGenerator.php | 194 ++++++++++++++++++ app/Traits/HasConfiguration.php | 42 ++++ .../project/application/general.blade.php | 11 +- 5 files changed, 263 insertions(+), 30 deletions(-) create mode 100644 app/Services/ConfigurationGenerator.php create mode 100644 app/Traits/HasConfiguration.php diff --git a/app/Livewire/Project/Application/General.php b/app/Livewire/Project/Application/General.php index 576f87801..f8e28d216 100644 --- a/app/Livewire/Project/Application/General.php +++ b/app/Livewire/Project/Application/General.php @@ -442,6 +442,7 @@ class General extends Component { $config = GenerateConfig::run($this->application, true); $fileName = str($this->application->name)->slug()->append('_config.json'); + dd($config); return response()->streamDownload(function () use ($config) { echo $config; diff --git a/app/Models/Application.php b/app/Models/Application.php index 289ef5b0f..3913ce37a 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -3,6 +3,8 @@ namespace App\Models; use App\Enums\ApplicationDeploymentStatus; +use App\Services\ConfigurationGenerator; +use App\Traits\HasConfiguration; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -105,7 +107,7 @@ use Visus\Cuid2\Cuid2; class Application extends BaseModel { - use HasFactory, SoftDeletes; + use HasConfiguration, HasFactory, SoftDeletes; private static $parserVersion = '4'; @@ -1640,35 +1642,28 @@ class Application extends BaseModel } } + public function getLimits(): array + { + return [ + 'limits_memory' => $this->limits_memory, + 'limits_memory_swap' => $this->limits_memory_swap, + 'limits_memory_swappiness' => $this->limits_memory_swappiness, + 'limits_memory_reservation' => $this->limits_memory_reservation, + 'limits_cpus' => $this->limits_cpus, + 'limits_cpuset' => $this->limits_cpuset, + 'limits_cpu_shares' => $this->limits_cpu_shares, + ]; + } + public function generateConfig($is_json = false) { - $config = collect([]); - if ($this->build_pack = 'nixpacks') { - $config = collect([ - 'build_pack' => 'nixpacks', - 'docker_registry_image_name' => $this->docker_registry_image_name, - 'docker_registry_image_tag' => $this->docker_registry_image_tag, - 'install_command' => $this->install_command, - 'build_command' => $this->build_command, - 'start_command' => $this->start_command, - 'base_directory' => $this->base_directory, - 'publish_directory' => $this->publish_directory, - 'custom_docker_run_options' => $this->custom_docker_run_options, - 'ports_exposes' => $this->ports_exposes, - 'ports_mappings' => $this->ports_mapping, - 'settings' => collect([ - 'is_static' => $this->settings->is_static, - ]), - ]); - } - $config = $config->filter(function ($value) { - return str($value)->isNotEmpty(); - }); + $generator = new ConfigurationGenerator($this); + if ($is_json) { - return json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + return $generator->toJson(); } - return $config; + return $generator->toArray(); } public function setConfig($config) diff --git a/app/Services/ConfigurationGenerator.php b/app/Services/ConfigurationGenerator.php new file mode 100644 index 000000000..a7e4b31be --- /dev/null +++ b/app/Services/ConfigurationGenerator.php @@ -0,0 +1,194 @@ +generateConfig(); + } + + protected function generateConfig(): void + { + if ($this->resource instanceof Application) { + $this->config = [ + 'id' => $this->resource->id, + 'name' => $this->resource->name, + 'uuid' => $this->resource->uuid, + 'description' => $this->resource->description, + 'coolify_details' => [ + 'project_uuid' => $this->resource->project()->uuid, + 'environment_uuid' => $this->resource->environment->uuid, + + 'destination_type' => $this->resource->destination_type, + 'destination_id' => $this->resource->destination_id, + 'source_type' => $this->resource->source_type, + 'source_id' => $this->resource->source_id, + 'private_key_id' => $this->resource->private_key_id, + ], + + 'post_deployment_command' => $this->resource->post_deployment_command, + 'post_deployment_command_container' => $this->resource->post_deployment_command_container, + 'pre_deployment_command' => $this->resource->pre_deployment_command, + 'pre_deployment_command_container' => $this->resource->pre_deployment_command_container, + 'build' => [ + 'type' => $this->resource->build_pack, + 'static_image' => $this->resource->static_image, + 'base_directory' => $this->resource->base_directory, + 'publish_directory' => $this->resource->publish_directory, + 'dockerfile' => $this->resource->dockerfile, + 'dockerfile_location' => $this->resource->dockerfile_location, + 'dockerfile_target_build' => $this->resource->dockerfile_target_build, + 'custom_docker_run_options' => $this->resource->custom_docker_options, + 'compose_parsing_version' => $this->resource->compose_parsing_version, + 'docker_compose' => $this->resource->docker_compose, + 'docker_compose_location' => $this->resource->docker_compose_location, + 'docker_compose_raw' => $this->resource->docker_compose_raw, + 'docker_compose_domains' => $this->resource->docker_compose_domains, + 'docker_compose_custom_start_command' => $this->resource->docker_compose_custom_start_command, + 'docker_compose_custom_build_command' => $this->resource->docker_compose_custom_build_command, + 'install_command' => $this->resource->install_command, + 'build_command' => $this->resource->build_command, + 'start_command' => $this->resource->start_command, + 'watch_paths' => $this->resource->watch_paths, + ], + 'source' => [ + 'git_repository' => $this->resource->git_repository, + 'git_branch' => $this->resource->git_branch, + 'git_commit_sha' => $this->resource->git_commit_sha, + 'repository_project_id' => $this->resource->repository_project_id, + ], + 'docker_registry_image' => $this->getDockerRegistryImage(), + 'domains' => [ + 'fqdn' => $this->resource->fqdn, + 'ports_exposes' => $this->resource->ports_exposes, + 'ports_mappings' => $this->resource->ports_mappings, + 'redirect' => $this->resource->redirect, + 'custom_nginx_configuration' => $this->resource->custom_nginx_configuration, + ], + 'environment_variables' => [ + 'production' => $this->getEnvironmentVariables(), + 'preview' => $this->getPreviewEnvironmentVariables(), + ], + 'settings' => $this->getApplicationSettings(), + 'preview' => $this->getPreview(), + 'limits' => $this->resource->getLimits(), + 'health_check' => [ + 'health_check_path' => $this->resource->health_check_path, + 'health_check_port' => $this->resource->health_check_port, + 'health_check_host' => $this->resource->health_check_host, + 'health_check_method' => $this->resource->health_check_method, + 'health_check_return_code' => $this->resource->health_check_return_code, + 'health_check_scheme' => $this->resource->health_check_scheme, + 'health_check_response_text' => $this->resource->health_check_response_text, + 'health_check_interval' => $this->resource->health_check_interval, + 'health_check_timeout' => $this->resource->health_check_timeout, + 'health_check_retries' => $this->resource->health_check_retries, + 'health_check_start_period' => $this->resource->health_check_start_period, + 'health_check_enabled' => $this->resource->health_check_enabled, + ], + 'webhooks_secrets' => [ + 'manual_webhook_secret_github' => $this->resource->manual_webhook_secret_github, + 'manual_webhook_secret_gitlab' => $this->resource->manual_webhook_secret_gitlab, + 'manual_webhook_secret_bitbucket' => $this->resource->manual_webhook_secret_bitbucket, + 'manual_webhook_secret_gitea' => $this->resource->manual_webhook_secret_gitea, + ], + 'swarm' => [ + 'swarm_replicas' => $this->resource->swarm_replicas, + 'swarm_placement_constraints' => $this->resource->swarm_placement_constraints, + ], + ]; + } + } + + protected function getPreview(): array + { + return [ + 'preview_url_template' => $this->resource->preview_url_template, + ]; + } + + protected function getDockerRegistryImage(): array + { + return [ + 'image' => $this->resource->docker_registry_image_name, + 'tag' => $this->resource->docker_registry_image_tag, + ]; + } + + protected function getEnvironmentVariables(): array + { + $variables = collect([]); + foreach ($this->resource->environment_variables as $env) { + $variables->push([ + 'key' => $env->key, + 'value' => $env->value, + 'is_build_time' => $env->is_build_time, + 'is_preview' => $env->is_preview, + 'is_multiline' => $env->is_multiline, + ]); + } + + return $variables->toArray(); + } + + protected function getPreviewEnvironmentVariables(): array + { + $variables = collect([]); + foreach ($this->resource->environment_variables_preview as $env) { + $variables->push([ + 'key' => $env->key, + 'value' => $env->value, + 'is_build_time' => $env->is_build_time, + 'is_preview' => $env->is_preview, + 'is_multiline' => $env->is_multiline, + ]); + } + + return $variables->toArray(); + } + + protected function getApplicationSettings(): array + { + $removedKeys = ['id', 'application_id', 'created_at', 'updated_at']; + $settings = $this->resource->settings->attributesToArray(); + $settings = collect($settings)->filter(function ($value, $key) use ($removedKeys) { + return ! in_array($key, $removedKeys); + })->sortBy(function ($value, $key) { + return $key; + })->toArray(); + + return $settings; + } + + public function saveJson(string $path): void + { + file_put_contents($path, json_encode($this->config, JSON_PRETTY_PRINT)); + } + + public function saveYaml(string $path): void + { + file_put_contents($path, Yaml::dump($this->config, 6, 2)); + } + + public function toArray(): array + { + return $this->config; + } + + public function toJson(): string + { + return json_encode($this->config, JSON_PRETTY_PRINT); + } + + public function toYaml(): string + { + return Yaml::dump($this->config, 6, 2); + } +} diff --git a/app/Traits/HasConfiguration.php b/app/Traits/HasConfiguration.php new file mode 100644 index 000000000..e572c45ea --- /dev/null +++ b/app/Traits/HasConfiguration.php @@ -0,0 +1,42 @@ +uuid}"; + if (! is_dir($configDir)) { + mkdir($configDir, 0755, true); + } + + $generator->saveJson($configDir.'/coolify.json'); + $generator->saveYaml($configDir.'/coolify.yaml'); + + // Generate a README file with basic information + file_put_contents( + $configDir.'/README.md', + generate_readme_file($this->name, now()->toIso8601String()) + ); + } + + public function getConfigurationAsJson(): string + { + return (new ConfigurationGenerator($this))->toJson(); + } + + public function getConfigurationAsYaml(): string + { + return (new ConfigurationGenerator($this))->toYaml(); + } + + public function getConfigurationAsArray(): array + { + return (new ConfigurationGenerator($this))->toArray(); + } +} diff --git a/resources/views/livewire/project/application/general.blade.php b/resources/views/livewire/project/application/general.blade.php index 62acda056..026b3b579 100644 --- a/resources/views/livewire/project/application/general.blade.php +++ b/resources/views/livewire/project/application/general.blade.php @@ -5,13 +5,14 @@ Save - {{-- - + + {{-- Download Config - + --}} + {{-- - - --}} + --}} +
General configuration for your application.