Add support for multiple module installation paths

Read the module paths from the configuration file and add form fields
to edit the path from the web interface.

refs #4607
This commit is contained in:
Matthias Jentsch 2014-01-22 18:21:05 +01:00
parent bb1c560e22
commit 5d8081ad09
4 changed files with 57 additions and 18 deletions

View File

@ -203,13 +203,22 @@ class GeneralForm extends Form
array(
'label' => 'Module Folder',
'required' => true,
'helptext' => 'The moduleFolder directive is currently not used anywhere but '
. 'configureable via the frontend and INI. With feature #4607 moduleFolder '
. 'will be replaced with a configuration directive for locations of '
. 'installed modules',
'helptext' => 'The directory that contains the symlink to all enabled directories.',
'value' => $cfg->get('moduleFolder', $this->getConfigDir() . '/config/enabledModules')
)
);
$this->addElement(
'text',
'module_path',
array(
'label' => 'Module Path',
'required' => true,
'helptext' => 'Contains the directories that will be searched for available modules, separated by ' .
' colons. Modules that don\'t exist in these directories can still be symlinked in the module ' .
' folder, but won\'t show up in the list of disabled modules.',
'value' => $cfg->get('modulePath', realpath(ICINGA_APPDIR . '/../modules'))
)
);
}
/**
@ -382,9 +391,11 @@ class GeneralForm extends Form
$cfg->global->environment = ($values['environment'] == 1) ? 'development' : 'production';
$cfg->global->timezone = $values['timezone'];
$cfg->global->moduleFolder = $values['module_folder'];
$cfg->global->modulePath = $values['module_path'];
$cfg->global->dateFormat = $values['date_format'];
$cfg->global->timeFormat = $values['time_format'];
$cfg->preferences->type = $values['preferences_type'];
if ($cfg->preferences->type === 'ini') {
$cfg->preferences->configPath = $values['preferences_ini_path'];

View File

@ -3,14 +3,16 @@ environment = "development"
timezone = "Europe/Berlin"
indexModule = "monitoring"
indexController = "dashboard"
; The moduleFolder directive is currently not used anywhere but configureable
; via the frontend and this file. With feature #4607 moduleFolder will
; be replaced with a configuration directive for locations of
; installed modules
moduleFolder = "@icingaweb_config_path@/enabledModules"
dateFormat = "d/m/Y"
timeFormat = "g:i A"
; The directory that contains the symlinks to all enabled directories.
moduleFolder = "@icingaweb_config_path@/enabledModules"
; Contains the directories that will be searched for available modules. Modules that
; don't exist in these directories can still be symlinked in the module folder, but
; won't show up in the list of disabled modules.
; modulePath = "/vagrant/modules:/usr/share/icingaweb/modules"
[logging]
; General log

View File

@ -354,6 +354,11 @@ abstract class ApplicationBootstrap
*/
protected function loadEnabledModules()
{
$this->moduleManager = new ModuleManager(
$this,
$this->config->global->get('moduleFolder', $this->getConfigDir() . '/enabledModules'),
explode(':', $this->config->global->get('modulePath', ICINGA_APPDIR . '/../modules'))
);
try {
$this->moduleManager->loadEnabledModules();
} catch (Exception $e) {
@ -362,7 +367,6 @@ abstract class ApplicationBootstrap
$e->getMessage()
);
}
return $this;
}

View File

@ -104,11 +104,16 @@ class Manager
$this->app = $app;
if (empty($availableDirs)) {
$availableDirs = array(realpath(ICINGA_APPDIR . '/../modules'));
} else {
foreach($availableDirs as $key => $dir) {
$dir[$key] = realpath($dir);
}
}
$this->modulePaths = $availableDirs;
if ($enabledDir === null) {
$enabledDir = $this->app->getConfigDir() . '/enabledModules';
}
$enabledDir = realpath($enabledDir);
$this->enableDir = $enabledDir;
}
@ -293,7 +298,7 @@ class Manager
'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. '
. 'In order to dynamically enable and disable modules, you have to create a symlink to '
. 'the enabled_modules folder'
. 'the enabled_modules folder.'
);
}
@ -424,15 +429,21 @@ class Manager
*/
public function getModuleInfo()
{
$installed = $this->listInstalledModules();
$info = array();
if ($installed === null) {
return $info;
$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[] = (object) array(
$info[$name] = (object) array(
'name' => $name,
'path' => $this->installedBaseDirs[$name],
'enabled' => $this->hasEnabled($name),
@ -496,17 +507,28 @@ class Manager
public function detectInstalledModules()
{
foreach ($this->modulePaths as $basedir) {
if (!file_exists($basedir)) {
Logger::warn('Module path "%s" does not exist.', $basedir);
continue;
}
$fh = opendir($basedir);
if ($fh === false) {
return $this;
}
while ($name = readdir($fh)) {
if ($name[0] === '.') {
continue;
}
if (is_dir($basedir . '/' . $name)) {
$this->installedBaseDirs[$name] = $basedir . '/' . $name;
if (!array_key_exists($name, $this->installedBaseDirs)) {
$this->installedBaseDirs[$name] = $basedir . '/' . $name;
} else {
Logger::warn(
'Module "%s" already exists in installation path "%s" and is ignored.',
$basedir . '/' . $name,
$this->installedBaseDirs[$name]
);
}
}
}
}