Merge pull request #1687 from coollabsio/next

v4.0.0-beta.202
This commit is contained in:
Andras Bacsai 2024-01-29 16:37:39 +01:00 committed by GitHub
commit 4792146f1d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 155 additions and 28 deletions

View File

@ -32,13 +32,14 @@ class DeleteService
}
$database->forceDelete();
}
foreach ($storagesToDelete as $storage) {
$commands[] = "docker volume rm -f $storage->name";
if ($server->isFunctional()) {
foreach ($storagesToDelete as $storage) {
$commands[] = "docker volume rm -f $storage->name";
}
$commands[] = "docker rm -f $service->uuid";
instant_remote_process($commands, $server, false);
}
$commands[] = "docker rm -f $service->uuid";
instant_remote_process($commands, $server, false);
$service->forceDelete();
}
}

View File

@ -1128,6 +1128,11 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
data_forget($docker_compose, 'services.' . $this->container_name);
$custom_compose = convert_docker_run_to_compose($this->application->custom_docker_run_options);
if (count($custom_compose) > 0) {
$docker_compose['services'][$this->application->uuid] = array_merge_recursive($docker_compose['services'][$this->application->uuid], $custom_compose);
}
$this->docker_compose = Yaml::dump($docker_compose, 10);
$this->docker_compose_base64 = base64_encode($this->docker_compose);
$this->execute_remote_command([executeInDocker($this->deployment_uuid, "echo '{$this->docker_compose_base64}' | base64 -d > {$this->workdir}/docker-compose.yml"), "hidden" => true]);

View File

@ -61,11 +61,12 @@ class General extends Component
'application.docker_compose_pr' => 'nullable',
'application.docker_compose_raw' => 'nullable',
'application.docker_compose_pr_raw' => 'nullable',
'application.custom_labels' => 'nullable',
'application.dockerfile_target_build' => 'nullable',
'application.settings.is_static' => 'boolean|required',
'application.docker_compose_custom_start_command' => 'nullable',
'application.docker_compose_custom_build_command' => 'nullable',
'application.custom_labels' => 'nullable',
'application.custom_docker_run_options' => 'nullable',
'application.settings.is_static' => 'boolean|required',
'application.settings.is_raw_compose_deployment_enabled' => 'boolean|required',
'application.settings.is_build_server_enabled' => 'boolean|required',
];
@ -97,9 +98,10 @@ class General extends Component
'application.docker_compose_pr_raw' => 'Docker compose raw',
'application.custom_labels' => 'Custom labels',
'application.dockerfile_target_build' => 'Dockerfile target build',
'application.settings.is_static' => 'Is static',
'application.custom_docker_run_options' => 'Custom docker run commands',
'application.docker_compose_custom_start_command' => 'Docker compose custom start command',
'application.docker_compose_custom_build_command' => 'Docker compose custom build command',
'application.settings.is_static' => 'Is static',
'application.settings.is_raw_compose_deployment_enabled' => 'Is raw compose deployment enabled',
'application.settings.is_build_server_enabled' => 'Is build server enabled',
];
@ -249,6 +251,9 @@ class General extends Component
$this->application->fqdn = $domains->implode(',');
}
if (data_get($this->application, 'custom_docker_run_options')) {
$this->application->custom_docker_run_options = str($this->application->custom_docker_run_options)->trim();
}
if (data_get($this->application, 'dockerfile')) {
$port = get_port_from_dockerfile($this->application->dockerfile);
if ($port && !$this->application->ports_exposes) {

View File

@ -905,8 +905,7 @@ class Application extends BaseModel
$commands->push("echo 'Checking out $branch'");
}
$git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$customPort} -o Port={$customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" git fetch origin $branch && git checkout $pr_branch_name";
}
if ($git_type === 'github') {
} else if ($git_type === 'github') {
$branch = "pull/{$pull_request_id}/head:$pr_branch_name";
if ($exec_in_docker) {
$commands->push(executeInDocker($deployment_uuid, "echo 'Checking out $branch'"));
@ -914,6 +913,13 @@ class Application extends BaseModel
$commands->push("echo 'Checking out $branch'");
}
$git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$customPort} -o Port={$customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" git fetch origin $branch && git checkout $pr_branch_name";
} else if ($git_type === 'bitbucket') {
if ($exec_in_docker) {
$commands->push(executeInDocker($deployment_uuid, "echo 'Checking out $branch'"));
} else {
$commands->push("echo 'Checking out $branch'");
}
$git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$customPort} -o Port={$customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" git checkout $commit";
}
}

View File

