From 2dc85873f1331f9d419372cb7b540039abcd3b7e Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 19 Dec 2023 17:56:50 +0100 Subject: [systemstatus] Add notice about security updates to main page --- modules-available/systemstatus/hooks/cron.inc.php | 6 +++ .../systemstatus/hooks/main-warning.inc.php | 5 +++ .../systemstatus/inc/systemstatus.inc.php | 49 ++++++++++++++++++++++ .../systemstatus/lang/de/messages.json | 1 + .../systemstatus/lang/en/messages.json | 1 + modules-available/systemstatus/page.inc.php | 15 ++++++- .../systemstatus/templates/sys-update-main.html | 2 +- 7 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 modules-available/systemstatus/hooks/cron.inc.php (limited to 'modules-available') diff --git a/modules-available/systemstatus/hooks/cron.inc.php b/modules-available/systemstatus/hooks/cron.inc.php new file mode 100644 index 00000000..91e069d4 --- /dev/null +++ b/modules-available/systemstatus/hooks/cron.inc.php @@ -0,0 +1,6 @@ + 0) { + Message::addWarning('systemstatus.security-updates-available', true, $cnt); +} + $pkgs = SystemStatus::getPackagesRequiringReboot(); if (!empty($pkgs)) { Message::addInfo('systemstatus.update-reboot-required', true, implode(', ', $pkgs)); diff --git a/modules-available/systemstatus/inc/systemstatus.inc.php b/modules-available/systemstatus/inc/systemstatus.inc.php index 4f87fa4e..dc81419f 100644 --- a/modules-available/systemstatus/inc/systemstatus.inc.php +++ b/modules-available/systemstatus/inc/systemstatus.inc.php @@ -3,6 +3,8 @@ class SystemStatus { + const PROP_UPGRADABLE_COUNT = 'systemstatus.upgradable-count'; + /** * Collect status about the disk and vmstore. * The *Usage vars are filled with arrays with keys mountPoint, fileSystem, @@ -108,4 +110,51 @@ class SystemStatus return array_unique($lines); } + /** + * Get a task struct querying upgradable packages. This adds + * a hook to the task to cache the number of upgradable packages + * that are security upgrades, so it is preferred to call this + * wrapper instead of running the task directly. + */ + public static function getUpgradableTask() + { + $task = Taskmanager::submit('AptGetUpgradable'); + if (Taskmanager::isTask($task)) { + TaskmanagerCallback::addCallback($task, 'ssUpgradable'); + } + return $task; + } + + /** + * Called from Taskmanager callback after invoking getUpgradableTask(). + */ + public static function setUpgradableData(array $task) + { + if (Taskmanager::isFailed($task) || !Taskmanager::isFinished($task) || !isset($task['data']['packages'])) + return; + $count = 0; + foreach ($task['data']['packages'] as $package) { + if (substr($package['source'], -9) === '-security') { + $count++; + } + } + error_log("Upgradable security count: $count, total count: " . count($task['data']['packages'])); + Property::set(self::PROP_UPGRADABLE_COUNT, $count . '|' . count($task['data']['packages']), 61); + } + + /** + * Get number of packages that can be upgraded and are security updates. + * This is a cached value and should be updated at least once an hour. + */ + public static function getUpgradableSecurityCount(): int + { + $str = Property::get(self::PROP_UPGRADABLE_COUNT); + if ($str === false) + return 0; + $p = explode('|', $str); + if (empty($p) || !is_numeric($p[0])) + return 0; + return (int)$p[0]; + } + } \ No newline at end of file diff --git a/modules-available/systemstatus/lang/de/messages.json b/modules-available/systemstatus/lang/de/messages.json index e9a8e736..551e937a 100644 --- a/modules-available/systemstatus/lang/de/messages.json +++ b/modules-available/systemstatus/lang/de/messages.json @@ -1,5 +1,6 @@ { "apt-db-out-of-date": "Die Systemupdate-Datenbank ist veraltet ({{0}}). Erw\u00e4gen Sie, nach neuen Updates zu suchen, und diese zu installieren.", + "security-updates-available": "Ausstehende Sicherheitsupdates: {{0}}", "storage-low-system": "Dem Betriebssystem geht der freie Speicher aus. Nur noch {{0}} frei. Versuchen Sie, alte \"Netboot Grundsystem\"-Versionen zu l\u00f6schen.", "storage-low-vmstore": "Auf dem VMstore sind nur noch {{0}} frei", "update-reboot-required": "Das Update der folgenden Pakete erfordert einen Reboot des Servers: {{0}}" diff --git a/modules-available/systemstatus/lang/en/messages.json b/modules-available/systemstatus/lang/en/messages.json index d708838a..2afc3431 100644 --- a/modules-available/systemstatus/lang/en/messages.json +++ b/modules-available/systemstatus/lang/en/messages.json @@ -1,5 +1,6 @@ { "apt-db-out-of-date": "The system update database is out of date ({{0}}). Consider checking for new updates and installing them.", + "security-updates-available": "Pending security updates: {{0}}", "storage-low-system": "System storage running out. Only {{0}} free. You could try deleting old Net-boot OS versions.", "storage-low-vmstore": "VMstore space is running out. Only {{0}} left.", "update-reboot-required": "Updating the following system packages requires reboot: {{0}}" diff --git a/modules-available/systemstatus/page.inc.php b/modules-available/systemstatus/page.inc.php index 92cea5ab..f774c4e0 100644 --- a/modules-available/systemstatus/page.inc.php +++ b/modules-available/systemstatus/page.inc.php @@ -48,6 +48,7 @@ class Page_SystemStatus extends Page User::assertPermission('apt.fix'); $aptAction = 'FIX'; break; + default: } if ($aptAction !== null) { if (!Taskmanager::isRunning(Taskmanager::status(self::TM_UPDATE_UUID))) { @@ -94,7 +95,8 @@ class Page_SystemStatus extends Page 'type' => $tab, 'name' => Dictionary::translate('tab_' . $tab), 'enabled' => User::hasPermission('tab.' . $tab), - 'important' => $tab === 'ListUpgradable' && SystemStatus::getAptLastDbUpdateTime() + 864000 < time(), + 'important' => $tab === 'ListUpgradable' + && (SystemStatus::getAptLastDbUpdateTime() + 864000 < time() || SystemStatus::getUpgradableSecurityCount() > 0), ); } Permission::addGlobalTags($data['perms'], null, ['serverreboot']); @@ -135,7 +137,7 @@ class Page_SystemStatus extends Page return; } - $task = Taskmanager::submit('AptGetUpgradable'); + $task = SystemStatus::getUpgradableTask(); // Estimate last time package list was updated $lastPackageInstalled = SystemStatus::getDpkgLastPackageChanges(); @@ -159,6 +161,15 @@ class Page_SystemStatus extends Page $task['data']['error'] = 'ECONNREFUSED'; } + foreach ($task['data']['packages'] as &$pkg) { + if (substr($pkg['source'], -9) === '-security') { + $pkg['row_class'] = 'bg-danger'; + } else { + $pkg['row_class'] = ''; + } + } + unset($pkg); + echo Render::parse('sys-update-main', [ 'task' => $task['data'], 'lastDownload' => Util::prettyTime($lastListDownloadAttempt), diff --git a/modules-available/systemstatus/templates/sys-update-main.html b/modules-available/systemstatus/templates/sys-update-main.html index 4bc3b00d..ca502ddb 100644 --- a/modules-available/systemstatus/templates/sys-update-main.html +++ b/modules-available/systemstatus/templates/sys-update-main.html @@ -76,7 +76,7 @@ {{#task.packages}} - + {{name}}/{{source}} {{oldVersion}} → -- cgit v1.2.3-55-g7522