Module enable/disable: Better error messages

refs #4604
This commit is contained in:
Marius Hein 2013-08-29 17:44:02 +02:00
parent 439fade88d
commit b6eb19ce6a
3 changed files with 87 additions and 39 deletions

View File

@ -141,12 +141,19 @@ class ConfigController extends BaseConfigController
*/ */
public function moduleenableAction() public function moduleenableAction()
{ {
$module = $this->_getParam('name'); $module = $this->getParam('name');
$manager = Icinga::app()->getModuleManager(); $manager = Icinga::app()->getModuleManager();
$manager->enableModule($module); try {
$manager->loadModule($module); $manager->enableModule($module);
$this->view->successMessage = 'Module "' . $module . '" enabled'; $manager->loadModule($module);
$this->moduleoverviewAction(); $this->view->successMessage = 'Module "' . $module . '" enabled';
$this->moduleoverviewAction();
} catch (Exception $e) {
$this->view->exceptionMessage = $e->getMessage();
$this->view->moduleName = $module;
$this->view->action = 'enable';
$this->render('module-configuration-error');
}
} }
/** /**
@ -154,11 +161,18 @@ class ConfigController extends BaseConfigController
*/ */
public function moduledisableAction() public function moduledisableAction()
{ {
$module = $this->_getParam('name'); $module = $this->getParam('name');
$manager = Icinga::app()->getModuleManager(); $manager = Icinga::app()->getModuleManager();
$manager->disableModule($module); try {
$this->view->successMessage = 'Module "' . $module . '" disabled'; $manager->disableModule($module);
$this->moduleoverviewAction(); $this->view->successMessage = 'Module "' . $module . '" disabled';
$this->moduleoverviewAction();
} catch (Exception $e) {
$this->view->exceptionMessage = $e->getMessage();
$this->view->moduleName = $module;
$this->view->action = 'disable';
$this->render('module-configuration-error');
}
} }
/** /**

View File

@ -0,0 +1,28 @@
<?php
$action = (isset($this->action)) ? $this->action : 'do something with';
$moduleName = $this->moduleName;
$exceptionMessage = $this->exceptionMessage;
?>
<?= $this->tabs->render($this); ?>
<br/>
<div class="alert alert-error">
<h1>Could not <?= $action; ?> module "<?= $moduleName; ?>"</h1>
<p>
While operation the following error occurred:
<br />
<?= $exceptionMessage; ?>
</p>
</div>
<p>
This could have one or more of the following reasons:
<ul>
<li>No file permissions to write into module directory</li>
<li>Errors on filesystems: Mount points, operational errors </li>
<li>General application error</li>
</ul>
</p>
<p>
Details can be seen in your application log (if you don't have access to this file, call your administrator in this case).
</p>

View File

@ -51,8 +51,6 @@ class Manager
/** /**
* Array of all installed module's base directories * Array of all installed module's base directories
* *
* null if modules haven't been scanned yet
*
* @var array * @var array
*/ */
private $installedBaseDirs = array(); private $installedBaseDirs = array();
@ -104,12 +102,11 @@ class Manager
{ {
$this->app = $app; $this->app = $app;
if (empty($availableDirs)) { if (empty($availableDirs)) {
$availableDirs = array(ICINGA_APPDIR."/../modules"); $availableDirs = array(ICINGA_APPDIR . '/../modules');
} }
$this->modulePaths = $availableDirs; $this->modulePaths = $availableDirs;
if ($enabledDir === null) { if ($enabledDir === null) {
$enabledDir = $this->app->getConfig()->getConfigDir() $enabledDir = $this->app->getConfigDir() . '/enabledModules';
. '/enabledModules';
} }
$this->prepareEssentials($enabledDir); $this->prepareEssentials($enabledDir);
$this->detectEnabledModules(); $this->detectEnabledModules();
@ -119,7 +116,7 @@ class Manager
* Set the module dir and checks for existence * Set the module dir and checks for existence
* *
* @param string $moduleDir The module directory to set for the module manager * @param string $moduleDir The module directory to set for the module manager
* @throws \Icinga\Exception\ProgrammingError * @throws ProgrammingError
*/ */
private function prepareEssentials($moduleDir) private function prepareEssentials($moduleDir)
{ {
@ -228,29 +225,29 @@ class Manager
/** /**
* Set the given module to the enabled state * Set the given module to the enabled state
* *
* @param string $name The module to enable * @param string $name The module to enable
* *
* @return self * @return self
* @throws ConfigurationError When trying to enable a module that is not installed * @throws ConfigurationError When trying to enable a module that is not installed
* @throws SystemPermissionException When insufficient permissions for the application exist * @throws SystemPermissionException When insufficient permissions for the application exist
*/ */
public function enableModule($name) public function enableModule($name)
{ {
if (!$this->hasInstalled($name)) { if (!$this->hasInstalled($name)) {
throw new ConfigurationError( throw new ConfigurationError(
sprintf( sprintf(
"Cannot enable module '%s' as it isn't installed", 'Cannot enable module "%s". Module is not installed.',
$name $name
) )
); );
return $this;
} }
clearstatcache(true); clearstatcache(true);
$target = $this->installedBaseDirs[$name]; $target = $this->installedBaseDirs[$name];
$link = $this->enableDir . '/' . $name; $link = $this->enableDir . '/' . $name;
if (!is_writable($this->enableDir)) { if (!is_writable($this->enableDir)) {
throw new SystemPermissionException( throw new SystemPermissionException(
"Insufficient system permissions for enabling modules" 'Can not enable module "' . $name . '". '
. 'Insufficient system permissions for enabling modules.'
); );
} }
if (file_exists($link) && is_link($link)) { if (file_exists($link) && is_link($link)) {
@ -259,7 +256,11 @@ class Manager
if (!@symlink($target, $link)) { if (!@symlink($target, $link)) {
$error = error_get_last(); $error = error_get_last();
if (strstr($error["message"], "File exists") === false) { if (strstr($error["message"], "File exists") === false) {
throw new SystemPermissionException($error["message"]); throw new SystemPermissionException(
'Could not enable module "' . $name . '" due to file system errors. '
. 'Please check path and mounting points because this is not a permission error. '
. 'Primary error was: ' . $error['message']
);
} }
} }
$this->enabledDirs[$name] = $link; $this->enabledDirs[$name] = $link;
@ -269,12 +270,12 @@ class Manager
/** /**
* Disable the given module and remove it's enabled state * Disable the given module and remove it's enabled state
* *
* @param string $name The name of the module to disable * @param string $name The name of the module to disable
* *
* @return self * @return self
* *
* @throws ConfigurationError When the module is not installed or it's not symlinked * @throws ConfigurationError When the module is not installed or it's not a symlink
* @throws SystemPermissionException When the module can't be disabled * @throws SystemPermissionException When the module can't be disabled
*/ */
public function disableModule($name) public function disableModule($name)
{ {
@ -282,15 +283,17 @@ class Manager
return $this; return $this;
} }
if (!is_writable($this->enableDir)) { if (!is_writable($this->enableDir)) {
throw new SystemPermissionException("Can't write the module directory"); throw new SystemPermissionException(
'Could not disable module. Module path is not writable.'
);
} }
$link = $this->enableDir . '/' . $name; $link = $this->enableDir . '/' . $name;
if (!file_exists($link)) { if (!file_exists($link)) {
throw new ConfigurationError('The module ' . $name . ' could not be found, can\'t disable it'); throw new ConfigurationError('Could not disable module. The module ' . $name . ' was not found.');
} }
if (!is_link($link)) { if (!is_link($link)) {
throw new ConfigurationError( throw new ConfigurationError(
'The module ' . $name . ' can\'t be disabled as this would delete the whole module. ' 'Could not disable module. The module "' . $name . '" is not a symlink. '
. 'It looks like you have installed this module manually and moved it to your module folder. ' . 'It looks like you have installed this module manually and moved it to your module folder. '
. 'In order to dynamically enable and disable modules, you have to create a symlink to ' . 'In order to dynamically enable and disable modules, you have to create a symlink to '
. 'the enabled_modules folder' . 'the enabled_modules folder'
@ -300,11 +303,14 @@ class Manager
if (file_exists($link) && is_link($link)) { if (file_exists($link) && is_link($link)) {
if (!@unlink($link)) { if (!@unlink($link)) {
$error = error_get_last(); $error = error_get_last();
throw new SystemPermissionException($error['message']); throw new SystemPermissionException(
'Could not disable module "' . $name . '" due to file system errors. '
. 'Please check path and mounting points because this is not a permission error. '
. 'Primary error was: ' . $error['message']
);
} }
} else {
} }
unset($this->enabledDirs[$name]); unset($this->enabledDirs[$name]);
return $this; return $this;
} }
@ -317,7 +323,7 @@ class Manager
* *
* @return string * @return string
* *
* @throws \Icinga\Exception\ProgrammingError When the module is not installed or existing * @throws ProgrammingError When the module is not installed or existing
*/ */
public function getModuleDir($name, $subdir = '') public function getModuleDir($name, $subdir = '')
{ {
@ -380,8 +386,7 @@ class Manager
* Return an array containing all loaded modules * Return an array containing all loaded modules
* *
* @return array * @return array
* * @see Module
* @see \Icinga\Application\Modules\Module
*/ */
public function getLoadedModules() public function getLoadedModules()
{ {
@ -391,11 +396,10 @@ class Manager
/** /**
* Return the module instance of the given module when it is loaded * Return the module instance of the given module when it is loaded
* *
* @param string $name The module name to return * @param string $name The module name to return
* *
* @return \Icinga\Application\Modules\Module * @return Module
* * @throws ProgrammingError When the module hasn't been loaded
* @throws \Icinga\Exception\ProgrammingError When the module hasn't been loaded
*/ */
public function getModule($name) public function getModule($name)
{ {
@ -462,7 +466,7 @@ class Manager
} }
/** /**
* Return an array containing all installled module names as strings * Return an array of module names from installed modules
* *
* Calls detectInstalledModules() if no module discovery has been performed yet * Calls detectInstalledModules() if no module discovery has been performed yet
* *
@ -479,6 +483,8 @@ class Manager
if (count($this->installedBaseDirs)) { if (count($this->installedBaseDirs)) {
return array_keys($this->installedBaseDirs); return array_keys($this->installedBaseDirs);
} }
return array();
} }
/** /**