refactor: Update parse method in Advanced, All, ApplicationPreview, General, and ApplicationDeploymentJob classes

This commit is contained in:
Andras Bacsai
2024-08-29 12:39:37 +02:00
parent b8a37d897e
commit cfc6518157
9 changed files with 36 additions and 1103 deletions

View File

@@ -454,7 +454,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
$yaml = $composeFile = $this->application->docker_compose_raw; $yaml = $composeFile = $this->application->docker_compose_raw;
$this->save_environment_variables(); $this->save_environment_variables();
} else { } else {
$composeFile = $this->application->oldParser(pull_request_id: $this->pull_request_id, preview_id: data_get($this->preview, 'id')); $composeFile = $this->application->parse(pull_request_id: $this->pull_request_id, preview_id: data_get($this->preview, 'id'));
$this->save_environment_variables(); $this->save_environment_variables();
if (! is_null($this->env_filename)) { if (! is_null($this->env_filename)) {
$services = collect($composeFile['services']); $services = collect($composeFile['services']);
@@ -955,13 +955,19 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
} }
} }
if ($this->application->environment_variables->where('key', 'COOLIFY_FQDN')->isEmpty()) { if ($this->application->environment_variables->where('key', 'COOLIFY_FQDN')->isEmpty()) {
$envs->push("COOLIFY_FQDN={$this->application->fqdn}"); if ($this->application->compose_parsing_version === '3') {
$envs->push("COOLIFY_DOMAIN_URL={$this->application->fqdn}"); $envs->push("COOLIFY_URL={$this->application->fqdn}");
} else {
$envs->push("COOLIFY_FQDN={$this->application->fqdn}");
}
} }
if ($this->application->environment_variables->where('key', 'COOLIFY_URL')->isEmpty()) { if ($this->application->environment_variables->where('key', 'COOLIFY_URL')->isEmpty()) {
$url = str($this->application->fqdn)->replace('http://', '')->replace('https://', ''); $url = str($this->application->fqdn)->replace('http://', '')->replace('https://', '');
$envs->push("COOLIFY_URL={$url}"); if ($this->application->compose_parsing_version === '3') {
$envs->push("COOLIFY_DOMAIN_FQDN={$url}"); $envs->push("COOLIFY_FQDN={$url}");
} else {
$envs->push("COOLIFY_URL={$url}");
}
} }
if ($this->application->build_pack !== 'dockercompose' || $this->application->compose_parsing_version === '1' || $this->application->compose_parsing_version === '2') { if ($this->application->build_pack !== 'dockercompose' || $this->application->compose_parsing_version === '1' || $this->application->compose_parsing_version === '2') {
if ($this->application->environment_variables->where('key', 'COOLIFY_BRANCH')->isEmpty()) { if ($this->application->environment_variables->where('key', 'COOLIFY_BRANCH')->isEmpty()) {

View File

@@ -68,7 +68,7 @@ class Advanced extends Component
if ($this->application->settings->is_raw_compose_deployment_enabled) { if ($this->application->settings->is_raw_compose_deployment_enabled) {
$this->application->oldRawParser(); $this->application->oldRawParser();
} else { } else {
$this->application->oldParser(); $this->application->parse();
} }
$this->application->settings->save(); $this->application->settings->save();
$this->dispatch('success', 'Settings saved.'); $this->dispatch('success', 'Settings saved.');

View File

@@ -131,7 +131,7 @@ class General extends Component
public function mount() public function mount()
{ {
try { try {
$this->parsedServices = $this->application->oldParser(); $this->parsedServices = $this->application->parse();
if (is_null($this->parsedServices) || empty($this->parsedServices)) { if (is_null($this->parsedServices) || empty($this->parsedServices)) {
$this->dispatch('error', 'Failed to parse your docker-compose file. Please check the syntax and try again.'); $this->dispatch('error', 'Failed to parse your docker-compose file. Please check the syntax and try again.');
@@ -204,7 +204,7 @@ class General extends Component
return; return;
} }
$this->application->oldParser(); $this->application->parse();
$this->dispatch('success', 'Docker compose file loaded.'); $this->dispatch('success', 'Docker compose file loaded.');
$this->dispatch('compose_loaded'); $this->dispatch('compose_loaded');
$this->dispatch('refreshStorages'); $this->dispatch('refreshStorages');

View File

@@ -26,7 +26,7 @@ class All extends Component
$this->containerNames = $this->containerNames->merge($this->resource->databases()->pluck('name')); $this->containerNames = $this->containerNames->merge($this->resource->databases()->pluck('name'));
} elseif ($this->resource->type() == 'application') { } elseif ($this->resource->type() == 'application') {
if ($this->resource->build_pack === 'dockercompose') { if ($this->resource->build_pack === 'dockercompose') {
$parsed = $this->resource->oldParser(); $parsed = $this->resource->parse();
$containers = collect(data_get($parsed, 'services'))->keys(); $containers = collect(data_get($parsed, 'services'))->keys();
$this->containerNames = $containers; $this->containerNames = $containers;
} else { } else {

View File

@@ -3,8 +3,6 @@
namespace App\Models; namespace App\Models;
use App\Enums\ApplicationDeploymentStatus; use App\Enums\ApplicationDeploymentStatus;
use App\Enums\ProxyTypes;
use App\Jobs\ServerFilesFromServerJob;
use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
@@ -1088,547 +1086,7 @@ class Application extends BaseModel
instant_remote_process($commands, $this->destination->server, false); instant_remote_process($commands, $this->destination->server, false);
} }
public function newParser(int $pull_request_id = 0, ?int $preview_id = null) public function parse(int $pull_request_id = 0, ?int $preview_id = null)
{
// return newParser($this, $pull_request_id, $preview_id);
// $pullRequestId = $pull_request_id;
// $isPullRequest = $pullRequestId == 0 ? false : true;
// $uuid = data_get($this, 'uuid');
// $server = data_get($this, 'destination.server');
// $compose = data_get($this, 'docker_compose_raw');
// try {
// $yaml = Yaml::parse($compose);
// } catch (\Exception $e) {
// return;
// }
// $services = data_get($yaml, 'services', collect([]));
// $topLevel = collect([
// 'volumes' => collect(data_get($yaml, 'volumes', [])),
// 'networks' => collect(data_get($yaml, 'networks', [])),
// 'configs' => collect(data_get($yaml, 'configs', [])),
// 'secrets' => collect(data_get($yaml, 'secrets', [])),
// ]);
// // If there are predefined volumes, make sure they are not null
// if ($topLevel->get('volumes')->count() > 0) {
// $temp = collect([]);
// foreach ($topLevel['volumes'] as $volumeName => $volume) {
// if (is_null($volume)) {
// continue;
// }
// $temp->put($volumeName, $volume);
// }
// $topLevel['volumes'] = $temp;
// }
// // Get the base docker network
// $baseNetwork = collect([$uuid]);
// if ($isPullRequest) {
// $baseNetwork = collect(["{$uuid}-{$pullRequestId}"]);
// }
// $parsedServices = collect([]);
// $fileStorages = $this->fileStorages();
// // Let's loop through the services
// foreach ($services as $serviceName => $service) {
// $image = data_get_str($service, 'image');
// $restart = data_get_str($service, 'restart', RESTART_MODE);
// $logging = data_get($service, 'logging');
// if ($server->isLogDrainEnabled() && $this->isLogDrainEnabled()) {
// $logging = [
// 'driver' => 'fluentd',
// 'options' => [
// 'fluentd-address' => 'tcp://127.0.0.1:24224',
// 'fluentd-async' => 'true',
// 'fluentd-sub-second-precision' => 'true',
// ],
// ];
// }
// $volumes = collect(data_get($service, 'volumes', []));
// $networks = collect(data_get($service, 'networks', []));
// $depends_on = collect(data_get($service, 'depends_on', []));
// $labels = collect(data_get($service, 'labels', []));
// $environment = collect(data_get($service, 'environment', []));
// $buildArgs = collect(data_get($service, 'build.args', []));
// $environment = $environment->merge($buildArgs);
// $baseName = generateApplicationContainerName(
// application: $this,
// pull_request_id: $pullRequestId
// );
// $containerName = "$serviceName-$baseName";
// $volumesParsed = collect([]);
// if ($volumes->count() > 0) {
// foreach ($volumes as $index => $volume) {
// $type = null;
// $source = null;
// $target = null;
// $content = null;
// $isDirectory = false;
// if (is_string($volume)) {
// $source = str($volume)->before(':');
// $target = str($volume)->after(':')->beforeLast(':');
// $foundConfig = $fileStorages->whereMountPath($target)->first();
// if (sourceIsLocal($source)) {
// $type = str('bind');
// if ($foundConfig) {
// $contentNotNull_temp = data_get($foundConfig, 'content');
// if ($contentNotNull_temp) {
// $content = $contentNotNull_temp;
// }
// $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
// $isDirectory = true;
// }
// } else {
// $type = str('volume');
// }
// } elseif (is_array($volume)) {
// $type = data_get_str($volume, 'type');
// $source = data_get_str($volume, 'source');
// $target = data_get_str($volume, 'target');
// $content = data_get($volume, 'content');
// $isDirectory = (bool) data_get($volume, 'isDirectory', null) || (bool) data_get($volume, 'is_directory', null);
// $foundConfig = $fileStorages->whereMountPath($target)->first();
// if ($foundConfig) {
// $contentNotNull_temp = data_get($foundConfig, 'content');
// if ($contentNotNull_temp) {
// $content = $contentNotNull_temp;
// }
// $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
// if ((is_null($isDirectory) || ! $isDirectory) && is_null($content)) {
// $isDirectory = true;
// }
// }
// }
// if ($type->value() === 'bind') {
// if ($source->value() === '/var/run/docker.sock') {
// return $volume;
// }
// if ($source->value() === '/tmp' || $source->value() === '/tmp/') {
// return $volume;
// }
// $mainDirectory = str(base_configuration_dir().'/applications/'.$uuid);
// $source = replaceLocalSource($source, $mainDirectory);
// if ($isPullRequest) {
// $source = $source."-pr-$pullRequestId";
// }
// if (
// ! $this?->settings?->is_preserve_repository_enabled || $foundConfig?->is_based_on_git
// ) {
// LocalFileVolume::updateOrCreate(
// [
// 'mount_path' => $target,
// 'resource_id' => $this->id,
// 'resource_type' => get_class($this),
// ],
// [
// 'fs_path' => $source,
// 'mount_path' => $target,
// 'content' => $content,
// 'is_directory' => $isDirectory,
// 'resource_id' => $this->id,
// 'resource_type' => get_class($this),
// ]
// );
// }
// $volume = "$source:$target";
// } elseif ($type->value() === 'volume') {
// if ($topLevel->get('volumes')->has($source->value())) {
// $temp = $topLevel->get('volumes')->get($source->value());
// if (data_get($temp, 'driver_opts.type') === 'cifs') {
// return $volume;
// }
// if (data_get($temp, 'driver_opts.type') === 'nfs') {
// return $volume;
// }
// }
// $slugWithoutUuid = Str::slug($source, '-');
// $name = "{$uuid}_{$slugWithoutUuid}";
// if ($isPullRequest) {
// $name = "{$name}-pr-$pullRequestId";
// }
// if (is_string($volume)) {
// $source = str($volume)->before(':');
// $target = str($volume)->after(':')->beforeLast(':');
// $source = $name;
// $volume = "$source:$target";
// } elseif (is_array($volume)) {
// data_set($volume, 'source', $name);
// }
// $topLevel->get('volumes')->put($name, [
// 'name' => $name,
// ]);
// LocalPersistentVolume::updateOrCreate(
// [
// 'mount_path' => $target,
// 'resource_id' => $this->id,
// 'resource_type' => get_class($this),
// ],
// [
// 'name' => $name,
// 'mount_path' => $target,
// 'resource_id' => $this->id,
// 'resource_type' => get_class($this),
// ]
// );
// }
// dispatch(new ServerFilesFromServerJob($this));
// $volumesParsed->put($index, $volume);
// }
// }
// if ($depends_on?->count() > 0) {
// if ($isPullRequest) {
// $newDependsOn = collect([]);
// $depends_on->each(function ($dependency, $condition) use ($pullRequestId, $newDependsOn) {
// if (is_numeric($condition)) {
// $dependency = "$dependency-pr-$pullRequestId";
// $newDependsOn->put($condition, $dependency);
// } else {
// $condition = "$condition-pr-$pullRequestId";
// $newDependsOn->put($condition, $dependency);
// }
// });
// $depends_on = $newDependsOn;
// }
// }
// if ($topLevel->get('networks')?->count() > 0) {
// foreach ($topLevel->get('networks') as $networkName => $network) {
// if ($networkName === 'default') {
// continue;
// }
// // ignore aliases
// if ($network['aliases'] ?? false) {
// continue;
// }
// $networkExists = $networks->contains(function ($value, $key) use ($networkName) {
// return $value == $networkName || $key == $networkName;
// });
// if (! $networkExists) {
// $networks->put($networkName, null);
// }
// }
// }
// $baseNetworkExists = $networks->contains(function ($value, $_) use ($baseNetwork) {
// return $value == $baseNetwork;
// });
// if (! $baseNetworkExists) {
// foreach ($baseNetwork as $network) {
// $topLevel->get('networks')->put($network, [
// 'name' => $network,
// 'external' => true,
// ]);
// }
// }
// $networks_temp = collect();
// foreach ($networks as $key => $network) {
// if (gettype($network) === 'string') {
// // networks:
// // - appwrite
// $networks_temp->put($network, null);
// } elseif (gettype($network) === 'array') {
// // networks:
// // default:
// // ipv4_address: 192.168.203.254
// $networks_temp->put($key, $network);
// }
// }
// foreach ($baseNetwork as $key => $network) {
// $networks_temp->put($network, null);
// }
// if (data_get($this, 'settings.connect_to_docker_network')) {
// $network = $this->destination->network;
// $networks_temp->put($network, null);
// $topLevel->get('networks')->put($network, [
// 'name' => $network,
// 'external' => true,
// ]);
// }
// foreach ($environment as $key => $value) {
// if (is_numeric($key)) {
// if (is_array($value)) {
// // - SESSION_SECRET: 123
// // - SESSION_SECRET:
// $key = str(collect($value)->keys()->first());
// $value = str(collect($value)->values()->first());
// } else {
// $variable = str($value);
// if ($variable->contains('=')) {
// // - SESSION_SECRET=123
// // - SESSION_SECRET=
// $key = $variable->before('=');
// $value = $variable->after('=');
// } else {
// // - SESSION_SECRET
// $key = $variable;
// $value = null;
// }
// }
// } else {
// // SESSION_SECRET: 123
// // SESSION_SECRET:
// $key = str($key);
// $value = str($value);
// }
// // Auto generate FQDN and URL
// if ($key->startsWith('SERVICE_FQDN') || $value->startsWith('$SERVICE_FQDN') || $value->startsWith('${SERVICE_FQDN')) {
// if ($value->contains('SERVICE_FQDN')) {
// $key = str(replaceVariables($value));
// $value = null;
// }
// $name = $key->after('SERVICE_FQDN_')->beforeLast('_')->lower();
// $fqdn = generateFqdn($server, "{$name->value()}-{$uuid}");
// $url = str($fqdn)->replace('http://', '')->replace('https://', '')->replace('www.', '');
// $keyUrl = $key->replace('SERVICE_FQDN', 'SERVICE_URL');
// // TODO: is this needed?
// // if (substr_count($key->value(), '_') === 3) {
// // // SERVICE_FQDN_UMAMI_1000
// // $port = $key->afterLast('_');
// // } else {
// // // SERVICE_FQDN_UMAMI
// // $port = null;
// // }
// // if ($port) {
// // $fqdn = "$fqdn:$port";
// // }
// if ($value && get_class($value) === 'Illuminate\Support\Stringable') {
// $path = $value->value();
// $fqdn = "$fqdn$path";
// }
// // ray([
// // 'key' => $key,
// // 'value' => $fqdn,
// // ]);
// // ray($this->environment_variables()->where('key', $key)->where('application_id', $this->id)->first());
// $this->environment_variables()->where('key', $key)->where('application_id', $this->id)->firstOrCreate([
// 'key' => $key,
// 'application_id' => $this->id,
// ], [
// 'value' => $fqdn,
// 'is_build_time' => false,
// 'is_preview' => false,
// ]);
// $this->environment_variables()->where('key', $keyUrl)->where('application_id', $this->id)->firstOrCreate([
// 'key' => $keyUrl,
// 'application_id' => $this->id,
// ], [
// 'value' => $url,
// 'is_build_time' => false,
// 'is_preview' => false,
// ]);
// } elseif ($value->startsWith('$')) {
// // If the value is a variable then we will add it to Coolify's DB
// // ${VARIABLE} will be VARIABLE instead
// $value = str(replaceVariables($value));
// if ($value->contains(':-')) {
// $key = $value->before(':');
// $defaultValue = $value->after(':-');
// } elseif ($value->contains('-')) {
// $key = $value->before('-');
// $defaultValue = $value->after('-');
// } elseif ($value->contains(':?')) {
// $key = $value->before(':');
// $defaultValue = $value->after(':?');
// } elseif ($value->contains('?')) {
// $key = $value->before('?');
// $defaultValue = $value->after('?');
// } else {
// $key = $value;
// $defaultValue = null;
// }
// $this->environment_variables()->where('key', $key)->where('application_id', $this->id)->firstOrCreate([
// 'key' => $key,
// 'application_id' => $this->id,
// 'is_preview' => false,
// ], [
// 'value' => $defaultValue,
// 'is_build_time' => false,
// 'is_preview' => false,
// ]);
// }
// }
// $branch = $this->git_branch;
// if ($pullRequestId !== 0) {
// $branch = "pull/{$pullRequestId}/head";
// }
// if ($this->environment_variables->where('key', 'COOLIFY_BRANCH')->isEmpty()) {
// $environment->put('COOLIFY_BRANCH', $branch);
// }
// if ($this->environment_variables->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) {
// $environment->put('COOLIFY_CONTAINER_NAME', $containerName);
// }
// // Remove SERVICE_FQDN and SERVICE_URL from environment
// $environment = $environment->filter(function ($value, $key) {
// return ! str($key)->startsWith('SERVICE_FQDN') && ! str($key)->startsWith('SERVICE_URL');
// });
// // Labels
// $fqdns = collect([]);
// $domains = collect(json_decode($this->docker_compose_domains)) ?? collect([]);
// if ($domains->count() !== 0) {
// $fqdns = data_get($domains, "$serviceName.domain");
// if (! $fqdns) {
// $fqdns = collect([]);
// } else {
// $fqdns = str($fqdns)->explode(',');
// if ($isPullRequest) {
// $preview = $this->previews()->find($preview_id);
// $docker_compose_domains = collect(json_decode(data_get($preview, 'docker_compose_domains')));
// if ($docker_compose_domains->count() > 0) {
// $found_fqdn = data_get($docker_compose_domains, "$serviceName.domain");
// if ($found_fqdn) {
// $fqdns = collect($found_fqdn);
// } else {
// $fqdns = collect([]);
// }
// } else {
// $fqdns = $fqdns->map(function ($fqdn) use ($pullRequestId) {
// $preview = ApplicationPreview::findPreviewByApplicationAndPullId($this->id, $pullRequestId);
// $url = Url::fromString($fqdn);
// $template = $this->preview_url_template;
// $host = $url->getHost();
// $schema = $url->getScheme();
// $random = new Cuid2;
// $preview_fqdn = str_replace('{{random}}', $random, $template);
// $preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn);
// $preview_fqdn = str_replace('{{pr_id}}', $pullRequestId, $preview_fqdn);
// $preview_fqdn = "$schema://$preview_fqdn";
// $preview->fqdn = $preview_fqdn;
// $preview->save();
// return $preview_fqdn;
// });
// }
// }
// $shouldGenerateLabelsExactly = $server->settings->generate_exact_labels;
// if ($shouldGenerateLabelsExactly) {
// switch ($server->proxyType()) {
// case ProxyTypes::TRAEFIK->value:
// $labels = $labels->merge(
// fqdnLabelsForTraefik(
// uuid: $this->uuid,
// domains: $fqdns,
// serviceLabels: $labels,
// generate_unique_uuid: $this->build_pack === 'dockercompose',
// image: $image,
// is_force_https_enabled: $this->isForceHttpsEnabled(),
// is_gzip_enabled: $this->isGzipEnabled(),
// is_stripprefix_enabled: $this->isStripprefixEnabled(),
// )
// );
// break;
// case ProxyTypes::CADDY->value:
// $labels = $labels->merge(
// fqdnLabelsForCaddy(
// network: $this->destination->network,
// uuid: $this->uuid,
// domains: $fqdns,
// serviceLabels: $labels,
// image: $image,
// is_force_https_enabled: $this->isForceHttpsEnabled(),
// is_gzip_enabled: $this->isGzipEnabled(),
// is_stripprefix_enabled: $this->isStripprefixEnabled(),
// )
// );
// break;
// }
// } else {
// $labels = $labels->merge(
// fqdnLabelsForTraefik(
// uuid: $this->uuid,
// domains: $fqdns,
// serviceLabels: $labels,
// generate_unique_uuid: $this->build_pack === 'dockercompose',
// image: $image,
// is_force_https_enabled: $this->isForceHttpsEnabled(),
// is_gzip_enabled: $this->isGzipEnabled(),
// is_stripprefix_enabled: $this->isStripprefixEnabled(),
// )
// );
// $labels = $labels->merge(
// fqdnLabelsForCaddy(
// network: $this->destination->network,
// uuid: $this->uuid,
// domains: $fqdns,
// serviceLabels: $labels,
// image: $image,
// is_force_https_enabled: $this->isForceHttpsEnabled(),
// is_gzip_enabled: $this->isGzipEnabled(),
// is_stripprefix_enabled: $this->isStripprefixEnabled(),
// )
// );
// }
// }
// }
// $defaultLabels = defaultLabels(
// id: $this->id,
// name: $containerName,
// pull_request_id: $pullRequestId,
// type: 'application');
// $labels = $labels->merge($defaultLabels);
// if ($labels->count() > 0 && $this->settings->is_container_label_escape_enabled) {
// $labels = $labels->map(function ($value, $key) {
// return escapeDollarSign($value);
// });
// }
// $payload = collect($service)->merge([
// 'restart' => $restart->value(),
// 'container_name' => $containerName,
// 'volumes' => $volumesParsed,
// 'networks' => $networks_temp,
// 'labels' => $labels,
// 'environment' => $environment,
// ]);
// if ($logging) {
// $payload['logging'] = $logging;
// }
// if ($depends_on->count() > 0) {
// $payload['depends_on'] = $depends_on;
// }
// if ($isPullRequest) {
// $serviceName = "{$serviceName}-pr-{$pullRequestId}";
// }
// $parsedServices->put($serviceName, $payload);
// }
// $topLevel->put('services', $parsedServices);
// $customOrder = ['services', 'volumes', 'networks', 'configs', 'secrets'];
// $topLevel = $topLevel->sortBy(function ($value, $key) use ($customOrder) {
// return array_search($key, $customOrder);
// });
// $this->docker_compose = Yaml::dump(convertToArray($topLevel), 10, 2);
// data_forget($this, 'environment_variables');
// data_forget($this, 'environment_variables_preview');
// $this->save();
// return $topLevel;
}
public function oldParser(int $pull_request_id = 0, ?int $preview_id = null)
{ {
if ($this->compose_parsing_version === '3') { if ($this->compose_parsing_version === '3') {
return newParser($this, $pull_request_id, $preview_id); return newParser($this, $pull_request_id, $preview_id);
@@ -1684,7 +1142,7 @@ class Application extends BaseModel
if ($composeFileContent) { if ($composeFileContent) {
$this->docker_compose_raw = $composeFileContent; $this->docker_compose_raw = $composeFileContent;
$this->save(); $this->save();
$parsedServices = $this->oldParser(); $parsedServices = $this->parse();
if ($this->docker_compose_domains) { if ($this->docker_compose_domains) {
$json = collect(json_decode($this->docker_compose_domains)); $json = collect(json_decode($this->docker_compose_domains));
$names = collect(data_get($parsedServices, 'services'))->keys()->toArray(); $names = collect(data_get($parsedServices, 'services'))->keys()->toArray();

View File

@@ -14,7 +14,7 @@ class ApplicationPreview extends BaseModel
static::deleting(function ($preview) { static::deleting(function ($preview) {
if (data_get($preview, 'application.build_pack') === 'dockercompose') { if (data_get($preview, 'application.build_pack') === 'dockercompose') {
$server = $preview->application->destination->server; $server = $preview->application->destination->server;
$composeFile = newParser($preview->application, pull_request_id: $preview->pull_request_id); $composeFile = $preview->application->parse(pull_request_id: $preview->pull_request_id);
$volumes = data_get($composeFile, 'volumes'); $volumes = data_get($composeFile, 'volumes');
$networks = data_get($composeFile, 'networks'); $networks = data_get($composeFile, 'networks');
$networkKeys = collect($networks)->keys(); $networkKeys = collect($networks)->keys();

View File

@@ -2,14 +2,11 @@
namespace App\Models; namespace App\Models;
use App\Enums\ProxyTypes;
use App\Jobs\ServerFilesFromServerJob;
use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use OpenApi\Attributes as OA; use OpenApi\Attributes as OA;
use Spatie\Url\Url; use Spatie\Url\Url;
use Symfony\Component\Yaml\Yaml; use Symfony\Component\Yaml\Yaml;
@@ -1022,532 +1019,6 @@ class Service extends BaseModel
instant_remote_process($commands, $this->server); instant_remote_process($commands, $this->server);
} }
public function newParser()
{
// $uuid = data_get($this, 'uuid');
// $server = data_get($this, 'destination.server');
// $compose = data_get($this, 'docker_compose_raw');
// try {
// $yaml = Yaml::parse($compose);
// } catch (\Exception $e) {
// return;
// }
// $allServices = get_service_templates();
// $services = data_get($yaml, 'services', collect([]));
// $topLevel = collect([
// 'volumes' => collect(data_get($yaml, 'volumes', [])),
// 'networks' => collect(data_get($yaml, 'networks', [])),
// 'configs' => collect(data_get($yaml, 'configs', [])),
// 'secrets' => collect(data_get($yaml, 'secrets', [])),
// ]);
// // If there are predefined volumes, make sure they are not null
// if ($topLevel->get('volumes')->count() > 0) {
// $temp = collect([]);
// foreach ($topLevel['volumes'] as $volumeName => $volume) {
// if (is_null($volume)) {
// continue;
// }
// $temp->put($volumeName, $volume);
// }
// $topLevel['volumes'] = $temp;
// }
// // Get the base docker network
// $baseNetwork = collect([$uuid]);
// $parsedServices = collect([]);
// // Let's loop through the services
// foreach ($services as $serviceName => $service) {
// if ($serviceName === 'registry') {
// $tempServiceName = 'docker-registry';
// } else {
// $tempServiceName = $serviceName;
// }
// if (str(data_get($service, 'image'))->contains('glitchtip')) {
// $tempServiceName = 'glitchtip';
// }
// if ($serviceName === 'supabase-kong') {
// $tempServiceName = 'supabase';
// }
// $serviceDefinition = data_get($allServices, $tempServiceName);
// $predefinedPort = data_get($serviceDefinition, 'port');
// if ($serviceName === 'plausible') {
// $predefinedPort = '8000';
// }
// $image = data_get_str($service, 'image');
// $restart = data_get_str($service, 'restart', RESTART_MODE);
// $logging = data_get($service, 'logging');
// if ($server->isLogDrainEnabled() && $this->isLogDrainEnabled()) {
// $logging = [
// 'driver' => 'fluentd',
// 'options' => [
// 'fluentd-address' => 'tcp://127.0.0.1:24224',
// 'fluentd-async' => 'true',
// 'fluentd-sub-second-precision' => 'true',
// ],
// ];
// }
// $volumes = collect(data_get($service, 'volumes', []));
// $networks = collect(data_get($service, 'networks', []));
// $labels = collect(data_get($service, 'labels', []));
// $environment = collect(data_get($service, 'environment', []));
// $buildArgs = collect(data_get($service, 'build.args', []));
// $environment = $environment->merge($buildArgs);
// $hasHostNetworkMode = data_get($service, 'network_mode') === 'host' ? true : false;
// $containerName = "$serviceName-{$this->uuid}";
// $isDatabase = isDatabaseImage(data_get_str($service, 'image'));
// $volumesParsed = collect([]);
// if ($isDatabase) {
// $savedService = ServiceDatabase::firstOrCreate([
// 'name' => $serviceName,
// 'image' => $image,
// 'service_id' => $this->id,
// ]);
// } else {
// $savedService = ServiceApplication::firstOrCreate([
// 'name' => $serviceName,
// 'image' => $image,
// 'service_id' => $this->id,
// ]);
// }
// $fileStorages = $savedService->fileStorages();
// // Check if image changed
// if ($savedService->image !== $image) {
// $savedService->image = $image;
// $savedService->save();
// }
// if ($volumes->count() > 0) {
// foreach ($volumes as $index => $volume) {
// $type = null;
// $source = null;
// $target = null;
// $content = null;
// $isDirectory = false;
// if (is_string($volume)) {
// $source = str($volume)->before(':');
// $target = str($volume)->after(':')->beforeLast(':');
// $foundConfig = $fileStorages->whereMountPath($target)->first();
// if (sourceIsLocal($source)) {
// $type = str('bind');
// if ($foundConfig) {
// $contentNotNull_temp = data_get($foundConfig, 'content');
// if ($contentNotNull_temp) {
// $content = $contentNotNull_temp;
// }
// $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
// $isDirectory = true;
// }
// } else {
// $type = str('volume');
// }
// } elseif (is_array($volume)) {
// $type = data_get_str($volume, 'type');
// $source = data_get_str($volume, 'source');
// $target = data_get_str($volume, 'target');
// $content = data_get($volume, 'content');
// $isDirectory = (bool) data_get($volume, 'isDirectory', null) || (bool) data_get($volume, 'is_directory', null);
// $foundConfig = $fileStorages->whereMountPath($target)->first();
// if ($foundConfig) {
// $contentNotNull_temp = data_get($foundConfig, 'content');
// if ($contentNotNull_temp) {
// $content = $contentNotNull_temp;
// }
// $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
// if ((is_null($isDirectory) || ! $isDirectory) && is_null($content)) {
// $isDirectory = true;
// }
// }
// }
// if ($type->value() === 'bind') {
// if ($source->value() === '/var/run/docker.sock') {
// return $volume;
// }
// if ($source->value() === '/tmp' || $source->value() === '/tmp/') {
// return $volume;
// }
// $mainDirectory = str(base_configuration_dir().'/applications/'.$uuid);
// $source = replaceLocalSource($source, $mainDirectory);
// LocalFileVolume::updateOrCreate(
// [
// 'mount_path' => $target,
// 'resource_id' => $savedService->id,
// 'resource_type' => get_class($savedService),
// ],
// [
// 'fs_path' => $source,
// 'mount_path' => $target,
// 'content' => $content,
// 'is_directory' => $isDirectory,
// 'resource_id' => $savedService->id,
// 'resource_type' => get_class($savedService),
// ]
// );
// $volume = "$source:$target";
// } elseif ($type->value() === 'volume') {
// if ($topLevel->get('volumes')->has($source->value())) {
// $temp = $topLevel->get('volumes')->get($source->value());
// if (data_get($temp, 'driver_opts.type') === 'cifs') {
// return $volume;
// }
// if (data_get($temp, 'driver_opts.type') === 'nfs') {
// return $volume;
// }
// }
// $slugWithoutUuid = Str::slug($source, '-');
// $name = "{$uuid}_{$slugWithoutUuid}";
// if (is_string($volume)) {
// $source = str($volume)->before(':');
// $target = str($volume)->after(':')->beforeLast(':');
// $source = $name;
// $volume = "$source:$target";
// } elseif (is_array($volume)) {
// data_set($volume, 'source', $name);
// }
// $topLevel->get('volumes')->put($name, [
// 'name' => $name,
// ]);
// LocalPersistentVolume::updateOrCreate(
// [
// 'mount_path' => $target,
// 'resource_id' => $savedService->id,
// 'resource_type' => get_class($savedService),
// ],
// [
// 'name' => $name,
// 'mount_path' => $target,
// 'resource_id' => $savedService->id,
// 'resource_type' => get_class($savedService),
// ]
// );
// }
// dispatch(new ServerFilesFromServerJob($savedService));
// $volumesParsed->put($index, $volume);
// }
// }
// if ($topLevel->get('networks')?->count() > 0) {
// foreach ($topLevel->get('networks') as $networkName => $network) {
// if ($networkName === 'default') {
// continue;
// }
// // ignore aliases
// if ($network['aliases'] ?? false) {
// continue;
// }
// $networkExists = $networks->contains(function ($value, $key) use ($networkName) {
// return $value == $networkName || $key == $networkName;
// });
// if (! $networkExists) {
// $networks->put($networkName, null);
// }
// }
// }
// $baseNetworkExists = $networks->contains(function ($value, $_) use ($baseNetwork) {
// return $value == $baseNetwork;
// });
// if (! $baseNetworkExists) {
// foreach ($baseNetwork as $network) {
// $topLevel->get('networks')->put($network, [
// 'name' => $network,
// 'external' => true,
// ]);
// }
// }
// $networks_temp = collect();
// foreach ($networks as $key => $network) {
// if (gettype($network) === 'string') {
// // networks:
// // - appwrite
// $networks_temp->put($network, null);
// } elseif (gettype($network) === 'array') {
// // networks:
// // default:
// // ipv4_address: 192.168.203.254
// $networks_temp->put($key, $network);
// }
// }
// foreach ($baseNetwork as $key => $network) {
// $networks_temp->put($network, null);
// }
// // Convert
// // - SESSION_SECRET: 123 to - SESSION_SECRET=123
// $convertedServiceVariables = collect([]);
// foreach ($environment as $variableName => $variable) {
// if (is_numeric($variableName)) {
// if (is_array($variable)) {
// $key = str(collect($variable)->keys()->first());
// $value = str(collect($variable)->values()->first());
// $variable = "$key=$value";
// $convertedServiceVariables->put($variableName, $variable);
// } elseif (is_string($variable)) {
// $convertedServiceVariables->put($variableName, $variable);
// }
// } elseif (is_string($variableName)) {
// $convertedServiceVariables->put($variableName, $variable);
// }
// }
// $environment = $convertedServiceVariables;
// // filter magic environments
// $magicEnvironments = $environment->filter(function ($value, $key) {
// return str($key)->startsWith('SERVICE_FQDN') || str($key)->startsWith('SERVICE_URL') || str($value)->startsWith('SERVICE_FQDN') || str($value)->startsWith('SERVICE_URL');
// });
// if ($magicEnvironments->count() > 0) {
// foreach ($magicEnvironments as $key => $value) {
// $key = str($key);
// $value = str($value);
// $command = $key->after('SERVICE_')->beforeLast('_');
// if ($command->value() === 'FQDN') {
// $fqdn = generateFqdn($server, "{$savedService->name}-{$uuid}");
// if ($value && get_class($value) === 'Illuminate\Support\Stringable' && $value->startsWith('/')) {
// $path = $value->value();
// $value = "$fqdn$path";
// } else {
// $value = $fqdn;
// }
// } elseif ($command->value() === 'URL') {
// $fqdn = generateFqdn($server, "{$savedService->name}-{$uuid}");
// $value = str($fqdn)->replace('http://', '')->replace('https://', '')->replace('www.', '');
// }
// if (! $isDatabase && ! $this->environment_variables()->where('key', $key)->where('service_id', $this->id)->first()) {
// $savedService->fqdn = $value;
// $savedService->save();
// }
// $this->environment_variables()->where('key', $key)->where('service_id', $this->id)->firstOrCreate([
// 'key' => $key,
// 'service_id' => $this->id,
// ], [
// 'value' => $value,
// 'is_build_time' => false,
// 'is_preview' => false,
// ]);
// }
// }
// foreach ($environment as $key => $value) {
// if (is_numeric($key)) {
// if (is_array($value)) {
// // - SESSION_SECRET: 123
// // - SESSION_SECRET:
// $key = str(collect($value)->keys()->first());
// $value = str(collect($value)->values()->first());
// } else {
// $variable = str($value);
// if ($variable->contains('=')) {
// // - SESSION_SECRET=123
// // - SESSION_SECRET=
// $key = $variable->before('=');
// $value = $variable->after('=');
// } else {
// // - SESSION_SECRET
// $key = $variable;
// $value = null;
// }
// }
// } else {
// // SESSION_SECRET: 123
// // SESSION_SECRET:
// $key = str($key);
// $value = str($value);
// }
// // Auto generate FQDN and URL
// // environment:
// // - SERVICE_FQDN_UMAMI=/umami
// // - FQDN=$SERVICE_FQDN_UMAMI
// // - URL=$SERVICE_URL_UMAMI
// // - TEST=${TEST:-initial}
// // - HARDCODED=stuff
// if ($value->startsWith('$')) {
// $value = str(replaceVariables($value));
// if ($value->startsWith('SERVICE_')) {
// // $value = SERVICE_FQDN_UMAMI
// $command = $value->after('SERVICE_')->beforeLast('_');
// if ($command->value() === 'FQDN') {
// if ($magicEnvironments->has($value->value())) {
// $found = $magicEnvironments->get($value->value());
// if ($found) {
// $found = $this->environment_variables()->where('key', $value->value())->where('service_id', $this->id)->first();
// if ($found) {
// $value = $found->value;
// }
// }
// } else {
// $fqdn = generateFqdn($server, "{$savedService->name}-{$uuid}");
// if ($value && get_class($value) === 'Illuminate\Support\Stringable' && $value->startsWith('/')) {
// $path = $value->value();
// $value = "$fqdn$path";
// } else {
// $value = $fqdn;
// }
// }
// } elseif ($command->value() === 'URL') {
// if ($magicEnvironments->has($value->value())) {
// $found = $magicEnvironments->get($value->value());
// if ($found) {
// $found = $this->environment_variables()->where('key', $value->value())->where('service_id', $this->id)->first();
// if ($found) {
// $value = str($found->value)->replace('http://', '')->replace('https://', '')->replace('www.', '');
// }
// }
// } else {
// $fqdn = generateFqdn($server, "{$savedService->name}-{$uuid}");
// $value = str($fqdn)->replace('http://', '')->replace('https://', '')->replace('www.', '');
// }
// } else {
// $value = generateEnvValue($command, $this);
// }
// $this->environment_variables()->where('key', $key)->where('service_id', $this->id)->firstOrCreate([
// 'key' => $key,
// 'service_id' => $this->id,
// ], [
// 'value' => $value,
// 'is_build_time' => false,
// 'is_preview' => false,
// ]);
// } else {
// if ($value->contains(':-')) {
// $key = $value->before(':');
// $value = $value->after(':-');
// } elseif ($value->contains('-')) {
// $key = $value->before('-');
// $value = $value->after('-');
// } elseif ($value->contains(':?')) {
// $key = $value->before(':');
// $value = $value->after(':?');
// } elseif ($value->contains('?')) {
// $key = $value->before('?');
// $value = $value->after('?');
// } else {
// $key = $value;
// $value = null;
// }
// $this->environment_variables()->where('key', $key)->where('service_id', $this->id)->firstOrCreate([
// 'key' => $key,
// 'service_id' => $this->id,
// ], [
// 'value' => $value,
// 'is_build_time' => false,
// 'is_preview' => false,
// ]);
// }
// }
// if ($this->environment_variables->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) {
// $environment->put('COOLIFY_CONTAINER_NAME', $containerName);
// }
// // Remove SERVICE_FQDN and SERVICE_URL from environment
// $environment = $environment->filter(function ($value, $key) {
// return ! str($key)->startsWith('SERVICE_FQDN') && ! str($key)->startsWith('SERVICE_URL');
// });
// }
// if ($savedService->serviceType()) {
// $fqdns = generateServiceSpecificFqdns($savedService);
// } else {
// $fqdns = collect(data_get($savedService, 'fqdns'))->filter();
// }
// $defaultLabels = defaultLabels($this->id, $containerName, type: 'service', subType: $isDatabase ? 'database' : 'application', subId: $savedService->id);
// $serviceLabels = $labels->merge($defaultLabels);
// if (! $isDatabase && $fqdns->count() > 0) {
// if ($fqdns) {
// $shouldGenerateLabelsExactly = $this->server->settings->generate_exact_labels;
// if ($shouldGenerateLabelsExactly) {
// switch ($this->server->proxyType()) {
// case ProxyTypes::TRAEFIK->value:
// $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik(
// uuid: $this->uuid,
// domains: $fqdns,
// is_force_https_enabled: true,
// serviceLabels: $serviceLabels,
// is_gzip_enabled: $savedService->isGzipEnabled(),
// is_stripprefix_enabled: $savedService->isStripprefixEnabled(),
// service_name: $serviceName,
// image: data_get($service, 'image')
// ));
// break;
// case ProxyTypes::CADDY->value:
// $serviceLabels = $serviceLabels->merge(fqdnLabelsForCaddy(
// network: $this->destination->network,
// uuid: $this->uuid,
// domains: $fqdns,
// is_force_https_enabled: true,
// serviceLabels: $serviceLabels,
// is_gzip_enabled: $savedService->isGzipEnabled(),
// is_stripprefix_enabled: $savedService->isStripprefixEnabled(),
// service_name: $serviceName,
// image: data_get($service, 'image')
// ));
// break;
// }
// } else {
// $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik(
// uuid: $this->uuid,
// domains: $fqdns,
// is_force_https_enabled: true,
// serviceLabels: $serviceLabels,
// is_gzip_enabled: $savedService->isGzipEnabled(),
// is_stripprefix_enabled: $savedService->isStripprefixEnabled(),
// service_name: $serviceName,
// image: data_get($service, 'image')
// ));
// $serviceLabels = $serviceLabels->merge(fqdnLabelsForCaddy(
// network: $this->destination->network,
// uuid: $this->uuid,
// domains: $fqdns,
// is_force_https_enabled: true,
// serviceLabels: $serviceLabels,
// is_gzip_enabled: $savedService->isGzipEnabled(),
// is_stripprefix_enabled: $savedService->isStripprefixEnabled(),
// service_name: $serviceName,
// image: data_get($service, 'image')
// ));
// }
// }
// }
// $payload = collect($service)->merge([
// 'restart' => $restart->value(),
// 'container_name' => $containerName,
// 'volumes' => $volumesParsed,
// 'networks' => $networks_temp,
// 'labels' => $serviceLabels,
// 'environment' => $environment,
// ]);
// if ($logging) {
// $payload['logging'] = $logging;
// }
// $parsedServices->put($serviceName, $payload);
// }
// $topLevel->put('services', $parsedServices);
// $customOrder = ['services', 'volumes', 'networks', 'configs', 'secrets'];
// $topLevel = $topLevel->sortBy(function ($value, $key) use ($customOrder) {
// return array_search($key, $customOrder);
// });
// $this->docker_compose = Yaml::dump(convertToArray($topLevel), 10, 2);
// data_forget($this, 'environment_variables');
// data_forget($this, 'environment_variables_preview');
// $this->save();
// return $topLevel;
}
public function parse(bool $isNew = false): Collection public function parse(bool $isNew = false): Collection
{ {
if ($this->compose_parsing_version === '3') { if ($this->compose_parsing_version === '3') {

View File

@@ -3267,19 +3267,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
} else { } else {
$value = $fqdn; $value = $fqdn;
} }
if (! $isDatabase) { $value = str($fqdn)->replace('http://', '')->replace('https://', '');
if ($isApplication && is_null($resource->fqdn)) {
data_forget($resource, 'environment_variables');
data_forget($resource, 'environment_variables_preview');
$resource->fqdn = $value;
$resource->save();
} elseif ($isService && is_null($savedService->fqdn)) {
if ($key->startsWith('SERVICE_FQDN_')) {
$savedService->fqdn = $value;
$savedService->save();
}
}
}
} elseif ($keyCommand->value() === 'URL' || $valueCommand->value() === 'URL') { } elseif ($keyCommand->value() === 'URL' || $valueCommand->value() === 'URL') {
if ($isApplication) { if ($isApplication) {
@@ -3293,7 +3281,19 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
} else { } else {
$value = $fqdn; $value = $fqdn;
} }
$value = str($fqdn)->replace('http://', '')->replace('https://', ''); if (! $isDatabase) {
if ($isApplication && is_null($resource->fqdn)) {
data_forget($resource, 'environment_variables');
data_forget($resource, 'environment_variables_preview');
$resource->fqdn = $value;
$resource->save();
} elseif ($isService && is_null($savedService->fqdn)) {
if ($key->startsWith('SERVICE_URL_')) {
$savedService->fqdn = $value;
$savedService->save();
}
}
}
} else { } else {
$generatedValue = generateEnvValue($valueCommand, $resource); $generatedValue = generateEnvValue($valueCommand, $resource);
if ($generatedValue) { if ($generatedValue) {
@@ -3428,14 +3428,12 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
} }
// Add COOLIFY_FQDN & COOLIFY_URL to environment // Add COOLIFY_FQDN & COOLIFY_URL to environment
if (! $isDatabase && $fqdns?->count() > 0) { if (! $isDatabase && $fqdns?->count() > 0) {
$environment->put('COOLIFY_FQDN', $fqdns->implode(',')); $environment->put('COOLIFY_URL', $fqdns->implode(','));
$environment->put('COOLIFY_DOMAIN_URL', $fqdns->implode(','));
$urls = $fqdns->map(function ($fqdn) { $urls = $fqdns->map(function ($fqdn) {
return str($fqdn)->replace('http://', '')->replace('https://', ''); return str($fqdn)->replace('http://', '')->replace('https://', '');
}); });
$environment->put('COOLIFY_URL', $urls->implode(',')); $environment->put('COOLIFY_FQDN', $urls->implode(','));
$environment->put('COOLIFY_DOMAIN_FQDN', $urls->implode(','));
} }
$serviceLabels = $labels->merge($defaultLabels); $serviceLabels = $labels->merge($defaultLabels);

View File

@@ -173,7 +173,7 @@ afterEach(function () {
// expect($this->jsonapplicationComposeFile)->toBeJson()->ray(); // expect($this->jsonapplicationComposeFile)->toBeJson()->ray();
// $output = $this->application->newParser(); // $output = $this->application->newParser();
// $outputOld = $this->application->oldParser(); // $outputOld = $this->application->parse();
// expect($output)->toBeInstanceOf(Collection::class); // expect($output)->toBeInstanceOf(Collection::class);
// expect($outputOld)->toBeInstanceOf(Collection::class); // expect($outputOld)->toBeInstanceOf(Collection::class);
@@ -252,7 +252,7 @@ afterEach(function () {
// expect($this->jsonapplicationComposeFile)->toBeJson()->ray(); // expect($this->jsonapplicationComposeFile)->toBeJson()->ray();
// $output = $this->application->newParser(pull_request_id: $pullRequestId, preview_id: $previewId); // $output = $this->application->newParser(pull_request_id: $pullRequestId, preview_id: $previewId);
// $outputOld = $this->application->oldParser(); // $outputOld = $this->application->parse();
// expect($output)->toBeInstanceOf(Collection::class); // expect($output)->toBeInstanceOf(Collection::class);
// expect($outputOld)->toBeInstanceOf(Collection::class); // expect($outputOld)->toBeInstanceOf(Collection::class);