[partition] Move partitioning options into a class

- As (auto) partitioning grows more options, the parameter
   list becomes more unwieldy. Add some structure to it.
This commit is contained in:
Adriaan de Groot 2018-09-17 06:42:14 -04:00
parent 5136021416
commit d2f4079a18
4 changed files with 121 additions and 86 deletions

View File

@ -28,7 +28,6 @@
#include "utils/Units.h" #include "utils/Units.h"
#include "JobQueue.h" #include "JobQueue.h"
#include "utils/Logger.h" #include "utils/Logger.h"
#include "GlobalStorage.h"
#include <kpmcore/core/device.h> #include <kpmcore/core/device.h>
#include <kpmcore/core/partition.h> #include <kpmcore/core/partition.h>
@ -43,17 +42,18 @@ using CalamaresUtils::operator""_GiB;
using CalamaresUtils::operator""_MiB; using CalamaresUtils::operator""_MiB;
qint64 qint64
swapSuggestion( const qint64 availableSpaceB ) swapSuggestion( const qint64 availableSpaceB, Choices::SwapChoice swap )
{ {
if ( ( swap != Choices::SmallSwap ) && ( swap != Choices::FullSwap ) )
return 0;
// See partition.conf for explanation // See partition.conf for explanation
qint64 suggestedSwapSizeB = 0; qint64 suggestedSwapSizeB = 0;
auto memory = CalamaresUtils::System::instance()->getTotalMemoryB(); auto memory = CalamaresUtils::System::instance()->getTotalMemoryB();
qint64 availableRamB = memory.first; qint64 availableRamB = memory.first;
qreal overestimationFactor = memory.second; qreal overestimationFactor = memory.second;
bool ensureSuspendToDisk = bool ensureSuspendToDisk = swap == Choices::FullSwap;
Calamares::JobQueue::instance()->globalStorage()->
value( "ensureSuspendToDisk" ).toBool();
// Ramp up quickly to 8GiB, then follow memory size // Ramp up quickly to 8GiB, then follow memory size
if ( availableRamB <= 4_GiB ) if ( availableRamB <= 4_GiB )
@ -97,16 +97,14 @@ bytesToSectors( qint64 bytes, qint64 blocksize )
} }
void void
doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPassphrase ) doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionOptions o )
{ {
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); QString defaultFsType = o.defaultFsType;
bool isEfi = PartUtils::isEfiSystem();
QString defaultFsType = gs->value( "defaultFileSystemType" ).toString();
if ( FileSystem::typeForName( defaultFsType ) == FileSystem::Unknown ) if ( FileSystem::typeForName( defaultFsType ) == FileSystem::Unknown )
defaultFsType = "ext4"; defaultFsType = "ext4";
bool isEfi = PartUtils::isEfiSystem();
// Partition sizes are expressed in MiB, should be multiples of // Partition sizes are expressed in MiB, should be multiples of
// the logical sector size (usually 512B). EFI starts with 2MiB // the logical sector size (usually 512B). EFI starts with 2MiB
// empty and a 300MiB EFI boot partition, while BIOS starts at // empty and a 300MiB EFI boot partition, while BIOS starts at
@ -139,8 +137,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass
PartitionTable::FlagNone PartitionTable::FlagNone
); );
PartitionInfo::setFormat( efiPartition, true ); PartitionInfo::setFormat( efiPartition, true );
PartitionInfo::setMountPoint( efiPartition, gs->value( "efiSystemPartition" ) PartitionInfo::setMountPoint( efiPartition, o.efiPartitionMountPoint );
.toString() );
core->createPartition( dev, efiPartition, PartitionTable::FlagEsp ); core->createPartition( dev, efiPartition, PartitionTable::FlagEsp );
firstFreeSector = lastSector + 1; firstFreeSector = lastSector + 1;
} }
@ -149,20 +146,18 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass
core->createPartitionTable( dev, PartitionTable::msdos ); core->createPartitionTable( dev, PartitionTable::msdos );
} }
const bool mayCreateSwap = !gs->value( "neverCreateSwap" ).toBool(); const bool mayCreateSwap = ( o.swap == Choices::SmallSwap ) || ( o.swap == Choices::FullSwap );
bool shouldCreateSwap = false; bool shouldCreateSwap = false;
qint64 suggestedSwapSizeB = 0; qint64 suggestedSwapSizeB = 0;
if ( mayCreateSwap ) if ( mayCreateSwap )
{ {
qint64 availableSpaceB = ( dev->totalLogical() - firstFreeSector ) * dev->logicalSize(); qint64 availableSpaceB = ( dev->totalLogical() - firstFreeSector ) * dev->logicalSize();
suggestedSwapSizeB = swapSuggestion( availableSpaceB ); suggestedSwapSizeB = swapSuggestion( availableSpaceB, o.swap );
// Space required by this installation is what the distro claims is needed // Space required by this installation is what the distro claims is needed
// (via global configuration) plus the swap size plus a fudge factor of // (via global configuration) plus the swap size plus a fudge factor of
// 0.6GiB (this was 2.1GiB up to Calamares 3.2.2). // 0.6GiB (this was 2.1GiB up to Calamares 3.2.2).
qint64 requiredSpaceB = qint64 requiredSpaceB = o.requiredSpaceB + 600_MiB + suggestedSwapSizeB;
GiBtoBytes( gs->value( "requiredStorageGB" ).toDouble() + 0.6 ) +
suggestedSwapSizeB;
// If there is enough room for ESP + root + swap, create swap, otherwise don't. // If there is enough room for ESP + root + swap, create swap, otherwise don't.
shouldCreateSwap = availableSpaceB > requiredSpaceB; shouldCreateSwap = availableSpaceB > requiredSpaceB;
@ -175,7 +170,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass
} }
Partition* rootPartition = nullptr; Partition* rootPartition = nullptr;
if ( luksPassphrase.isEmpty() ) if ( o.luksPassphrase.isEmpty() )
{ {
rootPartition = KPMHelpers::createNewPartition( rootPartition = KPMHelpers::createNewPartition(
dev->partitionTable(), dev->partitionTable(),
@ -195,7 +190,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass
FileSystem::typeForName( defaultFsType ), FileSystem::typeForName( defaultFsType ),
firstFreeSector, firstFreeSector,
lastSectorForRoot, lastSectorForRoot,
luksPassphrase o.luksPassphrase
); );
} }
PartitionInfo::setFormat( rootPartition, true ); PartitionInfo::setFormat( rootPartition, true );
@ -205,7 +200,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass
if ( shouldCreateSwap ) if ( shouldCreateSwap )
{ {
Partition* swapPartition = nullptr; Partition* swapPartition = nullptr;
if ( luksPassphrase.isEmpty() ) if ( o.luksPassphrase.isEmpty() )
{ {
swapPartition = KPMHelpers::createNewPartition( swapPartition = KPMHelpers::createNewPartition(
dev->partitionTable(), dev->partitionTable(),
@ -225,7 +220,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass
FileSystem::LinuxSwap, FileSystem::LinuxSwap,
lastSectorForRoot + 1, lastSectorForRoot + 1,
dev->totalLogical() - 1, dev->totalLogical() - 1,
luksPassphrase o.luksPassphrase
); );
} }
PartitionInfo::setFormat( swapPartition, true ); PartitionInfo::setFormat( swapPartition, true );
@ -240,13 +235,11 @@ void
doReplacePartition( PartitionCoreModule* core, doReplacePartition( PartitionCoreModule* core,
Device* dev, Device* dev,
Partition* partition, Partition* partition,
const QString& luksPassphrase ) Choices::ReplacePartitionOptions o )
{ {
cDebug() << "doReplacePartition for device" << partition->partitionPath(); cDebug() << "doReplacePartition for device" << partition->partitionPath();
QString defaultFsType = Calamares::JobQueue::instance()-> QString defaultFsType = o.defaultFsType;
globalStorage()->
value( "defaultFileSystemType" ).toString();
if ( FileSystem::typeForName( defaultFsType ) == FileSystem::Unknown ) if ( FileSystem::typeForName( defaultFsType ) == FileSystem::Unknown )
defaultFsType = "ext4"; defaultFsType = "ext4";
@ -267,7 +260,7 @@ doReplacePartition( PartitionCoreModule* core,
} }
Partition* newPartition = nullptr; Partition* newPartition = nullptr;
if ( luksPassphrase.isEmpty() ) if ( o.luksPassphrase.isEmpty() )
{ {
newPartition = KPMHelpers::createNewPartition( newPartition = KPMHelpers::createNewPartition(
partition->parent(), partition->parent(),
@ -287,7 +280,7 @@ doReplacePartition( PartitionCoreModule* core,
FileSystem::typeForName( defaultFsType ), FileSystem::typeForName( defaultFsType ),
partition->firstSector(), partition->firstSector(),
partition->lastSector(), partition->lastSector(),
luksPassphrase o.luksPassphrase
); );
} }
PartitionInfo::setMountPoint( newPartition, "/" ); PartitionInfo::setMountPoint( newPartition, "/" );

View File

@ -27,30 +27,6 @@ class Partition;
namespace PartitionActions namespace PartitionActions
{ {
/**
* @brief doAutopartition sets up an autopartitioning operation on the given Device.
* @param core a pointer to the PartitionCoreModule instance.
* @param dev the device to wipe.
* @param luksPassphrase the passphrase for LUKS encryption (optional, default is empty).
*/
void doAutopartition( PartitionCoreModule* core,
Device* dev,
const QString& luksPassphrase = QString() );
/**
* @brief doReplacePartition sets up replace-partitioning with the given partition.
* @param core a pointer to the PartitionCoreModule instance.
* @param dev a pointer to the Device on which to replace a partition.
* @param partition a pointer to the Partition to be replaced.
* @param luksPassphrase the passphrase for LUKS encryption (optional, default is empty).
* @note this function also takes care of requesting PCM to delete the partition.
*/
void doReplacePartition( PartitionCoreModule* core,
Device* dev,
Partition* partition,
const QString& luksPassphrase = QString() );
/** @brief Namespace for enums /** @brief Namespace for enums
* *
* This namespace houses non-class enums..... * This namespace houses non-class enums.....
@ -66,7 +42,59 @@ namespace Choices
FullSwap, // ensureSuspendToDisk -- at least RAM size FullSwap, // ensureSuspendToDisk -- at least RAM size
SwapFile // use a file (if supported) SwapFile // use a file (if supported)
}; };
struct ReplacePartitionOptions
{
QString defaultFsType; // e.g. "ext4" or "btrfs"
QString luksPassphrase; // optional
ReplacePartitionOptions( const QString& fs, const QString& luks )
: defaultFsType( fs )
, luksPassphrase( luks )
{
}
};
struct AutoPartitionOptions : ReplacePartitionOptions
{
QString efiPartitionMountPoint; // optional, e.g. "/boot"
quint64 requiredSpaceB; // estimated required space for root partition
SwapChoice swap;
AutoPartitionOptions( const QString& fs, const QString& luks, const QString& efi, qint64 r, SwapChoice s )
: ReplacePartitionOptions( fs, luks )
, efiPartitionMountPoint( efi )
, requiredSpaceB( r > 0 ? r : 0 )
, swap( s )
{
}
};
} // namespace Choices } // namespace Choices
/**
* @brief doAutopartition sets up an autopartitioning operation on the given Device.
* @param core a pointer to the PartitionCoreModule instance.
* @param dev the device to wipe.
* @param options settings for autopartitioning.
*/
void doAutopartition( PartitionCoreModule* core,
Device* dev,
Choices::AutoPartitionOptions options );
/**
* @brief doReplacePartition sets up replace-partitioning with the given partition.
* @param core a pointer to the PartitionCoreModule instance.
* @param dev a pointer to the Device on which to replace a partition.
* @param partition a pointer to the Partition to be replaced.
* @param options settings for partitioning (not all fields apply)
*
* @note this function also takes care of requesting PCM to delete the partition.
*/
void doReplacePartition( PartitionCoreModule* core,
Device* dev,
Partition* partition,
Choices::ReplacePartitionOptions options );
} // namespace PartitionActions } // namespace PartitionActions
#endif // PARTITIONACTIONS_H #endif // PARTITIONACTIONS_H

View File

@ -42,6 +42,7 @@
#include "utils/CalamaresUtilsGui.h" #include "utils/CalamaresUtilsGui.h"
#include "utils/Logger.h" #include "utils/Logger.h"
#include "utils/Retranslator.h" #include "utils/Retranslator.h"
#include "utils/Units.h"
#include "Branding.h" #include "Branding.h"
#include "GlobalStorage.h" #include "GlobalStorage.h"
@ -417,30 +418,37 @@ ChoicePage::applyActionChoice( ChoicePage::InstallChoice choice )
switch ( choice ) switch ( choice )
{ {
case Erase: case Erase:
if ( m_core->isDirty() )
{ {
ScanningDialog::run( QtConcurrent::run( [ = ] auto gs = Calamares::JobQueue::instance()->globalStorage();
{
QMutexLocker locker( &m_coreMutex );
m_core->revertDevice( selectedDevice() );
} ),
[ = ]
{
PartitionActions::doAutopartition( m_core,
selectedDevice(),
m_encryptWidget->passphrase() );
emit deviceChosen();
},
this );
}
else
{
PartitionActions::doAutopartition( m_core,
selectedDevice(),
m_encryptWidget->passphrase() );
emit deviceChosen();
}
PartitionActions::Choices::AutoPartitionOptions options {
gs->value( "defaultFileSystemType" ).toString(),
m_encryptWidget->passphrase(),
gs->value( "efiSystemPartition" ).toString(),
CalamaresUtils::GiBtoBytes( gs->value( "requiredStorageGB" ).toDouble() ),
static_cast<PartitionActions::Choices::SwapChoice>( m_eraseSwapChoices->currentData().toInt() )
};
if ( m_core->isDirty() )
{
ScanningDialog::run( QtConcurrent::run( [ = ]
{
QMutexLocker locker( &m_coreMutex );
m_core->revertDevice( selectedDevice() );
} ),
[ = ]
{
PartitionActions::doAutopartition( m_core, selectedDevice(), options );
emit deviceChosen();
},
this );
}
else
{
PartitionActions::doAutopartition( m_core, selectedDevice(), options );
emit deviceChosen();
}
}
break; break;
case Replace: case Replace:
if ( m_core->isDirty() ) if ( m_core->isDirty() )
@ -518,6 +526,7 @@ ChoicePage::doAlongsideSetupSplitter( const QModelIndex& current,
->value( "requiredStorageGB" ) ->value( "requiredStorageGB" )
.toDouble(); .toDouble();
// TODO: make this consistent
qint64 requiredStorageB = qRound64( requiredStorageGB + 0.1 + 2.0 ) * 1024 * 1024 * 1024; qint64 requiredStorageB = qRound64( requiredStorageGB + 0.1 + 2.0 ) * 1024 * 1024 * 1024;
m_afterPartitionSplitterWidget->setSplitPartition( m_afterPartitionSplitterWidget->setSplitPartition(
@ -802,14 +811,19 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current )
if ( homePartitionPath->isEmpty() ) if ( homePartitionPath->isEmpty() )
doReuseHomePartition = false; doReuseHomePartition = false;
PartitionActions::doReplacePartition( m_core, Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
selectedDevice(),
selectedPartition, PartitionActions::doReplacePartition(
m_encryptWidget->passphrase() ); m_core,
selectedDevice(),
selectedPartition,
{
gs->value( "defaultFileSystemType" ).toString(),
m_encryptWidget->passphrase()
} );
Partition* homePartition = KPMHelpers::findPartitionByPath( { selectedDevice() }, Partition* homePartition = KPMHelpers::findPartitionByPath( { selectedDevice() },
*homePartitionPath ); *homePartitionPath );
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
if ( homePartition && doReuseHomePartition ) if ( homePartition && doReuseHomePartition )
{ {
PartitionInfo::setMountPoint( homePartition, "/home" ); PartitionInfo::setMountPoint( homePartition, "/home" );

View File

@ -85,6 +85,8 @@ ReplaceWidget::reset()
void void
ReplaceWidget::applyChanges() ReplaceWidget::applyChanges()
{ {
auto gs = Calamares::JobQueue::instance()->globalStorage();
PartitionModel* model = qobject_cast< PartitionModel* >( m_ui->partitionTreeView->model() ); PartitionModel* model = qobject_cast< PartitionModel* >( m_ui->partitionTreeView->model() );
if ( model ) if ( model )
{ {
@ -93,7 +95,9 @@ ReplaceWidget::applyChanges()
{ {
Device* dev = model->device(); Device* dev = model->device();
PartitionActions::doReplacePartition( m_core, dev, partition ); PartitionActions::doReplacePartition(
m_core, dev, partition,
{ gs->value( "defaultFileSystemType" ).toString(), QString() } );
if ( m_isEfi ) if ( m_isEfi )
{ {
@ -102,17 +106,13 @@ ReplaceWidget::applyChanges()
{ {
PartitionInfo::setMountPoint( PartitionInfo::setMountPoint(
efiSystemPartitions.first(), efiSystemPartitions.first(),
Calamares::JobQueue::instance()-> gs->value( "efiSystemPartition" ).toString() );
globalStorage()->
value( "efiSystemPartition" ).toString() );
} }
else if ( efiSystemPartitions.count() > 1 ) else if ( efiSystemPartitions.count() > 1 )
{ {
PartitionInfo::setMountPoint( PartitionInfo::setMountPoint(
efiSystemPartitions.at( m_ui->bootComboBox->currentIndex() ), efiSystemPartitions.at( m_ui->bootComboBox->currentIndex() ),
Calamares::JobQueue::instance()-> gs->value( "efiSystemPartition" ).toString() );
globalStorage()->
value( "efiSystemPartition" ).toString() );
} }
} }