Big configuration overhaul.

Module descriptors are now module.desc, no configuration allowed inside.
Module config files are <modulename>.conf, installed in
share/calamares/modules.
settings.conf is read from /etc/calamares, then share/calamares, and if
running with --debug also in the current dir.
Module config files are read from /etc/calamares/modules, then
share/calamares/modules, and if running with --debug also in
src/modules/<modulename> relative to the current dir.
This commit is contained in:
Teo Mrnjavac 2014-08-05 18:18:57 +02:00
parent 75e9fd6aa3
commit 8f10c21e5b
38 changed files with 161 additions and 135 deletions

View File

@ -7,9 +7,10 @@ function( calamares_add_module_subdirectory )
if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/CMakeLists.txt" )
add_subdirectory( ${SUBDIRECTORY} )
# ...otherwise, we look for a module.conf.
elseif( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/module.conf" )
elseif( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/module.desc" )
set( MODULES_DIR ${CMAKE_INSTALL_LIBDIR}/calamares/modules )
set( MODULE_DESTINATION ${MODULES_DIR}/${SUBDIRECTORY} )
set( MODULE_CONFIG_FILE ${SUBDIRECTORY}.conf )
# We glob all the files inside the subdirectory, and we make sure they are
# synced with the bindir structure and installed.
@ -17,9 +18,15 @@ function( calamares_add_module_subdirectory )
foreach( MODULE_FILE ${MODULE_FILES} )
if( NOT IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/${MODULE_FILE} )
configure_file( ${SUBDIRECTORY}/${MODULE_FILE} ${SUBDIRECTORY}/${MODULE_FILE} COPYONLY )
if( "${MODULE_FILE}" STREQUAL "${MODULE_CONFIG_FILE}" )
install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBDIRECTORY}/${MODULE_FILE}
DESTINATION share/calamares/modules )
else()
install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBDIRECTORY}/${MODULE_FILE}
DESTINATION ${MODULE_DESTINATION} )
endif()
endif()
endforeach()
message( "-- ${BoldYellow}Found ${CALAMARES_APPLICATION_NAME} module: ${BoldRed}${SUBDIRECTORY}${ColorReset}" )

View File

@ -5,11 +5,13 @@ function( calamares_add_plugin )
# parse arguments ( name needs to be saved before passing ARGN into the macro )
set( NAME ${ARGV0} )
set( options NO_INSTALL SHARED_LIB )
set( oneValueArgs NAME TYPE EXPORT_MACRO CONFIG_FILE )
set( oneValueArgs NAME TYPE EXPORT_MACRO )
set( multiValueArgs SOURCES UI LINK_LIBRARIES COMPILE_DEFINITIONS )
cmake_parse_arguments( PLUGIN "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
set( PLUGIN_NAME ${NAME} )
set( PLUGIN_DESTINATION ${CMAKE_INSTALL_LIBDIR}/calamares/modules/${PLUGIN_NAME} )
set( PLUGIN_DESC_FILE module.desc )
set( PLUGIN_CONFIG_FILE ${NAME}.conf )
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" )
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" )
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" )
@ -62,7 +64,13 @@ function( calamares_add_plugin )
calamares_add_library( ${calamares_add_library_args} )
configure_file( ${PLUGIN_DESC_FILE} ${PLUGIN_DESC_FILE} COPYONLY )
install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_DESC_FILE}
DESTINATION ${PLUGIN_DESTINATION} )
if( EXISTS "${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_CONFIG_FILE}" )
configure_file( ${PLUGIN_CONFIG_FILE} ${PLUGIN_CONFIG_FILE} COPYONLY )
install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_CONFIG_FILE}
DESTINATION ${PLUGIN_DESTINATION} )
DESTINATION share/calamares/modules )
endif()
endfunction()

View File

