diff options
author | V3n3RiX <venerix@rogentos.ro> | 2016-10-16 18:24:22 +0100 |
---|---|---|
committer | V3n3RiX <venerix@rogentos.ro> | 2016-10-16 18:24:22 +0100 |
commit | c739ae6af89cbe2c34848a10ac554f907f8e6757 (patch) | |
tree | 92208c31832f970cff71d791fc392ca89b439e66 /app-admin/calamares | |
parent | 92a9c462ce35236904efefeac1b82187bbb24c73 (diff) |
prepare calamares 2.4.2 with dracut luks support
Diffstat (limited to 'app-admin/calamares')
-rw-r--r-- | app-admin/calamares/Manifest | 1 | ||||
-rw-r--r-- | app-admin/calamares/calamares-2.4.2.ebuild | 78 | ||||
-rw-r--r-- | app-admin/calamares/files/calamares-2.4.2-dracut-luks-fde.patch | 1918 |
3 files changed, 1997 insertions, 0 deletions
diff --git a/app-admin/calamares/Manifest b/app-admin/calamares/Manifest index a584cfc5..251d3951 100644 --- a/app-admin/calamares/Manifest +++ b/app-admin/calamares/Manifest @@ -1,2 +1,3 @@ DIST calamares-1.1.tar.gz 3641655 SHA256 db0b5f09d62f43c433ff53462dc35bd43bbc4fd618fa1aac081ebb05b570edee SHA512 5b67f99e8a13f0147d510ddef2f6ba90ec81e65526159643fe3a577f62030e7a466d9dfbad0fb7befa22e59074222dd5123565b871c90c2ed25f3547ca1bb582 WHIRLPOOL c9de81bcdff03d85c98438d00fa925216e3c50670eb7354e4574c499c8b49d8fbb77e99c5733e5a9e5d97e6c9a1b795fcdf35df0cad0002227fc8b051ffc2406 DIST calamares-2.3.tar.gz 2029483 SHA256 c499a8a8ea1573c6f0323398fb092f8978958202e11c9d339202c35c73276f9f SHA512 be0b1e328ebd6bddab3a163bf38649fd4f64cfe74213946f00b0d05c76fba870662386328c0ccb7656dc63975a1b28058be7eda56b2cee792fba78443ab6d36e WHIRLPOOL aa1602aa06a4320f5a263c24e17c322bbdfcd83b7f11012e4b2cec895d6a18cdbf627d82f614ace60c62572374a9fb247216619fa0a4de207e3f8267bf51cd9e +DIST calamares-2.4.2.tar.gz 2137039 SHA256 4620fd4e9c2d9868e6c20a5c600f123e91080f7ef3a7c6ea55314aa57841b96a SHA512 152857f256f15ff72c44087baf8d4d9d452c5692e131334dd429f40c0e212eac01178352fd17f4020a128f880d3a91dbd634500384d53752d4313a08de816112 WHIRLPOOL 1aa6919a461d5b02a43a4cdbd580a9e7fc9bdc3b048f467f082c4d053c83e5bae5f5777439870828d12153789aac2e4f3b4b6868732dd7c70b0baec3ad4d65c3 diff --git a/app-admin/calamares/calamares-2.4.2.ebuild b/app-admin/calamares/calamares-2.4.2.ebuild new file mode 100644 index 00000000..bbe4dc24 --- /dev/null +++ b/app-admin/calamares/calamares-2.4.2.ebuild @@ -0,0 +1,78 @@ +# Copyright 1999-2015 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI=5 +PYTHON_COMPAT=( python3_4 ) + +inherit eutils cmake-utils python-r1 + +SRC_URI="https://github.com/calamares/calamares/releases/download/v${PV}/${P}.tar.gz" + +DESCRIPTION="Distribution-independent installer framework" +HOMEPAGE="http://calamares.io" + +LICENSE="GPL-3" +SLOT="0" +KEYWORDS="amd64" +IUSE="+python" + +S="${WORKDIR}/${P}" + +DEPEND=" + dev-vcs/git + python? ( + >=dev-libs/boost-1.55.0-r2[python_targets_python3_4] + ) + >=dev-qt/designer-5.6.0:5 + >=dev-qt/linguist-tools-5.6.0:5 + >=dev-qt/qtconcurrent-5.6.0:5 + >=dev-qt/qtcore-5.6.0:5 + >=dev-qt/qtdbus-5.6.0:5 + >=dev-qt/qtdeclarative-5.6.0:5 + >=dev-qt/qtgui-5.6.0:5 + >=dev-qt/qtnetwork-5.6.0:5 + >=dev-qt/qtopengl-5.6.0:5 + >=dev-qt/qtprintsupport-5.6.0:5 + >=dev-qt/qtscript-5.6.0:5 + >=dev-qt/qtsvg-5.6.0:5 + >=dev-qt/qttest-5.6.0:5 + >=dev-qt/qtwebengine-5.6.0:5 + >=dev-qt/qtwebchannel-5.6.0:5 + >=dev-qt/qtwidgets-5.6.0:5 + >=dev-qt/qtxml-5.6.0:5 + >=dev-qt/qtxmlpatterns-5.6.0:5 + >=dev-cpp/yaml-cpp-0.5.1 + >=kde-frameworks/extra-cmake-modules-5.18.0 + >=sys-libs/kpmcore-2.2.0" + +RDEPEND=">=app-misc/calamares-runtime-3.1[branding]" + +src_prepare() { + # patch dracut module to be called the way we want it, until the module becomes configurable + epatch ${FILESDIR}/${PN}-kogaion-dracut-call.patch + # calamares dracut luks patch + epatch ${FILESDIR}/${P}-dracut-luks-fde.patch + # replace calamares installer desktop icon + sed -i "s/Icon=calamares/Icon=start-here/g" "${S}/calamares.desktop" + # fix installer doesn't start from desktop launcher (IMPROVE THIS UGLY THINGY) + sed -i "s/pkexec //g" "${S}/calamares.desktop" + sed -i "s/calamares/calamares-pkexec/g" "${S}/calamares.desktop" + # If qtchooser is installed, it may break the build, because moc,rcc and uic binaries for wrong qt version may be used. + # Setting QT_SELECT environment variable will enforce correct binaries (fix taken from vlc ebuild) + export QT_SELECT=qt5 +} + +src_configure() { + local mycmakeargs=( + -DWITH_PARTITIONMANAGER=1 + ) + cmake-utils_src_configure +} + +src_install() { + cmake-utils_src_install + insinto /usr/bin + insopts -m 755 + doins ${FILESDIR}/calamares-pkexec +} diff --git a/app-admin/calamares/files/calamares-2.4.2-dracut-luks-fde.patch b/app-admin/calamares/files/calamares-2.4.2-dracut-luks-fde.patch new file mode 100644 index 00000000..55669822 --- /dev/null +++ b/app-admin/calamares/files/calamares-2.4.2-dracut-luks-fde.patch @@ -0,0 +1,1918 @@ +From 03c7357dbcb70c047c0aac0a2566c50aaaed1168 Mon Sep 17 00:00:00 2001 +From: Kevin Kofler <kevin.kofler@chello.at> +Date: Sun, 25 Sep 2016 03:20:50 +0200 +Subject: [PATCH] Add support for LUKS full disk encryption with dracut. + +Add support for C++/Qt batch job plugins + +These job plugins work similarly to view modules, with the following +differences: + +* These jobs need to link only libcalamares, not libcalamaresui. For + this reason, PluginFactory was moved from libcalamaresui to + libcalamares. (It depends only on QtCore.) + +* Instead of deriving from ViewModule, derive from CppJob (which is a + subclass of Job). + +* Like process and Python jobs, a job plugin is a single job, whereas a + ViewModule can generate a whole list of jobs. + +The CppJob and CppJobModule classes are new. In Module::fromDescriptor, +the combination type=job, intf=qtplugin is now supported and mapped to +CppJobModule. + +[fstab] Do not omit "/" from crypttab. + +At least the Debian update-initramfs needs the entry to be there (see +pull request #254). Dracut will probably need it too. And logically, it +should be there. + +[fstab] Write configurable options to crypttab (default: luks). + +fstab.conf: Add a new "crypttabOptions" option that defaults to "luks". + Document that for Debian and Debian-based distributions, the + setting should be changed to "luks,keyscript=/bin/cat". + +main.py: Append the options from the above setting to the end of every + line in crypttab. + +At least the "luks" option should always be there, because there may be +different encryption types. The Debian initramfs-tools also require the +Debian-specific keyscript option and will otherwise ignore the keyfile +entirely (see pull request #254). + +[dracutlukscfg] New module: pre-configuration for dracut+LUKS. + +Add a dracutlukscfg module to write a +/etc/dracut.conf.d/calamares-luks.conf file for LUKS full disk +encryption support with Dracut. + +You should run: + +* partition +* luksbootkeyfile +* dracutlukscfg +* dracut + +in that order (not necessarily in immediate sequence). The +luksopenswaphook module is not used with Dracut. +--- + settings.conf | 1 + + src/libcalamares/CMakeLists.txt | 2 + + src/libcalamares/CppJob.cpp | 45 +++ + src/libcalamares/CppJob.h | 51 ++++ + src/libcalamares/utils/PluginFactory.cpp | 123 ++++++++ + src/libcalamares/utils/PluginFactory.h | 370 +++++++++++++++++++++++ + src/libcalamares/utils/PluginFactory_p.h | 54 ++++ + src/libcalamaresui/CMakeLists.txt | 3 +- + src/libcalamaresui/modulesystem/CppJobModule.cpp | 128 ++++++++ + src/libcalamaresui/modulesystem/CppJobModule.h | 53 ++++ + src/libcalamaresui/modulesystem/Module.cpp | 7 +- + src/libcalamaresui/utils/PluginFactory.cpp | 123 -------- + src/libcalamaresui/utils/PluginFactory.h | 370 ----------------------- + src/libcalamaresui/utils/PluginFactory_p.h | 54 ---- + src/modules/dracutlukscfg/CMakeLists.txt | 9 + + src/modules/dracutlukscfg/DracutLuksCfgJob.cpp | 143 +++++++++ + src/modules/dracutlukscfg/DracutLuksCfgJob.h | 56 ++++ + src/modules/dracutlukscfg/module.desc | 7 + + src/modules/fstab/fstab.conf | 3 + + src/modules/fstab/main.py | 21 +- + 20 files changed, 1064 insertions(+), 559 deletions(-) + create mode 100644 src/libcalamares/CppJob.cpp + create mode 100644 src/libcalamares/CppJob.h + create mode 100644 src/libcalamares/utils/PluginFactory.cpp + create mode 100644 src/libcalamares/utils/PluginFactory.h + create mode 100644 src/libcalamares/utils/PluginFactory_p.h + create mode 100644 src/libcalamaresui/modulesystem/CppJobModule.cpp + create mode 100644 src/libcalamaresui/modulesystem/CppJobModule.h + delete mode 100644 src/libcalamaresui/utils/PluginFactory.cpp + delete mode 100644 src/libcalamaresui/utils/PluginFactory.h + delete mode 100644 src/libcalamaresui/utils/PluginFactory_p.h + create mode 100644 src/modules/dracutlukscfg/CMakeLists.txt + create mode 100644 src/modules/dracutlukscfg/DracutLuksCfgJob.cpp + create mode 100644 src/modules/dracutlukscfg/DracutLuksCfgJob.h + create mode 100644 src/modules/dracutlukscfg/module.desc + +diff --git a/settings.conf b/settings.conf +index 0721098..d4439a7 100644 +--- a/settings.conf ++++ b/settings.conf +@@ -79,6 +79,7 @@ sequence: + - localecfg + # - luksbootkeyfile + # - luksopenswaphookcfg ++# - dracutlukscfg + - initcpiocfg + - initcpio + - users +diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt +index 966ca9c..b1f6c48 100644 +--- a/src/libcalamares/CMakeLists.txt ++++ b/src/libcalamares/CMakeLists.txt +@@ -11,6 +11,7 @@ configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/../calamares/CalamaresVersion.h.in + ${CMAKE_CURRENT_BINARY_DIR}/CalamaresVersion.h ) + + set( libSources ++ CppJob.cpp + GlobalStorage.cpp + Job.cpp + JobQueue.cpp +@@ -24,6 +25,7 @@ set( libSources + utils/CalamaresUtils.cpp + utils/CalamaresUtilsSystem.cpp + utils/Logger.cpp ++ utils/PluginFactory.cpp + utils/Retranslator.cpp + ) + +diff --git a/src/libcalamares/CppJob.cpp b/src/libcalamares/CppJob.cpp +new file mode 100644 +index 0000000..1925e39 +--- /dev/null ++++ b/src/libcalamares/CppJob.cpp +@@ -0,0 +1,45 @@ ++/* === This file is part of Calamares - <http://github.com/calamares> === ++ * ++ * Copyright 2014, Teo Mrnjavac <teo@kde.org> ++ * Copyright 2016, Kevin Kofler <kevin.kofler@chello.at> ++ * ++ * 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 "CppJob.h" ++ ++namespace Calamares ++{ ++ ++CppJob::CppJob( QObject* parent ) ++ : Job( parent ) ++{} ++ ++ ++CppJob::~CppJob() ++{} ++ ++ ++void ++CppJob::setModuleInstanceKey( const QString& instanceKey ) ++{ ++ m_instanceKey = instanceKey; ++} ++ ++ ++void ++CppJob::setConfigurationMap( const QVariantMap& configurationMap ) ++{} ++ ++} +diff --git a/src/libcalamares/CppJob.h b/src/libcalamares/CppJob.h +new file mode 100644 +index 0000000..a6e6735 +--- /dev/null ++++ b/src/libcalamares/CppJob.h +@@ -0,0 +1,51 @@ ++/* === This file is part of Calamares - <http://github.com/calamares> === ++ * ++ * Copyright 2014-2015, Teo Mrnjavac <teo@kde.org> ++ * Copyright 2016, Kevin Kofler <kevin.kofler@chello.at> ++ * ++ * 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 CALAMARES_CPPJOB_H ++#define CALAMARES_CPPJOB_H ++ ++#include <QObject> ++#include <QVariant> ++ ++#include "DllMacro.h" ++#include "Typedefs.h" ++#include "Job.h" ++ ++namespace Calamares ++{ ++ ++class DLLEXPORT CppJob : public Job ++{ ++ Q_OBJECT ++public: ++ explicit CppJob( QObject* parent = nullptr ); ++ virtual ~CppJob(); ++ ++ void setModuleInstanceKey( const QString& instanceKey ); ++ QString moduleInstanceKey() const { return m_instanceKey; } ++ ++ virtual void setConfigurationMap( const QVariantMap& configurationMap ); ++ ++protected: ++ QString m_instanceKey; ++}; ++ ++} ++ ++#endif // CALAMARES_CPPJOB_H +diff --git a/src/libcalamares/utils/PluginFactory.cpp b/src/libcalamares/utils/PluginFactory.cpp +new file mode 100644 +index 0000000..30a5bf4 +--- /dev/null ++++ b/src/libcalamares/utils/PluginFactory.cpp +@@ -0,0 +1,123 @@ ++/* === This file is part of Calamares - <http://github.com/calamares> === ++ * ++ * Copyright 2015, Teo Mrnjavac <teo@kde.org> ++ * ++ * Based on KPluginFactory from KCoreAddons, KDE project ++ * Copyright 2007, Matthias Kretz <kretz@kde.org> ++ * Copyright 2007, Bernhard Loos <nhuh.put@web.de> ++ * ++ * 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 "PluginFactory.h" ++#include "PluginFactory_p.h" ++ ++#include <QObjectCleanupHandler> ++#include <QDebug> ++ ++Q_GLOBAL_STATIC(QObjectCleanupHandler, factorycleanup) ++ ++extern int kLibraryDebugArea(); ++ ++namespace Calamares ++{ ++ ++PluginFactory::PluginFactory() ++ : d_ptr(new PluginFactoryPrivate) ++{ ++ Q_D(PluginFactory); ++ d->q_ptr = this; ++ ++ factorycleanup()->add(this); ++} ++ ++PluginFactory::PluginFactory(PluginFactoryPrivate &d) ++ : d_ptr(&d) ++{ ++ factorycleanup()->add(this); ++} ++ ++PluginFactory::~PluginFactory() ++{ ++ delete d_ptr; ++} ++ ++void PluginFactory::doRegisterPlugin(const QString &keyword, const QMetaObject *metaObject, CreateInstanceFunction instanceFunction) ++{ ++ Q_D(PluginFactory); ++ ++ Q_ASSERT(metaObject); ++ ++ // we allow different interfaces to be registered without keyword ++ if (!keyword.isEmpty()) { ++ if (d->createInstanceHash.contains(keyword)) { ++ qWarning() << "A plugin with the keyword" << keyword << "was already registered. A keyword must be unique!"; ++ } ++ d->createInstanceHash.insert(keyword, PluginFactoryPrivate::Plugin(metaObject, instanceFunction)); ++ } else { ++ const QList<PluginFactoryPrivate::Plugin> clashes(d->createInstanceHash.values(keyword)); ++ const QMetaObject *superClass = metaObject->superClass(); ++ if (superClass) { ++ for (const PluginFactoryPrivate::Plugin &plugin : clashes) { ++ for (const QMetaObject *otherSuper = plugin.first->superClass(); otherSuper; ++ otherSuper = otherSuper->superClass()) { ++ if (superClass == otherSuper) { ++ qWarning() << "Two plugins with the same interface(" << superClass->className() << ") were registered. Use keywords to identify the plugins."; ++ } ++ } ++ } ++ } ++ for (const PluginFactoryPrivate::Plugin &plugin : clashes) { ++ superClass = plugin.first->superClass(); ++ if (superClass) { ++ for (const QMetaObject *otherSuper = metaObject->superClass(); otherSuper; ++ otherSuper = otherSuper->superClass()) { ++ if (superClass == otherSuper) { ++ qWarning() << "Two plugins with the same interface(" << superClass->className() << ") were registered. Use keywords to identify the plugins."; ++ } ++ } ++ } ++ } ++ d->createInstanceHash.insertMulti(keyword, PluginFactoryPrivate::Plugin(metaObject, instanceFunction)); ++ } ++} ++ ++QObject *PluginFactory::create(const char *iface, QWidget *parentWidget, QObject *parent, const QString &keyword) ++{ ++ Q_D(PluginFactory); ++ ++ QObject *obj = 0; ++ ++ const QList<PluginFactoryPrivate::Plugin> candidates(d->createInstanceHash.values(keyword)); ++ // for !keyword.isEmpty() candidates.count() is 0 or 1 ++ ++ for (const PluginFactoryPrivate::Plugin &plugin : candidates) { ++ for (const QMetaObject *current = plugin.first; current; current = current->superClass()) { ++ if (0 == qstrcmp(iface, current->className())) { ++ if (obj) { ++ qWarning() << "ambiguous interface requested from a DSO containing more than one plugin"; ++ } ++ obj = plugin.second(parentWidget, parent); ++ break; ++ } ++ } ++ } ++ ++ if (obj) { ++ emit objectCreated(obj); ++ } ++ return obj; ++} ++ ++} +diff --git a/src/libcalamares/utils/PluginFactory.h b/src/libcalamares/utils/PluginFactory.h +new file mode 100644 +index 0000000..c0053ba +--- /dev/null ++++ b/src/libcalamares/utils/PluginFactory.h +@@ -0,0 +1,370 @@ ++/* === This file is part of Calamares - <http://github.com/calamares> === ++ * ++ * Copyright 2015, Teo Mrnjavac <teo@kde.org> ++ * ++ * Based on KPluginFactory from KCoreAddons, KDE project ++ * Copyright 2007, Matthias Kretz <kretz@kde.org> ++ * Copyright 2007, Bernhard Loos <nhuh.put@web.de> ++ * ++ * 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 CALAMARESPLUGINFACTORY_H ++#define CALAMARESPLUGINFACTORY_H ++ ++#include "DllMacro.h" ++ ++#include <QtCore/QObject> ++#include <QtCore/QVariant> ++#include <QtCore/QStringList> ++ ++namespace Calamares ++{ ++class PluginFactoryPrivate; ++} ++ ++#define CalamaresPluginFactory_iid "io.calamares.PluginFactory" ++ ++#define CALAMARES_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY_SKEL(name, baseFactory, ...) \ ++ class name : public Calamares::PluginFactory \ ++ { \ ++ Q_OBJECT \ ++ Q_INTERFACES(Calamares::PluginFactory) \ ++ __VA_ARGS__ \ ++ public: \ ++ explicit name(); \ ++ ~name(); \ ++ private: \ ++ void init(); \ ++ }; ++ ++#define CALAMARES_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY(name, baseFactory) \ ++ CALAMARES_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY_SKEL(name, baseFactory, Q_PLUGIN_METADATA(IID CalamaresPluginFactory_iid)) ++ ++#define CALAMARES_PLUGIN_FACTORY_DEFINITION_WITH_BASEFACTORY(name, baseFactory, pluginRegistrations) \ ++ name::name() \ ++ { \ ++ pluginRegistrations \ ++ } \ ++ name::~name() {} ++ ++#define CALAMARES_PLUGIN_FACTORY_WITH_BASEFACTORY(name, baseFactory, pluginRegistrations) \ ++ CALAMARES_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY(name, baseFactory) \ ++ CALAMARES_PLUGIN_FACTORY_DEFINITION_WITH_BASEFACTORY(name, baseFactory, pluginRegistrations) ++ ++#define CALAMARES_PLUGIN_FACTORY_DECLARATION(name) CALAMARES_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY(name, Calamares::PluginFactory) ++#define CALAMARES_PLUGIN_FACTORY_DEFINITION(name, pluginRegistrations) CALAMARES_PLUGIN_FACTORY_DEFINITION_WITH_BASEFACTORY(name, Calamares::PluginFactory, pluginRegistrations) ++ ++/** ++ * \relates PluginFactory ++ * ++ * Create a PluginFactory subclass and export it as the root plugin object. ++ * ++ * \param name The name of the PluginFactory derived class. ++ * ++ * \param pluginRegistrations Code to be inserted into the constructor of the ++ * class. Usually a series of registerPlugin() calls. ++ * ++ * Example: ++ * \code ++ * #include <PluginFactory.h> ++ * #include <plugininterface.h> ++ * ++ * class MyPlugin : public PluginInterface ++ * { ++ * public: ++ * MyPlugin(QObject *parent, const QVariantList &args) ++ * : PluginInterface(parent) ++ * {} ++ * }; ++ * ++ * CALAMARES_PLUGIN_FACTORY(MyPluginFactory, ++ * registerPlugin<MyPlugin>(); ++ * ) ++ * ++ * #include <myplugin.moc> ++ * \endcode ++ * ++ * \see CALAMARES_PLUGIN_FACTORY_DECLARATION ++ * \see CALAMARES_PLUGIN_FACTORY_DEFINITION ++ */ ++#define CALAMARES_PLUGIN_FACTORY(name, pluginRegistrations) CALAMARES_PLUGIN_FACTORY_WITH_BASEFACTORY(name, Calamares::PluginFactory, pluginRegistrations) ++ ++/** ++ * \relates PluginFactory ++ * ++ * CALAMARES_PLUGIN_FACTORY_DECLARATION declares the PluginFactory subclass. This macro ++ * can be used in a header file. ++ * ++ * \param name The name of the PluginFactory derived class. ++ * ++ * \see CALAMARES_PLUGIN_FACTORY ++ * \see CALAMARES_PLUGIN_FACTORY_DEFINITION ++ */ ++#define CALAMARES_PLUGIN_FACTORY_DECLARATION(name) CALAMARES_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY(name, Calamares::PluginFactory) ++ ++/** ++ * \relates PluginFactory ++ * CALAMARES_PLUGIN_FACTORY_DEFINITION defines the PluginFactory subclass. This macro ++ * can <b>not</b> be used in a header file. ++ * ++ * \param name The name of the PluginFactory derived class. ++ * ++ * \param pluginRegistrations Code to be inserted into the constructor of the ++ * class. Usually a series of registerPlugin() calls. ++ * ++ * \see CALAMARES_PLUGIN_FACTORY ++ * \see CALAMARES_PLUGIN_FACTORY_DECLARATION ++ */ ++#define CALAMARES_PLUGIN_FACTORY_DEFINITION(name, pluginRegistrations) CALAMARES_PLUGIN_FACTORY_DEFINITION_WITH_BASEFACTORY(name, Calamares::PluginFactory, pluginRegistrations) ++ ++namespace Calamares ++{ ++ ++/** ++ * \class PluginFactory PluginFactory.h <PluginFactory.h> ++ * ++ * PluginFactory provides a convenient way to provide factory-style plugins. ++ * Qt plugins provide a singleton object, but a common pattern is for plugins ++ * to generate as many objects of a particular type as the application requires. ++ * By using PluginFactory, you can avoid implementing the factory pattern ++ * yourself. ++ * ++ * PluginFactory also allows plugins to provide multiple different object ++ * types, indexed by keywords. ++ * ++ * The objects created by PluginFactory must inherit QObject, and must have a ++ * standard constructor pattern: ++ * \li if the object is a KPart::Part, it must be of the form ++ * \code ++ * T(QWidget *parentWidget, QObject *parent, const QVariantList &args) ++ * \endcode ++ * \li if it is a QWidget, it must be of the form ++ * \code ++ * T(QWidget *parent, const QVariantList &args) ++ * \endcode ++ * \li otherwise it must be of the form ++ * \code ++ * T(QObject *parent, const QVariantList &args) ++ * \endcode ++ * ++ * You should typically use either CALAMARES_PLUGIN_FACTORY() or ++ * CALAMARES_PLUGIN_FACTORY_WITH_JSON() in your plugin code to create the factory. The ++ * typical pattern is ++ * ++ * \code ++ * #include <PluginFactory.h> ++ * #include <plugininterface.h> ++ * ++ * class MyPlugin : public PluginInterface ++ * { ++ * public: ++ * MyPlugin(QObject *parent, const QVariantList &args) ++ * : PluginInterface(parent) ++ * {} ++ * }; ++ * ++ * CALAMARES_PLUGIN_FACTORY(MyPluginFactory, ++ * registerPlugin<MyPlugin>(); ++ * ) ++ * #include <myplugin.moc> ++ * \endcode ++ * ++ * If you want to load a library use KPluginLoader. ++ * The application that wants to instantiate plugin classes can do the following: ++ * \code ++ * PluginFactory *factory = KPluginLoader("libraryname").factory(); ++ * if (factory) { ++ * PluginInterface *p1 = factory->create<PluginInterface>(parent); ++ * OtherInterface *p2 = factory->create<OtherInterface>(parent); ++ * NextInterface *p3 = factory->create<NextInterface>("keyword1", parent); ++ * NextInterface *p3 = factory->create<NextInterface>("keyword2", parent); ++ * } ++ * \endcode ++ * ++ * \author Matthias Kretz <kretz@kde.org> ++ * \author Bernhard Loos <nhuh.put@web.de> ++ */ ++class DLLEXPORT PluginFactory : public QObject ++{ ++ Q_OBJECT ++ Q_DECLARE_PRIVATE(PluginFactory) ++public: ++ /** ++ * This constructor creates a factory for a plugin. ++ */ ++ explicit PluginFactory(); ++ ++ /** ++ * This destroys the PluginFactory. ++ */ ++ virtual ~PluginFactory(); ++ ++ /** ++ * Use this method to create an object. It will try to create an object which inherits ++ * \p T. If it has multiple choices, you will get a fatal error (kFatal()), so be careful ++ * to request a unique interface or use keywords. ++ * ++ * \tparam T The interface for which an object should be created. The object will inherit \p T. ++ * \param parent The parent of the object. If \p parent is a widget type, it will also passed ++ * to the parentWidget argument of the CreateInstanceFunction for the object. ++ * \returns A pointer to the created object is returned, or 0 if an error occurred. ++ */ ++ template<typename T> ++ T *create(QObject *parent = 0); ++ ++ /** ++ * Use this method to create an object. It will try to create an object which inherits ++ * \p T and was registered with \p keyword. ++ * ++ * \tparam T The interface for which an object should be created. The object will inherit \p T. ++ * \param keyword The keyword of the object. ++ * \param parent The parent of the object. If \p parent is a widget type, it will also passed ++ * to the parentWidget argument of the CreateInstanceFunction for the object. ++ * \returns A pointer to the created object is returned, or 0 if an error occurred. ++ */ ++ template<typename T> ++ T *create(const QString &keyword, QObject *parent = 0); ++ ++Q_SIGNALS: ++ void objectCreated(QObject *object); ++ ++protected: ++ /** ++ * Function pointer type to a function that instantiates a plugin. ++ */ ++ typedef QObject *(*CreateInstanceFunction)(QWidget *, QObject *); ++ ++ /** ++ * This is used to detect the arguments need for the constructor of plugin classes. ++ * You can inherit it, if you want to add new classes and still keep support for the old ones. ++ */ ++ template<class impl> ++ struct InheritanceChecker { ++ CreateInstanceFunction createInstanceFunction(QWidget *) ++ { ++ return &createInstance<impl, QWidget>; ++ } ++ CreateInstanceFunction createInstanceFunction(...) ++ { ++ return &createInstance<impl, QObject>; ++ } ++ }; ++ ++ explicit PluginFactory(PluginFactoryPrivate &dd); ++ ++ /** ++ * Registers a plugin with the factory. Call this function from the constructor of the ++ * PluginFactory subclass to make the create function able to instantiate the plugin when asked ++ * for an interface the plugin implements. ++ * ++ * \tparam T the name of the plugin class ++ * ++ * \param keyword An optional keyword as unique identifier for the plugin. This allows you to ++ * put more than one plugin with the same interface into the same library using the same ++ * factory. X-KDE-PluginKeyword is a convenient way to specify the keyword in a desktop file. ++ * ++ * \param instanceFunction A function pointer to a function that creates an instance of the ++ * plugin. The default function that will be used depends on the type of interface. If the ++ * interface inherits from ++ * \li \c KParts::Part the function will call ++ * \code ++ * new T(QWidget *parentWidget, QObject *parent) ++ * \endcode ++ * \li \c QWidget the function will call ++ * \code ++ * new T(QWidget *parent) ++ * \endcode ++ * \li else the function will call ++ * \code ++ * new T(QObject *parent) ++ * \endcode ++ */ ++ template<class T> ++ void registerPlugin(const QString &keyword = QString(), ++ CreateInstanceFunction instanceFunction ++ = InheritanceChecker<T>().createInstanceFunction(reinterpret_cast<T *>(0))) ++ { ++ doRegisterPlugin(keyword, &T::staticMetaObject, instanceFunction); ++ } ++ ++ PluginFactoryPrivate *const d_ptr; ++ ++ /** ++ * This function is called when the factory asked to create an Object. ++ * ++ * You may reimplement it to provide a very flexible factory. This is especially useful to ++ * provide generic factories for plugins implemeted using a scripting language. ++ * ++ * \param iface The staticMetaObject::className() string identifying the plugin interface that ++ * was requested. E.g. for KCModule plugins this string will be "KCModule". ++ * \param parentWidget Only used if the requested plugin is a KPart. ++ * \param parent The parent object for the plugin object. ++ * \param args A plugin specific list of arbitrary arguments. ++ * \param keyword A string that uniquely identifies the plugin. If a KService is used this ++ * keyword is read from the X-KDE-PluginKeyword entry in the .desktop file. ++ */ ++ virtual QObject *create(const char *iface, QWidget *parentWidget, QObject *parent, const QString &keyword); ++ ++ template<class impl, class ParentType> ++ static QObject *createInstance(QWidget *parentWidget, QObject *parent) ++ { ++ Q_UNUSED(parentWidget); ++ ParentType *p = 0; ++ if (parent) { ++ p = qobject_cast<ParentType *>(parent); ++ Q_ASSERT(p); ++ } ++ return new impl(p); ++ } ++ ++private: ++ void doRegisterPlugin(const QString &keyword, const QMetaObject *metaObject, CreateInstanceFunction instanceFunction); ++}; ++ ++template<typename T> ++inline T *PluginFactory::create(QObject *parent) ++{ ++ QObject *o = create(T::staticMetaObject.className(), ++ parent && parent->isWidgetType() ? reinterpret_cast<QWidget *>(parent) : 0, ++ parent, ++ QString()); ++ ++ T *t = qobject_cast<T *>(o); ++ if (!t) { ++ delete o; ++ } ++ return t; ++} ++ ++template<typename T> ++inline T *PluginFactory::create(const QString &keyword, QObject *parent) ++{ ++ QObject *o = create(T::staticMetaObject.className(), ++ parent && parent->isWidgetType() ? reinterpret_cast<QWidget *>(parent) : 0, ++ parent, ++ keyword); ++ ++ T *t = qobject_cast<T *>(o); ++ if (!t) { ++ delete o; ++ } ++ return t; ++} ++ ++} ++ ++Q_DECLARE_INTERFACE(Calamares::PluginFactory, CalamaresPluginFactory_iid) ++ ++#endif // CALAMARESPLUGINFACTORY_H +diff --git a/src/libcalamares/utils/PluginFactory_p.h b/src/libcalamares/utils/PluginFactory_p.h +new file mode 100644 +index 0000000..a0b4a1c +--- /dev/null ++++ b/src/libcalamares/utils/PluginFactory_p.h +@@ -0,0 +1,54 @@ ++/* === This file is part of Calamares - <http://github.com/calamares> === ++ * ++ * Copyright 2015, Teo Mrnjavac <teo@kde.org> ++ * ++ * Based on KPluginFactory from KCoreAddons, KDE project ++ * Copyright 2007, Matthias Kretz <kretz@kde.org> ++ * Copyright 2007, Bernhard Loos <nhuh.put@web.de> ++ * ++ * 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 CALAMARESPLUGINFACTORY_P_H ++#define CALAMARESPLUGINFACTORY_P_H ++ ++#include "PluginFactory.h" ++ ++#include <QtCore/QHash> ++ ++namespace Calamares ++{ ++ ++class PluginFactoryPrivate ++{ ++ Q_DECLARE_PUBLIC(PluginFactory) ++protected: ++ typedef QPair<const QMetaObject *, PluginFactory::CreateInstanceFunction> Plugin; ++ ++ PluginFactoryPrivate() ++ : catalogInitialized( false ) ++ , q_ptr( nullptr ) ++ {} ++ ~PluginFactoryPrivate() {} ++ ++ QHash<QString, Plugin> createInstanceHash; ++ QString catalogName; ++ bool catalogInitialized; ++ ++ PluginFactory *q_ptr; ++}; ++ ++} ++ ++#endif // CALAMARESPLUGINFACTORY_P_H +diff --git a/src/libcalamaresui/CMakeLists.txt b/src/libcalamaresui/CMakeLists.txt +index 939d05a..478034b 100644 +--- a/src/libcalamaresui/CMakeLists.txt ++++ b/src/libcalamaresui/CMakeLists.txt +@@ -1,6 +1,7 @@ + set( CALAMARESUI_LIBRARY_TARGET calamaresui ) + + list( APPEND ${CALAMARESUI_LIBRARY_TARGET}_SOURCES ++ modulesystem/CppJobModule.cpp + modulesystem/Module.cpp + modulesystem/ModuleManager.cpp + modulesystem/ProcessJobModule.cpp +@@ -14,8 +15,6 @@ list( APPEND ${CALAMARESUI_LIBRARY_TARGET}_SOURCES + utils/qjsonmodel.cpp + utils/qjsonitem.cpp + +- utils/PluginFactory.cpp +- + viewpages/AbstractPage.cpp + viewpages/ViewStep.cpp + +diff --git a/src/libcalamaresui/modulesystem/CppJobModule.cpp b/src/libcalamaresui/modulesystem/CppJobModule.cpp +new file mode 100644 +index 0000000..15e41c2 +--- /dev/null ++++ b/src/libcalamaresui/modulesystem/CppJobModule.cpp +@@ -0,0 +1,128 @@ ++/* === This file is part of Calamares - <http://github.com/calamares> === ++ * ++ * Copyright 2014, Teo Mrnjavac <teo@kde.org> ++ * Copyright 2016, Kevin Kofler <kevin.kofler@chello.at> ++ * ++ * 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 "CppJobModule.h" ++ ++#include "utils/PluginFactory.h" ++#include "utils/Logger.h" ++#include "CppJob.h" ++ ++#include <QDir> ++#include <QPluginLoader> ++ ++namespace Calamares { ++ ++ ++Module::Type ++CppJobModule::type() const ++{ ++ return Job; ++} ++ ++ ++Module::Interface ++CppJobModule::interface() const ++{ ++ return QtPlugin; ++} ++ ++ ++void ++CppJobModule::loadSelf() ++{ ++ if ( m_loader ) ++ { ++ PluginFactory* pf = qobject_cast< PluginFactory* >( m_loader->instance() ); ++ if ( !pf ) ++ { ++ cDebug() << Q_FUNC_INFO << m_loader->errorString(); ++ return; ++ } ++ ++ CppJob *cppJob = pf->create< Calamares::CppJob >(); ++ if ( !cppJob ) ++ { ++ cDebug() << Q_FUNC_INFO << m_loader->errorString(); ++ return; ++ } ++// cDebug() << "CppJobModule loading self for instance" << instanceKey() ++// << "\nCppJobModule at address" << this ++// << "\nCalamares::PluginFactory at address" << pf ++// << "\nCppJob at address" << cppJob; ++ ++ cppJob->setModuleInstanceKey( instanceKey() ); ++ cppJob->setConfigurationMap( m_configurationMap ); ++ m_job = Calamares::job_ptr( static_cast< Calamares::Job * >( cppJob ) ); ++ m_loaded = true; ++ cDebug() << "CppJobModule" << instanceKey() << "loading complete."; ++ } ++} ++ ++ ++QList< job_ptr > ++CppJobModule::jobs() const ++{ ++ return QList< job_ptr >() << m_job; ++} ++ ++ ++void ++CppJobModule::initFrom( const QVariantMap& moduleDescriptor ) ++{ ++ Module::initFrom( moduleDescriptor ); ++ QDir directory( location() ); ++ QString load; ++ if ( !moduleDescriptor.value( "load" ).toString().isEmpty() ) ++ { ++ load = moduleDescriptor.value( "load" ).toString(); ++ load = directory.absoluteFilePath( load ); ++ } ++ // If a load path is not specified, we look for a plugin to load in the directory. ++ if ( load.isEmpty() || !QLibrary::isLibrary( load ) ) ++ { ++ const QStringList ls = directory.entryList( QStringList{ "*.so" } ); ++ if ( !ls.isEmpty() ) ++ { ++ for ( QString entry : ls ) ++ { ++ entry = directory.absoluteFilePath( entry ); ++ if ( QLibrary::isLibrary( entry ) ) ++ { ++ load = entry; ++ break; ++ } ++ } ++ } ++ } ++ ++ m_loader = new QPluginLoader( load ); ++} ++ ++CppJobModule::CppJobModule() ++ : Module() ++ , m_loader( nullptr ) ++{ ++} ++ ++CppJobModule::~CppJobModule() ++{ ++ delete m_loader; ++} ++ ++} // namespace Calamares +diff --git a/src/libcalamaresui/modulesystem/CppJobModule.h b/src/libcalamaresui/modulesystem/CppJobModule.h +new file mode 100644 +index 0000000..127614e +--- /dev/null ++++ b/src/libcalamaresui/modulesystem/CppJobModule.h +@@ -0,0 +1,53 @@ ++/* === This file is part of Calamares - <http://github.com/calamares> === ++ * ++ * Copyright 2014, Teo Mrnjavac <teo@kde.org> ++ * Copyright 2016, Kevin Kofler <kevin.kofler@chello.at> ++ * ++ * 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 CALAMARES_CPPJOBMODULE_H ++#define CALAMARES_CPPJOBMODULE_H ++ ++#include "UiDllMacro.h" ++#include "Module.h" ++ ++class QPluginLoader; ++ ++namespace Calamares { ++ ++class UIDLLEXPORT CppJobModule : public Module ++{ ++public: ++ Type type() const override; ++ Interface interface() const override; ++ ++ void loadSelf() override; ++ QList< job_ptr > jobs() const override; ++ ++protected: ++ void initFrom( const QVariantMap& moduleDescriptor ) override; ++ ++private: ++ friend class Module; //so only the superclass can instantiate ++ explicit CppJobModule(); ++ virtual ~CppJobModule(); ++ ++ QPluginLoader* m_loader; ++ job_ptr m_job; ++}; ++ ++} // namespace Calamares ++ ++#endif // CALAMARES_CPPJOBMODULE_H +diff --git a/src/libcalamaresui/modulesystem/Module.cpp b/src/libcalamaresui/modulesystem/Module.cpp +index 7809754..2a2fe77 100644 +--- a/src/libcalamaresui/modulesystem/Module.cpp ++++ b/src/libcalamaresui/modulesystem/Module.cpp +@@ -19,6 +19,7 @@ + #include "Module.h" + + #include "ProcessJobModule.h" ++#include "CppJobModule.h" + #include "ViewModule.h" + #include "utils/CalamaresUtils.h" + #include "utils/YamlUtils.h" +@@ -76,7 +77,11 @@ Module::fromDescriptor( const QVariantMap& moduleDescriptor, + } + else if ( typeString == "job" ) + { +- if ( intfString == "process" ) ++ if ( intfString == "qtplugin" ) ++ { ++ m = new CppJobModule(); ++ } ++ else if ( intfString == "process" ) + { + m = new ProcessJobModule(); + } +diff --git a/src/libcalamaresui/utils/PluginFactory.cpp b/src/libcalamaresui/utils/PluginFactory.cpp +deleted file mode 100644 +index 30a5bf4..0000000 +--- a/src/libcalamaresui/utils/PluginFactory.cpp ++++ /dev/null +@@ -1,123 +0,0 @@ +-/* === This file is part of Calamares - <http://github.com/calamares> === +- * +- * Copyright 2015, Teo Mrnjavac <teo@kde.org> +- * +- * Based on KPluginFactory from KCoreAddons, KDE project +- * Copyright 2007, Matthias Kretz <kretz@kde.org> +- * Copyright 2007, Bernhard Loos <nhuh.put@web.de> +- * +- * 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 "PluginFactory.h" +-#include "PluginFactory_p.h" +- +-#include <QObjectCleanupHandler> +-#include <QDebug> +- +-Q_GLOBAL_STATIC(QObjectCleanupHandler, factorycleanup) +- +-extern int kLibraryDebugArea(); +- +-namespace Calamares +-{ +- +-PluginFactory::PluginFactory() +- : d_ptr(new PluginFactoryPrivate) +-{ +- Q_D(PluginFactory); +- d->q_ptr = this; +- +- factorycleanup()->add(this); +-} +- +-PluginFactory::PluginFactory(PluginFactoryPrivate &d) +- : d_ptr(&d) +-{ +- factorycleanup()->add(this); +-} +- +-PluginFactory::~PluginFactory() +-{ +- delete d_ptr; +-} +- +-void PluginFactory::doRegisterPlugin(const QString &keyword, const QMetaObject *metaObject, CreateInstanceFunction instanceFunction) +-{ +- Q_D(PluginFactory); +- +- Q_ASSERT(metaObject); +- +- // we allow different interfaces to be registered without keyword +- if (!keyword.isEmpty()) { +- if (d->createInstanceHash.contains(keyword)) { +- qWarning() << "A plugin with the keyword" << keyword << "was already registered. A keyword must be unique!"; +- } +- d->createInstanceHash.insert(keyword, PluginFactoryPrivate::Plugin(metaObject, instanceFunction)); +- } else { +- const QList<PluginFactoryPrivate::Plugin> clashes(d->createInstanceHash.values(keyword)); +- const QMetaObject *superClass = metaObject->superClass(); +- if (superClass) { +- for (const PluginFactoryPrivate::Plugin &plugin : clashes) { +- for (const QMetaObject *otherSuper = plugin.first->superClass(); otherSuper; +- otherSuper = otherSuper->superClass()) { +- if (superClass == otherSuper) { +- qWarning() << "Two plugins with the same interface(" << superClass->className() << ") were registered. Use keywords to identify the plugins."; +- } +- } +- } +- } +- for (const PluginFactoryPrivate::Plugin &plugin : clashes) { +- superClass = plugin.first->superClass(); +- if (superClass) { +- for (const QMetaObject *otherSuper = metaObject->superClass(); otherSuper; +- otherSuper = otherSuper->superClass()) { +- if (superClass == otherSuper) { +- qWarning() << "Two plugins with the same interface(" << superClass->className() << ") were registered. Use keywords to identify the plugins."; +- } +- } +- } +- } +- d->createInstanceHash.insertMulti(keyword, PluginFactoryPrivate::Plugin(metaObject, instanceFunction)); +- } +-} +- +-QObject *PluginFactory::create(const char *iface, QWidget *parentWidget, QObject *parent, const QString &keyword) +-{ +- Q_D(PluginFactory); +- +- QObject *obj = 0; +- +- const QList<PluginFactoryPrivate::Plugin> candidates(d->createInstanceHash.values(keyword)); +- // for !keyword.isEmpty() candidates.count() is 0 or 1 +- +- for (const PluginFactoryPrivate::Plugin &plugin : candidates) { +- for (const QMetaObject *current = plugin.first; current; current = current->superClass()) { +- if (0 == qstrcmp(iface, current->className())) { +- if (obj) { +- qWarning() << "ambiguous interface requested from a DSO containing more than one plugin"; +- } +- obj = plugin.second(parentWidget, parent); +- break; +- } +- } +- } +- +- if (obj) { +- emit objectCreated(obj); +- } +- return obj; +-} +- +-} +diff --git a/src/libcalamaresui/utils/PluginFactory.h b/src/libcalamaresui/utils/PluginFactory.h +deleted file mode 100644 +index a77d959..0000000 +--- a/src/libcalamaresui/utils/PluginFactory.h ++++ /dev/null +@@ -1,370 +0,0 @@ +-/* === This file is part of Calamares - <http://github.com/calamares> === +- * +- * Copyright 2015, Teo Mrnjavac <teo@kde.org> +- * +- * Based on KPluginFactory from KCoreAddons, KDE project +- * Copyright 2007, Matthias Kretz <kretz@kde.org> +- * Copyright 2007, Bernhard Loos <nhuh.put@web.de> +- * +- * 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 CALAMARESPLUGINFACTORY_H +-#define CALAMARESPLUGINFACTORY_H +- +-#include "UiDllMacro.h" +- +-#include <QtCore/QObject> +-#include <QtCore/QVariant> +-#include <QtCore/QStringList> +- +-namespace Calamares +-{ +-class PluginFactoryPrivate; +-} +- +-#define CalamaresPluginFactory_iid "io.calamares.PluginFactory" +- +-#define CALAMARES_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY_SKEL(name, baseFactory, ...) \ +- class name : public Calamares::PluginFactory \ +- { \ +- Q_OBJECT \ +- Q_INTERFACES(Calamares::PluginFactory) \ +- __VA_ARGS__ \ +- public: \ +- explicit name(); \ +- ~name(); \ +- private: \ +- void init(); \ +- }; +- +-#define CALAMARES_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY(name, baseFactory) \ +- CALAMARES_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY_SKEL(name, baseFactory, Q_PLUGIN_METADATA(IID CalamaresPluginFactory_iid)) +- +-#define CALAMARES_PLUGIN_FACTORY_DEFINITION_WITH_BASEFACTORY(name, baseFactory, pluginRegistrations) \ +- name::name() \ +- { \ +- pluginRegistrations \ +- } \ +- name::~name() {} +- +-#define CALAMARES_PLUGIN_FACTORY_WITH_BASEFACTORY(name, baseFactory, pluginRegistrations) \ +- CALAMARES_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY(name, baseFactory) \ +- CALAMARES_PLUGIN_FACTORY_DEFINITION_WITH_BASEFACTORY(name, baseFactory, pluginRegistrations) +- +-#define CALAMARES_PLUGIN_FACTORY_DECLARATION(name) CALAMARES_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY(name, Calamares::PluginFactory) +-#define CALAMARES_PLUGIN_FACTORY_DEFINITION(name, pluginRegistrations) CALAMARES_PLUGIN_FACTORY_DEFINITION_WITH_BASEFACTORY(name, Calamares::PluginFactory, pluginRegistrations) +- +-/** +- * \relates PluginFactory +- * +- * Create a PluginFactory subclass and export it as the root plugin object. +- * +- * \param name The name of the PluginFactory derived class. +- * +- * \param pluginRegistrations Code to be inserted into the constructor of the +- * class. Usually a series of registerPlugin() calls. +- * +- * Example: +- * \code +- * #include <PluginFactory.h> +- * #include <plugininterface.h> +- * +- * class MyPlugin : public PluginInterface +- * { +- * public: +- * MyPlugin(QObject *parent, const QVariantList &args) +- * : PluginInterface(parent) +- * {} +- * }; +- * +- * CALAMARES_PLUGIN_FACTORY(MyPluginFactory, +- * registerPlugin<MyPlugin>(); +- * ) +- * +- * #include <myplugin.moc> +- * \endcode +- * +- * \see CALAMARES_PLUGIN_FACTORY_DECLARATION +- * \see CALAMARES_PLUGIN_FACTORY_DEFINITION +- */ +-#define CALAMARES_PLUGIN_FACTORY(name, pluginRegistrations) CALAMARES_PLUGIN_FACTORY_WITH_BASEFACTORY(name, Calamares::PluginFactory, pluginRegistrations) +- +-/** +- * \relates PluginFactory +- * +- * CALAMARES_PLUGIN_FACTORY_DECLARATION declares the PluginFactory subclass. This macro +- * can be used in a header file. +- * +- * \param name The name of the PluginFactory derived class. +- * +- * \see CALAMARES_PLUGIN_FACTORY +- * \see CALAMARES_PLUGIN_FACTORY_DEFINITION +- */ +-#define CALAMARES_PLUGIN_FACTORY_DECLARATION(name) CALAMARES_PLUGIN_FACTORY_DECLARATION_WITH_BASEFACTORY(name, Calamares::PluginFactory) +- +-/** +- * \relates PluginFactory +- * CALAMARES_PLUGIN_FACTORY_DEFINITION defines the PluginFactory subclass. This macro +- * can <b>not</b> be used in a header file. +- * +- * \param name The name of the PluginFactory derived class. +- * +- * \param pluginRegistrations Code to be inserted into the constructor of the +- * class. Usually a series of registerPlugin() calls. +- * +- * \see CALAMARES_PLUGIN_FACTORY +- * \see CALAMARES_PLUGIN_FACTORY_DECLARATION +- */ +-#define CALAMARES_PLUGIN_FACTORY_DEFINITION(name, pluginRegistrations) CALAMARES_PLUGIN_FACTORY_DEFINITION_WITH_BASEFACTORY(name, Calamares::PluginFactory, pluginRegistrations) +- +-namespace Calamares +-{ +- +-/** +- * \class PluginFactory PluginFactory.h <PluginFactory.h> +- * +- * PluginFactory provides a convenient way to provide factory-style plugins. +- * Qt plugins provide a singleton object, but a common pattern is for plugins +- * to generate as many objects of a particular type as the application requires. +- * By using PluginFactory, you can avoid implementing the factory pattern +- * yourself. +- * +- * PluginFactory also allows plugins to provide multiple different object +- * types, indexed by keywords. +- * +- * The objects created by PluginFactory must inherit QObject, and must have a +- * standard constructor pattern: +- * \li if the object is a KPart::Part, it must be of the form +- * \code +- * T(QWidget *parentWidget, QObject *parent, const QVariantList &args) +- * \endcode +- * \li if it is a QWidget, it must be of the form +- * \code +- * T(QWidget *parent, const QVariantList &args) +- * \endcode +- * \li otherwise it must be of the form +- * \code +- * T(QObject *parent, const QVariantList &args) +- * \endcode +- * +- * You should typically use either CALAMARES_PLUGIN_FACTORY() or +- * CALAMARES_PLUGIN_FACTORY_WITH_JSON() in your plugin code to create the factory. The +- * typical pattern is +- * +- * \code +- * #include <PluginFactory.h> +- * #include <plugininterface.h> +- * +- * class MyPlugin : public PluginInterface +- * { +- * public: +- * MyPlugin(QObject *parent, const QVariantList &args) +- * : PluginInterface(parent) +- * {} +- * }; +- * +- * CALAMARES_PLUGIN_FACTORY(MyPluginFactory, +- * registerPlugin<MyPlugin>(); +- * ) +- * #include <myplugin.moc> +- * \endcode +- * +- * If you want to load a library use KPluginLoader. +- * The application that wants to instantiate plugin classes can do the following: +- * \code +- * PluginFactory *factory = KPluginLoader("libraryname").factory(); +- * if (factory) { +- * PluginInterface *p1 = factory->create<PluginInterface>(parent); +- * OtherInterface *p2 = factory->create<OtherInterface>(parent); +- * NextInterface *p3 = factory->create<NextInterface>("keyword1", parent); +- * NextInterface *p3 = factory->create<NextInterface>("keyword2", parent); +- * } +- * \endcode +- * +- * \author Matthias Kretz <kretz@kde.org> +- * \author Bernhard Loos <nhuh.put@web.de> +- */ +-class UIDLLEXPORT PluginFactory : public QObject +-{ +- Q_OBJECT +- Q_DECLARE_PRIVATE(PluginFactory) +-public: +- /** +- * This constructor creates a factory for a plugin. +- */ +- explicit PluginFactory(); +- +- /** +- * This destroys the PluginFactory. +- */ +- virtual ~PluginFactory(); +- +- /** +- * Use this method to create an object. It will try to create an object which inherits +- * \p T. If it has multiple choices, you will get a fatal error (kFatal()), so be careful +- * to request a unique interface or use keywords. +- * +- * \tparam T The interface for which an object should be created. The object will inherit \p T. +- * \param parent The parent of the object. If \p parent is a widget type, it will also passed +- * to the parentWidget argument of the CreateInstanceFunction for the object. +- * \returns A pointer to the created object is returned, or 0 if an error occurred. +- */ +- template<typename T> +- T *create(QObject *parent = 0); +- +- /** +- * Use this method to create an object. It will try to create an object which inherits +- * \p T and was registered with \p keyword. +- * +- * \tparam T The interface for which an object should be created. The object will inherit \p T. +- * \param keyword The keyword of the object. +- * \param parent The parent of the object. If \p parent is a widget type, it will also passed +- * to the parentWidget argument of the CreateInstanceFunction for the object. +- * \returns A pointer to the created object is returned, or 0 if an error occurred. +- */ +- template<typename T> +- T *create(const QString &keyword, QObject *parent = 0); +- +-Q_SIGNALS: +- void objectCreated(QObject *object); +- +-protected: +- /** +- * Function pointer type to a function that instantiates a plugin. +- */ +- typedef QObject *(*CreateInstanceFunction)(QWidget *, QObject *); +- +- /** +- * This is used to detect the arguments need for the constructor of plugin classes. +- * You can inherit it, if you want to add new classes and still keep support for the old ones. +- */ +- template<class impl> +- struct InheritanceChecker { +- CreateInstanceFunction createInstanceFunction(QWidget *) +- { +- return &createInstance<impl, QWidget>; +- } +- CreateInstanceFunction createInstanceFunction(...) +- { +- return &createInstance<impl, QObject>; +- } +- }; +- +- explicit PluginFactory(PluginFactoryPrivate &dd); +- +- /** +- * Registers a plugin with the factory. Call this function from the constructor of the +- * PluginFactory subclass to make the create function able to instantiate the plugin when asked +- * for an interface the plugin implements. +- * +- * \tparam T the name of the plugin class +- * +- * \param keyword An optional keyword as unique identifier for the plugin. This allows you to +- * put more than one plugin with the same interface into the same library using the same +- * factory. X-KDE-PluginKeyword is a convenient way to specify the keyword in a desktop file. +- * +- * \param instanceFunction A function pointer to a function that creates an instance of the +- * plugin. The default function that will be used depends on the type of interface. If the +- * interface inherits from +- * \li \c KParts::Part the function will call +- * \code +- * new T(QWidget *parentWidget, QObject *parent) +- * \endcode +- * \li \c QWidget the function will call +- * \code +- * new T(QWidget *parent) +- * \endcode +- * \li else the function will call +- * \code +- * new T(QObject *parent) +- * \endcode +- */ +- template<class T> +- void registerPlugin(const QString &keyword = QString(), +- CreateInstanceFunction instanceFunction +- = InheritanceChecker<T>().createInstanceFunction(reinterpret_cast<T *>(0))) +- { +- doRegisterPlugin(keyword, &T::staticMetaObject, instanceFunction); +- } +- +- PluginFactoryPrivate *const d_ptr; +- +- /** +- * This function is called when the factory asked to create an Object. +- * +- * You may reimplement it to provide a very flexible factory. This is especially useful to +- * provide generic factories for plugins implemeted using a scripting language. +- * +- * \param iface The staticMetaObject::className() string identifying the plugin interface that +- * was requested. E.g. for KCModule plugins this string will be "KCModule". +- * \param parentWidget Only used if the requested plugin is a KPart. +- * \param parent The parent object for the plugin object. +- * \param args A plugin specific list of arbitrary arguments. +- * \param keyword A string that uniquely identifies the plugin. If a KService is used this +- * keyword is read from the X-KDE-PluginKeyword entry in the .desktop file. +- */ +- virtual QObject *create(const char *iface, QWidget *parentWidget, QObject *parent, const QString &keyword); +- +- template<class impl, class ParentType> +- static QObject *createInstance(QWidget *parentWidget, QObject *parent) +- { +- Q_UNUSED(parentWidget); +- ParentType *p = 0; +- if (parent) { +- p = qobject_cast<ParentType *>(parent); +- Q_ASSERT(p); +- } +- return new impl(p); +- } +- +-private: +- void doRegisterPlugin(const QString &keyword, const QMetaObject *metaObject, CreateInstanceFunction instanceFunction); +-}; +- +-template<typename T> +-inline T *PluginFactory::create(QObject *parent) +-{ +- QObject *o = create(T::staticMetaObject.className(), +- parent && parent->isWidgetType() ? reinterpret_cast<QWidget *>(parent) : 0, +- parent, +- QString()); +- +- T *t = qobject_cast<T *>(o); +- if (!t) { +- delete o; +- } +- return t; +-} +- +-template<typename T> +-inline T *PluginFactory::create(const QString &keyword, QObject *parent) +-{ +- QObject *o = create(T::staticMetaObject.className(), +- parent && parent->isWidgetType() ? reinterpret_cast<QWidget *>(parent) : 0, +- parent, +- keyword); +- +- T *t = qobject_cast<T *>(o); +- if (!t) { +- delete o; +- } +- return t; +-} +- +-} +- +-Q_DECLARE_INTERFACE(Calamares::PluginFactory, CalamaresPluginFactory_iid) +- +-#endif // CALAMARESPLUGINFACTORY_H +diff --git a/src/libcalamaresui/utils/PluginFactory_p.h b/src/libcalamaresui/utils/PluginFactory_p.h +deleted file mode 100644 +index a0b4a1c..0000000 +--- a/src/libcalamaresui/utils/PluginFactory_p.h ++++ /dev/null +@@ -1,54 +0,0 @@ +-/* === This file is part of Calamares - <http://github.com/calamares> === +- * +- * Copyright 2015, Teo Mrnjavac <teo@kde.org> +- * +- * Based on KPluginFactory from KCoreAddons, KDE project +- * Copyright 2007, Matthias Kretz <kretz@kde.org> +- * Copyright 2007, Bernhard Loos <nhuh.put@web.de> +- * +- * 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 CALAMARESPLUGINFACTORY_P_H +-#define CALAMARESPLUGINFACTORY_P_H +- +-#include "PluginFactory.h" +- +-#include <QtCore/QHash> +- +-namespace Calamares +-{ +- +-class PluginFactoryPrivate +-{ +- Q_DECLARE_PUBLIC(PluginFactory) +-protected: +- typedef QPair<const QMetaObject *, PluginFactory::CreateInstanceFunction> Plugin; +- +- PluginFactoryPrivate() +- : catalogInitialized( false ) +- , q_ptr( nullptr ) +- {} +- ~PluginFactoryPrivate() {} +- +- QHash<QString, Plugin> createInstanceHash; +- QString catalogName; +- bool catalogInitialized; +- +- PluginFactory *q_ptr; +-}; +- +-} +- +-#endif // CALAMARESPLUGINFACTORY_P_H +diff --git a/src/modules/dracutlukscfg/CMakeLists.txt b/src/modules/dracutlukscfg/CMakeLists.txt +new file mode 100644 +index 0000000..a239521 +--- /dev/null ++++ b/src/modules/dracutlukscfg/CMakeLists.txt +@@ -0,0 +1,9 @@ ++calamares_add_plugin( dracutlukscfg ++ TYPE job ++ EXPORT_MACRO PLUGINDLLEXPORT_PRO ++ SOURCES ++ DracutLuksCfgJob.cpp ++ LINK_LIBRARIES ++ calamares ++ SHARED_LIB ++) +diff --git a/src/modules/dracutlukscfg/DracutLuksCfgJob.cpp b/src/modules/dracutlukscfg/DracutLuksCfgJob.cpp +new file mode 100644 +index 0000000..273ff98 +--- /dev/null ++++ b/src/modules/dracutlukscfg/DracutLuksCfgJob.cpp +@@ -0,0 +1,143 @@ ++/* === This file is part of Calamares - <http://github.com/calamares> === ++ * ++ * Copyright 2016, Kevin Kofler <kevin.kofler@chello.at> ++ * ++ * 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 "DracutLuksCfgJob.h" ++ ++#include <QDir> ++#include <QFile> ++#include <QFileInfo> ++#include <QTextStream> ++ ++#include "CalamaresVersion.h" ++#include "JobQueue.h" ++#include "GlobalStorage.h" ++ ++#include "utils/Logger.h" ++ ++// static ++const QString DracutLuksCfgJob::CONFIG_FILE = QStringLiteral( "/etc/dracut.conf.d/calamares-luks.conf" ); ++ ++// static ++const char *DracutLuksCfgJob::CONFIG_FILE_CONTENTS = ++ "# 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" ++ "# Enables support for LUKS full disk encryption with single sign on from GRUB.\n" ++ "\n" ++ "# force installing /etc/crypttab even if hostonly=\"no\", install the keyfile\n" ++ "install_items+=\" /etc/crypttab /crypto_keyfile.bin \"\n"; ++ ++// static ++const QString DracutLuksCfgJob::CONFIG_FILE_SWAPLINE = QStringLiteral( "# enable automatic resume from swap\nadd_device+=\" /dev/disk/by-uuid/%1 \"\n" ); ++ ++// static ++QString ++DracutLuksCfgJob::rootMountPoint() ++{ ++ Calamares::GlobalStorage *globalStorage = Calamares::JobQueue::instance()->globalStorage(); ++ return globalStorage->value( QStringLiteral( "rootMountPoint" ) ).toString(); ++} ++ ++// static ++QVariantList ++DracutLuksCfgJob::partitions() ++{ ++ Calamares::GlobalStorage *globalStorage = Calamares::JobQueue::instance()->globalStorage(); ++ return globalStorage->value( QStringLiteral( "partitions" ) ).toList(); ++} ++ ++// static ++bool ++DracutLuksCfgJob::isRootEncrypted() ++{ ++ const QVariantList partitions = DracutLuksCfgJob::partitions(); ++ for ( const QVariant &partition : partitions ) ++ { ++ QVariantMap partitionMap = partition.toMap(); ++ QString mountPoint = partitionMap.value( QStringLiteral( "mountPoint" ) ).toString(); ++ if ( mountPoint == QStringLiteral( "/" ) ) ++ return partitionMap.contains( QStringLiteral( "luksMapperName" ) ); ++ } ++ return false; ++} ++ ++// static ++QString ++DracutLuksCfgJob::swapOuterUuid() ++{ ++ const QVariantList partitions = DracutLuksCfgJob::partitions(); ++ for ( const QVariant &partition : partitions ) ++ { ++ QVariantMap partitionMap = partition.toMap(); ++ QString fsType = partitionMap.value( QStringLiteral( "fs" ) ).toString(); ++ if ( fsType == QStringLiteral( "linuxswap" ) && partitionMap.contains( QStringLiteral( "luksMapperName" ) ) ) ++ return partitionMap.value( QStringLiteral( "luksUuid" ) ).toString(); ++ } ++ return QString(); ++} ++ ++DracutLuksCfgJob::DracutLuksCfgJob( QObject* parent ) ++ : Calamares::CppJob( parent ) ++{ ++} ++ ++ ++DracutLuksCfgJob::~DracutLuksCfgJob() ++{ ++} ++ ++ ++QString ++DracutLuksCfgJob::prettyName() const ++{ ++ if ( isRootEncrypted() ) ++ return tr( "Write LUKS configuration for Dracut to %1" ).arg( CONFIG_FILE ); ++ else ++ return tr( "Skip writing LUKS configuration for Dracut: \"/\" partition is not encrypted" ); ++} ++ ++ ++Calamares::JobResult ++DracutLuksCfgJob::exec() ++{ ++ if ( isRootEncrypted() ) ++ { ++ const QString realConfigFilePath = rootMountPoint() + CONFIG_FILE; ++ cDebug() << "[DRACUTLUKSCFG]: Writing" << realConfigFilePath; ++ QDir( QStringLiteral( "/" ) ).mkpath( QFileInfo( realConfigFilePath ).absolutePath() ); ++ QFile configFile( realConfigFilePath ); ++ if ( ! configFile.open( QIODevice::WriteOnly | QIODevice::Text ) ) ++ { ++ cDebug() << "[DRACUTLUKSCFG]: Failed to open" << realConfigFilePath; ++ return Calamares::JobResult::error( tr( "Failed to open %1" ).arg( realConfigFilePath ) ); ++ } ++ QTextStream outStream( &configFile ); ++ outStream << CONFIG_FILE_CONTENTS; ++ const QString swapOuterUuid = DracutLuksCfgJob::swapOuterUuid(); ++ if ( ! swapOuterUuid.isEmpty() ) ++ { ++ cDebug() << "[DRACUTLUKSCFG]: Swap outer UUID" << swapOuterUuid; ++ outStream << CONFIG_FILE_SWAPLINE.arg( swapOuterUuid ).toLatin1(); ++ } ++ cDebug() << "[DRACUTLUKSCFG]: Wrote config to" << realConfigFilePath; ++ } else ++ cDebug() << "[DRACUTLUKSCFG]: / not encrypted, skipping"; ++ ++ return Calamares::JobResult::ok(); ++} ++ ++CALAMARES_PLUGIN_FACTORY_DEFINITION( DracutLuksCfgJobFactory, registerPlugin<DracutLuksCfgJob>(); ) +diff --git a/src/modules/dracutlukscfg/DracutLuksCfgJob.h b/src/modules/dracutlukscfg/DracutLuksCfgJob.h +new file mode 100644 +index 0000000..bfedb85 +--- /dev/null ++++ b/src/modules/dracutlukscfg/DracutLuksCfgJob.h +@@ -0,0 +1,56 @@ ++/* === This file is part of Calamares - <http://github.com/calamares> === ++ * ++ * Copyright 2016, Kevin Kofler <kevin.kofler@chello.at> ++ * ++ * 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 DRACUTLUKSCFGJOB_H ++#define DRACUTLUKSCFGJOB_H ++ ++#include <QObject> ++#include <QVariantMap> ++ ++#include <CppJob.h> ++ ++#include <utils/PluginFactory.h> ++ ++#include <PluginDllMacro.h> ++ ++class PLUGINDLLEXPORT DracutLuksCfgJob : public Calamares::CppJob ++{ ++ Q_OBJECT ++ ++public: ++ explicit DracutLuksCfgJob( QObject* parent = nullptr ); ++ virtual ~DracutLuksCfgJob(); ++ ++ QString prettyName() const override; ++ ++ Calamares::JobResult exec() override; ++ ++private: ++ static const QString CONFIG_FILE; ++ static const char *CONFIG_FILE_CONTENTS; ++ static const QString CONFIG_FILE_SWAPLINE; ++ ++ static QString rootMountPoint(); ++ static QVariantList partitions(); ++ static bool isRootEncrypted(); ++ static QString swapOuterUuid(); ++}; ++ ++CALAMARES_PLUGIN_FACTORY_DECLARATION( DracutLuksCfgJobFactory ) ++ ++#endif // DRACUTLUKSCFGJOB_H +diff --git a/src/modules/dracutlukscfg/module.desc b/src/modules/dracutlukscfg/module.desc +new file mode 100644 +index 0000000..10d9b78 +--- /dev/null ++++ b/src/modules/dracutlukscfg/module.desc +@@ -0,0 +1,7 @@ ++# Module metadata file for dracutlukscfg job ++# Syntax is YAML 1.2 ++--- ++type: "job" ++name: "dracutlukscfg" ++interface: "qtplugin" ++load: "libcalamares_job_dracutlukscfg.so" +diff --git a/src/modules/fstab/fstab.conf b/src/modules/fstab/fstab.conf +index 7dbf529..c3dbfc3 100644 +--- a/src/modules/fstab/fstab.conf ++++ b/src/modules/fstab/fstab.conf +@@ -8,3 +8,6 @@ ssdExtraMountOptions: + xfs: discard + swap: discard + btrfs: discard,compress=lzo ++crypttabOptions: luks ++# For Debian and Debian-based distributions, change the above line to: ++# crypttabOptions: luks,keyscript=/bin/cat +diff --git a/src/modules/fstab/main.py b/src/modules/fstab/main.py +index 65f483b..05b094f 100644 +--- a/src/modules/fstab/main.py ++++ b/src/modules/fstab/main.py +@@ -102,11 +102,13 @@ class FstabGenerator(object): + :param mount_options: + :param ssd_extra_mount_options: + """ +- def __init__(self, partitions, root_mount_point, mount_options, ssd_extra_mount_options): ++ def __init__(self, partitions, root_mount_point, mount_options, ++ ssd_extra_mount_options, crypttab_options): + self.partitions = partitions + self.root_mount_point = root_mount_point + self.mount_options = mount_options + self.ssd_extra_mount_options = ssd_extra_mount_options ++ self.crypttab_options = crypttab_options + self.ssd_disks = set() + self.root_is_ssd = False + +@@ -152,21 +154,20 @@ class FstabGenerator(object): + if not mapper_name or not luks_uuid: + return None + +- if mount_point == "/": +- return None +- + return dict( + name=mapper_name, + device="UUID=" + luks_uuid, + password="/crypto_keyfile.bin", ++ options=self.crypttab_options, + ) + + def print_crypttab_line(self, dct, file=None): + """ Prints line to '/etc/crypttab' file. """ +- line = "{:21} {:<45} {}".format(dct["name"], +- dct["device"], +- dct["password"], +- ) ++ line = "{:21} {:<45} {} {}".format(dct["name"], ++ dct["device"], ++ dct["password"], ++ dct["options"], ++ ) + + print(line, file=file) + +@@ -258,9 +259,11 @@ def run(): + root_mount_point = global_storage.value("rootMountPoint") + mount_options = conf["mountOptions"] + ssd_extra_mount_options = conf.get("ssdExtraMountOptions", {}) ++ crypttab_options = conf.get("crypttabOptions", "luks") + generator = FstabGenerator(partitions, + root_mount_point, + mount_options, +- ssd_extra_mount_options) ++ ssd_extra_mount_options, ++ crypttab_options) + + return generator.run() +-- +2.1.0 + |