feat: toggle label escaping mechanism

This commit is contained in:
Andras Bacsai 2024-05-15 17:52:14 +02:00
parent f98405188d
commit 2446dc6950
7 changed files with 98 additions and 19 deletions

View File

@ -1331,9 +1331,11 @@ private function generate_compose_file()
if ($this->pull_request_id !== 0) {
$labels = collect(generateLabelsApplication($this->application, $this->preview));
}
$labels = $labels->map(function ($value, $key) {
return escapeDollarSign($value);
});
if ($this->application->settings->is_container_label_escape_enabled) {
$labels = $labels->map(function ($value, $key) {
return escapeDollarSign($value);
});
}
$labels = $labels->merge(defaultLabels($this->application->id, $this->application->uuid, $this->pull_request_id))->toArray();
// Check for custom HEALTHCHECK

View File

@ -22,6 +22,7 @@ class General extends Component
public ?string $git_commit_sha = null;
public string $build_pack;
public ?string $ports_exposes = null;
public bool $is_container_label_escape_enabled = true;
public $customLabels;
public bool $labelsChanged = false;
@ -74,6 +75,7 @@ class General extends Component
'application.post_deployment_command_container' => 'nullable',
'application.settings.is_static' => 'boolean|required',
'application.settings.is_build_server_enabled' => 'boolean|required',
'application.settings.is_container_label_escape_enabled' => 'boolean|required',
'application.watch_paths' => 'nullable',
];
protected $validationAttributes = [
@ -109,6 +111,7 @@ class General extends Component
'application.docker_compose_custom_build_command' => 'Docker compose custom build command',
'application.settings.is_static' => 'Is static',
'application.settings.is_build_server_enabled' => 'Is build server enabled',
'application.settings.is_container_label_escape_enabled' => 'Is container label escape enabled',
'application.watch_paths' => 'Watch paths',
];
public function mount()
@ -124,6 +127,7 @@ public function mount()
}
$this->parsedServiceDomains = $this->application->docker_compose_domains ? json_decode($this->application->docker_compose_domains, true) : [];
$this->ports_exposes = $this->application->ports_exposes;
$this->is_container_label_escape_enabled = $this->application->settings->is_container_label_escape_enabled;
$this->customLabels = $this->application->parseContainerLabels();
if (!$this->customLabels && $this->application->destination->server->proxyType() !== 'NONE') {
$this->customLabels = str(implode("|", generateLabelsApplication($this->application)))->replace("|", "\n");
@ -145,7 +149,7 @@ public function instantSave()
$this->application->settings->save();
$this->dispatch('success', 'Settings saved.');
$this->application->refresh();
if ($this->ports_exposes !== $this->application->ports_exposes) {
if ($this->ports_exposes !== $this->application->ports_exposes || $this->is_container_label_escape_enabled !== $this->application->settings->is_container_label_escape_enabled) {
$this->resetDefaultLabels(false);
}
}
@ -204,6 +208,9 @@ public function generateDomain(string $serviceName)
$this->application->docker_compose_domains = json_encode($this->parsedServiceDomains);
$this->application->save();
$this->dispatch('success', 'Domain generated.');
if ($this->application->build_pack === 'dockercompose') {
$this->loadComposeFile();
}
return $domain;
}
public function updatedApplicationBaseDirectory()
@ -257,9 +264,12 @@ public function resetDefaultLabels()
{
$this->customLabels = str(implode("|", generateLabelsApplication($this->application)))->replace("|", "\n");
$this->ports_exposes = $this->application->ports_exposes;
$this->is_container_label_escape_enabled = $this->application->settings->is_container_label_escape_enabled;
$this->application->custom_labels = base64_encode($this->customLabels);
$this->application->save();
if ($this->application->build_pack === 'dockercompose') {
$this->loadComposeFile();
}
}
public function checkFqdns($showToaster = true)
@ -300,11 +310,11 @@ public function submit($showToaster = true)
if ($this->application->build_pack === 'dockercompose' && $this->initialDockerComposeLocation !== $this->application->docker_compose_location) {
$compose_return = $this->loadComposeFile();
if ($compose_return instanceof \Livewire\Features\SupportEvents\Event) {
return;
return;
}
}
$this->validate();
if ($this->ports_exposes !== $this->application->ports_exposes) {
if ($this->ports_exposes !== $this->application->ports_exposes || $this->is_container_label_escape_enabled !== $this->application->settings->is_container_label_escape_enabled) {
$this->resetDefaultLabels();
}
if (data_get($this->application, 'build_pack') === 'dockerimage') {

View File

@ -12,6 +12,7 @@ class EditCompose extends Component
protected $rules = [
'service.docker_compose_raw' => 'required',
'service.docker_compose' => 'required',
'service.is_container_label_escape_enabled' => 'required',
];
public function mount()
{
@ -23,6 +24,14 @@ public function saveEditedCompose()
$this->dispatch('info', "Saving new docker compose...");
$this->dispatch('saveCompose', $this->service->docker_compose_raw);
}
public function instantSave()
{
$this->validate([
'service.is_container_label_escape_enabled' => 'required',
]);
$this->service->save(['is_container_label_escape_enabled' => $this->service->is_container_label_escape_enabled]);
$this->dispatch('success', "Service updated successfully");
}
public function render()
{
return view('livewire.project.service.edit-compose');

View File

@ -1174,9 +1174,13 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
]
]);
}
$serviceLabels = $serviceLabels->map(function ($value, $key) {
return escapeDollarSign($value);
});
if ($serviceLabels->count() > 0) {
if ($resource->is_container_label_escape_enabled) {
$serviceLabels = $serviceLabels->map(function ($value, $key) {
return escapeDollarSign($value);
});
}
}
data_set($service, 'labels', $serviceLabels->toArray());
data_forget($service, 'is_database');
if (!data_get($service, 'restart')) {
@ -1279,11 +1283,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$serviceLabels->push("$removedLabelName=$removedLabel");
}
}
if ($serviceLabels->count() > 0) {
$serviceLabels = $serviceLabels->map(function ($value, $key) {
return escapeDollarSign($value);
});
}
$baseName = generateApplicationContainerName($resource, $pull_request_id);
$containerName = "$serviceName-$baseName";
if (count($serviceVolumes) > 0) {
@ -1663,6 +1663,13 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
]
]);
}
if ($serviceLabels->count() > 0) {
if ($resource->settings->is_container_label_escape_enabled) {
$serviceLabels = $serviceLabels->map(function ($value, $key) {
return escapeDollarSign($value);
});
}
}
data_set($service, 'labels', $serviceLabels->toArray());
data_forget($service, 'is_database');
if (!data_get($service, 'restart')) {

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('application_settings', function (Blueprint $table) {
$table->boolean('is_container_label_escape_enabled')->default(true);
});
Schema::table('services', function (Blueprint $table) {
$table->boolean('is_container_label_escape_enabled')->default(true);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('application_settings', function (Blueprint $table) {
$table->dropColumn('is_container_label_escape_enabled');
});
Schema::table('services', function (Blueprint $table) {
$table->dropColumn('is_container_label_escape_enabled');
});
}
};

View File

@ -219,6 +219,11 @@ class="underline" href="https://coolify.io/docs/knowledge-base/docker/registry"
<x-forms.textarea rows="10" readonly id="application.docker_compose"
label="Docker Compose Content" helper="You need to modify the docker compose file." />
@endif
<div class="w-72">
<x-forms.checkbox label="Escape special characters in labels?"
helper="By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$.<br><br>If you want to use env variables inside the labels, turn this off."
id="application.settings.is_container_label_escape_enabled" instantSave></x-forms.checkbox>
</div>
{{-- <x-forms.textarea rows="10" readonly id="application.docker_compose_pr"
label="Docker PR Compose Content" helper="You need to modify the docker compose file." /> --}}
@endif
@ -242,8 +247,15 @@ class="underline" href="https://coolify.io/docs/knowledge-base/docker/registry"
@endif
</div>
<x-forms.textarea label="Container Labels" rows="15" id="customLabels"></x-forms.textarea>
<x-modal-confirmation buttonFullWidth action="resetDefaultLabels" buttonTitle="Reset to Coolify Generated Labels">
Are you sure you want to reset the labels to Coolify generated labels? <br>It could break the proxy configuration after you restart the container.
<div class="w-72">
<x-forms.checkbox label="Escape special characters in labels?"
helper="By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$.<br><br>If you want to use env variables inside the labels, turn this off."
id="application.settings.is_container_label_escape_enabled" instantSave></x-forms.checkbox>
</div>
<x-modal-confirmation buttonFullWidth action="resetDefaultLabels"
buttonTitle="Reset to Coolify Generated Labels">
Are you sure you want to reset the labels to Coolify generated labels? <br>It could break the proxy
configuration after you restart the container.
</x-modal-confirmation>
@endif

View File

@ -3,6 +3,11 @@
prevent
name collision. <br>To see the actual volume names, check the Deployable Compose file, or go to Storage
menu.</div>
<div class="pb-2 w-72">
<x-forms.checkbox label="Escape special characters in labels?"
helper="By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$.<br><br>If you want to use env variables inside the labels, turn this off."
id="service.is_container_label_escape_enabled" instantSave></x-forms.checkbox>
</div>
<div x-cloak x-show="raw" class="font-mono">
<x-forms.textarea allowTab rows="20" id="service.docker_compose_raw">
</x-forms.textarea>
@ -14,10 +19,10 @@
<div class="flex justify-end w-full gap-2 pt-4">
<div class="flex items-end gap-2">
<div x-cloak x-show="raw">
<x-forms.button class="w-64" @click.prevent="raw = !raw">Show Deployable Compose</x-forms.button>
<x-forms.button class="w-64" @click.prevent="raw = !raw">Show Deployable Compose</x-forms.button>
</div>
<div x-cloak x-show="raw === false">
<x-forms.button class="w-64" @click.prevent="raw = !raw">Show Source
<x-forms.button class="w-64" @click.prevent="raw = !raw">Show Source
Compose</x-forms.button>
</div>
</div>