From 70f8beb931bc1c2bed1ceab742ae3f94c395a969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20PORTAY?= Date: Wed, 20 May 2020 11:22:37 -0400 Subject: [PATCH 1/2] [partition] Add setting for defaultPartitionTableType --- src/modules/partition/core/PartitionActions.cpp | 13 ++++++++----- src/modules/partition/core/PartitionActions.h | 11 +++++++---- src/modules/partition/gui/ChoicePage.cpp | 7 +++++-- src/modules/partition/gui/PartitionViewStep.cpp | 7 +++++++ src/modules/partition/gui/ReplaceWidget.cpp | 3 ++- src/modules/partition/partition.conf | 14 ++++++++++++++ 6 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index 9f6e63c91..a78e8ff53 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -118,6 +118,14 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO // before that one, numbered 0..2047). qint64 firstFreeSector = CalamaresUtils::bytesToSectors( empty_space_sizeB, dev->logicalSize() ); + PartitionTable::TableType partType = PartitionTable::nameToTableType( o.defaultPartitionTableType ); + if ( partType == PartitionTable::unknownTableType ) + { + partType = isEfi ? PartitionTable::gpt : PartitionTable::msdos; + } + + core->createPartitionTable( dev, partType ); + if ( isEfi ) { qint64 efiSectorCount = CalamaresUtils::bytesToSectors( uefisys_part_sizeB, dev->logicalSize() ); @@ -127,7 +135,6 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO // at firstFreeSector, we need efiSectorCount sectors, numbered // firstFreeSector..firstFreeSector+efiSectorCount-1. qint64 lastSector = firstFreeSector + efiSectorCount - 1; - core->createPartitionTable( dev, PartitionTable::gpt ); Partition* efiPartition = KPMHelpers::createNewPartition( dev->partitionTable(), *dev, PartitionRole( PartitionRole::Primary ), @@ -144,10 +151,6 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO core->createPartition( dev, efiPartition, KPM_PARTITION_FLAG_ESP ); firstFreeSector = lastSector + 1; } - else - { - core->createPartitionTable( dev, PartitionTable::msdos ); - } const bool mayCreateSwap = ( o.swap == Config::SwapChoice::SmallSwap ) || ( o.swap == Config::SwapChoice::FullSwap ); diff --git a/src/modules/partition/core/PartitionActions.h b/src/modules/partition/core/PartitionActions.h index 15b7c1e1e..45d6f460a 100644 --- a/src/modules/partition/core/PartitionActions.h +++ b/src/modules/partition/core/PartitionActions.h @@ -29,11 +29,13 @@ namespace Choices { struct ReplacePartitionOptions { + QString defaultPartitionTableType; // e.g. "gpt" or "msdos" QString defaultFsType; // e.g. "ext4" or "btrfs" QString luksPassphrase; // optional - ReplacePartitionOptions( const QString& fs, const QString& luks ) - : defaultFsType( fs ) + ReplacePartitionOptions( const QString& pt, const QString& fs, const QString& luks ) + : defaultPartitionTableType ( pt ) + , defaultFsType( fs ) , luksPassphrase( luks ) { } @@ -45,12 +47,13 @@ struct AutoPartitionOptions : ReplacePartitionOptions quint64 requiredSpaceB; // estimated required space for root partition Config::SwapChoice swap; - AutoPartitionOptions( const QString& fs, + AutoPartitionOptions( const QString& pt, + const QString& fs, const QString& luks, const QString& efi, qint64 requiredBytes, Config::SwapChoice s ) - : ReplacePartitionOptions( fs, luks ) + : ReplacePartitionOptions( pt, fs, luks ) , efiPartitionMountPoint( efi ) , requiredSpaceB( requiredBytes > 0 ? static_cast< quint64 >( requiredBytes ) : 0 ) , swap( s ) diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index 62e235c5c..c81248c82 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -448,7 +448,8 @@ ChoicePage::applyActionChoice( InstallChoice choice ) { auto gs = Calamares::JobQueue::instance()->globalStorage(); - PartitionActions::Choices::AutoPartitionOptions options { gs->value( "defaultFileSystemType" ).toString(), + PartitionActions::Choices::AutoPartitionOptions options { gs->value( "defaultPartitionTableType" ).toString(), + gs->value( "defaultFileSystemType" ).toString(), m_encryptWidget->passphrase(), gs->value( "efiSystemPartition" ).toString(), CalamaresUtils::GiBtoBytes( @@ -805,7 +806,9 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current ) m_core, selectedDevice(), selectedPartition, - { gs->value( "defaultFileSystemType" ).toString(), m_encryptWidget->passphrase() } ); + { gs->value( "defaultPartitionType" ).toString(), + gs->value( "defaultFileSystemType" ).toString(), + m_encryptWidget->passphrase() } ); Partition* homePartition = findPartitionByPath( { selectedDevice() }, *homePartitionPath ); if ( homePartition && doReuseHomePartition ) diff --git a/src/modules/partition/gui/PartitionViewStep.cpp b/src/modules/partition/gui/PartitionViewStep.cpp index d0390aa86..a9860cd1e 100644 --- a/src/modules/partition/gui/PartitionViewStep.cpp +++ b/src/modules/partition/gui/PartitionViewStep.cpp @@ -574,6 +574,13 @@ PartitionViewStep::setConfigurationMap( const QVariantMap& configurationMap ) } gs->insert( "defaultFileSystemType", fsRealName ); + QString partitionTableName = CalamaresUtils::getString( configurationMap, "defaultPartitionTableType" ); + if ( partitionTableName.isEmpty() ) + { + cWarning() << "Partition-module setting *defaultPartitionTableType* is unset, " + "will use gpt for efi or msdos for bios"; + } + gs->insert( "defaultPartitionTableType", partitionTableName ); // Now that we have the config, we load the PartitionCoreModule in the background // because it could take a while. Then when it's done, we can set up the widgets diff --git a/src/modules/partition/gui/ReplaceWidget.cpp b/src/modules/partition/gui/ReplaceWidget.cpp index a316d98b2..69c89889b 100644 --- a/src/modules/partition/gui/ReplaceWidget.cpp +++ b/src/modules/partition/gui/ReplaceWidget.cpp @@ -85,7 +85,8 @@ ReplaceWidget::applyChanges() Device* dev = model->device(); PartitionActions::doReplacePartition( - m_core, dev, partition, { gs->value( "defaultFileSystemType" ).toString(), QString() } ); + m_core, dev, partition, { gs->value( "defaultPartitionTableType" ).toString(), + gs->value( "defaultFileSystemType" ).toString(), QString() } ); if ( m_isEfi ) { diff --git a/src/modules/partition/partition.conf b/src/modules/partition/partition.conf index efebe19f4..451566f41 100644 --- a/src/modules/partition/partition.conf +++ b/src/modules/partition/partition.conf @@ -88,6 +88,20 @@ initialPartitioningChoice: none # one of the items from the options. initialSwapChoice: none +# Default partition table type, used when a "erase" disk is made. +# +# When erasing a disk, a new partition table is created on disk. +# In other cases, e.g. Replace and Alongside, as well as when using +# manual partitioning, this partition table exists already on disk +# and it is left unmodified. +# +# Suggested values: gpt, msdos +# If nothing is specified, Calamares defaults to "gpt" if system is +# efi or "msdos". +# +# Names are case-sensitive and defined by KPMCore. +# defaultPartitionTableType: msdos + # Default filesystem type, used when a "new" partition is made. # # When replacing a partition, the existing filesystem inside the From 2bbbb688385dc2ade84d7e4344618092717e6c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20PORTAY?= Date: Thu, 21 May 2020 17:13:28 -0400 Subject: [PATCH 2/2] [partition] Add setting for requiredPartitionTableType --- src/modules/partition/core/Config.cpp | 14 +++++++++++ src/modules/partition/core/Config.h | 1 + src/modules/partition/gui/ChoicePage.cpp | 31 ++++++++++++++++++++++++ src/modules/partition/gui/ChoicePage.h | 1 + src/modules/partition/partition.conf | 15 ++++++++++++ 5 files changed, 62 insertions(+) diff --git a/src/modules/partition/core/Config.cpp b/src/modules/partition/core/Config.cpp index 9f251229e..268399dbd 100644 --- a/src/modules/partition/core/Config.cpp +++ b/src/modules/partition/core/Config.cpp @@ -239,6 +239,20 @@ Config::setConfigurationMap( const QVariantMap& configurationMap ) Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); gs->insert( "allowManualPartitioning", CalamaresUtils::getBool( configurationMap, "allowManualPartitioning", true ) ); + + if ( configurationMap.contains( "requiredPartitionTableType" ) && + configurationMap.value( "requiredPartitionTableType" ).type() == QVariant::List ) + { + m_requiredPartitionTableType.clear(); + m_requiredPartitionTableType.append( configurationMap.value( "requiredPartitionTableType" ).toStringList() ); + } + else if ( configurationMap.contains( "requiredPartitionTableType" ) && + configurationMap.value( "requiredPartitionTableType" ).type() == QVariant::String ) + { + m_requiredPartitionTableType.clear(); + m_requiredPartitionTableType.append( configurationMap.value( "requiredPartitionTableType" ).toString() ); + } + gs->insert( "requiredPartitionTableType", m_requiredPartitionTableType); } void diff --git a/src/modules/partition/core/Config.h b/src/modules/partition/core/Config.h index 23ebdedf8..1629ccc22 100644 --- a/src/modules/partition/core/Config.h +++ b/src/modules/partition/core/Config.h @@ -114,6 +114,7 @@ private: InstallChoice m_initialInstallChoice = NoChoice; InstallChoice m_installChoice = NoChoice; qreal m_requiredStorageGiB = 0.0; // May duplicate setting in the welcome module + QStringList m_requiredPartitionTableType; }; /** @brief Given a set of swap choices, return a sensible value from it. diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index c81248c82..c3ac14735 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -89,6 +89,7 @@ ChoicePage::ChoicePage( Config* config, QWidget* parent ) auto gs = Calamares::JobQueue::instance()->globalStorage(); + m_requiredPartitionTableType = gs->value( "requiredPartitionTableType" ).toStringList(); m_defaultFsType = gs->value( "defaultFileSystemType" ).toString(); m_enableEncryptionWidget = gs->value( "enableLuksAutomatedPartitioning" ).toBool(); @@ -1252,6 +1253,7 @@ ChoicePage::setupActions() bool atLeastOneCanBeReplaced = false; bool atLeastOneIsMounted = false; // Suppress 'erase' if so bool isInactiveRAID = false; + bool matchTableType = false; #ifdef WITH_KPMCORE4API if ( currentDevice->type() == Device::Type::SoftwareRAID_Device @@ -1262,6 +1264,14 @@ ChoicePage::setupActions() } #endif + PartitionTable::TableType tableType = PartitionTable::unknownTableType; + if ( currentDevice->partitionTable() ) + { + tableType = currentDevice->partitionTable()->type(); + matchTableType = m_requiredPartitionTableType.size() == 0 || + m_requiredPartitionTableType.contains( PartitionTable::tableTypeToName( tableType ) ); + } + for ( auto it = PartitionIterator::begin( currentDevice ); it != PartitionIterator::end( currentDevice ); ++it ) { if ( PartUtils::canBeResized( *it ) ) @@ -1434,6 +1444,27 @@ ChoicePage::setupActions() m_replaceButton->hide(); } + if ( tableType != PartitionTable::unknownTableType && !matchTableType ) + { + m_messageLabel->setText( tr( "This storage device already may has an operating system on it, " + "but its partition table %1 mismatch the" + "requirement %2.
" ) + .arg( PartitionTable::tableTypeToName( tableType ) ) + .arg( m_requiredPartitionTableType.join( " or " ) ) ); + m_messageLabel->show(); + + cWarning() << "Partition table" << PartitionTable::tableTypeToName( tableType ) + << "does not match the requirement " << m_requiredPartitionTableType.join( " or " ) << ", " + "ENABLING erease feature and "; + "DISABLING alongside, replace and manual features."; + m_eraseButton->show(); + m_alongsideButton->hide(); + m_replaceButton->hide(); + m_somethingElseButton->hide(); + cDebug() << "Replace button suppressed because partition table type mismatch."; + force_uncheck( m_grp, m_replaceButton ); + } + if ( m_somethingElseButton->isHidden() && m_alongsideButton->isHidden() && m_replaceButton->isHidden() diff --git a/src/modules/partition/gui/ChoicePage.h b/src/modules/partition/gui/ChoicePage.h index cce91e9cc..118f23a46 100644 --- a/src/modules/partition/gui/ChoicePage.h +++ b/src/modules/partition/gui/ChoicePage.h @@ -154,6 +154,7 @@ private: int m_lastSelectedDeviceIndex = -1; int m_lastSelectedActionIndex = -1; + QStringList m_requiredPartitionTableType; QString m_defaultFsType; bool m_enableEncryptionWidget; diff --git a/src/modules/partition/partition.conf b/src/modules/partition/partition.conf index 451566f41..bfedddfca 100644 --- a/src/modules/partition/partition.conf +++ b/src/modules/partition/partition.conf @@ -102,6 +102,21 @@ initialSwapChoice: none # Names are case-sensitive and defined by KPMCore. # defaultPartitionTableType: msdos +# Requirement for partition table type +# +# Restrict the installation on disks that match the type of partition +# tables that are specified. +# +# Suggested values: msdos, gpt +# If nothing is specified, Calamares defaults to both "msdos" and "mbr". +# +# Names are case-sensitive and defined by KPMCore. +# requiredPartitionTableType: gpt +# or, +# requiredPartitionTableType: +# - msdos +# - gpt + # Default filesystem type, used when a "new" partition is made. # # When replacing a partition, the existing filesystem inside the