commit
78a3f1ce57
@ -6,10 +6,11 @@ function( calamares_add_module_subdirectory )
|
||||
# If this subdirectory has a CMakeLists.txt, we add_subdirectory it...
|
||||
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" )
|
||||
# ...otherwise, we look for a module.desc.
|
||||
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,8 +18,14 @@ 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 )
|
||||
install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBDIRECTORY}/${MODULE_FILE}
|
||||
DESTINATION ${MODULE_DESTINATION} )
|
||||
|
||||
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()
|
||||
|
||||
@ -30,7 +37,7 @@ function( calamares_add_module_subdirectory )
|
||||
message( "" )
|
||||
endif()
|
||||
else()
|
||||
message( "-- ${BoldYellow}Warning:${ColorReset} tried to add module subdirectory ${BoldRed}${SUBDIRECTORY}${ColorReset} which has no CMakeLists.txt or module.conf." )
|
||||
message( "-- ${BoldYellow}Warning:${ColorReset} tried to add module subdirectory ${BoldRed}${SUBDIRECTORY}${ColorReset} which has no CMakeLists.txt or module.desc." )
|
||||
message( "" )
|
||||
endif()
|
||||
endfunction()
|
||||
|
@ -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_CONFIG_FILE} ${PLUGIN_CONFIG_FILE} COPYONLY )
|
||||
install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_CONFIG_FILE}
|
||||
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 share/calamares/modules )
|
||||
endif()
|
||||
endfunction()
|
||||
|
@ -19,6 +19,7 @@ prepare:
|
||||
- locale
|
||||
- keyboard
|
||||
- partition
|
||||
- users
|
||||
- summary
|
||||
|
||||
# Phase 2 - install.
|
||||
@ -26,15 +27,15 @@ prepare:
|
||||
# allowed, their names should be added here as placeholders to specify the order in
|
||||
# which view module jobs should be enqueued. Job modules are also allowed.
|
||||
install:
|
||||
- dummyprocess
|
||||
- dummypython
|
||||
#- dummyprocess
|
||||
#- dummypython
|
||||
- partition
|
||||
- mount
|
||||
#- unsquashfs
|
||||
- unsquashfs
|
||||
- fstab
|
||||
- locale
|
||||
- keyboard
|
||||
#- users
|
||||
- users
|
||||
- umount
|
||||
|
||||
# Phase 3 - postinstall.
|
||||
|
@ -31,6 +31,9 @@
|
||||
#include "viewpages/ViewStep.h"
|
||||
#include "ViewManager.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
||||
|
||||
CalamaresApplication::CalamaresApplication( int& argc, char *argv[] )
|
||||
: QApplication( argc, argv )
|
||||
@ -130,7 +133,54 @@ CalamaresApplication::startPhase( Calamares::Phase phase )
|
||||
void
|
||||
CalamaresApplication::initSettings()
|
||||
{
|
||||
new Calamares::Settings( isDebug(), this );
|
||||
QFileInfo settingsFile;
|
||||
if ( CalamaresUtils::isAppDataDirOverridden() )
|
||||
{
|
||||
settingsFile = QFileInfo( CalamaresUtils::appDataDir().absoluteFilePath( "settings.conf" ) );
|
||||
if ( !settingsFile.exists() || !settingsFile.isReadable() )
|
||||
{
|
||||
cLog() << "FATAL ERROR: explicitly configured application data directory"
|
||||
<< CalamaresUtils::appDataDir().absolutePath()
|
||||
<< "does not contain a valid settings.conf file."
|
||||
<< "\nCowardly refusing to continue startup without settings.";
|
||||
::exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QStringList settingsFileCandidatesByPriority;
|
||||
if ( isDebug() )
|
||||
{
|
||||
settingsFileCandidatesByPriority.append(
|
||||
QDir::currentPath() +
|
||||
QDir::separator() +
|
||||
"settings.conf" );
|
||||
}
|
||||
settingsFileCandidatesByPriority.append( "/etc/calamares/settings.conf" );
|
||||
settingsFileCandidatesByPriority.append( CalamaresUtils::appDataDir()
|
||||
.absoluteFilePath( "settings.conf" ) );
|
||||
|
||||
foreach ( const QString& path, settingsFileCandidatesByPriority )
|
||||
{
|
||||
QFileInfo pathFi( path );
|
||||
if ( pathFi.exists() && pathFi.isReadable() )
|
||||
{
|
||||
settingsFile = pathFi;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !settingsFile.exists() || !settingsFile.isReadable() )
|
||||
{
|
||||
cLog() << "FATAL ERROR: none of the expected configuration file paths ("
|
||||
<< settingsFileCandidatesByPriority.join( ", " )
|
||||
<< ") contain a valid settings.conf file."
|
||||
<< "\nCowardly refusing to continue startup without settings.";
|
||||
::exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
|
||||
new Calamares::Settings( settingsFile.absoluteFilePath(), isDebug(), this );
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,7 +41,7 @@ main( int argc, char *argv[] )
|
||||
parser.addOption( debugOption );
|
||||
|
||||
QCommandLineOption configOption( QStringList() << "c" << "config",
|
||||
"Configuration dir to use, for testing purposes.", "config" );
|
||||
"Configuration directory to use, for testing purposes.", "config" );
|
||||
parser.addOption( configOption );
|
||||
|
||||
parser.process( a );
|
||||
|
@ -42,6 +42,7 @@ namespace CalamaresUtils
|
||||
{
|
||||
|
||||
static QDir s_appDataDir( CMAKE_INSTALL_FULL_DATADIR );
|
||||
static bool s_isAppDataDirOverridden = false;
|
||||
|
||||
static bool
|
||||
isWritableDir( const QDir& dir )
|
||||
@ -76,6 +77,14 @@ void
|
||||
setAppDataDir( const QDir& dir )
|
||||
{
|
||||
s_appDataDir = dir;
|
||||
s_isAppDataDirOverridden = true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
isAppDataDirOverridden()
|
||||
{
|
||||
return s_isAppDataDirOverridden;
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,6 +40,7 @@ namespace CalamaresUtils
|
||||
* Override app data dir. Only for testing purposes.
|
||||
*/
|
||||
DLLEXPORT void setAppDataDir( const QDir& dir );
|
||||
DLLEXPORT bool isAppDataDirOverridden();
|
||||
}
|
||||
|
||||
#endif // CALAMARESUTILS_H
|
||||
|
@ -40,23 +40,17 @@ Settings::instance()
|
||||
}
|
||||
|
||||
|
||||
Settings::Settings( bool debugMode, QObject* parent )
|
||||
Settings::Settings( const QString& settingsFilePath,
|
||||
bool debugMode,
|
||||
QObject* parent )
|
||||
: QObject( parent )
|
||||
, m_debug( debugMode )
|
||||
{
|
||||
QFileInfo settingsFile( CalamaresUtils::appDataDir().absoluteFilePath( "settings.conf" ) );
|
||||
if ( debugMode )
|
||||
{
|
||||
QFileInfo localFile( QDir( QDir::currentPath() ).absoluteFilePath( "settings.conf" ) );
|
||||
if ( localFile.exists() && localFile.isReadable() )
|
||||
settingsFile.setFile( localFile.absoluteFilePath() );
|
||||
}
|
||||
QFile file( settingsFile.absoluteFilePath() );
|
||||
|
||||
cDebug() << "Using Calamares settings file at" << settingsFilePath;
|
||||
QFile file( settingsFilePath );
|
||||
if ( file.exists() && file.open( QFile::ReadOnly | QFile::Text ) )
|
||||
{
|
||||
QByteArray ba = file.readAll();
|
||||
cDebug() << ba;
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -33,7 +33,9 @@ class UIDLLEXPORT Settings : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Settings( bool debugMode, QObject *parent = nullptr );
|
||||
explicit Settings( const QString& settingsFilePath,
|
||||
bool debugMode,
|
||||
QObject *parent = nullptr );
|
||||
|
||||
static Settings* instance();
|
||||
//TODO: load from JSON then emit ready
|
||||
|
@ -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,21 @@ 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;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node doc = YAML::Load( ba.constData() );
|
||||
if ( !doc.IsMap() )
|
||||
{
|
||||
cDebug() << Q_FUNC_INFO << "bad module metadata format"
|
||||
cLog() << Q_FUNC_INFO << "bad module descriptor format"
|
||||
<< path;
|
||||
return nullptr;
|
||||
}
|
||||
@ -91,7 +81,7 @@ Module::fromConfigFile( const QString& path )
|
||||
if ( !doc[ "type" ] ||
|
||||
!doc[ "interface" ] )
|
||||
{
|
||||
cDebug() << Q_FUNC_INFO << "bad module metadata format"
|
||||
cLog() << Q_FUNC_INFO << "bad module descriptor format"
|
||||
<< path;
|
||||
return nullptr;
|
||||
}
|
||||
@ -119,7 +109,7 @@ Module::fromConfigFile( const QString& path )
|
||||
|
||||
if ( !m )
|
||||
{
|
||||
cDebug() << Q_FUNC_INFO << "bad module type or interface string"
|
||||
cLog() << Q_FUNC_INFO << "bad module type or interface string"
|
||||
<< path << typeString << intfString;
|
||||
return nullptr;
|
||||
}
|
||||
@ -127,6 +117,8 @@ Module::fromConfigFile( const QString& path )
|
||||
QFileInfo mfi( path );
|
||||
m->m_directory = mfi.absoluteDir().absolutePath();
|
||||
|
||||
m->loadConfigurationFile();
|
||||
|
||||
m->initFrom( doc );
|
||||
return m;
|
||||
}
|
||||
@ -141,6 +133,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();
|
||||
cLog() << Q_FUNC_INFO << "module configuration file"
|
||||
<< path << ":\n" << ba;
|
||||
|
||||
YAML::Node doc = YAML::Load( ba.constData() );
|
||||
if ( !doc.IsMap() )
|
||||
{
|
||||
cLog() << Q_FUNC_INFO << "bad module configuration format"
|
||||
<< path;
|
||||
return;
|
||||
}
|
||||
|
||||
m_configurationMap = CalamaresUtils::yamlMapToVariant( doc ).toMap();
|
||||
return;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
Module::name() const
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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" );
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -1,18 +1,60 @@
|
||||
Calamares modules directory
|
||||
Calamares modules
|
||||
===
|
||||
|
||||
Calamares modules are plugins that provide features like installer pages, batch jobs, etc. Each Calamares module lives in its own directory.
|
||||
Calamares modules are plugins that provide features like installer pages, batch jobs, etc.
|
||||
Each Calamares module lives in its own directory.
|
||||
|
||||
All modules are installed in `$DESTDIR/lib/calamares/modules`.
|
||||
|
||||
### Module directory and descriptor
|
||||
A Calamares module must have a *module descriptor file*, named `module.desc`, this file must be placed in the module's
|
||||
directory.
|
||||
The module descriptor file is a YAML 1.2 document which defines the module's name, type, interface and possibly other
|
||||
properties. The name of the module as defined in `module.desc` must be the same as the name of the module's directory.
|
||||
|
||||
There are two types of Calamares module:
|
||||
* viewmodule,
|
||||
* jobmodule.
|
||||
|
||||
There are three interfaces for Calamares modules:
|
||||
* qtplugin,
|
||||
* python,
|
||||
* process.
|
||||
|
||||
### Module-specific configuration
|
||||
A Calamares module *may* read a module configuration file, named `<modulename>.conf`. If such a file is present in the
|
||||
module's directory, it is shipped as a *default* configuration file.
|
||||
The module configuration file, if it exists, is a YAML 1.2 document which contains a YAML map of anything.
|
||||
All default module configuration files are installed in `$DESTDIR/share/calamares/modules` but can be overridden by
|
||||
files with the same name placed manually (or by the packager) in `/etc/calamares/modules`.
|
||||
|
||||
### Qt plugin viewmodules
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
All code in Python job modules must obey PEP8, the only exception are `libcalamares.globalstorage` keys, which should always be camelCaseWithLowerCaseInitial.
|
||||
`CMakeLists.txt` is *not* used for Python and process jobmodules.
|
||||
|
||||
A Python jobmodule is a Python program which imports libcalamares and has a function `run()` as entry point.
|
||||
`run()` must return `None` if everything went well, or a tuple `(str,str)` with an error message and description if
|
||||
something went wrong.
|
||||
|
||||
Calamares offers a Python API for module developers, the core Calamares functionality is exposed as `libcalamares.job`
|
||||
for job data, `libcalamares.globalstorage` for shared data and `libcalamares.utils` for generic utility functions.
|
||||
Documentation is inline.
|
||||
|
||||
All code in Python job modules must obey PEP8, the only exception are `libcalamares.globalstorage` keys, which should
|
||||
always be camelCaseWithLowerCaseInitial.
|
||||
|
||||
For testing and debugging we provide the `testmodule.py` script which fakes a limited Calamares Python environment for
|
||||
running a single jobmodule.
|
@ -4,6 +4,5 @@
|
||||
type: "job"
|
||||
name: "dummyprocess"
|
||||
interface: "process"
|
||||
requires: []
|
||||
command: "/bin/sh -c \"touch ~/calamares-dummyprocess\""
|
||||
timeout: 5
|
18
src/modules/dummypython/dummypython.conf
Normal file
18
src/modules/dummypython/dummypython.conf
Normal 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"
|
@ -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"
|
7
src/modules/dummypython/module.desc
Normal file
7
src/modules/dummypython/module.desc
Normal 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
|
10
src/modules/fstab/fstab.conf
Normal file
10
src/modules/fstab/fstab.conf
Normal 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
|
@ -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
|
5
src/modules/fstab/module.desc
Normal file
5
src/modules/fstab/module.desc
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
type: "job"
|
||||
name: "fstab"
|
||||
interface: "python"
|
||||
script: "main.py"
|
@ -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
|
||||
|
@ -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"
|
@ -1,6 +1,5 @@
|
||||
---
|
||||
type: "job"
|
||||
name: "grub"
|
||||
interface: "python"
|
||||
requires: []
|
||||
script: "main.py"
|
||||
configuration:
|
2
src/modules/initcpio/initcpio.conf
Normal file
2
src/modules/initcpio/initcpio.conf
Normal file
@ -0,0 +1,2 @@
|
||||
---
|
||||
kernel: linux312
|
@ -1,7 +1,5 @@
|
||||
---
|
||||
type: "job"
|
||||
name: "initcpio"
|
||||
interface: "python"
|
||||
requires: []
|
||||
script: "main.py"
|
||||
configuration:
|
||||
kernel: linux312
|
@ -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
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include "GlobalStorage.h"
|
||||
#include "JobQueue.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QProcess>
|
||||
@ -262,5 +263,6 @@ KeyboardPage::onListVariantCurrentItemChanged( QListWidgetItem* current, QListWi
|
||||
|
||||
m_selectedLayout = layout;
|
||||
m_selectedVariant = variant;
|
||||
cDebug() << "xkbmap selection changed to: " << layout << "-" << variant;
|
||||
}
|
||||
|
||||
|
@ -4,5 +4,4 @@
|
||||
type: "view"
|
||||
name: "keyboard"
|
||||
interface: "qtplugin"
|
||||
requires: []
|
||||
load: "libcalamares_viewmodule_keyboard.so"
|
@ -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
|
||||
|
3
src/modules/locale/locale.conf
Normal file
3
src/modules/locale/locale.conf
Normal file
@ -0,0 +1,3 @@
|
||||
---
|
||||
region: "Europe"
|
||||
zone: "London"
|
@ -4,8 +4,4 @@
|
||||
type: "view"
|
||||
name: "locale"
|
||||
interface: "qtplugin"
|
||||
requires: []
|
||||
load: "libcalamares_viewmodule_locale.so"
|
||||
configuration:
|
||||
region: "Europe"
|
||||
zone: "London"
|
@ -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
|
5
src/modules/mount/module.desc
Normal file
5
src/modules/mount/module.desc
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
type: "job"
|
||||
name: "mount"
|
||||
interface: "python"
|
||||
script: "main.py"
|
11
src/modules/mount/mount.conf
Normal file
11
src/modules/mount/mount.conf
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
extraMounts:
|
||||
- device: proc
|
||||
fs: proc
|
||||
mountPoint: /proc
|
||||
- device: sys
|
||||
fs: sysfs
|
||||
mountPoint: /sys
|
||||
- device: /dev
|
||||
mountPoint: /dev
|
||||
options: bind
|
@ -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
|
||||
|
@ -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"
|
@ -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
|
||||
|
@ -4,5 +4,4 @@
|
||||
type: "view"
|
||||
name: "summary"
|
||||
interface: "qtplugin"
|
||||
requires: []
|
||||
load: "libcalamares_viewmodule_summary.so"
|
@ -34,11 +34,11 @@ except ImportError:
|
||||
|
||||
class Job:
|
||||
|
||||
def __init__(self, working_path, doc):
|
||||
def __init__(self, working_path, doc, cfg_doc):
|
||||
self.module_name = doc["name"]
|
||||
self.pretty_name = "Testing job " + doc["name"]
|
||||
self.working_path = working_path
|
||||
self.configuration = doc["configuration"]
|
||||
self.configuration = cfg_doc
|
||||
|
||||
def setprogress(self, progress):
|
||||
print("Job set progress to {}%.".format(progress * 100))
|
||||
@ -47,14 +47,16 @@ class Job:
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("moduledir",
|
||||
help="Dir containing the Python module")
|
||||
help="Dir containing the Python module.")
|
||||
parser.add_argument("globalstorage_yaml", nargs="?",
|
||||
help="A yaml file to initialize GlobalStorage")
|
||||
help="A yaml file to initialize GlobalStorage.")
|
||||
parser.add_argument("configuration_yaml", nargs="?",
|
||||
help="A yaml file to initialize the configuration dict.")
|
||||
args = parser.parse_args()
|
||||
|
||||
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)
|
||||
|
||||
@ -62,16 +64,21 @@ def main():
|
||||
print("Only Python jobs can be tested.")
|
||||
return 1
|
||||
|
||||
libcalamares.job = Job(args.moduledir, doc)
|
||||
libcalamares.globalstorage = libcalamares.GlobalStorage()
|
||||
|
||||
# if a file for simulating globalStorage contents is provided, load it
|
||||
if args.globalstorage_yaml:
|
||||
with open(args.globalstorage_yaml) as f:
|
||||
doc = yaml.load(f)
|
||||
for key, value in doc.items():
|
||||
gs_doc = yaml.load(f)
|
||||
for key, value in gs_doc.items():
|
||||
libcalamares.globalstorage.insert(key, value)
|
||||
|
||||
cfg_doc = dict()
|
||||
if args.configuration_yaml:
|
||||
with open(args.configuration_yaml) as f:
|
||||
cfg_doc = yaml.load(f)
|
||||
|
||||
libcalamares.job = Job(args.moduledir, doc, cfg_doc)
|
||||
libcalamares.globalstorage = libcalamares.GlobalStorage()
|
||||
|
||||
scriptpath = os.path.abspath(args.moduledir)
|
||||
sys.path.append(scriptpath)
|
||||
import main
|
||||
|
@ -1,6 +1,5 @@
|
||||
---
|
||||
type: "job"
|
||||
name: "umount"
|
||||
interface: "python"
|
||||
requires: []
|
||||
script: "main.py"
|
||||
configuration:
|
@ -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: ""
|
4
src/modules/unsquashfs/unsquashfs.conf
Normal file
4
src/modules/unsquashfs/unsquashfs.conf
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
unpack:
|
||||
- source: "/path/to/squashfs/image.sqfs"
|
||||
destination: ""
|
@ -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
|
||||
|
@ -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"
|
Loading…
Reference in New Issue
Block a user