Merge branch 'issue-2283' into calamares
This commit is contained in:
commit
d7bbfd055c
@ -1,4 +1,4 @@
|
||||
# Architecture
|
||||
#Architecture
|
||||
|
||||
<!-- SPDX-FileCopyrightText: 2014 Aurélien Gâteau <agateau@kde.org>
|
||||
SPDX-FileCopyrightText: 2016 Teo Mrnjavac <teo@kde.org>
|
||||
@ -47,7 +47,7 @@ Calamares-specific properties to the Partition instances: setting the install
|
||||
mount point is done with `PartitionInfo::setMountPoint(partition, "/")`,
|
||||
retrieving it is done with `mountPoint = PartitionInfo::mountPoint(partition)`.
|
||||
|
||||
The rational behind this unusual design is simplicity: the alternative would
|
||||
The rationale behind this unusual design is simplicity: the alternative would
|
||||
have been to keep a separate PartitionInfo object and a map linking each
|
||||
Partition to its PartitionInfo instance. Such a design makes things more
|
||||
complicated. It complicates memory management: if a Partition goes away, its
|
||||
@ -60,7 +60,7 @@ the real Partition object. This would have worked and would have made for a less
|
||||
surprising API, but it would mean more Calamares-specific patches on KPMcore.
|
||||
|
||||
|
||||
# Tests
|
||||
#Tests
|
||||
|
||||
The module comes with unit tests for the partition jobs. Those tests need to
|
||||
run on storage device which does not contain any data you care about.
|
||||
@ -78,7 +78,7 @@ this:
|
||||
sudo CALAMARES_TEST_DISK=/dev/sdb $top_build_dir/partitionjobtests
|
||||
|
||||
|
||||
# TODO
|
||||
#TODO
|
||||
|
||||
- Support resizing extended partitions. ResizePartitionJob should already
|
||||
support this but the UI prevents editing of extended partitions for now.
|
||||
|
@ -166,6 +166,23 @@ struct PartitionCoreModule::DeviceInfo
|
||||
return Calamares::job_ptr( nullptr );
|
||||
}
|
||||
|
||||
/** @brief Take the jobs of any type that apply to @p partition */
|
||||
void takeJobs( Partition* partition )
|
||||
{
|
||||
for ( auto it = m_jobs.begin(); it != m_jobs.end(); )
|
||||
{
|
||||
PartitionJob* job = qobject_cast< PartitionJob* >( it->data() );
|
||||
if ( job && job->partition() == partition )
|
||||
{
|
||||
it = m_jobs.erase( it );
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Add a job of given type to the job list
|
||||
*/
|
||||
template < typename Job, typename... Args >
|
||||
@ -557,15 +574,17 @@ PartitionCoreModule::formatPartition( Device* device, Partition* partition )
|
||||
void
|
||||
PartitionCoreModule::setFilesystemLabel( Device* device, Partition* partition, const QString& newLabel )
|
||||
{
|
||||
if ( newLabel.isEmpty() )
|
||||
if ( newLabel == PartitionInfo::label( partition ) )
|
||||
{
|
||||
// Don't bother
|
||||
return;
|
||||
}
|
||||
|
||||
auto deviceInfo = infoForDevice( device );
|
||||
Q_ASSERT( deviceInfo );
|
||||
|
||||
OperationHelper helper( partitionModelForDevice( device ), this );
|
||||
PartitionInfo::setLabel( partition, newLabel );
|
||||
deviceInfo->takeJob< ChangeFilesystemLabelJob >( partition );
|
||||
deviceInfo->makeJob< ChangeFilesystemLabelJob >( partition, newLabel );
|
||||
}
|
||||
|
||||
@ -1142,6 +1161,17 @@ PartitionCoreModule::clearJobs()
|
||||
updateIsDirty();
|
||||
}
|
||||
|
||||
void
|
||||
PartitionCoreModule::clearJobs( Device* device, Partition* partition )
|
||||
{
|
||||
DeviceInfo* devInfo = infoForDevice( device );
|
||||
|
||||
if ( devInfo )
|
||||
{
|
||||
devInfo->takeJobs( partition );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PartitionCoreModule::isDirty()
|
||||
|
@ -218,6 +218,7 @@ public:
|
||||
void asyncRevertDevice( Device* dev, std::function< void() > callback ); //like revertDevice, but asynchronous
|
||||
|
||||
void clearJobs(); // only clear jobs, the Device* states are preserved
|
||||
void clearJobs( Device* device, Partition* partition ); // clears all jobs changing @p partition
|
||||
|
||||
bool isDirty(); // true if there are pending changes, otherwise false
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
// KPMcore
|
||||
#include <kpmcore/core/lvmdevice.h>
|
||||
#include <kpmcore/core/partition.h>
|
||||
#include <kpmcore/fs/filesystemfactory.h>
|
||||
|
||||
// Qt
|
||||
#include <QVariant>
|
||||
@ -24,6 +25,7 @@ namespace PartitionInfo
|
||||
static const char MOUNT_POINT_PROPERTY[] = "_calamares_mountPoint";
|
||||
static const char FORMAT_PROPERTY[] = "_calamares_format";
|
||||
static const char FLAGS_PROPERTY[] = "_calamares_flags";
|
||||
static const char LABEL_PROPERTY[] = "_calamares_label";
|
||||
|
||||
QString
|
||||
mountPoint( const Partition* partition )
|
||||
@ -74,12 +76,32 @@ setFlags( Partition* partition, PartitionTable::Flags f )
|
||||
partition->setProperty( FLAGS_PROPERTY, PartitionTable::Flags::Int( f ) );
|
||||
}
|
||||
|
||||
QString
|
||||
label( const Partition* partition )
|
||||
{
|
||||
auto v = partition->property( LABEL_PROPERTY );
|
||||
if ( !v.isValid() )
|
||||
{
|
||||
return partition->fileSystem().label();
|
||||
}
|
||||
return v.toString();
|
||||
}
|
||||
|
||||
void
|
||||
setLabel( Partition* partition, const QString& value )
|
||||
{
|
||||
partition->setProperty( LABEL_PROPERTY, value );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
reset( Partition* partition )
|
||||
{
|
||||
// Setting a property to an invalid QVariant is equal to removing it
|
||||
partition->setProperty( MOUNT_POINT_PROPERTY, QVariant() );
|
||||
partition->setProperty( FORMAT_PROPERTY, QVariant() );
|
||||
partition->setProperty( FLAGS_PROPERTY, QVariant() );
|
||||
partition->setProperty( LABEL_PROPERTY, QVariant() );
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -21,7 +21,9 @@ class Partition;
|
||||
* Functions to store Calamares-specific information in the Qt properties of a
|
||||
* Partition object.
|
||||
*
|
||||
* See README.md for the rational behind this design.
|
||||
* See README.md for the rationale behind this design. Roughly, these
|
||||
* functions access **intent** while the existing Partition methods
|
||||
* access current state.
|
||||
*
|
||||
* Properties:
|
||||
* - mountPoint: which directory will a partition be mounted on the installed
|
||||
@ -29,6 +31,7 @@ class Partition;
|
||||
* directory on which a partition is *currently* mounted while the installer
|
||||
* is running.
|
||||
* - format: whether this partition should be formatted at install time.
|
||||
* - label: label to apply to the filesystem in the partition
|
||||
*/
|
||||
namespace PartitionInfo
|
||||
{
|
||||
@ -42,6 +45,9 @@ void setFormat( Partition* partition, bool value );
|
||||
PartitionTable::Flags flags( const Partition* partition );
|
||||
void setFlags( Partition* partition, PartitionTable::Flags f );
|
||||
|
||||
QString label( const Partition* partition );
|
||||
void setLabel( Partition* partition, const QString& value );
|
||||
|
||||
void reset( Partition* partition );
|
||||
|
||||
/**
|
||||
|
@ -45,6 +45,18 @@
|
||||
using Calamares::Partition::untranslatedFS;
|
||||
using Calamares::Partition::userVisibleFS;
|
||||
|
||||
static void
|
||||
updateLabel( PartitionCoreModule* core, Device* device, Partition* partition, const QString& fsLabel )
|
||||
{
|
||||
// In this case, we are not formatting the partition, but we are setting the
|
||||
// label on the current filesystem, if any. We only create the job if the
|
||||
// label actually changed.
|
||||
if ( partition->fileSystem().type() != FileSystem::Type::Unformatted && fsLabel != partition->fileSystem().label() )
|
||||
{
|
||||
core->setFilesystemLabel( device, partition, fsLabel );
|
||||
}
|
||||
}
|
||||
|
||||
EditExistingPartitionDialog::EditExistingPartitionDialog( Device* device,
|
||||
Partition* partition,
|
||||
const QStringList& usedMountPoints,
|
||||
@ -69,9 +81,10 @@ EditExistingPartitionDialog::EditExistingPartitionDialog( Device* device,
|
||||
this,
|
||||
&EditExistingPartitionDialog::checkMountPointSelection );
|
||||
|
||||
// The filesystem label dialog is always enabled, because we may want to change
|
||||
// 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( m_partition->fileSystem().label() );
|
||||
m_ui->fileSystemLabelEdit->setText( PartitionInfo::label( m_partition ) );
|
||||
m_ui->fileSystemLabel->setEnabled( true );
|
||||
|
||||
replacePartResizerWidget();
|
||||
|
||||
@ -81,7 +94,6 @@ EditExistingPartitionDialog::EditExistingPartitionDialog( Device* device,
|
||||
{
|
||||
replacePartResizerWidget();
|
||||
|
||||
m_ui->fileSystemLabel->setEnabled( doFormat );
|
||||
m_ui->fileSystemComboBox->setEnabled( doFormat );
|
||||
|
||||
if ( !doFormat )
|
||||
@ -126,14 +138,17 @@ EditExistingPartitionDialog::EditExistingPartitionDialog( Device* device,
|
||||
m_ui->fileSystemComboBox->setCurrentText( FileSystem::nameForType( defaultFSType ) );
|
||||
}
|
||||
|
||||
m_ui->fileSystemLabel->setEnabled( m_ui->formatRadioButton->isChecked() );
|
||||
m_ui->fileSystemComboBox->setEnabled( m_ui->formatRadioButton->isChecked() );
|
||||
// Force a format if the existing device is a zfs device since reusing a
|
||||
// zpool isn't currently supported; disable the radio buttons then.
|
||||
const bool partitionIsZFS = m_partition->fileSystem().type() == FileSystem::Type::Zfs;
|
||||
m_ui->formatRadioButton->setEnabled( !partitionIsZFS );
|
||||
m_ui->keepRadioButton->setEnabled( !partitionIsZFS );
|
||||
|
||||
// Force a format if the existing device is a zfs device since reusing a zpool isn't currently supported
|
||||
m_ui->formatRadioButton->setChecked( m_partition->fileSystem().type() == FileSystem::Type::Zfs );
|
||||
m_ui->formatRadioButton->setEnabled( !( m_partition->fileSystem().type() == FileSystem::Type::Zfs ) );
|
||||
m_ui->keepRadioButton->setChecked( !( m_partition->fileSystem().type() == FileSystem::Type::Zfs ) );
|
||||
m_ui->keepRadioButton->setEnabled( !( m_partition->fileSystem().type() == FileSystem::Type::Zfs ) );
|
||||
const bool formatChecked = partitionIsZFS || PartitionInfo::format( m_partition );
|
||||
m_ui->formatRadioButton->setChecked( formatChecked );
|
||||
m_ui->keepRadioButton->setChecked( !formatChecked );
|
||||
|
||||
m_ui->fileSystemComboBox->setEnabled( m_ui->formatRadioButton->isChecked() );
|
||||
|
||||
setFlagList( *( m_ui->m_listFlags ), m_partition->availableFlags(), PartitionInfo::flags( m_partition ) );
|
||||
}
|
||||
@ -149,16 +164,18 @@ EditExistingPartitionDialog::newFlags() const
|
||||
void
|
||||
EditExistingPartitionDialog::applyChanges( PartitionCoreModule* core )
|
||||
{
|
||||
PartitionInfo::setMountPoint( m_partition, selectedMountPoint( m_ui->mountPointComboBox ) );
|
||||
// Remove jobs that we might have created for this partition already,
|
||||
// and also clear intentions so that we set the current ones unconditionally.
|
||||
core->clearJobs( m_device, m_partition );
|
||||
PartitionInfo::reset( m_partition );
|
||||
|
||||
const QString mountPoint = selectedMountPoint( m_ui->mountPointComboBox );
|
||||
PartitionInfo::setMountPoint( m_partition, mountPoint );
|
||||
|
||||
qint64 newFirstSector = m_partitionSizeController->firstSector();
|
||||
qint64 newLastSector = m_partitionSizeController->lastSector();
|
||||
bool partResizedMoved = newFirstSector != m_partition->firstSector() || newLastSector != m_partition->lastSector();
|
||||
|
||||
cDebug() << "old boundaries:" << m_partition->firstSector() << m_partition->lastSector() << m_partition->length();
|
||||
cDebug() << Logger::SubEntry << "new boundaries:" << newFirstSector << newLastSector;
|
||||
cDebug() << Logger::SubEntry << "dirty status:" << m_partitionSizeController->isDirty();
|
||||
|
||||
FileSystem::Type fsType = FileSystem::Unknown;
|
||||
if ( m_ui->formatRadioButton->isChecked() )
|
||||
{
|
||||
@ -171,8 +188,15 @@ EditExistingPartitionDialog::applyChanges( PartitionCoreModule* core )
|
||||
const auto resultFlags = newFlags();
|
||||
const auto currentFlags = PartitionInfo::flags( m_partition );
|
||||
|
||||
cDebug() << m_partition->partitionPath() << "format?" << m_ui->formatRadioButton->isChecked() << "label=" << fsLabel
|
||||
<< "mount=" << mountPoint;
|
||||
|
||||
if ( partResizedMoved )
|
||||
{
|
||||
cDebug() << "old boundaries:" << m_partition->firstSector() << m_partition->lastSector()
|
||||
<< m_partition->length();
|
||||
cDebug() << Logger::SubEntry << "new boundaries:" << newFirstSector << newLastSector;
|
||||
|
||||
if ( m_ui->formatRadioButton->isChecked() )
|
||||
{
|
||||
Partition* newPartition = KPMHelpers::createNewPartition( m_partition->parent(),
|
||||
@ -197,6 +221,8 @@ EditExistingPartitionDialog::applyChanges( PartitionCoreModule* core )
|
||||
{
|
||||
core->setPartitionFlags( m_device, m_partition, resultFlags );
|
||||
}
|
||||
updateLabel( core, m_device, m_partition, fsLabel );
|
||||
PartitionInfo::setFormat( m_partition, false );
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -213,6 +239,7 @@ EditExistingPartitionDialog::applyChanges( PartitionCoreModule* core )
|
||||
core->setPartitionFlags( m_device, m_partition, resultFlags );
|
||||
}
|
||||
core->setFilesystemLabel( m_device, m_partition, fsLabel );
|
||||
PartitionInfo::setFormat( m_partition, true );
|
||||
}
|
||||
else // otherwise, we delete and recreate the partition with new fs type
|
||||
{
|
||||
@ -238,14 +265,8 @@ EditExistingPartitionDialog::applyChanges( PartitionCoreModule* core )
|
||||
{
|
||||
core->setPartitionFlags( m_device, m_partition, resultFlags );
|
||||
}
|
||||
// In this case, we are not formatting the partition, but we are setting the
|
||||
// label on the current filesystem, if any. We only create the job if the
|
||||
// label actually changed.
|
||||
if ( m_partition->fileSystem().type() != FileSystem::Type::Unformatted
|
||||
&& fsLabel != m_partition->fileSystem().label() )
|
||||
{
|
||||
core->setFilesystemLabel( m_device, m_partition, fsLabel );
|
||||
}
|
||||
updateLabel( core, m_device, m_partition, fsLabel );
|
||||
PartitionInfo::setFormat( m_partition, false );
|
||||
|
||||
core->refreshPartition( m_device, m_partition );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user