mirror of
https://github.com/tiennm99/coolify.git
synced 2026-10-13 10:15:40 +00:00
fix(upgrade): wait for new version before showing success
Expose the running Coolify version on /api/health and only treat an upgrade as complete once that version meets the target. Parse upgrade status in a shared service, start the update after the Livewire response, and keep polling when the instance is still on the old version.
This commit is contained in:
1 parent
882e25e072
commit
6481ffffcf
6 files changed
+317
-46
No files matched your search
@@ -292,13 +292,20 @@ class OtherController extends Controller
|
||||
|
||||
#[OA\Get(
|
||||
summary: 'Healthcheck',
|
||||
description: 'Healthcheck endpoint.',
|
||||
description: 'Healthcheck endpoint. Includes the running Coolify version in the X-Coolify-Version header.',
|
||||
path: '/health',
|
||||
operationId: 'healthcheck',
|
||||
responses: [
|
||||
new OA\Response(
|
||||
response: 200,
|
||||
description: 'Healthcheck endpoint.',
|
||||
headers: [
|
||||
new OA\Header(
|
||||
header: 'X-Coolify-Version',
|
||||
description: 'Currently running Coolify version.',
|
||||
schema: new OA\Schema(type: 'string', example: '4.3.1'),
|
||||
),
|
||||
],
|
||||
content: new OA\MediaType(
|
||||
mediaType: 'text/html',
|
||||
schema: new OA\Schema(type: 'string'),
|
||||
@@ -316,6 +323,6 @@ class OtherController extends Controller
|
||||
)]
|
||||
public function healthcheck(Request $request)
|
||||
{
|
||||
return 'OK';
|
||||
return response('OK')->header('X-Coolify-Version', (string) config('constants.coolify.version'));
|
||||
}
|
||||
}
|
||||
+13
-41
@@ -5,6 +5,7 @@ namespace App\Livewire;
|
||||
use App\Actions\Server\UpdateCoolify;
|
||||
use App\Models\InstanceSettings;
|
||||
use App\Models\Server;
|
||||
use App\Services\CoolifyUpgradeStatus;
|
||||
use Livewire\Component;
|
||||
|
||||
class Upgrade extends Component
|
||||
@@ -69,7 +70,13 @@ class Upgrade extends Component
|
||||
return;
|
||||
}
|
||||
$this->updateInProgress = true;
|
||||
UpdateCoolify::run(manual_update: true);
|
||||
dispatch(function () {
|
||||
try {
|
||||
UpdateCoolify::run(manual_update: true);
|
||||
} catch (\Throwable $e) {
|
||||
report($e);
|
||||
}
|
||||
})->afterResponse();
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
@@ -100,45 +107,10 @@ class Upgrade extends Component
|
||||
return ['status' => 'none'];
|
||||
}
|
||||
|
||||
if (empty($content)) {
|
||||
return ['status' => 'none'];
|
||||
}
|
||||
|
||||
$parts = explode('|', $content);
|
||||
if (count($parts) < 3) {
|
||||
return ['status' => 'none'];
|
||||
}
|
||||
|
||||
[$step, $message, $timestamp] = $parts;
|
||||
|
||||
// Check if status is stale (older than 10 minutes)
|
||||
try {
|
||||
$statusTime = new \DateTime($timestamp);
|
||||
$now = new \DateTime;
|
||||
$diffMinutes = ($now->getTimestamp() - $statusTime->getTimestamp()) / 60;
|
||||
|
||||
if ($diffMinutes > 10) {
|
||||
return ['status' => 'none'];
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
return ['status' => 'none'];
|
||||
}
|
||||
|
||||
if ($step === 'error') {
|
||||
return [
|
||||
'status' => 'error',
|
||||
'step' => 0,
|
||||
'message' => $message,
|
||||
];
|
||||
}
|
||||
|
||||
$stepInt = (int) $step;
|
||||
$status = $stepInt >= 6 ? 'complete' : 'in_progress';
|
||||
|
||||
return [
|
||||
'status' => $status,
|
||||
'step' => $stepInt,
|
||||
'message' => $message,
|
||||
];
|
||||
return CoolifyUpgradeStatus::fromFile(
|
||||
content: $content,
|
||||
runningVersion: $this->currentVersion !== '' ? $this->currentVersion : (string) config('constants.coolify.version'),
|
||||
targetVersion: $this->latestVersion !== '' ? $this->latestVersion : get_latest_version_of_coolify(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use DateTimeInterface;
|
||||
|
||||
class CoolifyUpgradeStatus
|
||||
{
|
||||
public const STALE_AFTER_MINUTES = 10;
|
||||
|
||||
/**
|
||||
* @return array{status: string, step?: int, message?: string, running_version: string, target_version: string}
|
||||
*/
|
||||
public static function fromFile(
|
||||
string $content,
|
||||
string $runningVersion,
|
||||
string $targetVersion,
|
||||
?DateTimeInterface $now = null,
|
||||
int $staleAfterMinutes = self::STALE_AFTER_MINUTES,
|
||||
): array {
|
||||
$base = [
|
||||
'running_version' => $runningVersion,
|
||||
'target_version' => $targetVersion,
|
||||
];
|
||||
|
||||
$content = trim($content);
|
||||
if ($content === '') {
|
||||
return ['status' => 'none', ...$base];
|
||||
}
|
||||
|
||||
$parts = explode('|', $content);
|
||||
if (count($parts) < 3) {
|
||||
return ['status' => 'none', ...$base];
|
||||
}
|
||||
|
||||
[$step, $message, $timestamp] = $parts;
|
||||
|
||||
try {
|
||||
$statusTime = new \DateTime($timestamp);
|
||||
$now = $now ?? new \DateTime;
|
||||
$diffMinutes = ($now->getTimestamp() - $statusTime->getTimestamp()) / 60;
|
||||
|
||||
if ($diffMinutes > $staleAfterMinutes) {
|
||||
return ['status' => 'none', ...$base];
|
||||
}
|
||||
} catch (\Throwable) {
|
||||
return ['status' => 'none', ...$base];
|
||||
}
|
||||
|
||||
if ($step === 'error') {
|
||||
return [
|
||||
'status' => 'error',
|
||||
'step' => 0,
|
||||
'message' => $message,
|
||||
...$base,
|
||||
];
|
||||
}
|
||||
|
||||
$stepInt = (int) $step;
|
||||
|
||||
if ($stepInt >= 6 && ! self::hasReachedTargetVersion($runningVersion, $targetVersion)) {
|
||||
return [
|
||||
'status' => 'in_progress',
|
||||
'step' => $stepInt,
|
||||
'message' => "Waiting for Coolify {$targetVersion} to come online...",
|
||||
...$base,
|
||||
];
|
||||
}
|
||||
|
||||
$status = $stepInt >= 6 ? 'complete' : 'in_progress';
|
||||
|
||||
return [
|
||||
'status' => $status,
|
||||
'step' => $stepInt,
|
||||
'message' => $message,
|
||||
...$base,
|
||||
];
|
||||
}
|
||||
|
||||
public static function hasReachedTargetVersion(string $runningVersion, string $targetVersion): bool
|
||||
{
|
||||
if ($runningVersion === '' || $targetVersion === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return version_compare($runningVersion, $targetVersion, '>=');
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user