Files
itflow/admin/post/update.php
johnnyq 3b5c11c552 Add managed mode, so one ITFlow can manage others - Admin > Managed Instances adds an instance and gives a one-time connection code (a week) that the other ITFlow pastes into the new Admin > Managed By, after which it checks in every minute from the new Manager Check-in cron job with a health report (versions, update waiting and whether it has security fixes, cron, last backup, errors today, agents against the seat limit, clients, storage) and takes back what the manager sets; the manager lists each instance's version, health, seats and last check-in with a page per instance showing what needs a look, its requests and everything it reported, can update it by hand or automatically after a set number of days (security releases straight away, not retried for six hours after a failure), set its seat limit and white-label key (locked on the instance while set), make it read-only (look, export and download only, across agents, portal, guest links and the API) or suspended (a notice with the manager's message and contact, 503 for the API) with other cron jobs paused until it is active again, sign in to it as support through a signed one-time two-minute link into a two-hour session that takes no seat, can't open the vault and can't set passwords or make API keys, and remove it, while the new Managed Instances job notifies when one stops checking in and closes requests never answered; instances only call the manager, can disconnect unless config.php sets $config_manager_required, and the Update page and queue_update defer to the manager; database 3.5.8 adds managed_instances, managed_instance_commands, settings.config_manager_keys and settings.config_managed, the logic is in the new functions/managed.php with api/managed/enroll.php, api/managed/checkin.php, login_support.php and includes/managed_blocked.php, cronJobClaim() takes a paused reason that leaves a due job due, getAgentUserLimit() and getActiveAgentUserCount() honour the manager's limit and leave out the support user, the vault helpers read a missing session key as empty, the audit log knows the new types and actions, and the email parser no longer logs an App Logs error every minute while parsing is switched off; changelog updated
2026-11-05 15:22:41 -05:00

73 lines
3.1 KiB
PHP

<?php
defined('FROM_POST_HANDLER') || die("Direct file access is not allowed");
/*
* Queueing is the ONLY update path from the web - files and database both. There used to be
* an ?update handler here that ran git pull inside this request, and an ?update_db one that
* ran the migrations; both are gone deliberately. 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 a host where PHP cannot run
* external commands could never do the first half 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.
*/
/*
* Check Now. The check runs git fetch, so it belongs on the command line for the same reason
* the update does; this only asks the dispatcher to bring the job forward. run_now works on a
* disabled job too, so turning the daily check off does not take the button with it.
*/
if (isset($_GET['check_update'])) {
validateCSRFToken();
enforceAdminPermission();
if (!settingsColumnExists($mysqli, 'config_update_latest_commit')) {
flashAlert("Checking needs a schema change this install has not caught up with yet - run php scripts/update_cli.php from a shell once, and it will work from then on.", 'error');
redirect();
}
mysqli_query($mysqli, "UPDATE cron_jobs SET cron_job_run_now = 1 WHERE cron_job_name = 'update_check'");
logAudit("App", "Update", "$session_name asked cron to check for updates");
flashAlert("Checking for updates - cron will run the check within a minute.");
redirect();
}
if (isset($_GET['queue_update'])) {
validateCSRFToken();
enforceAdminPermission();
// A managed instance is updated by its manager (functions/managed.php)
if (managedLocks()['updates']) {
flashAlert(escapeHtml(managedManagerName()) . " manages this ITFlow, so updates come from there.", 'error');
redirect();
}
// 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. There is no
// longer a button that applies migrations on their own, so the way out is the shell.
if (!settingsColumnExists($mysqli, 'config_update_queued_at')) {
flashAlert("Queueing needs a schema change this install has not caught up with yet - run php scripts/update_cli.php from a shell once, and it will work from then on.", '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("Updating ITFlow - cron starts within a minute, and this page shows how it goes.");
redirect();
}