272) { // observium_processes added in db version 272 // Check if discovery -u already running $pid_info = check_process_run(-1); if ($pid_info) { // Process ID exist in DB print_message("%rAnother " . $pid_info['process_name'] . " process (PID: " . $pid_info['PID'] . ", UID: " . $pid_info['UID'] . ", STARTED: " . $pid_info['STARTED'] . ") already running for update.%n", 'color'); // Not sure what better, return and process all other discovery operations // or complete stop discovery // (stop can produce 6 hour latency for devices discovery, but return can broke all discovery devices after update) return FALSE; //exit(2); } add_process_info(-1); // Store process info } // Note, undocumented ability for force update from db schema (not more than 50) $update_force = isset($options['U']) && is_numeric($options['U']) && $db_rev >= $options['U'] && ($db_rev - $options['U']) <= 50; if ($update_force) { print_debug("Forced update from DB schema " . $options['U']); $db_rev = (int)$options['U'] - 1; } $updating = 0; // Only numeric filenames (001.sql, 013.php) $sql_regexp = "/^\d{3,4}\.sql$/"; $php_regexp = "/^\d{3,4}\.php$/"; $filelist = []; if ($handle = opendir($config['install_dir'] . '/update')) { while (FALSE !== ($file = readdir($handle))) { if (filetype($config['install_dir'] . '/update/' . $file) === 'file' && (preg_match($sql_regexp, $file) || preg_match($php_regexp, $file))) { $filelist[] = $file; } } closedir($handle); } sort($filelist); //print_vars($filelist); foreach ($filelist as $file) { $filepath = $config['install_dir'] . '/update/' . $file; [$filename, $extension] = explode('.', $file, 2); if ($filename > $db_rev) { if (!$updating) { echo('-- Updating database/file schema' . PHP_EOL); } $error_ignore = $update_force; // Stop update if errors not ignored if ($extension === "php") { $log_msg = sprintf("%03d", $db_rev) . " -> " . sprintf("%03d", $filename) . " # (php) "; echo($log_msg); $start = time(); if (include_wrapper($filepath)) { // File included OK, update dbSchema $schema_status = set_db_version($filename, $schema_insert); if ($schema_insert && $schema_status !== FALSE) { // dbSchema inserted, now only update $schema_insert = FALSE; } $update_time = format_uptime(time() - $start); echo(" Done ($update_time)." . PHP_EOL); if ($filename >= 184) { log_event("Observium schema updated: " . $log_msg . "($update_time).", NULL, NULL, NULL, 5); } } else { // Critical errors, stop update logfile('update-errors.log', "====== Schema update " . sprintf("%03d", $db_rev) . " -> " . sprintf("%03d", $filename) . " =============="); logfile('update-errors.log', "Error: Could not load file $filepath!"); if ($filename >= 184) { log_event("Observium schema not updated: " . $log_msg . ".", NULL, NULL, NULL, 3); } exit(1); } } elseif ($extension === "sql") { $log_msg = sprintf("%03d", $db_rev) . " -> " . sprintf("%03d", $filename) . " # (db) "; echo($log_msg); $err = 0; $start = time(); if ($fd = @fopen($filepath, 'r')) { $data = fread($fd, 4096); while (!feof($fd)) { $data .= fread($fd, 4096); } fclose($fd); foreach (explode("\n", $data) as $line) { if (trim($line)) { // Skip comments if (str_starts($line, ['#', '-', '/'])) { if (str_contains_array($line, ['ERROR_IGNORE', 'IGNORE_ERROR'])) { $error_ignore = TRUE; } elseif (str_contains($line, 'NOTE')) { [, $note] = explode('NOTE', $line, 2); echo('(' . trim($note) . ')'); } continue; } print_debug($line); $update = dbQuery($line); if (!$update) { $error_no = dbErrorNo(); $error_msg = "($error_no) " . dbError(); if ($error_no >= 2000 || in_array($error_no, [3, 1114])) { // additional critical errors list // Critical errors, stop update log_event("Observium schema not updated: " . $log_msg . ".", NULL, NULL, NULL, 3); echo(" stopped. Critical error: " . $error_msg . PHP_EOL); // http://dev.mysql.com/doc/refman/5.6/en/error-messages-client.html logfile('update-errors.log', "====== Schema update " . sprintf("%03d", $db_rev) . " -> " . sprintf("%03d", $filename) . " =============="); logfile('update-errors.log', "Query: " . $line); logfile('update-errors.log', "Error: " . $error_msg); del_process_info(-1); // Remove process info exit(1); } if ($error_ignore) { echo('.'); } else { echo('F'); } $err++; $errors[] = ['query' => $line, 'error' => $error_msg]; print_debug($error_msg); } else { echo('.'); } } } $update_time = format_uptime(time() - $start); if ($db_rev < 1) { if ($filename >= 184) { log_event("Observium schema updated: " . $log_msg . "($update_time).", NULL, NULL, NULL, 5); } echo(" Done ($update_time)." . PHP_EOL); } elseif ($err) { if ($error_ignore) { if ($filename >= 184) { log_event("Observium schema updated: " . $log_msg . "($update_time).", NULL, NULL, NULL, 5); } echo(" Done ($update_time)." . PHP_EOL); } else { if ($filename >= 184) { log_event("Observium schema updated: " . $log_msg . "($update_time, $err errors).", NULL, NULL, NULL, 4); } echo(" Done ($update_time, $err errors)." . PHP_EOL); } logfile('update-errors.log', "====== Schema update " . sprintf("%03d", $db_rev) . " -> " . sprintf("%03d", $filename) . " =============="); foreach ($errors as $error) { logfile('update-errors.log', "Query: " . $error['query']); logfile('update-errors.log', "Error: " . $error['error']); } unset($errors); } else { if ($filename >= 184) { log_event("Observium schema updated: " . $log_msg . "($update_time).", NULL, NULL, NULL, 5); } echo(" Done ($update_time)." . PHP_EOL); } // SQL update done, update dbSchema $schema_status = set_db_version($filename, $schema_insert); if ($schema_insert && $schema_status !== FALSE) { // dbSchema inserted, now only update $schema_insert = FALSE; } /// Only for developers, export latest schema if ($schema_status && $filename >= 300 && OBS_DEBUG > 1 && !is_file($config['install_dir'] . '/update/db_schema_' . $filename . '.json')) { file_put_contents($config['install_dir'] . '/update/db_schema_' . $filename . '.json', export_db_schema('json')); } } else { if ($filename >= 184) { log_event("Observium schema not updated: " . $log_msg . ".", NULL, NULL, NULL, 3); } echo(' Could not open file!' . PHP_EOL); // Critical errors, stop update logfile('update-errors.log', "====== Schema update " . sprintf("%03d", $db_rev) . " -> " . sprintf("%03d", $filename) . " =============="); logfile('update-errors.log', "Error: Could not open file $filepath!"); del_process_info(-1); // Remove process info exit(1); } } $updating++; $db_rev = $filename; } } // Clean del_process_info(-1); // Remove process info if ($updating) { // $GLOBALS['cache']['db_version'] = $db_rev; // Cache new db version // if ($schema_insert) // { // dbInsert(array('attrib_type' => 'dbSchema', 'attrib_value' => $db_rev), 'observium_attribs'); // } else { // dbUpdate(array('attrib_value' => $db_rev), 'observium_attribs', 'attrib_type = ?', array('dbSchema')); // } echo('-- Done.' . PHP_EOL); } else { echo('-- Database is up to date.' . PHP_EOL); } return $updating; // EOF