feat: add command healthcheck type
This commit is contained in:
parent
c3ff32b287
commit
342e8e765d
9 changed files with 143 additions and 24 deletions
|
|
@ -1798,7 +1798,8 @@ private function health_check()
|
||||||
$counter = 1;
|
$counter = 1;
|
||||||
$this->application_deployment_queue->addLogEntry('Waiting for healthcheck to pass on the new container.');
|
$this->application_deployment_queue->addLogEntry('Waiting for healthcheck to pass on the new container.');
|
||||||
if ($this->full_healthcheck_url && ! $this->application->custom_healthcheck_found) {
|
if ($this->full_healthcheck_url && ! $this->application->custom_healthcheck_found) {
|
||||||
$this->application_deployment_queue->addLogEntry("Healthcheck URL (inside the container): {$this->full_healthcheck_url}");
|
$healthcheckLabel = $this->application->health_check_type === 'cmd' ? 'Healthcheck command' : 'Healthcheck URL';
|
||||||
|
$this->application_deployment_queue->addLogEntry("{$healthcheckLabel} (inside the container): {$this->full_healthcheck_url}");
|
||||||
}
|
}
|
||||||
$this->application_deployment_queue->addLogEntry("Waiting for the start period ({$this->application->health_check_start_period} seconds) before starting healthcheck.");
|
$this->application_deployment_queue->addLogEntry("Waiting for the start period ({$this->application->health_check_start_period} seconds) before starting healthcheck.");
|
||||||
$sleeptime = 0;
|
$sleeptime = 0;
|
||||||
|
|
@ -2749,6 +2750,14 @@ private function generate_local_persistent_volumes_only_volume_names()
|
||||||
|
|
||||||
private function generate_healthcheck_commands()
|
private function generate_healthcheck_commands()
|
||||||
{
|
{
|
||||||
|
// Handle CMD type healthcheck
|
||||||
|
if ($this->application->health_check_type === 'cmd' && ! empty($this->application->health_check_command)) {
|
||||||
|
$this->full_healthcheck_url = $this->application->health_check_command;
|
||||||
|
|
||||||
|
return $this->application->health_check_command;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTTP type healthcheck (default)
|
||||||
if (! $this->application->health_check_port) {
|
if (! $this->application->health_check_port) {
|
||||||
$health_check_port = $this->application->ports_exposes_array[0];
|
$health_check_port = $this->application->ports_exposes_array[0];
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,12 @@ class HealthChecks extends Component
|
||||||
#[Validate(['boolean'])]
|
#[Validate(['boolean'])]
|
||||||
public bool $healthCheckEnabled = false;
|
public bool $healthCheckEnabled = false;
|
||||||
|
|
||||||
|
#[Validate(['string', 'in:http,cmd'])]
|
||||||
|
public string $healthCheckType = 'http';
|
||||||
|
|
||||||
|
#[Validate(['nullable', 'string'])]
|
||||||
|
public ?string $healthCheckCommand = null;
|
||||||
|
|
||||||
#[Validate(['string'])]
|
#[Validate(['string'])]
|
||||||
public string $healthCheckMethod;
|
public string $healthCheckMethod;
|
||||||
|
|
||||||
|
|
@ -54,6 +60,8 @@ class HealthChecks extends Component
|
||||||
|
|
||||||
protected $rules = [
|
protected $rules = [
|
||||||
'healthCheckEnabled' => 'boolean',
|
'healthCheckEnabled' => 'boolean',
|
||||||
|
'healthCheckType' => 'string|in:http,cmd',
|
||||||
|
'healthCheckCommand' => 'nullable|string',
|
||||||
'healthCheckPath' => 'string',
|
'healthCheckPath' => 'string',
|
||||||
'healthCheckPort' => 'nullable|string',
|
'healthCheckPort' => 'nullable|string',
|
||||||
'healthCheckHost' => 'string',
|
'healthCheckHost' => 'string',
|
||||||
|
|
@ -81,6 +89,8 @@ public function syncData(bool $toModel = false): void
|
||||||
|
|
||||||
// Sync to model
|
// Sync to model
|
||||||
$this->resource->health_check_enabled = $this->healthCheckEnabled;
|
$this->resource->health_check_enabled = $this->healthCheckEnabled;
|
||||||
|
$this->resource->health_check_type = $this->healthCheckType;
|
||||||
|
$this->resource->health_check_command = $this->healthCheckCommand;
|
||||||
$this->resource->health_check_method = $this->healthCheckMethod;
|
$this->resource->health_check_method = $this->healthCheckMethod;
|
||||||
$this->resource->health_check_scheme = $this->healthCheckScheme;
|
$this->resource->health_check_scheme = $this->healthCheckScheme;
|
||||||
$this->resource->health_check_host = $this->healthCheckHost;
|
$this->resource->health_check_host = $this->healthCheckHost;
|
||||||
|
|
@ -98,6 +108,8 @@ public function syncData(bool $toModel = false): void
|
||||||
} else {
|
} else {
|
||||||
// Sync from model
|
// Sync from model
|
||||||
$this->healthCheckEnabled = $this->resource->health_check_enabled;
|
$this->healthCheckEnabled = $this->resource->health_check_enabled;
|
||||||
|
$this->healthCheckType = $this->resource->health_check_type ?? 'http';
|
||||||
|
$this->healthCheckCommand = $this->resource->health_check_command;
|
||||||
$this->healthCheckMethod = $this->resource->health_check_method;
|
$this->healthCheckMethod = $this->resource->health_check_method;
|
||||||
$this->healthCheckScheme = $this->resource->health_check_scheme;
|
$this->healthCheckScheme = $this->resource->health_check_scheme;
|
||||||
$this->healthCheckHost = $this->resource->health_check_host;
|
$this->healthCheckHost = $this->resource->health_check_host;
|
||||||
|
|
@ -119,6 +131,8 @@ public function instantSave()
|
||||||
|
|
||||||
// Sync component properties to model
|
// Sync component properties to model
|
||||||
$this->resource->health_check_enabled = $this->healthCheckEnabled;
|
$this->resource->health_check_enabled = $this->healthCheckEnabled;
|
||||||
|
$this->resource->health_check_type = $this->healthCheckType;
|
||||||
|
$this->resource->health_check_command = $this->healthCheckCommand;
|
||||||
$this->resource->health_check_method = $this->healthCheckMethod;
|
$this->resource->health_check_method = $this->healthCheckMethod;
|
||||||
$this->resource->health_check_scheme = $this->healthCheckScheme;
|
$this->resource->health_check_scheme = $this->healthCheckScheme;
|
||||||
$this->resource->health_check_host = $this->healthCheckHost;
|
$this->resource->health_check_host = $this->healthCheckHost;
|
||||||
|
|
@ -143,6 +157,8 @@ public function submit()
|
||||||
|
|
||||||
// Sync component properties to model
|
// Sync component properties to model
|
||||||
$this->resource->health_check_enabled = $this->healthCheckEnabled;
|
$this->resource->health_check_enabled = $this->healthCheckEnabled;
|
||||||
|
$this->resource->health_check_type = $this->healthCheckType;
|
||||||
|
$this->resource->health_check_command = $this->healthCheckCommand;
|
||||||
$this->resource->health_check_method = $this->healthCheckMethod;
|
$this->resource->health_check_method = $this->healthCheckMethod;
|
||||||
$this->resource->health_check_scheme = $this->healthCheckScheme;
|
$this->resource->health_check_scheme = $this->healthCheckScheme;
|
||||||
$this->resource->health_check_host = $this->healthCheckHost;
|
$this->resource->health_check_host = $this->healthCheckHost;
|
||||||
|
|
@ -171,6 +187,8 @@ public function toggleHealthcheck()
|
||||||
|
|
||||||
// Sync component properties to model
|
// Sync component properties to model
|
||||||
$this->resource->health_check_enabled = $this->healthCheckEnabled;
|
$this->resource->health_check_enabled = $this->healthCheckEnabled;
|
||||||
|
$this->resource->health_check_type = $this->healthCheckType;
|
||||||
|
$this->resource->health_check_command = $this->healthCheckCommand;
|
||||||
$this->resource->health_check_method = $this->healthCheckMethod;
|
$this->resource->health_check_method = $this->healthCheckMethod;
|
||||||
$this->resource->health_check_scheme = $this->healthCheckScheme;
|
$this->resource->health_check_scheme = $this->healthCheckScheme;
|
||||||
$this->resource->health_check_host = $this->healthCheckHost;
|
$this->resource->health_check_host = $this->healthCheckHost;
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,8 @@
|
||||||
'health_check_timeout' => ['type' => 'integer', 'description' => 'Health check timeout in seconds.'],
|
'health_check_timeout' => ['type' => 'integer', 'description' => 'Health check timeout in seconds.'],
|
||||||
'health_check_retries' => ['type' => 'integer', 'description' => 'Health check retries count.'],
|
'health_check_retries' => ['type' => 'integer', 'description' => 'Health check retries count.'],
|
||||||
'health_check_start_period' => ['type' => 'integer', 'description' => 'Health check start period in seconds.'],
|
'health_check_start_period' => ['type' => 'integer', 'description' => 'Health check start period in seconds.'],
|
||||||
|
'health_check_type' => ['type' => 'string', 'description' => 'Health check type: http or cmd.', 'enum' => ['http', 'cmd']],
|
||||||
|
'health_check_command' => ['type' => 'string', 'nullable' => true, 'description' => 'Health check command for CMD type.'],
|
||||||
'limits_memory' => ['type' => 'string', 'description' => 'Memory limit.'],
|
'limits_memory' => ['type' => 'string', 'description' => 'Memory limit.'],
|
||||||
'limits_memory_swap' => ['type' => 'string', 'description' => 'Memory swap limit.'],
|
'limits_memory_swap' => ['type' => 'string', 'description' => 'Memory swap limit.'],
|
||||||
'limits_memory_swappiness' => ['type' => 'integer', 'description' => 'Memory swappiness.'],
|
'limits_memory_swappiness' => ['type' => 'integer', 'description' => 'Memory swappiness.'],
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?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
|
||||||
|
{
|
||||||
|
if (! Schema::hasColumn('applications', 'health_check_type')) {
|
||||||
|
Schema::table('applications', function (Blueprint $table) {
|
||||||
|
$table->text('health_check_type')->default('http')->after('health_check_enabled');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! Schema::hasColumn('applications', 'health_check_command')) {
|
||||||
|
Schema::table('applications', function (Blueprint $table) {
|
||||||
|
$table->text('health_check_command')->nullable()->after('health_check_type');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
if (Schema::hasColumn('applications', 'health_check_type')) {
|
||||||
|
Schema::table('applications', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('health_check_type');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Schema::hasColumn('applications', 'health_check_command')) {
|
||||||
|
Schema::table('applications', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('health_check_command');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
13
openapi.json
13
openapi.json
|
|
@ -10173,6 +10173,19 @@
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"description": "Health check start period in seconds."
|
"description": "Health check start period in seconds."
|
||||||
},
|
},
|
||||||
|
"health_check_type": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Health check type: http or cmd.",
|
||||||
|
"enum": [
|
||||||
|
"http",
|
||||||
|
"cmd"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"health_check_command": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true,
|
||||||
|
"description": "Health check command for CMD type."
|
||||||
|
},
|
||||||
"limits_memory": {
|
"limits_memory": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Memory limit."
|
"description": "Memory limit."
|
||||||
|
|
|
||||||
10
openapi.yaml
10
openapi.yaml
|
|
@ -6416,6 +6416,16 @@ components:
|
||||||
health_check_start_period:
|
health_check_start_period:
|
||||||
type: integer
|
type: integer
|
||||||
description: 'Health check start period in seconds.'
|
description: 'Health check start period in seconds.'
|
||||||
|
health_check_type:
|
||||||
|
type: string
|
||||||
|
description: 'Health check type: http or cmd.'
|
||||||
|
enum:
|
||||||
|
- http
|
||||||
|
- cmd
|
||||||
|
health_check_command:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
description: 'Health check command for CMD type.'
|
||||||
limits_memory:
|
limits_memory:
|
||||||
type: string
|
type: string
|
||||||
description: 'Memory limit.'
|
description: 'Memory limit.'
|
||||||
|
|
|
||||||
|
|
@ -20,25 +20,48 @@
|
||||||
<p>A custom health check has been detected. If you enable this health check, it will disable the custom one and use this instead.</p>
|
<p>A custom health check has been detected. If you enable this health check, it will disable the custom one and use this instead.</p>
|
||||||
</x-callout>
|
</x-callout>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
{{-- Healthcheck Type Selector --}}
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<x-forms.select canGate="update" :canResource="$resource" id="healthCheckMethod" label="Method" required>
|
<x-forms.select canGate="update" :canResource="$resource" id="healthCheckType" label="Type" required wire:model.live="healthCheckType">
|
||||||
<option value="GET">GET</option>
|
<option value="http">HTTP</option>
|
||||||
<option value="POST">POST</option>
|
<option value="cmd">CMD</option>
|
||||||
</x-forms.select>
|
</x-forms.select>
|
||||||
<x-forms.select canGate="update" :canResource="$resource" id="healthCheckScheme" label="Scheme" required>
|
|
||||||
<option value="http">http</option>
|
|
||||||
<option value="https">https</option>
|
|
||||||
</x-forms.select>
|
|
||||||
<x-forms.input canGate="update" :canResource="$resource" id="healthCheckHost" placeholder="localhost" label="Host" required />
|
|
||||||
<x-forms.input canGate="update" :canResource="$resource" type="number" id="healthCheckPort"
|
|
||||||
helper="If no port is defined, the first exposed port will be used." placeholder="80" label="Port" />
|
|
||||||
<x-forms.input canGate="update" :canResource="$resource" id="healthCheckPath" placeholder="/health" label="Path" required />
|
|
||||||
</div>
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<x-forms.input canGate="update" :canResource="$resource" type="number" id="healthCheckReturnCode" placeholder="200" label="Return Code"
|
|
||||||
required />
|
|
||||||
<x-forms.input canGate="update" :canResource="$resource" id="healthCheckResponseText" placeholder="OK" label="Response Text" />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@if ($healthCheckType === 'http')
|
||||||
|
{{-- HTTP Healthcheck Fields --}}
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<x-forms.select canGate="update" :canResource="$resource" id="healthCheckMethod" label="Method" required>
|
||||||
|
<option value="GET">GET</option>
|
||||||
|
<option value="POST">POST</option>
|
||||||
|
</x-forms.select>
|
||||||
|
<x-forms.select canGate="update" :canResource="$resource" id="healthCheckScheme" label="Scheme" required>
|
||||||
|
<option value="http">http</option>
|
||||||
|
<option value="https">https</option>
|
||||||
|
</x-forms.select>
|
||||||
|
<x-forms.input canGate="update" :canResource="$resource" id="healthCheckHost" placeholder="localhost" label="Host" required />
|
||||||
|
<x-forms.input canGate="update" :canResource="$resource" type="number" id="healthCheckPort"
|
||||||
|
helper="If no port is defined, the first exposed port will be used." placeholder="80" label="Port" />
|
||||||
|
<x-forms.input canGate="update" :canResource="$resource" id="healthCheckPath" placeholder="/health" label="Path" required />
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<x-forms.input canGate="update" :canResource="$resource" type="number" id="healthCheckReturnCode" placeholder="200" label="Return Code"
|
||||||
|
required />
|
||||||
|
<x-forms.input canGate="update" :canResource="$resource" id="healthCheckResponseText" placeholder="OK" label="Response Text" />
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
{{-- CMD Healthcheck Fields --}}
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<x-forms.textarea canGate="update" :canResource="$resource" id="healthCheckCommand"
|
||||||
|
label="Command"
|
||||||
|
placeholder="Example: pg_isready -U postgres Example: redis-cli ping Example: curl -f http://localhost:8080/health"
|
||||||
|
helper="The command to run inside the container. It should exit with code 0 on success and non-zero on failure."
|
||||||
|
required />
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
{{-- Common timing fields (used by both types) --}}
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<x-forms.input canGate="update" :canResource="$resource" min="1" type="number" id="healthCheckInterval" placeholder="30"
|
<x-forms.input canGate="update" :canResource="$resource" min="1" type="number" id="healthCheckInterval" placeholder="30"
|
||||||
label="Interval (s)" required />
|
label="Interval (s)" required />
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue