feature: Show composer status in web validate. (#8181)

* Show composer status in web validate.
Don't duplicate in validate.php

* Create variable to check if a group has been completed.
No longer skips database checks.
Extract a base class.
Fix locate_binary and find_executable issues (mostly exposed by lack of db)

* Update Validator.php
This commit is contained in:
Tony Murray
2018-02-27 09:57:20 -06:00
committed by Neil Lathwood
parent f57e92102a
commit 3c3fbd3731
20 changed files with 218 additions and 165 deletions

View File

@@ -43,4 +43,18 @@ interface ValidationGroup
* @return bool
*/
public function isDefault();
/**
* Returns true if this group has been run
*
* @return bool
*/
public function isCompleted();
/**
* Mark this group as completed
*
* @return void
*/
public function markCompleted();
}

View File

@@ -0,0 +1,64 @@
<?php
/**
* BaseValidation.php
*
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\Validations;
use LibreNMS\Interfaces\ValidationGroup;
abstract class BaseValidation implements ValidationGroup
{
protected $completed = false;
protected static $RUN_BY_DEFAULT = true;
/**
* Returns if this test should be run by default or not.
*
* @return bool
*/
public function isDefault()
{
return static::$RUN_BY_DEFAULT;
}
/**
* Returns true if this group has been run
*
* @return bool
*/
public function isCompleted()
{
return $this->completed ;
}
/**
* Mark this group as completed
*
* @return void
*/
public function markCompleted()
{
$this->completed = true;
}
}

View File

@@ -26,10 +26,9 @@
namespace LibreNMS\Validations;
use LibreNMS\Config;
use LibreNMS\Interfaces\ValidationGroup;
use LibreNMS\Validator;
class Configuration implements ValidationGroup
class Configuration extends BaseValidation
{
/**
* Validate this module.
@@ -44,14 +43,4 @@ class Configuration implements ValidationGroup
$validator->warn('You have the old alerting system enabled - this is to be deprecated on the 1st of June 2015: https://groups.google.com/forum/#!topic/librenms-project/1llxos4m0p4');
}
}
/**
* Returns if this test should be run by default or not.
*
* @return bool
*/
public function isDefault()
{
return true;
}
}

View File

@@ -26,12 +26,11 @@
namespace LibreNMS\Validations;
use LibreNMS\Config;
use LibreNMS\Interfaces\ValidationGroup;
use LibreNMS\ValidationResult;
use LibreNMS\Validator;
use Symfony\Component\Yaml\Yaml;
class Database implements ValidationGroup
class Database extends BaseValidation
{
public function validate(Validator $validator)
{
@@ -308,14 +307,4 @@ FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = '" . Config::get('db_name'
return sprintf($index, $columns);
}
/**
* Returns if this test should be run by default or not.
*
* @return bool
*/
public function isDefault()
{
return true;
}
}

View File

@@ -0,0 +1,68 @@
<?php
/**
* Dependencies.php
*
* Checks libraries
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\Validations;
use LibreNMS\ValidationResult;
use LibreNMS\Validator;
class Dependencies extends BaseValidation
{
/**
* Validate this module.
* To return ValidationResults, call ok, warn, fail, or result methods on the $validator
*
* @param Validator $validator
*/
public function validate(Validator $validator)
{
$composer_output = trim(shell_exec($validator->getBaseDir() . '/scripts/composer_wrapper.php --version'));
$found = preg_match('/Composer version ([.0-9]+)/', $composer_output, $matches);
if (!$found) {
$validator->fail("No composer available, please install composer", "https://getcomposer.org/");
return;
} else {
$validator->ok("Composer Version: " . $matches[1]);
}
$dep_check = shell_exec($validator->getBaseDir() . '/scripts/composer_wrapper.php install --no-dev --dry-run');
preg_match_all('/Installing ([^ ]+\/[^ ]+) \(/', $dep_check, $dep_missing);
if (!empty($dep_missing[0])) {
$result = ValidationResult::fail("Missing dependencies!", "composer install --no-dev");
$result->setList("Dependencies", $dep_missing[1]);
$validator->result($result);
}
preg_match_all('/Updating ([^ ]+\/[^ ]+) \(/', $dep_check, $dep_outdated);
if (!empty($dep_outdated[0])) {
$result = ValidationResult::fail("Outdated dependencies", "composer install --no-dev");
$result->setList("Dependencies", $dep_outdated[1]);
}
if (empty($dep_missing[0]) && empty($dep_outdated[0])) {
$validator->ok("Dependencies up-to-date.");
}
}
}

