Merge branch 'feature/rhel-packages-6401'

resolves #6401
This commit is contained in:
Eric Lippmann 2014-12-29 16:50:20 +01:00
commit 9d9dd8ac99
36 changed files with 568 additions and 429 deletions

View File

@ -1,7 +1,7 @@
---
icingaweb2::config: /etc/icingaweb
icingaweb2::log: /var/log/icingaweb/icingaweb.log
icingaweb2::web_path: icingaweb
icingaweb2::db_user: icingaweb
icingaweb2::db_pass: icingaweb
icingaweb2::db_name: icingaweb
icingaweb2::config: /etc/icingaweb2
icingaweb2::log: /var/log/icingaweb2/icingaweb2.log
icingaweb2::web_path: icingaweb2
icingaweb2::db_user: icingaweb2
icingaweb2::db_pass: icingaweb2
icingaweb2::db_name: icingaweb2

View File

@ -4,16 +4,17 @@
# namespace Icinga\Application\Controllers;
use Icinga\Authentication\Backend\AutoLoginBackend;
use Icinga\Web\Controller\ActionController;
use Icinga\Forms\Authentication\LoginForm;
use Icinga\Authentication\AuthChain;
use Icinga\Application\Config;
use Icinga\Application\Icinga;
use Icinga\Application\Logger;
use Icinga\Authentication\AuthChain;
use Icinga\Authentication\Backend\AutoLoginBackend;
use Icinga\Exception\AuthenticationException;
use Icinga\Exception\NotReadableError;
use Icinga\Exception\ConfigurationError;
use Icinga\Exception\NotReadableError;
use Icinga\Forms\Authentication\LoginForm;
use Icinga\User;
use Icinga\Web\Controller\ActionController;
use Icinga\Web\Url;
/**
@ -33,7 +34,8 @@ class AuthenticationController extends ActionController
*/
public function loginAction()
{
if (@file_exists(Config::resolvePath('setup.token')) && !@file_exists(Config::resolvePath('config.ini'))) {
$icinga = Icinga::app();
if ($icinga->setupTokenExists() && $icinga->requiresSetup()) {
$this->redirectNow(Url::fromPath('setup'));
}
@ -139,7 +141,7 @@ class AuthenticationController extends ActionController
$this->view->errorInfo = $e->getMessage();
}
$this->view->configMissing = is_dir(Config::$configDir) === false;
$this->view->requiresSetup = Icinga::app()->requiresSetup();
}
/**

View File

@ -67,7 +67,7 @@ class LoggingConfigForm extends Form
'required' => true,
'label' => t('Application Prefix'),
'description' => t('The name of the application by which to prefix syslog messages.'),
'value' => 'icingaweb',
'value' => 'icingaweb2',
'validators' => array(
array(
'Regex',
@ -106,7 +106,7 @@ class LoggingConfigForm extends Form
'required' => true,
'label' => t('File path'),
'description' => t('The full path to the log file to write messages to.'),
'value' => $this->getDefaultLogDir(),
'value' => '/var/log/icingaweb2/icingaweb2.log',
'validators' => array(new WritablePathValidator())
)
);
@ -114,14 +114,4 @@ class LoggingConfigForm extends Form
return $this;
}
/**
* Return the default logging directory for type 'file'
*
* @return string
*/
protected function getDefaultLogDir()
{
return realpath(Icinga::app()->getApplicationDir('../var/log/icingaweb.log'));
}
}

View File

