Merge branch 'master' of https://github.com/calamares/calamares into development

This commit is contained in:
Philip Müller 2020-01-25 13:47:26 +01:00
commit 9c59e98f89
36 changed files with 410 additions and 266 deletions

View File

@ -18,6 +18,11 @@ This release contains contributions from (alphabetically by first name):
`branding.desc` specifies *center* or *free* placement. `branding.desc` specifies *center* or *free* placement.
## Modules ## ## Modules ##
- All modules can now set a new key in `module.desc` called *noconfig*.
If this key is set to `true` (the default is `false), no configuration
file is searched-for or loaded, and no warning is printed if the
configuration is missing. This should tidy up some unnecessary warnings
on startup. #1302 #1301
- The *license* module has seen a significant change to its looks. - The *license* module has seen a significant change to its looks.
Actions are now labeled more clearly, and the URL (or filename) Actions are now labeled more clearly, and the URL (or filename)
for each license is displayed. for each license is displayed.

View File

@ -38,6 +38,7 @@
# [RESOURCES resource-file] # [RESOURCES resource-file]
# [REQUIRES module-name...] # [REQUIRES module-name...]
# [NO_INSTALL] # [NO_INSTALL]
# [NO_CONFIG]
# [SHARED_LIB] # [SHARED_LIB]
# [EMERGENCY] # [EMERGENCY]
# ) # )
@ -71,7 +72,7 @@ include( CMakeColors )
function( calamares_add_plugin ) function( calamares_add_plugin )
# parse arguments ( name needs to be saved before passing ARGN into the macro ) # parse arguments ( name needs to be saved before passing ARGN into the macro )
set( NAME ${ARGV0} ) set( NAME ${ARGV0} )
set( options NO_INSTALL SHARED_LIB EMERGENCY ) set( options NO_CONFIG NO_INSTALL SHARED_LIB EMERGENCY )
set( oneValueArgs NAME TYPE EXPORT_MACRO RESOURCES ) set( oneValueArgs NAME TYPE EXPORT_MACRO RESOURCES )
set( multiValueArgs SOURCES UI LINK_LIBRARIES LINK_PRIVATE_LIBRARIES COMPILE_DEFINITIONS REQUIRES ) set( multiValueArgs SOURCES UI LINK_LIBRARIES LINK_PRIVATE_LIBRARIES COMPILE_DEFINITIONS REQUIRES )
cmake_parse_arguments( PLUGIN "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) cmake_parse_arguments( PLUGIN "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
@ -90,6 +91,9 @@ function( calamares_add_plugin )
message( " ${Green}LINK_PRIVATE_LIBRARIES:${ColorReset} ${PLUGIN_LINK_PRIVATE_LIBRARIES}" ) message( " ${Green}LINK_PRIVATE_LIBRARIES:${ColorReset} ${PLUGIN_LINK_PRIVATE_LIBRARIES}" )
message( " ${Green}PLUGIN_DESTINATION:${ColorReset} ${PLUGIN_DESTINATION}" ) message( " ${Green}PLUGIN_DESTINATION:${ColorReset} ${PLUGIN_DESTINATION}" )
if( PLUGIN_CONFIG_FILES ) if( PLUGIN_CONFIG_FILES )
if( PLUGIN_NO_CONFIG )
message( FATAL_ERROR "${Red}NO_CONFIG${ColorReset} is set, with configuration ${Red}${PLUGIN_CONFIG_FILES}${ColorReset}" )
endif()
set( _destination "(unknown)" ) set( _destination "(unknown)" )
if ( INSTALL_CONFIG AND NOT PLUGIN_NO_INSTALL ) if ( INSTALL_CONFIG AND NOT PLUGIN_NO_INSTALL )
set( _destination "${PLUGIN_DATA_DESTINATION}" ) set( _destination "${PLUGIN_DATA_DESTINATION}" )
@ -100,6 +104,10 @@ function( calamares_add_plugin )
set( _destination "[Skipping installation]" ) set( _destination "[Skipping installation]" )
endif() endif()
message( " ${Green}CONFIGURATION_FILES:${ColorReset} ${PLUGIN_CONFIG_FILES} => ${_destination}" ) message( " ${Green}CONFIGURATION_FILES:${ColorReset} ${PLUGIN_CONFIG_FILES} => ${_destination}" )
else()
if( NOT PLUGIN_NO_CONFIG )
message( " ${Red}NO_CONFIG${ColorReset} should be set." )
endif()
endif() endif()
if( PLUGIN_RESOURCES ) if( PLUGIN_RESOURCES )
message( " ${Green}RESOURCES:${ColorReset} ${PLUGIN_RESOURCES}" ) message( " ${Green}RESOURCES:${ColorReset} ${PLUGIN_RESOURCES}" )
@ -170,6 +178,9 @@ function( calamares_add_plugin )
if ( PLUGIN_EMERGENCY ) if ( PLUGIN_EMERGENCY )
file( APPEND ${_file} "emergency: true\n" ) file( APPEND ${_file} "emergency: true\n" )
endif() endif()
if ( PLUGIN_NO_CONFIG )
file( APPEND ${_file} "noconfig: true\n" )
endif()
endif() endif()
if ( NOT PLUGIN_NO_INSTALL ) if ( NOT PLUGIN_NO_INSTALL )

View File

@ -8,7 +8,7 @@
# #
AS=$( which astyle ) AS=$( which astyle )
for _cf in clang-format-7 clang-format-8 clang-format70 clang-format80 for _cf in clang-format-7 clang-format-8 clang-format70 clang-format80 clang-format
do do
# Not an error if this particular clang-format isn't found # Not an error if this particular clang-format isn't found
CF=$( which $_cf || true ) CF=$( which $_cf || true )

View File

@ -113,7 +113,13 @@ DebugWindow::DebugWindow()
} ); } );
// Modules page // Modules page
QStringListModel* modulesModel = new QStringListModel( ModuleManager::instance()->loadedInstanceKeys() ); QStringList modulesKeys;
for ( const auto& m : ModuleManager::instance()->loadedInstanceKeys() )
{
modulesKeys << m.toString();
}
QStringListModel* modulesModel = new QStringListModel( modulesKeys );
m_ui->modulesListView->setModel( modulesModel ); m_ui->modulesListView->setModel( modulesModel );
m_ui->modulesListView->setSelectionMode( QAbstractItemView::SingleSelection ); m_ui->modulesListView->setSelectionMode( QAbstractItemView::SingleSelection );

View File

@ -67,7 +67,7 @@ ViewStepItem::data( int role ) const
toolTip.append( QString( "<br/>Status:\t%1" ).arg( m_step->prettyStatus() ) ); toolTip.append( QString( "<br/>Status:\t%1" ).arg( m_step->prettyStatus() ) );
toolTip.append( toolTip.append(
QString( "<br/>Source:\t%1" ) QString( "<br/>Source:\t%1" )
.arg( m_step->moduleInstanceKey().isEmpty() ? "built-in" : m_step->moduleInstanceKey() ) ); .arg( m_step->moduleInstanceKey().isValid() ? m_step->moduleInstanceKey().toString() : QStringLiteral("built-in") ) );
} }
else else
{ {

View File

@ -37,6 +37,9 @@ set( libSources
locale/TimeZone.cpp locale/TimeZone.cpp
locale/TranslatableConfiguration.cpp locale/TranslatableConfiguration.cpp
# Modules
modulesystem/InstanceKey.cpp
# Network service # Network service
network/Manager.cpp network/Manager.cpp

View File

@ -32,7 +32,7 @@ CppJob::~CppJob() {}
void void
CppJob::setModuleInstanceKey( const QString& instanceKey ) CppJob::setModuleInstanceKey( const Calamares::ModuleSystem::InstanceKey& instanceKey )
{ {
m_instanceKey = instanceKey; m_instanceKey = instanceKey;
} }

View File

@ -2,6 +2,7 @@
* *
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org> * Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
* Copyright 2016, Kevin Kofler <kevin.kofler@chello.at> * Copyright 2016, Kevin Kofler <kevin.kofler@chello.at>
* Copyright 2020, Adriaan de Groor <groot@kde.org>
* *
* Calamares is free software: you can redistribute it and/or modify * Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -20,12 +21,14 @@
#ifndef CALAMARES_CPPJOB_H #ifndef CALAMARES_CPPJOB_H
#define CALAMARES_CPPJOB_H #define CALAMARES_CPPJOB_H
#include <QObject>
#include <QVariant>
#include "DllMacro.h" #include "DllMacro.h"
#include "Job.h" #include "Job.h"
#include "modulesystem/InstanceKey.h"
#include <QObject>
#include <QVariant>
namespace Calamares namespace Calamares
{ {
@ -36,13 +39,13 @@ public:
explicit CppJob( QObject* parent = nullptr ); explicit CppJob( QObject* parent = nullptr );
virtual ~CppJob(); virtual ~CppJob();
void setModuleInstanceKey( const QString& instanceKey ); void setModuleInstanceKey( const Calamares::ModuleSystem::InstanceKey& instanceKey );
QString moduleInstanceKey() const { return m_instanceKey; } Calamares::ModuleSystem::InstanceKey moduleInstanceKey() const { return m_instanceKey; }
virtual void setConfigurationMap( const QVariantMap& configurationMap ); virtual void setConfigurationMap( const QVariantMap& configurationMap );
protected: protected:
QString m_instanceKey; Calamares::ModuleSystem::InstanceKey m_instanceKey;
}; };
} // namespace Calamares } // namespace Calamares

View File

@ -0,0 +1,36 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2020, Adriaan de Groot <groot@kde.org>
*
* Calamares 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 3 of the License, or
* (at your option) any later version.
*
* Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MODULESYSTEM_DESCRIPTOR_H
#define MODULESYSTEM_DESCRIPTOR_H
#include <QVariantMap>
namespace Calamares
{
namespace ModuleSystem
{
/* While this isn't a useful *using* right now, the intention is
* to create a more strongly-typed Module Descriptor that carries
* only the necessary information and no variants.
*/
using Descriptor = QVariantMap;
} // namespace ModuleSystem
} // namespace Calamares
#endif

View File

@ -0,0 +1,46 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
* Copyright 2018-2019, Adriaan de Groot <groot@kde.org>
*
* Calamares 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 3 of the License, or
* (at your option) any later version.
*
* Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#include "InstanceKey.h"
namespace Calamares
{
namespace ModuleSystem
{
InstanceKey
InstanceKey::fromString( const QString& s )
{
QStringList moduleEntrySplit = s.split( '@' );
if ( moduleEntrySplit.length() < 1 || moduleEntrySplit.length() > 2 )
{
return InstanceKey();
}
// For length 1, first == last
return InstanceKey( moduleEntrySplit.first(), moduleEntrySplit.last() );
}
QDebug&
operator<<( QDebug& s, const Calamares::ModuleSystem::InstanceKey& i )
{
return s << i.toString();
}
} // namespace ModuleSystem
} // namespace Calamares

View File

@ -19,15 +19,9 @@
#ifndef MODULESYSTEM_INSTANCEKEY_H #ifndef MODULESYSTEM_INSTANCEKEY_H
#define MODULESYSTEM_INSTANCEKEY_H #define MODULESYSTEM_INSTANCEKEY_H
#include <QList> #include <QDebug>
#include <QPair> #include <QPair>
#include <QString> #include <QString>
#include <QStringList>
namespace Logger
{
class CLog;
}
namespace Calamares namespace Calamares
{ {
@ -77,16 +71,7 @@ public:
QString id() const { return second; } QString id() const { return second; }
/// @brief Create instance key from stringified version /// @brief Create instance key from stringified version
static InstanceKey fromString( const QString& s ) static InstanceKey fromString( const QString& s );
{
QStringList moduleEntrySplit = s.split( '@' );
if ( moduleEntrySplit.length() < 1 || moduleEntrySplit.length() > 2 )
{
return InstanceKey();
}
// For length 1, first == last
return InstanceKey( moduleEntrySplit.first(), moduleEntrySplit.last() );
}
QString toString() const QString toString() const
{ {
@ -109,6 +94,9 @@ private:
} }
}; };
QDebug&
operator <<( QDebug& s, const Calamares::ModuleSystem::InstanceKey& i );
} // namespace ModuleSystem } // namespace ModuleSystem
} // namespace Calamares } // namespace Calamares

View File

@ -86,7 +86,6 @@ CppJobModule::jobs() const
void void
CppJobModule::initFrom( const QVariantMap& moduleDescriptor ) CppJobModule::initFrom( const QVariantMap& moduleDescriptor )
{ {
Module::initFrom( moduleDescriptor );
QDir directory( location() ); QDir directory( location() );
QString load; QString load;
if ( !moduleDescriptor.value( "load" ).toString().isEmpty() ) if ( !moduleDescriptor.value( "load" ).toString().isEmpty() )

View File

@ -27,6 +27,7 @@
#include "utils/Dirs.h" #include "utils/Dirs.h"
#include "utils/Logger.h" #include "utils/Logger.h"
#include "utils/NamedEnum.h"
#include "utils/Yaml.h" #include "utils/Yaml.h"
#ifdef WITH_PYTHON #ifdef WITH_PYTHON
@ -48,10 +49,25 @@ static const char EMERGENCY[] = "emergency";
namespace Calamares namespace Calamares
{ {
Module::Module()
: m_loaded( false )
{
}
Module::~Module() {} Module::~Module() {}
void
Module::initFrom( const Calamares::ModuleSystem::Descriptor& moduleDescriptor, const QString& id )
{
m_key = ModuleSystem::InstanceKey( moduleDescriptor.value( "name" ).toString(), id );
if ( moduleDescriptor.contains( EMERGENCY ) )
{
m_maybe_emergency = moduleDescriptor[ EMERGENCY ].toBool();
}
}
Module* Module*
Module::fromDescriptor( const QVariantMap& moduleDescriptor, Module::fromDescriptor( const Calamares::ModuleSystem::Descriptor& moduleDescriptor,
const QString& instanceId, const QString& instanceId,
const QString& configFileName, const QString& configFileName,
const QString& moduleDirectory ) const QString& moduleDirectory )
@ -131,17 +147,25 @@ Module::fromDescriptor( const QVariantMap& moduleDescriptor,
return nullptr; return nullptr;
} }
m->m_instanceId = instanceId; m->initFrom( moduleDescriptor, instanceId );
if ( !m->m_key.isValid() )
{
cError() << "Module" << instanceId << "invalid ID";
return nullptr;
}
m->initFrom( moduleDescriptor ); m->initFrom( moduleDescriptor );
try if ( !configFileName.isEmpty() )
{ {
m->loadConfigurationFile( configFileName ); try
} {
catch ( YAML::Exception& e ) m->loadConfigurationFile( configFileName );
{ }
cError() << "YAML parser error " << e.what(); catch ( YAML::Exception& e )
return nullptr; {
cError() << "YAML parser error " << e.what();
return nullptr;
}
} }
return m.release(); return m.release();
} }
@ -190,7 +214,7 @@ moduleConfigurationCandidates( bool assumeBuildDir, const QString& moduleName, c
void Module::loadConfigurationFile( const QString& configFileName ) //throws YAML::Exception void Module::loadConfigurationFile( const QString& configFileName ) //throws YAML::Exception
{ {
QStringList configCandidates QStringList configCandidates
= moduleConfigurationCandidates( Settings::instance()->debugMode(), m_name, configFileName ); = moduleConfigurationCandidates( Settings::instance()->debugMode(), name(), configFileName );
for ( const QString& path : configCandidates ) for ( const QString& path : configCandidates )
{ {
QFile configFile( path ); QFile configFile( path );
@ -219,67 +243,59 @@ void Module::loadConfigurationFile( const QString& configFileName ) //throws YA
return; return;
} }
} }
cDebug() << "No config file for" << m_name << "found anywhere at" << Logger::DebugList( configCandidates ); cDebug() << "No config file for" << name() << "found anywhere at" << Logger::DebugList( configCandidates );
} }
QString static const NamedEnumTable< Module::Type >&
Module::name() const typeNames()
{ {
return m_name; using Type = Module::Type;
// *INDENT-OFF*
// clang-format off
static const NamedEnumTable< Type > table{
{ QStringLiteral( "job" ), Type::Job },
{ QStringLiteral( "view" ), Type::View },
{ QStringLiteral( "viewmodule" ), Type::View },
{ QStringLiteral( "jobmodule" ), Type::Job }
};
// *INDENT-ON*
// clang-format on
return table;
} }
QString
Module::instanceId() const
{
return m_instanceId;
}
QString
Module::instanceKey() const
{
return QString( "%1@%2" ).arg( m_name ).arg( m_instanceId );
}
QString
Module::location() const
{
return m_directory;
}
QString QString
Module::typeString() const Module::typeString() const
{ {
switch ( type() ) bool ok = false;
{ QString v = typeNames().find( type(), ok );
case Type::Job: return ok ? v : QString();
return "Job Module";
case Type::View:
return "View Module";
}
return QString();
} }
static const NamedEnumTable< Module::Interface >&
interfaceNames()
{
using Interface = Module::Interface;
// *INDENT-OFF*
// clang-format off
static const NamedEnumTable< Interface > table {
{ QStringLiteral("process"), Interface::Process },
{ QStringLiteral("qtplugin"), Interface::QtPlugin },
{ QStringLiteral("python"), Interface::Python },
{ QStringLiteral("pythonqt"), Interface::PythonQt }
};
// *INDENT-ON*
// clang-format on
return table;
}
QString QString
Module::interfaceString() const Module::interfaceString() const
{ {
switch ( interface() ) bool ok = false;
{ QString v = interfaceNames().find( interface(), ok );
case Interface::Process: return ok ? v : QString();
return "External process";
case Interface::Python:
return "Python (Boost.Python)";
case Interface::PythonQt:
return "Python (experimental)";
case Interface::QtPlugin:
return "Qt Plugin";
}
return QString();
} }
@ -290,22 +306,6 @@ Module::configurationMap()
} }
Module::Module()
: m_loaded( false )
{
}
void
Module::initFrom( const QVariantMap& moduleDescriptor )
{
m_name = moduleDescriptor.value( "name" ).toString();
if ( moduleDescriptor.contains( EMERGENCY ) )
{
m_maybe_emergency = moduleDescriptor[ EMERGENCY ].toBool();
}
}
RequirementsList RequirementsList
Module::checkRequirements() Module::checkRequirements()
{ {

View File

@ -24,6 +24,9 @@
#include "Requirement.h" #include "Requirement.h"
#include "UiDllMacro.h" #include "UiDllMacro.h"
#include "modulesystem/Descriptor.h"
#include "modulesystem/InstanceKey.h"
#include <QStringList> #include <QStringList>
#include <QVariant> #include <QVariant>
@ -73,7 +76,7 @@ public:
* @param moduleDirectory the path to the directory with this module's files. * @param moduleDirectory the path to the directory with this module's files.
* @return a pointer to an object of a subtype of Module. * @return a pointer to an object of a subtype of Module.
*/ */
static Module* fromDescriptor( const QVariantMap& moduleDescriptor, static Module* fromDescriptor( const ModuleSystem::Descriptor& moduleDescriptor,
const QString& instanceId, const QString& instanceId,
const QString& configFileName, const QString& configFileName,
const QString& moduleDirectory ); const QString& moduleDirectory );
@ -83,13 +86,13 @@ public:
* @brief name returns the name of this module. * @brief name returns the name of this module.
* @return a string with this module's name. * @return a string with this module's name.
*/ */
virtual QString name() const final; QString name() const { return m_key.module(); }
/** /**
* @brief instanceId returns the instance id of this module. * @brief instanceId returns the instance id of this module.
* @return a string with this module's instance id. * @return a string with this module's instance id.
*/ */
virtual QString instanceId() const final; QString instanceId() const { return m_key.id(); }
/** /**
* @brief instanceKey returns the instance key of this module. * @brief instanceKey returns the instance key of this module.
@ -98,49 +101,13 @@ public:
* For instance, "partition\@partition" (default configuration) or * For instance, "partition\@partition" (default configuration) or
* "locale\@someconfig" (custom configuration) * "locale\@someconfig" (custom configuration)
*/ */
virtual QString instanceKey() const final; ModuleSystem::InstanceKey instanceKey() const { return m_key; }
/** /**
* @brief location returns the full path of this module's directory. * @brief location returns the full path of this module's directory.
* @return the path. * @return the path.
*/ */
virtual QString location() const final; QString location() const { return m_directory; }
/**
* @brief type returns the Type of this module object.
* @return the type enum value.
*/
virtual Type type() const = 0;
/**
* @brief typeString returns a user-visible string for the module's type.
* @return the type string.
*/
virtual QString typeString() const;
/**
* @brief interface the Interface used by this module.
* @return the interface enum value.
*/
virtual Interface interface() const = 0;
/**
* @brief interface returns a user-visible string for the module's interface.
* @return the interface string.
*/
virtual QString interfaceString() const;
/**
* @brief isLoaded reports on the loaded status of a module.
* @return true if the module's loading phase has finished, otherwise false.
*/
bool isLoaded() const { return m_loaded; }
/**
* @brief loadSelf initialized the module.
* Subclasses must reimplement this depending on the module type and interface.
*/
virtual void loadSelf() = 0;
/** /**
* @brief Is this an emergency module? * @brief Is this an emergency module?
@ -154,10 +121,10 @@ public:
bool isEmergency() const { return m_emergency; } bool isEmergency() const { return m_emergency; }
/** /**
* @brief jobs returns any jobs exposed by this module. * @brief isLoaded reports on the loaded status of a module.
* @return a list of jobs (can be empty). * @return true if the module's loading phase has finished, otherwise false.
*/ */
virtual JobList jobs() const = 0; bool isLoaded() const { return m_loaded; }
/** /**
* @brief configurationMap returns the contents of the configuration file for * @brief configurationMap returns the contents of the configuration file for
@ -166,6 +133,42 @@ public:
*/ */
QVariantMap configurationMap(); QVariantMap configurationMap();
/**
* @brief typeString returns a user-visible string for the module's type.
* @return the type string.
*/
QString typeString() const;
/**
* @brief interface returns a user-visible string for the module's interface.
* @return the interface string.
*/
QString interfaceString() const;
/**
* @brief loadSelf initialized the module.
* Subclasses must reimplement this depending on the module type and interface.
*/
virtual void loadSelf() = 0;
/**
* @brief jobs returns any jobs exposed by this module.
* @return a list of jobs (can be empty).
*/
virtual JobList jobs() const = 0;
/**
* @brief type returns the Type of this module object.
* @return the type enum value.
*/
virtual Type type() const = 0;
/**
* @brief interface the Interface used by this module.
* @return the interface enum value.
*/
virtual Interface interface() const = 0;
/** /**
* @brief Check the requirements of this module. * @brief Check the requirements of this module.
*/ */
@ -173,7 +176,12 @@ public:
protected: protected:
explicit Module(); explicit Module();
virtual void initFrom( const QVariantMap& moduleDescriptor );
/// @brief For subclasses to read their part of the descriptor
virtual void initFrom( const QVariantMap& moduleDescriptor ) = 0;
/// @brief Generic part of descriptor reading (and instance id)
void initFrom( const QVariantMap& moduleDescriptor, const QString& id );
QVariantMap m_configurationMap; QVariantMap m_configurationMap;
bool m_loaded = false; bool m_loaded = false;
@ -183,9 +191,8 @@ protected:
private: private:
void loadConfigurationFile( const QString& configFileName ); //throws YAML::Exception void loadConfigurationFile( const QString& configFileName ); //throws YAML::Exception
QString m_name;
QString m_directory; QString m_directory;
QString m_instanceId; ModuleSystem::InstanceKey m_key;
}; };
} // namespace Calamares } // namespace Calamares

View File

@ -95,16 +95,12 @@ ModuleManager::doInit()
QFileInfo descriptorFileInfo( currentDir.absoluteFilePath( QLatin1String( "module.desc" ) ) ); QFileInfo descriptorFileInfo( currentDir.absoluteFilePath( QLatin1String( "module.desc" ) ) );
if ( !descriptorFileInfo.exists() ) if ( !descriptorFileInfo.exists() )
{ {
cDebug() << bad_descriptor cDebug() << bad_descriptor << descriptorFileInfo.absoluteFilePath() << "(missing)";
<< descriptorFileInfo.absoluteFilePath()
<< "(missing)";
continue; continue;
} }
if ( !descriptorFileInfo.isReadable() ) if ( !descriptorFileInfo.isReadable() )
{ {
cDebug() << bad_descriptor cDebug() << bad_descriptor << descriptorFileInfo.absoluteFilePath() << "(unreadable)";
<< descriptorFileInfo.absoluteFilePath()
<< "(unreadable)";
continue; continue;
} }
@ -131,28 +127,22 @@ ModuleManager::doInit()
cDebug() << "ModuleManager module search path does not exist:" << path; cDebug() << "ModuleManager module search path does not exist:" << path;
} }
} }
// At this point m_availableDescriptorsByModuleName is filled with // At this point m_availableDescriptorsByModuleName is filled with
// the modules that were found in the search paths. // the modules that were found in the search paths.
cDebug() << "Found" cDebug() << "Found" << m_availableDescriptorsByModuleName.count() << "modules"
<< m_availableDescriptorsByModuleName.count() << "modules" << m_moduleDirectoriesByModuleName.count() << "names";
<< m_moduleDirectoriesByModuleName.count() << "names";
emit initDone(); emit initDone();
} }
QStringList QList< ModuleSystem::InstanceKey >
ModuleManager::loadedInstanceKeys() ModuleManager::loadedInstanceKeys()
{ {
QStringList l; return m_loadedModulesByInstanceKey.keys();
for ( const auto& m : m_loadedModulesByInstanceKey.keys() )
{
l << m.toString();
}
return l;
} }
QVariantMap Calamares::ModuleSystem::Descriptor
ModuleManager::moduleDescriptor( const QString& name ) ModuleManager::moduleDescriptor( const QString& name )
{ {
return m_availableDescriptorsByModuleName.value( name ); return m_availableDescriptorsByModuleName.value( name );
@ -184,19 +174,54 @@ findCustomInstance( const Settings::InstanceDescriptionList& customInstances, co
return -1; return -1;
} }
/** @brief Returns the config file name for the fiven @p instanceKey
*
* Custom instances have custom config files, non-custom ones
* have a <modulename>.conf file. Returns an empty QString on
* errors.
*/
static QString
getConfigFileName( const Settings::InstanceDescriptionList& customInstances,
const ModuleSystem::InstanceKey& instanceKey,
const ModuleSystem::Descriptor& descriptor )
{
if ( instanceKey.isCustom() )
{
int found = findCustomInstance( customInstances, instanceKey );
if ( found < 0 )
{
// This should already have been checked and failed the module already
return QString();
}
return customInstances[ found ].value( "config" );
}
else
{
if ( descriptor.value( "noconfig", false ).toBool() )
{
// Explicitly set to no-configuration. This doesn't apply
// to custom instances (above) since the only reason to
// **have** a custom instance is to specify a different
// config file for more than one module.
return QString();
}
return QString( "%1.conf" ).arg( instanceKey.module() );
}
}
void void
ModuleManager::loadModules() ModuleManager::loadModules()
{ {
if (checkDependencies()) if ( checkDependencies() )
{ {
cWarning() << "Some installed modules have unmet dependencies."; cWarning() << "Some installed modules have unmet dependencies.";
} }
Settings::InstanceDescriptionList customInstances = Settings::instance()->customModuleInstances(); Settings::InstanceDescriptionList customInstances = Settings::instance()->customModuleInstances();
QStringList failedModules; QStringList failedModules;
const auto modulesSequence const auto modulesSequence = Settings::instance()->modulesSequence();
= Settings::instance()->modulesSequence() ;
for ( const auto& modulePhase : modulesSequence ) for ( const auto& modulePhase : modulesSequence )
{ {
ModuleSystem::Action currentAction = modulePhase.first; ModuleSystem::Action currentAction = modulePhase.first;
@ -210,38 +235,29 @@ ModuleManager::loadModules()
failedModules.append( moduleEntry ); failedModules.append( moduleEntry );
continue; continue;
} }
if ( !m_availableDescriptorsByModuleName.contains( instanceKey.module() )
|| m_availableDescriptorsByModuleName.value( instanceKey.module() ).isEmpty() )
{
cError() << "Module" << instanceKey.toString() << "not found in module search paths."
<< Logger::DebugList( m_paths );
failedModules.append( instanceKey.toString() );
continue;
}
QString configFileName;
if ( instanceKey.isCustom() ) if ( instanceKey.isCustom() )
{ {
int found = findCustomInstance( customInstances, instanceKey ); int found = findCustomInstance( customInstances, instanceKey );
if ( found < 0 )
if ( found > -1 )
{
configFileName = customInstances[ found ].value( "config" );
}
else //ought to be a custom instance, but cannot find instance entry
{ {
cError() << "Custom instance" << moduleEntry << "not found in custom instances section."; cError() << "Custom instance" << moduleEntry << "not found in custom instances section.";
failedModules.append( moduleEntry ); failedModules.append( moduleEntry );
continue; continue;
} }
} }
else
ModuleSystem::Descriptor descriptor
= m_availableDescriptorsByModuleName.value( instanceKey.module(), ModuleSystem::Descriptor() );
if ( descriptor.isEmpty() )
{ {
configFileName = QString( "%1.conf" ).arg( instanceKey.module() ); cError() << "Module" << instanceKey.toString() << "not found in module search paths."
<< Logger::DebugList( m_paths );
failedModules.append( instanceKey.toString() );
continue;
} }
QString configFileName = getConfigFileName( customInstances, instanceKey, descriptor );
// So now we can assume that the module entry is at least valid, // So now we can assume that the module entry is at least valid,
// that we have a descriptor on hand (and therefore that the // that we have a descriptor on hand (and therefore that the
// module exists), and that the instance is either default or // module exists), and that the instance is either default or
@ -250,26 +266,33 @@ ModuleManager::loadModules()
// exists and is valid, but that's the only thing that could fail // exists and is valid, but that's the only thing that could fail
// from this point on. -- Teo 8/2015 // from this point on. -- Teo 8/2015
Module* thisModule = m_loadedModulesByInstanceKey.value( instanceKey, nullptr ); Module* thisModule = m_loadedModulesByInstanceKey.value( instanceKey, nullptr );
if ( thisModule && !thisModule->isLoaded() ) if ( thisModule )
{ {
cError() << "Module" << instanceKey.toString() << "exists but not loaded."; if ( thisModule->isLoaded() )
failedModules.append( instanceKey.toString() ); {
continue; // It's been listed before, don't bother loading again.
} // This can happen for a module listed twice (e.g. with custom instances)
cDebug() << "Module" << instanceKey.toString() << "already loaded.";
if ( thisModule && thisModule->isLoaded() ) }
{ else
cDebug() << "Module" << instanceKey.toString() << "already loaded."; {
// An attempt was made, earlier, and that failed.
// This can happen for a module listed twice (e.g. with custom instances)
cError() << "Module" << instanceKey.toString() << "exists but not loaded.";
failedModules.append( instanceKey.toString() );
continue;
}
} }
else else
{ {
thisModule = Module::fromDescriptor( m_availableDescriptorsByModuleName.value( instanceKey.module() ), thisModule = Module::fromDescriptor( descriptor,
instanceKey.id(), instanceKey.id(),
configFileName, configFileName,
m_moduleDirectoriesByModuleName.value( instanceKey.module() ) ); m_moduleDirectoriesByModuleName.value( instanceKey.module() ) );
if ( !thisModule ) if ( !thisModule )
{ {
cError() << "Module" << instanceKey.toString() << "cannot be created from descriptor" << configFileName; cError() << "Module" << instanceKey.toString() << "cannot be created from descriptor"
<< configFileName;
failedModules.append( instanceKey.toString() ); failedModules.append( instanceKey.toString() );
continue; continue;
} }

View File

@ -20,6 +20,7 @@
#ifndef MODULELOADER_H #ifndef MODULELOADER_H
#define MODULELOADER_H #define MODULELOADER_H
#include "modulesystem/Descriptor.h"
#include "modulesystem/InstanceKey.h" #include "modulesystem/InstanceKey.h"
#include "Requirement.h" #include "Requirement.h"
@ -62,14 +63,14 @@ public:
* modules. * modules.
* @return a QStringList with the instance keys. * @return a QStringList with the instance keys.
*/ */
QStringList loadedInstanceKeys(); QList< ModuleSystem::InstanceKey > loadedInstanceKeys();
/** /**
* @brief moduleDescriptor returns the module descriptor structure for a given module. * @brief moduleDescriptor returns the module descriptor structure for a given module.
* @param name the name of the module for which to return the module descriptor. * @param name the name of the module for which to return the module descriptor.
* @return the module descriptor, as a variant map already parsed from YAML. * @return the module descriptor, as a variant map already parsed from YAML.
*/ */
QVariantMap moduleDescriptor( const QString& name ); ModuleSystem::Descriptor moduleDescriptor( const QString& name );
/** /**
* @brief moduleInstance returns a Module object for a given instance key. * @brief moduleInstance returns a Module object for a given instance key.
@ -126,7 +127,7 @@ private:
*/ */
bool checkModuleDependencies( const Module& ); bool checkModuleDependencies( const Module& );
QMap< QString, QVariantMap > m_availableDescriptorsByModuleName; QMap< QString, ModuleSystem::Descriptor > m_availableDescriptorsByModuleName;
QMap< QString, QString > m_moduleDirectoriesByModuleName; QMap< QString, QString > m_moduleDirectoriesByModuleName;
QMap< ModuleSystem::InstanceKey, Module* > m_loadedModulesByInstanceKey; QMap< ModuleSystem::InstanceKey, Module* > m_loadedModulesByInstanceKey;
const QStringList m_paths; const QStringList m_paths;

View File

@ -63,7 +63,6 @@ ProcessJobModule::jobs() const
void void
ProcessJobModule::initFrom( const QVariantMap& moduleDescriptor ) ProcessJobModule::initFrom( const QVariantMap& moduleDescriptor )
{ {
Module::initFrom( moduleDescriptor );
QDir directory( location() ); QDir directory( location() );
m_workingPath = directory.absolutePath(); m_workingPath = directory.absolutePath();

View File

@ -64,7 +64,6 @@ PythonJobModule::jobs() const
void void
PythonJobModule::initFrom( const QVariantMap& moduleDescriptor ) PythonJobModule::initFrom( const QVariantMap& moduleDescriptor )
{ {
Module::initFrom( moduleDescriptor );
QDir directory( location() ); QDir directory( location() );
m_workingPath = directory.absolutePath(); m_workingPath = directory.absolutePath();

View File

@ -174,7 +174,6 @@ PythonQtViewModule::jobs() const
void void
PythonQtViewModule::initFrom( const QVariantMap& moduleDescriptor ) PythonQtViewModule::initFrom( const QVariantMap& moduleDescriptor )
{ {
Module::initFrom( moduleDescriptor );
QDir directory( location() ); QDir directory( location() );
m_workingPath = directory.absolutePath(); m_workingPath = directory.absolutePath();

View File

@ -91,7 +91,6 @@ ViewModule::jobs() const
void void
ViewModule::initFrom( const QVariantMap& moduleDescriptor ) ViewModule::initFrom( const QVariantMap& moduleDescriptor )
{ {
Module::initFrom( moduleDescriptor );
QDir directory( location() ); QDir directory( location() );
QString load; QString load;
if ( !moduleDescriptor.value( "load" ).toString().isEmpty() ) if ( !moduleDescriptor.value( "load" ).toString().isEmpty() )

View File

@ -66,7 +66,7 @@ ViewStep::back()
void void
ViewStep::setModuleInstanceKey( const QString& instanceKey ) ViewStep::setModuleInstanceKey( const Calamares::ModuleSystem::InstanceKey& instanceKey )
{ {
m_instanceKey = instanceKey; m_instanceKey = instanceKey;
} }

View File

@ -1,7 +1,7 @@
/* === This file is part of Calamares - <https://github.com/calamares> === /* === This file is part of Calamares - <https://github.com/calamares> ===
* *
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org> * Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
* Copyright 2017, Adriaan de Groot <groot@kde.org> * Copyright 2017, 2020, Adriaan de Groot <groot@kde.org>
* *
* Calamares is free software: you can redistribute it and/or modify * Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -20,15 +20,16 @@
#ifndef VIEWSTEP_H #ifndef VIEWSTEP_H
#define VIEWSTEP_H #define VIEWSTEP_H
#include <QList>
#include <QObject>
#include <QSize>
#include "Job.h" #include "Job.h"
#include "UiDllMacro.h" #include "UiDllMacro.h"
#include "modulesystem/InstanceKey.h"
#include "modulesystem/Requirement.h" #include "modulesystem/Requirement.h"
#include <QList>
#include <QObject>
#include <QSize>
namespace Calamares namespace Calamares
{ {
@ -36,9 +37,9 @@ namespace Calamares
* @brief The ViewStep class is the base class for all view modules. * @brief The ViewStep class is the base class for all view modules.
* A view module is a Calamares module which has at least one UI page (exposed as * A view module is a Calamares module which has at least one UI page (exposed as
* ViewStep::widget), and can optionally create Calamares jobs at runtime. * ViewStep::widget), and can optionally create Calamares jobs at runtime.
* As of early 2017, a view module can be implemented by deriving from ViewStep * As of early 2020, a view module can be implemented by deriving from ViewStep
* in C++ (as a Qt Plugin) or in Python with the PythonQt interface (which also * in C++ (as a Qt Plugin or a Qml ViewStep) or in Python with the PythonQt interface
* mimics the ViewStep class). * (which also mimics the ViewStep class).
* *
* A ViewStep can describe itself in human-readable format for the SummaryPage * A ViewStep can describe itself in human-readable format for the SummaryPage
* (which shows all of the things which have been collected to be done in the * (which shows all of the things which have been collected to be done in the
@ -129,8 +130,8 @@ public:
*/ */
virtual JobList jobs() const = 0; virtual JobList jobs() const = 0;
void setModuleInstanceKey( const QString& instanceKey ); void setModuleInstanceKey( const Calamares::ModuleSystem::InstanceKey& instanceKey );
QString moduleInstanceKey() const { return m_instanceKey; } Calamares::ModuleSystem::InstanceKey moduleInstanceKey() const { return m_instanceKey; }
virtual void setConfigurationMap( const QVariantMap& configurationMap ); virtual void setConfigurationMap( const QVariantMap& configurationMap );
@ -154,7 +155,7 @@ signals:
void enlarge( QSize enlarge ) const; void enlarge( QSize enlarge ) const;
protected: protected:
QString m_instanceKey; Calamares::ModuleSystem::InstanceKey m_instanceKey;
}; };
using ViewStepList = QList< ViewStep* >; using ViewStepList = QList< ViewStep* >;

View File

@ -54,10 +54,12 @@ Module descriptors for Python and PythonQt modules **must** have the following k
- *script* (the name of the Python script to load, nearly always `main.py`) - *script* (the name of the Python script to load, nearly always `main.py`)
Module descriptors **may** have the following keys: Module descriptors **may** have the following keys:
- *requiredModules* (a list of modules which are required for this module
to operate properly)
- *emergency* (a boolean value, set to true to mark the module - *emergency* (a boolean value, set to true to mark the module
as an emergency module) as an emergency module)
- *noconfig* (a boolean value, set to true to state that the module
has no configuration file; defaults to false)
- *requiredModules* (a list of modules which are required for this module
to operate properly)
### Required Modules ### Required Modules
@ -96,6 +98,12 @@ named `<modulename>.conf`. If such a file is present in the
module's directory, it can be shipped as a *default* configuration file. module's directory, it can be shipped as a *default* configuration file.
This only happens if the CMake-time option `INSTALL_CONFIG` is on. This only happens if the CMake-time option `INSTALL_CONFIG` is on.
Modules that have *noconfig* set to true will not attempt to
read a configuration file, and will not warn that one is missing;
conversely if *noconfig* is set to false (or is missing, since
the default value is false) if there is no configuration file,
a warning is printed during Calamares start-up.
The sample configuration files may work and may be suitable for The sample configuration files may work and may be suitable for
your distribution, but no guarantee is given about their stability your distribution, but no guarantee is given about their stability
beyond syntactic correctness. beyond syntactic correctness.
@ -122,7 +130,8 @@ to provide jobs.
To add a Qt plugin module, put it in a subdirectory and make sure it has To add a Qt plugin module, put it in a subdirectory and make sure it has
a `CMakeLists.txt` with a `calamares_add_plugin` call. It will be picked a `CMakeLists.txt` with a `calamares_add_plugin` call. It will be picked
up automatically by our CMake magic. The `module.desc` file is optional. up automatically by our CMake magic. The `module.desc` file is not recommended:
nearly all cases can be described in CMake.

View File

@ -6,4 +6,5 @@ calamares_add_plugin( dracutlukscfg
LINK_PRIVATE_LIBRARIES LINK_PRIVATE_LIBRARIES
calamares calamares
SHARED_LIB SHARED_LIB
NO_CONFIG
) )

View File

@ -24,8 +24,8 @@
#include <QTextStream> #include <QTextStream>
#include "CalamaresVersion.h" #include "CalamaresVersion.h"
#include "JobQueue.h"
#include "GlobalStorage.h" #include "GlobalStorage.h"
#include "JobQueue.h"
#include "utils/Logger.h" #include "utils/Logger.h"
@ -33,30 +33,30 @@
const QLatin1String DracutLuksCfgJob::CONFIG_FILE( "/etc/dracut.conf.d/calamares-luks.conf" ); const QLatin1String DracutLuksCfgJob::CONFIG_FILE( "/etc/dracut.conf.d/calamares-luks.conf" );
// static // static
const char *DracutLuksCfgJob::CONFIG_FILE_HEADER = const char* DracutLuksCfgJob::CONFIG_FILE_HEADER
"# Configuration file automatically written by the Calamares system installer\n" = "# Configuration file automatically written by the Calamares system installer\n"
"# (This file is written once at install time and should be safe to edit.)\n" "# (This file is written once at install time and should be safe to edit.)\n"
"# Enables support for LUKS full disk encryption with single sign on from GRUB.\n" "# Enables support for LUKS full disk encryption with single sign on from GRUB.\n"
"\n"; "\n";
// static // static
const char *DracutLuksCfgJob::CONFIG_FILE_CRYPTTAB_KEYFILE_LINE = const char* DracutLuksCfgJob::CONFIG_FILE_CRYPTTAB_KEYFILE_LINE
"# force installing /etc/crypttab even if hostonly=\"no\", install the keyfile\n" = "# force installing /etc/crypttab even if hostonly=\"no\", install the keyfile\n"
"install_items+=\" /etc/crypttab /crypto_keyfile.bin \"\n"; "install_items+=\" /etc/crypttab /crypto_keyfile.bin \"\n";
// static // static
const char *DracutLuksCfgJob::CONFIG_FILE_CRYPTTAB_LINE = const char* DracutLuksCfgJob::CONFIG_FILE_CRYPTTAB_LINE = "# force installing /etc/crypttab even if hostonly=\"no\"\n"
"# force installing /etc/crypttab even if hostonly=\"no\"\n" "install_items+=\" /etc/crypttab \"\n";
"install_items+=\" /etc/crypttab \"\n";
// static // static
const QLatin1String DracutLuksCfgJob::CONFIG_FILE_SWAPLINE( "# enable automatic resume from swap\nadd_device+=\" /dev/disk/by-uuid/%1 \"\n" ); const QLatin1String DracutLuksCfgJob::CONFIG_FILE_SWAPLINE(
"# enable automatic resume from swap\nadd_device+=\" /dev/disk/by-uuid/%1 \"\n" );
// static // static
QString QString
DracutLuksCfgJob::rootMountPoint() DracutLuksCfgJob::rootMountPoint()
{ {
Calamares::GlobalStorage *globalStorage = Calamares::JobQueue::instance()->globalStorage(); Calamares::GlobalStorage* globalStorage = Calamares::JobQueue::instance()->globalStorage();
return globalStorage->value( QStringLiteral( "rootMountPoint" ) ).toString(); return globalStorage->value( QStringLiteral( "rootMountPoint" ) ).toString();
} }
@ -64,7 +64,7 @@ DracutLuksCfgJob::rootMountPoint()
QVariantList QVariantList
DracutLuksCfgJob::partitions() DracutLuksCfgJob::partitions()
{ {
Calamares::GlobalStorage *globalStorage = Calamares::JobQueue::instance()->globalStorage(); Calamares::GlobalStorage* globalStorage = Calamares::JobQueue::instance()->globalStorage();
return globalStorage->value( QStringLiteral( "partitions" ) ).toList(); return globalStorage->value( QStringLiteral( "partitions" ) ).toList();
} }
@ -73,12 +73,14 @@ bool
DracutLuksCfgJob::isRootEncrypted() DracutLuksCfgJob::isRootEncrypted()
{ {
const QVariantList partitions = DracutLuksCfgJob::partitions(); const QVariantList partitions = DracutLuksCfgJob::partitions();
for ( const QVariant &partition : partitions ) for ( const QVariant& partition : partitions )
{ {
QVariantMap partitionMap = partition.toMap(); QVariantMap partitionMap = partition.toMap();
QString mountPoint = partitionMap.value( QStringLiteral( "mountPoint" ) ).toString(); QString mountPoint = partitionMap.value( QStringLiteral( "mountPoint" ) ).toString();
if ( mountPoint == QStringLiteral( "/" ) ) if ( mountPoint == QStringLiteral( "/" ) )
{
return partitionMap.contains( QStringLiteral( "luksMapperName" ) ); return partitionMap.contains( QStringLiteral( "luksMapperName" ) );
}
} }
return false; return false;
} }
@ -88,12 +90,14 @@ bool
DracutLuksCfgJob::hasUnencryptedSeparateBoot() DracutLuksCfgJob::hasUnencryptedSeparateBoot()
{ {
const QVariantList partitions = DracutLuksCfgJob::partitions(); const QVariantList partitions = DracutLuksCfgJob::partitions();
for ( const QVariant &partition : partitions ) for ( const QVariant& partition : partitions )
{ {
QVariantMap partitionMap = partition.toMap(); QVariantMap partitionMap = partition.toMap();
QString mountPoint = partitionMap.value( QStringLiteral( "mountPoint" ) ).toString(); QString mountPoint = partitionMap.value( QStringLiteral( "mountPoint" ) ).toString();
if ( mountPoint == QStringLiteral( "/boot" ) ) if ( mountPoint == QStringLiteral( "/boot" ) )
{
return !partitionMap.contains( QStringLiteral( "luksMapperName" ) ); return !partitionMap.contains( QStringLiteral( "luksMapperName" ) );
}
} }
return false; return false;
} }
@ -103,12 +107,14 @@ QString
DracutLuksCfgJob::swapOuterUuid() DracutLuksCfgJob::swapOuterUuid()
{ {
const QVariantList partitions = DracutLuksCfgJob::partitions(); const QVariantList partitions = DracutLuksCfgJob::partitions();
for ( const QVariant &partition : partitions ) for ( const QVariant& partition : partitions )
{ {
QVariantMap partitionMap = partition.toMap(); QVariantMap partitionMap = partition.toMap();
QString fsType = partitionMap.value( QStringLiteral( "fs" ) ).toString(); QString fsType = partitionMap.value( QStringLiteral( "fs" ) ).toString();
if ( fsType == QStringLiteral( "linuxswap" ) && partitionMap.contains( QStringLiteral( "luksMapperName" ) ) ) if ( fsType == QStringLiteral( "linuxswap" ) && partitionMap.contains( QStringLiteral( "luksMapperName" ) ) )
{
return partitionMap.value( QStringLiteral( "luksUuid" ) ).toString(); return partitionMap.value( QStringLiteral( "luksUuid" ) ).toString();
}
} }
return QString(); return QString();
} }
@ -119,18 +125,20 @@ DracutLuksCfgJob::DracutLuksCfgJob( QObject* parent )
} }
DracutLuksCfgJob::~DracutLuksCfgJob() DracutLuksCfgJob::~DracutLuksCfgJob() {}
{
}
QString QString
DracutLuksCfgJob::prettyName() const DracutLuksCfgJob::prettyName() const
{ {
if ( isRootEncrypted() ) if ( isRootEncrypted() )
{
return tr( "Write LUKS configuration for Dracut to %1" ).arg( CONFIG_FILE ); return tr( "Write LUKS configuration for Dracut to %1" ).arg( CONFIG_FILE );
}
else else
{
return tr( "Skip writing LUKS configuration for Dracut: \"/\" partition is not encrypted" ); return tr( "Skip writing LUKS configuration for Dracut: \"/\" partition is not encrypted" );
}
} }
@ -143,26 +151,28 @@ DracutLuksCfgJob::exec()
cDebug() << "[DRACUTLUKSCFG]: Writing" << realConfigFilePath; cDebug() << "[DRACUTLUKSCFG]: Writing" << realConfigFilePath;
QDir( QStringLiteral( "/" ) ).mkpath( QFileInfo( realConfigFilePath ).absolutePath() ); QDir( QStringLiteral( "/" ) ).mkpath( QFileInfo( realConfigFilePath ).absolutePath() );
QFile configFile( realConfigFilePath ); QFile configFile( realConfigFilePath );
if ( ! configFile.open( QIODevice::WriteOnly | QIODevice::Text ) ) if ( !configFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
{ {
cDebug() << "[DRACUTLUKSCFG]: Failed to open" << realConfigFilePath; cDebug() << "[DRACUTLUKSCFG]: Failed to open" << realConfigFilePath;
return Calamares::JobResult::error( tr( "Failed to open %1" ).arg( realConfigFilePath ) ); return Calamares::JobResult::error( tr( "Failed to open %1" ).arg( realConfigFilePath ) );
} }
QTextStream outStream( &configFile ); QTextStream outStream( &configFile );
outStream << CONFIG_FILE_HEADER outStream << CONFIG_FILE_HEADER
<< ( hasUnencryptedSeparateBoot() ? CONFIG_FILE_CRYPTTAB_LINE << ( hasUnencryptedSeparateBoot() ? CONFIG_FILE_CRYPTTAB_LINE : CONFIG_FILE_CRYPTTAB_KEYFILE_LINE );
: CONFIG_FILE_CRYPTTAB_KEYFILE_LINE );
const QString swapOuterUuid = DracutLuksCfgJob::swapOuterUuid(); const QString swapOuterUuid = DracutLuksCfgJob::swapOuterUuid();
if ( ! swapOuterUuid.isEmpty() ) if ( !swapOuterUuid.isEmpty() )
{ {
cDebug() << "[DRACUTLUKSCFG]: Swap outer UUID" << swapOuterUuid; cDebug() << "[DRACUTLUKSCFG]: Swap outer UUID" << swapOuterUuid;
outStream << QString(CONFIG_FILE_SWAPLINE).arg( swapOuterUuid ).toLatin1(); outStream << QString( CONFIG_FILE_SWAPLINE ).arg( swapOuterUuid ).toLatin1();
} }
cDebug() << "[DRACUTLUKSCFG]: Wrote config to" << realConfigFilePath; cDebug() << "[DRACUTLUKSCFG]: Wrote config to" << realConfigFilePath;
} else }
else
{
cDebug() << "[DRACUTLUKSCFG]: / not encrypted, skipping"; cDebug() << "[DRACUTLUKSCFG]: / not encrypted, skipping";
}
return Calamares::JobResult::ok(); return Calamares::JobResult::ok();
} }
CALAMARES_PLUGIN_FACTORY_DEFINITION( DracutLuksCfgJobFactory, registerPlugin<DracutLuksCfgJob>(); ) CALAMARES_PLUGIN_FACTORY_DEFINITION( DracutLuksCfgJobFactory, registerPlugin< DracutLuksCfgJob >(); )

View File

@ -43,9 +43,9 @@ public:
private: private:
static const QLatin1String CONFIG_FILE; static const QLatin1String CONFIG_FILE;
static const char *CONFIG_FILE_HEADER; static const char* CONFIG_FILE_HEADER;
static const char *CONFIG_FILE_CRYPTTAB_KEYFILE_LINE; static const char* CONFIG_FILE_CRYPTTAB_KEYFILE_LINE;
static const char *CONFIG_FILE_CRYPTTAB_LINE; static const char* CONFIG_FILE_CRYPTTAB_LINE;
static const QLatin1String CONFIG_FILE_SWAPLINE; static const QLatin1String CONFIG_FILE_SWAPLINE;
static QString rootMountPoint(); static QString rootMountPoint();
@ -57,4 +57,4 @@ private:
CALAMARES_PLUGIN_FACTORY_DECLARATION( DracutLuksCfgJobFactory ) CALAMARES_PLUGIN_FACTORY_DECLARATION( DracutLuksCfgJobFactory )
#endif // DRACUTLUKSCFGJOB_H #endif // DRACUTLUKSCFGJOB_H

View File

@ -25,6 +25,7 @@ calamares_add_plugin( hostinfo
LINK_PRIVATE_LIBRARIES LINK_PRIVATE_LIBRARIES
calamares calamares
SHARED_LIB SHARED_LIB
NO_CONFIG
) )
if ( KF5CoreAddons_FOUND AND KF5CoreAddons_VERSION VERSION_GREATER_EQUAL 5.58 ) if ( KF5CoreAddons_FOUND AND KF5CoreAddons_VERSION VERSION_GREATER_EQUAL 5.58 )

View File

@ -165,9 +165,4 @@ HostInfoJob::exec()
return Calamares::JobResult::ok(); return Calamares::JobResult::ok();
} }
void
HostInfoJob::setConfigurationMap( const QVariantMap& )
{
}
CALAMARES_PLUGIN_FACTORY_DEFINITION( HostInfoJobFactory, registerPlugin< HostInfoJob >(); ) CALAMARES_PLUGIN_FACTORY_DEFINITION( HostInfoJobFactory, registerPlugin< HostInfoJob >(); )

View File

@ -57,8 +57,6 @@ public:
QString prettyName() const override; QString prettyName() const override;
Calamares::JobResult exec() override; Calamares::JobResult exec() override;
void setConfigurationMap( const QVariantMap& configurationMap ) override;
}; };
CALAMARES_PLUGIN_FACTORY_DECLARATION( HostInfoJobFactory ) CALAMARES_PLUGIN_FACTORY_DECLARATION( HostInfoJobFactory )

View File

@ -4,3 +4,4 @@ name: "hwclock"
interface: "python" interface: "python"
requires: [] requires: []
script: "main.py" script: "main.py"
noconfig: true

View File

@ -3,3 +3,4 @@ type: "job"
name: "initramfscfg" name: "initramfscfg"
interface: "python" interface: "python"
script: "main.py" script: "main.py"
noconfig: true

View File

@ -6,3 +6,4 @@ type: "job"
name: "localecfg" name: "localecfg"
interface: "python" interface: "python"
script: "main.py" script: "main.py"
noconfig: true

View File

@ -6,4 +6,5 @@ calamares_add_plugin( luksbootkeyfile
LINK_PRIVATE_LIBRARIES LINK_PRIVATE_LIBRARIES
calamares calamares
SHARED_LIB SHARED_LIB
NO_CONFIG
) )

View File

@ -4,3 +4,4 @@ name: "networkcfg"
interface: "python" interface: "python"
requires: [] requires: []
script: "main.py" script: "main.py"
noconfig: true

View File

@ -192,8 +192,7 @@ PackageChooserViewStep::setConfigurationMap( const QVariantMap& configurationMap
if ( m_id.isEmpty() ) if ( m_id.isEmpty() )
{ {
// Not set, so use the instance id // Not set, so use the instance id
// TODO: use a stronger type than QString for structured IDs m_id = moduleInstanceKey().id();
m_id = moduleInstanceKey().split( '@' ).last();
} }
bool labels_ok = false; bool labels_ok = false;

View File

@ -9,4 +9,5 @@ calamares_add_plugin( summary
LINK_PRIVATE_LIBRARIES LINK_PRIVATE_LIBRARIES
calamaresui calamaresui
SHARED_LIB SHARED_LIB
NO_CONFIG
) )