refactor(application): streamline healthcheck parsing from Dockerfile

This commit is contained in:
Andras Bacsai
2025-03-24 11:43:10 +01:00
parent fa6d50ae50
commit 806d892031
5 changed files with 50 additions and 14 deletions

View File

@@ -1211,7 +1211,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
if ($this->container_name) { if ($this->container_name) {
$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) { if ($this->full_healthcheck_url && ! $this->application->custom_healthcheck_found) {
$this->application_deployment_queue->addLogEntry("Healthcheck URL (inside the container): {$this->full_healthcheck_url}"); $this->application_deployment_queue->addLogEntry("Healthcheck URL (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.");
@@ -1718,8 +1718,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
'save' => 'dockerfile_from_repo', 'save' => 'dockerfile_from_repo',
'ignore_errors' => true, 'ignore_errors' => true,
]); ]);
$dockerfile = collect(str($this->saved_outputs->get('dockerfile_from_repo'))->trim()->explode("\n")); $this->application->parseHealthcheckFromDockerfile($this->saved_outputs->get('dockerfile_from_repo'));
$this->application->parseHealthcheckFromDockerfile($dockerfile);
} }
$docker_compose = [ $docker_compose = [
'services' => [ 'services' => [

View File

@@ -369,6 +369,9 @@ class General extends Component
if ($this->application->isDirty('redirect')) { if ($this->application->isDirty('redirect')) {
$this->setRedirect(); $this->setRedirect();
} }
if ($this->application->isDirty('dockerfile')) {
$this->application->parseHealthcheckFromDockerfile($this->application->dockerfile);
}
$this->checkFqdns(); $this->checkFqdns();

View File

@@ -74,7 +74,7 @@ CMD ["nginx", "-g", "daemon off;"]
'fqdn' => $fqdn, 'fqdn' => $fqdn,
]); ]);
$application->parseHealthcheckFromDockerfile(dockerfile: collect(str($this->dockerfile)->trim()->explode("\n")), isInit: true); $application->parseHealthcheckFromDockerfile(dockerfile: $this->dockerfile, isInit: true);
return redirect()->route('project.application.configuration', [ return redirect()->route('project.application.configuration', [
'application_uuid' => $application->uuid, 'application_uuid' => $application->uuid,

View File

@@ -1507,6 +1507,7 @@ class Application extends BaseModel
public function parseHealthcheckFromDockerfile($dockerfile, bool $isInit = false) public function parseHealthcheckFromDockerfile($dockerfile, bool $isInit = false)
{ {
$dockerfile = str($dockerfile)->trim()->explode("\n");
if (str($dockerfile)->contains('HEALTHCHECK') && ($this->isHealthcheckDisabled() || $isInit)) { if (str($dockerfile)->contains('HEALTHCHECK') && ($this->isHealthcheckDisabled() || $isInit)) {
$healthcheckCommand = null; $healthcheckCommand = null;
$lines = $dockerfile->toArray(); $lines = $dockerfile->toArray();
@@ -1526,23 +1527,24 @@ class Application extends BaseModel
} }
} }
if (str($healthcheckCommand)->isNotEmpty()) { if (str($healthcheckCommand)->isNotEmpty()) {
$interval = str($healthcheckCommand)->match('/--interval=(\d+)/'); $interval = str($healthcheckCommand)->match('/--interval=([0-9]+[a-zµ]*)/');
$timeout = str($healthcheckCommand)->match('/--timeout=(\d+)/'); $timeout = str($healthcheckCommand)->match('/--timeout=([0-9]+[a-zµ]*)/');
$start_period = str($healthcheckCommand)->match('/--start-period=(\d+)/'); $start_period = str($healthcheckCommand)->match('/--start-period=([0-9]+[a-zµ]*)/');
$start_interval = str($healthcheckCommand)->match('/--start-interval=(\d+)/'); $start_interval = str($healthcheckCommand)->match('/--start-interval=([0-9]+[a-zµ]*)/');
$retries = str($healthcheckCommand)->match('/--retries=(\d+)/'); $retries = str($healthcheckCommand)->match('/--retries=(\d+)/');
if ($interval->isNotEmpty()) { if ($interval->isNotEmpty()) {
$this->health_check_interval = $interval->toInteger(); $this->health_check_interval = parseDockerfileInterval($interval);
} }
if ($timeout->isNotEmpty()) { if ($timeout->isNotEmpty()) {
$this->health_check_timeout = $timeout->toInteger(); $this->health_check_timeout = parseDockerfileInterval($timeout);
} }
if ($start_period->isNotEmpty()) { if ($start_period->isNotEmpty()) {
$this->health_check_start_period = $start_period->toInteger(); $this->health_check_start_period = parseDockerfileInterval($start_period);
}
if ($start_interval->isNotEmpty()) {
$this->health_check_start_interval = parseDockerfileInterval($start_interval);
} }
// if ($start_interval) {
// $this->health_check_start_interval = $start_interval->value();
// }
if ($retries->isNotEmpty()) { if ($retries->isNotEmpty()) {
$this->health_check_retries = $retries->toInteger(); $this->health_check_retries = $retries->toInteger();
} }

View File

@@ -4137,3 +4137,35 @@ function getJobStatus(?string $jobId = null)
return $jobFound->first()->status; return $jobFound->first()->status;
} }
function parseDockerfileInterval(string $something)
{
$value = preg_replace('/[^0-9]/', '', $something);
$unit = preg_replace('/[0-9]/', '', $something);
// Default to seconds if no unit specified
$unit = $unit ?: 's';
// Convert to seconds based on unit
$seconds = (int) $value;
switch ($unit) {
case 'ns':
$seconds = (int) ($value / 1000000000);
break;
case 'us':
case 'µs':
$seconds = (int) ($value / 1000000);
break;
case 'ms':
$seconds = (int) ($value / 1000);
break;
case 'm':
$seconds = (int) ($value * 60);
break;
case 'h':
$seconds = (int) ($value * 3600);
break;
}
return $seconds;
}