View File

@@ -26,10 +26,9 @@
namespace LibreNMS\Validations;
use LibreNMS\Config;
use LibreNMS\Interfaces\ValidationGroup;
use LibreNMS\Validator;
class Disk implements ValidationGroup
class Disk extends BaseValidation
{
/**
* Validate this module.
@@ -56,14 +55,4 @@ class Disk implements ValidationGroup
$validator->fail("Disk space where $rrd_dir is located is empty!!!");
}
}
/**
* Returns if this test should be run by default or not.
*
* @return bool
*/
public function isDefault()
{
return true;
}
}

View File

@@ -33,11 +33,12 @@
namespace LibreNMS\Validations;
use LibreNMS\Config;
use LibreNMS\Interfaces\ValidationGroup;
use LibreNMS\Validator;
class DistributedPoller implements ValidationGroup
class DistributedPoller extends BaseValidation
{
protected static $RUN_BY_DEFAULT = false;
/**
* Validate this module.
* To return ValidationResults, call ok, warn, fail, or result methods on the $validator
@@ -74,14 +75,4 @@ class DistributedPoller implements ValidationGroup
Rrd::checkRrdcached($validator);
}
}
/**
* Returns if this test should be run by default or not.
*
* @return bool
*/
public function isDefault()
{
return false;
}
}

View File

@@ -26,11 +26,11 @@
namespace LibreNMS\Validations;
use LibreNMS\Config;
use LibreNMS\Interfaces\ValidationGroup;
use LibreNMS\Validator;
class Mail implements ValidationGroup
class Mail extends BaseValidation
{
protected static $RUN_BY_DEFAULT = false;
/**
* Validate this module.
@@ -79,14 +79,4 @@ class Mail implements ValidationGroup
}
}//end if
}
/**
* Returns if this test should be run by default or not.
*
* @return bool
*/
public function isDefault()
{
return false;
}
}

View File

@@ -26,11 +26,10 @@
namespace LibreNMS\Validations;
use LibreNMS\Config;
use LibreNMS\Interfaces\ValidationGroup;
use LibreNMS\ValidationResult;
use LibreNMS\Validator;
class Php implements ValidationGroup
class Php extends BaseValidation
{
/**
* Validate this module.
@@ -161,14 +160,4 @@ class Php implements ValidationGroup
}
}
}
/**
* Returns if this test should be run by default or not.
*
* @return bool
*/
public function isDefault()
{
return true;
}
}

View File

@@ -25,11 +25,10 @@
namespace LibreNMS\Validations;
use LibreNMS\Interfaces\ValidationGroup;
use LibreNMS\ValidationResult;
use LibreNMS\Validator;
class Poller implements ValidationGroup
class Poller extends BaseValidation
{
/**
* Validate this module.
@@ -145,14 +144,4 @@ class Poller implements ValidationGroup
);
}
}
/**
* Returns if this test should be run by default or not.
*
* @return bool
*/
public function isDefault()
{
return true;
}
}

View File

@@ -26,10 +26,9 @@
namespace LibreNMS\Validations;
use LibreNMS\Config;
use LibreNMS\Interfaces\ValidationGroup;
use LibreNMS\Validator;
class Programs implements ValidationGroup
class Programs extends BaseValidation
{
/**
* Validate this module.
@@ -99,16 +98,11 @@ class Programs implements ValidationGroup
return Config::get($bin);
}
return is_executable(locate_binary($bin));
$located = locate_binary($bin);
if (is_executable($located)) {
return $located;
}
/**
* Returns if this test should be run by default or not.
*
* @return bool
*/
public function isDefault()
{
return true;
return false;
}
}

View File

