diff --git a/src/modules/partition/CMakeLists.txt b/src/modules/partition/CMakeLists.txt index b5185bcea..3af8e4465 100644 --- a/src/modules/partition/CMakeLists.txt +++ b/src/modules/partition/CMakeLists.txt @@ -60,7 +60,6 @@ if(KPMcore_FOUND) core/DeviceList.cpp core/DeviceModel.cpp core/KPMHelpers.cpp - core/DirFSRestrictLayout.cpp core/OsproberEntry.cpp core/PartitionActions.cpp core/PartitionCoreModule.cpp diff --git a/src/modules/partition/Config.cpp b/src/modules/partition/Config.cpp index 085c45179..2e78d7c52 100644 --- a/src/modules/partition/Config.cpp +++ b/src/modules/partition/Config.cpp @@ -47,12 +47,12 @@ Config::swapChoiceNames() // *INDENT-OFF* // clang-format off static const NamedEnumTable< SwapChoice > names { - { QStringLiteral( "none" ), SwapChoice::NoSwap }, - { QStringLiteral( "small" ), SwapChoice::SmallSwap }, - { QStringLiteral( "suspend" ), SwapChoice::FullSwap }, - { QStringLiteral( "reuse" ), SwapChoice::ReuseSwap }, - { QStringLiteral( "file" ), SwapChoice::SwapFile }, - }; + { QStringLiteral( "none" ), SwapChoice::NoSwap }, + { QStringLiteral( "small" ), SwapChoice::SmallSwap }, + { QStringLiteral( "suspend" ), SwapChoice::FullSwap }, + { QStringLiteral( "reuse" ), SwapChoice::ReuseSwap }, + { QStringLiteral( "file" ), SwapChoice::SwapFile }, + }; // clang-format on // *INDENT-ON* @@ -65,10 +65,10 @@ Config::luksGenerationNames() // *INDENT-OFF* // clang-format off static const NamedEnumTable< LuksGeneration > names { - { QStringLiteral( "luks1" ), LuksGeneration::Luks1 }, - { QStringLiteral( "luks" ), LuksGeneration::Luks1 }, - { QStringLiteral( "luks2" ), LuksGeneration::Luks2 }, - }; + { QStringLiteral( "luks1" ), LuksGeneration::Luks1 }, + { QStringLiteral( "luks" ), LuksGeneration::Luks1 }, + { QStringLiteral( "luks2" ), LuksGeneration::Luks2 }, + }; // clang-format on // *INDENT-ON* @@ -260,6 +260,12 @@ Config::setReplaceFilesystemChoice( const QString& filesystemName ) } } +void +Config::setLuksFileSystemType( const LuksGeneration luks) +{ + m_luksFileSystemType = luks; +} + bool Config::acceptPartitionTableType( PartitionTable::TableType tableType ) const { @@ -316,6 +322,24 @@ fillGSConfigurationEFI( Calamares::GlobalStorage* gs, const QVariantMap& configu const auto efiMinimumSize = Calamares::getString( efiConfiguration, "minimumSize" ); if ( !efiMinimumSize.isEmpty() ) + if ( configurationMap.contains( "efiSystemPartitionMinSize" ) ) + { + const QString sizeString = Calamares::getString( configurationMap, "efiSystemPartitionMinSize" ); + Calamares::Partition::PartitionSize part_size = Calamares::Partition::PartitionSize( sizeString ); + if ( part_size.isValid() ) + { + // Insert once as string, once as a size-in-bytes; + // changes to these keys should be synchronized with PartUtils.cpp + gs->insert( "efiSystemPartitionMinSize", sizeString ); + gs->insert( "efiSystemPartitionMinSize_i", part_size.toBytes() ); + } + else + { + cWarning() << "Minimum EFI partition size" << sizeString << "is invalid, ignored"; + } + } + + { Calamares::Partition::PartitionSize part_size = Calamares::Partition::PartitionSize( efiMinimumSize ); if ( part_size.isValid() ) @@ -406,7 +430,6 @@ Config::fillConfigurationFSTypes( const QVariantMap& configurationMap ) } m_luksFileSystemType = luksGeneration; gs->insert( "luksFileSystemType", luksGenerationNames().find( luksGeneration ) ); - Q_ASSERT( !m_eraseFsTypes.isEmpty() ); Q_ASSERT( m_eraseFsTypes.contains( fsRealName ) ); m_eraseFsTypeChoice = fsRealName; @@ -415,6 +438,7 @@ Config::fillConfigurationFSTypes( const QVariantMap& configurationMap ) Q_EMIT replaceModeFilesystemChanged( m_replaceFileSystemChoice ); } + void Config::setConfigurationMap( const QVariantMap& configurationMap ) { @@ -448,11 +472,7 @@ Config::setConfigurationMap( const QVariantMap& configurationMap ) m_showNotEncryptedBootMessage = Calamares::getBool( configurationMap, "showNotEncryptedBootMessage", true ); m_requiredPartitionTableType = Calamares::getStringList( configurationMap, "requiredPartitionTableType" ); - { - bool bogus = true; - const auto lvmConfiguration = Calamares::getSubMap( configurationMap, "lvm", bogus ); - m_isLVMEnabled = Calamares::getBool( lvmConfiguration, "enable", true); - } + m_bootloaderVar = Calamares::getString( configurationMap, "efiBootLoaderVar", "" ); Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); gs->insert( "armInstall", Calamares::getBool( configurationMap, "armInstall", false ) ); diff --git a/src/modules/partition/Config.h b/src/modules/partition/Config.h index 13da58ac4..07acc4353 100644 --- a/src/modules/partition/Config.h +++ b/src/modules/partition/Config.h @@ -38,8 +38,6 @@ class Config : public QObject Q_PROPERTY( bool preCheckEncryption READ preCheckEncryption CONSTANT FINAL ) Q_PROPERTY( bool showNotEncryptedBootMessage READ showNotEncryptedBootMessage CONSTANT FINAL ) - Q_PROPERTY( bool lvmEnabled READ isLVMEnabled CONSTANT FINAL ) - public: Config( QObject* parent ); ~Config() override = default; @@ -70,7 +68,6 @@ public: using EraseFsTypesSet = QStringList; - /** @brief Choice of LUKS disk encryption generation */ enum class LuksGeneration { Luks1, // First generation of LUKS @@ -128,6 +125,11 @@ public: */ SwapChoice swapChoice() const { return m_swapChoice; } + /** @brief Get the variable name in global storage holding the name of bootloader + * + */ + QString bootloaderVar() const { return m_bootloaderVar; } + /** @brief Get the list of configured FS types to use with *erase* mode * * This list is not empty. @@ -176,8 +178,6 @@ public: /// @brief If zfs encryption should be allowed bool allowZfsEncryption() const { return m_allowZfsEncryption; } - bool isLVMEnabled() const { return m_isLVMEnabled; } - public Q_SLOTS: void setInstallChoice( int ); ///< Translates a button ID or so to InstallChoice void setInstallChoice( InstallChoice ); @@ -185,6 +185,7 @@ public Q_SLOTS: void setSwapChoice( SwapChoice ); void setEraseFsTypeChoice( const QString& filesystemName ); ///< See property eraseModeFilesystem void setReplaceFilesystemChoice( const QString& filesystemName ); + void setLuksFileSystemType( const LuksGeneration ); Q_SIGNALS: void installChoiceChanged( InstallChoice ); @@ -209,10 +210,10 @@ private: qreal m_requiredStorageGiB = 0.0; // May duplicate setting in the welcome module QStringList m_requiredPartitionTableType; bool m_allowZfsEncryption = true; + QString m_bootloaderVar; bool m_allowManualPartitioning = true; bool m_preCheckEncryption = false; bool m_showNotEncryptedBootMessage = true; - bool m_isLVMEnabled = true; }; /** @brief Given a set of swap choices, return a sensible value from it. diff --git a/src/modules/partition/PartitionViewStep.cpp b/src/modules/partition/PartitionViewStep.cpp index f356c7168..d19babe9e 100644 --- a/src/modules/partition/PartitionViewStep.cpp +++ b/src/modules/partition/PartitionViewStep.cpp @@ -17,11 +17,11 @@ #include "core/BootLoaderModel.h" #include "core/DeviceModel.h" #include "core/PartitionCoreModule.h" +#include "core/PartitionInfo.h" #include "gui/ChoicePage.h" #include "gui/PartitionBarsView.h" #include "gui/PartitionLabelsView.h" #include "gui/PartitionPage.h" -#include "partition/FileSystem.h" #include "Branding.h" #include "GlobalStorage.h" @@ -34,7 +34,6 @@ #include "widgets/TranslationFix.h" #include "widgets/WaitingWidget.h" -#include #include #include @@ -61,18 +60,6 @@ PartitionViewStep::PartitionViewStep( QObject* parent ) // We're not done loading, but we need the configuration map first. } -PartitionViewStep::FSConflictEntry::FSConflictEntry() {} - -PartitionViewStep::FSConflictEntry::FSConflictEntry( const QString& conflictingPathArg, - const QString& conflictingFilesystemArg, - const QString& conflictedPathArg, - QStringList allowableFilesystemsArg ) - : conflictingPath( conflictingPathArg ) - , conflictingFilesystem( conflictingFilesystemArg ) - , conflictedPath( conflictedPathArg ) - , allowableFilesystems( allowableFilesystemsArg ) -{} - void PartitionViewStep::initPartitionCoreModule() { @@ -131,7 +118,7 @@ static QStringList jobDescriptions( const Calamares::JobList& jobs ) { QStringList jobsLines; - for ( const Calamares::job_ptr& job : std::as_const( jobs ) ) + for ( const Calamares::job_ptr& job : qAsConst( jobs ) ) { const auto description = job->prettyDescription(); if ( !description.isEmpty() ) @@ -375,7 +362,7 @@ PartitionViewStep::next() { if ( !m_manualPartitionPage ) { - m_manualPartitionPage = new PartitionPage( m_core, *m_config ); + m_manualPartitionPage = new PartitionPage( m_core ); m_widget->addWidget( m_manualPartitionPage ); } @@ -463,6 +450,63 @@ PartitionViewStep::isAtEnd() const void PartitionViewStep::onActivate() { + + auto gs = Calamares::JobQueue::instance()->globalStorage(); + + if ( PartUtils::isEfiSystem() && !m_config->bootloaderVar().isEmpty() ) + { + // Alter GS based on prior module + QString efiLocation; + bool efiChanged = false; + bool luksChanged = false; + if ( gs->contains( m_config->bootloaderVar() ) ) + { + m_bootloader = gs->value( m_config->bootloaderVar() ).toString(); + gs->insert( "curBootloader", m_bootloader ); + + cDebug() << "The bootloader is " << m_bootloader; + if ( m_bootloader.toLower() == "grub" ) + { + efiLocation = "/boot/efi"; + } + else if ( m_bootloader.toLower() == "refind" ) + { + efiLocation = "/boot"; + } + else + { + efiLocation = "/efi"; + } + cDebug() << "The efi location is " << efiLocation; + + if ( gs->contains( "efiSystemPartition" ) && gs->value( "efiSystemPartition" ).toString() != efiLocation ) + { + efiChanged = true; + } + gs->insert( "efiSystemPartition", efiLocation ); + } + + + // Set the luks type + Config::LuksGeneration currentLuks = m_config->luksFileSystemType(); + const Config::LuksGeneration newLuks + = m_bootloader == "grub" ? Config::LuksGeneration::Luks1 : Config::LuksGeneration::Luks2; + + if ( newLuks != currentLuks ) + { + m_config->setLuksFileSystemType( newLuks ); + gs->insert( "luksFileSystemType", Config::luksGenerationNames().find( newLuks ) ); + luksChanged = true; + } + + // This may not be our first trip so reset things if needed + if ( m_core->isDirty() && ( luksChanged || efiChanged ) ) + { + m_core->revertAllDevices(); + m_choicePage->reset(); + } + } + m_config->fillGSSecondaryConfiguration(); // if we're coming back to PVS from the next VS @@ -473,12 +517,6 @@ PartitionViewStep::onActivate() } } -static QString -listItem( QString s ) -{ - return s.prepend( QStringLiteral( "
  • " ) ).append( QStringLiteral( "
  • " ) ); -} - static bool shouldWarnForGPTOnBIOS( const PartitionCoreModule* core ) { @@ -498,7 +536,7 @@ shouldWarnForGPTOnBIOS( const PartitionCoreModule* core ) if ( table && table->type() == PartitionTable::TableType::gpt ) { // So this is a BIOS system, and the bootloader will be installed on a GPT system - for ( const auto& partition : std::as_const( table->children() ) ) + for ( const auto& partition : qAsConst( table->children() ) ) { using Calamares::Units::operator""_MiB; if ( ( partition->activeFlags() & KPM_PARTITION_FLAG( BiosGrub ) ) @@ -542,146 +580,50 @@ shouldWarnForNotEncryptedBoot( const Config* config, const PartitionCoreModule* return false; } -static PartitionViewStep::FSConflictEntry -calcFSConflictEntry( PartitionCoreModule* core, PartitionModel* partModel, QModelIndex partFsIdx, QModelIndex partMountPointIdx, QStringList mountPointList ) -{ - PartitionViewStep::FSConflictEntry result; - - QString partFs = partModel->data( partFsIdx ).toString().toLower(); - QString partMountPoint = partModel->data( partMountPointIdx ).toString(); - FileSystem::Type fsType; - PartUtils::canonicalFilesystemName( partFs, &fsType ); - bool fsTypeIsAllowed = false; - if ( fsType == FileSystem::Type::Unknown ) - { - fsTypeIsAllowed = true; - } - else - { - QList< FileSystem::Type > allowedFsTypes = core->dirFSRestrictLayout().allowedFSTypes( partMountPoint, mountPointList, true ); - for ( const auto& allowedFsType : allowedFsTypes ) - { - if ( fsType == allowedFsType ) - { - fsTypeIsAllowed = true; - break; - } - } - } - - if ( !fsTypeIsAllowed ) - { - QString conflictedPath = core->dirFSRestrictLayout().diagnoseFSConflict( partMountPoint, fsType, mountPointList ); - QList< FileSystem::Type > nonConflictingFilesystemTypes = core->dirFSRestrictLayout().allowedFSTypes( conflictedPath, mountPointList, true ); - QStringList nonConflictingFilesystems; - for ( const auto& fsType : nonConflictingFilesystemTypes ) - { - nonConflictingFilesystems.append( Calamares::Partition::prettyNameForFileSystemType( fsType ) ); - } - result = PartitionViewStep::FSConflictEntry( partMountPoint, partFs, conflictedPath, nonConflictingFilesystems ); - } - - return result; -} - -static QList< PartitionViewStep::FSConflictEntry > -checkForFilesystemConflicts( PartitionCoreModule* core ) -{ - QList< PartitionViewStep::FSConflictEntry > result; - - DeviceModel* dm = core->deviceModel(); - QStringList mountPointList; - - // Walk the device and partition tree, extracting mountpoints from it - for ( int i = 0; i < dm->rowCount(); i++ ) - { - Device* dev = dm->deviceForIndex( dm->index( i ) ); - PartitionModel* pm = core->partitionModelForDevice( dev ); - - QModelIndex extPartMountPointIdx = QModelIndex(); - bool extPartFound = false; - for ( int j = 0; j < pm->rowCount(); j++ ) - { - QModelIndex partFsIdx = pm->index( j, PartitionModel::FileSystemColumn ); - QModelIndex partMountPointIdx = pm->index( j, PartitionModel::MountPointColumn ); - - if ( pm->data( partFsIdx ).toString().toLower() == "extended" ) - { - extPartFound = true; - extPartMountPointIdx = partMountPointIdx; - break; - } - - QString mountPoint = pm->data( partMountPointIdx ).toString(); - if ( !mountPoint.isEmpty() ) - { - mountPointList.append( mountPoint ); - } - } - if ( extPartFound ) - { - for ( int j = 0; j < pm->rowCount( extPartMountPointIdx ); j++ ) - { - QModelIndex partMountPointIdx = pm->index( j, PartitionModel::MountPointColumn, extPartMountPointIdx ); - QString mountPoint = pm->data( partMountPointIdx ).toString(); - if ( !mountPoint.isEmpty() ) - { - mountPointList.append( mountPoint ); - } - } - } - } - - // Walk the device and partition tree again, validating it this time - for ( int i = 0; i < dm->rowCount(); i++ ) - { - Device* dev = dm->deviceForIndex( dm->index( i ) ); - PartitionModel* pm = core->partitionModelForDevice( dev ); - - QModelIndex extPartFsIdx = QModelIndex(); - QModelIndex extPartMountPointIdx = QModelIndex(); - bool extPartFound = false; - - for ( int j = 0; j < pm->rowCount(); j++ ) - { - QModelIndex partFsIdx = pm->index( j, PartitionModel::FileSystemColumn ); - QModelIndex partMountPointIdx = pm->index( j, PartitionModel::MountPointColumn ); - - if ( pm->data( partFsIdx ).toString().toLower() == "extended" ) - { - extPartFound = true; - extPartFsIdx = partFsIdx; - extPartMountPointIdx = partMountPointIdx; - break; - } - - PartitionViewStep::FSConflictEntry conflictEntry = calcFSConflictEntry( core, pm, partFsIdx, partMountPointIdx, mountPointList ); - if ( !conflictEntry.conflictedPath.isEmpty() ) - { - result.append( conflictEntry ); - } - } - if ( extPartFound ) - { - for ( int j = 0; j < pm->rowCount( extPartFsIdx ); j++ ) - { - QModelIndex partFsIdx = pm->index( j, PartitionModel::FileSystemColumn, extPartFsIdx ); - QModelIndex partMountPointIdx = pm->index( j, PartitionModel::MountPointColumn, extPartMountPointIdx ); - PartitionViewStep::FSConflictEntry conflictEntry = calcFSConflictEntry( core, pm, partFsIdx, partMountPointIdx, mountPointList ); - if ( !conflictEntry.conflictedPath.isEmpty() ) - { - result.append( conflictEntry ); - } - } - } - } - - return result; -} - void PartitionViewStep::onLeave() { + auto gs = Calamares::JobQueue::instance()->globalStorage(); + + // Put the ESPs in global storage + if ( PartUtils::isEfiSystem() ) + { + QList< Partition* > efiSystemPartitions = m_core->efiSystemPartitions(); + QStringList espPaths; + for ( auto partition : efiSystemPartitions ) + { + if ( !partition->partitionPath().trimmed().isEmpty() ) + { + espPaths.append( partition->partitionPath() ); + } + } + gs->insert( "espList", espPaths ); + } + + // Check the size of the ESP for systemd-boot + if ( PartUtils::isEfiSystem() && m_bootloader.trimmed() == "systemd-boot" ) + { + const QString espMountPoint = gs->value( "efiSystemPartition" ).toString(); + Partition* esp = m_core->findPartitionByMountPoint( espMountPoint ); + + qint64 minEspSize = gs->value( "efiSystemPartitionMinSize_i" ).toLongLong(); + if ( esp != nullptr && esp->capacity() < minEspSize ) + { + QString minSizeString = gs->value( "efiSystemPartitionMinSize" ).toString(); + + QString message = tr( "EFI partition too small" ); + QString description = tr( "The size of the EFI partition is smaller than recommended " + "for systemd-boot. If you proceed with this partition size, " + "the installation may fail or the system may not boot. " + "The recommended minimum size is %1" ) + .arg( minSizeString ); + + QMessageBox mb( QMessageBox::Warning, message, description, QMessageBox::Ok, m_choicePage ); + Calamares::fixButtonLabels( &mb ); + mb.exec(); + } + } + if ( m_widget->currentWidget() == m_choicePage ) { m_choicePage->onLeave(); @@ -689,10 +631,6 @@ PartitionViewStep::onLeave() } const auto* branding = Calamares::Branding::instance(); - - const QString startList = QStringLiteral( "

      " ); - const QString endList = QStringLiteral( "


    " ); - if ( m_widget->currentWidget() == m_manualPartitionPage ) { if ( PartUtils::isEfiSystem() ) @@ -707,7 +645,6 @@ PartitionViewStep::onLeave() Logger::Once o; const bool okType = esp && PartUtils::isEfiFilesystemSuitableType( esp ); - const bool okRecommendedSize = esp && PartUtils::isEfiFilesystemRecommendedSize( esp ); const bool okMinimumSize = esp && PartUtils::isEfiFilesystemMinimumSize( esp ); const bool okFlag = esp && PartUtils::isEfiBootable( esp ); @@ -748,6 +685,12 @@ PartitionViewStep::onLeave() const QString possibleFail = tr( "You can continue with this EFI system " "partition configuration but your system may fail to start." ); + const QString startList = QStringLiteral( "

      " ); + const QString endList = QStringLiteral( "


    " ); + + auto listItem = []( QString s ) -> QString + { return s.prepend( QStringLiteral( "
  • " ) ).append( QStringLiteral( "
  • " ) ); }; + if ( !esp ) { cDebug() << o << "No ESP mounted"; @@ -777,11 +720,6 @@ PartitionViewStep::onLeave() description.append( endList ); description.append( mayFail ); } - else if ( !okRecommendedSize ) - { - message = tr( "EFI system partition recommendation" ); - description = genericRecommendationMessage + suggestConfiguredSize + possibleFail; - } if ( !message.isEmpty() ) { @@ -839,52 +777,6 @@ PartitionViewStep::onLeave() Calamares::fixButtonLabels( &mb ); mb.exec(); } - - QList< FSConflictEntry > conflictMap = checkForFilesystemConflicts( m_core ); - if ( !conflictMap.isEmpty() ) - { - QString message = tr( "Filesystem conflicts found" ); - const QString descHeader = tr( "The chosen manual partitioning layout does not " - "comply with the filesystem restrictions set by the " - "distro. The following issues were found:"); - - QStringList issueList; - for ( const auto& entry : conflictMap ) - { - QString buildString; - if ( entry.conflictedPath == "any" ) - { - buildString = tr( "The %1 directory uses filesystem %2, but this distro only allows the following filesystems: %3." ) - .arg( entry.conflictingPath ) - .arg( entry.conflictingFilesystem ) - .arg( entry.allowableFilesystems.join( ", " ) ); - issueList.append( buildString ); - } - else - { - buildString = tr( "The %1 directory uses filesystem %2, but the %3 directory must use one of the following filesystems: %4." ) - .arg( entry.conflictingPath ) - .arg( entry.conflictingFilesystem ) - .arg( entry.conflictedPath ) - .arg( entry.allowableFilesystems.join( ", " ) ); - issueList.append( buildString ); - } - } - - const QString descFooter = tr( "You can continue without setting up filesystems " - "properly, but your system may fail to start." ); - - QString description = descHeader + startList; - for ( const auto& item : issueList ) - { - description += listItem( item ); - } - description += endList + descFooter; - - QMessageBox mb( QMessageBox::Warning, message, description, QMessageBox::Ok, m_manualPartitionPage ); - Calamares::fixButtonLabels( &mb ); - mb.exec(); - } } } @@ -941,7 +833,6 @@ PartitionViewStep::setConfigurationMap( const QVariantMap& configurationMap ) m_future->setFuture( future ); m_core->partitionLayout().init( m_config->defaultFsType(), configurationMap.value( "partitionLayout" ).toList() ); - m_core->dirFSRestrictLayout().init( configurationMap.value( "directoryFilesystemRestrictions" ).toList() ); } Calamares::JobList diff --git a/src/modules/partition/PartitionViewStep.h b/src/modules/partition/PartitionViewStep.h index 8224154dd..3d5781477 100644 --- a/src/modules/partition/PartitionViewStep.h +++ b/src/modules/partition/PartitionViewStep.h @@ -39,21 +39,6 @@ class PLUGINDLLEXPORT PartitionViewStep : public Calamares::ViewStep Q_OBJECT public: - struct FSConflictEntry - { - QString conflictingPath; - QString conflictingFilesystem; - QString conflictedPath; - QStringList allowableFilesystems; - - FSConflictEntry(); - FSConflictEntry( const QString& conflictingPathArg, - const QString& conflictingFilesystemArg, - const QString& conflictedPathArg, - QStringList allowableFilesystemsArg ); - FSConflictEntry( const FSConflictEntry& e ) = default; - }; - explicit PartitionViewStep( QObject* parent = nullptr ); ~PartitionViewStep() override; @@ -81,6 +66,8 @@ public: Calamares::RequirementsList checkRequirements() override; + QString bootLoader() const { return m_bootloader; } + private: void initPartitionCoreModule(); void continueLoading(); @@ -97,6 +84,8 @@ private: WaitingWidget* m_waitingWidget; QFutureWatcher< void >* m_future; + + QString m_bootloader; }; CALAMARES_PLUGIN_FACTORY_DECLARATION( PartitionViewStepFactory ) diff --git a/src/modules/partition/core/ColorUtils.cpp b/src/modules/partition/core/ColorUtils.cpp index 6dc17be11..5136f6b8b 100644 --- a/src/modules/partition/core/ColorUtils.cpp +++ b/src/modules/partition/core/ColorUtils.cpp @@ -33,19 +33,19 @@ static const int NUM_NEW_PARTITION_COLORS = 4; //Let's try to use the Breeze palette static const QColor PARTITION_COLORS[ NUM_PARTITION_COLORS ] = { "#2980b9", //Dark Plasma Blue - "#27ae60", //Dark Icon Green - "#c9ce3b", //Dirty Yellow + "#7f3fbf", //Dark Purple + "#ff5454", //Orange "#3daee9", //Plasma Blue "#9b59b6", //Purple }; static const QColor NEW_PARTITION_COLORS[ NUM_NEW_PARTITION_COLORS ] = { "#c0392b", //Dark Icon Red - "#f39c1f", //Dark Icon Yellow - "#f1b7bc", //Light Salmon - "#fed999", //Light Orange + "#3b3b81", //Dark Blue + "#615c5d", //Light Salmon + "#ff8585", //Light Orange }; -static QColor FREE_SPACE_COLOR = "#777777"; -static QColor EXTENDED_COLOR = "#aaaaaa"; +static QColor FREE_SPACE_COLOR = "#6969ea"; +static QColor EXTENDED_COLOR = "#6e5151"; static QColor UNKNOWN_DISKLABEL_COLOR = "#4d4151"; static QMap< QString, QColor > s_partitionColorsCache; @@ -98,7 +98,7 @@ colorForPartition( Partition* partition ) if ( partition->fileSystem().supportGetUUID() != FileSystem::cmdSupportNone && !partition->fileSystem().uuid().isEmpty() ) { - if ( partition->fileSystem().type() == FileSystem::Luks || partition->fileSystem().type() == FileSystem::Luks2 ) + if ( partition->fileSystem().type() == FileSystem::Luks ) { FS::luks& luksFs = dynamic_cast< FS::luks& >( partition->fileSystem() ); if ( !luksFs.outerUuid().isEmpty() && s_partitionColorsCache.contains( luksFs.outerUuid() ) ) @@ -146,7 +146,7 @@ colorForPartition( Partition* partition ) if ( partition->fileSystem().supportGetUUID() != FileSystem::cmdSupportNone && !partition->fileSystem().uuid().isEmpty() ) { - if ( partition->fileSystem().type() == FileSystem::Luks || partition->fileSystem().type() == FileSystem::Luks2 ) + if ( partition->fileSystem().type() == FileSystem::Luks ) { FS::luks& luksFs = dynamic_cast< FS::luks& >( partition->fileSystem() ); if ( !luksFs.outerUuid().isEmpty() ) diff --git a/src/modules/partition/core/KPMHelpers.h b/src/modules/partition/core/KPMHelpers.h index b8e6fca18..3ceafb003 100644 --- a/src/modules/partition/core/KPMHelpers.h +++ b/src/modules/partition/core/KPMHelpers.h @@ -149,19 +149,6 @@ execute( Operation&& operation, const QString& failureMessage ) return execute( operation, failureMessage ); } -/** @brief Is this an MSDOS partition table? - * - * Deals with KPMcore deprecations in the TableType enum. - */ -inline bool isMSDOSPartition(PartitionTable::TableType t) -{ -#if WITH_KPMcore > 0x240801 - return t == PartitionTable::TableType::msdos; -#else - return t == PartitionTable::TableType::msdos || t == PartitionTable::TableType::msdos_sectorbased; -#endif -} - } // namespace KPMHelpers #endif /* KPMHELPERS_H */ diff --git a/src/modules/partition/core/PartUtils.cpp b/src/modules/partition/core/PartUtils.cpp index 8da0aee81..2c396498b 100644 --- a/src/modules/partition/core/PartUtils.cpp +++ b/src/modules/partition/core/PartUtils.cpp @@ -390,7 +390,7 @@ runOsprober( DeviceModel* dm ) } QString file, path = lineColumns.value( 0 ).simplified(); - if ( !path.startsWith( "/dev/" ) ) //basic sanity check + if ( !path.startsWith( "/dev/" ) ) // basic sanity check { continue; } @@ -512,7 +512,6 @@ isEfiFilesystemMinimumSize( const Partition* candidate ) return false; } } - bool isEfiBootable( const Partition* candidate ) { @@ -563,20 +562,24 @@ efiFilesystemMinimumSize() { const QString key = efiFilesystemMinimumSizeGSKey(); - qint64 uefisys_part_sizeB = efiFilesystemRecommendedSize(); + qint64 uefisys_part_sizeB = 0; // The default can be overridden; the key used here comes // from the partition module Config.cpp auto* gs = Calamares::JobQueue::instance()->globalStorage(); if ( gs->contains( key ) ) { - qint64 v = gs->value( key ).toLongLong(); - uefisys_part_sizeB = v > 0 ? v : 0; + // Ignore the minimum size when grub is the bootloader + if ( !gs->contains( "curBootloader" ) || gs->value( "curBootloader" ).toString().toLower() != "grub" ) + { + qint64 v = gs->value( key ).toLongLong(); + uefisys_part_sizeB = v > 0 ? v : 0; + } } + // There is a lower limit of what can be configured return std::max( uefisys_part_sizeB, efiSpecificationHardMinimumSize ); } - QString canonicalFilesystemName( const QString& fsName, FileSystem::Type* fsType ) { diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index ddfabaf85..e17947e55 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -108,7 +108,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO partType = isEfi ? PartitionTable::gpt : PartitionTable::msdos; } // last usable sector possibly allowing for secondary GPT using 66 sectors (256 entries) - const qint64 lastUsableSector = dev->totalLogical() - ( partType == PartitionTable::gpt ? 67 : 1 ); + qint64 lastSectorForRoot = dev->totalLogical() - (partType == PartitionTable::gpt ? 67 : 1); // Looking up the defaultFsType (which should name a filesystem type) // will log an error and set the type to Unknown if there's something wrong. @@ -154,7 +154,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO const quint64 sectorSize = quint64( dev->logicalSize() ); if ( mayCreateSwap ) { - quint64 availableSpaceB = quint64( lastUsableSector - firstFreeSector + 1 ) * sectorSize; + quint64 availableSpaceB = quint64( dev->totalLogical() - firstFreeSector ) * sectorSize; suggestedSwapSizeB = swapSuggestion( availableSpaceB, o.swap ); // Space required by this installation is what the distro claims is needed // (via global configuration) plus the swap size plus a fudge factor of @@ -165,7 +165,6 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO shouldCreateSwap = availableSpaceB > requiredSpaceB; } - qint64 lastSectorForRoot = lastUsableSector; if ( shouldCreateSwap ) { lastSectorForRoot -= suggestedSwapSizeB / sectorSize + 1; @@ -184,7 +183,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO FileSystem::LinuxSwap, QStringLiteral( "swap" ), lastSectorForRoot + 1, - lastUsableSector, + dev->totalLogical() - 1, KPM_PARTITION_FLAG( None ) ); } else @@ -195,7 +194,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO FileSystem::LinuxSwap, QStringLiteral( "swap" ), lastSectorForRoot + 1, - lastUsableSector, + dev->totalLogical() - 1, o.luksFsType, o.luksPassphrase, KPM_PARTITION_FLAG( None ) ); @@ -214,6 +213,8 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO void doReplacePartition( PartitionCoreModule* core, Device* dev, Partition* partition, Choices::ReplacePartitionOptions o ) { + Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); + qint64 firstSector, lastSector; cDebug() << "doReplacePartition for device" << partition->partitionPath(); @@ -252,7 +253,36 @@ doReplacePartition( PartitionCoreModule* core, Device* dev, Partition* partition core->deletePartition( dev, partition ); } - core->layoutApply( dev, firstSector, lastSector, o.luksFsType, o.luksPassphrase ); + qint64 newFirstSector = firstSector; + if ( o.newEfiPartition && PartUtils::isEfiSystem() ) + { + qint64 uefisys_part_sizeB = PartUtils::efiFilesystemRecommendedSize(); + qint64 efiSectorCount = Calamares::bytesToSectors( uefisys_part_sizeB, dev->logicalSize() ); + Q_ASSERT( efiSectorCount > 0 ); + + // Since sectors count from 0, and this partition is created starting + // at firstFreeSector, we need efiSectorCount sectors, numbered + // firstFreeSector..firstFreeSector+efiSectorCount-1. + qint64 lastSector = newFirstSector + efiSectorCount - 1; + Partition* efiPartition = KPMHelpers::createNewPartition( dev->partitionTable(), + *dev, + PartitionRole( PartitionRole::Primary ), + FileSystem::Fat32, + QString(), + newFirstSector, + lastSector, + KPM_PARTITION_FLAG( None ) ); + PartitionInfo::setFormat( efiPartition, true ); + PartitionInfo::setMountPoint( efiPartition, gs->value( "efiSystemPartition" ).toString() ); + if ( gs->contains( "efiSystemPartitionName" ) ) + { + efiPartition->setLabel( gs->value( "efiSystemPartitionName" ).toString() ); + } + core->createPartition( dev, efiPartition, KPM_PARTITION_FLAG_ESP ); + newFirstSector = lastSector + 1; + } + + core->layoutApply( dev, newFirstSector, lastSector, o.luksFsType, o.luksPassphrase ); core->dumpQueue(); } diff --git a/src/modules/partition/core/PartitionActions.h b/src/modules/partition/core/PartitionActions.h index 24969bb43..328f6ec02 100644 --- a/src/modules/partition/core/PartitionActions.h +++ b/src/modules/partition/core/PartitionActions.h @@ -27,21 +27,26 @@ namespace PartitionActions */ namespace Choices { + struct ReplacePartitionOptions { QString defaultPartitionTableType; // e.g. "gpt" or "msdos" QString defaultFsType; // e.g. "ext4" or "btrfs" Config::LuksGeneration luksFsType = Config::LuksGeneration::Luks1; // optional ("luks", "luks2") QString luksPassphrase; // optional + bool newEfiPartition; ReplacePartitionOptions( const QString& pt, const QString& fs, Config::LuksGeneration luksFs, - const QString& passphrase ) + const QString& passphrase, + const bool& newEsp + ) : defaultPartitionTableType( pt ) , defaultFsType( fs ) , luksFsType( luksFs ) , luksPassphrase( passphrase ) + , newEfiPartition( newEsp ) { } }; @@ -59,7 +64,7 @@ struct AutoPartitionOptions : ReplacePartitionOptions const QString& efi, qint64 requiredBytes, Config::SwapChoice s ) - : ReplacePartitionOptions( pt, fs, luksFs, passphrase ) + : ReplacePartitionOptions( pt, fs, luksFs, passphrase, false ) , efiPartitionMountPoint( efi ) , requiredSpaceB( requiredBytes > 0 ? quint64( requiredBytes ) : 0U ) , swap( s ) diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index c2fd61db9..fe6824961 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -619,7 +619,7 @@ findEssentialLVs( const QList< PartitionCoreModule::DeviceInfo* >& infos ) continue; } - for ( const auto& j : std::as_const( info->jobs() ) ) + for ( const auto& j : qAsConst( info->jobs() ) ) { FormatPartitionJob* format = dynamic_cast< FormatPartitionJob* >( j.data() ); if ( format ) @@ -1221,3 +1221,12 @@ PartitionCoreModule::createSummaryInfo() const } return lst; } + +void +PartitionCoreModule::removeEspMounts() +{ + for ( auto const partition : qAsConst( m_efiSystemPartitions ) ) + { + PartitionInfo::setMountPoint( partition, QString() ); + } +} diff --git a/src/modules/partition/core/PartitionCoreModule.h b/src/modules/partition/core/PartitionCoreModule.h index 08b92abab..80877d88a 100644 --- a/src/modules/partition/core/PartitionCoreModule.h +++ b/src/modules/partition/core/PartitionCoreModule.h @@ -16,7 +16,6 @@ #include "core/KPMHelpers.h" #include "core/PartitionLayout.h" #include "core/PartitionModel.h" -#include "core/DirFSRestrictLayout.h" #include "jobs/PartitionJob.h" #include "Job.h" @@ -120,6 +119,8 @@ public: //FIXME: make this horrible method private. -- Teo 12/2015 Device* immutableDeviceCopy( const Device* device ); + void removeEspMounts(); + /** * @brief bootLoaderModel returns a model which represents the available boot * loader locations. @@ -168,9 +169,6 @@ public: */ PartitionLayout& partitionLayout() { return m_partLayout; } - /// @brief Get the directory filesystem restriction layout. - DirFSRestrictLayout& dirFSRestrictLayout() { return m_dirFSRestrictLayout; } - void layoutApply( Device* dev, qint64 firstSector, qint64 lastSector, @@ -274,7 +272,6 @@ private: bool m_isDirty = false; QString m_bootLoaderInstallPath; PartitionLayout m_partLayout; - DirFSRestrictLayout m_dirFSRestrictLayout; OsproberEntryList m_osproberLines; diff --git a/src/modules/partition/core/PartitionLayout.cpp b/src/modules/partition/core/PartitionLayout.cpp index ff049784a..b476a3181 100644 --- a/src/modules/partition/core/PartitionLayout.cpp +++ b/src/modules/partition/core/PartitionLayout.cpp @@ -221,7 +221,7 @@ PartitionLayout::createPartitions( Device* dev, // Let's check if we have enough space for each partitions, using the size // propery or the min-size property if unit is in percentage. - for ( const auto& entry : std::as_const( m_partLayout ) ) + for ( const auto& entry : qAsConst( m_partLayout ) ) { if ( !entry.partSize.isValid() ) { @@ -250,7 +250,7 @@ PartitionLayout::createPartitions( Device* dev, if ( availableSectors < 0 ) { availableSectors = totalSectors; - for ( const auto& entry : std::as_const( m_partLayout ) ) + for ( const auto& entry : qAsConst( m_partLayout ) ) { qint64 sectors = partSectorsMap.value( &entry ); if ( entry.partMinSize.isValid() ) @@ -263,7 +263,7 @@ PartitionLayout::createPartitions( Device* dev, } // Assign sectors for percentage-defined partitions. - for ( const auto& entry : std::as_const( m_partLayout ) ) + for ( const auto& entry : qAsConst( m_partLayout ) ) { if ( entry.partSize.unit() == Calamares::Partition::SizeUnit::Percent ) { @@ -286,7 +286,7 @@ PartitionLayout::createPartitions( Device* dev, // Create the partitions. currentSector = firstSector; availableSectors = totalSectors; - for ( const auto& entry : std::as_const( m_partLayout ) ) + for ( const auto& entry : qAsConst( m_partLayout ) ) { // Adjust partition size based on available space. qint64 sectors = partSectorsMap.value( &entry ); diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index a7665bbbc..75dd4848a 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -34,7 +34,6 @@ #include "Branding.h" #include "GlobalStorage.h" #include "JobQueue.h" -#include "compat/CheckBox.h" #include "partition/PartitionIterator.h" #include "partition/PartitionQuery.h" #include "utils/Gui.h" @@ -188,7 +187,7 @@ ChoicePage::init( PartitionCoreModule* core ) connect( m_drivesCombo, qOverload< int >( &QComboBox::currentIndexChanged ), this, &ChoicePage::applyDeviceChoice ); connect( m_encryptWidget, &EncryptWidget::stateChanged, this, &ChoicePage::onEncryptWidgetStateChanged ); - connect( m_reuseHomeCheckBox, Calamares::checkBoxStateChangedSignal, this, &ChoicePage::onHomeCheckBoxStateChanged ); + connect( m_reuseHomeCheckBox, &QCheckBox::stateChanged, this, &ChoicePage::onHomeCheckBoxStateChanged ); ChoicePage::applyDeviceChoice(); } @@ -353,6 +352,12 @@ ChoicePage::setupChoices() updateChoiceButtonsTr(); } +bool +ChoicePage::isNewEfiSelected() const +{ + return m_efiComboBox && m_efiNewIndex != -1 && m_efiComboBox->currentIndex() == m_efiNewIndex; +} + /** * @brief ChoicePage::selectedDevice queries the device picker (which may be a combo or * a list view) to get a pointer to the currently selected Device. @@ -362,8 +367,7 @@ ChoicePage::setupChoices() Device* ChoicePage::selectedDevice() { - Device* const currentDevice - = m_core->deviceModel()->deviceForIndex( m_core->deviceModel()->index( m_drivesCombo->currentIndex() ) ); + Device* const currentDevice = m_core->deviceModel()->deviceForIndex( m_core->deviceModel()->index( m_drivesCombo->currentIndex() ) ); return currentDevice; } @@ -586,21 +590,8 @@ ChoicePage::applyActionChoice( InstallChoice choice ) &ChoicePage::doAlongsideSetupSplitter, Qt::UniqueConnection ); break; - case InstallChoice::Manual: - if ( m_core->isDirty() ) - { - ScanningDialog::run( - QtConcurrent::run( - [ = ] - { - QMutexLocker locker( &m_coreMutex ); - m_core->revertDevice( selectedDevice() ); - } ), - [] {}, - this ); - } - break; case InstallChoice::NoChoice: + case InstallChoice::Manual: break; } updateNextEnabled(); @@ -686,6 +677,17 @@ ChoicePage::onHomeCheckBoxStateChanged() } } +int +ChoicePage::efiIndex() +{ + if ( !m_efiComboBox ) + { + return 0; + } + + return m_efiComboBox->currentIndex(); +} + void ChoicePage::onLeave() { @@ -703,22 +705,29 @@ ChoicePage::onLeave() || m_config->installChoice() == InstallChoice::Replace ) ) { QList< Partition* > efiSystemPartitions = m_core->efiSystemPartitions(); - if ( efiSystemPartitions.count() == 1 ) + if ( !isNewEfiSelected() ) { - PartitionInfo::setMountPoint( - efiSystemPartitions.first(), - Calamares::JobQueue::instance()->globalStorage()->value( "efiSystemPartition" ).toString() ); - } - else if ( efiSystemPartitions.count() > 1 && m_efiComboBox ) - { - PartitionInfo::setMountPoint( - efiSystemPartitions.at( m_efiComboBox->currentIndex() ), - Calamares::JobQueue::instance()->globalStorage()->value( "efiSystemPartition" ).toString() ); - } - else - { - cError() << "cannot set up EFI system partition.\nESP count:" << efiSystemPartitions.count() - << "\nm_efiComboBox:" << m_efiComboBox; + Partition* part = nullptr; + for ( auto const partition : qAsConst( efiSystemPartitions ) ) + { + if ( partition->partitionPath() == m_efiComboBox->currentText() ) + { + part = partition; + break; + } + } + + if ( part != nullptr ) + { + m_core->removeEspMounts(); + PartitionInfo::setMountPoint( + part, Calamares::JobQueue::instance()->globalStorage()->value( "efiSystemPartition" ).toString() ); + } + else + { + // This should never happen + cError() << "No valid efi partition found matching the selected partition" << Qt::endl; + } } } else // installPath is then passed to the bootloader module for MBR setup @@ -756,6 +765,8 @@ ChoicePage::doAlongsideApply() Q_ASSERT( m_afterPartitionSplitterWidget->splitPartitionSize() >= 0 ); Q_ASSERT( m_afterPartitionSplitterWidget->newPartitionSize() >= 0 ); + auto gs = Calamares::JobQueue::instance()->globalStorage(); + QMutexLocker locker( &m_coreMutex ); QString path = m_beforePartitionBarsView->selectionModel() @@ -776,8 +787,40 @@ ChoicePage::doAlongsideApply() = firstSector + m_afterPartitionSplitterWidget->splitPartitionSize() / dev->logicalSize(); m_core->resizePartition( dev, candidate, firstSector, newLastSector ); + + qint64 firstFreeSector = newLastSector + 2; + + // Add an EFI partition if required + if ( PartUtils::isEfiSystem() && isNewEfiSelected() ) + { + qint64 uefisys_part_sizeB = PartUtils::efiFilesystemRecommendedSize(); + qint64 efiSectorCount = Calamares::bytesToSectors( uefisys_part_sizeB, dev->logicalSize() ); + Q_ASSERT( efiSectorCount > 0 ); + + // Since sectors count from 0, and this partition is created starting + // at firstFreeSector, we need efiSectorCount sectors, numbered + // firstFreeSector..firstFreeSector+efiSectorCount-1. + qint64 lastSector = firstFreeSector + efiSectorCount - 1; + Partition* efiPartition = KPMHelpers::createNewPartition( dev->partitionTable(), + *dev, + PartitionRole( PartitionRole::Primary ), + FileSystem::Fat32, + QString(), + firstFreeSector, + lastSector, + KPM_PARTITION_FLAG( None ) ); + PartitionInfo::setFormat( efiPartition, true ); + m_core->removeEspMounts(); + PartitionInfo::setMountPoint( efiPartition, gs->value( "efiSystemPartition" ).toString() ); + if ( gs->contains( "efiSystemPartitionName" ) ) + { + efiPartition->setLabel( gs->value( "efiSystemPartitionName" ).toString() ); + } + m_core->createPartition( dev, efiPartition, KPM_PARTITION_FLAG_ESP ); + firstFreeSector = lastSector + 1; + } m_core->layoutApply( dev, - newLastSector + 2, + firstFreeSector, oldLastSector, m_config->luksFileSystemType(), m_encryptWidget->passphrase(), @@ -827,6 +870,13 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current ) m_core->revertDevice( selectedDevice() ); } + if ( m_isEfi && m_efiComboBox->count() == 0 ) + { + m_inOnReplace = true; + setupEfiSystemPartitionSelector(); + m_inOnReplace = false; + } + // if the partition is unallocated(free space), we don't replace it but create new one // with the same first and last sector Partition* selectedPartition @@ -836,6 +886,9 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current ) //NOTE: if the selected partition is free space, we don't deal with // a separate /home partition at all because there's no existing // rootfs to read it from. + + Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); + PartitionRole newRoles = PartitionRole( PartitionRole::Primary ); PartitionNode* newParent = selectedDevice()->partitionTable(); @@ -849,8 +902,38 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current ) } } - m_core->layoutApply( selectedDevice(), - selectedPartition->firstSector(), + auto dev = selectedDevice(); + qint64 newFirstSector = selectedPartition->firstSector(); + if ( isNewEfiSelected() && PartUtils::isEfiSystem() ) + { + qint64 uefisys_part_sizeB = PartUtils::efiFilesystemRecommendedSize(); + qint64 efiSectorCount = Calamares::bytesToSectors( uefisys_part_sizeB, dev->logicalSize() ); + Q_ASSERT( efiSectorCount > 0 ); + + // Since sectors count from 0, and this partition is created starting + // at firstFreeSector, we need efiSectorCount sectors, numbered + // firstFreeSector..firstFreeSector+efiSectorCount-1. + qint64 lastSector = newFirstSector + efiSectorCount - 1; + Partition* efiPartition + = KPMHelpers::createNewPartition( dev->partitionTable(), + *dev, + PartitionRole( PartitionRole::Primary ), + FileSystem::Fat32, + QString(), + newFirstSector, + lastSector, + KPM_PARTITION_FLAG( None ) ); + PartitionInfo::setFormat( efiPartition, true ); + PartitionInfo::setMountPoint( efiPartition, gs->value( "efiSystemPartition" ).toString() ); + if ( gs->contains( "efiSystemPartitionName" ) ) + { + efiPartition->setLabel( gs->value( "efiSystemPartitionName" ).toString() ); + } + m_core->createPartition( dev, efiPartition, KPM_PARTITION_FLAG_ESP ); + newFirstSector = lastSector + 1; + } + m_core->layoutApply( dev, + newFirstSector, selectedPartition->lastSector(), m_config->luksFileSystemType(), m_encryptWidget->passphrase(), @@ -888,7 +971,8 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current ) { gs->value( "defaultPartitionType" ).toString(), m_config->replaceModeFilesystem(), m_config->luksFileSystemType(), - m_encryptWidget->passphrase() } ); + m_encryptWidget->passphrase(), + isNewEfiSelected() } ); Partition* homePartition = findPartitionByPath( { selectedDevice() }, *homePartitionPath ); if ( homePartition && doReuseHomePartition ) @@ -919,7 +1003,6 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current ) { setupEfiSystemPartitionSelector(); } - updateNextEnabled(); if ( !m_bootloaderComboBox.isNull() && m_bootloaderComboBox->currentIndex() < 0 ) { @@ -1046,10 +1129,9 @@ ChoicePage::updateActionChoicePreview( InstallChoice choice ) if ( m_enableEncryptionWidget ) { m_encryptWidget->show(); - if ( m_config->preCheckEncryption() && !m_preCheckActivated ) + if ( m_config->preCheckEncryption() ) { m_encryptWidget->setEncryptionCheckbox( true ); - m_preCheckActivated = true; } } m_previewBeforeLabel->setText( tr( "Current:", "@label" ) ); @@ -1106,10 +1188,9 @@ ChoicePage::updateActionChoicePreview( InstallChoice choice ) if ( shouldShowEncryptWidget( choice ) ) { m_encryptWidget->show(); - if ( m_config->preCheckEncryption() && !m_preCheckActivated ) + if ( m_config->preCheckEncryption() ) { m_encryptWidget->setEncryptionCheckbox( true ); - m_preCheckActivated = true; } } m_previewBeforeLabel->setText( tr( "Current:", "@label" ) ); @@ -1183,6 +1264,7 @@ ChoicePage::updateActionChoicePreview( InstallChoice choice ) efiLayout->addWidget( m_efiComboBox ); m_efiLabel->setBuddy( m_efiComboBox ); m_efiComboBox->hide(); + connect( m_efiComboBox, &QComboBox::currentTextChanged, this, &ChoicePage::onEficomboTextChanged ); efiLayout->addStretch(); } @@ -1211,41 +1293,58 @@ ChoicePage::setupEfiSystemPartitionSelector() { Q_ASSERT( m_isEfi ); + // Ensure the EFI selector is not already configured + if ( m_efiComboBox->count() > 0 ) + { + return; + } + + auto gs = Calamares::JobQueue::instance()->globalStorage(); + + m_efiNewIndex = -1; + // Only the already existing ones: QList< Partition* > efiSystemPartitions = m_core->efiSystemPartitions(); - if ( efiSystemPartitions.count() == 0 ) //should never happen + m_efiLabel->setText( tr( "EFI system partition:", "@label" ) ); + for ( int i = 0; i < efiSystemPartitions.count(); ++i ) { - m_efiLabel->setText( tr( "An EFI system partition cannot be found anywhere " - "on this system. Please go back and use manual " - "partitioning to set up %1.", - "@info, %1 is product name" ) - .arg( Calamares::Branding::instance()->shortProductName() ) ); - updateNextEnabled(); - } - else if ( efiSystemPartitions.count() == 1 ) //probably most usual situation - { - m_efiLabel->setText( tr( "The EFI system partition at %1 will be used for " - "starting %2.", - "@info, %1 is partition path, %2 is product name" ) - .arg( efiSystemPartitions.first()->partitionPath() ) - .arg( Calamares::Branding::instance()->shortProductName() ) ); - } - else - { - m_efiComboBox->show(); - m_efiLabel->setText( tr( "EFI system partition:", "@label" ) ); - for ( int i = 0; i < efiSystemPartitions.count(); ++i ) + Partition* efiPartition = efiSystemPartitions.at( i ); + if ( gs->contains( "curBootloader" ) + && gs->value( "curBootloader" ).toString().trimmed() == QStringLiteral( "systemd-boot" ) ) { - Partition* efiPartition = efiSystemPartitions.at( i ); - m_efiComboBox->addItem( efiPartition->partitionPath(), i ); - - // We pick an ESP on the currently selected device, if possible - if ( efiPartition->devicePath() == selectedDevice()->deviceNode() && efiPartition->number() == 1 ) + if ( efiPartition->capacity() < PartUtils::efiFilesystemMinimumSize() ) { - m_efiComboBox->setCurrentIndex( i ); + continue; } } + + m_efiComboBox->addItem( efiPartition->partitionPath() ); + + // We pick an ESP on the currently selected device, if possible + if ( efiPartition->devicePath() == selectedDevice()->deviceNode() && m_efiComboBox->currentIndex() < 0 ) + { + m_efiComboBox->setCurrentIndex( m_efiComboBox->findText( efiPartition->partitionPath() ) ); + } + } + m_efiComboBox->addItem( tr( "New" ) ); + m_efiNewIndex = m_efiComboBox->count() - 1; + + m_efiComboBox->show(); + + // Ensure the combobox has something selected + if ( m_efiComboBox->currentIndex() < 0 ) + { + m_efiComboBox->setCurrentIndex( 0 ); + } +} + +void +ChoicePage::onEficomboTextChanged( const QString& text ) +{ + if ( m_config->installChoice() == InstallChoice::Replace && !m_inOnReplace ) + { + doReplaceSelectedPartition( m_beforePartitionBarsView->selectionModel()->currentIndex() ); } } @@ -1718,6 +1817,29 @@ ChoicePage::shouldShowEncryptWidget( Config::InstallChoice choice ) const return suitableChoice && m_enableEncryptionWidget && suitableFS; } +void +ChoicePage::reset() +{ + m_grp->setExclusive( false ); + if ( m_alongsideButton->isChecked() ) + { + m_alongsideButton->setChecked( false ); + } + if ( m_eraseButton->isChecked() ) + { + m_eraseButton->setChecked( false ); + } + if ( m_replaceButton->isChecked() ) + { + m_replaceButton->setChecked( false ); + } + if ( m_somethingElseButton->isChecked() ) + { + m_somethingElseButton->setChecked( false ); + } + m_grp->setExclusive( true ); +} + void ChoicePage::updateActionDescriptionsTr() { @@ -1803,8 +1925,7 @@ ChoicePage::updateActionDescriptionsTr() "currently present on the selected storage device." ) ); m_replaceButton->setText( tr( "Replace a partition
    " - "Replaces a partition with %1." ) - .arg( Calamares::Branding::instance()->shortVersionedName() ) ); + "Replaces a partition with %1." ) ); } if ( m_osproberEntriesCount < 0 ) { diff --git a/src/modules/partition/gui/ChoicePage.h b/src/modules/partition/gui/ChoicePage.h index 6a777e20d..3272c7349 100644 --- a/src/modules/partition/gui/ChoicePage.h +++ b/src/modules/partition/gui/ChoicePage.h @@ -87,6 +87,8 @@ public: int lastSelectedDeviceIndex(); void setLastSelectedDeviceIndex( int index ); + int efiIndex(); + void reset(); signals: void nextStatusChanged( bool ); @@ -111,6 +113,7 @@ private: bool calculateNextEnabled() const; void updateNextEnabled(); void setupChoices(); + bool isNewEfiSelected() const; void checkInstallChoiceRadioButton( Config::InstallChoice choice ); ///< Sets the chosen button to "on" /** @brief Create a panel with "boot loader location:" * @@ -133,6 +136,8 @@ private: void doAlongsideApply(); void setupEfiSystemPartitionSelector(); + void onEficomboTextChanged(const QString &text); + // Translations support void updateSwapChoicesTr(); void updateChoiceButtonsTr(); @@ -173,9 +178,14 @@ private: QString m_osproberOneEntryName; bool m_enableEncryptionWidget = false; - bool m_preCheckActivated = false; QMutex m_coreMutex; + + int m_efiNewIndex = -1; + + QString m_bootLoader; + + bool m_inOnReplace = false; }; #endif // CHOICEPAGE_H diff --git a/src/modules/partition/gui/CreatePartitionDialog.cpp b/src/modules/partition/gui/CreatePartitionDialog.cpp index 213f5c793..0bbb0083f 100644 --- a/src/modules/partition/gui/CreatePartitionDialog.cpp +++ b/src/modules/partition/gui/CreatePartitionDialog.cpp @@ -18,7 +18,6 @@ #include "core/KPMHelpers.h" #include "core/PartUtils.h" #include "core/PartitionInfo.h" -#include "core/PartitionCoreModule.h" #include "gui/PartitionDialogHelpers.h" #include "gui/PartitionSizeController.h" @@ -34,7 +33,6 @@ #include #include #include -#include #include #include @@ -47,14 +45,18 @@ using Calamares::Partition::untranslatedFS; using Calamares::Partition::userVisibleFS; -CreatePartitionDialog::CreatePartitionDialog( PartitionCoreModule* core, - Device* device, +static QSet< FileSystem::Type > s_unmountableFS( { FileSystem::Unformatted, + FileSystem::LinuxSwap, + FileSystem::Extended, + FileSystem::Unknown, + FileSystem::Lvm2_PV } ); + +CreatePartitionDialog::CreatePartitionDialog( Device* device, PartitionNode* parentPartition, const QStringList& usedMountPoints, QWidget* parentWidget ) : QDialog( parentWidget ) , m_ui( new Ui_CreatePartitionDialog ) - , m_core( core ) , m_partitionSizeController( new PartitionSizeController( this ) ) , m_device( device ) , m_parent( parentPartition ) @@ -79,7 +81,8 @@ CreatePartitionDialog::CreatePartitionDialog( PartitionCoreModule* core, m_ui->lvNameLineEdit->setValidator( validator ); } - if ( KPMHelpers::isMSDOSPartition( device->partitionTable()->type() ) ) + if ( device->partitionTable()->type() == PartitionTable::msdos + || device->partitionTable()->type() == PartitionTable::msdos_sectorbased ) { initMbrPartitionTypeUi(); } @@ -125,23 +128,17 @@ CreatePartitionDialog::CreatePartitionDialog( PartitionCoreModule* core, this, &CreatePartitionDialog::checkMountPointSelection ); - connect( m_ui->fsComboBox, - &QComboBox::currentTextChanged, - this, - &CreatePartitionDialog::checkMountPointSelection ); - // Select a default m_ui->fsComboBox->setCurrentIndex( defaultFsIndex ); updateMountPointUi(); checkMountPointSelection(); } -CreatePartitionDialog::CreatePartitionDialog( PartitionCoreModule* core, - Device* device, +CreatePartitionDialog::CreatePartitionDialog( Device* device, const FreeSpace& freeSpacePartition, const QStringList& usedMountPoints, QWidget* parentWidget ) - : CreatePartitionDialog( core, device, freeSpacePartition.p->parent(), usedMountPoints, parentWidget ) + : CreatePartitionDialog( device, freeSpacePartition.p->parent(), usedMountPoints, parentWidget ) { standardMountPoints( *( m_ui->mountPointComboBox ), QString() ); setFlagList( *( m_ui->m_listFlags ), @@ -150,12 +147,11 @@ CreatePartitionDialog::CreatePartitionDialog( PartitionCoreModule* core, initPartResizerWidget( freeSpacePartition.p ); } -CreatePartitionDialog::CreatePartitionDialog( PartitionCoreModule* core, - Device* device, +CreatePartitionDialog::CreatePartitionDialog( Device* device, const FreshPartition& existingNewPartition, const QStringList& usedMountPoints, QWidget* parentWidget ) - : CreatePartitionDialog( core, device, existingNewPartition.p->parent(), usedMountPoints, parentWidget ) + : CreatePartitionDialog( device, existingNewPartition.p->parent(), usedMountPoints, parentWidget ) { standardMountPoints( *( m_ui->mountPointComboBox ), PartitionInfo::mountPoint( existingNewPartition.p ) ); setFlagList( *( m_ui->m_listFlags ), @@ -324,12 +320,6 @@ CreatePartitionDialog::updateMountPointUi() m_ui->encryptWidget->show(); m_ui->encryptWidget->reset(); } - else if ( FileSystemFactory::map()[ FileSystem::Type::Luks2 ]->supportCreate() - && FS::luks2::canEncryptType( type ) && !m_role.has( PartitionRole::Extended ) ) - { - m_ui->encryptWidget->show(); - m_ui->encryptWidget->reset(); - } else { m_ui->encryptWidget->reset(); @@ -347,10 +337,8 @@ CreatePartitionDialog::updateMountPointUi() void CreatePartitionDialog::checkMountPointSelection() { - validateMountPoint( m_core, - selectedMountPoint( m_ui->mountPointComboBox ), + validateMountPoint( selectedMountPoint( m_ui->mountPointComboBox ), m_usedMountPoints, - m_ui->fsComboBox->currentText(), m_ui->mountPointExplanation, m_ui->buttonBox->button( QDialogButtonBox::Ok ) ); } diff --git a/src/modules/partition/gui/CreatePartitionDialog.h b/src/modules/partition/gui/CreatePartitionDialog.h index 75a0da096..38c65aaf6 100644 --- a/src/modules/partition/gui/CreatePartitionDialog.h +++ b/src/modules/partition/gui/CreatePartitionDialog.h @@ -19,7 +19,7 @@ #include #include -class PartitionCoreModule; + class Device; class Partition; class PartitionNode; @@ -39,8 +39,7 @@ private: * * This does all the shared UI setup. */ - CreatePartitionDialog( PartitionCoreModule* core, - Device* device, + CreatePartitionDialog( Device* device, PartitionNode* parentPartition, const QStringList& usedMountPoints, QWidget* parentWidget ); @@ -60,8 +59,7 @@ public: * Creating from free space makes a wholly new partition with * no flags set at all. */ - CreatePartitionDialog( PartitionCoreModule* core, - Device* device, + CreatePartitionDialog( Device* device, const FreeSpace& freeSpacePartition, const QStringList& usedMountPoints, QWidget* parentWidget = nullptr ); @@ -70,8 +68,7 @@ public: * A partition previously newly created (e.g. via this dialog * and the constructor above) can be re-edited. */ - CreatePartitionDialog( PartitionCoreModule* core, - Device* device, + CreatePartitionDialog( Device* device, const FreshPartition& existingNewPartition, const QStringList& usedMountPoints, QWidget* parentWidget = nullptr ); @@ -87,7 +84,6 @@ private Q_SLOTS: private: QScopedPointer< Ui_CreatePartitionDialog > m_ui; - PartitionCoreModule* m_core; PartitionSizeController* m_partitionSizeController; Device* m_device; PartitionNode* m_parent; diff --git a/src/modules/partition/gui/DeviceInfoWidget.cpp b/src/modules/partition/gui/DeviceInfoWidget.cpp index 628560fa4..f57ed91d3 100644 --- a/src/modules/partition/gui/DeviceInfoWidget.cpp +++ b/src/modules/partition/gui/DeviceInfoWidget.cpp @@ -73,15 +73,7 @@ DeviceInfoWidget::retranslateUi() switch ( m_tableType ) { case PartitionTable::msdos: -#if WITH_KPMcore > 0x240801 - // Pick your warning: either deprecation warning, or unchecked enum-switch -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED -#endif case PartitionTable::msdos_sectorbased: -#if WITH_KPMcore > 0x240801 -QT_WARNING_POP -#endif typeString = "MBR"; toolTipString += tr( "

    This partition table type is only advisable on older " "systems which start from a BIOS boot " diff --git a/src/modules/partition/gui/EditExistingPartitionDialog.cpp b/src/modules/partition/gui/EditExistingPartitionDialog.cpp index 2b9b9405b..7a3f4951a 100644 --- a/src/modules/partition/gui/EditExistingPartitionDialog.cpp +++ b/src/modules/partition/gui/EditExistingPartitionDialog.cpp @@ -57,14 +57,12 @@ updateLabel( PartitionCoreModule* core, Device* device, Partition* partition, co } } -EditExistingPartitionDialog::EditExistingPartitionDialog( PartitionCoreModule* core, - Device* device, +EditExistingPartitionDialog::EditExistingPartitionDialog( Device* device, Partition* partition, const QStringList& usedMountPoints, QWidget* parentWidget ) : QDialog( parentWidget ) , m_ui( new Ui_EditExistingPartitionDialog ) - , m_core( core ) , m_device( device ) , m_partition( partition ) , m_partitionSizeController( new PartitionSizeController( this ) ) @@ -83,11 +81,6 @@ EditExistingPartitionDialog::EditExistingPartitionDialog( PartitionCoreModule* c this, &EditExistingPartitionDialog::checkMountPointSelection ); - connect( m_ui->fileSystemComboBox, - &QComboBox::currentTextChanged, - this, - &EditExistingPartitionDialog::checkMountPointSelection ); - // The filesystem label field is always enabled, because we may want to change // the label on the current filesystem without formatting. m_ui->fileSystemLabelEdit->setText( PartitionInfo::label( m_partition ) ); @@ -352,10 +345,8 @@ EditExistingPartitionDialog::updateMountPointPicker() void EditExistingPartitionDialog::checkMountPointSelection() { - if ( validateMountPoint( m_core, - selectedMountPoint( m_ui->mountPointComboBox ), + if ( validateMountPoint( selectedMountPoint( m_ui->mountPointComboBox ), m_usedMountPoints, - m_ui->fileSystemComboBox->currentText(), m_ui->mountPointExplanation, m_ui->buttonBox->button( QDialogButtonBox::Ok ) ) ) { diff --git a/src/modules/partition/gui/EditExistingPartitionDialog.h b/src/modules/partition/gui/EditExistingPartitionDialog.h index 8674b8b62..5d1e7fd65 100644 --- a/src/modules/partition/gui/EditExistingPartitionDialog.h +++ b/src/modules/partition/gui/EditExistingPartitionDialog.h @@ -37,8 +37,7 @@ public: Partition* p; }; - EditExistingPartitionDialog( PartitionCoreModule* core, - Device* device, + EditExistingPartitionDialog( Device* device, Partition* partition, const QStringList& usedMountPoints, QWidget* parentWidget = nullptr ); @@ -51,7 +50,6 @@ private slots: private: QScopedPointer< Ui_EditExistingPartitionDialog > m_ui; - PartitionCoreModule* m_core; Device* m_device; Partition* m_partition; PartitionSizeController* m_partitionSizeController; diff --git a/src/modules/partition/gui/EncryptWidget.cpp b/src/modules/partition/gui/EncryptWidget.cpp index 58c1f5143..ea0f57b29 100644 --- a/src/modules/partition/gui/EncryptWidget.cpp +++ b/src/modules/partition/gui/EncryptWidget.cpp @@ -60,8 +60,7 @@ EncryptWidget::EncryptWidget( QWidget* parent ) m_ui->m_encryptionUnsupportedLabel->show(); } - connect( - m_ui->m_encryptCheckBox, Calamares::checkBoxStateChangedSignal, this, &EncryptWidget::onCheckBoxStateChanged ); + connect( m_ui->m_encryptCheckBox, &QCheckBox::stateChanged, this, &EncryptWidget::onCheckBoxStateChanged ); connect( m_ui->m_passphraseLineEdit, &QLineEdit::textEdited, this, &EncryptWidget::onPassphraseEdited ); connect( m_ui->m_confirmLineEdit, &QLineEdit::textEdited, this, &EncryptWidget::onPassphraseEdited ); @@ -185,10 +184,13 @@ EncryptWidget::updateState( const bool notify ) Encryption newState = state(); - m_state = newState; - if ( notify ) + if ( newState != m_state ) { - Q_EMIT stateChanged( m_state ); + m_state = newState; + if ( notify ) + { + Q_EMIT stateChanged( m_state ); + } } } @@ -204,12 +206,12 @@ EncryptWidget::onPassphraseEdited() } void -EncryptWidget::onCheckBoxStateChanged( Calamares::checkBoxStateType checked ) +EncryptWidget::onCheckBoxStateChanged( int checked ) { - const bool visible = ( checked != Calamares::checkBoxUncheckedValue ); - m_ui->m_passphraseLineEdit->setVisible( visible ); - m_ui->m_confirmLineEdit->setVisible( visible ); - m_ui->m_iconLabel->setVisible( visible ); + // @p checked is a Qt::CheckState, 0 is "unchecked" and 2 is "checked" + m_ui->m_passphraseLineEdit->setVisible( checked ); + m_ui->m_confirmLineEdit->setVisible( checked ); + m_ui->m_iconLabel->setVisible( checked ); m_ui->m_passphraseLineEdit->clear(); m_ui->m_confirmLineEdit->clear(); m_ui->m_iconLabel->clear(); diff --git a/src/modules/partition/gui/EncryptWidget.h b/src/modules/partition/gui/EncryptWidget.h index 6f3db7532..c7cc23daa 100644 --- a/src/modules/partition/gui/EncryptWidget.h +++ b/src/modules/partition/gui/EncryptWidget.h @@ -13,8 +13,6 @@ #ifndef ENCRYPTWIDGET_H #define ENCRYPTWIDGET_H -#include "compat/CheckBox.h" - #include #include @@ -38,7 +36,7 @@ public: explicit EncryptWidget( QWidget* parent = nullptr ); - void setEncryptionCheckbox( bool preCheckEncrypt = false ); + void setEncryptionCheckbox( bool preCheckEncrypt = false); void reset( bool checkVisible = true ); bool isEncryptionCheckboxChecked(); @@ -61,7 +59,7 @@ signals: private: void updateState( const bool notify = true ); void onPassphraseEdited(); - void onCheckBoxStateChanged( Calamares::checkBoxStateType checked ); + void onCheckBoxStateChanged( int checked ); Ui::EncryptWidget* m_ui; Encryption m_state; diff --git a/src/modules/partition/gui/PartitionDialogHelpers.cpp b/src/modules/partition/gui/PartitionDialogHelpers.cpp index db1943a23..b41c12cc9 100644 --- a/src/modules/partition/gui/PartitionDialogHelpers.cpp +++ b/src/modules/partition/gui/PartitionDialogHelpers.cpp @@ -12,15 +12,12 @@ #include "PartitionDialogHelpers.h" #include "core/PartUtils.h" -#include "core/PartitionCoreModule.h" #include "gui/CreatePartitionDialog.h" #include "GlobalStorage.h" #include "JobQueue.h" #include "utils/Logger.h" -#include - #include #include #include @@ -84,7 +81,7 @@ setSelectedMountPoint( QComboBox& combo, const QString& selected ) } bool -validateMountPoint( PartitionCoreModule* core, const QString& mountPoint, const QStringList& inUse, const QString& fileSystem, QLabel* label, QPushButton* button ) +validateMountPoint( const QString& mountPoint, const QStringList& inUse, QLabel* label, QPushButton* button ) { QString msg; bool ok = true; @@ -98,58 +95,6 @@ validateMountPoint( PartitionCoreModule* core, const QString& mountPoint, const { msg = CreatePartitionDialog::tr( "Mountpoint must start with a /.", "@info" ); ok = false; - } else { - // Validate the chosen filesystem + mountpoint combination. - FileSystem::Type selectedFsType; - PartUtils::canonicalFilesystemName( fileSystem, &selectedFsType ); - bool fsTypeIsAllowed = false; - if ( selectedFsType == FileSystem::Type::Unknown ) - { - fsTypeIsAllowed = true; - } - else - { - QList< FileSystem::Type > anyAllowedFsTypes = core->dirFSRestrictLayout().anyAllowedFSTypes(); - for ( auto& anyAllowedFsType : anyAllowedFsTypes ) - { - if ( selectedFsType == anyAllowedFsType ) - { - fsTypeIsAllowed = true; - break; - } - } - } - - bool fsTypeIsAllowedForMountPoint = false; - // We allow arbitrary unmountable filesystems here since an - // unmountable filesystem has no mount point associated with it, thus - // any filesystem restriction we'd find at this point would be - // irrelevant. - if ( selectedFsType == FileSystem::Type::Unknown || s_unmountableFS.contains( selectedFsType ) ) - { - fsTypeIsAllowedForMountPoint = true; - } - else - { - QList< FileSystem::Type > allowedFsTypes = core->dirFSRestrictLayout().allowedFSTypes( mountPoint, inUse, false ); - for ( auto& allowedFsType : allowedFsTypes ) - { - if ( selectedFsType == allowedFsType ) - { - fsTypeIsAllowedForMountPoint = true; - break; - } - } - } - - if ( !fsTypeIsAllowed ) { - msg = CreatePartitionDialog::tr( "Filesystem is prohibited by this distro. Consider selecting another one.", "@info" ); - ok = true; - } - else if ( !fsTypeIsAllowedForMountPoint ) { - msg = CreatePartitionDialog::tr( "Filesystem is prohibited for use on this mountpoint. Consider selecting a different filesystem or mountpoint.", "@info" ); - ok = true; - } } if ( label ) diff --git a/src/modules/partition/gui/PartitionDialogHelpers.h b/src/modules/partition/gui/PartitionDialogHelpers.h index 4f77c3a71..eea0998c4 100644 --- a/src/modules/partition/gui/PartitionDialogHelpers.h +++ b/src/modules/partition/gui/PartitionDialogHelpers.h @@ -13,23 +13,14 @@ #define PARTITION_GUI_PARTITIONDIALOGHELPERS #include -#include #include -#include -class PartitionCoreModule; class QPushButton; class QComboBox; class QLabel; class QListWidget; -static QSet< FileSystem::Type > s_unmountableFS( { FileSystem::Unformatted, - FileSystem::LinuxSwap, - FileSystem::Extended, - FileSystem::Unknown, - FileSystem::Lvm2_PV } ); - /** * Returns a list of standard mount points (e.g. /, /usr, ...). * This also includes the EFI mount point if that is necessary @@ -77,7 +68,7 @@ setSelectedMountPoint( QComboBox* combo, const QString& selected ) * If it is not valid, returns @c false and sets the UI * to explain why. */ -bool validateMountPoint( PartitionCoreModule* core, const QString& mountPoint, const QStringList& inUse, const QString& fileSystem, QLabel* label, QPushButton* button ); +bool validateMountPoint( const QString& mountPoint, const QStringList& inUse, QLabel* label, QPushButton* button ); /** * Get the flags that have been checked in the list widget. diff --git a/src/modules/partition/gui/PartitionLabelsView.cpp b/src/modules/partition/gui/PartitionLabelsView.cpp index e338da252..cb9212d36 100644 --- a/src/modules/partition/gui/PartitionLabelsView.cpp +++ b/src/modules/partition/gui/PartitionLabelsView.cpp @@ -360,7 +360,7 @@ PartitionLabelsView::drawLabel( QPainter* painter, const QPoint& pos, bool selected ) { - painter->setPen( Qt::black ); + painter->setPen( Qt::gray ); int vertOffset = 0; int width = 0; for ( const QString& textLine : text ) diff --git a/src/modules/partition/gui/PartitionPage.cpp b/src/modules/partition/gui/PartitionPage.cpp index a5f4365d7..15a543f18 100644 --- a/src/modules/partition/gui/PartitionPage.cpp +++ b/src/modules/partition/gui/PartitionPage.cpp @@ -15,7 +15,6 @@ #include "PartitionPage.h" // Local -#include "Config.h" #include "core/BootLoaderModel.h" #include "core/DeviceModel.h" #include "core/KPMHelpers.h" @@ -40,12 +39,14 @@ #include "utils/Retranslator.h" #include "widgets/TranslationFix.h" +// KPMcore #include #include #include #include #include +// Qt #include #include #include @@ -54,17 +55,14 @@ #include #include -PartitionPage::PartitionPage( PartitionCoreModule* core, const Config & config, QWidget* parent ) +PartitionPage::PartitionPage( PartitionCoreModule* core, QWidget* parent ) : QWidget( parent ) , m_ui( new Ui_PartitionPage ) , m_core( core ) , m_lastSelectedBootLoaderIndex( -1 ) - , m_isEfi( PartUtils::isEfiSystem() ) + , m_isEfi( false ) { - if ( config.installChoice() != Config::InstallChoice::Manual ) - { - cWarning() << "Manual partitioning page created without user choosing manual-partitioning."; - } + m_isEfi = PartUtils::isEfiSystem(); m_ui->setupUi( this ); m_ui->partitionLabelsView->setVisible( @@ -78,8 +76,6 @@ PartitionPage::PartitionPage( PartitionCoreModule* core, const Config & config, ? PartitionBarsView::DrawNestedPartitions : PartitionBarsView::NoNestedPartitions; m_ui->partitionBarsView->setNestedPartitionsMode( mode ); - m_ui->lvmButtonPanel->setVisible( config.isLVMEnabled() ); - updateButtons(); updateBootLoaderInstallPath(); @@ -255,7 +251,7 @@ PartitionPage::checkCanCreate( Device* device ) { auto table = device->partitionTable(); - if ( KPMHelpers::isMSDOSPartition( table->type() ) ) + if ( table->type() == PartitionTable::msdos || table->type() == PartitionTable::msdos_sectorbased ) { cDebug() << "Checking MSDOS partition" << table->numPrimaries() << "primaries, max" << table->maxPrimaries(); @@ -411,7 +407,7 @@ PartitionPage::onCreateClicked() } QPointer< CreatePartitionDialog > dlg = new CreatePartitionDialog( - m_core, model->device(), CreatePartitionDialog::FreeSpace { partition }, getCurrentUsedMountpoints(), this ); + model->device(), CreatePartitionDialog::FreeSpace { partition }, getCurrentUsedMountpoints(), this ); if ( dlg->exec() == QDialog::Accepted ) { Partition* newPart = dlg->getNewlyCreatedPartition(); @@ -515,7 +511,7 @@ PartitionPage::updatePartitionToCreate( Device* device, Partition* partition ) mountPoints.removeOne( PartitionInfo::mountPoint( partition ) ); QPointer< CreatePartitionDialog > dlg - = new CreatePartitionDialog( m_core, device, CreatePartitionDialog::FreshPartition { partition }, mountPoints, this ); + = new CreatePartitionDialog( device, CreatePartitionDialog::FreshPartition { partition }, mountPoints, this ); if ( dlg->exec() == QDialog::Accepted ) { Partition* newPartition = dlg->getNewlyCreatedPartition(); @@ -532,7 +528,7 @@ PartitionPage::editExistingPartition( Device* device, Partition* partition ) mountPoints.removeOne( PartitionInfo::mountPoint( partition ) ); QPointer< EditExistingPartitionDialog > dlg - = new EditExistingPartitionDialog( m_core, device, partition, mountPoints, this ); + = new EditExistingPartitionDialog( device, partition, mountPoints, this ); if ( dlg->exec() == QDialog::Accepted ) { dlg->applyChanges( m_core ); diff --git a/src/modules/partition/gui/PartitionPage.h b/src/modules/partition/gui/PartitionPage.h index 85021d5a0..d3ae60eb8 100644 --- a/src/modules/partition/gui/PartitionPage.h +++ b/src/modules/partition/gui/PartitionPage.h @@ -16,7 +16,6 @@ #include #include -class Config; class PartitionCoreModule; class Ui_PartitionPage; @@ -33,7 +32,7 @@ class PartitionPage : public QWidget { Q_OBJECT public: - explicit PartitionPage( PartitionCoreModule* core, const Config & config, QWidget* parent = nullptr ); + explicit PartitionPage( PartitionCoreModule* core, QWidget* parent = nullptr ); ~PartitionPage() override; void onRevertClicked(); diff --git a/src/modules/partition/gui/PartitionPage.ui b/src/modules/partition/gui/PartitionPage.ui index 7de478c33..ddbd21bf6 100644 --- a/src/modules/partition/gui/PartitionPage.ui +++ b/src/modules/partition/gui/PartitionPage.ui @@ -11,7 +11,7 @@ SPDX-License-Identifier: GPL-3.0-or-later 0 0 684 - 327 + 304 @@ -129,38 +129,36 @@ SPDX-License-Identifier: GPL-3.0-or-later - - - - - - New Volume Group - - - - - - - Resize Volume Group - - - - - - - Deactivate Volume Group - - - - - - - Remove Volume Group - - - - - + + + + + New Volume Group + + + + + + + Resize Volume Group + + + + + + + Deactivate Volume Group + + + + + + + Remove Volume Group + + + + diff --git a/src/modules/partition/jobs/ClearMountsJob.cpp b/src/modules/partition/jobs/ClearMountsJob.cpp index 2865d9538..ce1355b2b 100644 --- a/src/modules/partition/jobs/ClearMountsJob.cpp +++ b/src/modules/partition/jobs/ClearMountsJob.cpp @@ -333,7 +333,7 @@ template < typename F > void apply( const QStringList& paths, F f, QList< MessageAndPath >& news ) { - for ( const QString& p : std::as_const( paths ) ) + for ( const QString& p : qAsConst( paths ) ) { auto n = f( p ); if ( !n.isEmpty() ) @@ -347,7 +347,7 @@ STATICTEST QStringList stringify( const QList< MessageAndPath >& news ) { QStringList l; - for ( const auto& m : std::as_const( news ) ) + for ( const auto& m : qAsConst( news ) ) { l << QString( m ); } diff --git a/src/modules/partition/jobs/ClearTempMountsJob.cpp b/src/modules/partition/jobs/ClearTempMountsJob.cpp index f231983de..cb0fb572e 100644 --- a/src/modules/partition/jobs/ClearTempMountsJob.cpp +++ b/src/modules/partition/jobs/ClearTempMountsJob.cpp @@ -56,7 +56,7 @@ ClearTempMountsJob::exec() std::sort( targetMounts.begin(), targetMounts.end(), MtabInfo::mountPointOrder ); QStringList goodNews; - for ( const auto& m : std::as_const( targetMounts ) ) + for ( const auto& m : qAsConst( targetMounts ) ) { cDebug() << o << "Will try to umount path" << m.mountPoint; if ( Calamares::Partition::unmount( m.mountPoint, { "-lv" } ) == 0 ) diff --git a/src/modules/partition/jobs/FillGlobalStorageJob.cpp b/src/modules/partition/jobs/FillGlobalStorageJob.cpp index 357c1e210..3885e713c 100644 --- a/src/modules/partition/jobs/FillGlobalStorageJob.cpp +++ b/src/modules/partition/jobs/FillGlobalStorageJob.cpp @@ -99,6 +99,7 @@ mapForPartition( Partition* partition, const QString& uuid ) { map[ "fs" ] = untranslatedFS( dynamic_cast< FS::luks& >( partition->fileSystem() ).innerFS() ); } + if ( partition->fileSystem().type() == FileSystem::Luks2 && dynamic_cast< FS::luks2& >( partition->fileSystem() ).innerFS() ) { diff --git a/src/modules/partition/partition.conf b/src/modules/partition/partition.conf index 2f56df715..2a7213313 100644 --- a/src/modules/partition/partition.conf +++ b/src/modules/partition/partition.conf @@ -20,6 +20,10 @@ # system partition. If nothing is specified, the *recommendedSize* # is used instead. # - *label* +# This size is the minimum acceptable efi partition size when using systemd-boot +# +efiSystemPartitionMinSize: 500M + # This optional setting specifies the name of the EFI system partition (see # PARTLABEL; gpt only; requires KPMCore >= 4.2.0). # If nothing is specified, the partition name is left unset. @@ -46,6 +50,10 @@ efi: # Deprecated alias of efi.label # efiSystemPartitionName: EFI +# An optional variable from global storage which holds the bootloader and is used to +# override the value of efiSystemPartition +# efiBootLoaderVar: "packagechooser_bootloader" + # In autogenerated partitioning, allow the user to select a swap size? # If there is exactly one choice, no UI is presented, and the user # cannot make a choice -- this setting is used. If there is more than @@ -86,20 +94,7 @@ userSwapChoices: # LEGACY SETTINGS (these will generate a warning) # ensureSuspendToDisk: true # neverCreateSwap: false - -# This setting specifies the LUKS generation (i.e LUKS1, LUKS2) used internally by -# cryptsetup when creating an encrypted partition. -# -# This option is set to luks1 by default, as grub doesn't support LUKS2 + Argon2id -# currently. On the other hand grub does support LUKS2 with PBKDF2 and could therefore be -# also set to luks2. Also there are some patches for grub and Argon2. -# See: https://aur.archlinux.org/packages/grub-improved-luks2-git -# # Choices: luks1, luks2 (in addition, "luks" means "luks1") -# -# The default is luks1 -# -luksGeneration: luks1 # This setting determines if encryption should be allowed when using zfs. This # setting has no effect unless zfs support is provided. @@ -223,49 +218,6 @@ defaultFileSystemType: "ext4" # warning (this matches traditional no-choice-available behavior best). # availableFileSystemTypes: ["ext4","f2fs"] -# Per-directory filesystem restrictions. -# -# This optional setting specifies what filesystems the user can and cannot use -# for various directories and mountpoints when using manual partitioning. -# -# If nothing is specified, the only restriction enforced by default is that -# the EFI system partition must use the fat32 filesystem. -# -# Otherwise, the filesystem restrictions are defined as follow: -# -# directoryFilesystemRestrictions: -# - directory: "any" -# allowedFilesystemTypes: ["all"] -# - directory: "/" -# allowedFilesystemTypes: ["ext4","xfs","btrfs","jfs","f2fs"] -# - mountpoint: "efi" -# allowedFilesystemTypes: ["fat32"] -# onlyWhenMountpoint: true -# -# There can be any number of mountpoints listed, each entry having the -# following attributes: -# - mountpoint: mountpoint's full path -# or -# "any" to specify a global whitelist that applies to all -# mountpoints -# or -# "efi" to specify a whitelist specific to the EFI system -# partition, wherever that partition is located -# - allowedFilesystemTypes: the list of all filesystems valid for this -# mountpoint. If the list contains exactly one -# element, and that element is the special value -# "any", all filesystem types recognized by -# Calamares will be allowed. -# - onlyWhenMountpoint: Whether the restriction should apply only when the -# specified directory is a mountpoint. When set to -# true, Calamares will only enforce the listed -# restrictions when the user makes a separate partition -# for this directory and assigns the mountpoint -# accordingly. When set to false, Calamares will -# ensure this directory uses the specified filesystem -# even if the directory is part of a filesystem on a -# different mountpoint. Defaults to false. - # Show/hide LUKS related functionality in automated partitioning modes. # Disable this if you choose not to deploy early unlocking support in GRUB2 # and/or your distribution's initramfs solution. @@ -290,13 +242,6 @@ defaultFileSystemType: "ext4" # to cypher their disk when installing in enterprise (for exemple). #preCheckEncryption: false -# LVM support -# -# There is only one sub-key available, *enable* (defaults to true) -# which can be used to show (default) or hide the LVM buttons in the partitioning module. -lvm: - enable: true - # Partition layout. # # This optional setting specifies a custom partition layout. diff --git a/src/modules/partition/partition.schema.yaml b/src/modules/partition/partition.schema.yaml index 4bd2fa4ae..65cf7e979 100644 --- a/src/modules/partition/partition.schema.yaml +++ b/src/modules/partition/partition.schema.yaml @@ -20,12 +20,6 @@ properties: mountPoint: { type: string } additionalProperties: false - lvm: - type: object - properties: - enable: { type: boolean, default: true } - additionalProperties: false - userSwapChoices: { type: array, items: { type: string, enum: [ none, reuse, small, suspend, file ] } } # ensureSuspendToDisk: { type: boolean, default: true } # Legacy # neverCreateSwap: { type: boolean, default: false } # Legacy @@ -37,12 +31,10 @@ properties: defaultFileSystemType: { type: string } availableFileSystemTypes: { type: array, items: { type: string } } - mountpointFilesystemRestrictions: { type: array } # TODO: specify items luksGeneration: { type: string, enum: [luks1, luks2] } # Also allows "luks" as alias of "luks1" enableLuksAutomatedPartitioning: { type: boolean, default: false } preCheckEncryption: { type: boolean, default: false } - allowManualPartitioning: { type: boolean, default: true } showNotEncryptedBootMessage: { type: boolean, default: true } partitionLayout: { type: array } # TODO: specify items