diff --git a/.gitignore b/.gitignore index 26e8ff869..d67fee190 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,6 @@ CMakeLists.txt.user # Backup files *~ + +# Kate +*.kate-swp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c6105e38..aa0d9016b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -166,8 +166,8 @@ set( CALAMARES_TRANSLATION_LANGUAGES ar ast bg ca cs_CZ da de el en en_GB es_MX ### Bump version here set( CALAMARES_VERSION_MAJOR 3 ) set( CALAMARES_VERSION_MINOR 1 ) -set( CALAMARES_VERSION_PATCH 7 ) -set( CALAMARES_VERSION_RC 0 ) +set( CALAMARES_VERSION_PATCH 8 ) +set( CALAMARES_VERSION_RC 1 ) set( CALAMARES_VERSION ${CALAMARES_VERSION_MAJOR}.${CALAMARES_VERSION_MINOR}.${CALAMARES_VERSION_PATCH} ) set( CALAMARES_VERSION_SHORT "${CALAMARES_VERSION}" ) @@ -267,9 +267,9 @@ else() endif() # Doesn't list mksquashfs as an optional dep, though, because it # hasn't been sent through the find_package() scheme. -add_feature_info( mksquashfs mksquashfs_FOUND - "Create squashed filesystems for the example distro" -) +# +# "http://tldp.org/HOWTO/SquashFS-HOWTO/creatingandusing.html" +add_feature_info( ExampleDistro ${mksquashfs_FOUND} "Create example-distro target.") # add_subdirectory( thirdparty ) add_subdirectory( src ) diff --git a/CMakeModules/FindPythonQt.cmake b/CMakeModules/FindPythonQt.cmake index d016b57b1..0d886902d 100644 --- a/CMakeModules/FindPythonQt.cmake +++ b/CMakeModules/FindPythonQt.cmake @@ -9,6 +9,13 @@ if(NOT PYTHONLIBS_FOUND) message(FATAL_ERROR "error: Python is required to build PythonQt") endif() +string(REGEX REPLACE + "^([0-9][0-9]*)\.([0-9][0-9]*)" + "\\1" + PYTHONLIBS_MAJMIN + ${PYTHONLIBS_VERSION_STRING} +) + if(NOT EXISTS "${PYTHONQT_INSTALL_DIR}") find_path(PYTHONQT_INSTALL_DIR include/PythonQt/PythonQt.h DOC "Directory where PythonQt was installed.") endif() @@ -22,17 +29,58 @@ find_path(PYTHONQT_INCLUDE_DIR PythonQt.h "${PYTHONQT_INSTALL_DIR}/src" DOC "Path to the PythonQt include directory") -# Minimum v3.1 is needed -find_library(PYTHONQT_LIBRARY_RELEASE PythonQt PATHS "${PYTHONQT_INSTALL_DIR}/lib" DOC "The PythonQt library.") -find_library(PYTHONQT_LIBRARY_DEBUG NAMES PythonQt${CTK_CMAKE_DEBUG_POSTFIX} PythonQt${CMAKE_DEBUG_POSTFIX} PythonQt PATHS "${PYTHONQT_INSTALL_DIR}/lib" DOC "The PythonQt library.") -find_library(PYTHONQT_QTALL_LIBRARY_RELEASE PythonQt_QtAll PATHS "${PYTHONQT_INSTALL_DIR}/lib" DOC "Full Qt bindings for the PythonQt library.") -find_library(PYTHONQT_QTALL_LIBRARY_DEBUG NAMES PythonQt_QtAll${CTK_CMAKE_DEBUG_POSTFIX} PythonQt_QtAll${CMAKE_DEBUG_POSTFIX} PythonQt_QtAll PATHS "${PYTHONQT_INSTALL_DIR}/lib" DOC "Full Qt bindings for the PythonQt library.") +if ( NOT PythonQt_FIND_QUIETLY ) + message( STATUS "Searching for PythonQt (Python ${PYTHONLIBS_MAJMIN}) .." ) + if ( PYTHONQT_INCLUDE_DIR ) + message( STATUS " .. found include ${PYTHONQT_INCLUDE_DIR}" ) + endif() +endif() -# Also check for v3.2+ -find_library(PYTHONQT_LIBRARY_RELEASE PythonQt-Qt5-Python3 PATHS "${PYTHONQT_INSTALL_DIR}/lib" DOC "The PythonQt library.") -find_library(PYTHONQT_LIBRARY_DEBUG NAMES PythonQt-Qt5-Python3${CTK_CMAKE_DEBUG_POSTFIX} PythonQt-Qt5-Python3${CMAKE_DEBUG_POSTFIX} PythonQt-Qt5-Python3 PATHS "${PYTHONQT_INSTALL_DIR}/lib" DOC "The PythonQt library.") -find_library(PYTHONQT_QTALL_LIBRARY_RELEASE PythonQt_QtAll-Qt5-Python3 PATHS "${PYTHONQT_INSTALL_DIR}/lib" DOC "Full Qt bindings for the PythonQt library.") -find_library(PYTHONQT_QTALL_LIBRARY_DEBUG NAMES PythonQt_QtAll-Qt5-Python3${CTK_CMAKE_DEBUG_POSTFIX} PythonQt_QtAll-Qt5-Python3${CMAKE_DEBUG_POSTFIX} PythonQt_QtAll-Qt5-Python3 PATHS "${PYTHONQT_INSTALL_DIR}/lib" DOC "Full Qt bindings for the PythonQt library.") +# Minimum v3.1 is needed +find_library(PYTHONQT_LIBRARY_RELEASE + NAMES + PythonQt-Qt5-Python${PYTHONLIBS_MAJMIN} + PythonQt-Qt5-Python3 + PythonQt + PATHS "${PYTHONQT_INSTALL_DIR}/lib" + DOC "The PythonQt library." +) +find_library(PYTHONQT_LIBRARY_DEBUG + NAMES + PythonQt-Qt5-Python${PYTHONLIBS_MAJMIN}JMIN${CTK_CMAKE_DEBUG_POSTFIX} + PythonQt-Qt5-Python${PYTHONLIBS_MAJMIN}${CMAKE_DEBUG_POSTFIX} + PythonQt-Qt5-Python${PYTHONLIBS_MAJMIN} + PythonQt-Qt5-Python3${CTK_CMAKE_DEBUG_POSTFIX} + PythonQt-Qt5-Python3${CMAKE_DEBUG_POSTFIX} + PythonQt-Qt5-Python3 + PythonQt${CTK_CMAKE_DEBUG_POSTFIX} + PythonQt${CMAKE_DEBUG_POSTFIX} + PythonQt + PATHS "${PYTHONQT_INSTALL_DIR}/lib" + DOC "The PythonQt library (debug build)." +) +find_library(PYTHONQT_QTALL_LIBRARY_RELEASE + NAMES + PythonQt_QtAll-Qt5-Python${PYTHONLIBS_MAJMIN} + PythonQt_QtAll-Qt5-Python3 + PythonQt_QtAll + PATHS "${PYTHONQT_INSTALL_DIR}/lib" + DOC "Full Qt bindings for the PythonQt library." +) +find_library(PYTHONQT_QTALL_LIBRARY_DEBUG + NAMES + PythonQt_QtAll-Qt5-Python${PYTHONLIBS_MAJMIN}${CTK_CMAKE_DEBUG_POSTFIX} + PythonQt_QtAll-Qt5-Python${PYTHONLIBS_MAJMIN}${CMAKE_DEBUG_POSTFIX} + PythonQt_QtAll-Qt5-Python${PYTHONLIBS_MAJMIN} + PythonQt_QtAll-Qt5-Python3${CTK_CMAKE_DEBUG_POSTFIX} + PythonQt_QtAll-Qt5-Python3${CMAKE_DEBUG_POSTFIX} + PythonQt_QtAll-Qt5-Python3 + PythonQt_QtAll${CTK_CMAKE_DEBUG_POSTFIX} + PythonQt_QtAll${CMAKE_DEBUG_POSTFIX} + PythonQt_QtAll + PATHS "${PYTHONQT_INSTALL_DIR}/lib" + DOC "Full Qt bindings for the PythonQt library (debug build)." +) set(PYTHONQT_LIBRARY) if(PYTHONQT_LIBRARY_RELEASE) @@ -50,6 +98,12 @@ if(PYTHONQT_QTALL_LIBRARY_DEBUG) list(APPEND PYTHONQT_QTALL_LIBRARY debug ${PYTHONQT_QTALL_LIBRARY_DEBUG}) endif() +if ( NOT PythonQt_FIND_QUIETLY ) + message( STATUS " .. found library ${PYTHONQT_LIBRARY}" ) + message( STATUS " .. found qtall ${PYTHONQT_QTALL_LIBRARY}" ) +endif() + + mark_as_advanced(PYTHONQT_INSTALL_DIR) mark_as_advanced(PYTHONQT_INCLUDE_DIR) mark_as_advanced(PYTHONQT_LIBRARY_RELEASE) diff --git a/src/libcalamares/JobQueue.cpp b/src/libcalamares/JobQueue.cpp index a1badcf86..86e33a0cd 100644 --- a/src/libcalamares/JobQueue.cpp +++ b/src/libcalamares/JobQueue.cpp @@ -46,7 +46,7 @@ public: #endif } - void setJobs( const QList< job_ptr >& jobs ) + void setJobs( const JobList& jobs ) { m_jobs = jobs; } @@ -73,7 +73,7 @@ public: } private: - QList< job_ptr > m_jobs; + JobList m_jobs; JobQueue* m_queue; int m_jobIndex; @@ -164,7 +164,7 @@ JobQueue::enqueue( const job_ptr& job ) void -JobQueue::enqueue( const QList< job_ptr >& jobs ) +JobQueue::enqueue( const JobList& jobs ) { Q_ASSERT( !m_thread->isRunning() ); m_jobs.append( jobs ); diff --git a/src/libcalamares/JobQueue.h b/src/libcalamares/JobQueue.h index 903783d53..2c1b85ed5 100644 --- a/src/libcalamares/JobQueue.h +++ b/src/libcalamares/JobQueue.h @@ -42,11 +42,11 @@ public: GlobalStorage* globalStorage() const; void enqueue( const job_ptr& job ); - void enqueue( const QList< job_ptr >& jobs ); + void enqueue( const JobList& jobs ); void start(); signals: - void queueChanged( const QList< job_ptr >& jobs ); + void queueChanged( const JobList& jobs ); void progress( qreal percent, const QString& prettyName ); void finished(); void failed( const QString& message, const QString& details ); @@ -54,7 +54,7 @@ signals: private: static JobQueue* s_instance; - QList< job_ptr > m_jobs; + JobList m_jobs; JobThread* m_thread; GlobalStorage* m_storage; }; diff --git a/src/libcalamares/Typedefs.h b/src/libcalamares/Typedefs.h index 8aefcd6af..4ff28e3d7 100644 --- a/src/libcalamares/Typedefs.h +++ b/src/libcalamares/Typedefs.h @@ -19,6 +19,7 @@ #ifndef TYPEDEFS_H #define TYPEDEFS_H +#include #include namespace Calamares @@ -26,6 +27,7 @@ namespace Calamares class Job; typedef QSharedPointer< Job > job_ptr; +using JobList = QList< job_ptr >; enum ModuleAction : char { diff --git a/src/libcalamares/utils/CalamaresUtils.cpp b/src/libcalamares/utils/CalamaresUtils.cpp index db748ec94..ae3a14497 100644 --- a/src/libcalamares/utils/CalamaresUtils.cpp +++ b/src/libcalamares/utils/CalamaresUtils.cpp @@ -326,5 +326,35 @@ crash() *a = 1; } +bool +getBool( const QVariantMap& map, const QString& key, bool d ) +{ + bool result = d; + if ( map.contains( key ) ) + { + auto v = map.value( key ); + if ( v.type() == QVariant::Bool ) + result = v.toBool(); + } + + return result; +} + +QVariantMap +getSubMap( const QVariantMap& map, const QString& key, bool& success ) +{ + success = false; + + if ( map.contains( key ) ) + { + auto v = map.value( key ); + if ( v.type() == QVariant::Map ) + { + success = true; + return v.toMap(); + } + } + return QVariantMap(); +} } diff --git a/src/libcalamares/utils/CalamaresUtils.h b/src/libcalamares/utils/CalamaresUtils.h index 66650ff57..651c6746a 100644 --- a/src/libcalamares/utils/CalamaresUtils.h +++ b/src/libcalamares/utils/CalamaresUtils.h @@ -97,6 +97,22 @@ namespace CalamaresUtils * @brief crash makes Calamares crash immediately. */ DLLEXPORT void crash(); + + /** + * Get a bool value from a mapping with a given key; returns the default + * if no value is stored in the map. + */ + DLLEXPORT bool getBool( const QVariantMap& map, const QString& key, bool d ); + + /** + * Returns a sub-map (i.e. a nested map) from the given mapping with the + * given key. @p success is set to true if the @p key exists + * in @p map and converts to a map, false otherwise. + * + * Returns an empty map if there is no such key or it is not a map-value. + * (e.g. if @p success is false). + */ + DLLEXPORT QVariantMap getSubMap( const QVariantMap& map, const QString& key, bool& success ); } #endif // CALAMARESUTILS_H diff --git a/src/libcalamaresui/ExecutionViewStep.cpp b/src/libcalamaresui/ExecutionViewStep.cpp index 37c2318d0..4c813bbca 100644 --- a/src/libcalamaresui/ExecutionViewStep.cpp +++ b/src/libcalamaresui/ExecutionViewStep.cpp @@ -148,10 +148,10 @@ ExecutionViewStep::onActivate() } -QList< Calamares::job_ptr > +JobList ExecutionViewStep::jobs() const { - return QList< Calamares::job_ptr >(); + return JobList(); } diff --git a/src/libcalamaresui/ExecutionViewStep.h b/src/libcalamaresui/ExecutionViewStep.h index 3101cf479..05b26a436 100644 --- a/src/libcalamaresui/ExecutionViewStep.h +++ b/src/libcalamaresui/ExecutionViewStep.h @@ -52,7 +52,7 @@ public: void onActivate() override; - QList< job_ptr > jobs() const override; + JobList jobs() const override; void appendJobModuleInstanceKey( const QString& instanceKey ); diff --git a/src/libcalamaresui/modulesystem/CppJobModule.cpp b/src/libcalamaresui/modulesystem/CppJobModule.cpp index 6ff846027..e6240b4c9 100644 --- a/src/libcalamaresui/modulesystem/CppJobModule.cpp +++ b/src/libcalamaresui/modulesystem/CppJobModule.cpp @@ -75,10 +75,10 @@ CppJobModule::loadSelf() } -QList< job_ptr > +JobList CppJobModule::jobs() const { - return QList< job_ptr >() << m_job; + return JobList() << m_job; } diff --git a/src/libcalamaresui/modulesystem/CppJobModule.h b/src/libcalamaresui/modulesystem/CppJobModule.h index 46d27bf8b..89cf19e06 100644 --- a/src/libcalamaresui/modulesystem/CppJobModule.h +++ b/src/libcalamaresui/modulesystem/CppJobModule.h @@ -36,7 +36,7 @@ public: Interface interface() const override; void loadSelf() override; - QList< job_ptr > jobs() const override; + JobList jobs() const override; protected: void initFrom( const QVariantMap& moduleDescriptor ) override; diff --git a/src/libcalamaresui/modulesystem/Module.h b/src/libcalamaresui/modulesystem/Module.h index 5f756938f..71390fa83 100644 --- a/src/libcalamaresui/modulesystem/Module.h +++ b/src/libcalamaresui/modulesystem/Module.h @@ -70,7 +70,6 @@ public: ProcessInterface, PythonQtInterface }; - virtual ~Module(); /** * @brief fromDescriptor creates a new Module object of the correct type. @@ -84,6 +83,7 @@ public: const QString& instanceId, const QString& configFileName, const QString& moduleDirectory ); + virtual ~Module(); /** * @brief name returns the name of this module. @@ -159,7 +159,7 @@ public: * @brief jobs returns any jobs exposed by this module. * @return a list of jobs (can be empty). */ - virtual QList< job_ptr > jobs() const = 0; + virtual JobList jobs() const = 0; /** * @brief configurationMap returns the contents of the configuration file for diff --git a/src/libcalamaresui/modulesystem/ProcessJobModule.cpp b/src/libcalamaresui/modulesystem/ProcessJobModule.cpp index aefcbf6f0..989385a18 100644 --- a/src/libcalamaresui/modulesystem/ProcessJobModule.cpp +++ b/src/libcalamaresui/modulesystem/ProcessJobModule.cpp @@ -53,10 +53,10 @@ ProcessJobModule::loadSelf() } -QList< job_ptr > +JobList ProcessJobModule::jobs() const { - return QList< job_ptr >() << m_job; + return JobList() << m_job; } diff --git a/src/libcalamaresui/modulesystem/ProcessJobModule.h b/src/libcalamaresui/modulesystem/ProcessJobModule.h index af9a46bd5..d2c8ba905 100644 --- a/src/libcalamaresui/modulesystem/ProcessJobModule.h +++ b/src/libcalamaresui/modulesystem/ProcessJobModule.h @@ -34,7 +34,7 @@ public: Interface interface() const override; void loadSelf() override; - QList< job_ptr > jobs() const override; + JobList jobs() const override; protected: void initFrom( const QVariantMap& moduleDescriptor ) override; diff --git a/src/libcalamaresui/modulesystem/PythonJobModule.cpp b/src/libcalamaresui/modulesystem/PythonJobModule.cpp index 544f27e1f..3c0a8234e 100644 --- a/src/libcalamaresui/modulesystem/PythonJobModule.cpp +++ b/src/libcalamaresui/modulesystem/PythonJobModule.cpp @@ -53,10 +53,10 @@ PythonJobModule::loadSelf() } -QList< job_ptr > +JobList PythonJobModule::jobs() const { - return QList< job_ptr >() << m_job; + return JobList() << m_job; } diff --git a/src/libcalamaresui/modulesystem/PythonJobModule.h b/src/libcalamaresui/modulesystem/PythonJobModule.h index c82137cb8..b5ae34c07 100644 --- a/src/libcalamaresui/modulesystem/PythonJobModule.h +++ b/src/libcalamaresui/modulesystem/PythonJobModule.h @@ -32,7 +32,7 @@ public: Interface interface() const override; void loadSelf() override; - QList< job_ptr > jobs() const override; + JobList jobs() const override; protected: void initFrom( const QVariantMap& moduleDescriptor ) override; diff --git a/src/libcalamaresui/modulesystem/PythonQtViewModule.cpp b/src/libcalamaresui/modulesystem/PythonQtViewModule.cpp index 96a1ce71c..f4fae4398 100644 --- a/src/libcalamaresui/modulesystem/PythonQtViewModule.cpp +++ b/src/libcalamaresui/modulesystem/PythonQtViewModule.cpp @@ -171,7 +171,7 @@ PythonQtViewModule::loadSelf() } -QList< job_ptr > +JobList PythonQtViewModule::jobs() const { return m_viewStep->jobs(); diff --git a/src/libcalamaresui/modulesystem/PythonQtViewModule.h b/src/libcalamaresui/modulesystem/PythonQtViewModule.h index ba18cfac6..06de7c6e9 100644 --- a/src/libcalamaresui/modulesystem/PythonQtViewModule.h +++ b/src/libcalamaresui/modulesystem/PythonQtViewModule.h @@ -33,7 +33,7 @@ public: Interface interface() const override; void loadSelf() override; - QList< job_ptr > jobs() const override; + JobList jobs() const override; protected: void initFrom( const QVariantMap& moduleDescriptor ) override; diff --git a/src/libcalamaresui/modulesystem/ViewModule.cpp b/src/libcalamaresui/modulesystem/ViewModule.cpp index ba054a8b1..419cad611 100644 --- a/src/libcalamaresui/modulesystem/ViewModule.cpp +++ b/src/libcalamaresui/modulesystem/ViewModule.cpp @@ -76,7 +76,7 @@ ViewModule::loadSelf() } -QList< job_ptr > +JobList ViewModule::jobs() const { return m_viewStep->jobs(); diff --git a/src/libcalamaresui/modulesystem/ViewModule.h b/src/libcalamaresui/modulesystem/ViewModule.h index 6b2e381a2..323315947 100644 --- a/src/libcalamaresui/modulesystem/ViewModule.h +++ b/src/libcalamaresui/modulesystem/ViewModule.h @@ -37,7 +37,7 @@ public: Interface interface() const override; void loadSelf() override; - QList< job_ptr > jobs() const override; + JobList jobs() const override; protected: void initFrom( const QVariantMap& moduleDescriptor ) override; diff --git a/src/libcalamaresui/utils/DebugWindow.cpp b/src/libcalamaresui/utils/DebugWindow.cpp index d4bc74f65..e00c2097b 100644 --- a/src/libcalamaresui/utils/DebugWindow.cpp +++ b/src/libcalamaresui/utils/DebugWindow.cpp @@ -62,7 +62,7 @@ DebugWindow::DebugWindow() // JobQueue page jobQueueText->setReadOnly( true ); connect( JobQueue::instance(), &JobQueue::queueChanged, - this, [ this ]( const QList< Calamares::job_ptr >& jobs ) + this, [ this ]( const JobList& jobs ) { QStringList text; for ( const auto &job : jobs ) diff --git a/src/libcalamaresui/utils/qjsonitem.cpp b/src/libcalamaresui/utils/qjsonitem.cpp index 24494f0fd..cdc4b3b13 100644 --- a/src/libcalamaresui/utils/qjsonitem.cpp +++ b/src/libcalamaresui/utils/qjsonitem.cpp @@ -26,11 +26,9 @@ #include "qjsonitem.h" QJsonTreeItem::QJsonTreeItem(QJsonTreeItem *parent) + : mParent( parent ) + , mType( QJsonValue::Type::Null ) { - - mParent = parent; - - } QJsonTreeItem::~QJsonTreeItem() diff --git a/src/libcalamaresui/utils/qjsonmodel.cpp b/src/libcalamaresui/utils/qjsonmodel.cpp index 5ce0cd695..4238bfd6b 100644 --- a/src/libcalamaresui/utils/qjsonmodel.cpp +++ b/src/libcalamaresui/utils/qjsonmodel.cpp @@ -33,14 +33,19 @@ QJsonModel::QJsonModel(QObject *parent) : QAbstractItemModel(parent) + , mRootItem( new QJsonTreeItem ) { - mRootItem = new QJsonTreeItem; mHeaders.append("key"); mHeaders.append("value"); } +QJsonModel::~QJsonModel() +{ + delete mRootItem; +} + bool QJsonModel::load(const QString &fileName) { QFile file(fileName); @@ -66,6 +71,7 @@ bool QJsonModel::loadJson(const QByteArray &json) if (!mDocument.isNull()) { beginResetModel(); + delete mRootItem; if (mDocument.isArray()) { mRootItem = QJsonTreeItem::load(QJsonValue(mDocument.array())); } else { diff --git a/src/libcalamaresui/utils/qjsonmodel.h b/src/libcalamaresui/utils/qjsonmodel.h index 6a2399287..0d1b3232d 100644 --- a/src/libcalamaresui/utils/qjsonmodel.h +++ b/src/libcalamaresui/utils/qjsonmodel.h @@ -17,6 +17,7 @@ class QJsonModel : public QAbstractItemModel Q_OBJECT public: explicit QJsonModel(QObject *parent = 0); + ~QJsonModel(); bool load(const QString& fileName); bool load(QIODevice * device); bool loadJson(const QByteArray& json); diff --git a/src/libcalamaresui/viewpages/PythonQtViewStep.cpp b/src/libcalamaresui/viewpages/PythonQtViewStep.cpp index 78881e337..f5f84eadd 100644 --- a/src/libcalamaresui/viewpages/PythonQtViewStep.cpp +++ b/src/libcalamaresui/viewpages/PythonQtViewStep.cpp @@ -159,10 +159,10 @@ PythonQtViewStep::isAtEnd() const } -QList< Calamares::job_ptr > +JobList PythonQtViewStep::jobs() const { - QList< Calamares::job_ptr > jobs; + JobList jobs; PythonQtObjectPtr jobsCallable = PythonQt::self()->lookupCallable( m_obj, "jobs" ); if ( jobsCallable.isNull() ) diff --git a/src/libcalamaresui/viewpages/PythonQtViewStep.h b/src/libcalamaresui/viewpages/PythonQtViewStep.h index e1f8bd1e5..594af2817 100644 --- a/src/libcalamaresui/viewpages/PythonQtViewStep.h +++ b/src/libcalamaresui/viewpages/PythonQtViewStep.h @@ -46,7 +46,7 @@ public: bool isAtBeginning() const override; bool isAtEnd() const override; - QList< Calamares::job_ptr > jobs() const override; + JobList jobs() const override; void setConfigurationMap( const QVariantMap& configurationMap ) override; diff --git a/src/libcalamaresui/viewpages/ViewStep.h b/src/libcalamaresui/viewpages/ViewStep.h index 617d64fe1..f69f872e2 100644 --- a/src/libcalamaresui/viewpages/ViewStep.h +++ b/src/libcalamaresui/viewpages/ViewStep.h @@ -91,7 +91,7 @@ public: */ virtual void onLeave(); - virtual QList< job_ptr > jobs() const = 0; + virtual JobList jobs() const = 0; void setModuleInstanceKey( const QString& instanceKey ); QString moduleInstanceKey() const diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index d48ecd29f..680a9c12c 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -3,6 +3,7 @@ include( CMakeColors ) if( BUILD_TESTING ) add_executable( test_conf test_conf.cpp ) target_link_libraries( test_conf ${YAMLCPP_LIBRARY} ) + target_include_directories( test_conf PUBLIC ${YAMLCPP_INCLUDE_DIR} ) endif() file( GLOB SUBDIRECTORIES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*" ) diff --git a/src/modules/bootloader/main.py b/src/modules/bootloader/main.py index cb94ae45d..1759f4500 100644 --- a/src/modules/bootloader/main.py +++ b/src/modules/bootloader/main.py @@ -271,9 +271,9 @@ def install_grub(efi_directory, fw_type): # Workaround for some UEFI firmwares efi_file_source = os.path.join(install_efi_directory_firmware, efi_bootloader_id, - efi_grub_file), + efi_grub_file) efi_file_target = os.path.join(install_efi_boot_directory, - efi_boot_file), + efi_boot_file) shutil.copy2(efi_file_source, efi_file_target) else: diff --git a/src/modules/locale/LocaleViewStep.cpp b/src/modules/locale/LocaleViewStep.cpp index 4b4219751..73efc266f 100644 --- a/src/modules/locale/LocaleViewStep.cpp +++ b/src/modules/locale/LocaleViewStep.cpp @@ -120,7 +120,7 @@ LocaleViewStep::fetchGeoIpTimezone() try { - YAML::Node doc = YAML::Load( reply->readAll() ); + YAML::Node doc = YAML::Load( data ); QVariant var = CalamaresUtils::yamlToVariant( doc ); if ( !var.isNull() && diff --git a/src/modules/locale/locale.conf b/src/modules/locale/locale.conf index 1cb39228e..3d7f34e6f 100644 --- a/src/modules/locale/locale.conf +++ b/src/modules/locale/locale.conf @@ -1,7 +1,27 @@ --- -region: "America" -zone: "New_York" +# This settings are used to set your default system time zone. +# Time zones are usually located under /usr/share/zoneinfo and +# provided by the 'tzdata' package of your Distribution. +# +# Distributions using systemd can list available +# time zones by using the timedatectl command. +# timedatectl list-timezones +region: "America" +zone: "New_York" -# GeoIP settings. Leave commented out to disable GeoIP. -localeGenPath: "/etc/locale.gen" + +# System locales are detected in the following order: +# +# /usr/share/i18n/SUPPORTED +# localeGenPath (defaults to /etc/locale.gen if not set) +# 'locale -a' output +# Enable only when your Distribution is using an +# custom path for locale.gen +#localeGenPath: "PATH_TO/locale.gen" + +# GeoIP based Language settings: +# GeoIP need an working Internet connecion. +# This can be managed from welcome.conf by adding +# internet to the list of required conditions. +# Leave commented out to disable GeoIP. geoipUrl: "freegeoip.net" diff --git a/src/modules/netinstall/NetInstallPage.cpp b/src/modules/netinstall/NetInstallPage.cpp index f0bc9d93d..28c836a79 100644 --- a/src/modules/netinstall/NetInstallPage.cpp +++ b/src/modules/netinstall/NetInstallPage.cpp @@ -3,6 +3,7 @@ * Copyright 2016, Lisa Vitolo * Copyright 2017, Kyle Robbertze * Copyright 2017, Adriaan de Groot + * Copyright 2017, Gabriel Craciunescu * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -56,14 +57,6 @@ NetInstallPage::NetInstallPage( QWidget* parent ) ui->setupUi( this ); } -bool -NetInstallPage::isReady() -{ - // nothing to wait for, the data are immediately ready - // if the user does not select any group nothing is installed - return true; -} - bool NetInstallPage::readGroups( const QByteArray& yamlData ) { @@ -77,7 +70,7 @@ NetInstallPage::readGroups( const QByteArray& yamlData ) m_groups = new PackageModel( groups ); CALAMARES_RETRANSLATE( m_groups->setHeaderData( 0, Qt::Horizontal, tr( "Name" ) ); - m_groups->setHeaderData( 0, Qt::Horizontal, tr( "Description" ) ); ) + m_groups->setHeaderData( 1, Qt::Horizontal, tr( "Description" ) ); ) return true; } @@ -91,10 +84,13 @@ NetInstallPage::readGroups( const QByteArray& yamlData ) void NetInstallPage::dataIsHere( QNetworkReply* reply ) { + // If m_required is *false* then we still say we're ready + // even if the reply is corrupt or missing. if ( reply->error() != QNetworkReply::NoError ) { cDebug() << reply->errorString(); ui->netinst_status->setText( tr( "Network Installation. (Disabled: Unable to fetch package lists, check your network connection)" ) ); + emit checkReady( !m_required ); return; } @@ -103,6 +99,7 @@ NetInstallPage::dataIsHere( QNetworkReply* reply ) cDebug() << "Netinstall groups data was received, but invalid."; ui->netinst_status->setText( tr( "Network Installation. (Disabled: Received invalid groups data)" ) ); reply->deleteLater(); + emit checkReady( !m_required ); return; } @@ -111,15 +108,23 @@ NetInstallPage::dataIsHere( QNetworkReply* reply ) ui->groupswidget->header()->setSectionResizeMode( 1, QHeaderView::Stretch ); reply->deleteLater(); - emit checkReady( isReady() ); + emit checkReady( true ); } -QList NetInstallPage::selectedPackages() const +PackageModel::PackageItemDataList +NetInstallPage::selectedPackages() const { - return m_groups->getPackages(); + if ( m_groups ) + return m_groups->getPackages(); + else + { + cDebug() << "WARNING: no netinstall groups are available."; + return PackageModel::PackageItemDataList(); + } } -void NetInstallPage::loadGroupList() +void +NetInstallPage::loadGroupList() { QString confUrl( Calamares::JobQueue::instance()->globalStorage()->value( @@ -138,7 +143,15 @@ void NetInstallPage::loadGroupList() m_networkManager.get( request ); } -void NetInstallPage::onActivate() +void +NetInstallPage::setRequired( bool b ) +{ + m_required = b; +} + + +void +NetInstallPage::onActivate() { ui->groupswidget->setFocus(); } diff --git a/src/modules/netinstall/NetInstallPage.h b/src/modules/netinstall/NetInstallPage.h index 423c16b8e..58308412d 100644 --- a/src/modules/netinstall/NetInstallPage.h +++ b/src/modules/netinstall/NetInstallPage.h @@ -46,17 +46,24 @@ public: void onActivate(); - bool isReady(); - // Retrieves the groups, with name, description and packages, from // the remote URL configured in the settings. Assumes the URL is already // in the global storage. This should be called before displaying the page. void loadGroupList(); + // Sets the "required" state of netinstall data. Influences whether + // corrupt or unavailable data causes checkReady() to be emitted + // true (not-required) or false. + void setRequired( bool ); + bool getRequired() const + { + return m_required; + } + // Returns the list of packages belonging to groups that are // selected in the view in this given moment. No data is cached here, so // this function does not have constant time. - QList selectedPackages() const; + PackageModel::PackageItemDataList selectedPackages() const; public slots: void dataIsHere( QNetworkReply* ); @@ -76,6 +83,7 @@ private: QNetworkAccessManager m_networkManager; PackageModel* m_groups; + bool m_required; }; #endif // NETINSTALLPAGE_H diff --git a/src/modules/netinstall/NetInstallViewStep.cpp b/src/modules/netinstall/NetInstallViewStep.cpp index 347b2bf27..50e08486b 100644 --- a/src/modules/netinstall/NetInstallViewStep.cpp +++ b/src/modules/netinstall/NetInstallViewStep.cpp @@ -2,6 +2,7 @@ * Copyright 2016, Luca Giambonini * Copyright 2016, Lisa Vitolo * Copyright 2017, Kyle Robbertze + * Copyright 2017, Adriaan de Groot * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,11 +31,11 @@ CALAMARES_PLUGIN_FACTORY_DEFINITION( NetInstallViewStepFactory, registerPlugin packages = m_widget->selectedPackages(); + PackageModel::PackageItemDataList packages = m_widget->selectedPackages(); QVariantList installPackages; QVariantList tryInstallPackages; QVariantList packageOperations; @@ -138,7 +139,7 @@ NetInstallViewStep::onLeave() QVariant details( package.packageName ); // If it's a package with a pre- or post-script, replace // with the more complicated datastructure. - if (!package.preScript.isEmpty() || !package.postScript.isEmpty()) + if ( !package.preScript.isEmpty() || !package.postScript.isEmpty() ) { QMap sdetails; sdetails.insert( "pre-script", package.preScript ); @@ -156,14 +157,14 @@ NetInstallViewStep::onLeave() { QMap op; op.insert( "install", QVariant( installPackages ) ); - packageOperations.append(op); + packageOperations.append( op ); cDebug() << " .." << installPackages.length() << "critical packages."; } if ( !tryInstallPackages.empty() ) { QMap op; op.insert( "try_install", QVariant( tryInstallPackages ) ); - packageOperations.append(op); + packageOperations.append( op ); cDebug() << " .." << tryInstallPackages.length() << "non-critical packages."; } @@ -178,6 +179,11 @@ NetInstallViewStep::onLeave() void NetInstallViewStep::setConfigurationMap( const QVariantMap& configurationMap ) { + m_widget->setRequired( + configurationMap.contains( "required" ) && + configurationMap.value( "required" ).type() == QVariant::Bool && + configurationMap.value( "required" ).toBool() ); + if ( configurationMap.contains( "groupsUrl" ) && configurationMap.value( "groupsUrl" ).type() == QVariant::String ) { @@ -186,3 +192,10 @@ NetInstallViewStep::setConfigurationMap( const QVariantMap& configurationMap ) m_widget->loadGroupList(); } } + +void +NetInstallViewStep::nextIsReady( bool b ) +{ + m_nextEnabled = b; + emit nextStatusChanged( b ); +} diff --git a/src/modules/netinstall/NetInstallViewStep.h b/src/modules/netinstall/NetInstallViewStep.h index d9853f26f..ee53f61ce 100644 --- a/src/modules/netinstall/NetInstallViewStep.h +++ b/src/modules/netinstall/NetInstallViewStep.h @@ -60,6 +60,9 @@ public: void setConfigurationMap( const QVariantMap& configurationMap ) override; +public slots: + void nextIsReady( bool ); + private: NetInstallPage* m_widget; bool m_nextEnabled; diff --git a/src/modules/netinstall/PackageModel.h b/src/modules/netinstall/PackageModel.h index 148bd99ab..06d6c0ca1 100644 --- a/src/modules/netinstall/PackageModel.h +++ b/src/modules/netinstall/PackageModel.h @@ -1,3 +1,4 @@ + /* === This file is part of Calamares - === * * Copyright (c) 2017, Kyle Robbertze @@ -28,14 +29,13 @@ #include -// Required forward declarations -class PackageTreeItem; - class PackageModel : public QAbstractItemModel { Q_OBJECT public: + using PackageItemDataList = QList< PackageTreeItem::ItemData >; + explicit PackageModel( const YAML::Node& data, QObject* parent = nullptr ); ~PackageModel() override; @@ -52,7 +52,7 @@ public: QModelIndex parent( const QModelIndex& index ) const override; int rowCount( const QModelIndex& parent = QModelIndex() ) const override; int columnCount( const QModelIndex& parent = QModelIndex() ) const override; - QList getPackages() const; + PackageItemDataList getPackages() const; QList getItemPackages( PackageTreeItem* item ) const; private: diff --git a/src/modules/netinstall/netinstall.conf b/src/modules/netinstall/netinstall.conf index b87aef43e..f5977a267 100644 --- a/src/modules/netinstall/netinstall.conf +++ b/src/modules/netinstall/netinstall.conf @@ -1,2 +1,13 @@ --- +# This is the URL that is retrieved to get the netinstall groups-and-packages +# data (which should be in the format described in netinstall.yaml). groupsUrl: http://chakraos.org/netinstall.php + +# If the installation can proceed without netinstall (e.g. the Live CD +# can create a working installed system, but netinstall is preferred +# to bring it up-to-date or extend functionality) leave this set to +# false (the default). If set to true, the netinstall data is required. +# +# This only has an effect if the netinstall data cannot be retrieved, +# or is corrupt: having "required" set, means the install cannot proceed. +required: false diff --git a/src/modules/partition/CMakeLists.txt b/src/modules/partition/CMakeLists.txt index 961490bef..a60801531 100644 --- a/src/modules/partition/CMakeLists.txt +++ b/src/modules/partition/CMakeLists.txt @@ -12,10 +12,21 @@ find_package( KF5 REQUIRED Config I18n IconThemes KIO Service ) # first and add a define for it; otherwise we need 3.0.3 for NVMe # support; 3.0.2 works as well, but is buggy (#697) find_package( KPMcore 3.1.50 QUIET ) -if ( ${KPMcore_FOUND} ) +if ( KPMcore_FOUND ) add_definitions(-DWITH_KPMCORE22) endif() -find_package( KPMcore 3.0.3 REQUIRED ) +find_package( KPMcore 3.0.3 QUIET ) +# 3.0.3 and newer has fixes for NVMe support; allow 3.0.2, but warn +# about it .. needs to use a different feature name because it otherwise +# gets reported as KPMcore (the package). +if ( KPMcore_FOUND ) + message( STATUS "KPMCore supports NVMe operations" ) + add_feature_info( KPMcoreNVMe KPMcore_FOUND "KPMcore with NVMe support" ) +else() + find_package( KPMcore 3.0.2 REQUIRED ) + message( WARNING "KPMCore 3.0.2 is known to have bugs with NVMe devices" ) + add_feature_info( KPMcoreNVMe KPMcore_FOUND "Older KPMcore with no NVMe support" ) +endif() find_library( atasmart_LIB atasmart ) find_library( blkid_LIB blkid ) @@ -62,7 +73,6 @@ calamares_add_plugin( partition gui/PrettyRadioButton.cpp gui/ScanningDialog.cpp gui/ReplaceWidget.cpp - jobs/CheckFileSystemJob.cpp jobs/ClearMountsJob.cpp jobs/ClearTempMountsJob.cpp jobs/CreatePartitionJob.cpp @@ -70,7 +80,6 @@ calamares_add_plugin( partition jobs/DeletePartitionJob.cpp jobs/FillGlobalStorageJob.cpp jobs/FormatPartitionJob.cpp - jobs/MoveFileSystemJob.cpp jobs/PartitionJob.cpp jobs/ResizePartitionJob.cpp jobs/SetPartitionFlagsJob.cpp diff --git a/src/modules/partition/jobs/CheckFileSystemJob.cpp b/src/modules/partition/jobs/CheckFileSystemJob.cpp deleted file mode 100644 index 3d694f69a..000000000 --- a/src/modules/partition/jobs/CheckFileSystemJob.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* === This file is part of Calamares - === - * - * Copyright 2014, Aurélien Gâteau - * Copyright 2016, Teo Mrnjavac - * - * 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 . - */ - -#include "jobs/CheckFileSystemJob.h" - -#include - -// KPMcore -#include -#include -#include - -#include - -CheckFileSystemJob::CheckFileSystemJob( Partition* partition ) - : PartitionJob( partition ) -{} - -QString -CheckFileSystemJob::prettyName() const -{ - QString path = partition()->partitionPath(); - return tr( "Checking file system on partition %1." ).arg( path ); -} - - -QString -CheckFileSystemJob::prettyStatusMessage() const -{ - return prettyName(); -} - - -Calamares::JobResult -CheckFileSystemJob::exec() -{ - FileSystem& fs = partition()->fileSystem(); - - // if we cannot check, assume everything is fine - if ( fs.supportCheck() != FileSystem::cmdSupportFileSystem ) - return Calamares::JobResult::ok(); - - Report report( nullptr ); - bool ok = fs.check( report, partition()->partitionPath() ); - int retries = 0; - const int MAX_RETRIES = 10; - while ( !ok ) - { - cDebug() << "Partition" << partition()->partitionPath() - << "might not be ready yet, retrying (" << ++retries - << "/" << MAX_RETRIES << ") ..."; - QThread::sleep( 2 /*seconds*/ ); - ok = fs.check( report, partition()->partitionPath() ); - - if ( retries == MAX_RETRIES ) - break; - } - - if ( !ok ) - return Calamares::JobResult::error( - tr( "The file system check on partition %1 failed." ) - .arg( partition()->partitionPath() ), - report.toText() - ); - - return Calamares::JobResult::ok(); -} diff --git a/src/modules/partition/jobs/CheckFileSystemJob.h b/src/modules/partition/jobs/CheckFileSystemJob.h deleted file mode 100644 index 7dba8f493..000000000 --- a/src/modules/partition/jobs/CheckFileSystemJob.h +++ /dev/null @@ -1,38 +0,0 @@ -/* === This file is part of Calamares - === - * - * Copyright 2014, Aurélien Gâteau - * - * 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 . - */ - -#ifndef CHECKFILESYSTEMJOB_H -#define CHECKFILESYSTEMJOB_H - -#include - -/** - * Runs a file system check on an existing partition. - */ -class CheckFileSystemJob : public PartitionJob -{ - Q_OBJECT -public: - CheckFileSystemJob( Partition* partition ); - - QString prettyName() const override; - QString prettyStatusMessage() const override; - Calamares::JobResult exec() override; -}; - -#endif /* CHECKFILESYSTEMJOB_H */ diff --git a/src/modules/partition/jobs/MoveFileSystemJob.cpp b/src/modules/partition/jobs/MoveFileSystemJob.cpp deleted file mode 100644 index fbcc4641c..000000000 --- a/src/modules/partition/jobs/MoveFileSystemJob.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* === This file is part of Calamares - === - * - * Copyright 2014, Aurélien Gâteau - * - * 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 . - */ - -// This class is heavily based on the MoveFileSystemJob class from KDE Partition -// Manager. -// The copyBlock functions come from Partition Manager Job class. -// Original copyright follow: - -/*************************************************************************** - * Copyright (C) 2008 by Volker Lanz * - * * - * This program 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 2 of the License, or * - * (at your option) any later version. * - * * - * This program 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 this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - -#include - -#include - -// KPMcore -#include -#include -#include -#include -#include -#include - -MoveFileSystemJob::MoveFileSystemJob( Device* device, Partition* partition, qint64 oldFirstSector, qint64 newFirstSector, qint64 length ) - : PartitionJob( partition ) - , m_device( device ) - , m_oldFirstSector( oldFirstSector ) - , m_newFirstSector( newFirstSector ) - , m_length( length ) -{} - -QString -MoveFileSystemJob::prettyName() const -{ - return tr( "Move file system of partition %1." ).arg( partition()->partitionPath() ); -} - -Calamares::JobResult -MoveFileSystemJob::exec() -{ - Report report( nullptr ); - QString partitionPath = partition()->partitionPath(); - CopySourceDevice moveSource( *m_device, m_oldFirstSector, m_oldFirstSector + m_length - 1 ); - CopyTargetDevice moveTarget( *m_device, m_newFirstSector, m_newFirstSector + m_length - 1 ); - - if ( !moveSource.open() ) - return Calamares::JobResult::error( - QString(), - tr( "Could not open file system on partition %1 for moving." ).arg( partitionPath ) - ); - - if ( !moveTarget.open() ) - return Calamares::JobResult::error( - QString(), - tr( "Could not create target for moving file system on partition %1." ).arg( partitionPath ) - ); - - bool ok = copyBlocks( report, moveTarget, moveSource ); - if ( !ok ) - { - if ( rollbackCopyBlocks( report, moveTarget, moveSource ) ) - return Calamares::JobResult::error( - QString(), - tr( "Moving of partition %1 failed, changes have been rolled back." ).arg( partitionPath ) - + '\n' + report.toText() - ); - else - return Calamares::JobResult::error( - QString(), - tr( "Moving of partition %1 failed. Roll back of the changes have failed." ).arg( partitionPath ) - + '\n' + report.toText() - ); - } - - FileSystem& fs = partition()->fileSystem(); - fs.setFirstSector( m_newFirstSector ); - fs.setLastSector( m_newFirstSector + m_length - 1 ); - - if ( !fs.updateBootSector( report, partitionPath ) ) - return Calamares::JobResult::error( - QString(), - tr( "Updating boot sector after the moving of partition %1 failed." ).arg( partitionPath ) - + '\n' + report.toText() - ); - - return Calamares::JobResult::ok(); -} - -bool -MoveFileSystemJob::copyBlocks( Report& report, CopyTargetDevice& target, CopySourceDevice& source ) -{ - /** @todo copyBlocks() assumes that source.sectorSize() == target.sectorSize(). */ - - if ( source.sectorSize() != target.sectorSize() ) - { - report.line() << tr( "The logical sector sizes in the source and target for copying are not the same. This is currently unsupported." ); - return false; - } - - bool rval = true; - const qint64 blockSize = 16065 * 8; // number of sectors per block to copy - const qint64 blocksToCopy = source.length() / blockSize; - - qint64 readOffset = source.firstSector(); - qint64 writeOffset = target.firstSector(); - qint32 copyDir = 1; - - if ( target.firstSector() > source.firstSector() ) - { - readOffset = source.firstSector() + source.length() - blockSize; - writeOffset = target.firstSector() + source.length() - blockSize; - copyDir = -1; - } - - qint64 blocksCopied = 0; - - Q_ASSERT( blockSize > 0 ); - Q_ASSERT( source.sectorSize() > 0 ); - Q_ASSERT( blockSize * source.sectorSize() > 0 ); - - void* buffer = malloc( size_t( blockSize * source.sectorSize() ) ); - qint64 percent = 0; - - while ( blocksCopied < blocksToCopy ) - { - rval = source.readSectors( buffer, readOffset + blockSize * blocksCopied * copyDir, blockSize ); - if ( !rval ) - break; - - rval = target.writeSectors( buffer, writeOffset + blockSize * blocksCopied * copyDir, blockSize ); - if ( !rval ) - break; - - if ( ++blocksCopied * 100 / blocksToCopy != percent ) - { - percent = blocksCopied * 100 / blocksToCopy; - progress( percent / 100. ); - } - } - - const qint64 lastBlock = source.length() % blockSize; - - // copy the remainder - if ( rval && lastBlock > 0 ) - { - Q_ASSERT( lastBlock < blockSize ); - - const qint64 lastBlockReadOffset = copyDir > 0 ? readOffset + blockSize * blocksCopied : source.firstSector(); - const qint64 lastBlockWriteOffset = copyDir > 0 ? writeOffset + blockSize * blocksCopied : target.firstSector(); - - rval = source.readSectors( buffer, lastBlockReadOffset, lastBlock ); - - if ( rval ) - rval = target.writeSectors( buffer, lastBlockWriteOffset, lastBlock ); - - if ( rval ) - emit progress( 1.0 ); - } - - free( buffer ); - - return rval; -} - -bool -MoveFileSystemJob::rollbackCopyBlocks( Report& report, CopyTargetDevice& origTarget, CopySourceDevice& origSource ) -{ - if ( !origSource.overlaps( origTarget ) ) - { - report.line() << tr( "Source and target for copying do not overlap: Rollback is not required." ); - return true; - } - - // default: use values as if we were copying from front to back. - qint64 undoSourceFirstSector = origTarget.firstSector(); - qint64 undoSourceLastSector = origTarget.firstSector() + origTarget.sectorsWritten() - 1; - - qint64 undoTargetFirstSector = origSource.firstSector(); - qint64 undoTargetLastSector = origSource.firstSector() + origTarget.sectorsWritten() - 1; - - if ( origTarget.firstSector() > origSource.firstSector() ) - { - // we were copying from back to front - undoSourceFirstSector = origTarget.firstSector() + origSource.length() - origTarget.sectorsWritten(); - undoSourceLastSector = origTarget.firstSector() + origSource.length() - 1; - - undoTargetFirstSector = origSource.lastSector() - origTarget.sectorsWritten() + 1; - undoTargetLastSector = origSource.lastSector(); - } - - CopySourceDevice undoSource( origTarget.device(), undoSourceFirstSector, undoSourceLastSector ); - if ( !undoSource.open() ) - { - report.line() << tr( "Could not open device %1 to rollback copying." ) - .arg( origTarget.device().deviceNode() ); - return false; - } - - CopyTargetDevice undoTarget( origSource.device(), undoTargetFirstSector, undoTargetLastSector ); - if ( !undoTarget.open() ) - { - report.line() << tr( "Could not open device %1 to rollback copying." ) - .arg( origSource.device().deviceNode() ); - return false; - } - - return copyBlocks( report, undoTarget, undoSource ); -} diff --git a/src/modules/partition/jobs/MoveFileSystemJob.h b/src/modules/partition/jobs/MoveFileSystemJob.h deleted file mode 100644 index f2ae6d741..000000000 --- a/src/modules/partition/jobs/MoveFileSystemJob.h +++ /dev/null @@ -1,76 +0,0 @@ -/* === This file is part of Calamares - === - * - * Copyright 2014, Aurélien Gâteau - * - * 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 . - */ - -// This class is heavily based on the MoveFileSystemJob class from KDE Partition -// Manager. Original copyright follow: - -/*************************************************************************** - * Copyright (C) 2008 by Volker Lanz * - * * - * This program 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 2 of the License, or * - * (at your option) any later version. * - * * - * This program 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 this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ -#ifndef MOVEFILESYSTEMJOB_H -#define MOVEFILESYSTEMJOB_H - -#include - -class CopySourceDevice; -class CopyTargetDevice; -class Device; -class Partition; -class Report; - -/** - * This job moves the data of a filesystem from one position on the disk to - * another. - * - * It is used by the ResizePartitionJob. - */ -class MoveFileSystemJob : public PartitionJob -{ - Q_OBJECT -public: - MoveFileSystemJob( Device* device, Partition* partition, qint64 oldFirstSector, qint64 newFirstSector, qint64 length ); - - QString prettyName() const override; - - Calamares::JobResult exec() override; - -private: - Device* m_device; - qint64 m_oldFirstSector; - qint64 m_newFirstSector; - qint64 m_length; - bool copyBlocks( Report& report, CopyTargetDevice& target, CopySourceDevice& source ); - bool rollbackCopyBlocks( Report& report, CopyTargetDevice& origTarget, CopySourceDevice& origSource ); -}; - -#endif /* MOVEFILESYSTEMJOB_H */ diff --git a/src/modules/partition/jobs/ResizePartitionJob.cpp b/src/modules/partition/jobs/ResizePartitionJob.cpp index d3fcb75b4..41950d4df 100644 --- a/src/modules/partition/jobs/ResizePartitionJob.cpp +++ b/src/modules/partition/jobs/ResizePartitionJob.cpp @@ -2,6 +2,7 @@ * * Copyright 2014, Aurélien Gâteau * Copyright 2015, Teo Mrnjavac + * Copyright 2017, Andrius Štikonas * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,156 +18,12 @@ * along with Calamares. If not, see . */ -// This class is heavily based on the ResizeOperation class from KDE Partition -// Manager. Original copyright follow: - -/*************************************************************************** - * Copyright (C) 2008,2012 by Volker Lanz * - * * - * This program 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 2 of the License, or * - * (at your option) any later version. * - * * - * This program 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 this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - #include "jobs/ResizePartitionJob.h" -#include "jobs/CheckFileSystemJob.h" -#include "jobs/MoveFileSystemJob.h" -#include "utils/Logger.h" - // KPMcore -#include -#include -#include -#include -#include -#include -#include -#include - -// Qt -#include - -//- ResizeFileSystemJob -------------------------------------------------------- -class ResizeFileSystemJob : public Calamares::Job -{ - Q_OBJECT -public: - ResizeFileSystemJob( Device* device, CoreBackendPartitionTable* backendPartitionTable, Partition* partition, qint64 length ) - : m_device( device ) - , m_backendPartitionTable( backendPartitionTable ) - , m_partition( partition ) - , m_length( length ) - {} - - QString prettyName() const override - { - QString path = m_partition->partitionPath(); - return tr( "Resize file system on partition %1." ).arg( path ); - } - - Calamares::JobResult exec() override - { - Report report( nullptr ); - FileSystem& fs = m_partition->fileSystem(); - FileSystem::CommandSupportType support = m_length < fs.length() ? fs.supportShrink() : fs.supportGrow(); - - switch ( support ) - { - case FileSystem::cmdSupportBackend: - if ( !backendResize( &report ) ) - return Calamares::JobResult::error( - QString(), - tr( "Parted failed to resize filesystem." ) + '\n' + report.toText() - ); - break; - case FileSystem::cmdSupportFileSystem: - { - qint64 byteLength = m_device->logicalSize() * m_length; - bool ok = fs.resize( report, m_partition->partitionPath(), byteLength ); - if ( !ok ) - return Calamares::JobResult::error( - QString(), - tr( "Failed to resize filesystem." ) + '\n' + report.toText() - ); - break; - } - default: - break; - } - - fs.setLastSector( fs.firstSector() + m_length - 1 ); - return Calamares::JobResult::ok(); - } - -private: - Device* m_device; - CoreBackendPartitionTable* m_backendPartitionTable; - Partition* m_partition; - qint64 m_length; - - bool backendResize( Report* report ) - { - bool ok = m_backendPartitionTable->resizeFileSystem( *report, *m_partition, m_length ); - if ( !ok ) - return false; - m_backendPartitionTable->commit(); - return true; - } -}; - -//- SetPartGeometryJob --------------------------------------------------------- -class SetPartGeometryJob : public Calamares::Job -{ - Q_OBJECT -public: - SetPartGeometryJob( CoreBackendPartitionTable* backendPartitionTable, Partition* partition, qint64 firstSector, qint64 length ) - : m_backendPartitionTable( backendPartitionTable ) - , m_partition( partition ) - , m_firstSector( firstSector ) - , m_length( length ) - {} - - QString prettyName() const override - { - QString path = m_partition->partitionPath(); - return tr( "Update geometry of partition %1." ).arg( path ); - } - - Calamares::JobResult exec() override - { - Report report( nullptr ); - qint64 lastSector = m_firstSector + m_length - 1; - bool ok = m_backendPartitionTable->updateGeometry( report, *m_partition, m_firstSector, lastSector ); - if ( !ok ) - { - return Calamares::JobResult::error( - QString(), - tr( "Failed to change the geometry of the partition." ) + '\n' + report.toText() ); - } - m_partition->setFirstSector( m_firstSector ); - m_partition->setLastSector( lastSector ); - m_backendPartitionTable->commit(); - return Calamares::JobResult::ok(); - } - -private: - CoreBackendPartitionTable* m_backendPartitionTable; - Partition* m_partition; - qint64 m_firstSector; - qint64 m_length; -}; +#include +#include +#include //- ResizePartitionJob --------------------------------------------------------- ResizePartitionJob::ResizePartitionJob( Device* device, Partition* partition, qint64 firstSector, qint64 lastSector ) @@ -194,7 +51,7 @@ ResizePartitionJob::prettyDescription() const return tr( "Resize %2MB partition %1 to " "%3MB." ) .arg( partition()->partitionPath() ) - .arg( ( m_oldLastSector - m_oldFirstSector ) * partition()->sectorSize() / 1024 / 1024 ) + .arg( ( m_oldLastSector - m_oldFirstSector + 1 ) * partition()->sectorSize() / 1024 / 1024 ) .arg( ( m_newLastSector - m_newFirstSector + 1 ) * partition()->sectorSize() / 1024 / 1024 ); } @@ -205,7 +62,7 @@ ResizePartitionJob::prettyStatusMessage() const return tr( "Resizing %2MB partition %1 to " "%3MB." ) .arg( partition()->partitionPath() ) - .arg( ( m_oldLastSector - m_oldFirstSector ) * partition()->sectorSize() / 1024 / 1024 ) + .arg( ( m_oldLastSector - m_oldFirstSector + 1 ) * partition()->sectorSize() / 1024 / 1024 ) .arg( ( m_newLastSector - m_newFirstSector + 1 ) * partition()->sectorSize() / 1024 / 1024 ); } @@ -213,64 +70,21 @@ ResizePartitionJob::prettyStatusMessage() const Calamares::JobResult ResizePartitionJob::exec() { - qint64 oldLength = m_oldLastSector - m_oldFirstSector + 1; - qint64 newLength = m_newLastSector - m_newFirstSector + 1; - - // Assuming updatePreview() has been called, `partition` uses its new - // position and size. Reset it to the old values: part of the libparted - // backend relies on this (for example: - // LibPartedPartitionTable::updateGeometry()) - // The jobs are responsible for updating the partition back when they are - // done. + Report report (nullptr); + // Restore partition sectors that were modified for preview m_partition->setFirstSector( m_oldFirstSector ); m_partition->setLastSector( m_oldLastSector ); + ResizeOperation op(*m_device, *m_partition, m_newFirstSector, m_newLastSector); + op.setStatus(Operation::StatusRunning); + connect(&op, &Operation::progress, [&](int percent) { emit progress(percent / 100.0); } ); - CoreBackend* backend = CoreBackendManager::self()->backend(); - QScopedPointer backendDevice( backend->openDevice( m_device->deviceNode() ) ); - if ( !backendDevice.data() ) - { - QString errorMessage = tr( "The installer failed to resize partition %1 on disk '%2'." ) - .arg( m_partition->partitionPath() ) - .arg( m_device->name() ); - return Calamares::JobResult::error( - errorMessage, - tr( "Could not open device '%1'." ).arg( m_device->deviceNode() ) - ); - } - QScopedPointer backendPartitionTable( backendDevice->openPartitionTable() ); + QString errorMessage = tr( "The installer failed to resize partition %1 on disk '%2'." ) + .arg( m_partition->partitionPath() ) + .arg( m_device->name() ); + if (op.execute(report)) + return Calamares::JobResult::ok(); - // Create jobs - QList< Calamares::job_ptr > jobs; - jobs << Calamares::job_ptr( new CheckFileSystemJob( partition() ) ); - if ( m_partition->roles().has( PartitionRole::Extended ) ) - jobs << Calamares::job_ptr( new SetPartGeometryJob( backendPartitionTable.data(), m_partition, m_newFirstSector, newLength ) ); - else - { - bool shrink = newLength < oldLength; - bool grow = newLength > oldLength; - bool moveRight = m_newFirstSector > m_oldFirstSector; - bool moveLeft = m_newFirstSector < m_oldFirstSector; - if ( shrink ) - { - jobs << Calamares::job_ptr( new ResizeFileSystemJob( m_device, backendPartitionTable.data(), m_partition, newLength ) ); - jobs << Calamares::job_ptr( new SetPartGeometryJob( backendPartitionTable.data(), m_partition, m_oldFirstSector, newLength ) ); - } - if ( moveRight || moveLeft ) - { - // At this point, we need to set the partition's length to either the resized length, if it has already been - // shrunk, or to the original length (it may or may not then later be grown, we don't care here) - const qint64 length = shrink ? newLength : oldLength; - jobs << Calamares::job_ptr( new SetPartGeometryJob( backendPartitionTable.data(), m_partition, m_newFirstSector, length ) ); - jobs << Calamares::job_ptr( new MoveFileSystemJob( m_device, m_partition, m_oldFirstSector, m_newFirstSector, length ) ); - } - if ( grow ) - { - jobs << Calamares::job_ptr( new SetPartGeometryJob( backendPartitionTable.data(), m_partition, m_newFirstSector, newLength ) ); - jobs << Calamares::job_ptr( new ResizeFileSystemJob( m_device, backendPartitionTable.data(), m_partition, newLength ) ); - } - } - jobs << Calamares::job_ptr( new CheckFileSystemJob( partition() ) ); - return execJobList( jobs ); + return Calamares::JobResult::error(errorMessage, report.toText()); } void @@ -290,31 +104,3 @@ ResizePartitionJob::device() const { return m_device; } - - -Calamares::JobResult -ResizePartitionJob::execJobList( const QList< Calamares::job_ptr >& jobs ) -{ - QString errorMessage = tr( "The installer failed to resize partition %1 on disk '%2'." ) - .arg( m_partition->partitionPath() ) - .arg( m_device->name() ); - - int nbJobs = jobs.size(); - int count = 0; - for ( Calamares::job_ptr job : jobs ) - { - cLog() << "- " + job->prettyName(); - Calamares::JobResult result = job->exec(); - if ( !result ) - { - if ( result.message().isEmpty() ) - result.setMessage( errorMessage ); - return result; - } - ++count; - progress( qreal( count ) / nbJobs ); - } - return Calamares::JobResult::ok(); -} - -#include "ResizePartitionJob.moc" diff --git a/src/modules/partition/jobs/ResizePartitionJob.h b/src/modules/partition/jobs/ResizePartitionJob.h index 9ae31130f..453461d8d 100644 --- a/src/modules/partition/jobs/ResizePartitionJob.h +++ b/src/modules/partition/jobs/ResizePartitionJob.h @@ -51,8 +51,6 @@ private: qint64 m_oldLastSector; qint64 m_newFirstSector; qint64 m_newLastSector; - - Calamares::JobResult execJobList( const QList< Calamares::job_ptr >& jobs ); }; #endif /* RESIZEPARTITIONJOB_H */ diff --git a/src/modules/partition/tests/CMakeLists.txt b/src/modules/partition/tests/CMakeLists.txt index 1917a226b..41f494ba2 100644 --- a/src/modules/partition/tests/CMakeLists.txt +++ b/src/modules/partition/tests/CMakeLists.txt @@ -9,11 +9,9 @@ set( partitionjobtests_SRCS ${PartitionModule_SOURCE_DIR}/core/KPMHelpers.cpp ${PartitionModule_SOURCE_DIR}/core/PartitionInfo.cpp ${PartitionModule_SOURCE_DIR}/core/PartitionIterator.cpp - ${PartitionModule_SOURCE_DIR}/jobs/CheckFileSystemJob.cpp ${PartitionModule_SOURCE_DIR}/jobs/CreatePartitionJob.cpp ${PartitionModule_SOURCE_DIR}/jobs/CreatePartitionTableJob.cpp ${PartitionModule_SOURCE_DIR}/jobs/DeletePartitionJob.cpp - ${PartitionModule_SOURCE_DIR}/jobs/MoveFileSystemJob.cpp ${PartitionModule_SOURCE_DIR}/jobs/PartitionJob.cpp ${PartitionModule_SOURCE_DIR}/jobs/ResizePartitionJob.cpp PartitionJobTests.cpp diff --git a/src/modules/users/UsersViewStep.cpp b/src/modules/users/UsersViewStep.cpp index 609e9d8d4..4441616d1 100644 --- a/src/modules/users/UsersViewStep.cpp +++ b/src/modules/users/UsersViewStep.cpp @@ -1,6 +1,11 @@ /* === This file is part of Calamares - === * * Copyright 2014-2015, Teo Mrnjavac +<<<<<<< HEAD +======= + * Copyright 2017, Adriaan de Groot + * Copyright 2017, Gabriel Craciunescu +>>>>>>> 62c03d685768a2c814e258cb03ad5884363bc9dc * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -130,6 +135,7 @@ UsersViewStep::setConfigurationMap( const QVariantMap& configurationMap ) } else { + cDebug() << "WARNING: Using fallback groups. Please check defaultGroups in users.conf"; m_defaultGroups = QStringList{ "lp", "video", "network", "storage", "wheel", "audio" }; } diff --git a/src/modules/users/users.conf b/src/modules/users/users.conf index ed1043432..4f5c3b7af 100644 --- a/src/modules/users/users.conf +++ b/src/modules/users/users.conf @@ -11,6 +11,8 @@ # These globalconfig keys are set when the jobs for this module # are created. --- +# Used as default groups for the created user. +# Adjust to your Distribution defaults. defaultGroups: - users - lp @@ -19,17 +21,43 @@ defaultGroups: - storage - wheel - audio -autologinGroup: autologin -doAutologin: false -# remove the following line to avoid creating /etc/sudoers.d/10-installer +# Some Distributions require a 'autologin' group for the user. +# Autologin causes a user to become automatically logged in to +# the desktop environment on boot. +# Disable when your Distribution does not require such a group. +autologinGroup: autologin +<<<<<<< HEAD +doAutologin: false +======= +# You can control the initial state for the 'autologin checkbox' in UsersViewStep here. +# Possible values are: true to enable or false to disable the checkbox by default +doAutologin: true +>>>>>>> 62c03d685768a2c814e258cb03ad5884363bc9dc + +# When set to a non-empty string, Calamares creates a sudoers file for the user. +# /etc/sudoers.d/10-installer +# Remember to add sudoersGroup to defaultGroups. +# +# If your Distribution already sets up a group of sudoers in its packaging, +# remove this setting (delete or comment out the line below). Otherwise, +# the setting will be duplicated in the /etc/sudoers.d/10-installer file, +# potentially confusing users. sudoersGroup: wheel +<<<<<<< HEAD <<<<<<< HEAD setRootPassword: false availableShells: /bin/bash, /bin/zsh ======= +======= +# Setting this to false , causes the root account to be disabled. +>>>>>>> 62c03d685768a2c814e258cb03ad5884363bc9dc setRootPassword: true +# You can control the initial state for the 'root password checkbox' in UsersViewStep here. +# Possible values are: true to enable or false to disable the checkbox by default. +# When enabled the user password is used for the root account too. +# NOTE: doReusePassword requires setRootPassword to be enabled. doReusePassword: true # These are optional password-requirements that a distro can enforce diff --git a/src/modules/welcome/checker/RequirementsChecker.cpp b/src/modules/welcome/checker/RequirementsChecker.cpp index 3d4e394c4..654434513 100644 --- a/src/modules/welcome/checker/RequirementsChecker.cpp +++ b/src/modules/welcome/checker/RequirementsChecker.cpp @@ -2,6 +2,7 @@ * * Copyright 2014-2017, Teo Mrnjavac * Copyright 2017, Adriaan de Groot + * Copyright 2017, Gabriel Craciunescu * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -99,8 +100,12 @@ RequirementsChecker::RequirementsChecker( QObject* parent ) if ( m_entriesToCheck.contains( "root" ) ) isRoot = checkIsRoot(); - cDebug() << "enoughStorage, enoughRam, hasPower, hasInternet, isRoot: " - << enoughStorage << enoughRam << hasPower << hasInternet << isRoot; + cDebug() << "RequirementsChecker output:" + << " enoughStorage:" << enoughStorage + << " enoughRam:" << enoughRam + << " hasPower:" << hasPower + << " hasInternet:" << hasInternet + << " isRoot:" << isRoot; QList< PrepareEntry > checkEntries; foreach ( const QString& entry, m_entriesToCheck )