Merge branch 'issue-1297' into calamares

This does **not** result issue-1297, but brings in some
prep-work and pleasant clean-ups.
This commit is contained in:
Adriaan de Groot 2020-07-31 23:21:23 +02:00
commit b1b81f27cc
13 changed files with 376 additions and 231 deletions

View File

@ -24,7 +24,7 @@ section "cmake $CMAKE_ARGS $SRCDIR"
cmake $CMAKE_ARGS $SRCDIR || { echo "! CMake failed" ; exit 1 ; }
section "make"
make -j2 || { echo "! Make recheck" ; pwd -P ; df -h ; make -j1 VERBOSE=1 ; echo "! Make failed" ; exit 1 ; }
make -j2 VERBOSE=1 || { echo "! Make recheck" ; pwd -P ; df -h ; make -j1 VERBOSE=1 ; echo "! Make failed" ; exit 1 ; }
section "make install"

View File

@ -56,6 +56,7 @@ if ( KPMcore_FOUND AND Qt5DBus_FOUND AND KF5CoreAddons_FOUND AND KF5Config_FOUND
SOURCES
core/BootLoaderModel.cpp
core/ColorUtils.cpp
core/Config.cpp
core/DeviceList.cpp
core/DeviceModel.cpp
core/KPMHelpers.cpp

View File

@ -0,0 +1,141 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Config.h"
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "utils/Logger.h"
#include "utils/Variant.h"
Config::Config( QObject* parent )
: QObject( parent )
{
}
static PartitionActions::Choices::SwapChoiceSet
getSwapChoices( const QVariantMap& configurationMap )
{
// SWAP SETTINGS
//
// This is a bit convoluted because there's legacy settings to handle as well
// as the new-style list of choices, with mapping back-and-forth.
if ( configurationMap.contains( "userSwapChoices" )
&& ( configurationMap.contains( "ensureSuspendToDisk" ) || configurationMap.contains( "neverCreateSwap" ) ) )
{
cError() << "Partition-module configuration mixes old- and new-style swap settings.";
}
if ( configurationMap.contains( "ensureSuspendToDisk" ) )
{
cWarning() << "Partition-module setting *ensureSuspendToDisk* is deprecated.";
}
bool ensureSuspendToDisk = CalamaresUtils::getBool( configurationMap, "ensureSuspendToDisk", true );
if ( configurationMap.contains( "neverCreateSwap" ) )
{
cWarning() << "Partition-module setting *neverCreateSwap* is deprecated.";
}
bool neverCreateSwap = CalamaresUtils::getBool( configurationMap, "neverCreateSwap", false );
PartitionActions::Choices::SwapChoiceSet choices; // Available swap choices
if ( configurationMap.contains( "userSwapChoices" ) )
{
// We've already warned about overlapping settings with the
// legacy *ensureSuspendToDisk* and *neverCreateSwap*.
QStringList l = configurationMap[ "userSwapChoices" ].toStringList();
for ( const auto& item : l )
{
bool ok = false;
auto v = PartitionActions::Choices::swapChoiceNames().find( item, ok );
if ( ok )
{
choices.insert( v );
}
}
if ( choices.isEmpty() )
{
cWarning() << "Partition-module configuration for *userSwapChoices* is empty:" << l;
choices.insert( PartitionActions::Choices::SwapChoice::FullSwap );
}
// suspend if it's one of the possible choices; suppress swap only if it's
// the **only** choice available.
ensureSuspendToDisk = choices.contains( PartitionActions::Choices::SwapChoice::FullSwap );
neverCreateSwap = ( choices.count() == 1 ) && choices.contains( PartitionActions::Choices::SwapChoice::NoSwap );
}
else
{
// Convert the legacy settings into a single setting for now.
if ( neverCreateSwap )
{
choices.insert( PartitionActions::Choices::SwapChoice::NoSwap );
}
else if ( ensureSuspendToDisk )
{
choices.insert( PartitionActions::Choices::SwapChoice::FullSwap );
}
else
{
choices.insert( PartitionActions::Choices::SwapChoice::SmallSwap );
}
}
// Not all are supported right now // FIXME
static const char unsupportedSetting[] = "Partition-module does not support *userSwapChoices* setting";
#define COMPLAIN_UNSUPPORTED( x ) \
if ( choices.contains( x ) ) \
{ \
bool bogus = false; \
cWarning() << unsupportedSetting << PartitionActions::Choices::swapChoiceNames().find( x, bogus ); \
choices.remove( x ); \
}
COMPLAIN_UNSUPPORTED( PartitionActions::Choices::SwapChoice::SwapFile )
COMPLAIN_UNSUPPORTED( PartitionActions::Choices::SwapChoice::ReuseSwap )
#undef COMPLAIN_UNSUPPORTED
return choices;
}
void
Config::setConfigurationMap( const QVariantMap& configurationMap )
{
// Settings that overlap with the Welcome module
m_requiredStorageGiB = CalamaresUtils::getDouble( configurationMap, "requiredStorage", -1.0 );
m_swapChoices = getSwapChoices( configurationMap );
bool nameFound = false; // In the name table (ignored, falls back to first entry in table)
m_initialInstallChoice = PartitionActions::Choices::installChoiceNames().find( CalamaresUtils::getString( configurationMap, "initialPartitioningChoice" ), nameFound );
}
void
Config::updateGlobalStorage() const
{
// If there's no setting (e.g. from the welcome page) for required storage
// then use ours, if it was set.
auto* gs = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr;
if ( m_requiredStorageGiB >= 0.0 && gs && !gs->contains( "requiredStorageGiB" ) )
{
gs->insert( "requiredStorageGiB", m_requiredStorageGiB );
}
}

View File

@ -0,0 +1,55 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PARTITION_CONFIG_H
#define PARTITION_CONFIG_H
#include "core/PartitionActions.h"
#include <QObject>
#include <QSet>
class Config : public QObject
{
Q_OBJECT
public:
Config( QObject* parent );
virtual ~Config() = default;
void setConfigurationMap( const QVariantMap& );
void updateGlobalStorage() const;
PartitionActions::Choices::SwapChoiceSet swapChoices() const { return m_swapChoices; }
/**
* @brief What kind of installation (partitioning) is requested **initially**?
*
* @return the partitioning choice (may by @c NoChoice)
*/
PartitionActions::Choices::InstallChoice initialInstallChoice() const { return m_initialInstallChoice; }
private:
PartitionActions::Choices::SwapChoiceSet m_swapChoices;
PartitionActions::Choices::InstallChoice m_initialInstallChoice = PartitionActions::Choices::NoChoice;
qreal m_requiredStorageGiB = 0.0; // May duplicate setting in the welcome module
};
#endif

View File

@ -257,8 +257,8 @@ doReplacePartition( PartitionCoreModule* core, Device* dev, Partition* partition
namespace Choices
{
static const NamedEnumTable< SwapChoice >&
nameTable()
const NamedEnumTable< SwapChoice >&
swapChoiceNames()
{
static const NamedEnumTable< SwapChoice > names { { QStringLiteral( "none" ), SwapChoice::NoSwap },
{ QStringLiteral( "small" ), SwapChoice::SmallSwap },
@ -270,18 +270,37 @@ nameTable()
}
SwapChoice
nameToChoice( QString name, bool& ok )
pickOne( const SwapChoiceSet& s )
{
return nameTable().find( name, ok );
if ( s.count() == 0 )
{
return SwapChoice::NoSwap;
}
if ( s.count() == 1 )
{
return *( s.begin() );
}
if ( s.contains( SwapChoice::NoSwap ) )
{
return SwapChoice::NoSwap;
}
// Here, count > 1 but NoSwap is not a member.
return *( s.begin() );
}
QString
choiceToName( SwapChoice c )
const NamedEnumTable< InstallChoice >&
installChoiceNames()
{
bool ok = false;
return nameTable().find( c, ok );
static const NamedEnumTable< InstallChoice > names { { QStringLiteral( "none" ), InstallChoice::NoChoice },
{ QStringLiteral( "nochoice" ), InstallChoice::NoChoice },
{ QStringLiteral( "alongside" ), InstallChoice::Alongside },
{ QStringLiteral( "erase" ), InstallChoice::Erase },
{ QStringLiteral( "replace" ), InstallChoice::Replace },
{ QStringLiteral( "manual" ), InstallChoice::Manual } };
return names;
}
} // namespace Choices
} // namespace PartitionActions

View File

@ -19,6 +19,9 @@
#ifndef PARTITIONACTIONS_H
#define PARTITIONACTIONS_H
#include "utils/NamedEnum.h"
#include <QSet>
#include <QString>
class PartitionCoreModule;
@ -33,7 +36,7 @@ namespace PartitionActions
*/
namespace Choices
{
/** @brief Ccchoice of swap (size and type) */
/** @brief Choice of swap (size and type) */
enum SwapChoice
{
NoSwap, // don't create any swap, don't use any
@ -42,9 +45,26 @@ enum SwapChoice
FullSwap, // ensureSuspendToDisk -- at least RAM size
SwapFile // use a file (if supported)
};
using SwapChoiceSet = QSet< SwapChoice >;
const NamedEnumTable< SwapChoice >& swapChoiceNames();
SwapChoice nameToChoice( QString name, bool& ok );
QString choiceToName( SwapChoice );
/** @brief Given a set of swap choices, return a sensible value from it.
*
* "Sensible" here means: if there is one value, use it; otherwise, use
* NoSwap if there are no choices, or if NoSwap is one of the choices, in the set.
* If that's not possible, any value from the set.
*/
SwapChoice pickOne( const SwapChoiceSet& s );
enum InstallChoice
{
NoChoice,
Alongside,
Erase,
Replace,
Manual
};
const NamedEnumTable< InstallChoice >& installChoiceNames();
struct ReplacePartitionOptions
{

View File

@ -20,7 +20,15 @@
#include "ChoicePage.h"
#include "BootInfoWidget.h"
#include "DeviceInfoWidget.h"
#include "PartitionBarsView.h"
#include "PartitionLabelsView.h"
#include "PartitionSplitterWidget.h"
#include "ReplaceWidget.h"
#include "ScanningDialog.h"
#include "core/BootLoaderModel.h"
#include "core/Config.h"
#include "core/DeviceModel.h"
#include "core/KPMHelpers.h"
#include "core/OsproberEntry.h"
@ -30,14 +38,6 @@
#include "core/PartitionInfo.h"
#include "core/PartitionModel.h"
#include "BootInfoWidget.h"
#include "DeviceInfoWidget.h"
#include "PartitionBarsView.h"
#include "PartitionLabelsView.h"
#include "PartitionSplitterWidget.h"
#include "ReplaceWidget.h"
#include "ScanningDialog.h"
#include "Branding.h"
#include "GlobalStorage.h"
#include "JobQueue.h"
@ -70,34 +70,17 @@ using CalamaresUtils::Partition::isPartitionFreeSpace;
using CalamaresUtils::Partition::findPartitionByPath;
using Calamares::PrettyRadioButton;
/** @brief Given a set of swap choices, return a sensible value from it.
*
* "Sensible" here means: if there is one value, use it; otherwise, use
* NoSwap if there are no choices, or if NoSwap is one of the choices, in the set.
* If that's not possible, any value from the set.
*/
SwapChoice pickOne( const SwapChoiceSet& s )
{
if ( s.count() == 0 )
return SwapChoice::NoSwap;
if ( s.count() == 1 )
return *( s.begin() );
if ( s.contains( SwapChoice::NoSwap ) )
return SwapChoice::NoSwap;
// Here, count > 1 but NoSwap is not a member.
return *( s.begin() );
}
/**
* @brief ChoicePage::ChoicePage is the default constructor. Called on startup as part of
* the module loading code path.
* @param parent the QWidget parent.
*/
ChoicePage::ChoicePage( const SwapChoiceSet& swapChoices, QWidget* parent )
ChoicePage::ChoicePage( Config* config, QWidget* parent )
: QWidget( parent )
, m_config( config )
, m_nextEnabled( false )
, m_core( nullptr )
, m_choice( NoChoice )
, m_choice( InstallChoice::NoChoice )
, m_isEfi( false )
, m_grp( nullptr )
, m_alongsideButton( nullptr )
@ -111,8 +94,8 @@ ChoicePage::ChoicePage( const SwapChoiceSet& swapChoices, QWidget* parent )
, m_bootloaderComboBox( nullptr )
, m_lastSelectedDeviceIndex( -1 )
, m_enableEncryptionWidget( true )
, m_availableSwapChoices( swapChoices )
, m_eraseSwapChoice( pickOne( swapChoices ) )
, m_availableSwapChoices( config->swapChoices() )
, m_eraseSwapChoice( PartitionActions::Choices::pickOne( m_availableSwapChoices ) )
, m_allowManualPartitioning( true )
{
setupUi( this );
@ -259,14 +242,14 @@ ChoicePage::setupChoices()
m_alongsideButton->setIcon( CalamaresUtils::defaultPixmap( CalamaresUtils::PartitionAlongside,
CalamaresUtils::Original,
iconSize ) );
m_alongsideButton->addToGroup( m_grp, Alongside );
m_alongsideButton->addToGroup( m_grp, InstallChoice::Alongside );
m_eraseButton = new PrettyRadioButton;
m_eraseButton->setIconSize( iconSize );
m_eraseButton->setIcon( CalamaresUtils::defaultPixmap( CalamaresUtils::PartitionEraseAuto,
CalamaresUtils::Original,
iconSize ) );
m_eraseButton->addToGroup( m_grp, Erase );
m_eraseButton->addToGroup( m_grp, InstallChoice::Erase );
m_replaceButton = new PrettyRadioButton;
@ -274,7 +257,7 @@ ChoicePage::setupChoices()
m_replaceButton->setIcon( CalamaresUtils::defaultPixmap( CalamaresUtils::PartitionReplaceOs,
CalamaresUtils::Original,
iconSize ) );
m_replaceButton->addToGroup( m_grp, Replace );
m_replaceButton->addToGroup( m_grp, InstallChoice::Replace );
// Fill up swap options
// .. TODO: only if enabled in the config
@ -294,7 +277,7 @@ ChoicePage::setupChoices()
CalamaresUtils::Original,
iconSize ) );
m_itemsLayout->addWidget( m_somethingElseButton );
m_somethingElseButton->addToGroup( m_grp, Manual );
m_somethingElseButton->addToGroup( m_grp, InstallChoice::Manual );
m_itemsLayout->addStretch();
@ -312,7 +295,7 @@ ChoicePage::setupChoices()
{
if ( m_grp->checkedButton() == nullptr ) // If no other action is chosen, we must
{ // set m_choice to NoChoice and reset previews.
m_choice = NoChoice;
m_choice = InstallChoice::NoChoice;
updateNextEnabled();
emit actionChosen();
@ -458,7 +441,7 @@ ChoicePage::applyActionChoice( ChoicePage::InstallChoice choice )
switch ( choice )
{
case Erase:
case InstallChoice::Erase:
{
auto gs = Calamares::JobQueue::instance()->globalStorage();
@ -491,7 +474,7 @@ ChoicePage::applyActionChoice( ChoicePage::InstallChoice choice )
}
}
break;
case Replace:
case InstallChoice::Replace:
if ( m_core->isDirty() )
{
ScanningDialog::run( QtConcurrent::run( [ = ]
@ -509,7 +492,7 @@ ChoicePage::applyActionChoice( ChoicePage::InstallChoice choice )
Qt::UniqueConnection );
break;
case Alongside:
case InstallChoice::Alongside:
if ( m_core->isDirty() )
{
ScanningDialog::run( QtConcurrent::run( [ = ]
@ -532,8 +515,8 @@ ChoicePage::applyActionChoice( ChoicePage::InstallChoice choice )
this, SLOT( doAlongsideSetupSplitter( QModelIndex, QModelIndex ) ),
Qt::UniqueConnection );
break;
case NoChoice:
case Manual:
case InstallChoice::NoChoice:
case InstallChoice::Manual:
break;
}
updateActionChoicePreview( choice );
@ -588,13 +571,13 @@ void
ChoicePage::onEncryptWidgetStateChanged()
{
EncryptWidget::Encryption state = m_encryptWidget->state();
if ( m_choice == Erase )
if ( m_choice == InstallChoice::Erase )
{
if ( state == EncryptWidget::Encryption::Confirmed ||
state == EncryptWidget::Encryption::Disabled )
applyActionChoice( m_choice );
}
else if ( m_choice == Replace )
else if ( m_choice == InstallChoice::Replace )
{
if ( m_beforePartitionBarsView &&
m_beforePartitionBarsView->selectionModel()->currentIndex().isValid() &&
@ -613,7 +596,7 @@ ChoicePage::onEncryptWidgetStateChanged()
void
ChoicePage::onHomeCheckBoxStateChanged()
{
if ( currentChoice() == Replace &&
if ( currentChoice() == InstallChoice::Replace &&
m_beforePartitionBarsView->selectionModel()->currentIndex().isValid() )
{
doReplaceSelectedPartition( m_beforePartitionBarsView->
@ -626,10 +609,10 @@ ChoicePage::onHomeCheckBoxStateChanged()
void
ChoicePage::onLeave()
{
if ( m_choice == Alongside )
if ( m_choice == InstallChoice::Alongside )
doAlongsideApply();
if ( m_isEfi && ( m_choice == Alongside || m_choice == Replace ) )
if ( m_isEfi && ( m_choice == InstallChoice::Alongside || m_choice == InstallChoice::Replace ) )
{
QList< Partition* > efiSystemPartitions = m_core->efiSystemPartitions();
if ( efiSystemPartitions.count() == 1 )
@ -896,8 +879,8 @@ ChoicePage::updateDeviceStatePreview()
switch ( m_choice )
{
case Replace:
case Alongside:
case InstallChoice::Replace:
case InstallChoice::Alongside:
m_beforePartitionBarsView->setSelectionMode( QAbstractItemView::SingleSelection );
m_beforePartitionLabelsView->setSelectionMode( QAbstractItemView::SingleSelection );
break;
@ -948,7 +931,7 @@ ChoicePage::updateActionChoicePreview( ChoicePage::InstallChoice choice )
switch ( choice )
{
case Alongside:
case InstallChoice::Alongside:
{
if ( m_enableEncryptionWidget )
m_encryptWidget->show();
@ -992,8 +975,8 @@ ChoicePage::updateActionChoicePreview( ChoicePage::InstallChoice choice )
break;
}
case Erase:
case Replace:
case InstallChoice::Erase:
case InstallChoice::Replace:
{
if ( m_enableEncryptionWidget )
m_encryptWidget->show();
@ -1059,7 +1042,7 @@ ChoicePage::updateActionChoicePreview( ChoicePage::InstallChoice choice )
m_previewAfterFrame->show();
m_previewAfterLabel->show();
if ( m_choice == Erase )
if ( m_choice == InstallChoice::Erase )
m_selectLabel->hide();
else
{
@ -1079,8 +1062,8 @@ ChoicePage::updateActionChoicePreview( ChoicePage::InstallChoice choice )
break;
}
case NoChoice:
case Manual:
case InstallChoice::NoChoice:
case InstallChoice::Manual:
m_selectLabel->hide();
m_previewAfterFrame->hide();
m_previewBeforeLabel->setText( tr( "Current:" ) );
@ -1089,7 +1072,7 @@ ChoicePage::updateActionChoicePreview( ChoicePage::InstallChoice choice )
break;
}
if ( m_isEfi && ( m_choice == Alongside || m_choice == Replace ) )
if ( m_isEfi && ( m_choice == InstallChoice::Alongside || m_choice == InstallChoice::Replace ) )
{
QHBoxLayout* efiLayout = new QHBoxLayout;
layout->addLayout( efiLayout );
@ -1106,8 +1089,8 @@ ChoicePage::updateActionChoicePreview( ChoicePage::InstallChoice choice )
QAbstractItemView::SelectionMode previewSelectionMode;
switch ( m_choice )
{
case Replace:
case Alongside:
case InstallChoice::Replace:
case InstallChoice::Alongside:
previewSelectionMode = QAbstractItemView::SingleSelection;
break;
default:
@ -1450,11 +1433,11 @@ ChoicePage::calculateNextEnabled() const
switch ( m_choice )
{
case NoChoice:
case InstallChoice::NoChoice:
cDebug() << "No partitioning choice";
return false;
case Replace:
case Alongside:
case InstallChoice::Replace:
case InstallChoice::Alongside:
if ( !( sm_p && sm_p->currentIndex().isValid() ) )
{
cDebug() << "No partition selected";
@ -1462,8 +1445,8 @@ ChoicePage::calculateNextEnabled() const
}
enabled = true;
break;
case Erase:
case Manual:
case InstallChoice::Erase:
case InstallChoice::Manual:
enabled = true;
}
@ -1474,7 +1457,7 @@ ChoicePage::calculateNextEnabled() const
}
if ( m_isEfi && ( m_choice == Alongside || m_choice == Replace ) )
if ( m_isEfi && ( m_choice == InstallChoice::Alongside || m_choice == InstallChoice::Replace ) )
{
if ( m_core->efiSystemPartitions().count() == 0 )
{
@ -1483,7 +1466,7 @@ ChoicePage::calculateNextEnabled() const
}
}
if ( m_choice != Manual && m_encryptWidget->isVisible() )
if ( m_choice != InstallChoice::Manual && m_encryptWidget->isVisible() )
{
switch ( m_encryptWidget->state() )
{

View File

@ -42,11 +42,12 @@ namespace Calamares
class PrettyRadioButton;
}
class Config;
class DeviceInfoWidget;
class PartitionBarsView;
class PartitionSplitterWidget;
class PartitionLabelsView;
class PartitionCoreModule;
class DeviceInfoWidget;
class Device;
@ -61,16 +62,9 @@ class ChoicePage : public QWidget, private Ui::ChoicePage
{
Q_OBJECT
public:
enum InstallChoice
{
NoChoice,
Alongside,
Erase,
Replace,
Manual
};
using InstallChoice = PartitionActions::Choices::InstallChoice;
explicit ChoicePage( const SwapChoiceSet& swapChoices, QWidget* parent = nullptr );
explicit ChoicePage( Config* config, QWidget* parent = nullptr );
virtual ~ChoicePage();
/**
@ -147,6 +141,7 @@ private:
// Translations support
void updateSwapChoicesTr( QComboBox* box );
Config* m_config;
bool m_nextEnabled;
PartitionCoreModule* m_core;

View File

@ -22,6 +22,7 @@
#include "gui/PartitionViewStep.h"
#include "core/Config.h"
#include "core/DeviceModel.h"
#include "core/KPMHelpers.h"
#include "core/OsproberEntry.h"
@ -64,11 +65,11 @@
PartitionViewStep::PartitionViewStep( QObject* parent )
: Calamares::ViewStep( parent )
, m_config( new Config( this ) )
, m_core( nullptr )
, m_widget( new QStackedWidget() )
, m_choicePage( nullptr )
, m_manualPartitionPage( nullptr )
, m_requiredStorageGiB( 0.0 )
{
m_widget->setContentsMargins( 0, 0, 0, 0 );
@ -93,7 +94,7 @@ void
PartitionViewStep::continueLoading()
{
Q_ASSERT( !m_choicePage );
m_choicePage = new ChoicePage( m_swapChoices );
m_choicePage = new ChoicePage( m_config );
m_choicePage->init( m_core );
m_widget->addWidget( m_choicePage );
@ -166,20 +167,20 @@ PartitionViewStep::createSummaryWidget() const
QString modeText;
switch ( choice )
{
case ChoicePage::Alongside:
case ChoicePage::InstallChoice::Alongside:
modeText = tr( "Install %1 <strong>alongside</strong> another operating system." )
.arg( branding->shortVersionedName() );
break;
case ChoicePage::Erase:
case ChoicePage::InstallChoice::Erase:
modeText
= tr( "<strong>Erase</strong> disk and install %1." ).arg( branding->shortVersionedName() );
break;
case ChoicePage::Replace:
case ChoicePage::InstallChoice::Replace:
modeText
= tr( "<strong>Replace</strong> a partition with %1." ).arg( branding->shortVersionedName() );
break;
case ChoicePage::NoChoice:
case ChoicePage::Manual:
case ChoicePage::InstallChoice::NoChoice:
case ChoicePage::InstallChoice::Manual:
modeText = tr( "<strong>Manual</strong> partitioning." );
}
modeLabel->setText( modeText );
@ -192,27 +193,27 @@ PartitionViewStep::createSummaryWidget() const
QString modeText;
switch ( choice )
{
case ChoicePage::Alongside:
case ChoicePage::InstallChoice::Alongside:
modeText = tr( "Install %1 <strong>alongside</strong> another operating system on disk "
"<strong>%2</strong> (%3)." )
.arg( branding->shortVersionedName() )
.arg( info.deviceNode )
.arg( info.deviceName );
break;
case ChoicePage::Erase:
case ChoicePage::InstallChoice::Erase:
modeText = tr( "<strong>Erase</strong> disk <strong>%2</strong> (%3) and install %1." )
.arg( branding->shortVersionedName() )
.arg( info.deviceNode )
.arg( info.deviceName );
break;
case ChoicePage::Replace:
case ChoicePage::InstallChoice::Replace:
modeText = tr( "<strong>Replace</strong> a partition on disk <strong>%2</strong> (%3) with %1." )
.arg( branding->shortVersionedName() )
.arg( info.deviceNode )
.arg( info.deviceName );
break;
case ChoicePage::NoChoice:
case ChoicePage::Manual:
case ChoicePage::InstallChoice::NoChoice:
case ChoicePage::InstallChoice::Manual:
modeText = tr( "<strong>Manual</strong> partitioning on disk <strong>%1</strong> (%2)." )
.arg( info.deviceNode )
.arg( info.deviceName );
@ -295,7 +296,7 @@ PartitionViewStep::next()
{
if ( m_choicePage == m_widget->currentWidget() )
{
if ( m_choicePage->currentChoice() == ChoicePage::Manual )
if ( m_choicePage->currentChoice() == ChoicePage::InstallChoice::Manual )
{
if ( !m_manualPartitionPage )
{
@ -377,8 +378,8 @@ PartitionViewStep::isAtEnd() const
{
if ( m_widget->currentWidget() == m_choicePage )
{
if ( m_choicePage->currentChoice() == ChoicePage::Erase || m_choicePage->currentChoice() == ChoicePage::Replace
|| m_choicePage->currentChoice() == ChoicePage::Alongside )
if ( m_choicePage->currentChoice() == ChoicePage::InstallChoice::Erase || m_choicePage->currentChoice() == ChoicePage::InstallChoice::Replace
|| m_choicePage->currentChoice() == ChoicePage::InstallChoice::Alongside )
{
return true;
}
@ -391,18 +392,12 @@ PartitionViewStep::isAtEnd() const
void
PartitionViewStep::onActivate()
{
// If there's no setting (e.g. from the welcome page) for required storage
// then use ours, if it was set.
auto* gs = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr;
if ( m_requiredStorageGiB >= 0.0 && gs && !gs->contains( "requiredStorageGiB" ) )
{
gs->insert( "requiredStorageGiB", m_requiredStorageGiB );
}
m_config->updateGlobalStorage();
// if we're coming back to PVS from the next VS
if ( m_widget->currentWidget() == m_choicePage && m_choicePage->currentChoice() == ChoicePage::Alongside )
if ( m_widget->currentWidget() == m_choicePage && m_choicePage->currentChoice() == ChoicePage::InstallChoice::Alongside )
{
m_choicePage->applyActionChoice( ChoicePage::Alongside );
m_choicePage->applyActionChoice( ChoicePage::InstallChoice::Alongside );
// m_choicePage->reset();
//FIXME: ReplaceWidget should be reset maybe?
}
@ -531,6 +526,8 @@ PartitionViewStep::onLeave()
void
PartitionViewStep::setConfigurationMap( const QVariantMap& configurationMap )
{
m_config->setConfigurationMap( configurationMap );
// Copy the efiSystemPartition setting to the global storage. It is needed not only in
// the EraseDiskPage, but also in the bootloader configuration modules (grub, bootloader).
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
@ -558,97 +555,6 @@ PartitionViewStep::setConfigurationMap( const QVariantMap& configurationMap )
gs->insert( "efiSystemPartitionName", CalamaresUtils::getString( configurationMap, "efiSystemPartitionName" ) );
}
// SWAP SETTINGS
//
// This is a bit convoluted because there's legacy settings to handle as well
// as the new-style list of choices, with mapping back-and-forth.
if ( configurationMap.contains( "userSwapChoices" )
&& ( configurationMap.contains( "ensureSuspendToDisk" ) || configurationMap.contains( "neverCreateSwap" ) ) )
{
cError() << "Partition-module configuration mixes old- and new-style swap settings.";
}
if ( configurationMap.contains( "ensureSuspendToDisk" ) )
{
cWarning() << "Partition-module setting *ensureSuspendToDisk* is deprecated.";
}
bool ensureSuspendToDisk = CalamaresUtils::getBool( configurationMap, "ensureSuspendToDisk", true );
if ( configurationMap.contains( "neverCreateSwap" ) )
{
cWarning() << "Partition-module setting *neverCreateSwap* is deprecated.";
}
bool neverCreateSwap = CalamaresUtils::getBool( configurationMap, "neverCreateSwap", false );
QSet< PartitionActions::Choices::SwapChoice > choices; // Available swap choices
if ( configurationMap.contains( "userSwapChoices" ) )
{
// We've already warned about overlapping settings with the
// legacy *ensureSuspendToDisk* and *neverCreateSwap*.
QStringList l = configurationMap[ "userSwapChoices" ].toStringList();
for ( const auto& item : l )
{
bool ok = false;
auto v = PartitionActions::Choices::nameToChoice( item, ok );
if ( ok )
{
choices.insert( v );
}
}
if ( choices.isEmpty() )
{
cWarning() << "Partition-module configuration for *userSwapChoices* is empty:" << l;
choices.insert( PartitionActions::Choices::SwapChoice::FullSwap );
}
// suspend if it's one of the possible choices; suppress swap only if it's
// the **only** choice available.
ensureSuspendToDisk = choices.contains( PartitionActions::Choices::SwapChoice::FullSwap );
neverCreateSwap = ( choices.count() == 1 ) && choices.contains( PartitionActions::Choices::SwapChoice::NoSwap );
}
else
{
// Convert the legacy settings into a single setting for now.
if ( neverCreateSwap )
{
choices.insert( PartitionActions::Choices::SwapChoice::NoSwap );
}
else if ( ensureSuspendToDisk )
{
choices.insert( PartitionActions::Choices::SwapChoice::FullSwap );
}
else
{
choices.insert( PartitionActions::Choices::SwapChoice::SmallSwap );
}
}
// Not all are supported right now // FIXME
static const char unsupportedSetting[] = "Partition-module does not support *userSwapChoices* setting";
#define COMPLAIN_UNSUPPORTED( x ) \
if ( choices.contains( x ) ) \
{ \
cWarning() << unsupportedSetting << PartitionActions::Choices::choiceToName( x ); \
choices.remove( x ); \
}
COMPLAIN_UNSUPPORTED( PartitionActions::Choices::SwapChoice::SwapFile )
COMPLAIN_UNSUPPORTED( PartitionActions::Choices::SwapChoice::ReuseSwap )
#undef COMPLAIN_UNSUPPORTED
m_swapChoices = choices;
// Settings that overlap with the Welcome module
m_requiredStorageGiB = CalamaresUtils::getDouble( configurationMap, "requiredStorage", -1.0 );
// These gs settings seem to be unused (in upstream Calamares) outside of
// the partition module itself.
gs->insert( "ensureSuspendToDisk", ensureSuspendToDisk );
gs->insert( "neverCreateSwap", neverCreateSwap );
// OTHER SETTINGS
//
gs->insert( "drawNestedPartitions", CalamaresUtils::getBool( configurationMap, "drawNestedPartitions", false ) );

View File

@ -26,12 +26,11 @@
#include "DllMacro.h"
#include "core/PartitionActions.h"
#include <QObject>
#include <QSet>
class ChoicePage;
class Config;
class PartitionPage;
class PartitionCoreModule;
class QStackedWidget;
@ -81,6 +80,8 @@ private:
/// "slot" for changes to next-status from the KPMCore and ChoicePage
void nextPossiblyChanged( bool );
Config* m_config;
PartitionCoreModule* m_core;
QStackedWidget* m_widget;
ChoicePage* m_choicePage;
@ -88,10 +89,6 @@ private:
WaitingWidget* m_waitingWidget;
QFutureWatcher<void>* m_future;
QSet< PartitionActions::Choices::SwapChoice > m_swapChoices;
qreal m_requiredStorageGiB; // May duplicate setting in the welcome module
};
CALAMARES_PLUGIN_FACTORY_DECLARATION( PartitionViewStepFactory )

View File

@ -34,10 +34,10 @@ efiSystemPartition: "/boot/efi"
# 8.8GiB on disk in the end).
userSwapChoices:
- none # Create no swap, use no swap
- reuse # Re-use existing swap, but don't create any (unsupported right now)
- small # Up to 4GB
- suspend # At least main memory size
- file # To swap file instead of partition (unsupported right now)
# - reuse # Re-use existing swap, but don't create any (unsupported right now)
# - file # To swap file instead of partition (unsupported right now)
# LEGACY SETTINGS (these will generate a warning)
# ensureSuspendToDisk: true
@ -49,6 +49,29 @@ drawNestedPartitions: false
# Show/hide partition labels on manual partitioning page.
alwaysShowPartitionLabels: true
# Allow manual partitioning.
#
# When set to false, this option hides the "Manual partitioning" button,
# limiting the user's choice to "Erase", "Replace" or "Alongside".
# This can be useful when using a custom partition layout we don't want
# the user to modify.
#
# If nothing is specified, manual partitioning is enabled.
#allowManualPartitioning: true
# Initial selection on the Choice page
#
# There are four radio buttons (in principle: erase, replace, alongside, manual),
# and you can pick which of them, if any, is initially selected. For most
# installers, "none" is the right choice: it makes the user pick something specific,
# rather than accidentally being able to click past an important choice (in particular,
# "erase" is a dangerous choice).
#
# The default is "none"
#
# TODO: this isn't implemented
# initialPartitioningChoice: none
# Default filesystem type, used when a "new" partition is made.
#
# When replacing a partition, the existing filesystem inside the
@ -86,16 +109,6 @@ defaultFileSystemType: "ext4"
# If nothing is specified, LUKS is enabled in automated modes.
#enableLuksAutomatedPartitioning: true
# Allow manual partitioning.
#
# When set to false, this option hides the "Manual partitioning" button,
# limiting the user's choice to "Erase", "Replace" or "Alongside".
# This can be useful when using a custom partition layout we don't want
# the user to modify.
#
# If nothing is specified, manual partitioning is enabled.
#allowManualPartitioning: true
# To apply a custom partition layout, it has to be defined this way :
#
# partitionLayout:

View File

@ -4,8 +4,24 @@ $id: https://calamares.io/schemas/partition
additionalProperties: false
type: object
properties:
efiSystemPartition: { type: string, required: true }
ensureSuspendToDisk: { type: boolean, default: true }
efiSystemPartition: { type: string } # Mount point
efiSystemPartitionSize: { type: string }
efiSystemPartitionName: { type: string }
userSwapChoices: { type: array, items: { type: string, enum: [ none, reuse, small, suspend, file ] } }
# ensureSuspendToDisk: { type: boolean, default: true } # Legacy
# neverCreateSwap: { type: boolean, default: false } # Legacy
drawNestedPartitions: { type: boolean, default: false }
alwaysShowPartitionLabels: { type: boolean, default: true }
defaultFileSystemType: { type: string, required: true }
defaultFileSystemType: { type: string }
enableLuksAutomatedPartitioning: { type: boolean, default: false }
allowManualPartitioning: { type: boolean, default: true }
partitionLayout: { type: array } # TODO: specify items
initialPartitioningChoice: { type: string, enum: [ none, erase, replace, alongside, manual ] }
requiredStorage: { type: number }
required:
- efiSystemPartition
- userSwapChoices

View File

@ -26,19 +26,17 @@ QTEST_GUILESS_MAIN( ClearMountsJobTests )
/* Not exactly public API */
QStringList
getPartitionsForDevice( const QString& deviceName );
QStringList getPartitionsForDevice( const QString& deviceName );
QStringList
getPartitionsForDevice_other( const QString& deviceName )
{
QProcess process;
process.setProgram( "sh" );
process.setArguments( {
"-c",
process.setArguments(
{ "-c",
QString( "echo $(awk '{print $4}' /proc/partitions | sed -e '/name/d' -e '/^$/d' -e '/[1-9]/!d' | grep %1)" )
.arg( deviceName )
} );
.arg( deviceName ) } );
process.start();
process.waitForFinished();
@ -55,10 +53,11 @@ getPartitionsForDevice_other(const QString& deviceName)
ClearMountsJobTests::ClearMountsJobTests()
{
Logger::setupLogLevel(6);
Logger::setupLogLevel( Logger::LOGDEBUG );
}
void ClearMountsJobTests::testFindPartitions()
void
ClearMountsJobTests::testFindPartitions()
{
QStringList partitions = getPartitionsForDevice( "sda" );
QStringList other_part = getPartitionsForDevice_other( "sda" );