@ -3,9 +3,7 @@
use App\Models\Application;
use App\Models\ApplicationPreview;
use App\Models\Server;
use App\Models\Service;
use App\Models\ServiceApplication;
use App\Models\ServiceDatabase;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Spatie\Url\Url;
@ -323,3 +321,89 @@ function isDatabaseImage(?string $image = null)
}
return false;
}
function convert_docker_run_to_compose(?string $custom_docker_run_options = null)
{
$options = [];
$compose_options = collect([]);
preg_match_all('/(--\w+(?:-\w+)*)(?:\s|=)?([^\s-]+)?/', $custom_docker_run_options, $matches, PREG_SET_ORDER);
$list_options = collect([
'--cap-add',
'--cap-drop',
'--security-opt',
'--sysctl',
'--ulimit',
'--device'
]);
$mapping = collect([
'--cap-add' => 'cap_add',
'--cap-drop' => 'cap_drop',
'--security-opt' => 'security_opt',
'--sysctl' => 'sysctls',
'--device' => 'devices',
'--ulimit' => 'ulimits',
'--init' => 'init',
'--ulimit' => 'ulimits',
'--privileged' => 'privileged',
]);
foreach ($matches as $match) {
$option = $match[1];
$value = isset($match[2]) && $match[2] !== '' ? $match[2] : true;
if ($list_options->contains($option)) {
$value = explode(',', $value);
}
if (array_key_exists($option, $options)) {
if (is_array($options[$option])) {
$options[$option][] = $value;
} else {
$options[$option] = [$options[$option], $value];
}
} else {
$options[$option] = $value;
}
}
$options = collect($options);
// Easily get mappings from https://github.com/composerize/composerize/blob/master/packages/composerize/src/mappings.js
foreach ($options as $option => $value) {
if (!data_get($mapping, $option)) {
continue;
}
if ($option === '--ulimit') {
$ulimits = collect([]);
collect($value)->map(function ($ulimit) use ($ulimits){
$ulimit = explode('=', $ulimit);
$type = $ulimit[0];
$limits = explode(':', $ulimit[1]);
if (count($limits) == 2) {
$soft_limit = $limits[0];
$hard_limit = $limits[1];
$ulimits->put($type, [
'soft' => $soft_limit,
'hard' => $hard_limit
]);
} else {
$soft_limit = $ulimit[1];
$ulimits->put($type, [
'soft' => $soft_limit,
]);
}
});
$compose_options->put($mapping[$option], $ulimits);
} else {
if ($list_options->contains($option)) {
if ($compose_options->has($mapping[$option])) {
$compose_options->put($mapping[$option], $options->get($mapping[$option]) . ',' . $value);
} else {
$compose_options->put($mapping[$option], $value);
}
continue;
} else {
$compose_options->put($mapping[$option], $value);
continue;
}
$compose_options->forget($option);
}
}
return $compose_options->toArray();
}

View File

@ -7,7 +7,7 @@ return [
// 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.201',
'release' => '4.0.0-beta.202',
// When left empty or `null` the Laravel environment will be used
'environment' => config('app.env'),

View File

@ -1,3 +1,3 @@
<?php
return '4.0.0-beta.201';
return '4.0.0-beta.202';

View File

@ -0,0 +1,28 @@
<?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('applications', function (Blueprint $table) {
$table->string('custom_docker_run_options')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('applications', function (Blueprint $table) {
$table->dropColumn('custom_docker_run_options');
});
}
};

View File

@ -130,7 +130,6 @@
@endif
@if ($application->could_set_build_commands())
@if ($application->build_pack === 'nixpacks')
<div class="flex flex-col gap-2 xl:flex-row">
<x-forms.input placeholder="If you modify this, you probably need to have a nixpacks.toml"
id="application.install_command" label="Install Command" />
@ -194,6 +193,13 @@
@endif
@endif
</div>
<div>The following options are for advanced use cases. Only modify them if you
know what are
you doing.</div>
<x-forms.input
helper="You can add custom docker run options that will be used when your container is started.<br>Note: Not all options are supported, as they could mess up Coolify's automation and could cause bad experience for users.<br><br>Check the <a class='text-white underline' href='https://coolify.io/docs/custom-docker-options'>docs.</a>"
placeholder="--cap-add SYS_ADMIN --device=/dev/fuse --security-opt apparmor:unconfined --ulimit nofile=1024:1024 --tmpfs /run:rw,noexec,nosuid,size=65536k"
id="application.custom_docker_run_options" label="Custom Docker Options" />
@endif
@endif

View File

@ -14,7 +14,7 @@
~/.ssh/authorized_keys
file</span>
<x-forms.button type="submit">
Save Private Key
Continue
</x-forms.button>
</form>
</div>

View File

@ -277,14 +277,6 @@ Route::post('/source/bitbucket/events/manual', function () {
]);
}
foreach ($applications as $application) {
if (!$application->isPRDeployable()) {
$return_payloads->push([
'application' => $application->name,
'status' => 'failed',
'message' => 'Preview deployments disabled.',
]);
continue;
}
$webhook_secret = data_get($application, 'manual_webhook_secret_bitbucket');
$payload = request()->getContent();
@ -310,7 +302,7 @@ Route::post('/source/bitbucket/events/manual', function () {
continue;
}
if ($x_bitbucket_event === 'repo:push') {
if ($application->isPRDeployable()) {
if ($application->isDeployable()) {
ray('Deploying ' . $application->name . ' with branch ' . $branch);
$deployment_uuid = new Cuid2(7);
queue_application_deployment(
@ -328,7 +320,7 @@ Route::post('/source/bitbucket/events/manual', function () {
$return_payloads->push([
'application' => $application->name,
'status' => 'failed',
'message' => 'Preview deployments disabled.',
'message' => 'Auto deployment disabled.',
]);
}
}

View File

@ -4,7 +4,7 @@
"version": "3.12.36"
},
"v4": {
"version": "4.0.0-beta.201"
"version": "4.0.0-beta.202"
}
}
}