Add a default file mode for new configuration files

The file mode which can be configured in the general configuration is now
used when creating new configuration files with the PreservingIniWriter.
This commit is contained in:
Johannes Meyer 2014-10-21 17:02:21 +02:00
parent d201cff087
commit f5c4708ae2
6 changed files with 78 additions and 7 deletions

View File

@ -8,6 +8,8 @@ use DateTimeZone;
use Icinga\Web\Form;
use Icinga\Util\Translator;
use Icinga\Data\ResourceFactory;
use Icinga\Web\Form\Element\Number;
use Icinga\Config\PreservingIniWriter;
/**
* Form class to modify the general application configuration
@ -65,6 +67,20 @@ class ApplicationConfigForm extends Form
)
);
$this->addElement(
new Number(
'global_filemode',
array(
'required' => true,
'label' => t('Default File Mode'),
'description' => t(
'This is the global default file mode for new configuration files created by Icinga Web 2.'
),
'value' => decoct(PreservingIniWriter::$fileMode)
)
)
);
$this->addElement(
'text',
'global_modulePath',

View File

@ -38,8 +38,11 @@ class GeneralConfigPage extends Form
)
);
// TODO: This is splitted as not all elements are required (as of d201cff)
$appForm = new ApplicationConfigForm();
$this->addElement($appForm->createElements($formData)->getElement('global_modulePath'));
$appForm->createElements($formData);
$this->addElement($appForm->getElement('global_modulePath'));
$this->addElement($appForm->getElement('global_filemode'));
$loggingForm = new LoggingConfigForm();
$this->addElements($loggingForm->createElements($formData)->getElements());

View File

@ -156,6 +156,10 @@ $loggingType = $summary['setup_general_config']['logging_log'];
t('Icinga Web 2 will look for modules at: %s'),
$summary['setup_general_config']['global_modulePath']
); ?></li>
<li><?= sprintf(
t('Icinga Web 2 will save new configuration files using the mode "%s".'),
$summary['setup_general_config']['global_filemode']
); ?></li>
<li><?= sprintf(
$prefType === 'ini' ? sprintf(
t('Preferences will be stored per user account in INI files at: %s'),

View File

@ -15,6 +15,7 @@ use Icinga\Logger\Logger;
use Icinga\Util\DateTimeFactory;
use Icinga\Util\Translator;
use Icinga\Exception\IcingaException;
use Icinga\Config\PreservingIniWriter;
/**
* This class bootstraps a thin Icinga application layer
@ -363,12 +364,20 @@ abstract class ApplicationBootstrap
protected function loadConfig()
{
Config::$configDir = $this->configDir;
try {
$this->config = Config::app();
} catch (NotReadableError $e) {
Logger::error(new IcingaException('Cannot load application configuration. An exception was thrown:', $e));
$this->config = new Zend_Config(array());
}
if ($this->config->global !== null) {
PreservingIniWriter::$fileMode = octdec($this->config->global->get('filemode', '0664'));
} else {
PreservingIniWriter::$fileMode = 0664;
}
return $this;
}

View File

@ -131,13 +131,18 @@ class WebInstaller implements Installer
$config = array(
'global' => array(
'modulepath' => $this->pageData['setup_general_config']['global_modulePath']
'modulepath' => $this->pageData['setup_general_config']['global_modulePath'],
'filemode' => $this->pageData['setup_general_config']['global_filemode']
),
'preferences' => $preferencesConfig,
'logging' => $loggingConfig
);
$writer = new PreservingIniWriter(array('config' => new Zend_Config($config), 'filename' => $configPath));
$writer = new PreservingIniWriter(array(
'config' => new Zend_Config($config),
'filename' => $configPath,
'filemode' => octdec($this->pageData['setup_general_config']['global_filemode'])
));
$writer->write();
}
@ -178,7 +183,8 @@ class WebInstaller implements Installer
$writer = new PreservingIniWriter(array(
'config' => new Zend_Config($resourceConfig),
'filename' => $configPath
'filename' => $configPath,
'filemode' => octdec($this->pageData['setup_general_config']['global_filemode'])
));
$writer->write();
}
@ -213,7 +219,8 @@ class WebInstaller implements Installer
$writer = new PreservingIniWriter(array(
'config' => new Zend_Config($backendConfig),
'filename' => $configPath
'filename' => $configPath,
'filemode' => octdec($this->pageData['setup_general_config']['global_filemode'])
));
$writer->write();
}

View File

@ -6,6 +6,7 @@ namespace Icinga\Config;
use Zend_Config;
use Zend_Config_Ini;
use Zend_Config_Exception;
use Zend_Config_Writer_FileAbstract;
use Icinga\Config\IniEditor;
@ -21,11 +22,18 @@ class PreservingIniWriter extends Zend_Config_Writer_FileAbstract
*/
protected $options;
/**
* The mode to set on new files
*
* @var int
*/
public static $fileMode;
/**
* Create a new PreservingIniWriter
*
* @param array $options Supports all options of Zend_Config_Writer and additional
* options for the internal IniEditor:
* @param array $options Supports all options of Zend_Config_Writer and additional options:
* * filemode: The mode to set on new files
* * valueIndentation: The indentation level of the values
* * commentIndentation: The indentation level of the comments
* * sectionSeparators: The amount of newlines between sections
@ -107,6 +115,30 @@ class PreservingIniWriter extends Zend_Config_Writer_FileAbstract
return $editor->getText();
}
/**
* Write configuration to file and set file mode in case it does not exist yet
*
* @param string $filename
* @param Zend_Config $config
* @param bool $exclusiveLock
*/
public function write($filename = null, Zend_Config $config = null, $exclusiveLock = null)
{
$filePath = $filename !== null ? $filename : $this->_filename;
$setMode = false === file_exists($filePath);
parent::write($filename, $config, $exclusiveLock);
if ($setMode) {
$mode = isset($this->options['filemode']) ? $this->options['filemode'] : static::$fileMode;
$old = umask(0); // Make sure that the mode we're going to set doesn't get mangled
if (is_int($mode) && false === @chmod($filePath, $mode)) {
throw new Zend_Config_Exception(sprintf('Failed to set file mode "%o" on file "%s"', $mode, $filePath));
}
umask($old);
}
}
/**
* Create a property diff and apply the changes to the editor
*