@@ -26,10 +26,9 @@
namespace LibreNMS\Validations;
use LibreNMS\Config;
use LibreNMS\Interfaces\ValidationGroup;
use LibreNMS\Validator;
class Rrd implements ValidationGroup
class Rrd extends BaseValidation
{
/**
* Validate this module.
@@ -86,14 +85,4 @@ class Rrd implements ValidationGroup
}
}
}
/**
* Returns if this test should be run by default or not.
*
* @return bool
*/
public function isDefault()
{
return true;
}
}

View File

@@ -26,14 +26,15 @@
namespace LibreNMS\Validations;
use LibreNMS\Config;
use LibreNMS\Interfaces\ValidationGroup;
use LibreNMS\RRDRecursiveFilterIterator;
use LibreNMS\Validator;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
class RrdCheck implements ValidationGroup
class RrdCheck extends BaseValidation
{
protected static $RUN_BY_DEFAULT = false;
/**
* Validate this module.
* To return ValidationResults, call ok, warn, fail, or result methods on the $validator
@@ -79,14 +80,4 @@ class RrdCheck implements ValidationGroup
echo "\033[" . $screenpad . "D";
echo "Status: " . $loopcount . "/" . $rrd_total . " - Complete\n";
}
/**
* Returns if this test should be run by default or not.
*
* @return bool
*/
public function isDefault()
{
return false;
}
}

View File

@@ -29,11 +29,10 @@ use DateTime;
use DateTimeZone;
use Exception;
use LibreNMS\Config;
use LibreNMS\Interfaces\ValidationGroup;
use LibreNMS\ValidationResult;
use LibreNMS\Validator;
class Updates implements ValidationGroup
class Updates extends BaseValidation
{
public function validate(Validator $validator)
{
@@ -90,14 +89,4 @@ class Updates implements ValidationGroup
$validator->result($result);
}
}
/**
* Returns if this test should be run by default or not.
*
* @return bool
*/
public function isDefault()
{
return true;
}
}

View File

@@ -26,11 +26,10 @@
namespace LibreNMS\Validations;
use LibreNMS\Config;
use LibreNMS\Interfaces\ValidationGroup;
use LibreNMS\ValidationResult;
use LibreNMS\Validator;
class User implements ValidationGroup
class User extends BaseValidation
{
/**
* Validate this module.
@@ -99,16 +98,4 @@ class User implements ValidationGroup
$validator->fail("The log folder has improper permissions.", "chmod ug+rw $log_dir");
}
}
/**
* Returns if this test should be run by default or not.
*
* @return bool
*/
public function isDefault()
{
return true;
}
}

View File

@@ -25,6 +25,9 @@
namespace LibreNMS;
use LibreNMS\Interfaces\ValidationGroup;
use ReflectionClass;
class Validator
{
private $validation_groups = array();
@@ -40,16 +43,20 @@ class Validator
public function __construct()
{
// load all validations
$pattern = Config::get('install_dir') . '/LibreNMS/Validations/*.php';
$pattern = $this->getBaseDir() . '/LibreNMS/Validations/*.php';
foreach (glob($pattern) as $file) {
$class_name = basename($file, '.php');
$class = '\LibreNMS\Validations\\' . $class_name;
$rc = new ReflectionClass($class);
if (!$rc->isAbstract()) {
$validation_name = strtolower($class_name);
$this->validation_groups[$validation_name] = new $class();
$this->results[$validation_name] = array();
}
}
}
/**
@@ -61,11 +68,17 @@ class Validator
public function validate($validation_groups = array(), $print_group_status = false)
{
foreach ($this->validation_groups as $group_name => $group) {
// only run each group once
if ($group->isCompleted()) {
continue;
}
if ((empty($validation_groups) && $group->isDefault()) || in_array($group_name, $validation_groups)) {
if ($print_group_status && isCli()) {
echo "Checking $group_name:";
}
/** @var ValidationGroup $group */
$group->validate($this);
if (isCli()) {
@@ -76,6 +89,9 @@ class Validator
$this->printResults($group_name);
}
// validation is complete for this group
$group->markCompleted();
}
}
}
@@ -270,4 +286,9 @@ class Validator
$url = function_exists('get_url') ? get_url() : Config::get('base_url');
return rtrim(str_replace('validate', '', $url), '/'); // get base_url from current url
}
public function getBaseDir()
{
return realpath(__DIR__ . '/..');
}
}

