diff options
author | Simon Rettberg | 2023-07-03 18:13:40 +0200 |
---|---|---|
committer | Simon Rettberg | 2023-07-03 18:13:40 +0200 |
commit | 6c61723146e272f8ce10d880d0d991767fdc82e8 (patch) | |
tree | 969fafe8760ae872da99ad5372b156f673612e61 /modules-available/systemstatus | |
parent | [remoteaccess] Make sure we get the right client when updating pw (diff) | |
download | slx-admin-6c61723146e272f8ce10d880d0d991767fdc82e8.tar.gz slx-admin-6c61723146e272f8ce10d880d0d991767fdc82e8.tar.xz slx-admin-6c61723146e272f8ce10d880d0d991767fdc82e8.zip |
[systemstatus] Add page to update/upgrade the server OS
Some simple UI/buttons to run apt-get update, upgrade etc.
Diffstat (limited to 'modules-available/systemstatus')
10 files changed, 278 insertions, 4 deletions
diff --git a/modules-available/systemstatus/lang/de/module.json b/modules-available/systemstatus/lang/de/module.json index 22be8a1d..3b310b1d 100644 --- a/modules-available/systemstatus/lang/de/module.json +++ b/modules-available/systemstatus/lang/de/module.json @@ -5,6 +5,7 @@ "tab_Dnbd3Log": "DNBD3 Server Log", "tab_LdadpLog": "LDAP\/AD", "tab_LighttpdLog": "lighttpd Log", + "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/de/permissions.json b/modules-available/systemstatus/lang/de/permissions.json index 9e7c5be9..a9be676b 100644 --- a/modules-available/systemstatus/lang/de/permissions.json +++ b/modules-available/systemstatus/lang/de/permissions.json @@ -1,4 +1,8 @@ { + "apt.autoremove": "Nicht mehr ben\u00f6tigte Pakete deinstallieren.", + "apt.fix": "Installalations- und Abh\u00e4ngigkeitsprobleme beheben lassen.", + "apt.update": "Das System updaten.", + "apt.upgrade": "Das System mittels \"full-upgrade\" updaten.", "restart.dmsd": "bwLehrpool-Suite neustarten.", "restart.dnbd3-server": "DNBD3-Server neustarten.", "restart.ldadp": "LDADP neustarten.", diff --git a/modules-available/systemstatus/lang/de/template-tags.json b/modules-available/systemstatus/lang/de/template-tags.json index d9be820c..34bbb942 100644 --- a/modules-available/systemstatus/lang/de/template-tags.json +++ b/modules-available/systemstatus/lang/de/template-tags.json @@ -1,19 +1,27 @@ { "lang_OK": "OK", "lang_addressConfiguration": "Adresskonfiguration", + "lang_aptOutput": "apt-get Ausgabe", "lang_areYouSureReboot": "Server jetzt neustarten?", "lang_attention": "Achtung!", "lang_average": "Durchschnitt", + "lang_backToPackagelist": "Zur\u00fcck zur Update-\u00dcbersicht", "lang_capacity": "Kapazit\u00e4t", + "lang_checkForUpdates": "Auf neue Updates pr\u00fcfen", "lang_confirmRestart": "Diesen Dienst wirklich neustarten? Dies kann Auswirkungen auf den Betrieb haben.", "lang_cpuLoad": "CPU-Last", "lang_distribution": "Distribution", "lang_dmsdUnreachable": "dmsd nicht erreichbar", + "lang_everythingUpToDate": "Das System ist auf dem aktuellen Stand", "lang_failure": "Fehler", + "lang_fixDependencies": "Installationsprobleme beheben", "lang_foundStore": "Vorgefunden:", "lang_free": "Frei", "lang_goToStoreConf": "Zur VM-Store-Konfiguration wechseln", "lang_kernel": "Kernel", + "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.", "lang_logicCPUs": "Logische CPUs", "lang_maintenance": "Maintenance", "lang_moduleHeading": "System-Status", @@ -21,12 +29,17 @@ "lang_occupied": "Belegt", "lang_onlyOS": "Nur OS", "lang_overview": "\u00dcbersicht", + "lang_package": "Paket", "lang_ramUsage": "RAM-Nutzung", + "lang_removeUnusedPackages": "Nicht mehr ben\u00f6tigte Pakete entfernen", "lang_restart": "Neustarten", + "lang_runFullUpdate": "\"Full-Upgrade\" durchf\u00fchren", + "lang_runUpdate": "Update durchf\u00fchren", "lang_runningDownloads": "Aktive Downloads", "lang_runningUploads": "Aktive Uploads", "lang_serverReboot": "Server neustarten", "lang_services": "Dienste", + "lang_showPackageList": "Zur Update- und Paket-\u00dcbersicht", "lang_space": "Speicherplatz", "lang_storeMissingExpected": "VM-Store nicht eingebunden. Erwartet:", "lang_storeNotConfigured": "Kein VM-Store konfiguriert!", @@ -37,7 +50,9 @@ "lang_systemStoreError": "Fehler beim Ermitteln des verf\u00fcgbaren Systemspeichers", "lang_total": "Gesamt", "lang_updatedPackages": "Ausstehende Updates", + "lang_updatesWikiLink": "Mehr Informationen zu Updates im bwLehrpool-Wiki", "lang_uptimeOS": "OS Uptime", + "lang_versionFromTo": "Update-Details", "lang_vmStore": "VM-Speicher", "lang_vmStoreError": "Fehler beim Ermitteln des verf\u00fcgbaren Speicherplatzes am VM-Speicherort. Bitte \u00fcberpr\u00fcfen Sie die Konfiguration." }
\ No newline at end of file diff --git a/modules-available/systemstatus/lang/en/module.json b/modules-available/systemstatus/lang/en/module.json index f5fec515..ad3bbfef 100644 --- a/modules-available/systemstatus/lang/en/module.json +++ b/modules-available/systemstatus/lang/en/module.json @@ -5,6 +5,7 @@ "tab_Dnbd3Log": "DNBD3 server log", "tab_LdadpLog": "LDAP\/AD", "tab_LighttpdLog": "lighttpd log", + "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 d510e257..1347dbf7 100644 --- a/modules-available/systemstatus/lang/en/permissions.json +++ b/modules-available/systemstatus/lang/en/permissions.json @@ -1,4 +1,8 @@ { + "apt.autoremove": "Remove packages that are no longer required.", + "apt.fix": "Try to fix installation and dependency problems.", + "apt.update": "Update system.", + "apt.upgrade": "Update system via \"full-upgrade\".", "restart.dmsd": "Restart bwLehrpool-Suite.", "restart.dnbd3-server": "Restart DNBD3 server.", "restart.ldadp": "Restart LDADP.", diff --git a/modules-available/systemstatus/lang/en/template-tags.json b/modules-available/systemstatus/lang/en/template-tags.json index 330aa1b2..9f14d4d6 100644 --- a/modules-available/systemstatus/lang/en/template-tags.json +++ b/modules-available/systemstatus/lang/en/template-tags.json @@ -1,19 +1,27 @@ { "lang_OK": "OK", "lang_addressConfiguration": "Address Configuration", + "lang_aptOutput": "apt-get output", "lang_areYouSureReboot": "Reboot server now?", "lang_attention": "Attention!", "lang_average": "Average", + "lang_backToPackagelist": "Back up update page", "lang_capacity": "Capacity", + "lang_checkForUpdates": "Check for updates", "lang_confirmRestart": "Are you sure you want to restart this service? This can lead to interruptions.", "lang_cpuLoad": "CPU Load", "lang_distribution": "Distribution", "lang_dmsdUnreachable": "dmsd not reachable", + "lang_everythingUpToDate": "Everything is up to date", "lang_failure": "Failure", + "lang_fixDependencies": "Fix installation\/dependency problems", "lang_foundStore": "Found:", "lang_free": "Free", "lang_goToStoreConf": "Go to VM store configuration", "lang_kernel": "Kernel", + "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.", "lang_logicCPUs": "Logical CPUs", "lang_maintenance": "Maintenance", "lang_moduleHeading": "System Status", @@ -21,12 +29,17 @@ "lang_occupied": "In use", "lang_onlyOS": "OS only", "lang_overview": "Overview", + "lang_package": "Package", "lang_ramUsage": "RAM usage", + "lang_removeUnusedPackages": "Remove unused packages", "lang_restart": "Restart", + "lang_runFullUpdate": "Run \"full-upgrade\"", + "lang_runUpdate": "Run update", "lang_runningDownloads": "Running downloads", "lang_runningUploads": "Running uploads", "lang_serverReboot": "Reboot Server", "lang_services": "Services", + "lang_showPackageList": "Show updates and packages", "lang_space": "Space", "lang_storeMissingExpected": "VM store not mounted. Expected:", "lang_storeNotConfigured": "No VM store configured!", @@ -37,7 +50,9 @@ "lang_systemStoreError": "Error querying available system storage", "lang_total": "Total", "lang_updatedPackages": "Pending updates", + "lang_updatesWikiLink": "See bwLehrpool Wiki for more information regarding updates", "lang_uptimeOS": "OS uptime", + "lang_versionFromTo": "Update details", "lang_vmStore": "VM store", "lang_vmStoreError": "Error determining available space of the VM storage. Please check the configuration." }
\ No newline at end of file diff --git a/modules-available/systemstatus/page.inc.php b/modules-available/systemstatus/page.inc.php index c25120f0..302e150d 100644 --- a/modules-available/systemstatus/page.inc.php +++ b/modules-available/systemstatus/page.inc.php @@ -3,6 +3,8 @@ class Page_SystemStatus extends Page { + const TM_UPDATE_UUID = '345-45763457-24356-234324556'; + protected function doPreprocess() { User::load(); @@ -13,14 +15,46 @@ class Page_SystemStatus extends Page } $action = Request::post('action', false, 'string'); - if ($action === 'reboot') { + $aptAction = null; + switch ($action) { + case 'reboot': User::assertPermission("serverreboot"); $task = Taskmanager::submit('Reboot'); if (Taskmanager::isTask($task)) { Util::redirect('?do=systemstatus&taskid=' . $task['id']); } - } elseif ($action === 'service-start' || $action === 'service-restart') { + break; + case 'service-start': + case 'service-restart': $this->handleServiceAction(substr($action, 8)); + break; + case 'apt-update': + User::assertPermission('apt.update'); + $aptAction = 'UPDATE'; + break; + case 'apt-upgrade': + User::assertPermission('apt.upgrade'); + $aptAction = 'UPGRADE'; + break; + case 'apt-full-upgrade': + User::assertPermission('apt.upgrade'); + $aptAction = 'FULL_UPGRADE'; + break; + case 'apt-autoremove': + User::assertPermission('apt.autoremove'); + $aptAction = 'AUTOREMOVE'; + break; + case 'apt-fix': + User::assertPermission('apt.fix'); + $aptAction = 'FIX'; + break; + } + if ($aptAction !== null) { + if (!Taskmanager::isRunning(Taskmanager::status(self::TM_UPDATE_UUID))) { + $task = Taskmanager::submit('AptUpgrade', ['mode' => $aptAction, 'id' => self::TM_UPDATE_UUID]); + Taskmanager::release($task); + } + Util::redirect('?do=systemstatus#id-ListUpgradable_pane'); } if (Request::isPost()) { Util::redirect('?do=systemstatus'); @@ -50,10 +84,11 @@ class Page_SystemStatus extends Page $data = array(); $data['taskid'] = Request::get('taskid', '', 'string'); $data['taskname'] = Request::get('taskname', 'Reboot', 'string'); - $tabs = array('DmsdLog', 'Netstat', 'PsList', 'LdadpLog', 'LighttpdLog', 'Dnbd3Log'); + $tabs = ['DmsdLog', 'Netstat', 'PsList', 'LdadpLog', 'LighttpdLog', 'Dnbd3Log', 'ListUpgradable']; $data['tabs'] = array(); // Dictionary::translate('tab_DmsdLog') Dictionary::translate('tab_LdadpLog') Dictionary::translate('tab_Netstat') // Dictionary::translate('tab_LighttpdLog') Dictionary::translate('tab_PsList') Dictionary::translate('tab_Dnbd3Log') + // Dictionary::translate('tab_ListUpgradable') foreach ($tabs as $tab) { $data['tabs'][] = array( 'type' => $tab, @@ -86,6 +121,56 @@ class Page_SystemStatus extends Page } } + protected function ajaxListUpgradable() + { + User::assertPermission("apt.*"); + + if (User::hasPermission('apt.update') + && Taskmanager::isRunning(Taskmanager::status(self::TM_UPDATE_UUID))) { + echo Render::parse('sys-update-update', [ + 'taskid' => self::TM_UPDATE_UUID, + 'rnd' => mt_rand(), + ]); + return; + } + + $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)); + } + } + + $perms = []; + Permission::addGlobalTags($perms, 0, ['apt.update', 'apt.upgrade', 'apt.autoremove', 'apt.fix']); + + if ($task !== false) { + $task = Taskmanager::waitComplete($task, 30000); + + if (Taskmanager::isFailed($task) || !Taskmanager::isFinished($task)) { + Taskmanager::addErrorMessage($task); + return; + } + if (!Taskmanager::isFailed($task) && empty($task['data']['packages'])) { + $task['data']['error'] = ''; + } + } + + echo Render::parse('sys-update-main', [ + 'task' => $task['data'], + 'lastDownload' => Util::prettyTime($lastDownload), + 'lastChanged' => Util::prettyTime($lastChanged), + 'perm' => $perms, + 'list_old' => $lastDownload + 86400 < time(), + ]); + } + protected function ajaxDiskStat() { User::assertPermission("show.overview.diskstat"); @@ -112,7 +197,7 @@ class Page_SystemStatus extends Page return; $task = Taskmanager::waitComplete($task, 3000); - if (!isset($task['data']['addresses']) || empty($task['data']['addresses'])) { + if (empty($task['data']['addresses'])) { Taskmanager::addErrorMessage($task); return; } diff --git a/modules-available/systemstatus/permissions/permissions.json b/modules-available/systemstatus/permissions/permissions.json index a116fd56..9265a8eb 100644 --- a/modules-available/systemstatus/permissions/permissions.json +++ b/modules-available/systemstatus/permissions/permissions.json @@ -43,5 +43,17 @@ }, "restart.dmsd": { "location-aware": false + }, + "apt.update": { + "location-aware": false + }, + "apt.upgrade": { + "location-aware": false + }, + "apt.autoremove": { + "location-aware": false + }, + "apt.fix": { + "location-aware": false } }
\ No newline at end of file diff --git a/modules-available/systemstatus/templates/sys-update-main.html b/modules-available/systemstatus/templates/sys-update-main.html new file mode 100644 index 00000000..0dac76c8 --- /dev/null +++ b/modules-available/systemstatus/templates/sys-update-main.html @@ -0,0 +1,102 @@ +<div class="panel panel-default"> + <div class="panel-body"> + <div class="pull-right"> + <form action="?do=systemstatus" method="post"> + <input type="hidden" name="token" value="{{token}}"> + <div> + <button type="submit" class="btn btn-success" name="action" + value="apt-update" {{perm.apt.update.disabled}}> + <span class="glyphicon glyphicon-refresh"></span> + {{lang_checkForUpdates}} + </button> + </div> + <div class="slx-smallspace"></div> + <div class="btn-group dropdown"> + <button type="submit" class="btn btn-primary" name="action" + value="apt-upgrade" {{perm.apt.upgrade.disabled}}> + <span class="glyphicon glyphicon-play"></span> + {{lang_runUpdate}} + </button> + <button type="button" class="btn btn-primary dropdown-toggle" + data-toggle="dropdown" aria-haspopup="true"> + <span class="caret"></span> + <span class="sr-only">Toggle Dropdown</span> + </button> + <div class="dropdown-menu" style="padding:0"> + <div class="btn-group-vertical"> + <button type="submit" name="action" value="apt-full-upgrade" class="btn btn-primary" + style="text-align: left !important" {{perm.apt.upgrade.disabled}}> + <span class="glyphicon glyphicon-play"></span> + {{lang_runFullUpdate}} + </button> + <button type="submit" name="action" value="apt-autoremove" class="btn btn-primary" + style="text-align: left !important" {{perm.apt.autoremove.disabled}}> + <span class="glyphicon glyphicon-trash"></span> + {{lang_removeUnusedPackages}} + </button> + <button type="submit" name="action" value="apt-fix" class="btn btn-primary" + style="text-align: left !important" {{perm.apt.fix.disabled}}> + <span class="glyphicon glyphicon-wrench"></span> + {{lang_fixDependencies}} + </button> + </div> + </div> + </div> + </form> + </div> + <table> + <tr> + <td>{{lang_lastUpdateCheck}}: </td> + <td>{{lastDownload}}</td> + </tr> + <tr> + <td>{{lang_lastestUpdate}}: </td> + <td>{{lastChanged}}</td> + <tr> + </table> + {{#list_old}} + <div class="slx-smallspace"></div> + <div class="text-danger"> + {{lang_listOldWarning}} + </div> + {{/list_old}} + </div> +</div> + +{{#task.packages.0}} + <table class="table table-condensed"> + <thead> + <tr> + <th>{{lang_package}}</th> + <th colspan="3">{{lang_versionFromTo}}</th> + </tr> + </thead> + {{#task.packages}} + <tr> + <td><strong>{{name}}</strong><span class="text-muted">/{{source}}</span></td> + <td class="slx-smallcol">{{oldVersion}}</td> + <td class="slx-smallcol">→</td> + <td class="slx-smallcol">{{newVersion}}</td> + </tr> + {{/task.packages}} + </table> +{{/task.packages.0}} + +{{^task.packages}} + <div class="alert alert-success"> + <span class="glyphicon glyphicon-check"></span> + {{lang_everythingUpToDate}} + </div> +{{/task.packages}} + +{{#task.error}} + <div class="alert alert-warning">{{task.error}}</div> +{{/task.error}} + +<div class="pull-right"> + <a href="https://www.bwlehrpool.de/wiki/doku.php/satellite/system_updates" target="_blank"> + {{lang_updatesWikiLink}} + <span class="glyphicon glyphicon-new-window"></span> + </a> +</div> +<div class="clearfix"></div>
\ No newline at end of file diff --git a/modules-available/systemstatus/templates/sys-update-update.html b/modules-available/systemstatus/templates/sys-update-update.html new file mode 100644 index 00000000..7be4e648 --- /dev/null +++ b/modules-available/systemstatus/templates/sys-update-update.html @@ -0,0 +1,35 @@ +<div id="apt-output" data-tm-id="{{taskid}}" data-tm-log="output" + data-tm-callback="aptUpdate">{{lang_aptOutput}}</div> + +<div class="buttonbar pull-right" id="btn-bar"> + <a id="fail-button" href="?do=systemstatus&rnd={{rnd}}#id-ListUpgradable_pane" class="btn btn-warning collapse"> + <span class="glyphicon glyphicon-arrow-left"></span> + {{lang_backToPackagelist}} + </a> + <a id="success-button" href="?do=systemstatus&rnd={{rnd}}#id-ListUpgradable_pane" class="btn btn-success + collapse"> + <span class="glyphicon glyphicon-arrow-right"></span> + {{lang_showPackageList}} + </a> +</div> +<div class="clearfix"></div> + +<script> + function aptUpdate(task) { + if (task.statusCode === 'TASK_ERROR') { + if (task.data && task.data.error) { + $('#apt-output').append($('<pre class="text-danger slx-bold">').text(task.data.error)); + } + $('#fail-button').show(); + } + if (task.statusCode === 'TASK_FINISHED') { + $('#success-button').show(); + } + } + + tmInit(); + $('#btn-bar a').click(function () { + window.location.reload(); + return false; + }); +</script>
\ No newline at end of file |