#include "partition/PartitionIterator.h"
#include "partition/PartitionQuery.h"
#include "utils/Logger.h"
+#include "utils/Traits.h"
#include "utils/Variant.h"
// KPMcore
//- DeviceInfo ---------------------------------------------
+// Some jobs have an updatePreview some don't
+DECLARE_HAS_METHOD(updatePreview)
+
+template< typename Job >
+void updatePreview( Job* job, const std::true_type& )
+{
+ job->updatePreview();
+}
+
+template< typename Job >
+void updatePreview( Job* job, const std::false_type& )
+{
+}
+
+template< typename Job >
+void updatePreview( Job* job )
+{
+ updatePreview(job, has_updatePreview<Job>{});
+}
+
+/**
+ * Owns the Device, PartitionModel and the jobs
+ */
+struct PartitionCoreModule::DeviceInfo
+{
+ DeviceInfo( Device* );
+ ~DeviceInfo();
+ QScopedPointer< Device > device;
+ QScopedPointer< PartitionModel > partitionModel;
+ const QScopedPointer< Device > immutableDevice;
+
+ // To check if LVM VGs are deactivated
+ bool isAvailable;
+
+ void forgetChanges();
+ bool isDirty() const;
+
+ const Calamares::JobList& jobs() const { return m_jobs; }
+
+ template< typename Job, typename... Args >
+ Calamares::Job* makeJob(Args... a)
+ {
+ auto* job = new Job( device.get(), a... );
+ updatePreview( job );
+ m_jobs << Calamares::job_ptr( job );
+ return job;
+ }
+
+private:
+ Calamares::JobList m_jobs;
+};
+
+
PartitionCoreModule::DeviceInfo::DeviceInfo( Device* _device )
: device( _device )
, partitionModel( new PartitionModel )
void
PartitionCoreModule::DeviceInfo::forgetChanges()
{
- jobs.clear();
+ m_jobs.clear();
for ( auto it = PartitionIterator::begin( device.data() ); it != PartitionIterator::end( device.data() ); ++it )
{
PartitionInfo::reset( *it );
bool
PartitionCoreModule::DeviceInfo::isDirty() const
{
- if ( !jobs.isEmpty() )
+ if ( !m_jobs.isEmpty() )
{
return true;
}
for ( auto it = PartitionIterator::begin( device.data() ); it != PartitionIterator::end( device.data() ); ++it )
+ {
if ( PartitionInfo::isDirty( *it ) )
{
return true;
}
+ }
return false;
}
void
PartitionCoreModule::createPartitionTable( Device* device, PartitionTable::TableType type )
{
- DeviceInfo* info = infoForDevice( device );
- if ( info )
+ auto* deviceInfo = infoForDevice( device );
+ if ( deviceInfo )
{
// Creating a partition table wipes all the disk, so there is no need to
// keep previous changes
- info->forgetChanges();
+ deviceInfo->forgetChanges();
OperationHelper helper( partitionModelForDevice( device ), this );
- CreatePartitionTableJob* job = new CreatePartitionTableJob( device, type );
- job->updatePreview();
- info->jobs << Calamares::job_ptr( job );
+ deviceInfo->makeJob< CreatePartitionTableJob >( type );
}
}
void
PartitionCoreModule::createPartition( Device* device, Partition* partition, PartitionTable::Flags flags )
{
- auto deviceInfo = infoForDevice( device );
+ auto* deviceInfo = infoForDevice( device );
Q_ASSERT( deviceInfo );
OperationHelper helper( partitionModelForDevice( device ), this );
- CreatePartitionJob* job = new CreatePartitionJob( device, partition );
- job->updatePreview();
-
- deviceInfo->jobs << Calamares::job_ptr( job );
+ deviceInfo->makeJob< CreatePartitionJob >( partition );
if ( flags != KPM_PARTITION_FLAG( None ) )
{
- SetPartFlagsJob* fJob = new SetPartFlagsJob( device, partition, flags );
- deviceInfo->jobs << Calamares::job_ptr( fJob );
+ deviceInfo->makeJob< SetPartFlagsJob >( partition, flags );
PartitionInfo::setFlags( partition, flags );
}
}
vgName.append( '_' );
}
- CreateVolumeGroupJob* job = new CreateVolumeGroupJob( vgName, pvList, peSize );
- job->updatePreview();
-
LvmDevice* device = new LvmDevice( vgName );
-
for ( const Partition* p : pvList )
{
device->physicalVolumes() << p;
}
DeviceInfo* deviceInfo = new DeviceInfo( device );
-
deviceInfo->partitionModel->init( device, osproberEntries() );
-
m_deviceModel->addDevice( device );
-
m_deviceInfos << deviceInfo;
- deviceInfo->jobs << Calamares::job_ptr( job );
+ deviceInfo->makeJob< CreateVolumeGroupJob >( vgName, pvList, peSize );
refreshAfterModelChange();
}
void
PartitionCoreModule::resizeVolumeGroup( LvmDevice* device, QVector< const Partition* >& pvList )
{
- DeviceInfo* deviceInfo = infoForDevice( device );
+ auto* deviceInfo = infoForDevice( device );
Q_ASSERT( deviceInfo );
-
- ResizeVolumeGroupJob* job = new ResizeVolumeGroupJob( device, pvList );
-
- deviceInfo->jobs << Calamares::job_ptr( job );
-
+ deviceInfo->makeJob< ResizeVolumeGroupJob >( device, pvList );
refreshAfterModelChange();
}
void
PartitionCoreModule::deactivateVolumeGroup( LvmDevice* device )
{
- DeviceInfo* deviceInfo = infoForDevice( device );
+ auto* deviceInfo = infoForDevice( device );
Q_ASSERT( deviceInfo );
deviceInfo->isAvailable = false;
+ // TODO: this leaks
DeactivateVolumeGroupJob* job = new DeactivateVolumeGroupJob( device );
// DeactivateVolumeGroupJob needs to be immediately called
void
PartitionCoreModule::removeVolumeGroup( LvmDevice* device )
{
- DeviceInfo* deviceInfo = infoForDevice( device );
+ auto* deviceInfo = infoForDevice( device );
Q_ASSERT( deviceInfo );
-
- RemoveVolumeGroupJob* job = new RemoveVolumeGroupJob( device );
-
- deviceInfo->jobs << Calamares::job_ptr( job );
-
+ deviceInfo->makeJob< RemoveVolumeGroupJob >( device );
refreshAfterModelChange();
}
void
PartitionCoreModule::deletePartition( Device* device, Partition* partition )
{
- auto deviceInfo = infoForDevice( device );
+ auto* deviceInfo = infoForDevice( device );
Q_ASSERT( deviceInfo );
OperationHelper helper( partitionModelForDevice( device ), this );
}
}
- Calamares::JobList& jobs = deviceInfo->jobs;
+ const Calamares::JobList& jobs = deviceInfo->jobs();
if ( partition->state() == KPM_PARTITION_STATE( New ) )
{
// First remove matching SetPartFlagsJobs
++it;
}
}
- DeletePartitionJob* job = new DeletePartitionJob( device, partition );
- job->updatePreview();
- jobs << Calamares::job_ptr( job );
+
+ deviceInfo->makeJob< DeletePartitionJob >( partition );
}
}
void
PartitionCoreModule::formatPartition( Device* device, Partition* partition )
{
- auto deviceInfo = infoForDevice( device );
+ auto* deviceInfo = infoForDevice( device );
Q_ASSERT( deviceInfo );
OperationHelper helper( partitionModelForDevice( device ), this );
-
- FormatPartitionJob* job = new FormatPartitionJob( device, partition );
- deviceInfo->jobs << Calamares::job_ptr( job );
+ deviceInfo->makeJob< FormatPartitionJob >( partition );
}
void
PartitionCoreModule::resizePartition( Device* device, Partition* partition, qint64 first, qint64 last )
{
- auto deviceInfo = infoForDevice( device );
+ auto* deviceInfo = infoForDevice( device );
Q_ASSERT( deviceInfo );
OperationHelper helper( partitionModelForDevice( device ), this );
-
- ResizePartitionJob* job = new ResizePartitionJob( device, partition, first, last );
- job->updatePreview();
- deviceInfo->jobs << Calamares::job_ptr( job );
+ deviceInfo->makeJob< ResizePartitionJob >( partition, first, last );
}
void
PartitionCoreModule::setPartitionFlags( Device* device, Partition* partition, PartitionTable::Flags flags )
{
- auto deviceInfo = infoForDevice( device );
+ auto* deviceInfo = infoForDevice( device );
Q_ASSERT( deviceInfo );
OperationHelper( partitionModelForDevice( device ), this );
-
- SetPartFlagsJob* job = new SetPartFlagsJob( device, partition, flags );
- deviceInfo->jobs << Calamares::job_ptr( job );
+ deviceInfo->makeJob< SetPartFlagsJob >( partition, flags );
PartitionInfo::setFlags( partition, flags );
}
for ( auto info : m_deviceInfos )
{
- lst << info->jobs;
+ lst << info->jobs();
devices << info->device.data();
}
lst << Calamares::job_ptr( new FillGlobalStorageJob( devices, m_bootLoaderInstallPath ) );
for ( auto info : m_deviceInfos )
{
cDebug() << "## Device:" << info->device->name();
- for ( auto job : info->jobs )
+ for ( const auto& job : info->jobs() )
{
cDebug() << "-" << job->prettyName();
}
for ( DeviceInfo* d : m_deviceInfos )
{
- for ( auto job : d->jobs )
+ for ( const auto& job : d->jobs() )
{
// Including new LVM PVs
CreatePartitionJob* partJob = dynamic_cast< CreatePartitionJob* >( job.data() );
{
( *it )->isAvailable = true;
- if ( !( *it )->jobs.empty() )
+ if ( !( *it )->jobs().empty() )
{
- CreateVolumeGroupJob* vgJob = dynamic_cast< CreateVolumeGroupJob* >( ( *it )->jobs[ 0 ].data() );
+ CreateVolumeGroupJob* vgJob = dynamic_cast< CreateVolumeGroupJob* >( ( *it )->jobs().first().data() );
if ( vgJob )
{