From d2f6f0b3f88713e988590d833b2738edd6a4bbf1 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 7 Feb 2024 15:03:22 +0100 Subject: [minilinux] Introduce new "installed" state: broken Avoid marking broken (i.e. missing/corrupted files) versions as "not installed", which could in turn lead to complete deletions of versions from the database without removing the according (broken) files from the filesystem. Instead, properly mark them as broken in the DB so we keep them but can handle them differently (UI: to be done). --- .../minilinux/inc/linuxbootentryhook.inc.php | 14 +++++----- modules-available/minilinux/inc/minilinux.inc.php | 30 ++++++++++++++-------- modules-available/minilinux/page.inc.php | 19 +++++++------- 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/modules-available/minilinux/inc/linuxbootentryhook.inc.php b/modules-available/minilinux/inc/linuxbootentryhook.inc.php index 56b3db69..1424b6b9 100644 --- a/modules-available/minilinux/inc/linuxbootentryhook.inc.php +++ b/modules-available/minilinux/inc/linuxbootentryhook.inc.php @@ -60,7 +60,7 @@ class LinuxBootEntryHook extends BootEntryHook true), ]; foreach ($versions[$branch['branchid']] as $version) { - $valid = $version['installed'] != 0; + $valid = $version['installed'] != MiniLinux::INSTALL_MISSING; $title = $version['versionid'] . ' ' . $version['title']; if (!$valid) { $title .= ' ' . Dictionary::translateFileModule('minilinux', 'module', @@ -89,14 +89,12 @@ class LinuxBootEntryHook extends BootEntryHook ['id' => $effectiveId]); if ($res === false) { // Maybe this is a branchid, which means latest from according branch (installed only) - $res = Database::queryFirst('SELECT versionid, installed, data FROM minilinux_version WHERE branchid = :id - ORDER BY installed DESC, dateline DESC LIMIT 1', // Order by installed instead of WHERE for better errormsg - ['id' => $effectiveId]); + $res = Database::queryFirst('SELECT versionid, installed, data FROM minilinux_version + WHERE branchid = :id AND installed = :ok + ORDER BY dateline DESC LIMIT 1', + ['id' => $effectiveId, 'ok' => MiniLinux::INSTALL_OK]); } if ($res === false) { - return BootEntry::newCustomBootEntry(['script' => 'prompt Invalid minilinux boot entry id: ' . $id]); - } - if ($res['installed'] == 0) { return BootEntry::newCustomBootEntry(['script' => 'prompt Selected version not currently installed on server: ' . $effectiveId]); } $effectiveId = $res['versionid']; // In case we selected from a branchid, so above message doesn't show versionid @@ -187,7 +185,7 @@ class LinuxBootEntryHook extends BootEntryHook if ($id === 'default') return true; // Meta-version that links to whatever the default is set to $res = Database::queryFirst('SELECT installed FROM minilinux_version WHERE versionid = :id', ['id' => $id]); - if ($res !== false && $res['installed']) + if ($res !== false && $res['installed'] != MiniLinux::INSTALL_MISSING) return true; $res = Database::queryFirst('SELECT branchid FROM minilinux_branch WHERE branchid = :id', ['id' => $id]); return $res !== false; diff --git a/modules-available/minilinux/inc/minilinux.inc.php b/modules-available/minilinux/inc/minilinux.inc.php index 88c50995..cbc797f2 100644 --- a/modules-available/minilinux/inc/minilinux.inc.php +++ b/modules-available/minilinux/inc/minilinux.inc.php @@ -11,6 +11,12 @@ class MiniLinux const INVALID = 'invalid'; + const INSTALL_MISSING = 0; + + const INSTALL_OK = 1; + + const INSTALL_BROKEN = 2; + /* * Update of available versions by querying sources */ @@ -73,7 +79,8 @@ class MiniLinux WHERE sourceid = :sourceid AND taskid = :taskid", ['sourceid' => $sourceid, 'taskid' => $taskId]); // Clean up -- delete orphaned versions that are not installed - Database::exec('DELETE FROM minilinux_version WHERE orphan > 4 AND installed = 0'); + Database::exec('DELETE FROM minilinux_version WHERE orphan > 4 AND installed = :missing', + ['missing' => self::INSTALL_MISSING]); // FKC makes sure we only delete orphaned ones Database::exec('DELETE IGNORE FROM minilinux_branch WHERE 1', [], true); } @@ -336,7 +343,7 @@ class MiniLinux } elseif ($slashes === 1) { // Latest from branch $ver = Database::queryFirst('SELECT versionid, installed FROM minilinux_version - WHERE branchid = :branchid AND installed = 1 ORDER BY dateline DESC', ['branchid' => $default]); + WHERE branchid = :branchid AND installed = :ok ORDER BY dateline DESC', ['branchid' => $default, 'ok' => self::INSTALL_OK]); } else { // Unknown return false; @@ -347,22 +354,23 @@ class MiniLinux return false; } Property::set(self::PROPERTY_DEFAULT_BOOT_EFFECTIVE, $ver['versionid']); - return $ver['installed'] != 0; + return $ver['installed'] != self::INSTALL_MISSING; } public static function linuxDownloadCallback($task, $versionid) { - self::setInstalledState($versionid, $task['statusCode'] === 'TASK_FINISHED'); + self::setInstalledState($versionid, $task['statusCode'] === 'TASK_FINISHED' ? self::INSTALL_OK : self::INSTALL_BROKEN); } - public static function setInstalledState($versionid, bool $installed): void + public static function setInstalledState($versionid, int $installed): void { Database::exec('UPDATE minilinux_version SET installed = :installed WHERE versionid = :versionid', [ 'versionid' => $versionid, - 'installed' => (int)$installed, + 'installed' => $installed, ]); - if ($installed) { - $res = Database::queryFirst('SELECT Count(*) AS cnt FROM minilinux_version WHERE installed <> 0'); + if ($installed === self::INSTALL_OK) { + $res = Database::queryFirst('SELECT Count(*) AS cnt FROM minilinux_version WHERE installed = :ok', + ['ok' => self::INSTALL_OK]); if ($res['cnt'] == 1) { self::setDefaultVersion($versionid); } @@ -550,9 +558,9 @@ class MiniLinux } if (substr_count($id, '/') < 2) { // Maybe this is a branchid, which means latest from according branch (installed only) - $res = Database::queryFirst('SELECT versionid FROM minilinux_version WHERE branchid = :id AND installed = 1 + $res = Database::queryFirst('SELECT versionid FROM minilinux_version WHERE branchid = :id AND installed = :ok ORDER BY dateline DESC LIMIT 1', - ['id' => $id]); + ['id' => $id, 'ok' => self::INSTALL_OK]); if ($res !== false) { $id = $res['versionid']; } @@ -560,4 +568,4 @@ class MiniLinux return $id; } -} \ No newline at end of file +} diff --git a/modules-available/minilinux/page.inc.php b/modules-available/minilinux/page.inc.php index 349bbfad..8004f1ab 100644 --- a/modules-available/minilinux/page.inc.php +++ b/modules-available/minilinux/page.inc.php @@ -113,14 +113,14 @@ class Page_MiniLinux extends Page //$eff = Property::get(MiniLinux::PROPERTY_DEFAULT_BOOT_EFFECTIVE); foreach ($versions as &$version) { $version['dateline_s'] = Util::prettyTime($version['dateline']); - $version['orphan'] = ($version['orphan'] > 0 && !$version['installed']) || ($version['orphan'] > 1); + $version['orphan'] = ($version['orphan'] > 0 && $version['installed'] == MiniLinux::INSTALL_MISSING) || ($version['orphan'] > 1); $version['downloading'] = $version['taskid'] && Taskmanager::isRunning(Taskmanager::status($version['taskid'])); - if ($version['installed'] && $version['versionid'] !== $def) { + if ($version['installed'] != MiniLinux::INSTALL_MISSING && $version['versionid'] !== $def) { $version['showsetdefault'] = true; } if ($version['versionid'] === $def) { $version['isdefault'] = true; - if (!$version['installed']) { + if (!$version['installed'] != MiniLinux::INSTALL_OK) { $version['default_class'] = 'bg-danger'; } } @@ -184,14 +184,14 @@ class Page_MiniLinux extends Page array_multisort($sort, SORT_ASC, $data['files']); if (!$valid) { $data['verify_button'] = false; - if ($ver['installed']) { - MiniLinux::setInstalledState($versionid, false); + if ($ver['installed'] != MiniLinux::INSTALL_MISSING) { + MiniLinux::setInstalledState($versionid, MiniLinux::INSTALL_BROKEN); } - } elseif (!$ver['installed'] && $verify) { - MiniLinux::setInstalledState($versionid, true); + } elseif ($ver['installed'] != MiniLinux::INSTALL_OK && $verify) { + MiniLinux::setInstalledState($versionid, MiniLinux::INSTALL_OK); } } - if ($data['dltask'] !== null || $ver['installed']) { + if ($data['dltask'] !== null || $ver['installed'] != MiniLinux::INSTALL_MISSING) { MiniLinux::checkStage4($data, $data['s4_errors']); } $data['changelog'] = Util::markup($ver['description'] ?? ''); @@ -274,7 +274,6 @@ class Page_MiniLinux extends Page Message::addError('no-such-version'); return; } - MiniLinux::setInstalledState($version['versionid'], false); $path = CONFIG_HTTP_DIR . '/' . $version['versionid']; $task = Taskmanager::submit('DeleteDirectory', [ 'path' => $path, @@ -283,8 +282,10 @@ class Page_MiniLinux extends Page if ($task !== false) { $task = Taskmanager::waitComplete($task, 2500); if (Taskmanager::isFailed($task)) { + MiniLinux::setInstalledState($version['versionid'], MiniLinux::INSTALL_BROKEN); Message::addError('delete-error', $versionid, $task['data']['error']); } else { + MiniLinux::setInstalledState($version['versionid'], MiniLinux::INSTALL_MISSING); Message::addSuccess('version-deleted', $versionid); } } -- cgit v1.2.3-55-g7522