Managed Instances): notices what the instances * don't say themselves. An instance that has stopped checking in gets one notification, until * it's back (the check-in clears it - managerCheckin()); a request it took and never answered, * or an update that never said it finished, is closed as failed rather than left waiting. */ // Set working directory to the directory this cron script lives at. chdir(dirname(__FILE__)); // Ensure we're running from command line if (php_sapi_name() !== 'cli') { die("This script must be run from the command line.\n"); } // Prevent overlapping runs of this script $cron_lock_script = __FILE__; require_once "includes/cron_lock.php"; require_once "../config.php"; // Set Timezone require_once "../includes/inc_set_timezone.php"; require_once "../functions.php"; $managed_instances_settings = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT config_enable_cron FROM settings WHERE company_id = 1")); if (intval($managed_instances_settings['config_enable_cron'] ?? 0) === 0) { cronJobStop("Cron: is not enabled\n"); } // Off unless config.php turns it on - the dispatcher doesn't list this job then (includes/cron_jobs.php) if (!managerEnabled()) { cronJobStop("Managed Instances is off in config.php\n"); } // Files newer than the schema - the tables arrive with the migration if (!settingsColumnExists($mysqli, 'config_manager_keys')) { cronJobStop("The database update has not been applied yet\n"); } $managed_instances_count = intval(mysqli_fetch_row(mysqli_query($mysqli, "SELECT COUNT(*) FROM managed_instances WHERE managed_instance_archived_at IS NULL AND managed_instance_secret_hash IS NOT NULL"))[0] ?? 0); if ($managed_instances_count === 0) { cronJobStop("No instances connected\n"); } // Gone quiet - told once, until it checks in again $managed_instances_quiet = mysqli_query($mysqli, "SELECT managed_instance_id, managed_instance_name, managed_instance_client_id, managed_instance_last_checkin_at, managed_instance_secret_hash, managed_instance_report FROM managed_instances WHERE managed_instance_archived_at IS NULL AND managed_instance_secret_hash IS NOT NULL AND managed_instance_offline_notified_at IS NULL AND (managed_instance_last_checkin_at IS NULL OR managed_instance_last_checkin_at < NOW() - INTERVAL " . MANAGED_OFFLINE_MINUTES . " MINUTE)"); while ($managed_instance = mysqli_fetch_assoc($managed_instances_quiet)) { $managed_instance_id = intval($managed_instance['managed_instance_id']); $managed_instance_last = $managed_instance['managed_instance_last_checkin_at']; // Connected, and its cron has never run - a new install whose cron job isn't in yet $managed_instance_waiting = managedInstanceHealth($managed_instance)['state'] === 'waiting'; appNotify("Managed Instance", escapeSql($managed_instance['managed_instance_name'] . ($managed_instance_waiting ? " is waiting for its cron job - add it in its hosting control panel" : " has stopped checking in" . ($managed_instance_last ? " - last " . date('M j, g:i A', strtotime($managed_instance_last)) : ''))), "/admin/managed_instance.php?id=$managed_instance_id", intval($managed_instance['managed_instance_client_id']), $managed_instance_id); mysqli_query($mysqli, "UPDATE managed_instances SET managed_instance_offline_notified_at = NOW() WHERE managed_instance_id = $managed_instance_id"); } // A request it took and never answered mysqli_query($mysqli, "UPDATE managed_instance_commands SET managed_command_status = 'failed', managed_command_done_at = NOW(), managed_command_result = 'It took the request but never answered - see whether it is still checking in' WHERE managed_command_status = 'sent' AND managed_command_sent_at < NOW() - INTERVAL 1 HOUR"); // An update that never said it finished $managed_instances_stuck = mysqli_query($mysqli, "SELECT managed_command_id, managed_instance_id, managed_instance_name, managed_instance_client_id FROM managed_instance_commands JOIN managed_instances ON managed_instance_id = managed_command_instance_id WHERE managed_command = 'update_now' AND managed_command_status = 'running' AND managed_command_sent_at < NOW() - INTERVAL 2 HOUR"); while ($managed_instance = mysqli_fetch_assoc($managed_instances_stuck)) { mysqli_query($mysqli, "UPDATE managed_instance_commands SET managed_command_status = 'failed', managed_command_done_at = NOW(), managed_command_result = 'No word of the update finishing in two hours - look at its Maintenance > Update page' WHERE managed_command_id = " . intval($managed_instance['managed_command_id'])); appNotify("Managed Instance", escapeSql("The update on " . $managed_instance['managed_instance_name'] . " hasn't finished in two hours"), "/admin/managed_instance.php?id=" . intval($managed_instance['managed_instance_id']), intval($managed_instance['managed_instance_client_id']), intval($managed_instance['managed_instance_id'])); }