mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-12 15:53:46 -04:00
fix(server): accept OS derivatives through ID_LIKE in validateOS
validateOS matched only ID from /etc/os-release, so derivatives such as Omarchy, CachyOS, Manjaro or Linux Mint failed validation before the Docker checks ran. Check ID first, then each ID_LIKE entry, and keep the exactly-one-match rule. Move the parsing into a testable function. Closes #12033 Co-authored-by: Furox <177975472+Furox-Art@users.noreply.github.com>
This commit is contained in:
+26
-17
@@ -1728,25 +1728,34 @@ $siteAddress {
|
||||
public function validateOS(): bool|Stringable
|
||||
{
|
||||
$os_release = instant_remote_process(['cat /etc/os-release'], $this);
|
||||
$releaseLines = collect(explode("\n", $os_release));
|
||||
$collectedData = collect([]);
|
||||
foreach ($releaseLines as $line) {
|
||||
$item = str($line)->trim();
|
||||
$collectedData->put($item->before('=')->value(), $item->after('=')->lower()->replace('"', '')->value());
|
||||
}
|
||||
$ID = data_get($collectedData, 'ID');
|
||||
// $ID_LIKE = data_get($collectedData, 'ID_LIKE');
|
||||
// $VERSION_ID = data_get($collectedData, 'VERSION_ID');
|
||||
$supported = collect(SUPPORTED_OS)->filter(function ($supportedOs) use ($ID) {
|
||||
if (str($supportedOs)->contains($ID)) {
|
||||
return str($ID);
|
||||
|
||||
return self::supportedOsFromOsRelease($os_release);
|
||||
}
|
||||
|
||||
/**
|
||||
* Match /etc/os-release against SUPPORTED_OS: ID first, then each ID_LIKE token (e.g. Manjaro: ID=manjaro, ID_LIKE=arch).
|
||||
*/
|
||||
public static function supportedOsFromOsRelease(?string $osRelease): bool|Stringable
|
||||
{
|
||||
$collectedData = collect(explode("\n", (string) $osRelease))
|
||||
->mapWithKeys(function ($line) {
|
||||
$item = str($line)->trim();
|
||||
|
||||
return [$item->before('=')->value() => $item->after('=')->lower()->replace(['"', "'"], '')->value()];
|
||||
});
|
||||
|
||||
$candidates = collect([data_get($collectedData, 'ID')])
|
||||
->merge(explode(' ', (string) data_get($collectedData, 'ID_LIKE')))
|
||||
->filter();
|
||||
|
||||
foreach ($candidates as $candidate) {
|
||||
$supported = collect(SUPPORTED_OS)->filter(fn ($supportedOs) => str($supportedOs)->contains($candidate));
|
||||
if ($supported->count() === 1) {
|
||||
return str($supported->first());
|
||||
}
|
||||
});
|
||||
if ($supported->count() === 1) {
|
||||
return str($supported->first());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function gatherServerMetadata(): ?array
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Server;
|
||||
|
||||
it('matches the supported OS family from os-release', function (string $osRelease, string|false $expected) {
|
||||
$result = Server::supportedOsFromOsRelease($osRelease);
|
||||
|
||||
expect($result === false ? false : $result->value())->toBe($expected);
|
||||
})->with([
|
||||
'ubuntu by ID' => ["ID=ubuntu\nID_LIKE=debian", 'ubuntu debian raspbian pop'],
|
||||
'arch by ID' => ['ID=arch', 'arch'],
|
||||
'rocky by ID' => ["ID=\"rocky\"\nID_LIKE=\"rhel centos fedora\"", 'centos fedora rhel ol rocky amzn almalinux'],
|
||||
'omarchy by ID_LIKE' => ["NAME=\"Omarchy\"\nID=omarchy\nID_LIKE=arch", 'arch'],
|
||||
'manjaro by ID_LIKE' => ["ID=manjaro\nID_LIKE=arch", 'arch'],
|
||||
'linux mint by ID_LIKE' => ["ID=linuxmint\nID_LIKE=\"ubuntu debian\"", 'ubuntu debian raspbian pop'],
|
||||
'single-quoted ID_LIKE' => ["ID=zorin\nID_LIKE='ubuntu debian'", 'ubuntu debian raspbian pop'],
|
||||
'unsupported without ID_LIKE' => ['ID=gentoo', false],
|
||||
'unsupported ID_LIKE' => ["ID=foo\nID_LIKE=bar", false],
|
||||
'empty output' => ['', false],
|
||||
]);
|
||||
|
||||
it('returns false for null os-release output', function () {
|
||||
expect(Server::supportedOsFromOsRelease(null))->toBeFalse();
|
||||
});
|
||||
Reference in New Issue
Block a user