From cbfbb3a1623755ab3bd1ddc277e119df7562a01b Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Tue, 7 Nov 2017 12:51:31 +0100 Subject: [PATCH] Handle enabled, but deleted modules properly refs #2811 --- application/clicommands/ModuleCommand.php | 4 +- application/controllers/ConfigController.php | 3 +- .../views/scripts/config/modules.phtml | 4 +- .../Icinga/Application/Modules/Manager.php | 48 +++++++++---------- 4 files changed, 32 insertions(+), 27 deletions(-) diff --git a/application/clicommands/ModuleCommand.php b/application/clicommands/ModuleCommand.php index 8cc470dad..cd3390404 100644 --- a/application/clicommands/ModuleCommand.php +++ b/application/clicommands/ModuleCommand.php @@ -78,7 +78,9 @@ class ModuleCommand extends Command "%-14s %-9s %-9s %s\n", $module, $mod->getVersion(), - ($type === 'enabled' || $this->modules->hasEnabled($module)) ? 'enabled' : 'disabled', + ($type === 'enabled' || $this->modules->hasEnabled($module)) + ? $this->modules->hasInstalled($module) ? 'enabled' : 'dangling' + : 'disabled', $dir ); } diff --git a/application/controllers/ConfigController.php b/application/controllers/ConfigController.php index 997c6a708..fe25e7ca3 100644 --- a/application/controllers/ConfigController.php +++ b/application/controllers/ConfigController.php @@ -102,6 +102,7 @@ class ConfigController extends Controller $this->view->modules = Icinga::app()->getModuleManager()->select() ->from('modules') ->order('enabled', 'desc') + ->order('installed', 'asc') ->order('name'); $this->setupLimitControl(); $this->setupPaginationControl($this->view->modules); @@ -113,7 +114,7 @@ class ConfigController extends Controller $app = Icinga::app(); $manager = $app->getModuleManager(); $name = $this->getParam('name'); - if ($manager->hasInstalled($name)) { + if ($manager->hasInstalled($name) || $manager->hasEnabled($name)) { $this->view->moduleData = $manager->select()->from('modules')->where('name', $name)->fetchRow(); if ($manager->hasLoaded($name)) { $module = $manager->getModule($name); diff --git a/application/views/scripts/config/modules.phtml b/application/views/scripts/config/modules.phtml index d2fe2d6b2..b7722ce55 100644 --- a/application/views/scripts/config/modules.phtml +++ b/application/views/scripts/config/modules.phtml @@ -15,7 +15,9 @@ - enabled && $module->loaded) { + installed) { + $this->icon('flash', sprintf($this->translate('Module %s is dangling'), $module->name)); + } elseif ($module->enabled && $module->loaded) { echo $this->icon('thumbs-up', sprintf($this->translate('Module %s is enabled'), $module->name)); } elseif (! $module->enabled) { echo $this->icon('block', sprintf($this->translate('Module %s is disabled'), $module->name)); diff --git a/library/Icinga/Application/Modules/Manager.php b/library/Icinga/Application/Modules/Manager.php index 72905441e..3c754d661 100644 --- a/library/Icinga/Application/Modules/Manager.php +++ b/library/Icinga/Application/Modules/Manager.php @@ -158,17 +158,19 @@ class Manager } $dir = realpath($link); - if (! file_exists($dir) || !is_dir($dir)) { + if ($dir !== false && is_dir($dir)) { + $this->enabledDirs[$file] = $dir; + } else { + $this->enabledDirs[$file] = null; + Logger::warning( 'Found invalid module in enabledModule directory "%s": "%s" points to non existing path "%s"', $this->enableDir, $link, $dir ); - continue; } - $this->enabledDirs[$file] = $dir; ksort($this->enabledDirs); } closedir($dh); @@ -329,12 +331,6 @@ class Manager } $link = $this->enableDir . DIRECTORY_SEPARATOR . $name; - if (! file_exists($link)) { - throw new ConfigurationError( - 'Cannot disable module "%s". Module is not installed.', - $name - ); - } if (! is_link($link)) { throw new ConfigurationError( 'Cannot disable module %s at %s. ' @@ -346,7 +342,7 @@ class Manager ); } - if (file_exists($link) && is_link($link)) { + if (is_link($link)) { if (! @unlink($link)) { $error = error_get_last(); throw new SystemPermissionException( @@ -471,6 +467,7 @@ class Manager * Each entry has the following fields * * name, name of the module as a string * * path, path where the module is located as a string + * * installed, whether the module is installed or not as a boolean * * enabled, whether the module is enabled or not as a boolean * * loaded, whether the module is loaded or not as a boolean * @@ -480,25 +477,28 @@ class Manager { $info = array(); - $enabled = $this->listEnabledModules(); - foreach ($enabled as $name) { - $info[$name] = (object) array( - 'name' => $name, - 'path' => $this->enabledDirs[$name], - 'enabled' => true, - 'loaded' => $this->hasLoaded($name) - ); - } - $installed = $this->listInstalledModules(); foreach ($installed as $name) { $info[$name] = (object) array( - 'name' => $name, - 'path' => $this->installedBaseDirs[$name], - 'enabled' => $this->hasEnabled($name), - 'loaded' => $this->hasLoaded($name) + 'name' => $name, + 'path' => $this->installedBaseDirs[$name], + 'installed' => true, + 'enabled' => $this->hasEnabled($name), + 'loaded' => $this->hasLoaded($name) ); } + + $enabled = $this->listEnabledModules(); + foreach ($enabled as $name) { + $info[$name] = (object) array( + 'name' => $name, + 'path' => $this->enabledDirs[$name], + 'installed' => $this->enabledDirs[$name] !== null, + 'enabled' => true, + 'loaded' => $this->hasLoaded($name) + ); + } + return $info; }