From 13c22169624e5633977ed62b95aed844301881ac Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 4 Jul 2023 14:10:46 +0200 Subject: [systemstatus] Show (estimate) of last time updates were installed Plus other minor tweaks, like message on main page. --- .../permissionmanager/install.inc.php | 3 +- .../systemstatus/hooks/main-warning.inc.php | 6 ++++ .../systemstatus/inc/systemstatus.inc.php | 38 ++++++++++++++++++++++ .../systemstatus/lang/de/messages.json | 1 + .../systemstatus/lang/de/permissions.json | 1 + .../systemstatus/lang/de/template-tags.json | 1 + .../systemstatus/lang/en/messages.json | 1 + modules-available/systemstatus/lang/en/module.json | 2 +- .../systemstatus/lang/en/permissions.json | 1 + .../systemstatus/lang/en/template-tags.json | 1 + modules-available/systemstatus/page.inc.php | 23 ++++++------- .../systemstatus/permissions/permissions.json | 3 ++ .../systemstatus/templates/sys-update-main.html | 18 ++++++---- 13 files changed, 77 insertions(+), 22 deletions(-) diff --git a/modules-available/permissionmanager/install.inc.php b/modules-available/permissionmanager/install.inc.php index a1533ac3..40b153ad 100644 --- a/modules-available/permissionmanager/install.inc.php +++ b/modules-available/permissionmanager/install.inc.php @@ -123,8 +123,6 @@ if (Database::exec("INSERT INTO `role` (roleid, rolename, builtin, roledescripti (3,'Prüfungsadmin', 1, 'Kann E-Prüfungen verwalten, Prüfungsmodus einschalten, etc.'), (4,'Lesezugriff', 1, 'Kann auf die meisten Seiten zugreifen, jedoch keine Änderungen vornehmen') ON DUPLICATE KEY UPDATE rolename = VALUES(rolename), builtin = 1, roledescription = VALUES(roledescription)") !== false) { - // Old ruleset accidentally gave write permissions to the read-only role - Database::exec("DELETE FROM role_x_permission WHERE roleid = 4 AND permissionid = 'news.*'"); // Assign roles to location (all) Database::exec("DELETE FROM role_x_location WHERE roleid IN (1,2,3,4)"); Database::exec("INSERT INTO `role_x_location` VALUES (1,NULL),(2,NULL),(3,NULL),(4,NULL)"); @@ -196,6 +194,7 @@ if (Database::exec("INSERT INTO `role` (roleid, rolename, builtin, roledescripti (2,'locations.*'), (2,'minilinux.*'), (2,'news.*'), + (4,'passthrough.*'), (2,'permissionmanager.locations.view'), (2,'permissionmanager.roles.view'), (2,'permissionmanager.users.view'), diff --git a/modules-available/systemstatus/hooks/main-warning.inc.php b/modules-available/systemstatus/hooks/main-warning.inc.php index 5707c7d2..02b017e8 100644 --- a/modules-available/systemstatus/hooks/main-warning.inc.php +++ b/modules-available/systemstatus/hooks/main-warning.inc.php @@ -6,6 +6,12 @@ if (file_exists('/run/reboot-required.pkgs')) { Message::addInfo('systemstatus.update-reboot-required', true, implode(', ', $lines)); } +$aptTs = SystemStatus::getAptLastDbUpdateTime(); +if ($aptTs + 864000 < time()) { + // No update for 10 days + Message::addWarning('systemstatus.apt-db-out-of-date', true, Util::prettyTime($aptTs)); +} + if (SystemStatus::diskStat($systemUsage, $storeUsage, $current, $wanted)) { if ($current === $wanted && isset($storeUsage['freeKb']) && $storeUsage['freeKb'] < 60000000) { // 60GB Message::addWarning('systemstatus.storage-low-vmstore', true, Util::readableFileSize($storeUsage['freeKb'], -1 , 1)); diff --git a/modules-available/systemstatus/inc/systemstatus.inc.php b/modules-available/systemstatus/inc/systemstatus.inc.php index 36b4ef36..85f0410b 100644 --- a/modules-available/systemstatus/inc/systemstatus.inc.php +++ b/modules-available/systemstatus/inc/systemstatus.inc.php @@ -57,4 +57,42 @@ class SystemStatus return true; } + /** + * Get timestamp of the available updates. This is an estimate, the downloaded apt data usually + * preserves the Last-Modified timestamp from the HTTP download or the according data. Note + * that this list gets updated whener any available package changes, so it does not necessarily + * mean that any currently installed package can be updated when the list changes. + */ + public static function getAptLastDbUpdateTime(): int + { + $osRelease = parse_ini_file('/etc/os-release'); + $updateDbTime = 0; + foreach (glob('/var/lib/apt/lists/*_dists_' . ($osRelease['VERSION_CODENAME'] ?? '') . '*_InRelease', GLOB_NOSORT) as $f) { + $b = basename($f); + if (preg_match('/dists_[a-z]+(?:[\-_]updates)?_InRelease$/', $b)) { + $updateDbTime = max($updateDbTime, filemtime($f)); + } + } + return $updateDbTime; + } + + /** + * Get timestamp when the apt database was last attempted to be updated. This does not + * imply that the operation was successful. + */ + public static function getAptLastUpdateAttemptTime(): int + { + return (int)filemtime('/var/lib/apt/lists/partial'); + } + + /** + * Get when the dpkg database was last changed, i.e. when a package was last installed, updated or removed. + * This is an estimate as it just looks at the modification time of relevant files. It is possible these + * files get modified for other reasons. + */ + public static function getDpkgLastPackageChanges(): int + { + return (int)filemtime(file_exists('/var/log/dpkg.log') ? '/var/log/dpkg.log' : '/var/lib/dpkg/status'); + } + } \ 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 0aaefd23..e9a8e736 100644 --- a/modules-available/systemstatus/lang/de/messages.json +++ b/modules-available/systemstatus/lang/de/messages.json @@ -1,4 +1,5 @@ { + "apt-db-out-of-date": "Die Systemupdate-Datenbank ist veraltet ({{0}}). Erw\u00e4gen Sie, nach neuen Updates zu suchen, und diese zu installieren.", "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/de/permissions.json b/modules-available/systemstatus/lang/de/permissions.json index a9be676b..f2dd9a21 100644 --- a/modules-available/systemstatus/lang/de/permissions.json +++ b/modules-available/systemstatus/lang/de/permissions.json @@ -16,6 +16,7 @@ "tab.dnbd3log": "Zugriff auf DNBD3 Log.", "tab.ldadplog": "Zugriff auf LDAP\/AD-Proxy Logs.", "tab.lighttpdlog": "Zugriff auf Webserver-Logs.", + "tab.listupgradable": "Zugriff auf System-Update-\u00dcbersicht.", "tab.netstat": "Zeige Ausgabe von netstat.", "tab.pslist": "Zeige Prozessliste." } \ No newline at end of file diff --git a/modules-available/systemstatus/lang/de/template-tags.json b/modules-available/systemstatus/lang/de/template-tags.json index 34bbb942..08f75a27 100644 --- a/modules-available/systemstatus/lang/de/template-tags.json +++ b/modules-available/systemstatus/lang/de/template-tags.json @@ -19,6 +19,7 @@ "lang_free": "Frei", "lang_goToStoreConf": "Zur VM-Store-Konfiguration wechseln", "lang_kernel": "Kernel", + "lang_lastPackageInstall": "Updates installiert", "lang_lastUpdateCheck": "Letzter Update-Check", "lang_lastestUpdate": "Neuste Updates von", "lang_listOldWarning": "Die Update-Datenbank scheint veraltet. Es wird empfohlen, zun\u00e4chst nach Updates zu suchen.", diff --git a/modules-available/systemstatus/lang/en/messages.json b/modules-available/systemstatus/lang/en/messages.json index dc9d3dd0..d708838a 100644 --- a/modules-available/systemstatus/lang/en/messages.json +++ b/modules-available/systemstatus/lang/en/messages.json @@ -1,4 +1,5 @@ { + "apt-db-out-of-date": "The system update database is out of date ({{0}}). Consider checking for new updates and installing them.", "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/lang/en/module.json b/modules-available/systemstatus/lang/en/module.json index ad3bbfef..cc2b5283 100644 --- a/modules-available/systemstatus/lang/en/module.json +++ b/modules-available/systemstatus/lang/en/module.json @@ -5,7 +5,7 @@ "tab_Dnbd3Log": "DNBD3 server log", "tab_LdadpLog": "LDAP\/AD", "tab_LighttpdLog": "lighttpd log", - "tab_ListUpgradable": "System Updates", + "tab_ListUpgradable": "System updates", "tab_Netstat": "netstat -tulpn", "tab_PsList": "ps auxf" } \ No newline at end of file diff --git a/modules-available/systemstatus/lang/en/permissions.json b/modules-available/systemstatus/lang/en/permissions.json index 1347dbf7..21e7538f 100644 --- a/modules-available/systemstatus/lang/en/permissions.json +++ b/modules-available/systemstatus/lang/en/permissions.json @@ -16,6 +16,7 @@ "tab.dnbd3log": "Show DNBD3 log.", "tab.ldadplog": "Show LDAP\/AD proxy logs.", "tab.lighttpdlog": "Show web server logs.", + "tab.listupgradable": "Show system update status.", "tab.netstat": "Show output of netstat.", "tab.pslist": "Show process list." } \ No newline at end of file diff --git a/modules-available/systemstatus/lang/en/template-tags.json b/modules-available/systemstatus/lang/en/template-tags.json index 9f14d4d6..3ae392d4 100644 --- a/modules-available/systemstatus/lang/en/template-tags.json +++ b/modules-available/systemstatus/lang/en/template-tags.json @@ -19,6 +19,7 @@ "lang_free": "Free", "lang_goToStoreConf": "Go to VM store configuration", "lang_kernel": "Kernel", + "lang_lastPackageInstall": "Updates installed", "lang_lastUpdateCheck": "Last update check", "lang_lastestUpdate": "Latest updates from", "lang_listOldWarning": "The package database is out of date. Consider checking for updates before updating.", diff --git a/modules-available/systemstatus/page.inc.php b/modules-available/systemstatus/page.inc.php index 302e150d..34dbcc84 100644 --- a/modules-available/systemstatus/page.inc.php +++ b/modules-available/systemstatus/page.inc.php @@ -123,7 +123,7 @@ class Page_SystemStatus extends Page protected function ajaxListUpgradable() { - User::assertPermission("apt.*"); + User::assertPermission("tab.listupgradable"); if (User::hasPermission('apt.update') && Taskmanager::isRunning(Taskmanager::status(self::TM_UPDATE_UUID))) { @@ -137,15 +137,9 @@ class Page_SystemStatus extends Page $task = Taskmanager::submit('AptGetUpgradable'); // Estimate last time package list was updated - $osRelease = parse_ini_file('/etc/os-release'); - $lastDownload = filemtime('/var/lib/apt/lists/partial'); - $lastChanged = 0; - foreach (glob('/var/lib/apt/lists/*_dists_' . ($osRelease['VERSION_CODENAME'] ?? '') . '*_InRelease', GLOB_NOSORT) as $f) { - $b = basename($f); - if (preg_match('/dists_[a-z]+(?:[\-_]updates)?_InRelease$/', $b)) { - $lastChanged = max($lastChanged, filemtime($f)); - } - } + $lastPackageInstalled = SystemStatus::getDpkgLastPackageChanges(); + $lastListDownloadAttempt = SystemStatus::getAptLastUpdateAttemptTime(); + $updateDbTime = SystemStatus::getAptLastDbUpdateTime(); $perms = []; Permission::addGlobalTags($perms, 0, ['apt.update', 'apt.upgrade', 'apt.autoremove', 'apt.fix']); @@ -160,14 +154,17 @@ class Page_SystemStatus extends Page if (!Taskmanager::isFailed($task) && empty($task['data']['packages'])) { $task['data']['error'] = ''; } + } else { + $task['data']['error'] = 'ECONNREFUSED'; } echo Render::parse('sys-update-main', [ 'task' => $task['data'], - 'lastDownload' => Util::prettyTime($lastDownload), - 'lastChanged' => Util::prettyTime($lastChanged), + 'lastDownload' => Util::prettyTime($lastListDownloadAttempt), + 'lastChanged' => Util::prettyTime($updateDbTime), + 'lastInstalled' => Util::prettyTime($lastPackageInstalled), 'perm' => $perms, - 'list_old' => $lastDownload + 86400 < time(), + 'list_old' => $lastListDownloadAttempt + 86400 < time(), ]); } diff --git a/modules-available/systemstatus/permissions/permissions.json b/modules-available/systemstatus/permissions/permissions.json index 9265a8eb..0be0a8c5 100644 --- a/modules-available/systemstatus/permissions/permissions.json +++ b/modules-available/systemstatus/permissions/permissions.json @@ -20,6 +20,9 @@ "tab.lighttpdlog": { "location-aware": false }, + "tab.listupgradable": { + "location-aware": false + }, "show.overview.addresses": { "location-aware": false }, diff --git a/modules-available/systemstatus/templates/sys-update-main.html b/modules-available/systemstatus/templates/sys-update-main.html index 0dac76c8..f597f5ae 100644 --- a/modules-available/systemstatus/templates/sys-update-main.html +++ b/modules-available/systemstatus/templates/sys-update-main.html @@ -45,13 +45,17 @@ + + + + - - + +
{{lang_lastestUpdate}}: {{lastChanged}}
{{lang_lastUpdateCheck}}:  {{lastDownload}}
{{lang_lastestUpdate}}: {{lastChanged}}{{lang_lastPackageInstall}}: {{lastInstalled}}
{{#list_old}} @@ -83,10 +87,12 @@ {{/task.packages.0}} {{^task.packages}} -
- - {{lang_everythingUpToDate}} -
+ {{^task.error}} +
+ + {{lang_everythingUpToDate}} +
+ {{/task.error}} {{/task.packages}} {{#task.error}} -- cgit v1.2.3-55-g7522