Skip to content

Commit

Permalink
Move Config loading to a service provider (librenms#13927)
Browse files Browse the repository at this point in the history
* Move Config loading to a service provider
That way other service providers can depend on it
Move various random listener registrations into the EventServiceProvider
Various startup cleanup

* Config::persist Set live variable before persisting incase db update fail

* Disable strict mode for legacy code (init.php)

* Disable debug after os test data is gathered

* remove Eloquent::boot it is never used

* remove Eloquent::version

* lint fixes

* style fixes

* there is no c_echo here
  • Loading branch information
murrant authored Apr 23, 2022
1 parent d4479e1 commit 0142136
Show file tree
Hide file tree
Showing 23 changed files with 251 additions and 352 deletions.
14 changes: 2 additions & 12 deletions LibreNMS/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use LibreNMS\Data\Store\Rrd;
use LibreNMS\DB\Eloquent;
use LibreNMS\Util\Debug;
use LibreNMS\Util\Version;
use Log;
Expand Down Expand Up @@ -254,11 +253,11 @@ public static function set($key, $value)
public static function persist($key, $value)
{
try {
Arr::set(self::$config, $key, $value);
\App\Models\Config::updateOrCreate(['config_name' => $key], [
'config_name' => $key,
'config_value' => $value,
]);
Arr::set(self::$config, $key, $value);

// delete any children (there should not be any unless it is legacy)
\App\Models\Config::query()->where('config_name', 'like', "$key.%")->delete();
Expand Down Expand Up @@ -338,10 +337,6 @@ public static function getAll()
*/
private static function loadDB()
{
if (! Eloquent::isConnected()) {
return;
}

try {
\App\Models\Config::get(['config_name', 'config_value'])
->each(function ($item) {
Expand Down Expand Up @@ -462,15 +457,10 @@ private static function processConfig()
self::persist('device_display_default', $display_value);
}

$persist = Eloquent::isConnected();
// make sure we have full path to binaries in case PATH isn't set
foreach (['fping', 'fping6', 'snmpgetnext', 'rrdtool', 'traceroute', 'traceroute6'] as $bin) {
if (! is_executable(self::get($bin))) {
if ($persist) {
self::persist($bin, self::locateBinary($bin));
} else {
self::set($bin, self::locateBinary($bin));
}
self::persist($bin, self::locateBinary($bin));
}
}

Expand Down
89 changes: 27 additions & 62 deletions LibreNMS/DB/Eloquent.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,59 +25,19 @@

namespace LibreNMS\DB;

use Dotenv\Dotenv;
use Illuminate\Database\Capsule\Manager as Capsule;
use Illuminate\Database\Events\StatementPrepared;
use Illuminate\Events\Dispatcher;
use Illuminate\Support\Arr;
use DB;
use Illuminate\Database\Connection;
use LibreNMS\Util\Laravel;
use PDOException;

class Eloquent
{
/** @var Capsule static reference to capsule */
private static $capsule;

public static function boot()
{
// boot Eloquent outside of Laravel
if (! Laravel::isBooted() && is_null(self::$capsule)) {
$install_dir = realpath(__DIR__ . '/../../');

Dotenv::createMutable($install_dir)->load();

$db_config = include $install_dir . '/config/database.php';
$settings = $db_config['connections'][$db_config['default']];

self::$capsule = new Capsule;
self::$capsule->addConnection($settings);
self::$capsule->setEventDispatcher(new Dispatcher());
self::$capsule->setAsGlobal();
self::$capsule->bootEloquent();
}

self::initLegacyListeners();
self::setStrictMode(false); // set non-strict mode if for legacy code
}

public static function initLegacyListeners()
{
if (self::isConnected()) {
// set FETCH_ASSOC for queries that required by setting the global variable $PDO_FETCH_ASSOC (for dbFacile)
self::DB()->getEventDispatcher()->listen(StatementPrepared::class, function ($event) {
global $PDO_FETCH_ASSOC;
if ($PDO_FETCH_ASSOC) {
$event->statement->setFetchMode(\PDO::FETCH_ASSOC);
}
});
}
}

/**
* Set the strict mode for the current connection (will not persist)
*
* @param bool $strict
*/
public static function setStrictMode($strict = true)
public static function setStrictMode(bool $strict = true): void
{
if (self::isConnected() && self::getDriver() == 'mysql') {
if ($strict) {
Expand All @@ -88,14 +48,16 @@ public static function setStrictMode($strict = true)
}
}

public static function isConnected($name = null)
public static function isConnected(?string $name = null): bool
{
try {
$conn = self::DB($name);
if ($conn) {
return ! is_null($conn->getPdo());
$conn->getPdo();

return true;
}
} catch (\PDOException $e) {
} catch (PDOException $e) {
return false;
}

Expand All @@ -105,31 +67,39 @@ public static function isConnected($name = null)
/**
* Access the Database Manager for Fluent style queries. Like the Laravel DB facade.
*
* @param string $name
* @param string|null $name
* @return \Illuminate\Database\Connection|null
*/
public static function DB($name = null)
public static function DB(?string $name = null): ?Connection
{
// check if Laravel is booted
if (Laravel::isBooted()) {
return \DB::connection($name);
return DB::connection($name);
}

if (is_null(self::$capsule)) {
return null;
}

return self::$capsule->getDatabaseManager()->connection($name);
return null;
}

public static function getDriver()
public static function getDriver(): ?string
{
$connection = config('database.default');

return config("database.connections.{$connection}.driver");
}

public static function setConnection($name, $db_host = null, $db_user = '', $db_pass = '', $db_name = '', $db_port = null, $db_socket = null)
/**
* Set the active connection, used during install
*
* @param string $name
* @param string $db_host
* @param string $db_user
* @param string $db_pass
* @param string $db_name
* @param int|string $db_port
* @param string $db_socket
* @return void
*/
public static function setConnection($name, $db_host = null, $db_user = '', $db_pass = '', $db_name = '', $db_port = null, $db_socket = null): void
{
\Config::set("database.connections.$name", [
'driver' => 'mysql',
Expand All @@ -147,9 +117,4 @@ public static function setConnection($name, $db_host = null, $db_user = '', $db_
]);
\Config::set('database.default', $name);
}

public static function version($name = null)
{
return Arr::first(self::DB($name)->selectOne('select version()'));
}
}
2 changes: 1 addition & 1 deletion LibreNMS/IRCBot.php
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ private function chkdb()
{
if (! Eloquent::isConnected()) {
try {
Eloquent::boot();
Eloquent::DB()->statement('SELECT VERSION()');
} catch (\PDOException $e) {
$this->log('Cannot connect to MySQL: ' . $e->getMessage());

Expand Down
3 changes: 2 additions & 1 deletion LibreNMS/Poller.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
use LibreNMS\Util\Dns;
use LibreNMS\Util\Git;
use LibreNMS\Util\StringHelpers;
use LibreNMS\Util\Version;
use Psr\Log\LoggerInterface;
use Throwable;

Expand Down Expand Up @@ -371,7 +372,7 @@ private function printHeader(): void
Git::localDate(),
vsprintf('%s (%s)', $version->database()),
phpversion(),
\LibreNMS\DB\Eloquent::isConnected() ? \LibreNMS\DB\Eloquent::version() : '?',
Version::get()->databaseServer(),
$version->rrdtool(),
$version->netSnmp()
));
Expand Down
51 changes: 13 additions & 38 deletions LibreNMS/Util/Debug.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,16 @@
namespace LibreNMS\Util;

use App;
use Illuminate\Database\Events\QueryExecuted;
use LibreNMS\DB\Eloquent;
use Log;

class Debug
{
/**
* @var bool
*/
/** @var bool */
private static $debug = false;
/**
* @var bool
*/
/** @var bool */
private static $verbose = false;
/** @var bool */
private static $sql_debug_enabled = false;

/**
* Enable/disable debug output
Expand All @@ -52,8 +48,6 @@ public static function set($debug = true, bool $silence = false): bool
{
self::$debug = (bool) $debug;

restore_error_handler(); // disable Laravel error handler

if (self::$debug) {
self::enableErrorReporting();
self::enableCliDebugOutput();
Expand Down Expand Up @@ -92,18 +86,15 @@ public static function isVerbose(): bool

public static function disableQueryDebug(): void
{
$db = Eloquent::DB();

if ($db) {
// remove all query executed event handlers
$db->getEventDispatcher()->flush('Illuminate\Database\Events\QueryExecuted');
}
self::$sql_debug_enabled = false;
}

public static function enableCliDebugOutput(): void
{
if (Laravel::isBooted() && App::runningInConsole()) {
Log::setDefaultDriver('console_debug');
} else {
putenv('LOG_CHANNEL=console_debug');
}
}

Expand All @@ -116,28 +107,12 @@ public static function disableCliDebugOutput(bool $silence): void

public static function enableQueryDebug(): void
{
static $sql_debug_enabled;
$db = Eloquent::DB();

if ($db && ! $sql_debug_enabled) {
$db->listen(function (QueryExecuted $query) {
// collect bindings and make them a little more readable
$bindings = collect($query->bindings)->map(function ($item) {
if ($item instanceof \Carbon\Carbon) {
return $item->toDateTimeString();
}

return $item;
})->toJson();

if (Laravel::isBooted()) {
Log::debug("SQL[%Y{$query->sql} %y$bindings%n {$query->time}ms] \n", ['color' => true]);
} else {
c_echo("SQL[%Y{$query->sql} %y$bindings%n {$query->time}ms] \n");
}
});
$sql_debug_enabled = true;
}
self::$sql_debug_enabled = true;
}

public static function queryDebugIsEnabled(): bool
{
return self::$sql_debug_enabled;
}

/**
Expand Down
4 changes: 3 additions & 1 deletion LibreNMS/Util/Version.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@

namespace LibreNMS\Util;

use DB;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Support\Arr;
use LibreNMS\Config;
use LibreNMS\DB\Eloquent;
use Symfony\Component\Process\Process;
Expand Down Expand Up @@ -100,7 +102,7 @@ public function remoteCommit(): array

public function databaseServer(): string
{
return \LibreNMS\DB\Eloquent::isConnected() ? \LibreNMS\DB\Eloquent::version() : 'Not Connected';
return Eloquent::isConnected() ? Arr::first(DB::selectOne('select version()')) : 'Not Connected';
}

public function database(): array
Expand Down
2 changes: 1 addition & 1 deletion LibreNMS/Validations/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ private function checkSchemaVersion(Validator $validator): bool

private function checkVersion(Validator $validator)
{
$version = Eloquent::version();
$version = \LibreNMS\Util\Version::get()->databaseServer();
$version = explode('-', $version);

if (isset($version[1]) && $version[1] == 'MariaDB') {
Expand Down
3 changes: 1 addition & 2 deletions app/Http/Controllers/AboutController.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
use Illuminate\Http\Request;
use LibreNMS\Config;
use LibreNMS\Data\Store\Rrd;
use LibreNMS\DB\Eloquent;
use LibreNMS\Util\Version;

class AboutController extends Controller
Expand All @@ -73,7 +72,7 @@ public function index(Request $request)
'project_name' => Config::get('project_name'),

'version_local' => $version->local(),
'version_mysql' => Eloquent::version(),
'version_mysql' => $version->databaseServer(),
'version_php' => phpversion(),
'version_laravel' => App::VERSION(),
'version_python' => $version->python(),
Expand Down
19 changes: 0 additions & 19 deletions app/Http/Controllers/Auth/SocialiteController.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,10 @@
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Event;
use Laravel\Socialite\Contracts\User as SocialiteUser;
use Laravel\Socialite\Facades\Socialite;
use LibreNMS\Config as LibreNMSConfig;
use LibreNMS\Exceptions\AuthenticationException;
use Log;

class SocialiteController extends Controller
{
Expand All @@ -45,23 +43,6 @@ public function __construct()
$this->injectConfig();
}

public static function registerEventListeners(): void
{
foreach (LibreNMSConfig::get('auth.socialite.configs', []) as $provider => $config) {
// Treat not set as "disabled"
if (! isset($config['listener'])) {
continue;
}
$listener = $config['listener'];

if (class_exists($listener)) {
Event::listen(\SocialiteProviders\Manager\SocialiteWasCalled::class, "$listener@handle");
} else {
Log::error("Wrong value for auth.socialite.configs.$provider.listener set, class: '$listener' does not exist!");
}
}
}

/**
* @return RedirectResponse|\Symfony\Component\HttpFoundation\Response
*/
Expand Down
Loading

0 comments on commit 0142136

Please sign in to comment.