Feature: queued Updates which now eliminates the need for shell_exec from the webui, but if enabled you can still update from the webui the old way too

This commit is contained in:
johnnyq
2026-08-15 16:41:42 -04:00
parent d5ee0bff74
commit 4c4c172f59
8 changed files with 410 additions and 29 deletions

View File

@@ -2,12 +2,53 @@
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
/*
* Hands the update to cron instead of running it in this request. scripts/update_cli.php
* replaces the files this request is executing from and then applies the migrations that
* came with them, which is not something to do half way through a page load - and on a host
* where PHP cannot run external commands it is the only way to update the application at all.
*
* The row is written as well as the settings column: config_update_queued_at is what
* cron/app_update.php acts on, and cron_job_run_now is what gets the dispatcher to look
* before the job's own schedule comes round.
*/
if (isset($_GET['queue_update'])) {
validateCSRFToken();
enforceAdminPermission();
// The files can be newer than the schema - that is the window this whole page exists to
// close - and the column the queue is written to arrives with a migration
if (!settingsColumnExists($mysqli, 'config_update_queued_at')) {
flashAlert("Apply the database update first - queueing needs a schema change this install has not caught up with yet.", 'error');
redirect();
}
mysqli_query($mysqli, "UPDATE settings SET config_update_queued_at = '" . date('Y-m-d H:i:s') . "' WHERE company_id = 1");
mysqli_query($mysqli, "UPDATE cron_jobs SET cron_job_run_now = 1 WHERE cron_job_name = 'app_update'");
logAudit("App", "Update", "$session_name queued an update to be applied by cron");
flashAlert("Update queued - cron will start it within a minute.");
redirect();
}
if (isset($_GET['update'])) {
validateCSRFToken();
enforceAdminPermission();
// Reached only from buttons this install cannot draw without a shell, so anything
// arriving here without one is a crafted request rather than somebody's mistake
if (!shellCommandsAvailable()) {
flashAlert("PHP on this server cannot run Git. Queue the update instead and cron will apply it.", 'error');
redirect();
}
// git fetch downloads the latest from the remote without merging or rebasing anything.
// The hard reset then throws away every local change and makes the working tree match
// the tracked branch exactly.