View File

@@ -88,9 +88,9 @@ foreach ($validator->getAllResults() as $group => $results) {
if ($result->hasFix() || $result->hasList()) {
echo '<div class="panel-body">';
if ($result->hasFix()) {
echo '<code>' . linkify($result->getFix()) . '</code>';
echo 'Fix: <code>' . linkify($result->getFix()) . '</code>';
if ($result->hasList()) {
echo '<br />';
echo '<br /><br />';
}
}

View File

@@ -2420,12 +2420,15 @@ function locate_binary($binary)
{
if (!str_contains($binary, '/')) {
$output = `whereis -b $binary`;
$target = trim(substr($output, strpos($output, ':') + 1));
$list = trim(substr($output, strpos($output, ':') + 1));
$targets = explode(' ', $list);
if (file_exists($target)) {
foreach ($targets as $target) {
if (is_executable($target)) {
return $target;
}
}
}
return $binary;
}

View File

@@ -44,7 +44,7 @@ require_once $install_dir . '/includes/common.php';
if (!is_file($install_dir . '/vendor/autoload.php')) {
c_echo("%RError: Missing dependencies%n, run: %B./scripts/composer_wrapper.php install --no-dev%n\n\n");
}
require $install_dir . '/vendor/autoload.php';
require_once $install_dir . '/vendor/autoload.php';
if (!function_exists('module_selected')) {
function module_selected($module, $modules)

View File

@@ -14,10 +14,13 @@
*/
use LibreNMS\Config;
use LibreNMS\ValidationResult;
use LibreNMS\Validator;
chdir(__DIR__); // cwd to the directory containing this script
ini_set('display_errors', 1);
require_once 'includes/common.php';
require_once 'includes/functions.php';
require_once 'includes/dbFacile.php';
@@ -39,6 +42,7 @@ if (isset($options['h'])) {
Default groups:
- configuration: checks various config settings are correct
- database: checks the database for errors
- dependencies: checks that all required libraries are installed and up-to-date
- disk: checks for disk space and other disk related issues
- php: check that various PHP modules and functions exist
- poller: check that the poller and discovery are running properly
@@ -92,13 +96,12 @@ if (str_contains(`tail config.php`, '?>')) {
// Composer checks
if (!file_exists('vendor/autoload.php')) {
print_fail('Composer has not been run, dependencies are missing', 'composer install --no-dev');
$pre_checks_failed = true;
exit;
}
if (!str_contains(shell_exec('php scripts/composer_wrapper.php --version'), 'Composer version')) {
print_fail("No composer available, please install composer", "https://getcomposer.org/");
$pre_checks_failed = true;
}
// init autoloading
require_once 'vendor/autoload.php';
$dep_check = shell_exec('php scripts/composer_wrapper.php install --no-dev --dry-run');
preg_match_all('/Installing ([^ ]+\/[^ ]+) \(/', $dep_check, $dep_missing);
@@ -113,6 +116,12 @@ if (!empty($dep_outdated[0])) {
print_list($dep_outdated[1], "\t %s\n");
}
$validator = new Validator();
$validator->validate(array('dependencies'));
if ($validator->getGroupStatus('dependencies') == ValidationResult::FAILURE) {
$pre_checks_failed = true;
}
if ($pre_checks_failed) {
exit;
}
@@ -122,13 +131,11 @@ require 'includes/init.php';
// make sure install_dir is set correctly, or the next includes will fail
if (!file_exists(Config::get('install_dir').'/config.php')) {
$suggested = realpath(__DIR__ . '/../..');
$suggested = realpath(__DIR__);
print_fail('$config[\'install_dir\'] is not set correctly.', "It should probably be set to: $suggested");
exit;
}
$validator = new Validator();
// Connect to MySQL
try {
@@ -160,7 +167,7 @@ $validator->validate($modules, isset($options['s'])||!empty($modules));
function print_header($versions)
{
$output = ob_get_clean();
ob_end_clean();
@ob_end_clean();
echo <<< EOF
====================================