Add clearstatcache and tests for ModuleManager

Added the clearstatcache call before enabling or disabling modules,
as this prevents a 'File exists' error that occurs sometimes on
symlink creation (even when the folder is empty). Also added tests
for teh moduleManager

refs #4092
This commit is contained in:
Jannis Moßhammer 2013-06-20 17:01:13 +02:00 committed by Marius Hein
parent 8b84de934a
commit 81bbee7e24
1 changed files with 46 additions and 30 deletions

View File

@ -2,33 +2,39 @@
namespace Icinga\Application\Modules;
use Icinga\Application\ApplicationBootstrap;
use Icinga\Data\ArrayDatasource;
use Icinga\Web\Notification;
use Icinga\Exception\ConfigurationError;
use Icinga\Exception\SystemPermissionException;
use Icinga\Exception\ProgrammingError;
// TODO: show whether enabling/disabling modules is allowed by checking enableDir
// perms
class Manager
{
protected $installedBaseDirs;
protected $installedBaseDirs = null;
protected $enabledDirs = array();
protected $loadedModules = array();
protected $index;
protected $app;
protected $enableDir;
public function __construct(ApplicationBootstrap $app, $dir = null)
protected $modulePaths = array();
/**
* @param $app : The applicaiton bootstrap. This one needs a properly defined interface
* In order to test it correctly, the application now only requires a stdClass
* @param $dir :
**/
public function __construct($app, $enabledDir = null, array $availableDirs = array())
{
$this->app = $app;
if ($dir === null) {
$dir = $this->app->getConfig()->getConfigDir()
if (empty($availableDirs)) {
$availableDirs = array(ICINGA_APPDIR."/../modules");
}
$this->modulePaths = $availableDirs;
if ($enabledDir === null) {
$enabledDir = $this->app->getConfig()->getConfigDir()
. '/enabledModules';
}
$this->prepareEssentials($dir);
$this->prepareEssentials($enabledDir);
$this->detectEnabledModules();
}
@ -46,10 +52,17 @@ class Manager
}
}
public function select()
{
$source = new \Icinga\Data\ArrayDataSource($this->getModuleInfo());
return $source->select();
}
protected function detectEnabledModules()
{
$fh = opendir($this->enableDir);
$this->enabledDirs = array();
while (false !== ($file = readdir($fh))) {
if ($file[0] === '.') {
@ -78,12 +91,18 @@ class Manager
return $this;
}
public function loadModule($name)
public function loadModule($name, $moduleBase = null)
{
if ($this->hasLoaded($name)) {
return $this;
}
$module = new Module($this->app, $name, $this->getModuleDir($name));
$module = null;
if ($moduleBase === null) {
$module = new Module($this->app, $name, $this->getModuleDir($name));
} else {
$module = new $moduleBase($this->app, $name, $this->getModuleDir($name));
}
$module->register();
$this->loadedModules[$name] = $module;
return $this;
@ -100,6 +119,7 @@ class Manager
);
return $this;
}
clearstatcache(true);
$target = $this->installedBaseDirs[$name];
$link = $this->enableDir . '/' . $name;
if (! is_writable($this->enableDir)) {
@ -118,6 +138,7 @@ class Manager
throw new SystemPermissionException($error["message"], "symlink", $link);
}
}
$this->enabledDirs[$name] = $link;
return $this;
}
@ -151,6 +172,7 @@ class Manager
} else {
}
unset($this->enabledDirs[$name]);
return $this;
}
@ -228,12 +250,6 @@ class Manager
return $info;
}
public function select()
{
$ds = new ArrayDatasource($this->getModuleInfo());
return $ds->select();
}
public function listEnabledModules()
{
return array_keys($this->enabledDirs);
@ -254,19 +270,19 @@ class Manager
public function detectInstalledModules()
{
// TODO: Allow multiple paths for installed modules (e.g. web vs pkg)
$basedir = realpath(ICINGA_APPDIR . '/../modules');
$fh = @opendir($basedir);
if ($fh === false) {
return $this;
}
while ($name = readdir($fh)) {
if ($name[0] === '.') {
continue;
foreach ($this->modulePaths as $basedir) {
$fh = opendir($basedir);
if ($fh === false) {
return $this;
}
if (is_dir($basedir . '/' . $name)) {
$this->installedBaseDirs[$name] = $basedir . '/' . $name;
while ($name = readdir($fh)) {
if ($name[0] === '.') {
continue;
}
if (is_dir($basedir . '/' . $name)) {
$this->installedBaseDirs[$name] = $basedir . '/' . $name;
}
}
}
}