@ -15,7 +15,7 @@
<?php endif ?>
<?= $this->form ?>
<div class="footer">Icinga Web 2 &copy; 2013-2014<br><a href="https://www.icinga.org">The Icinga Project</a></div>
<?php if ($configMissing): ?>
<?php if ($requiresSetup): ?>
<div class="config-note"><?= sprintf(
t(
'It appears that you did not configure Icinga Web 2 yet so it\'s not possible to log in without any defined '

View File

@ -1,237 +1,235 @@
#/**
# * This file is part of Icinga Web 2.
# *
# * Icinga Web 2 - Head for multiple monitoring backends.
# * Copyright (C) 2014 Icinga Development Team
# *
# * This program is free software; you can redistribute it and/or
# * modify it under the terms of the GNU General Public License
# * as published by the Free Software Foundation; either version 2
# * of the License, or (at your option) any later version.
# *
# * This program is distributed in the hope that it will be useful,
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# * GNU General Public License for more details.
# *
# * You should have received a copy of the GNU General Public License
# * along with this program; if not, write to the Free Software
# * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# *
# * @copyright 2014 Icinga Development Team <info@icinga.org>
# * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
# * @author Icinga Development Team <info@icinga.org>
# *
# */
%define revision 1
%define configdir %{_sysconfdir}/%{name}
%define sharedir %{_datadir}/%{name}
%define prefixdir %{_datadir}/%{name}
%define usermodparam -a -G
%define logdir %{_localstatedir}/log/%{name}
%define docdir %{sharedir}/doc
%if "%{_vendor}" == "suse"
%define phpname php5
%define phpzendname php5-ZendFramework
%define apache2modphpname apache2-mod_php5
%endif
# SLE 11 = 1110
%if 0%{?suse_version} == 1110
%define phpname php53
%define apache2modphpname apache2-mod_php53
%define usermodparam -A
%endif
%if "%{_vendor}" == "redhat"
%define phpname php
%define phpzendname php-ZendFramework
%endif
# el5 requires newer php53 rather than php (5.1)
%if 0%{?el5} || 0%{?rhel} == 5 || "%{?dist}" == ".el5"
%define phpname php53
%endif
%if "%{_vendor}" == "suse"
%define apacheconfdir %{_sysconfdir}/apache2/conf.d
%define apacheuser wwwrun
%define apachegroup www
%define extcmdfile %{_localstatedir}/run/icinga2/cmd/icinga.cmd
%define livestatussocket %{_localstatedir}/run/icinga2/cmd/livestatus
%endif
%if "%{_vendor}" == "redhat"
%define apacheconfdir %{_sysconfdir}/httpd/conf.d
%define apacheuser apache
%define apachegroup apache
%define extcmdfile %{_localstatedir}/run/icinga2/cmd/icinga.cmd
%define livestatussocket %{_localstatedir}/run/icinga2/cmd/livestatus
%endif
Summary: Open Source host, service and network monitoring Web UI
Name: icingaweb2
Version: 0.0.1
Release: %{revision}%{?dist}
License: GPLv2
Version: 2.0.0
Release: 1.beta2%{?dist}
Summary: Icinga Web 2
Group: Applications/System
URL: http://www.icinga.org
License: GPL
URL: https://icinga.org
Source0: https://github.com/Icinga/%{name}/archive/v%{version}.tar.gz
BuildArch: noarch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}
Packager: Icinga Team <info@icinga.org>
%if "%{_vendor}" == "suse"
AutoReqProv: Off
%if 0%{?fedora} || 0%{?rhel}
%define wwwconfigdir %{_sysconfdir}/httpd/conf.d
%define wwwuser apache
%if 0%{?rhel} == 5
%define php php53
%define php_cli php53-cli
%else
%define php php
%define php_cli php-cli
%endif
%if 0%{rhel} == 6
%define zend php-ZendFramework
%else
%define zend %{name}-vendor-Zend
%endif
%endif
Source: icingaweb2-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
BuildRequires: %{phpname} >= 5.3.0
BuildRequires: %{phpname}-devel >= 5.3.0
BuildRequires: %{phpname}-ldap
BuildRequires: %{phpname}-pdo
BuildRequires: %{phpzendname}
%if "%{_vendor}" != "suse"
BuildRequires: %{phpzendname}-Db-Adapter-Pdo
BuildRequires: %{phpzendname}-Db-Adapter-Pdo-Mysql
BuildRequires: %{phpzendname}-Db-Adapter-Pdo-Pgsql
%endif
%if "%{_vendor}" == "redhat"
%endif
%if "%{_vendor}" == "suse"
Requires: %{phpname}-devel >= 5.3.0
BuildRequires: %{phpname}-json
BuildRequires: %{phpname}-sockets
BuildRequires: %{phpname}-dom
%endif
Requires: %{phpname} >= 5.3.0
Requires: %{phpzendname}
Requires: %{phpname}-ldap
Requires: %{phpname}-pdo
%if "%{_vendor}" == "redhat"
Requires: %{phpname}-common
Requires: %{phpzendname}-Db-Adapter-Pdo
Requires: %{phpzendname}-Db-Adapter-Pdo-Mysql
Requires: php-pear
%endif
%if "%{_vendor}" == "suse"
Requires: %{phpname}-pear
Requires: %{phpname}-dom
Requires: %{phpname}-tokenizer
Requires: %{phpname}-gettext
Requires: %{phpname}-ctype
Requires: %{phpname}-json
Requires: %{apache2modphpname}
%endif
Requires: php-Icinga
Requires(pre): shadow-utils
Requires: %{name}-common = %{version}-%{release}
Requires: php-Icinga = %{version}-%{release}
Requires: %{name}-vendor-dompdf
Requires: %{name}-vendor-HTMLPurifier
Requires: %{name}-vendor-JShrink
Requires: %{name}-vendor-lessphp
Requires: %{name}-vendor-Parsedown
Requires: %{zend}
%description
Icinga Web 2 for Icinga 2 or Icinga 1.x using multiple backends
for example DB IDO.
Icinga Web 2
%define basedir %{_datadir}/%{name}
%define bindir %{_bindir}
%define configdir %{_sysconfdir}/%{name}
%define logdir %{_localstatedir}/log/%{name}
%define phpdir %{_datadir}/php
%define icingawebgroup icingaweb2
%package common
Summary: Common files for Icinga Web 2 and the Icinga CLI
Group: Applications/System
%description common
Common files for Icinga Web 2 and the Icinga CLI
%package -n php-Icinga
Summary: Icinga Web 2 PHP library
Group: Development/Libraries
Requires: %{php} >= 5.3.0
%description -n php-Icinga
Icinga Web 2 PHP library
%package -n icingacli
Summary: Icinga CLI
Group: Applications/System
Requires: %{name} = %{version}-%{release}
Requires: php-Icinga
Requires: %{name}-common = %{version}-%{release}
Requires: php-Icinga = %{version}-%{release}
Requires: %{php_cli} >= 5.3.0
%description -n icingacli
Icinga CLI using php-Icinga Icinga Web 2 backend.
%package -n php-Icinga
Summary: Icinga Web 2 PHP Libraries
Group: Applications/System
Requires: %{name} = %{version}-%{release}
Requires: %{phpname} >= 5.3.0
Requires: %{phpzendname}
Icinga CLI
%description -n php-Icinga
Icinga Web 2 PHP Libraries required by the web frontend and cli tool.
%package vendor-dompdf
Version: 0.6.1
Release: 1%{?dist}
Summary: Icinga Web 2 vendor library dompdf
Group: Development/Libraries
Requires: %{php} >= 5.3.0
%description vendor-dompdf
Icinga Web 2 vendor library dompdf
%package vendor-HTMLPurifier
Version: 4.6.0
Release: 1%{?dist}
Summary: Icinga Web 2 vendor library HTMLPurifier
Group: Development/Libraries
Requires: %{php} >= 5.3.0
%description vendor-HTMLPurifier
Icinga Web 2 vendor library HTMLPurifier
%package vendor-JShrink
Version: 1.0.1
Release: 1%{?dist}
Summary: Icinga Web 2 vendor library JShrink
Group: Development/Libraries
Requires: %{php} >= 5.3.0
%description vendor-JShrink
Icinga Web 2 vendor library JShrink
%package vendor-lessphp
Version: 0.4.0
Release: 1%{?dist}
Summary: Icinga Web 2 vendor library lessphp
Group: Development/Libraries
Requires: %{php} >= 5.3.0
%description vendor-lessphp
Icinga Web 2 vendor library lessphp
%package vendor-Parsedown
Version: 1.0.0
Release: 1%{?dist}
Summary: Icinga Web 2 vendor library Parsedown
Group: Development/Libraries
Requires: %{php} >= 5.3.0
%description vendor-Parsedown
Icinga Web 2 vendor library Parsedown
%package vendor-Zend
Version: 1.12.9
Release: 1%{?dist}
Summary: Icinga Web 2 vendor library Zend Framework
Group: Development/Libraries
Requires: %{php} >= 5.3.0
%description vendor-Zend
Icinga Web 2 vendor library Zend
%prep
#VERSION=0.0.1; git archive --format=tar --prefix=icingaweb2-$VERSION/ HEAD | gzip >icingaweb2-$VERSION.tar.gz
%setup -q -n %{name}-%{version}
%setup -q
%build
%install
[ "%{buildroot}" != "/" ] && [ -d "%{buildroot}" ] && rm -rf %{buildroot}
# prepare configuration for sub packages
# install rhel apache config
install -D -m0644 packages/files/apache/icingaweb.conf %{buildroot}/%{apacheconfdir}/icingaweb.conf
# install public, library, modules
%{__mkdir} -p %{buildroot}/%{sharedir}
%{__mkdir} -p %{buildroot}/%{logdir}
%{__mkdir} -p %{buildroot}/%{docdir}
%{__mkdir} -p %{buildroot}/%{_sysconfdir}/%{name}
%{__mkdir} -p %{buildroot}/%{_sysconfdir}/dashboard
%{__mkdir} -p %{buildroot}/%{_sysconfdir}/%{name}/modules
%{__mkdir} -p %{buildroot}/%{_sysconfdir}/%{name}/modules/monitoring
%{__mkdir} -p %{buildroot}/%{_sysconfdir}/%{name}/enabledModules
# make sure to install local icingacli for setup wizard token generation & webserver config
%{__cp} -r application doc library modules public bin %{buildroot}/%{sharedir}/
# enable the monitoring module by default
ln -s %{sharedir}/modules/monitoring %{buildroot}/%{_sysconfdir}/%{name}/enabledModules/monitoring
## config
# symlink icingacli
mkdir -p %{buildroot}/usr/bin
ln -sf %{sharedir}/bin/icingacli %{buildroot}/usr/bin/icingacli
rm -rf %{buildroot}
mkdir -p %{buildroot}/{%{basedir}/{modules,library,public},%{bindir},%{configdir},%{logdir},%{phpdir},%{wwwconfigdir}}
cp -prv application doc var %{buildroot}/%{basedir}
cp -prv modules/{monitoring,setup} %{buildroot}/%{basedir}/modules
cp -prv library/Icinga %{buildroot}/%{phpdir}
cp -prv library/vendor %{buildroot}/%{basedir}/library
cp -prv public/{css,img,js,error_norewrite.html} %{buildroot}/%{basedir}/public
cp -pv packages/files/apache/icingaweb2.conf %{buildroot}/%{wwwconfigdir}/icingaweb2.conf
cp -pv packages/files/bin/icingacli %{buildroot}/%{bindir}
cp -pv packages/files/public/index.php %{buildroot}/%{basedir}/public
%pre
# Add apacheuser in the icingacmd group
# If the group exists, add the apacheuser in the icingacmd group.
# It is not neccessary that icinga2-web is installed on the same system as
# icinga and only on systems with icinga installed the icingacmd
# group exists. In all other cases the user used for ssh access has
# to be added to the icingacmd group on the remote icinga server.
getent group icingacmd > /dev/null
if [ $? -eq 0 ]; then
%{_sbindir}/usermod %{usermodparam} icingacmd %{apacheuser}
fi
%preun
%post
getent group icingacmd >/dev/null || groupadd -r icingacmd
usermod -a -G icingacmd,%{icingawebgroup} %{wwwuser}
exit 0
%clean
[ "%{buildroot}" != "/" ] && [ -d "%{buildroot}" ] && rm -rf %{buildroot}
rm -rf %{buildroot}
%files
# main dirs
%defattr(-,root,root)
%doc etc/schema doc packages/RPM.md
%attr(755,%{apacheuser},%{apachegroup}) %{sharedir}/public
%attr(755,%{apacheuser},%{apachegroup}) %{sharedir}/modules
# configs
%{basedir}/application/controllers
%{basedir}/application/fonts
%{basedir}/application/forms
%{basedir}/application/layouts
%{basedir}/application/views
%{basedir}/doc
%{basedir}/modules
%{basedir}/public
%{wwwconfigdir}/icingaweb2.conf
%attr(2775,root,%{icingawebgroup}) %dir %{logdir}
%pre common
getent group %{icingawebgroup} >/dev/null || groupadd -r %{icingawebgroup}
exit 0
%files common
%defattr(-,root,root)
%config(noreplace) %attr(-,root,root) %{apacheconfdir}/icingaweb.conf
%config(noreplace) %attr(-,%{apacheuser},%{apachegroup}) %{configdir}
# logs
%attr(2775,%{apacheuser},%{apachegroup}) %dir %{logdir}
# shipped docs
%attr(755,%{apacheuser},%{apachegroup}) %{sharedir}/doc
%{basedir}/application/locale
%dir %{basedir}/modules
%attr(2770,root,%{icingawebgroup}) %config(noreplace) %{configdir}
%files -n php-Icinga
%attr(755,%{apacheuser},%{apachegroup}) %{sharedir}/application
%attr(755,%{apacheuser},%{apachegroup}) %{sharedir}/library
%defattr(-,root,root)
%{phpdir}/Icinga
%files -n icingacli
%attr(0755,root,root) /usr/bin/icingacli
%attr(0755,root,root) %{sharedir}/bin/icingacli
%attr(0755,root,root) %{sharedir}/bin/license_writer.py
%defattr(-,root,root)
%{basedir}/application/clicommands
%attr(0755,root,root) %{bindir}/icingacli
%changelog
%files vendor-dompdf
%defattr(-,root,root)
%{basedir}/library/vendor/dompdf
%files vendor-HTMLPurifier
%defattr(-,root,root)
%{basedir}/library/vendor/HTMLPurifier
%files vendor-JShrink
%defattr(-,root,root)
%{basedir}/library/vendor/JShrink
%files vendor-lessphp
%defattr(-,root,root)
%{basedir}/library/vendor/lessphp
%files vendor-Parsedown
%defattr(-,root,root)
%{basedir}/library/vendor/Parsedown
%files vendor-Zend
%defattr(-,root,root)
%{basedir}/library/vendor/Zend

View File

@ -113,6 +113,13 @@ abstract class ApplicationBootstrap
*/
protected $isWeb = false;
/**
* Whether Icinga Web 2 requires setup
*
* @type bool
*/
protected $requiresSetup = false;
/**
* Constructor
*
@ -133,7 +140,7 @@ abstract class ApplicationBootstrap
if (array_key_exists('ICINGAWEB_CONFIGDIR', $_SERVER)) {
$configDir = $_SERVER['ICINGAWEB_CONFIGDIR'];
} else {
$configDir = '/etc/icingaweb';
$configDir = '/etc/icingaweb2';
}
}
$canonical = realpath($configDir);
@ -333,7 +340,7 @@ abstract class ApplicationBootstrap
/**
* Setup Icinga auto loader
*
* @return self
* @return $this
*/
public function setupAutoloader()
{
@ -366,7 +373,7 @@ abstract class ApplicationBootstrap
/**
* Setup module manager
*
* @return self
* @return $this
*/
protected function setupModuleManager()
{
@ -378,25 +385,10 @@ abstract class ApplicationBootstrap
return $this;
}
/**
* Load all core modules
*
* @return self
*/
protected function loadCoreModules()
{
try {
$this->moduleManager->loadCoreModules();
} catch (NotReadableError $e) {
Logger::error(new IcingaException('Cannot load core modules. An exception was thrown:', $e));
}
return $this;
}
/**
* Load all enabled modules
*
* @return self
* @return $this
*/
protected function loadEnabledModules()
{
@ -408,10 +400,44 @@ abstract class ApplicationBootstrap
return $this;
}
/**
* Load the setup module if Icinga Web 2 requires setup
*
* @return $this
*/
protected function loadSetupModuleIfNecessary()
{
if (! @file_exists($this->config->resolvePath('config.ini'))) {
$this->requiresSetup = true;
$this->moduleManager->loadModule('setup');
}
return $this;
}
/**
* Get whether Icinga Web 2 requires setup
*
* @return bool
*/
public function requiresSetup()
{
return $this->requiresSetup;
}
/**
* Get whether the setup token exists
*
* @return bool
*/
public function setupTokenExists()
{
return @file_exists($this->config->resolvePath('setup.token'));
}
/**
* Setup default logging
*
* @return self
* @return $this
*/
protected function setupLogging()
{
@ -428,7 +454,7 @@ abstract class ApplicationBootstrap
/**
* Load Configuration
*
* @return self
* @return $this
*/
protected function loadConfig()
{
@ -447,7 +473,7 @@ abstract class ApplicationBootstrap
/**
* Error handling configuration
*
* @return self
* @return $this
*/
protected function setupErrorHandling()
{
@ -473,7 +499,7 @@ abstract class ApplicationBootstrap
/**
* Set up logger
*
* @return self
* @return $this
*/
protected function setupLogger()
{
@ -490,7 +516,7 @@ abstract class ApplicationBootstrap
/**
* Set up the resource factory
*
* @return self
* @return $this
*/
protected function setupResourceFactory()
{

View File

@ -43,8 +43,7 @@ class Cli extends ApplicationBootstrap
->parseBasicParams()
->setupLogger()
->setupResourceFactory()
->setupModuleManager()
->loadCoreModules();
->setupModuleManager();
}
protected function setupLogging()

View File

@ -6,10 +6,8 @@ namespace Icinga\Application;
require_once dirname(__FILE__) . '/ApplicationBootstrap.php';
use Icinga\Exception\ProgrammingError;
/**
* Use this if you want to make use of Icinga funtionality in other web projects
* Use this if you want to make use of Icinga functionality in other web projects
*
* Usage example:
* <code>

View File

@ -68,18 +68,6 @@ class Manager
*/
private $modulePaths = array();
/**
* The core modules
*
* Core modules do not need to be enabled to load and cannot be disabled
* by the user. This must not be writable programmatically!
*
* @var array
*/
private $coreModules = array(
'setup'
);
/**
* Create a new instance of the module manager
*
@ -170,21 +158,7 @@ class Manager
}
/**
* Try to set all core modules in loaded state
*
* @return self
* @see Manager::loadModule()
*/
public function loadCoreModules()
{
foreach ($this->coreModules as $name) {
$this->loadModule($name);
}
return $this;
}
/**
* Try to set all enabled modules in loaded state
* Try to set all enabled modules in loaded sate
*
* @return self
* @see Manager::loadModule()
@ -239,8 +213,6 @@ class Manager
'Cannot enable module "%s". Module is not installed.',
$name
);
} elseif (in_array($name, $this->coreModules)) {
return $this;
}
clearstatcache(true);
@ -458,7 +430,7 @@ class Manager
}
$installed = $this->listInstalledModules();
foreach (array_diff($installed, $this->coreModules) as $name) {
foreach ($installed as $name) {
$info[$name] = (object) array(
'name' => $name,
'path' => $this->installedBaseDirs[$name],

View File

@ -104,7 +104,7 @@ class Web extends ApplicationBootstrap
->setupZendMvc()
->setupFormNamespace()
->setupModuleManager()
->loadCoreModules()
->loadSetupModuleIfNecessary()
->loadEnabledModules()
->setupRoute()
->setupPagination();

View File

@ -0,0 +1,71 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\File;
use FilterIterator;
use Iterator;
/**
* Iterator over files having a specific file extension
*
* Usage example:
* <code>
* <?php
*
* namespace Icinga\Example;
*
* use RecursiveDirectoryIterator;
* use RecursiveIteratorIterator;
* use Icinga\File\FileExtensionFilterIterator;
*
* $markdownFiles = new FileExtensionFilterIterator(
* new RecursiveIteratorIterator(
* new RecursiveDirectoryIterator(__DIR__),
* RecursiveIteratorIterator::SELF_FIRST
* ),
* 'md'
* );
* </code>
*/
class FileExtensionFilterIterator extends FilterIterator
{
/**
* The extension to filter for
*
* @type string
*/
protected $extension;
/**
* Create a new FileExtensionFilterIterator
*
* @param Iterator $iterator Apply filter to this iterator
* @param string $extension The file extension to filter for. The file extension may not contain the leading dot
*/
public function __construct(Iterator $iterator, $extension)
{
$this->extension = '.' . ltrim(strtolower((string) $extension), '.');
parent::__construct($iterator);
}
/**
* Accept files which match the file extension to filter for
*
* @return bool Whether the current element of the iterator is acceptable
* through this filter
*/
public function accept()
{
$current = $this->current();
/* @var $current \SplFileInfo */
if (! $current->isFile()) {
return false;
}
// SplFileInfo::getExtension() is only available since PHP 5 >= 5.3.6
$filename = $current->getFilename();
$sfx = substr($filename, -strlen($this->extension));
return $sfx === false ? false : strtolower($sfx) === $this->extension;
}
}

View File

@ -0,0 +1,49 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}
namespace Icinga\File;
use FilterIterator;
/**
* Iterator over non-empty files
*
* Usage example:
* <code>
* <?php
*
* namespace Icinga\Example;
*
* use RecursiveDirectoryIterator;
* use RecursiveIteratorIterator;
* use Icinga\File\NonEmptyFilterIterator;
*
* $nonEmptyFiles = new NonEmptyFileIterator(
* new RecursiveIteratorIterator(
* new RecursiveDirectoryIterator(__DIR__),
* RecursiveIteratorIterator::SELF_FIRST
* )
* );
* </code>
*/
class NonEmptyFileIterator extends FilterIterator
{
/**
* Accept non-empty files
*
* @return bool Whether the current element of the iterator is acceptable
* through this filter
*/
public function accept()
{
$current = $this->current();
/** @type $current \SplFileInfo */
if (! $current->isFile()
|| $current->getSize() === 0
) {
return false;
}
return true;
}
}

View File

@ -4,3 +4,4 @@ DESTINATION=.
wget -O ${FILENAME}.tar.gz https://github.com/erusev/parsedown/archive/${RELEASE}.tar.gz
tar xfz ${FILENAME}.tar.gz -C $DESTINATION/ --strip-components 1 $FILENAME/Parsedown.php $FILENAME/LICENSE.txt
chmod 644 $DESTINATION/Parsedown.php
mv LICENSE.txt LICENSE

View File

@ -1,6 +1,7 @@
curl https://codeload.github.com/dompdf/dompdf/tar.gz/v0.6.1 -o dompdf-0.6.1.tar.gz
tar xzf dompdf-0.6.1.tar.gz --strip-components 1 dompdf-0.6.1/{include/*.php,lib,dompdf*.php,LICENSE.LGPL}
rm dompdf-0.6.1.tar.gz
mv LICENSE.LGPL LICENSE
curl https://codeload.github.com/PhenX/php-font-lib/tar.gz/0.3.1 -o php-font-lib-0.3.1.tar.gz
mkdir lib/php-font-lib/classes

View File

@ -8,12 +8,36 @@ use Icinga\Module\Doc\DocController;
class Doc_IcingawebController extends DocController
{
/**
* Get the path to Icinga Web 2's documentation
*
* @return string
*
* @throws Zend_Controller_Action_Exception If Icinga Web 2's documentation is not available
*/
protected function getPath()
{
$path = Icinga::app()->getBaseDir('doc');
if (is_dir($path)) {
return $path;
}
if (($path = $this->Config()->get('documentation', 'icingaweb2')) !== null) {
if (is_dir($path)) {
return $path;
}
}
throw new Zend_Controller_Action_Exception(
$this->translate('Documentation for Icinga Web 2 is not available'),
404
);
}
/**
* View the toc of Icinga Web 2's documentation
*/
public function tocAction()
{
return $this->renderToc(Icinga::app()->getApplicationDir('/../doc'), 'Icinga Web 2', 'doc/icingaweb/chapter');
$this->renderToc($this->getPath(), 'Icinga Web 2', 'doc/icingaweb/chapter');
}
/**
@ -26,12 +50,12 @@ class Doc_IcingawebController extends DocController
$chapterId = $this->getParam('chapterId');
if ($chapterId === null) {
throw new Zend_Controller_Action_Exception(
$this->translate('Missing parameter \'chapterId\''),
sprintf($this->translate('Missing parameter \'%s\''), 'chapterId'),
404
);
}
return $this->renderChapter(
Icinga::app()->getApplicationDir('/../doc'),
$this->renderChapter(
$this->getPath(),
$chapterId,
'doc/icingaweb/toc',
'doc/icingaweb/chapter'
@ -43,6 +67,6 @@ class Doc_IcingawebController extends DocController
*/
public function pdfAction()
{
return $this->renderPdf(Icinga::app()->getApplicationDir('/../doc'), 'Icinga Web 2', 'doc/icingaweb/chapter');
$this->renderPdf($this->getPath(), 'Icinga Web 2', 'doc/icingaweb/chapter');
}
}

View File

@ -9,6 +9,40 @@ use Icinga\Module\Doc\Exception\DocException;
class Doc_ModuleController extends DocController
{
/**
* Get the path to a module documentation
*
* @param string $module The name of the module
* @param string $default The default path
* @param bool $suppressErrors Whether to not throw an exception if the module documentation is not
* available
*
* @return string|null Path to the documentation or null if the module documentation is not
* available and errors are suppressed
*
* @throws Zend_Controller_Action_Exception If the module documentation is not available and errors are not
* suppressed
*/
protected function getPath($module, $default, $suppressErrors = false)
{
if (is_dir($default)) {
return $default;
}
if (($path = $this->Config()->get('documentation', 'modules')) !== null) {
$path = str_replace('{module}', $module, $path);
if (is_dir($path)) {
return $path;
}
}
if ($suppressErrors) {
return null;
}
throw new Zend_Controller_Action_Exception(
sprintf($this->translate('Documentation for module \'%s\' is not available'), $module),
404
);
}
/**
* List modules which are enabled and having the 'doc' directory
*/
@ -16,10 +50,10 @@ class Doc_ModuleController extends DocController
{
$moduleManager = Icinga::app()->getModuleManager();
$modules = array();
foreach (Icinga::app()->getModuleManager()->listEnabledModules() as $enabledModule) {
$docDir = $moduleManager->getModuleDir($enabledModule, '/doc');
if (is_dir($docDir)) {
$modules[] = $enabledModule;
foreach (Icinga::app()->getModuleManager()->listEnabledModules() as $module) {
$path = $this->getPath($module, $moduleManager->getModuleDir($module, '/doc'), true);
if ($path !== null) {
$modules[] = $module;
}
}
$this->view->modules = $modules;
@ -37,7 +71,7 @@ class Doc_ModuleController extends DocController
{
if (empty($moduleName)) {
throw new Zend_Controller_Action_Exception(
$this->translate('Missing parameter \'moduleName\''),
sprintf($this->translate('Missing parameter \'%s\''), 'moduleName'),
404
);
}
@ -63,16 +97,15 @@ class Doc_ModuleController extends DocController
*/
public function tocAction()
{
$moduleName = $this->getParam('moduleName');
$this->assertModuleEnabled($moduleName);
$this->view->moduleName = $moduleName;
$moduleManager = Icinga::app()->getModuleManager();
$module = $this->getParam('moduleName');
$this->assertModuleEnabled($module);
$this->view->moduleName = $module;
try {
return $this->renderToc(
$moduleManager->getModuleDir($moduleName, '/doc'),
$moduleName,
$this->renderToc(
$this->getPath($module, Icinga::app()->getModuleManager()->getModuleDir($module, '/doc')),
$module,
'doc/module/chapter',
array('moduleName' => $moduleName)
array('moduleName' => $module)
);
} catch (DocException $e) {
throw new Zend_Controller_Action_Exception($e->getMessage(), 404);
@ -88,24 +121,23 @@ class Doc_ModuleController extends DocController
*/
public function chapterAction()
{
$moduleName = $this->getParam('moduleName');
$this->assertModuleEnabled($moduleName);
$module = $this->getParam('moduleName');
$this->assertModuleEnabled($module);
$chapterId = $this->getParam('chapterId');
if ($chapterId === null) {
throw new Zend_Controller_Action_Exception(
$this->translate('Missing parameter \'chapterId\''),
sprintf($this->translate('Missing parameter \'%s\''), 'chapterId'),
404
);
}
$this->view->moduleName = $moduleName;
$moduleManager = Icinga::app()->getModuleManager();
$this->view->moduleName = $module;
try {
return $this->renderChapter(
$moduleManager->getModuleDir($moduleName, '/doc'),
$this->renderChapter(
$this->getPath($module, Icinga::app()->getModuleManager()->getModuleDir($module, '/doc')),
$chapterId,
$this->_helper->url->url(array('moduleName' => $moduleName), 'doc/module/toc'),
$this->_helper->url->url(array('moduleName' => $module), 'doc/module/toc'),
'doc/module/chapter',
array('moduleName' => $moduleName)
array('moduleName' => $module)
);
} catch (DocException $e) {
throw new Zend_Controller_Action_Exception($e->getMessage(), 404);
@ -119,14 +151,13 @@ class Doc_ModuleController extends DocController
*/
public function pdfAction()
{
$moduleName = $this->getParam('moduleName');
$this->assertModuleEnabled($moduleName);
$moduleManager = Icinga::app()->getModuleManager();
return $this->renderPdf(
$moduleManager->getModuleDir($moduleName, '/doc'),
$moduleName,
$module = $this->getParam('moduleName');
$this->assertModuleEnabled($module);
$this->renderPdf(
$this->getPath($module, Icinga::app()->getModuleManager()->getModuleDir($module, '/doc')),
$module,
'doc/module/chapter',
array('moduleName' => $moduleName)
array('moduleName' => $module)
);
}
}

View File

@ -2,7 +2,7 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
/* @var $this \Icinga\Application\Modules\Module */
/** @type $this \Icinga\Application\Modules\Module */
$section = $this->menuSection($this->translate('Documentation'), array(
'title' => 'Documentation',

View File

@ -0,0 +1,59 @@
# <a id="module-documentation"></a> Writing Module Documentation
![Markdown](/img/doc/doc/markdown.png)
Icinga Web 2 is capable of viewing your module's documentation, if the documentation is written in
[Markdown](http://en.wikipedia.org/wiki/Markdown). Please refer to
[Markdown Syntax Documentation](http://daringfireball.net/projects/markdown/syntax) for Markdown's formatting syntax.
## <a id="location"></a> Where to Put Module Documentation?
By default, your module's Markdown documentation files must be placed in the `doc` directory beneath your module's root
directory, e.g.:
example-module/doc
## <a id="chapters"></a> Chapters
Each Markdown documentation file represents a chapter of your module's documentation. The first found heading inside
each file is the chapter's title. The order of chapters is based on the case insensitive "Natural Order" of your files'
names. <dfn>Natural Order</dfn> means that the file names are ordered in the way which seems natural to humans.
It is best practice to prefix Markdown documentation file names with numbers to ensure that they appear in the correct
order, e.g.:
1-about.md
2-installation.md
3-configuration.md
## <a id="toc"></a> Table Of Contents
The table of contents for your module's documentation is auto-generated based on all found headings inside each
Markdown documentation file.
## <a id="linking"></a> Linking Between Headings
For linking between headings, place an anchor where you want to link to, e.g.:
# <a id="heading"></a> Heading
Now you can reference the anchor either in the same or **in another** Markdown documentation file, e.g.:
This is a link to [Heading](#heading).
## <a id="images"></a> Including Images
Images must placed in the `img` directory beneath your module's `public` directory, e.g.:
example-module/public/img/doc
Module images can be accessed using the following URL:
{baseURL}/img/{moduleName}/{file} e.g. icingaweb/img/example-module/doc/example.png
Markdown's image syntax is very similar to Markdown's link syntax, but prefixed with an exclamation mark, e.g.:
![Alt text](http://path/to/img.png "Optional Title")
URLs to images inside your Markdown documentation files must be specified without the base URL, e.g.:
![Example](/img/example-module/doc/example.png)

View File

@ -28,7 +28,7 @@ class DocController extends ModuleActionController
$urlParams
);
$this->view->title = $chapterId;
return $this->render('chapter', null, true);
$this->render('chapter', null, true);
}
/**
@ -46,7 +46,7 @@ class DocController extends ModuleActionController
$name = ucfirst($name);
$this->view->docName = $name;
$this->view->title = sprintf($this->translate('%s Documentation'), $name);
return $this->render('toc', null, true);
$this->render('toc', null, true);
}
/**
@ -71,6 +71,6 @@ class DocController extends ModuleActionController
);
$this->view->docName = $name;
$this->_request->setParam('format', 'pdf');
return $this->render('pdf', null, true);
$this->render('pdf', null, true);
}
}

View File

@ -9,6 +9,8 @@ use Countable;
use IteratorAggregate;
use RecursiveIteratorIterator;
use RecursiveDirectoryIterator;
use Icinga\File\NonEmptyFileIterator;
use Icinga\File\FileExtensionFilterIterator;
/**
* Iterator over non-empty Markdown files ordered by the case insensitive "natural order" of file names
@ -29,12 +31,14 @@ class DocIterator implements Countable, IteratorAggregate
*/
public function __construct($path)
{
$it = new RecursiveIteratorIterator(
$it = new FileExtensionFilterIterator(
new NonEmptyFileIterator(
new MarkdownFileIterator(
new RecursiveDirectoryIterator($path)
new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path),
RecursiveIteratorIterator::SELF_FIRST
)
)
),
'md'
);
// Unfortunately we have no chance to sort the iterator
$fileInfo = iterator_to_array($it);

View File

@ -31,7 +31,7 @@ class DocParser
/**
* Create a new documentation parser for the given path
*
* @param string $path Path to the documentation
* @param string $path Path to the documentation
*
* @throws DocException If the documentation directory does not exist
* @throws NotReadableError If the documentation directory is not readable

View File

@ -1,31 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Module\Doc;
use RecursiveFilterIterator;
/**
* Recursive iterator over Markdown files
*/
class MarkdownFileIterator extends RecursiveFilterIterator
{
/**
* Accept files with '.md' suffix
*
* @return bool Whether the current element of the iterator is acceptable
* through this filter
*/
public function accept()
{
$current = $this->getInnerIterator()->current();
/* @var $current \SplFileInfo */
if (! $current->isFile()) {
return false;
}
$filename = $current->getFilename();
$sfx = substr($filename, -3);
return $sfx === false ? false : strtolower($sfx) === '.md';
}
}

View File

@ -1,31 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}
namespace Icinga\Module\Doc;
use RecursiveFilterIterator;
/**
* Recursive iterator over non-empty files
*/
class NonEmptyFileIterator extends RecursiveFilterIterator
{
/**
* Accept non-empty files
*
* @return bool Whether the current element of the iterator is acceptable
* through this filter
*/
public function accept()
{
$current = $this->getInnerIterator()->current();
/* @var $current \SplFileInfo */
if (! $current->isFile()
|| $current->getSize() === 0
) {
return false;
}
return true;
}
}

View File

@ -1,4 +1,4 @@
Module: doc
Version: 2.0.0~alpha4
Version: 2.0.0
Description: Documentation module
Extracts, shows and exports documentation for Icinga Web 2 and it's modules.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -47,4 +47,3 @@ $this->addRoute('doc/module/chapter', $docModuleChapter);
$this->addRoute('doc/icingaweb/chapter', $docIcingaWebChapter);
$this->addRoute('doc/module/toc', $docModuleToc);
$this->addRoute('doc/module/pdf', $docModulePdf);

View File

@ -2,7 +2,7 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
/** @var $this \Icinga\Application\Modules\Module */
/** @type $this \Icinga\Application\Modules\Module */
$this->providePermission(
'monitoring/command/*',

View File

@ -112,7 +112,7 @@ class AuthBackendPage extends Form
}
$this->addElements($backendForm->getElements());
$this->getElement('name')->setValue('icingaweb');
$this->getElement('name')->setValue('icingaweb2');
}
/**

View File

@ -38,10 +38,6 @@ class TokenValidator extends Zend_Validate_Abstract
mt('setup', 'Cannot validate token, file "%s" is empty. Please define a token.'),
$tokenPath
),
'TOKEN_FILE_PUBLIC' => sprintf(
mt('setup', 'Cannot validate token, file "%s" must only be accessible by the webserver\'s user.'),
$tokenPath
),
'TOKEN_INVALID' => mt('setup', 'Invalid token supplied.')
);
}
@ -56,12 +52,6 @@ class TokenValidator extends Zend_Validate_Abstract
*/
public function isValid($value, $context = null)
{
$tokenStats = @stat($this->tokenPath);
if (($tokenStats['mode'] & 4) === 4) {
$this->_error('TOKEN_FILE_PUBLIC');
return false;
}
try {
$file = new File($this->tokenPath);
$expectedToken = trim($file->fgets());

View File

@ -9,6 +9,7 @@ use Icinga\Web\Form;
use Icinga\Web\Wizard;
use Icinga\Web\Request;
use Icinga\Application\Config;
use Icinga\Application\Icinga;
use Icinga\Application\Platform;
use Icinga\Module\Setup\Forms\ModulePage;
use Icinga\Module\Setup\Forms\WelcomePage;
@ -343,7 +344,7 @@ class WebWizard extends Wizard implements SetupWizard
);
}
$configDir = $this->getConfigDir();
$configDir = Icinga::app()->getConfigDir();
$setup->addStep(
new MakeDirStep(
array(
@ -528,12 +529,12 @@ class WebWizard extends Wizard implements SetupWizard
)
);
$configDir = $this->getConfigDir();
$configDir = Icinga::app()->getConfigDir();
$requirements->addMandatory(
mt('setup', 'Writable Config Directory'),
mt(
'setup',
'The Icinga Web 2 configuration directory defaults to "/etc/icingaweb", if' .
'The Icinga Web 2 configuration directory defaults to "/etc/icingaweb2", if' .
' not explicitly set in the environment variable "ICINGAWEB_CONFIGDIR".'
),
is_writable($configDir),
@ -551,21 +552,4 @@ class WebWizard extends Wizard implements SetupWizard
return $requirements;
}
/**
* Return the configuration directory of Icinga Web 2
*
* @return string
*/
protected function getConfigDir()
{
if (array_key_exists('ICINGAWEB_CONFIGDIR', $_SERVER)) {
$configDir = $_SERVER['ICINGAWEB_CONFIGDIR'];
} else {
$configDir = '/etc/icingaweb';
}
$canonical = realpath($configDir);
return $canonical ? $canonical : $configDir;
}
}

View File

@ -101,7 +101,7 @@ class GettextTranslationHelper
*/
public function __construct(ApplicationBootstrap $bootstrap, $locale)
{
$this->moduleMgr = $bootstrap->getModuleManager()->loadCoreModules()->loadEnabledModules();
$this->moduleMgr = $bootstrap->getModuleManager()->loadEnabledModules();
$this->appDir = $bootstrap->getApplicationDir();
$this->locale = $locale;
}

View File

@ -1,4 +1,4 @@
Alias /icingaweb "/usr/share/icingaweb2/public"
Alias /icingaweb2 "/usr/share/icingaweb2/public"
<Directory "/usr/share/icingaweb2/public">
Options SymLinksIfOwnerMatch
@ -23,7 +23,7 @@ Alias /icingaweb "/usr/share/icingaweb2/public"
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /icingaweb/
RewriteBase /icingaweb2/
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d

View File

@ -3,4 +3,4 @@
require_once '/usr/share/php/Icinga/Application/Cli.php';
Icinga\Application\Cli::start('/usr/share/icingaweb')->dispatch();
Icinga\Application\Cli::start('/usr/share/icingaweb2')->dispatch();

View File

@ -0,0 +1,3 @@
[documentation]
icingaweb2 = /usr/share/doc/icingaweb2/markdown
modules = /usr/share/doc/icingaweb2/modules/{module}/markdown