From 51bbba6aa818333f81c8d55d99e7b0071888abba Mon Sep 17 00:00:00 2001 From: Ludovic <54670129+lbr38@users.noreply.github.com> Date: Mon, 10 Feb 2025 15:25:50 +0100 Subject: [PATCH] 4.17.0 --- www/controllers/App/Config/Settings.php | 16 +++++ .../Container/vars/tasks/log.vars.inc.php | 11 ++- .../Table/vars/tasks/list-queued.vars.inc.php | 30 ++++++++ www/controllers/Repo/Package.php | 52 +++++++------- www/controllers/Service/File.php | 4 +- www/controllers/Service/ScheduledTask.php | 5 ++ www/controllers/Settings.php | 12 ++++ www/controllers/Task/Task.php | 41 ++++++++--- www/controllers/ajax/settings.php | 11 ++- www/models/Connection.php | 6 ++ www/models/Task/Task.php | 71 ++++++++++++++++--- .../resources/js/events/task/actions.js | 6 +- www/public/resources/js/functions.js | 3 + www/public/resources/js/functions/task.js | 2 +- www/tasks/execute.php | 70 ++++++++++++++++-- www/update/database/4.17.0.php | 18 +++++ www/update/database/ci/deb/delete.php | 2 +- www/update/database/ci/deb/duplicate.php | 2 +- www/update/database/ci/deb/env.php | 2 +- www/update/database/ci/deb/mirror.php | 2 +- www/update/database/ci/deb/rebuild.php | 2 +- www/update/database/ci/deb/update.php | 2 +- www/update/database/ci/rpm/delete.php | 2 +- www/update/database/ci/rpm/duplicate.php | 2 +- www/update/database/ci/rpm/env.php | 2 +- www/update/database/ci/rpm/mirror.php | 2 +- www/update/database/ci/rpm/rebuild.php | 2 +- www/update/database/ci/rpm/update.php | 2 +- www/version | 2 +- .../containers/settings/health.inc.php | 2 +- .../containers/settings/settings.inc.php | 20 +++++- .../includes/containers/tasks/list.inc.php | 13 ++-- www/views/includes/panels/repos/new.inc.php | 12 ++-- .../includes/tables/tasks/list-done.inc.php | 2 + .../includes/tables/tasks/list-queued.inc.php | 7 ++ .../tables/tasks/list-running.inc.php | 2 + .../tables/tasks/list-scheduled.inc.php | 2 + www/views/includes/tables/tasks/list.inc.php | 59 +++++++-------- 38 files changed, 392 insertions(+), 111 deletions(-) create mode 100644 www/controllers/Layout/Table/vars/tasks/list-queued.vars.inc.php create mode 100644 www/update/database/4.17.0.php create mode 100644 www/views/includes/tables/tasks/list-queued.inc.php diff --git a/www/controllers/App/Config/Settings.php b/www/controllers/App/Config/Settings.php index 4a2aaf4d..aae59db8 100644 --- a/www/controllers/App/Config/Settings.php +++ b/www/controllers/App/Config/Settings.php @@ -101,6 +101,22 @@ public static function get() } } + if (!defined('TASK_QUEUING')) { + if (!empty($settings['TASK_QUEUING'])) { + define('TASK_QUEUING', $settings['TASK_QUEUING']); + } else { + define('TASK_QUEUING', 'false'); + } + } + + if (!defined('TASK_QUEUING_MAX_SIMULTANEOUS')) { + if (!empty($settings['TASK_QUEUING_MAX_SIMULTANEOUS'])) { + define('TASK_QUEUING_MAX_SIMULTANEOUS', $settings['TASK_QUEUING_MAX_SIMULTANEOUS']); + } else { + define('TASK_QUEUING_MAX_SIMULTANEOUS', 2); + } + } + if (!defined('TASK_EXECUTION_MEMORY_LIMIT')) { if (!empty($settings['TASK_EXECUTION_MEMORY_LIMIT'])) { define('TASK_EXECUTION_MEMORY_LIMIT', $settings['TASK_EXECUTION_MEMORY_LIMIT']); diff --git a/www/controllers/Layout/Container/vars/tasks/log.vars.inc.php b/www/controllers/Layout/Container/vars/tasks/log.vars.inc.php index 30e27314..9d58dd14 100644 --- a/www/controllers/Layout/Container/vars/tasks/log.vars.inc.php +++ b/www/controllers/Layout/Container/vars/tasks/log.vars.inc.php @@ -8,6 +8,10 @@ * Get the log file of the task */ try { + /** + * If a task Id is provided in the URL, use it + * Otherwise, get the latest task Id + */ if (!empty(__ACTUAL_URI__[2]) and (is_numeric(__ACTUAL_URI__[2]))) { $taskId = __ACTUAL_URI__[2]; } else { @@ -29,7 +33,12 @@ $taskLogController = new \Controllers\Task\Log\Log($taskId); // Get raw params from the task - $rawParams = json_decode($taskInfo['Raw_params'], true); + try { + $rawParams = json_decode($taskInfo['Raw_params'], true, 512, JSON_THROW_ON_ERROR); + } catch (JsonException $e) { + throw new Exception('Error while reading log: could not get task params from task #' . $taskId . ': ' . $e->getMessage()); + } + $repoId = null; $snapId = null; $envId = null; diff --git a/www/controllers/Layout/Table/vars/tasks/list-queued.vars.inc.php b/www/controllers/Layout/Table/vars/tasks/list-queued.vars.inc.php new file mode 100644 index 00000000..60bc6a53 --- /dev/null +++ b/www/controllers/Layout/Table/vars/tasks/list-queued.vars.inc.php @@ -0,0 +1,30 @@ +listQueued('', true, $reloadableTableOffset); + +/** + * Get list of ALL queued tasks, without offset, for the total count + */ +$reloadableTableTotalItems = count($myTask->listQueued()); + +/** + * Count total pages for the pagination + */ +$reloadableTableTotalPages = ceil($reloadableTableTotalItems / 10); + +/** + * Calculate current page number + */ +$reloadableTableCurrentPage = ceil($reloadableTableOffset / 10) + 1; diff --git a/www/controllers/Repo/Package.php b/www/controllers/Repo/Package.php index b46bbcf3..bfffa8fa 100644 --- a/www/controllers/Repo/Package.php +++ b/www/controllers/Repo/Package.php @@ -288,35 +288,37 @@ public function delete(int $snapId, array $packages) * Check that the file path starts with REPOS_DIR * Prevents a malicious person from providing a path that has nothing to do with the repo directory (e.g. /etc/...) */ - if (preg_match("#^" . REPOS_DIR . "#", $path)) { - /** - * Check that the file ends with .deb or .rpm otherwise we move on to the next one - */ - if (!preg_match("#.deb$#", $path) and !preg_match("#.rpm$#", $path)) { - continue; - } - - /** - * If the file does not exist, we ignore it and move on to the next one - */ - if (!file_exists($path)) { - continue; - } + if (!preg_match("#^" . REPOS_DIR . "#", realpath($path))) { + throw new Exception('Invalid package path ' . $path); + } - /** - * Delete package - */ - if (!unlink($path)) { - throw new Exception('Unable to delete package ' . $path); - } + /** + * Check that the file ends with .deb or .rpm otherwise we move on to the next one + */ + if (!preg_match("#.deb$#", $path) and !preg_match("#.rpm$#", $path)) { + continue; + } - $deletedPackages[] = str_replace($repoPath . '/', '', $path); + /** + * If the file does not exist, we ignore it and move on to the next one + */ + if (!file_exists($path)) { + continue; + } - /** - * Set repo rebuild status to 'needed' - */ - $myrepo->snapSetRebuild($snapId, 'needed'); + /** + * Delete package + */ + if (!unlink($path)) { + throw new Exception('Unable to delete package ' . $path); } + + $deletedPackages[] = str_replace($repoPath . '/', '', $path); + + /** + * Set repo rebuild status to 'needed' + */ + $myrepo->snapSetRebuild($snapId, 'needed'); } return $deletedPackages; diff --git a/www/controllers/Service/File.php b/www/controllers/Service/File.php index f1daf356..0b887308 100644 --- a/www/controllers/Service/File.php +++ b/www/controllers/Service/File.php @@ -23,7 +23,7 @@ public function cleanUp() try { /** - * Clean temp files and directories older than 7 days + * Clean temp files and directories older than 3 days */ if (is_dir(DATA_DIR . '/.temp')) { $files = \Controllers\Common::findRecursive(DATA_DIR . '/.temp'); @@ -31,7 +31,7 @@ public function cleanUp() if (!empty($files)) { foreach ($files as $file) { - if (filemtime($file) < strtotime('-7 days')) { + if (filemtime($file) < strtotime('-3 days')) { if (!unlink($file)) { throw new Exception('Could not clean temporary file ' . $file . ''); } diff --git a/www/controllers/Service/ScheduledTask.php b/www/controllers/Service/ScheduledTask.php index 3bb9bcac..8c364a1b 100644 --- a/www/controllers/Service/ScheduledTask.php +++ b/www/controllers/Service/ScheduledTask.php @@ -146,10 +146,15 @@ public function execute() echo $this->getDate() . ' Launching scheduled task #' . $taskId . '...' . PHP_EOL; try { + // Add the scheduled task to the queue and execute it + $this->taskController->updateStatus($taskId, 'queued'); $this->taskController->executeId($taskId); } catch (Exception $e) { $this->logController->log('error', 'Service', 'Error while launching scheduled task: ' . $e->getMessage()); } + + // Let some time between each task, to make sure the queue system works properly + sleep(1); } } } diff --git a/www/controllers/Settings.php b/www/controllers/Settings.php index 7af532a6..6139fdba 100644 --- a/www/controllers/Settings.php +++ b/www/controllers/Settings.php @@ -74,6 +74,18 @@ public function apply(array $sendSettings) $settingsToApply['PROXY'] = ''; } + if (!empty($sendSettings['task-queuing'])) { + if ($sendSettings['task-queuing'] == 'true') { + $settingsToApply['TASK_QUEUING'] = 'true'; + } else { + $settingsToApply['TASK_QUEUING'] = 'false'; + } + } + + if (!empty($sendSettings['task-queuing-max-simultaneous']) and is_numeric($sendSettings['task-queuing-max-simultaneous']) and $sendSettings['task-queuing-max-simultaneous'] > 0) { + $settingsToApply['TASK_QUEUING_MAX_SIMULTANEOUS'] = \Controllers\Common::validateData($sendSettings['task-queuing-max-simultaneous']); + } + if (!empty($sendSettings['task-execution-memory-limit']) and is_numeric($sendSettings['task-execution-memory-limit']) and $sendSettings['task-execution-memory-limit'] > 2) { $settingsToApply['TASK_EXECUTION_MEMORY_LIMIT'] = \Controllers\Common::validateData($sendSettings['task-execution-memory-limit']); } diff --git a/www/controllers/Task/Task.php b/www/controllers/Task/Task.php index 0ed83623..31782d7a 100644 --- a/www/controllers/Task/Task.php +++ b/www/controllers/Task/Task.php @@ -156,6 +156,16 @@ public function updateDuration(int $id, string $duration) : void $this->model->updateDuration($id, $duration); } + /** + * List all queued tasks + * It is possible to filter the type of task ('immediate' or 'scheduled') + * It is possible to add an offset to the request + */ + public function listQueued(string $type = '', bool $withOffset = false, int $offset = 0) + { + return $this->model->listQueued($type, $withOffset, $offset); + } + /** * List all running tasks * It is possible to filter the type of task ('immediate' or 'scheduled') @@ -281,17 +291,18 @@ private function new(array $params) : int { /** * Default values - * By default the task is new and immediate + * By default the task is immediate and is queued */ - $status = 'new'; - $type = 'immediate'; + $type = 'immediate'; + $status = 'queued'; /** - * If task is scheduled + * If task is scheduled then overwrite the type and status + * Task is not queued immediately, it will be queued at the scheduled time (when the service will launch the task) */ if ($params['schedule']['scheduled'] == 'true') { + $type = 'scheduled'; $status = 'scheduled'; - $type = 'scheduled'; } /** @@ -325,10 +336,16 @@ private function new(array $params) : int } } + try { + $paramsJson = json_encode($params, JSON_THROW_ON_ERROR); + } catch (JsonException $e) { + throw new Exception('Could not encode task parameters: ' . $e->getMessage()); + } + /** * Add the task in database */ - $taskId = $this->model->new($type, json_encode($params), $status); + $taskId = $this->model->new($type, $paramsJson, $status); return $taskId; } @@ -548,6 +565,10 @@ public function end() */ public function relaunch(int $id) { + if (!IS_ADMIN) { + throw new Exception('You are not allowed to relaunch a task'); + } + /** * First, duplicate task in database */ @@ -574,6 +595,10 @@ private function duplicate(int $id) : int */ public function kill(string $taskId) { + if (!IS_ADMIN) { + throw new Exception('You are not allowed to relaunch a task'); + } + if (!file_exists(PID_DIR . '/' . $taskId . '.pid')) { throw new Exception('Specified task PID does not exist'); } @@ -738,7 +763,7 @@ public function getChildrenPid(int $pid) } /** - * Enable a task + * Enable a recurrent task */ public function enable(int $id) { @@ -746,7 +771,7 @@ public function enable(int $id) } /** - * Disable a task + * Disable a recurrent task */ public function disable(int $id) { diff --git a/www/controllers/ajax/settings.php b/www/controllers/ajax/settings.php index 7cc91d82..06b192fb 100644 --- a/www/controllers/ajax/settings.php +++ b/www/controllers/ajax/settings.php @@ -77,13 +77,20 @@ * Get websocker server log content */ if ($action == 'get-wss-log' and !empty([$_POST['logfile']])) { + $logfile = \Controllers\Common::validateData($_POST['logfile']); + + // Check if the log file is allowed and is not outside the logs directory. Verify that the user is not trying to do something malicious. + if (!preg_match('#^' . WS_LOGS_DIR . '#', realpath(WS_LOGS_DIR . '/' . $logfile))) { + response(HTTP_BAD_REQUEST, 'Invalid log file'); + } + // Check if the log file exists - if (!file_exists(WS_LOGS_DIR . '/' . $_POST['logfile'])) { + if (!file_exists(WS_LOGS_DIR . '/' . $logfile)) { response(HTTP_BAD_REQUEST, 'Log file not found'); } // Get the log content - $content = file_get_contents(WS_LOGS_DIR . '/' . $_POST['logfile']); + $content = file_get_contents(WS_LOGS_DIR . '/' . $logfile); // Check if the log content was read successfully if ($content === false) { diff --git a/www/models/Connection.php b/www/models/Connection.php index 91a5fd9f..dbcc092c 100644 --- a/www/models/Connection.php +++ b/www/models/Connection.php @@ -531,6 +531,8 @@ private function generateMainTables() EMAIL_RECIPIENT VARCHAR(255), PROXY VARCHAR(255), TASK_EXECUTION_MEMORY_LIMIT INTEGER, + TASK_QUEUING CHAR(5), + TASK_QUEUING_MAX_SIMULTANEOUS INTEGER, /* Repo settings */ RETENTION INTEGER, REPO_CONF_FILES_PREFIX VARCHAR(255), @@ -587,6 +589,8 @@ private function generateMainTables() REPO_CONF_FILES_PREFIX, TIMEZONE, TASK_EXECUTION_MEMORY_LIMIT, + TASK_QUEUING, + TASK_QUEUING_MAX_SIMULTANEOUS, MIRRORING_PACKAGE_DOWNLOAD_TIMEOUT, RPM_REPO, RPM_SIGN_PACKAGES, @@ -614,6 +618,8 @@ private function generateMainTables() 'repomanager-', 'Europe/Paris', '1024', + 'false', + '2', '300', 'true', 'true', diff --git a/www/models/Task/Task.php b/www/models/Task/Task.php index f3e9d599..fd7bf882 100644 --- a/www/models/Task/Task.php +++ b/www/models/Task/Task.php @@ -137,6 +137,59 @@ public function somethingRunning() return false; } + /** + * List all newest tasks + * It is possible to add an offset to the request + */ + public function listQueued(string $type, bool $withOffset, int $offset) + { + $data = array(); + + try { + /** + * Case where we want all types + */ + if (empty($type)) { + $query = "SELECT * FROM tasks + WHERE Status = 'queued' + ORDER BY Date DESC, Time DESC"; + } + + /** + * Case where we want to filter by type + */ + if (!empty($type)) { + $query = "SELECT * FROM tasks + WHERE Type = :type + AND Status = 'queued' + ORDER BY Date DESC, Time DESC"; + } + + /** + * Add offset if needed + */ + if ($withOffset === true) { + $query .= " LIMIT 10 OFFSET :offset"; + } + + /** + * Prepare query + */ + $stmt = $this->db->prepare($query); + $stmt->bindValue(':type', $type); + $stmt->bindValue(':offset', $offset, SQLITE3_INTEGER); + $result = $stmt->execute(); + } catch (Exception $e) { + $this->db->logError($e); + } + + while ($row = $result->fetchArray(SQLITE3_ASSOC)) { + $data[] = $row; + } + + return $data; + } + /** * List all running tasks * It is possible to filter the type of task ('immediate' or 'scheduled') @@ -244,8 +297,7 @@ public function listDone(string $type, bool $withOffset, int $offset) */ if (empty($type)) { $query = "SELECT * FROM tasks - WHERE Status = 'new' - OR Status = 'error' + WHERE Status = 'error' OR Status = 'done' OR Status = 'stopped' ORDER BY Date DESC, Time DESC"; @@ -257,8 +309,7 @@ public function listDone(string $type, bool $withOffset, int $offset) if (!empty($type)) { $query = "SELECT * FROM tasks WHERE Type = :type - AND (Status = 'new' - OR Status = 'error' + AND (Status = 'error' OR Status = 'done' OR Status = 'stopped') ORDER BY Date DESC, Time DESC"; @@ -298,7 +349,9 @@ public function getLastTaskId() : int try { $result = $this->db->query("SELECT Id FROM tasks - WHERE Status != 'scheduled' + WHERE Status != 'queued' + AND Status != 'scheduled' + AND Status !='disabled' ORDER BY Id DESC LIMIT 1"); } catch (\Exception $e) { $this->db->logError($e); @@ -346,7 +399,7 @@ public function getNextScheduledTask() $data = array(); try { - $result = $this->db->query("SELECT * FROM tasks WHERE Type = 'scheduled' AND Status = 'scheduled'"); + $result = $this->db->query("SELECT * FROM tasks WHERE Type = 'scheduled' AND Status = 'queued'"); } catch (\Exception $e) { $this->db->logError($e); } @@ -385,7 +438,7 @@ public function new(string $type, string $rawParams, string $status) : int public function duplicate(int $id) : int { try { - $stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params) SELECT Type, Raw_params FROM tasks WHERE Id = :id"); + $stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) SELECT Type, Raw_params, 'queued' FROM tasks WHERE Id = :id"); $stmt->bindValue(':id', $id); $stmt->execute(); } catch (\Exception $e) { @@ -415,7 +468,7 @@ public function close(int $id, string $status, string $duration) } /** - * Enable a task + * Enable a recurrent task */ public function enable(int $id) { @@ -429,7 +482,7 @@ public function enable(int $id) } /** - * Disable a task + * Disable a recurrent task */ public function disable(int $id) { diff --git a/www/public/resources/js/events/task/actions.js b/www/public/resources/js/events/task/actions.js index ae0920f3..14f78eeb 100644 --- a/www/public/resources/js/events/task/actions.js +++ b/www/public/resources/js/events/task/actions.js @@ -272,9 +272,9 @@ $(document).on('click','.enable-scheduled-task-btn',function (e) { }); /** - * Event: cancel scheduled task + * Event: cancel unlaunched task */ -$(document).on('click','.cancel-scheduled-task-btn',function (e) { +$(document).on('click','.cancel-task-btn',function (e) { // Prevent parent to be triggered e.stopPropagation(); @@ -282,7 +282,7 @@ $(document).on('click','.cancel-scheduled-task-btn',function (e) { confirmBox( { - 'title': 'Cancel and delete scheduled task', + 'title': 'Cancel task', 'message': 'Are you sure you want to cancel and delete this task?', 'buttons': [ { diff --git a/www/public/resources/js/functions.js b/www/public/resources/js/functions.js index 49ba1e99..b285f85e 100644 --- a/www/public/resources/js/functions.js +++ b/www/public/resources/js/functions.js @@ -570,6 +570,9 @@ function getGetParams() return array; } +/** + * Return true if the value is empty + */ function empty(value) { // Check if the value is null or undefined diff --git a/www/public/resources/js/functions/task.js b/www/public/resources/js/functions/task.js index 5e8f0db7..53ed7aa5 100644 --- a/www/public/resources/js/functions/task.js +++ b/www/public/resources/js/functions/task.js @@ -78,7 +78,7 @@ function autorefresh() // Remove autorefresh lock localStorage.removeItem('autorefreshLock'); }); - }, 2000); + }, 2500); } /** diff --git a/www/tasks/execute.php b/www/tasks/execute.php index ad70da94..05da33f7 100644 --- a/www/tasks/execute.php +++ b/www/tasks/execute.php @@ -37,28 +37,86 @@ /** * Retrieve task details */ - $taskParams = $myTask->getById($taskId); + $task = $myTask->getById($taskId); - if (empty($taskParams)) { + if (empty($task)) { throw new Exception('Cannot get task details from task #' . $taskId . ': empty results.'); } - $taskParams = json_decode($taskParams['Raw_params'], true); + try { + $taskRawParams = json_decode($task['Raw_params'], true, 512, JSON_THROW_ON_ERROR); + } catch (JsonException $e) { + throw new Exception('Cannot decode task params from task #' . $taskId . ': ' . $e->getMessage()); + } - if (empty($taskParams['action'])) { + if (empty($taskRawParams['action'])) { throw new Exception('Action not specified'); } /** * Generate controller name */ - $controllerPath = '\Controllers\Task\Repo\\' . ucfirst($taskParams['action']); + $controllerPath = '\Controllers\Task\Repo\\' . ucfirst($taskRawParams['action']); /** * Check if class exists, otherwise the action might be invalid */ if (!class_exists($controllerPath)) { - throw new Exception('Invalid action: ' . $taskParams['action']); + throw new Exception('Invalid action: ' . $taskRawParams['action']); + } + + /** + * If task queuing is enabled and the maximum number of simultaneous tasks is set, check if the task can be started + */ + if (!empty(TASK_QUEUING) and TASK_QUEUING == 'true' and !empty(TASK_QUEUING_MAX_SIMULTANEOUS)) { + while (true) { + /** + * Get running tasks + */ + $runningTasks = $myTask->listRunning(); + + /** + * If number of running tasks is greater than or equal to the maximum number of simultaneous tasks, we wait + */ + if (count($runningTasks) >= TASK_QUEUING_MAX_SIMULTANEOUS) { + sleep(5); + continue; + } + + /** + * If this task type is 'scheduled', the task can be started now. + * It has more priority than any 'immediate' tasks because it has a specific time to be run. + */ + if ($task['Type'] == 'scheduled') { + break; + } + + /** + * If the task type is 'immediate', get all currently queued tasks + */ + $newestTask = $myTask->listQueued(); + + /** + * If there are tasks of type 'scheduled' in the queue list, we wait, they have more priority + */ + foreach ($newestTask as $task) { + if ($task['Type'] == 'scheduled') { + sleep(5); + continue 2; + } + } + + /** + * If there is no task of type 'scheduled' in the queue list, this task may be started + * If the first task in the list has the same Id as $taskId, then this task can be started + */ + if ($newestTask[0]['Id'] == $taskId) { + break; + } + + // Just for safety + sleep(5); + } } /** diff --git a/www/update/database/4.17.0.php b/www/update/database/4.17.0.php new file mode 100644 index 00000000..7083250c --- /dev/null +++ b/www/update/database/4.17.0.php @@ -0,0 +1,18 @@ +db->columnExist('settings', 'TASK_QUEUING')) { + $this->db->exec("ALTER TABLE settings ADD COLUMN TASK_QUEUING BOOLEAN DEFAULT 'false'"); +} + +/** + * Add 'TASK_QUEUING_MAX_SIMULTANEOUS' column to settings table + */ +if (!$this->db->columnExist('settings', 'TASK_QUEUING_MAX_SIMULTANEOUS')) { + $this->db->exec("ALTER TABLE settings ADD COLUMN TASK_QUEUING_MAX_SIMULTANEOUS INTEGER DEFAULT '2'"); +} diff --git a/www/update/database/ci/deb/delete.php b/www/update/database/ci/deb/delete.php index cbc353ad..9fdefad5 100644 --- a/www/update/database/ci/deb/delete.php +++ b/www/update/database/ci/deb/delete.php @@ -18,6 +18,6 @@ 'schedule-recipient' => [''] ]; -$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'new');"); +$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'queued');"); $stmt->bindParam(':rawParams', json_encode($rawParams)); $stmt->execute(); diff --git a/www/update/database/ci/deb/duplicate.php b/www/update/database/ci/deb/duplicate.php index 1ff0bf45..835e7033 100644 --- a/www/update/database/ci/deb/duplicate.php +++ b/www/update/database/ci/deb/duplicate.php @@ -22,6 +22,6 @@ 'schedule-recipient' => [''] ]; -$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'new');"); +$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'queued');"); $stmt->bindParam(':rawParams', json_encode($rawParams)); $stmt->execute(); diff --git a/www/update/database/ci/deb/env.php b/www/update/database/ci/deb/env.php index 51812ecf..e7489ae5 100644 --- a/www/update/database/ci/deb/env.php +++ b/www/update/database/ci/deb/env.php @@ -20,6 +20,6 @@ 'schedule-recipient' => [''] ]; -$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'new');"); +$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'queued');"); $stmt->bindParam(':rawParams', json_encode($rawParams)); $stmt->execute(); diff --git a/www/update/database/ci/deb/mirror.php b/www/update/database/ci/deb/mirror.php index 8f874782..40932ca4 100644 --- a/www/update/database/ci/deb/mirror.php +++ b/www/update/database/ci/deb/mirror.php @@ -27,6 +27,6 @@ ]; $rawParams['repo-id'] = 'debian|bookworm|contrib'; -$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'new');"); +$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'queued');"); $stmt->bindParam(':rawParams', json_encode($rawParams)); $stmt->execute(); diff --git a/www/update/database/ci/deb/rebuild.php b/www/update/database/ci/deb/rebuild.php index 8745c22d..cb60278f 100644 --- a/www/update/database/ci/deb/rebuild.php +++ b/www/update/database/ci/deb/rebuild.php @@ -19,6 +19,6 @@ 'schedule-recipient' => [''] ]; -$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'new');"); +$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'queued');"); $stmt->bindParam(':rawParams', json_encode($rawParams)); $stmt->execute(); diff --git a/www/update/database/ci/deb/update.php b/www/update/database/ci/deb/update.php index f7a17eaa..abe1ee23 100644 --- a/www/update/database/ci/deb/update.php +++ b/www/update/database/ci/deb/update.php @@ -22,6 +22,6 @@ 'schedule-recipient' => [''] ]; -$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'new');"); +$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'queued');"); $stmt->bindParam(':rawParams', json_encode($rawParams)); $stmt->execute(); diff --git a/www/update/database/ci/rpm/delete.php b/www/update/database/ci/rpm/delete.php index 9dd84adb..0d531adb 100644 --- a/www/update/database/ci/rpm/delete.php +++ b/www/update/database/ci/rpm/delete.php @@ -18,6 +18,6 @@ 'schedule-recipient' => [''] ]; -$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'new');"); +$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'queued');"); $stmt->bindParam(':rawParams', json_encode($rawParams)); $stmt->execute(); diff --git a/www/update/database/ci/rpm/duplicate.php b/www/update/database/ci/rpm/duplicate.php index e96c85cb..99e3433b 100644 --- a/www/update/database/ci/rpm/duplicate.php +++ b/www/update/database/ci/rpm/duplicate.php @@ -22,6 +22,6 @@ 'schedule-recipient' => [''] ]; -$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'new');"); +$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'queued');"); $stmt->bindParam(':rawParams', json_encode($rawParams)); $stmt->execute(); diff --git a/www/update/database/ci/rpm/env.php b/www/update/database/ci/rpm/env.php index 1a363824..92855c93 100644 --- a/www/update/database/ci/rpm/env.php +++ b/www/update/database/ci/rpm/env.php @@ -20,6 +20,6 @@ 'schedule-recipient' => [''] ]; -$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'new');"); +$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'queued');"); $stmt->bindParam(':rawParams', json_encode($rawParams)); $stmt->execute(); diff --git a/www/update/database/ci/rpm/mirror.php b/www/update/database/ci/rpm/mirror.php index 5f0d4e40..593232a5 100644 --- a/www/update/database/ci/rpm/mirror.php +++ b/www/update/database/ci/rpm/mirror.php @@ -25,6 +25,6 @@ 'schedule-recipient' => [''] ]; -$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'new');"); +$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'queued');"); $stmt->bindParam(':rawParams', json_encode($rawParams)); $stmt->execute(); diff --git a/www/update/database/ci/rpm/rebuild.php b/www/update/database/ci/rpm/rebuild.php index 8a133d8e..9387824c 100644 --- a/www/update/database/ci/rpm/rebuild.php +++ b/www/update/database/ci/rpm/rebuild.php @@ -19,6 +19,6 @@ 'schedule-recipient' => [''] ]; -$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'new');"); +$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'queued');"); $stmt->bindParam(':rawParams', json_encode($rawParams)); $stmt->execute(); diff --git a/www/update/database/ci/rpm/update.php b/www/update/database/ci/rpm/update.php index 73ea490a..7004553b 100644 --- a/www/update/database/ci/rpm/update.php +++ b/www/update/database/ci/rpm/update.php @@ -22,6 +22,6 @@ 'schedule-recipient' => [''] ]; -$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'new');"); +$stmt = $this->db->prepare("INSERT INTO tasks (Type, Raw_params, Status) VALUES ('immediate', :rawParams, 'queued');"); $stmt->bindParam(':rawParams', json_encode($rawParams)); $stmt->execute(); diff --git a/www/version b/www/version index 2bd63a3b..8643e722 100644 --- a/www/version +++ b/www/version @@ -1 +1 @@ -4.16.4 \ No newline at end of file +4.17.0 \ No newline at end of file diff --git a/www/views/includes/containers/settings/health.inc.php b/www/views/includes/containers/settings/health.inc.php index cf870569..3f3b7b4b 100644 --- a/www/views/includes/containers/settings/health.inc.php +++ b/www/views/includes/containers/settings/health.inc.php @@ -145,7 +145,7 @@
-
CURRENT USERS
+
CURRENT USERS
diff --git a/www/views/includes/containers/settings/settings.inc.php b/www/views/includes/containers/settings/settings.inc.php index ed0b8094..d08321a6 100644 --- a/www/views/includes/containers/settings/settings.inc.php +++ b/www/views/includes/containers/settings/settings.inc.php @@ -49,8 +49,26 @@

Specify the proxy URL to use to access the internet. e.g. https://myproxy.com:8080

+

+
TASK EXECUTION
+ +
TASK QUEUING
+

Enable or disable the task queuing.

+ + + +
MAXIMUM NUMBER OF SIMULTANEOUS TASKS
+

Maximum number of tasks that can run simultaneously. The other tasks will be queued.

+ + +
TASK EXECUTION MEMORY LIMIT (in MB)
-

Set PHP memory limit for tasks execution. It is recommended to set this value to a higher value when mirroring large repositories.

+

Set PHP memory limit for task execution. It is recommended to set this value to a higher value when mirroring large repositories.

diff --git a/www/views/includes/containers/tasks/list.inc.php b/www/views/includes/containers/tasks/list.inc.php index eb309161..28387894 100644 --- a/www/views/includes/containers/tasks/list.inc.php +++ b/www/views/includes/containers/tasks/list.inc.php @@ -3,14 +3,19 @@ " offset=""> ' . $taskTableTitle . ''; + } + foreach ($reloadableTableContent as $item) : $headerColor = ''; @@ -12,8 +16,8 @@ /** * If the current task item was made in a scheduled task, we display the scheduled task header */ - if ($item['Type'] == 'scheduled' and $item['Status'] == 'scheduled') { - $headerColor = 'header-light-blue'; + if ($item['Status'] == 'scheduled' or $item['Status'] == 'queued') { + $headerColor = 'header-blue-min'; } $tableClass = 'table-container grid-40p-45p-10p column-gap-10 justify-space-between pointer show-task-btn ' . $headerColor; ?> @@ -75,19 +79,14 @@
- - - format('d-m-Y') . ' ' . $item['Time']; - endif ?> - - - ' . DateTime::createFromFormat('Y-m-d', $item['Date'])->format('d-m-Y') . ' ' . $item['Time'] . ''; + endif; + /** * If task is scheduled */ @@ -154,6 +153,13 @@
'; + } + /** * If task is a scheduled task */ @@ -178,20 +184,9 @@ } } - /** - * Delete task button - */ - if ($item['Status'] == 'scheduled') { - echo ''; - } - /** * Task status icon */ - if ($item['Status'] == 'scheduled') { - echo ''; - } - if ($item['Status'] == 'disabled') { echo ''; } @@ -204,6 +199,10 @@ echo ''; } + if ($item['Status'] == 'scheduled' or $item['Status'] == 'queued') { + echo ''; + } + if ($item['Status'] == 'running') { echo ''; echo ''; @@ -261,19 +260,19 @@

+

+