@ -44,7 +44,10 @@ Settings::Settings( bool debugMode, QObject* parent )
: QObject( parent )
, m_debug( debugMode )
{
QFileInfo settingsFile( CalamaresUtils::appDataDir().absoluteFilePath( "settings.conf" ) );
QFileInfo settingsFile( "/etc/calamares/settings.conf" );
if ( !settingsFile.exists() || !settingsFile.isReadable() )
settingsFile = QFileInfo( CalamaresUtils::appDataDir().absoluteFilePath( "settings.conf" ) );
if ( debugMode )
{
QFileInfo localFile( QDir( QDir::currentPath() ).absoluteFilePath( "settings.conf" ) );

View File

@ -20,8 +20,10 @@
#include "ProcessJobModule.h"
#include "ViewModule.h"
#include "utils/CalamaresUtils.h"
#include "utils/YamlUtils.h"
#include "utils/Logger.h"
#include "Settings.h"
#include "CalamaresConfig.h"
#ifdef WITH_PYTHON
@ -36,30 +38,18 @@
#include <QString>
// Example module.conf
// Example module.desc
/*
---
type: "view" #job or view
name: "foo" #the module name. must be unique and same as the parent directory
interface: "qtplugin" #can be: qtplugin, python, process, ...
requires: [] #list of module names that must also be loaded before this one
*/
void
operator>>( const YAML::Node& node, Calamares::Module* m )
{
m->m_name = QString::fromStdString( node[ "name" ].as< std::string >() );
if ( node[ "requires" ] && node[ "requires" ].IsSequence() )
{
node[ "requires" ] >> m->m_requiredModules;
}
// Module-specific configuration
if ( node[ "configuration" ] && node[ "configuration" ].IsMap() )
{
m->m_configurationMap = CalamaresUtils::yamlMapToVariant( node[ "configuration" ] ).toMap();
}
}
namespace Calamares
@ -69,21 +59,22 @@ Module::~Module()
{}
Module*
Module::fromConfigFile( const QString& path )
Module::fromDescriptorFile( const QString& path )
{
Module* m = nullptr;
QFile metadataFile( path );
if ( metadataFile.exists() && metadataFile.open( QFile::ReadOnly | QFile::Text ) )
QFile descriptorFile( path );
if ( descriptorFile.exists() && descriptorFile.open( QFile::ReadOnly | QFile::Text ) )
{
QByteArray ba = metadataFile.readAll();
cDebug() << Q_FUNC_INFO << "module metadata file: " << ba;
QByteArray ba = descriptorFile.readAll();
cDebug() << Q_FUNC_INFO << "module descriptor file"
<< path << ":\n" << ba;
try
{
YAML::Node doc = YAML::Load( ba.constData() );
if ( !doc.IsMap() )
{
cDebug() << Q_FUNC_INFO << "bad module metadata format"
cDebug() << Q_FUNC_INFO << "bad module descriptor format"
<< path;
return nullptr;
}
@ -91,7 +82,7 @@ Module::fromConfigFile( const QString& path )
if ( !doc[ "type" ] ||
!doc[ "interface" ] )
{
cDebug() << Q_FUNC_INFO << "bad module metadata format"
cDebug() << Q_FUNC_INFO << "bad module descriptor format"
<< path;
return nullptr;
}
@ -127,6 +118,8 @@ Module::fromConfigFile( const QString& path )
QFileInfo mfi( path );
m->m_directory = mfi.absoluteDir().absolutePath();
m->loadConfigurationFile();
m->initFrom( doc );
return m;
}
@ -141,6 +134,50 @@ Module::fromConfigFile( const QString& path )
return nullptr;
}
void
Module::loadConfigurationFile() //throws YAML::Exception
{
QStringList configFilesByPriority;
configFilesByPriority.append(
QString( "/etc/calamares/modules/%1.conf" ).arg( m_name ) );
configFilesByPriority.append(
CalamaresUtils::appDataDir().absoluteFilePath(
QString( "modules/%1.conf" ).arg( m_name ) ) );
if ( Settings::instance()->debugMode() )
{
configFilesByPriority.append(
QDir( QDir::currentPath() ).absoluteFilePath(
QString( "src/modules/%1/%1.conf" ).arg( m_name ) ) );
}
foreach ( const QString& path, configFilesByPriority )
{
QFile configFile( path );
if ( configFile.exists() && configFile.open( QFile::ReadOnly | QFile::Text ) )
{
QByteArray ba = configFile.readAll();
cDebug() << Q_FUNC_INFO << "module configuration file"
<< path << ":\n" << ba;
YAML::Node doc = YAML::Load( ba.constData() );
if ( !doc.IsMap() )
{
cDebug() << Q_FUNC_INFO << "bad module configuration format"
<< path;
return;
}
m_configurationMap = CalamaresUtils::yamlMapToVariant( doc ).toMap();
return;
}
else
continue;
}
}
QString
Module::name() const
{

View File

@ -59,7 +59,7 @@ public:
};
virtual ~Module();
static Module* fromConfigFile( const QString& path );
static Module* fromDescriptorFile( const QString& path );
virtual QString name() const;
virtual QStringList requiredModules() const;
@ -80,6 +80,7 @@ protected:
QVariantMap m_configurationMap;
private:
void loadConfigurationFile(); //throws YAML::Exception
QString m_name;
Type m_type;
Interface m_interface;

View File

@ -27,7 +27,7 @@
#include <QDir>
#include <QTimer>
#define MODULE_CONFIG_FILENAME "module.conf"
#define MODULE_CONFIG_FILENAME "module.desc"
namespace Calamares
{
@ -92,7 +92,7 @@ ModuleManager::loadModules( Phase phase )
continue;
}
recursiveLoad( moduleName );
doLoad( moduleName );
}
emit modulesLoaded( phase );
// Loading sequence:
@ -114,7 +114,7 @@ ModuleManager::doInit()
// might (should) contain Calamares modules of any type/interface.
// For each modules search path (directory), it is expected that each module
// lives in its own subdirectory. This subdirectory must have the same name as
// the module name, and must contain a settings file named module.conf.
// the module name, and must contain a settings file named module.desc.
// If at any time the module loading procedure finds something unexpected, it
// silently skips to the next module or search path. --Teo 6/2014
foreach ( const QString& path, m_paths )
@ -137,7 +137,7 @@ ModuleManager::doInit()
continue;
}
Module* moduleInfo = Module::fromConfigFile( metadataFileInfo.absoluteFilePath() );
Module* moduleInfo = Module::fromDescriptorFile( metadataFileInfo.absoluteFilePath() );
if ( moduleInfo &&
( moduleInfo->name() == currentDir.dirName() ) &&
@ -170,16 +170,9 @@ ModuleManager::doInit()
void
ModuleManager::recursiveLoad( const QString& moduleName )
ModuleManager::doLoad( const QString& moduleName )
{
Module* thisModule = m_availableModules.value( moduleName );
foreach ( const QString& module, thisModule->requiredModules() )
{
if ( !m_availableModules.value( module )->isLoaded() )
{
recursiveLoad( module );
}
}
thisModule->loadSelf();
cDebug() << ( thisModule->isLoaded() ? "SUCCESS" : "FAILURE" );
}

View File

@ -58,7 +58,7 @@ private slots:
void doInit();
private:
void recursiveLoad( const QString& moduleName );
void doLoad( const QString& moduleName );
void checkDependencies();
QMap< QString, Module* > m_availableModules;

View File

@ -7,12 +7,12 @@ Calamares modules are plugins that provide features like installer pages, batch
Currently the only way to write a module which exposes one or more installer pages (viewmodule) is through a Qt plugin. Viewmodules should implement `Calamares::ViewStep`. They can also implement `Calamares::Job` to provide jobs.
To add a Qt plugin module, put it in a subdirectory and make sure it has a `module.conf` and a `CMakeLists.txt` with a `calamares_add_plugin` call. It will be picked up automatically by our CMake magic.
To add a Qt plugin module, put it in a subdirectory and make sure it has a `module.desc` and a `CMakeLists.txt` with a `calamares_add_plugin` call. It will be picked up automatically by our CMake magic.
### Python and process jobmodules
Batch jobs for Calamares can be written as Python scripts or as generic commands (shell scripts, external programs, etc.).
To add a Python or process jobmodule, put it in a subdirectory and make sure it has a `module.conf`. It will be picked up automatically by our CMake magic. `CMakeLists.txt` is not used for Python and process jobmodules.
To add a Python or process jobmodule, put it in a subdirectory and make sure it has a `module.desc`. It will be picked up automatically by our CMake magic. `CMakeLists.txt` is not used for Python and process jobmodules.
All code in Python job modules must obey PEP8, the only exception are `libcalamares.globalstorage` keys, which should always be camelCaseWithLowerCaseInitial.

View File

@ -4,6 +4,5 @@
type: "job"
name: "dummyprocess"
interface: "process"
requires: []
command: "/bin/sh -c \"touch ~/calamares-dummyprocess\""
timeout: 5

View File

@ -0,0 +1,18 @@
---
syntax: "YAML map of anything"
example:
whats_this: "module-specific configuration"
from_where: "dummypython.conf"
a_list:
- "item1"
- "item2"
- "item3"
- "item4"
a_list_of_maps:
- name: "an Item"
contents:
- "an element"
- "another element"
- name: "another item"
contents:
- "not much"

View File

@ -1,26 +0,0 @@
# Module metadata file for dummy process jobmodule
# Syntax is YAML 1.2
---
type: "job"
name: "dummypython"
interface: "python"
requires: []
script: "main.py" #assumed relative to the current directory
configuration:
syntax: "YAML map of anything"
example:
whats_this: "module-specific configuration"
from_where: "module.conf"
a_list:
- "item1"
- "item2"
- "item3"
- "item4"
a_list_of_maps:
- name: "an Item"
contents:
- "an element"
- "another element"
- name: "another item"
contents:
- "not much"

View File

@ -0,0 +1,7 @@
# Module metadata file for dummy process jobmodule
# Syntax is YAML 1.2
---
type: "job"
name: "dummypython"
interface: "python"
script: "main.py" #assumed relative to the current directory

View File

@ -0,0 +1,10 @@
---
mountOptions:
default: defaults,noatime
btrfs: defaults,noatime,space_cache,autodefrag
ssdExtraMountOptions:
ext4: discard
jfs: discard
xfs: discard
swap: discard
btrfs: discard,compress=lzo

View File

@ -1,15 +0,0 @@
type: "job"
name: "fstab"
interface: "python"
requires: []
script: "main.py"
configuration:
mountOptions:
default: defaults,noatime
btrfs: defaults,noatime,space_cache,autodefrag
ssdExtraMountOptions:
ext4: discard
jfs: discard
xfs: discard
swap: discard
btrfs: discard,compress=lzo

View File

@ -0,0 +1,5 @@
---
type: "job"
name: "fstab"
interface: "python"
script: "main.py"

View File

@ -2,7 +2,6 @@ include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui )
calamares_add_plugin( greeting
TYPE viewmodule
EXPORT_MACRO PLUGINDLLEXPORT_PRO
CONFIG_FILE module.conf
SOURCES
GreetingViewStep.cpp
GreetingPage.cpp

View File

@ -4,7 +4,4 @@
type: "view" #core or view
name: "greeting" #the module name. must be unique and same as the parent directory
interface: "qtplugin" #can be: qtplugin, python, process, ...
requires: [] #list of module names that must also be loaded. only applies to
#binary plugins! these are actual link-time dependencies, not
#conceptual dependencies for the setup procedure
load: "libcalamares_viewmodule_greeting.so"

View File

@ -1,6 +1,5 @@
---
type: "job"
name: "grub"
interface: "python"
requires: []
script: "main.py"
configuration:

View File

@ -0,0 +1,2 @@
---
kernel: linux312

View File

@ -1,7 +1,5 @@
---
type: "job"
name: "initcpio"
interface: "python"
requires: []
script: "main.py"
configuration:
kernel: linux312

View File

@ -3,7 +3,6 @@ include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui )
calamares_add_plugin( keyboard
TYPE viewmodule
EXPORT_MACRO PLUGINDLLEXPORT_PRO
CONFIG_FILE module.conf
SOURCES
KeyboardViewStep.cpp
KeyboardPage.cpp

View File

@ -4,5 +4,4 @@
type: "view"
name: "keyboard"
interface: "qtplugin"
requires: []
load: "libcalamares_viewmodule_keyboard.so"

View File

@ -3,7 +3,6 @@ include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui )
calamares_add_plugin( locale
TYPE viewmodule
EXPORT_MACRO PLUGINDLLEXPORT_PRO
CONFIG_FILE module.conf
SOURCES
LocaleViewStep.cpp
LocalePage.cpp

View File

@ -0,0 +1,3 @@
---
region: "Europe"
zone: "London"

View File

@ -4,8 +4,4 @@
type: "view"
name: "locale"
interface: "qtplugin"
requires: []
load: "libcalamares_viewmodule_locale.so"
configuration:
region: "Europe"
zone: "London"

View File

@ -1,16 +0,0 @@
type: "job"
name: "mount"
interface: "python"
requires: []
script: "main.py"
configuration:
extraMounts:
- device: proc
fs: proc
mountPoint: /proc
- device: sys
fs: sysfs
mountPoint: /sys
- device: /dev
mountPoint: /dev
options: bind

View File

@ -0,0 +1,5 @@
---
type: "job"
name: "mount"
interface: "python"
script: "main.py"

View File

@ -0,0 +1,11 @@
---
extraMounts:
- device: proc
fs: proc
mountPoint: /proc
- device: sys
fs: sysfs
mountPoint: /sys
- device: /dev
mountPoint: /dev
options: bind

View File

@ -20,7 +20,6 @@ include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui )
calamares_add_plugin( partition
TYPE viewmodule
EXPORT_MACRO PLUGINDLLEXPORT_PRO
CONFIG_FILE module.conf
SOURCES
BootLoaderModel.cpp
CreatePartitionDialog.cpp

View File

@ -4,7 +4,4 @@
type: "view" #core or view
name: "partition" #the module name. must be unique and same as the parent directory
interface: "qtplugin" #can be: qtplugin, python, process, ...
requires: [] #list of module names that must also be loaded. only applies to
#binary plugins! these are actual link-time dependencies, not
#conceptual dependencies for the setup procedure
load: "libcalamares_viewmodule_partition.so"

View File

@ -2,7 +2,6 @@ include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui )
calamares_add_plugin( summary
TYPE viewmodule
EXPORT_MACRO PLUGINDLLEXPORT_PRO
CONFIG_FILE module.conf
SOURCES
SummaryViewStep.cpp
SummaryPage.cpp

View File

@ -4,5 +4,4 @@
type: "view"
name: "summary"
interface: "qtplugin"
requires: []
load: "libcalamares_viewmodule_summary.so"

View File

@ -54,7 +54,7 @@ def main():
print("Testing module in: " + args.moduledir)
confpath = os.path.join(args.moduledir, "module.conf")
confpath = os.path.join(args.moduledir, "module.desc")
with open(confpath) as f:
doc = yaml.load(f)

View File

@ -1,6 +1,5 @@
---
type: "job"
name: "umount"
interface: "python"
requires: []
script: "main.py"
configuration:

View File

@ -3,9 +3,4 @@
type: "job"
name: "unsquashfs"
interface: "python"
requires: []
script: "main.py" #assumed relative to the current directory
configuration:
unpack:
- source: "/path/to/squashfs/image.sqfs"
destination: ""

View File

@ -0,0 +1,4 @@
---
unpack:
- source: "/path/to/squashfs/image.sqfs"
destination: ""

View File

@ -6,7 +6,6 @@ find_package( Crypt )
calamares_add_plugin( users
TYPE viewmodule
EXPORT_MACRO PLUGINDLLEXPORT_PRO
CONFIG_FILE module.conf
SOURCES
CreateUserJob.cpp
SetPasswordJob.cpp

View File

@ -4,7 +4,4 @@
type: "view" #core or view
name: "users" #the module name. must be unique and same as the parent directory
interface: "qtplugin" #can be: qtplugin, python, process, ...
requires: [] #list of module names that must also be loaded. only applies to
#binary plugins! these are actual link-time dependencies, not
#conceptual dependencies for the setup procedure
load: "libcalamares_viewmodule_users.so"