mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
feat(patches): mark security updates, reboot state, and risky packages
- Security updates: apt marks a package from a "-security" suite (Debian 12 now reports oldstable-security). dnf reads `dnf updateinfo list --security` (dnf5 keeps updateinfo as an alias of advisory). zypper uses `zypper -x patch --dry-run --category security`, because `zypper -x list-patches` ignores --category and has no package names. pacman and apk cannot tell, so they show no security count. https://dnf5.readthedocs.io/en/latest/commands/advisory.8.html https://github.com/openSUSE/zypper/blob/master/doc/zypper.8.txt - Reboot required: /var/run/reboot-required, `needrestart -b` (KSTA 2 or 3), `dnf needs-restarting -r` (matched by text, because a missing plugin also exits 1), and `zypper needs-rebooting` (exit 102). https://github.com/liske/needrestart/blob/master/README.batch.md https://dnf-plugins-core.readthedocs.io/en/latest/needs_restarting.html - An explicit risk list per package manager (Docker engine, kernels, libc/glibc/musl, systemd, dbus, openssh) replaces the "name contains docker/kernel" guess on the page and in every notification channel. - The page shows security and reboot badges, a security count, and the risk of each package. "Reboot server" (with confirmation, update policy on the loaded server) schedules the reboot with systemd-run and checks the server again five minutes later. Archived (transferred) servers are never touched. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
6806ed31fa
commit
3da85e2c07
@@ -8,6 +8,7 @@ use App\Notifications\Dto\DiscordMessage;
|
||||
use App\Notifications\Dto\PushoverMessage;
|
||||
use App\Notifications\Dto\SlackMessage;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class ServerPatchCheck extends CustomEmailNotification
|
||||
{
|
||||
@@ -48,6 +49,8 @@ class ServerPatchCheck extends CustomEmailNotification
|
||||
'name' => $this->server->name,
|
||||
'total_updates' => $totalUpdates,
|
||||
'updates' => $this->patchData['updates'] ?? [],
|
||||
'security_updates' => $this->patchData['security_updates'] ?? null,
|
||||
'reboot_required' => $this->patchData['reboot_required'] ?? null,
|
||||
'osId' => $this->patchData['osId'] ?? 'unknown',
|
||||
'package_manager' => $this->patchData['package_manager'] ?? 'unknown',
|
||||
'server_url' => $this->serverUrl,
|
||||
@@ -101,12 +104,7 @@ class ServerPatchCheck extends CustomEmailNotification
|
||||
}
|
||||
|
||||
// Check for critical packages
|
||||
$criticalPackages = collect($updates)->filter(function ($update) {
|
||||
return str_contains(strtolower($update['package']), 'docker') ||
|
||||
str_contains(strtolower($update['package']), 'kernel') ||
|
||||
str_contains(strtolower($update['package']), 'openssh') ||
|
||||
str_contains(strtolower($update['package']), 'ssl');
|
||||
});
|
||||
$criticalPackages = $this->criticalPackages();
|
||||
|
||||
if ($criticalPackages->count() > 0) {
|
||||
$description .= "\n **Critical packages detected** ({$criticalPackages->count()} packages may require restarts)";
|
||||
@@ -169,12 +167,7 @@ class ServerPatchCheck extends CustomEmailNotification
|
||||
}
|
||||
|
||||
// Check for critical packages
|
||||
$criticalPackages = collect($updates)->filter(function ($update) {
|
||||
return str_contains(strtolower($update['package']), 'docker') ||
|
||||
str_contains(strtolower($update['package']), 'kernel') ||
|
||||
str_contains(strtolower($update['package']), 'openssh') ||
|
||||
str_contains(strtolower($update['package']), 'ssl');
|
||||
});
|
||||
$criticalPackages = $this->criticalPackages();
|
||||
|
||||
if ($criticalPackages->count() > 0) {
|
||||
$message .= "\n⚠️ Critical packages detected: {$criticalPackages->count()} packages may require restarts\n";
|
||||
@@ -247,12 +240,7 @@ class ServerPatchCheck extends CustomEmailNotification
|
||||
}
|
||||
|
||||
// Check for critical packages
|
||||
$criticalPackages = collect($updates)->filter(function ($update) {
|
||||
return str_contains(strtolower($update['package']), 'docker') ||
|
||||
str_contains(strtolower($update['package']), 'kernel') ||
|
||||
str_contains(strtolower($update['package']), 'openssh') ||
|
||||
str_contains(strtolower($update['package']), 'ssl');
|
||||
});
|
||||
$criticalPackages = $this->criticalPackages();
|
||||
|
||||
if ($criticalPackages->count() > 0) {
|
||||
$message .= "\nCritical packages detected: {$criticalPackages->count()} may require restarts";
|
||||
@@ -316,12 +304,7 @@ class ServerPatchCheck extends CustomEmailNotification
|
||||
}
|
||||
|
||||
// Check for critical packages
|
||||
$criticalPackages = collect($updates)->filter(function ($update) {
|
||||
return str_contains(strtolower($update['package']), 'docker') ||
|
||||
str_contains(strtolower($update['package']), 'kernel') ||
|
||||
str_contains(strtolower($update['package']), 'openssh') ||
|
||||
str_contains(strtolower($update['package']), 'ssl');
|
||||
});
|
||||
$criticalPackages = $this->criticalPackages();
|
||||
|
||||
if ($criticalPackages->count() > 0) {
|
||||
$description .= "\n:warning: *Critical packages detected:* {$criticalPackages->count()} packages may require restarts\n";
|
||||
@@ -364,12 +347,7 @@ class ServerPatchCheck extends CustomEmailNotification
|
||||
$updates = $this->patchData['updates'] ?? [];
|
||||
|
||||
// Check for critical packages
|
||||
$criticalPackages = collect($updates)->filter(function ($update) {
|
||||
return str_contains(strtolower($update['package']), 'docker') ||
|
||||
str_contains(strtolower($update['package']), 'kernel') ||
|
||||
str_contains(strtolower($update['package']), 'openssh') ||
|
||||
str_contains(strtolower($update['package']), 'ssl');
|
||||
});
|
||||
$criticalPackages = $this->criticalPackages();
|
||||
|
||||
return [
|
||||
'success' => false,
|
||||
@@ -382,7 +360,17 @@ class ServerPatchCheck extends CustomEmailNotification
|
||||
'package_manager' => $this->patchData['package_manager'] ?? 'unknown',
|
||||
'updates' => $updates,
|
||||
'critical_packages_count' => $criticalPackages->count(),
|
||||
'security_updates' => $this->patchData['security_updates'] ?? null,
|
||||
'reboot_required' => $this->patchData['reboot_required'] ?? null,
|
||||
'url' => $this->serverUrl,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates that can restart Docker or core services, or need a reboot (see CheckUpdates::RISKY_PACKAGES).
|
||||
*/
|
||||
private function criticalPackages(): Collection
|
||||
{
|
||||
return collect($this->patchData['updates'] ?? [])->filter(fn (array $update) => filled($update['risk'] ?? null))->values();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user