Merge branch 'update-lvm-support' of https://github.com/calamares/calamares into development

This commit is contained in:
Philip Müller 2018-07-22 08:33:58 +02:00
commit 627161258f
26 changed files with 1736 additions and 13 deletions

View File

@ -12,6 +12,10 @@ set_package_properties(
) )
if ( KPMcore_FOUND ) if ( KPMcore_FOUND )
if ( KPMcore_VERSION VERSION_GREATER "3.3.0")
add_definitions(-DWITH_KPMCOREGT33) # kpmcore greater than 3.3
endif()
include_directories( ${KPMCORE_INCLUDE_DIR} ) include_directories( ${KPMCORE_INCLUDE_DIR} )
include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui ) include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui )
@ -35,9 +39,11 @@ if ( KPMcore_FOUND )
gui/BootInfoWidget.cpp gui/BootInfoWidget.cpp
gui/ChoicePage.cpp gui/ChoicePage.cpp
gui/CreatePartitionDialog.cpp gui/CreatePartitionDialog.cpp
gui/CreateVolumeGroupDialog.cpp
gui/DeviceInfoWidget.cpp gui/DeviceInfoWidget.cpp
gui/EditExistingPartitionDialog.cpp gui/EditExistingPartitionDialog.cpp
gui/EncryptWidget.cpp gui/EncryptWidget.cpp
gui/ListPhysicalVolumeWidgetItem.cpp
gui/PartitionPage.cpp gui/PartitionPage.cpp
gui/PartitionBarsView.cpp gui/PartitionBarsView.cpp
gui/PartitionDialogHelpers.cpp gui/PartitionDialogHelpers.cpp
@ -46,17 +52,23 @@ if ( KPMcore_FOUND )
gui/PartitionSplitterWidget.cpp gui/PartitionSplitterWidget.cpp
gui/PartitionViewStep.cpp gui/PartitionViewStep.cpp
gui/PrettyRadioButton.cpp gui/PrettyRadioButton.cpp
gui/ResizeVolumeGroupDialog.cpp
gui/ScanningDialog.cpp gui/ScanningDialog.cpp
gui/ReplaceWidget.cpp gui/ReplaceWidget.cpp
gui/VolumeGroupBaseDialog.cpp
jobs/ClearMountsJob.cpp jobs/ClearMountsJob.cpp
jobs/ClearTempMountsJob.cpp jobs/ClearTempMountsJob.cpp
jobs/CreatePartitionJob.cpp jobs/CreatePartitionJob.cpp
jobs/CreatePartitionTableJob.cpp jobs/CreatePartitionTableJob.cpp
jobs/CreateVolumeGroupJob.cpp
jobs/DeactivateVolumeGroupJob.cpp
jobs/DeletePartitionJob.cpp jobs/DeletePartitionJob.cpp
jobs/FillGlobalStorageJob.cpp jobs/FillGlobalStorageJob.cpp
jobs/FormatPartitionJob.cpp jobs/FormatPartitionJob.cpp
jobs/PartitionJob.cpp jobs/PartitionJob.cpp
jobs/RemoveVolumeGroupJob.cpp
jobs/ResizePartitionJob.cpp jobs/ResizePartitionJob.cpp
jobs/ResizeVolumeGroupJob.cpp
jobs/SetPartitionFlagsJob.cpp jobs/SetPartitionFlagsJob.cpp
UI UI
gui/ChoicePage.ui gui/ChoicePage.ui
@ -66,6 +78,7 @@ if ( KPMcore_FOUND )
gui/EncryptWidget.ui gui/EncryptWidget.ui
gui/PartitionPage.ui gui/PartitionPage.ui
gui/ReplaceWidget.ui gui/ReplaceWidget.ui
gui/VolumeGroupBaseDialog.ui
LINK_PRIVATE_LIBRARIES LINK_PRIVATE_LIBRARIES
kpmcore kpmcore
calamaresui calamaresui

View File

@ -29,6 +29,7 @@
// KF5 // KF5
#include <KFormat> #include <KFormat>
#include <QStandardItemModel>
#include <QIcon> #include <QIcon>
// STL // STL
@ -77,10 +78,18 @@ DeviceModel::data( const QModelIndex& index, int role ) const
if ( device->name().isEmpty() ) if ( device->name().isEmpty() )
return device->deviceNode(); return device->deviceNode();
else else
return tr( "%1 - %2 (%3)" ) {
.arg( device->name() ) if ( device->logicalSize() >= 0 && device->totalLogical() >= 0 )
.arg( KFormat().formatByteSize( device->capacity() ) ) return tr( "%1 - %2 (%3)" )
.arg( device->deviceNode() ); .arg( device->name() )
.arg( KFormat().formatByteSize( device->capacity() ) )
.arg( device->deviceNode() );
// Newly LVM VGs don't have capacity property yet (i.e. always has 1B capacity), so don't show it for a while
else
return tr( "%1 - (%2)" )
.arg( device->name() )
.arg( device->deviceNode() );
}
case Qt::DecorationRole: case Qt::DecorationRole:
return CalamaresUtils::defaultPixmap( CalamaresUtils::PartitionDisk, return CalamaresUtils::defaultPixmap( CalamaresUtils::PartitionDisk,
CalamaresUtils::Original, CalamaresUtils::Original,
@ -116,3 +125,31 @@ DeviceModel::swapDevice( Device* oldDevice, Device* newDevice )
emit dataChanged( index( indexOfOldDevice ), index( indexOfOldDevice ) ); emit dataChanged( index( indexOfOldDevice ), index( indexOfOldDevice ) );
} }
void
DeviceModel::addDevice( Device *device )
{
beginResetModel();
m_devices << device;
std::sort( m_devices.begin(), m_devices.end(), []( const Device* dev1, const Device* dev2 )
{
return dev1->deviceNode() < dev2->deviceNode();
} );
endResetModel();
}
void
DeviceModel::removeDevice( Device *device )
{
beginResetModel();
m_devices.removeAll( device );
std::sort( m_devices.begin(), m_devices.end(), []( const Device* dev1, const Device* dev2 )
{
return dev1->deviceNode() < dev2->deviceNode();
} );
endResetModel();
}

View File

@ -49,6 +49,10 @@ public:
void swapDevice( Device* oldDevice, Device* newDevice ); void swapDevice( Device* oldDevice, Device* newDevice );
void addDevice( Device* device );
void removeDevice( Device* device );
private: private:
QList< Device* > m_devices; QList< Device* > m_devices;
}; };

View File

@ -34,10 +34,14 @@
#include "jobs/ClearTempMountsJob.h" #include "jobs/ClearTempMountsJob.h"
#include "jobs/CreatePartitionJob.h" #include "jobs/CreatePartitionJob.h"
#include "jobs/CreatePartitionTableJob.h" #include "jobs/CreatePartitionTableJob.h"
#include "jobs/CreateVolumeGroupJob.h"
#include "jobs/DeactivateVolumeGroupJob.h"
#include "jobs/DeletePartitionJob.h" #include "jobs/DeletePartitionJob.h"
#include "jobs/FillGlobalStorageJob.h" #include "jobs/FillGlobalStorageJob.h"
#include "jobs/FormatPartitionJob.h" #include "jobs/FormatPartitionJob.h"
#include "jobs/RemoveVolumeGroupJob.h"
#include "jobs/ResizePartitionJob.h" #include "jobs/ResizePartitionJob.h"
#include "jobs/ResizeVolumeGroupJob.h"
#include "jobs/SetPartitionFlagsJob.h" #include "jobs/SetPartitionFlagsJob.h"
#include "Typedefs.h" #include "Typedefs.h"
@ -45,10 +49,13 @@
// KPMcore // KPMcore
#include <kpmcore/core/device.h> #include <kpmcore/core/device.h>
#include <kpmcore/core/lvmdevice.h>
#include <kpmcore/core/partition.h> #include <kpmcore/core/partition.h>
#include <kpmcore/backend/corebackend.h> #include <kpmcore/backend/corebackend.h>
#include <kpmcore/backend/corebackendmanager.h> #include <kpmcore/backend/corebackendmanager.h>
#include <kpmcore/fs/filesystemfactory.h> #include <kpmcore/fs/filesystemfactory.h>
#include <kpmcore/fs/luks.h>
#include <kpmcore/fs/lvm2_pv.h>
// Qt // Qt
#include <QStandardItemModel> #include <QStandardItemModel>
@ -62,6 +69,7 @@ PartitionCoreModule::DeviceInfo::DeviceInfo( Device* _device )
: device( _device ) : device( _device )
, partitionModel( new PartitionModel ) , partitionModel( new PartitionModel )
, immutableDevice( new Device( *_device ) ) , immutableDevice( new Device( *_device ) )
, isAvailable( true )
{} {}
PartitionCoreModule::DeviceInfo::~DeviceInfo() PartitionCoreModule::DeviceInfo::~DeviceInfo()
@ -178,6 +186,8 @@ PartitionCoreModule::doInit()
m_bootLoaderModel->init( bootLoaderDevices ); m_bootLoaderModel->init( bootLoaderDevices );
scanForLVMPVs();
//FIXME: this should be removed in favor of //FIXME: this should be removed in favor of
// proper KPM support for EFI // proper KPM support for EFI
if ( PartUtils::isEfiSystem() ) if ( PartUtils::isEfiSystem() )
@ -265,6 +275,77 @@ PartitionCoreModule::createPartition( Device* device,
refresh(); refresh();
} }
void
PartitionCoreModule::createVolumeGroup( QString &vgName,
QVector< const Partition* > pvList,
qint32 peSize )
{
// Appending '_' character in case of repeated VG name
while ( hasVGwithThisName( vgName ) )
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 );
refresh();
}
void
PartitionCoreModule::resizeVolumeGroup( LvmDevice *device, QVector< const Partition* >& pvList )
{
DeviceInfo* deviceInfo = infoForDevice( device );
Q_ASSERT( deviceInfo );
ResizeVolumeGroupJob* job = new ResizeVolumeGroupJob( device, pvList );
deviceInfo->jobs << Calamares::job_ptr( job );
refresh();
}
void
PartitionCoreModule::deactivateVolumeGroup( LvmDevice *device )
{
DeviceInfo* deviceInfo = infoForDevice( device );
Q_ASSERT( deviceInfo );
deviceInfo->isAvailable = false;
DeactivateVolumeGroupJob* job = new DeactivateVolumeGroupJob( device );
// DeactivateVolumeGroupJob needs to be immediately called
job->exec();
refresh();
}
void
PartitionCoreModule::removeVolumeGroup( LvmDevice *device )
{
DeviceInfo* deviceInfo = infoForDevice( device );
Q_ASSERT( deviceInfo );
RemoveVolumeGroupJob* job = new RemoveVolumeGroupJob( device );
deviceInfo->jobs << Calamares::job_ptr( job );
refresh();
}
void void
PartitionCoreModule::deletePartition( Device* device, Partition* partition ) PartitionCoreModule::deletePartition( Device* device, Partition* partition )
{ {
@ -435,6 +516,37 @@ PartitionCoreModule::efiSystemPartitions() const
return m_efiSystemPartitions; return m_efiSystemPartitions;
} }
QVector< const Partition* >
PartitionCoreModule::lvmPVs() const
{
return m_lvmPVs;
}
bool
PartitionCoreModule::hasVGwithThisName( const QString& name ) const
{
for ( DeviceInfo* d : m_deviceInfos )
if ( dynamic_cast<LvmDevice*>(d->device.data()) &&
d->device.data()->name() == name)
return true;
return false;
}
bool
PartitionCoreModule::isInVG( const Partition *partition ) const
{
for ( DeviceInfo* d : m_deviceInfos )
{
LvmDevice* vg = dynamic_cast<LvmDevice*>( d->device.data() );
if ( vg && vg->physicalVolumes().contains( partition ))
return true;
}
return false;
}
void void
PartitionCoreModule::dumpQueue() const PartitionCoreModule::dumpQueue() const
{ {
@ -474,6 +586,8 @@ PartitionCoreModule::refresh()
updateIsDirty(); updateIsDirty();
m_bootLoaderModel->update(); m_bootLoaderModel->update();
scanForLVMPVs();
//FIXME: this should be removed in favor of //FIXME: this should be removed in favor of
// proper KPM support for EFI // proper KPM support for EFI
if ( PartUtils::isEfiSystem() ) if ( PartUtils::isEfiSystem() )
@ -526,6 +640,80 @@ PartitionCoreModule::scanForEfiSystemPartitions()
m_efiSystemPartitions = efiSystemPartitions; m_efiSystemPartitions = efiSystemPartitions;
} }
void
PartitionCoreModule::scanForLVMPVs()
{
m_lvmPVs.clear();
QList< Device* > physicalDevices;
QList< LvmDevice* > vgDevices;
for ( DeviceInfo* deviceInfo : m_deviceInfos )
{
if ( deviceInfo->device.data()->type() == Device::Type::Disk_Device)
physicalDevices << deviceInfo->device.data();
else if ( deviceInfo->device.data()->type() == Device::Type::LVM_Device )
{
LvmDevice* device = dynamic_cast<LvmDevice*>(deviceInfo->device.data());
// Restoring physical volume list
device->physicalVolumes().clear();
vgDevices << device;
}
}
// Update LVM::pvList
LvmDevice::scanSystemLVM( physicalDevices );
for ( auto p : LVM::pvList )
{
m_lvmPVs << p.partition().data();
for ( LvmDevice* device : vgDevices )
if ( p.vgName() == device->name() )
{
// Adding scanned VG to PV list
device->physicalVolumes() << p.partition();
break;
}
}
for ( DeviceInfo* d : m_deviceInfos )
{
for ( auto job : d->jobs )
{
// Including new LVM PVs
CreatePartitionJob* partJob = dynamic_cast<CreatePartitionJob*>( job.data() );
if ( partJob )
{
Partition* p = partJob->partition();
if ( p->fileSystem().type() == FileSystem::Type::Lvm2_PV )
m_lvmPVs << p;
else if ( p->fileSystem().type() == FileSystem::Type::Luks )
{
// Encrypted LVM PVs
FileSystem* innerFS = static_cast<const FS::luks*>(&p->fileSystem())->innerFS();
if ( innerFS && innerFS->type() == FileSystem::Type::Lvm2_PV )
m_lvmPVs << p;
}
#ifdef WITH_KPMCOREGT33
else if ( p->fileSystem().type() == FileSystem::Type::Luks2 )
{
// Encrypted LVM PVs
FileSystem* innerFS = static_cast<const FS::luks*>(&p->fileSystem())->innerFS();
if ( innerFS && innerFS->type() == FileSystem::Type::Lvm2_PV )
m_lvmPVs << p;
}
#endif
}
}
}
}
PartitionCoreModule::DeviceInfo* PartitionCoreModule::DeviceInfo*
PartitionCoreModule::infoForDevice( const Device* device ) const PartitionCoreModule::infoForDevice( const Device* device ) const
{ {
@ -575,8 +763,36 @@ PartitionCoreModule::revert()
void void
PartitionCoreModule::revertAllDevices() PartitionCoreModule::revertAllDevices()
{ {
foreach ( DeviceInfo* devInfo, m_deviceInfos ) for ( auto it = m_deviceInfos.begin(); it != m_deviceInfos.end(); )
revertDevice( devInfo->device.data() ); {
// In new VGs device info, there will be always a CreateVolumeGroupJob as the first job in jobs list
if ( dynamic_cast<LvmDevice*>( ( *it )->device.data() ) )
{
( *it )->isAvailable = true;
if ( !( *it )->jobs.empty() )
{
CreateVolumeGroupJob* vgJob = dynamic_cast<CreateVolumeGroupJob*>( ( *it )->jobs[0].data() );
if ( vgJob )
{
vgJob->undoPreview();
( *it )->forgetChanges();
m_deviceModel->removeDevice( ( *it )->device.data() );
it = m_deviceInfos.erase( it );
continue;
}
}
}
revertDevice( ( *it )->device.data() );
++it;
}
refresh(); refresh();
} }
@ -586,6 +802,7 @@ PartitionCoreModule::revertDevice( Device* dev )
{ {
QMutexLocker locker( &m_revertMutex ); QMutexLocker locker( &m_revertMutex );
DeviceInfo* devInfo = infoForDevice( dev ); DeviceInfo* devInfo = infoForDevice( dev );
if ( !devInfo ) if ( !devInfo )
return; return;
devInfo->forgetChanges(); devInfo->forgetChanges();
@ -597,8 +814,13 @@ PartitionCoreModule::revertDevice( Device* dev )
m_deviceModel->swapDevice( dev, newDev ); m_deviceModel->swapDevice( dev, newDev );
QList< Device* > devices; QList< Device* > devices;
foreach ( auto info, m_deviceInfos ) for ( auto info : m_deviceInfos )
devices.append( info->device.data() ); {
if ( info->device.data()->type() != Device::Type::Disk_Device )
continue;
else
devices.append( info->device.data() );
}
m_bootLoaderModel->init( devices ); m_bootLoaderModel->init( devices );
@ -638,6 +860,16 @@ PartitionCoreModule::isDirty()
return m_isDirty; return m_isDirty;
} }
bool
PartitionCoreModule::isVGdeactivated( LvmDevice *device )
{
for ( DeviceInfo* deviceInfo : m_deviceInfos )
if ( device == deviceInfo->device.data() && !deviceInfo->isAvailable )
return true;
return false;
}
QList< PartitionCoreModule::SummaryInfo > QList< PartitionCoreModule::SummaryInfo >
PartitionCoreModule::createSummaryInfo() const PartitionCoreModule::createSummaryInfo() const
{ {

View File

@ -24,6 +24,7 @@
#include "Typedefs.h" #include "Typedefs.h"
// KPMcore // KPMcore
#include <kpmcore/core/lvmdevice.h>
#include <kpmcore/core/partitiontable.h> #include <kpmcore/core/partitiontable.h>
// Qt // Qt
@ -111,6 +112,14 @@ public:
void createPartition( Device* device, Partition* partition, void createPartition( Device* device, Partition* partition,
PartitionTable::Flags flags = PartitionTable::FlagNone ); PartitionTable::Flags flags = PartitionTable::FlagNone );
void createVolumeGroup( QString &vgName, QVector< const Partition* > pvList, qint32 peSize );
void resizeVolumeGroup( LvmDevice* device, QVector< const Partition* >& pvList );
void deactivateVolumeGroup( LvmDevice* device );
void removeVolumeGroup( LvmDevice* device );
void deletePartition( Device* device, Partition* partition ); void deletePartition( Device* device, Partition* partition );
void formatPartition( Device* device, Partition* partition ); void formatPartition( Device* device, Partition* partition );
@ -132,6 +141,12 @@ public:
QList< Partition* > efiSystemPartitions() const; QList< Partition* > efiSystemPartitions() const;
QVector< const Partition* > lvmPVs() const;
bool hasVGwithThisName( const QString& name ) const;
bool isInVG( const Partition* partition ) const;
/** /**
* @brief findPartitionByMountPoint returns a Partition* for a given mount point. * @brief findPartitionByMountPoint returns a Partition* for a given mount point.
* @param mountPoint the mount point to find a partition for. * @param mountPoint the mount point to find a partition for.
@ -151,6 +166,8 @@ public:
bool isDirty(); // true if there are pending changes, otherwise false bool isDirty(); // true if there are pending changes, otherwise false
bool isVGdeactivated( LvmDevice* device );
/** /**
* To be called when a partition has been altered, but only for changes * To be called when a partition has been altered, but only for changes
* which do not affect its size, because changes which affect the partition size * which do not affect its size, because changes which affect the partition size
@ -189,11 +206,15 @@ private:
const QScopedPointer< Device > immutableDevice; const QScopedPointer< Device > immutableDevice;
QList< Calamares::job_ptr > jobs; QList< Calamares::job_ptr > jobs;
// To check if LVM VGs are deactivated
bool isAvailable;
void forgetChanges(); void forgetChanges();
bool isDirty() const; bool isDirty() const;
}; };
QList< DeviceInfo* > m_deviceInfos; QList< DeviceInfo* > m_deviceInfos;
QList< Partition* > m_efiSystemPartitions; QList< Partition* > m_efiSystemPartitions;
QVector< const Partition* > m_lvmPVs;
DeviceModel* m_deviceModel; DeviceModel* m_deviceModel;
BootLoaderModel* m_bootLoaderModel; BootLoaderModel* m_bootLoaderModel;
@ -205,6 +226,7 @@ private:
void updateHasRootMountPoint(); void updateHasRootMountPoint();
void updateIsDirty(); void updateIsDirty();
void scanForEfiSystemPartitions(); void scanForEfiSystemPartitions();
void scanForLVMPVs();
DeviceInfo* infoForDevice( const Device* ) const; DeviceInfo* infoForDevice( const Device* ) const;

View File

@ -20,6 +20,7 @@
#include "core/PartitionInfo.h" #include "core/PartitionInfo.h"
// KPMcore // KPMcore
#include <kpmcore/core/lvmdevice.h>
#include <kpmcore/core/partition.h> #include <kpmcore/core/partition.h>
// Qt // Qt
@ -80,6 +81,9 @@ reset( Partition* partition )
bool bool
isDirty( Partition* partition ) isDirty( Partition* partition )
{ {
if ( LvmDevice::s_DirtyPVs.contains( partition ) )
return true;
return !mountPoint( partition ).isEmpty() return !mountPoint( partition ).isEmpty()
|| format( partition ) || format( partition )
|| flags( partition ) != partition->activeFlags(); || flags( partition ) != partition->activeFlags();

View File

@ -0,0 +1,56 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2018, Caio Jordão Carvalho <caiojcarvalho@gmail.com>
*
* 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 "CreateVolumeGroupDialog.h"
#include <kpmcore/core/device.h>
#include <kpmcore/core/lvmdevice.h>
#include <QComboBox>
#include <QLineEdit>
#include <QSpinBox>
CreateVolumeGroupDialog::CreateVolumeGroupDialog( QString& vgName,
QVector< const Partition* >& selectedPVs,
QVector< const Partition* > pvList,
qint64& pSize,
QWidget* parent )
: VolumeGroupBaseDialog( vgName, pvList, parent )
, m_selectedPVs( selectedPVs )
, m_peSize( pSize )
{
setWindowTitle( "Create Volume Group" );
peSize()->setValue( pSize );
vgType()->setEnabled( false );
}
void
CreateVolumeGroupDialog::accept()
{
QString& name = vgNameValue();
name = vgName()->text();
m_selectedPVs << checkedItems();
qint64& pe = m_peSize;
pe = peSize()->value();
QDialog::accept();
}

View File

@ -0,0 +1,41 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2018, Caio Jordão Carvalho <caiojcarvalho@gmail.com>
*
* 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 CREATEVOLUMEGROUPDIALOG_H
#define CREATEVOLUMEGROUPDIALOG_H
#include "gui/VolumeGroupBaseDialog.h"
class CreateVolumeGroupDialog : public VolumeGroupBaseDialog
{
public:
CreateVolumeGroupDialog( QString& vgName,
QVector< const Partition* >& selectedPVs,
QVector< const Partition* > pvList,
qint64& pSize,
QWidget* parent );
void accept() override;
private:
QVector< const Partition* >& m_selectedPVs;
qint64& m_peSize;
};
#endif // CREATEVOLUMEGROUPDIALOG_H

View File

@ -0,0 +1,36 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2018, Caio Jordão Carvalho <caiojcarvalho@gmail.com>
*
* 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 "ListPhysicalVolumeWidgetItem.h"
#include <kpmcore/util/capacity.h>
ListPhysicalVolumeWidgetItem::ListPhysicalVolumeWidgetItem( const Partition* partition, bool checked )
: QListWidgetItem(QString("%1 | %2").arg( partition->deviceNode(), Capacity::formatByteSize( partition->capacity() )))
, m_partition(partition)
{
setToolTip( partition->deviceNode() );
setSizeHint( QSize(0, 32) );
setCheckState( checked ? Qt::Checked : Qt::Unchecked );
}
const Partition*
ListPhysicalVolumeWidgetItem::partition() const
{
return m_partition;
}

View File

@ -0,0 +1,37 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2018, Caio Jordão Carvalho <caiojcarvalho@gmail.com>
*
* 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 LISTPHYSICALVOLUMEWIDGETITEM_H
#define LISTPHYSICALVOLUMEWIDGETITEM_H
#include <kpmcore/core/partition.h>
#include <QListWidgetItem>
class ListPhysicalVolumeWidgetItem : public QListWidgetItem
{
public:
ListPhysicalVolumeWidgetItem( const Partition* partition, bool checked );
const Partition* partition() const;
private:
const Partition* m_partition;
};
#endif // LISTPHYSICALVOLUMEWIDGETITEM_H

View File

@ -30,7 +30,9 @@
#include "core/PartUtils.h" #include "core/PartUtils.h"
#include "core/KPMHelpers.h" #include "core/KPMHelpers.h"
#include "gui/CreatePartitionDialog.h" #include "gui/CreatePartitionDialog.h"
#include "gui/CreateVolumeGroupDialog.h"
#include "gui/EditExistingPartitionDialog.h" #include "gui/EditExistingPartitionDialog.h"
#include "gui/ResizeVolumeGroupDialog.h"
#include "gui/ScanningDialog.h" #include "gui/ScanningDialog.h"
#include "ui_PartitionPage.h" #include "ui_PartitionPage.h"
@ -45,6 +47,8 @@
// KPMcore // KPMcore
#include <kpmcore/core/device.h> #include <kpmcore/core/device.h>
#include <kpmcore/core/partition.h> #include <kpmcore/core/partition.h>
#include <kpmcore/ops/deactivatevolumegroupoperation.h>
#include <kpmcore/ops/removevolumegroupoperation.h>
// Qt // Qt
#include <QDebug> #include <QDebug>
@ -102,6 +106,10 @@ PartitionPage::PartitionPage( PartitionCoreModule* core, QWidget* parent )
connect( m_ui->partitionTreeView, &QAbstractItemView::doubleClicked, this, &PartitionPage::onPartitionViewActivated ); connect( m_ui->partitionTreeView, &QAbstractItemView::doubleClicked, this, &PartitionPage::onPartitionViewActivated );
connect( m_ui->revertButton, &QAbstractButton::clicked, this, &PartitionPage::onRevertClicked ); connect( m_ui->revertButton, &QAbstractButton::clicked, this, &PartitionPage::onRevertClicked );
connect( m_ui->newVolumeGroupButton, &QAbstractButton::clicked, this, &PartitionPage::onNewVolumeGroupClicked );
connect( m_ui->resizeVolumeGroupButton, &QAbstractButton::clicked, this, &PartitionPage::onResizeVolumeGroupClicked );
connect( m_ui->deactivateVolumeGroupButton, &QAbstractButton::clicked, this, &PartitionPage::onDeactivateVolumeGroupClicked );
connect( m_ui->removeVolumeGroupButton, &QAbstractButton::clicked, this, &PartitionPage::onRemoveVolumeGroupClicked );
connect( m_ui->newPartitionTableButton, &QAbstractButton::clicked, this, &PartitionPage::onNewPartitionTableClicked ); connect( m_ui->newPartitionTableButton, &QAbstractButton::clicked, this, &PartitionPage::onNewPartitionTableClicked );
connect( m_ui->createButton, &QAbstractButton::clicked, this, &PartitionPage::onCreateClicked ); connect( m_ui->createButton, &QAbstractButton::clicked, this, &PartitionPage::onCreateClicked );
connect( m_ui->editButton, &QAbstractButton::clicked, this, &PartitionPage::onEditClicked ); connect( m_ui->editButton, &QAbstractButton::clicked, this, &PartitionPage::onEditClicked );
@ -122,7 +130,8 @@ PartitionPage::~PartitionPage()
void void
PartitionPage::updateButtons() PartitionPage::updateButtons()
{ {
bool create = false, createTable = false, edit = false, del = false; bool create = false, createTable = false, edit = false, del = false, currentDeviceIsVG = false, isDeactivable = false;
bool isRemovable = false, isVGdeactivated = false;
QModelIndex index = m_ui->partitionTreeView->currentIndex(); QModelIndex index = m_ui->partitionTreeView->currentIndex();
if ( index.isValid() ) if ( index.isValid() )
@ -134,6 +143,8 @@ PartitionPage::updateButtons()
bool isFree = KPMHelpers::isPartitionFreeSpace( partition ); bool isFree = KPMHelpers::isPartitionFreeSpace( partition );
bool isExtended = partition->roles().has( PartitionRole::Extended ); bool isExtended = partition->roles().has( PartitionRole::Extended );
bool isInVG = m_core->isInVG( partition );
create = isFree; create = isFree;
// Keep it simple for now: do not support editing extended partitions as // Keep it simple for now: do not support editing extended partitions as
// it does not work with our current edit implementation which is // it does not work with our current edit implementation which is
@ -141,8 +152,9 @@ PartitionPage::updateButtons()
// because they need to be created *before* creating logical partitions // because they need to be created *before* creating logical partitions
// inside them, so an edit must be applied without altering the job // inside them, so an edit must be applied without altering the job
// order. // order.
// TODO: See if LVM PVs can be edited in Calamares
edit = !isFree && !isExtended; edit = !isFree && !isExtended;
del = !isFree; del = !isFree && !isInVG;
} }
if ( m_ui->deviceComboBox->currentIndex() >= 0 ) if ( m_ui->deviceComboBox->currentIndex() >= 0 )
@ -150,12 +162,29 @@ PartitionPage::updateButtons()
QModelIndex deviceIndex = m_core->deviceModel()->index( m_ui->deviceComboBox->currentIndex(), 0 ); QModelIndex deviceIndex = m_core->deviceModel()->index( m_ui->deviceComboBox->currentIndex(), 0 );
if ( m_core->deviceModel()->deviceForIndex( deviceIndex )->type() != Device::Type::LVM_Device ) if ( m_core->deviceModel()->deviceForIndex( deviceIndex )->type() != Device::Type::LVM_Device )
createTable = true; createTable = true;
else
{
currentDeviceIsVG = true;
LvmDevice* lvmDevice = dynamic_cast<LvmDevice*>(m_core->deviceModel()->deviceForIndex( deviceIndex ));
isDeactivable = DeactivateVolumeGroupOperation::isDeactivatable( lvmDevice );
isRemovable = RemoveVolumeGroupOperation::isRemovable( lvmDevice );
isVGdeactivated = m_core->isVGdeactivated( lvmDevice );
if ( isVGdeactivated )
m_ui->revertButton->setEnabled( true );
}
} }
m_ui->createButton->setEnabled( create ); m_ui->createButton->setEnabled( create );
m_ui->editButton->setEnabled( edit ); m_ui->editButton->setEnabled( edit );
m_ui->deleteButton->setEnabled( del ); m_ui->deleteButton->setEnabled( del );
m_ui->newPartitionTableButton->setEnabled( createTable ); m_ui->newPartitionTableButton->setEnabled( createTable );
m_ui->resizeVolumeGroupButton->setEnabled( currentDeviceIsVG && !isVGdeactivated );
m_ui->deactivateVolumeGroupButton->setEnabled( currentDeviceIsVG && isDeactivable && !isVGdeactivated );
m_ui->removeVolumeGroupButton->setEnabled( currentDeviceIsVG && isRemovable );
} }
void void
@ -204,6 +233,114 @@ PartitionPage::checkCanCreate( Device* device )
return true; // GPT is fine return true; // GPT is fine
} }
void
PartitionPage::onNewVolumeGroupClicked()
{
QString vgName;
QVector< const Partition* > selectedPVs;
qint64 peSize = 4;
QVector< const Partition* > availablePVs;
for ( const Partition* p : m_core->lvmPVs() )
if ( !m_core->isInVG( p ) )
availablePVs << p;
QPointer< CreateVolumeGroupDialog > dlg = new CreateVolumeGroupDialog( vgName,
selectedPVs,
availablePVs,
peSize,
this );
if ( dlg->exec() == QDialog::Accepted )
{
QModelIndex partitionIndex = m_ui->partitionTreeView->currentIndex();
if ( partitionIndex.isValid() )
{
const PartitionModel* model = static_cast< const PartitionModel* >( partitionIndex.model() );
Q_ASSERT( model );
Partition* partition = model->partitionForIndex( partitionIndex );
Q_ASSERT( partition );
// Disable delete button if current partition was selected to be in VG
// TODO: Should Calamares edit LVM PVs which are in VGs?
if ( selectedPVs.contains( partition ) )
m_ui->deleteButton->setEnabled( false );
}
QModelIndex deviceIndex = m_core->deviceModel()->index( m_ui->deviceComboBox->currentIndex(), 0 );
Q_ASSERT( deviceIndex.isValid() );
QVariant previousIndexDeviceData = m_core->deviceModel()->data( deviceIndex, Qt::ToolTipRole );
// Creating new VG
m_core->createVolumeGroup( vgName, selectedPVs, peSize );
// As createVolumeGroup method call resets deviceModel,
// is needed to set the current index in deviceComboBox as the previous one
int previousIndex = m_ui->deviceComboBox->findData( previousIndexDeviceData, Qt::ToolTipRole );
m_ui->deviceComboBox->setCurrentIndex( ( previousIndex < 0 ) ? 0 : previousIndex );
updateFromCurrentDevice();
}
delete dlg;
}
void
PartitionPage::onResizeVolumeGroupClicked()
{
QModelIndex deviceIndex = m_core->deviceModel()->index( m_ui->deviceComboBox->currentIndex(), 0 );
LvmDevice* device = dynamic_cast< LvmDevice* >( m_core->deviceModel()->deviceForIndex( deviceIndex ) );
Q_ASSERT( device && device->type() == Device::Type::LVM_Device );
QVector< const Partition* > availablePVs;
QVector< const Partition* > selectedPVs;
for ( const Partition* p : m_core->lvmPVs() )
if ( !m_core->isInVG( p ) )
availablePVs << p;
QPointer< ResizeVolumeGroupDialog > dlg = new ResizeVolumeGroupDialog( device,
availablePVs,
selectedPVs,
this );
if ( dlg->exec() == QDialog::Accepted )
m_core->resizeVolumeGroup( device, selectedPVs );
delete dlg;
}
void
PartitionPage::onDeactivateVolumeGroupClicked()
{
QModelIndex deviceIndex = m_core->deviceModel()->index( m_ui->deviceComboBox->currentIndex(), 0 );
LvmDevice* device = dynamic_cast< LvmDevice* >( m_core->deviceModel()->deviceForIndex( deviceIndex ) );
Q_ASSERT( device && device->type() == Device::Type::LVM_Device );
m_core->deactivateVolumeGroup( device );
updateFromCurrentDevice();
PartitionModel* model = m_core->partitionModelForDevice( device );
model->update();
}
void
PartitionPage::onRemoveVolumeGroupClicked()
{
QModelIndex deviceIndex = m_core->deviceModel()->index( m_ui->deviceComboBox->currentIndex(), 0 );
LvmDevice* device = dynamic_cast< LvmDevice* >( m_core->deviceModel()->deviceForIndex( deviceIndex ) );
Q_ASSERT( device && device->type() == Device::Type::LVM_Device );
m_core->removeVolumeGroup( device );
}
void void
PartitionPage::onCreateClicked() PartitionPage::onCreateClicked()
{ {
@ -272,7 +409,7 @@ PartitionPage::onRevertClicked()
int oldIndex = m_ui->deviceComboBox->currentIndex(); int oldIndex = m_ui->deviceComboBox->currentIndex();
m_core->revertAllDevices(); m_core->revertAllDevices();
m_ui->deviceComboBox->setCurrentIndex( oldIndex ); m_ui->deviceComboBox->setCurrentIndex( ( oldIndex < 0 ) ? 0 : oldIndex );
updateFromCurrentDevice(); updateFromCurrentDevice();
} ), } ),
[ this ]{ [ this ]{

View File

@ -51,6 +51,10 @@ private:
PartitionCoreModule* m_core; PartitionCoreModule* m_core;
void updateButtons(); void updateButtons();
void onNewPartitionTableClicked(); void onNewPartitionTableClicked();
void onNewVolumeGroupClicked();
void onResizeVolumeGroupClicked();
void onDeactivateVolumeGroupClicked();
void onRemoveVolumeGroupClicked();
void onCreateClicked(); void onCreateClicked();
void onEditClicked(); void onEditClicked();
void onDeleteClicked(); void onDeleteClicked();

View File

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>655</width> <width>684</width>
<height>304</height> <height>304</height>
</rect> </rect>
</property> </property>
@ -124,6 +124,38 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QPushButton" name="newVolumeGroupButton">
<property name="text">
<string>New Volume Group</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="resizeVolumeGroupButton">
<property name="text">
<string>Resize Volume Group</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deactivateVolumeGroupButton">
<property name="text">
<string>Deactivate Volume Group</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeVolumeGroupButton">
<property name="text">
<string>Remove Volume Group</string>
</property>
</widget>
</item>
</layout>
</item>
<item> <item>
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">
@ -145,7 +177,7 @@
<item> <item>
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="label_3">
<property name="text"> <property name="text">
<string>Install boot &amp;loader on:</string> <string>I&amp;nstall boot loader on:</string>
</property> </property>
<property name="buddy"> <property name="buddy">
<cstring>bootLoaderComboBox</cstring> <cstring>bootLoaderComboBox</cstring>

View File

@ -0,0 +1,62 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2018, Caio Jordão Carvalho <caiojcarvalho@gmail.com>
*
* 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 "ResizeVolumeGroupDialog.h"
#include "gui/ListPhysicalVolumeWidgetItem.h"
#include <kpmcore/core/lvmdevice.h>
#include <kpmcore/util/capacity.h>
#include <QComboBox>
#include <QLineEdit>
#include <QListWidgetItem>
#include <QSpinBox>
ResizeVolumeGroupDialog::ResizeVolumeGroupDialog( LvmDevice *device,
QVector< const Partition* > availablePVs,
QVector< const Partition* >& selectedPVs,
QWidget* parent )
: VolumeGroupBaseDialog( device->name(), device->physicalVolumes(), parent )
, m_selectedPVs( selectedPVs )
{
setWindowTitle( "Resize Volume Group" );
for ( int i = 0; i < pvList()->count(); i++ )
pvList()->item(i)->setCheckState( Qt::Checked );
for ( const Partition* p : availablePVs )
pvList()->addItem( new ListPhysicalVolumeWidgetItem( p, false ) );
peSize()->setValue( device->peSize() / Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB) );
vgName()->setEnabled( false );
peSize()->setEnabled( false );
vgType()->setEnabled( false );
setUsedSizeValue( device->allocatedPE() * device->peSize() );
setLVQuantity( device->partitionTable()->children().count() );
}
void
ResizeVolumeGroupDialog::accept()
{
m_selectedPVs << checkedItems();
QDialog::accept();
}

View File

@ -0,0 +1,40 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2018, Caio Jordão Carvalho <caiojcarvalho@gmail.com>
*
* 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 RESIZEVOLUMEGROUPDIALOG_H
#define RESIZEVOLUMEGROUPDIALOG_H
#include "gui/VolumeGroupBaseDialog.h"
class LvmDevice;
class ResizeVolumeGroupDialog : public VolumeGroupBaseDialog
{
public:
ResizeVolumeGroupDialog( LvmDevice *device,
QVector< const Partition* > availablePVs,
QVector< const Partition* >& selectedPVs,
QWidget* parent );
void accept() override;
private:
QVector< const Partition* >& m_selectedPVs;
};
#endif // RESIZEVOLUMEGROUPDIALOG_H

View File

@ -0,0 +1,184 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2018, Caio Jordão Carvalho <caiojcarvalho@gmail.com>
*
* 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 "VolumeGroupBaseDialog.h"
#include "ui_VolumeGroupBaseDialog.h"
#include "gui/ListPhysicalVolumeWidgetItem.h"
#include <kpmcore/util/capacity.h>
#include <QComboBox>
#include <QDialogButtonBox>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QSpinBox>
VolumeGroupBaseDialog::VolumeGroupBaseDialog( QString& vgName,
QVector< const Partition* > pvList,
QWidget *parent )
: QDialog(parent)
, ui(new Ui::VolumeGroupBaseDialog)
, m_vgNameValue(vgName)
, m_totalSizeValue(0)
, m_usedSizeValue(0)
{
ui->setupUi(this);
for ( const Partition* p : pvList )
ui->pvList->addItem( new ListPhysicalVolumeWidgetItem( p, false ) );
ui->vgType->addItems( QStringList() << "LVM" << "RAID" );
ui->vgType->setCurrentIndex(0);
QRegularExpression re(R"(^(?!_|\.)[\w\-.+]+)");
ui->vgName->setValidator( new QRegularExpressionValidator( re, this ) );
ui->vgName->setText( m_vgNameValue );
updateOkButton();
updateTotalSize();
connect( ui->pvList, &QListWidget::itemChanged, this,
[&](QListWidgetItem*) {
updateTotalSize();
updateOkButton();
} );
connect( ui->peSize, qOverload<int>(&QSpinBox::valueChanged), this,
[&](int) {
updateTotalSectors();
updateOkButton();
});
connect( ui->vgName, &QLineEdit::textChanged, this,
[&](const QString&) {
updateOkButton();
});
}
VolumeGroupBaseDialog::~VolumeGroupBaseDialog()
{
delete ui;
}
QVector< const Partition* >
VolumeGroupBaseDialog::checkedItems() const
{
QVector< const Partition* > items;
for ( int i = 0; i < ui->pvList->count(); i++) {
ListPhysicalVolumeWidgetItem* item = dynamic_cast< ListPhysicalVolumeWidgetItem* >( ui->pvList->item(i) );
if ( item && item->checkState() == Qt::Checked )
items << item->partition();
}
return items;
}
bool
VolumeGroupBaseDialog::isSizeValid() const
{
return m_totalSizeValue >= m_usedSizeValue;
}
void
VolumeGroupBaseDialog::updateOkButton()
{
okButton()->setEnabled(isSizeValid() &&
!checkedItems().empty() &&
!ui->vgName->text().isEmpty() &&
ui->peSize->value() > 0);
}
void
VolumeGroupBaseDialog::setUsedSizeValue( qint64 usedSize )
{
m_usedSizeValue = usedSize;
ui->usedSize->setText( Capacity::formatByteSize(m_usedSizeValue) );
}
void
VolumeGroupBaseDialog::setLVQuantity( qint32 lvQuantity )
{
ui->lvQuantity->setText( QString::number( lvQuantity ) );
}
void
VolumeGroupBaseDialog::updateTotalSize()
{
m_totalSizeValue = 0;
for ( const Partition *p : checkedItems())
m_totalSizeValue += p->capacity() - p->capacity() % (ui->peSize->value() * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB));
ui->totalSize->setText(Capacity::formatByteSize(m_totalSizeValue));
updateTotalSectors();
}
void
VolumeGroupBaseDialog::updateTotalSectors()
{
qint32 totalSectors = 0;
qint32 extentSize = ui->peSize->value() * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
if ( extentSize > 0 )
totalSectors = m_totalSizeValue / extentSize;
ui->totalSectors->setText( QString::number( totalSectors ) );
}
QString&
VolumeGroupBaseDialog::vgNameValue() const
{
return m_vgNameValue;
}
QLineEdit*
VolumeGroupBaseDialog::vgName() const
{
return ui->vgName;
}
QComboBox*
VolumeGroupBaseDialog::vgType() const
{
return ui->vgType;
}
QSpinBox*
VolumeGroupBaseDialog::peSize() const
{
return ui->peSize;
}
QListWidget*
VolumeGroupBaseDialog::pvList() const
{
return ui->pvList;
}
QPushButton*
VolumeGroupBaseDialog::okButton() const
{
return ui->buttonBox->button( QDialogButtonBox::StandardButton::Ok );
}

View File

@ -0,0 +1,81 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2018, Caio Jordão Carvalho <caiojcarvalho@gmail.com>
*
* 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 VOLUMEGROUPBASEDIALOG_H
#define VOLUMEGROUPBASEDIALOG_H
#include <kpmcore/core/partition.h>
#include <QDialog>
namespace Ui {
class VolumeGroupBaseDialog;
}
class QComboBox;
class QLineEdit;
class QListWidget;
class QSpinBox;
class VolumeGroupBaseDialog : public QDialog
{
Q_OBJECT
public:
explicit VolumeGroupBaseDialog( QString& vgName,
QVector< const Partition* > pvList,
QWidget* parent = nullptr );
~VolumeGroupBaseDialog();
protected:
virtual void updateOkButton();
void setUsedSizeValue( qint64 usedSize );
void setLVQuantity( qint32 lvQuantity );
void updateTotalSize();
void updateTotalSectors();
QVector< const Partition* > checkedItems() const;
bool isSizeValid() const;
QString& vgNameValue() const;
QLineEdit* vgName() const;
QComboBox* vgType() const;
QSpinBox* peSize() const;
QListWidget* pvList() const;
QPushButton* okButton() const;
private:
Ui::VolumeGroupBaseDialog* ui;
QString& m_vgNameValue;
qint64 m_totalSizeValue;
qint64 m_usedSizeValue;
};
#endif // VOLUMEGROUPBASEDIALOG_H

View File

@ -0,0 +1,206 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>VolumeGroupBaseDialog</class>
<widget class="QDialog" name="VolumeGroupBaseDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>611</width>
<height>367</height>
</rect>
</property>
<property name="windowTitle">
<string>VolumeGroupDialog</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="pvListLabel">
<property name="text">
<string>List of Physical Volumes</string>
</property>
</widget>
</item>
<item row="1" column="0" rowspan="7">
<widget class="QListWidget" name="pvList"/>
</item>
<item row="1" column="1">
<widget class="QLabel" name="vgNameLabel">
<property name="text">
<string>Volume Group Name:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="vgName"/>
</item>
<item row="2" column="1">
<widget class="QLabel" name="vgTypeLabel">
<property name="text">
<string>Volume Group Type:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QComboBox" name="vgType"/>
</item>
<item row="3" column="1">
<widget class="QLabel" name="peSizeLabel">
<property name="text">
<string>Physical Extent Size:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QSpinBox" name="peSize">
<property name="suffix">
<string> MiB</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>999</number>
</property>
<property name="value">
<number>4</number>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="totalSizeLabel">
<property name="text">
<string>Total Size:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QLabel" name="totalSize">
<property name="text">
<string>---</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="usedSizeLabel">
<property name="text">
<string>Used Size:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLabel" name="usedSize">
<property name="text">
<string>---</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="totalSectorsLabel">
<property name="text">
<string>Total Sectors:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QLabel" name="totalSectors">
<property name="text">
<string>---</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLabel" name="lvQuantityLabel">
<property name="text">
<string>Quantity of LVs:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QLabel" name="lvQuantity">
<property name="text">
<string>---</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="8" column="0" colspan="3">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>VolumeGroupBaseDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>VolumeGroupBaseDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,84 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2018, Caio Jordão Carvalho <caiojcarvalho@gmail.com>
*
* 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 "CreateVolumeGroupJob.h"
// KPMcore
#include <kpmcore/core/lvmdevice.h>
#include <kpmcore/core/partition.h>
#include <kpmcore/ops/createvolumegroupoperation.h>
#include <kpmcore/util/report.h>
CreateVolumeGroupJob::CreateVolumeGroupJob( QString& vgName, QVector< const Partition* > pvList, const qint32 peSize )
: m_vgName(vgName)
, m_pvList(pvList)
, m_peSize(peSize)
{
}
QString
CreateVolumeGroupJob::prettyName() const
{
return tr( "Create new volume group named %1." )
.arg( m_vgName );
}
QString
CreateVolumeGroupJob::prettyDescription() const
{
return tr( "Create new volume group named <strong>%1</strong>." )
.arg( m_vgName );
}
QString
CreateVolumeGroupJob::prettyStatusMessage() const
{
return tr( "Creating new volume group named %1." )
.arg( m_vgName );
}
Calamares::JobResult
CreateVolumeGroupJob::exec()
{
Report report( nullptr );
CreateVolumeGroupOperation op( m_vgName, m_pvList, m_peSize );
op.setStatus( Operation::StatusRunning );
QString message = tr( "The installer failed to create a volume group named '%1'.").arg( m_vgName );
if (op.execute(report))
return Calamares::JobResult::ok();
return Calamares::JobResult::error(message, report.toText());
}
void
CreateVolumeGroupJob::updatePreview()
{
LvmDevice::s_DirtyPVs << m_pvList;
}
void
CreateVolumeGroupJob::undoPreview()
{
for ( const auto& pv : m_pvList )
if ( LvmDevice::s_DirtyPVs.contains( pv ))
LvmDevice::s_DirtyPVs.removeAll( pv );
}

View File

@ -0,0 +1,47 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2018, Caio Jordão Carvalho <caiojcarvalho@gmail.com>
*
* 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 CREATEVOLUMEGROUPJOB_H
#define CREATEVOLUMEGROUPJOB_H
#include <Job.h>
#include <kpmcore/core/partition.h>
#include <QVector>
class CreateVolumeGroupJob : public Calamares::Job
{
public:
CreateVolumeGroupJob( QString& vgName, QVector< const Partition* > pvList, const qint32 peSize );
QString prettyName() const override;
QString prettyDescription() const override;
QString prettyStatusMessage() const override;
Calamares::JobResult exec() override;
void updatePreview();
void undoPreview();
private:
QString m_vgName;
QVector< const Partition* > m_pvList;
qint32 m_peSize;
};
#endif // CREATEVOLUMEGROUPJOB_H

View File

@ -0,0 +1,69 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2018, Caio Jordão Carvalho <caiojcarvalho@gmail.com>
*
* 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 "DeactivateVolumeGroupJob.h"
#include <kpmcore/core/lvmdevice.h>
#include <kpmcore/ops/deactivatevolumegroupoperation.h>
#include <kpmcore/util/report.h>
DeactivateVolumeGroupJob::DeactivateVolumeGroupJob( LvmDevice* device )
: m_device( device )
{
}
QString
DeactivateVolumeGroupJob::prettyName() const
{
return tr( "Deactivate volume group named %1." )
.arg( m_device->name() );
}
QString
DeactivateVolumeGroupJob::prettyDescription() const
{
return tr( "Deactivate volume group named <strong>%1</strong>." )
.arg( m_device->name() );
}
QString
DeactivateVolumeGroupJob::prettyStatusMessage() const
{
return tr( "Deactivate volume group named %1." )
.arg( m_device->name() );
}
Calamares::JobResult
DeactivateVolumeGroupJob::exec()
{
Report report( nullptr );
DeactivateVolumeGroupOperation op( *m_device );
op.setStatus( Operation::OperationStatus::StatusRunning );
QString message = tr( "The installer failed to deactivate a volume group named %1." ).arg( m_device->name() );
if ( op.execute( report ) )
{
op.preview();
return Calamares::JobResult::ok();
}
return Calamares::JobResult::error(message, report.toText());
}

View File

@ -0,0 +1,40 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2018, Caio Jordão Carvalho <caiojcarvalho@gmail.com>
*
* 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 DEACTIVATEVOLUMEGROUPJOB_H
#define DEACTIVATEVOLUMEGROUPJOB_H
#include "Job.h"
class LvmDevice;
class DeactivateVolumeGroupJob : public Calamares::Job
{
public:
DeactivateVolumeGroupJob( LvmDevice* device );
QString prettyName() const override;
QString prettyDescription() const override;
QString prettyStatusMessage() const override;
Calamares::JobResult exec() override;
private:
LvmDevice* m_device;
};
#endif // DEACTIVATEVOLUMEGROUPJOB_H

View File

@ -0,0 +1,66 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2018, Caio Jordão Carvalho <caiojcarvalho@gmail.com>
*
* 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 "RemoveVolumeGroupJob.h"
#include <kpmcore/core/lvmdevice.h>
#include <kpmcore/ops/removevolumegroupoperation.h>
#include <kpmcore/util/report.h>
RemoveVolumeGroupJob::RemoveVolumeGroupJob( LvmDevice* device )
: m_device( device )
{
}
QString
RemoveVolumeGroupJob::prettyName() const
{
return tr( "Remove Volume Group named %1." )
.arg( m_device->name() );
}
QString
RemoveVolumeGroupJob::prettyDescription() const
{
return tr( "Remove Volume Group named <strong>%1</strong>.")
.arg( m_device->name() );
}
QString
RemoveVolumeGroupJob::prettyStatusMessage() const
{
return tr( "Remove Volume Group named %1." )
.arg( m_device->name() );
}
Calamares::JobResult
RemoveVolumeGroupJob::exec()
{
Report report( nullptr );
RemoveVolumeGroupOperation op( *m_device );
op.setStatus( Operation::OperationStatus::StatusRunning );
QString message = tr( "The installer failed to remove a volume group named '%1'." ).arg( m_device->name() );
if ( op.execute( report ) )
return Calamares::JobResult::ok();
return Calamares::JobResult::error(message, report.toText());
}

View File

@ -0,0 +1,40 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2018, Caio Jordão Carvalho <caiojcarvalho@gmail.com>
*
* 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 REMOVEVOLUMEGROUPJOB_H
#define REMOVEVOLUMEGROUPJOB_H
#include <Job.h>
class LvmDevice;
class RemoveVolumeGroupJob : public Calamares::Job
{
public:
RemoveVolumeGroupJob( LvmDevice* device );
QString prettyName() const override;
QString prettyDescription() const override;
QString prettyStatusMessage() const override;
Calamares::JobResult exec() override;
private:
LvmDevice* m_device;
};
#endif // REMOVEVOLUMEGROUPJOB_H

View File

@ -0,0 +1,101 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2018, Caio Jordão Carvalho <caiojcarvalho@gmail.com>
*
* 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 "ResizeVolumeGroupJob.h"
// KPMcore
#include <kpmcore/core/lvmdevice.h>
#include <kpmcore/core/partition.h>
#include <kpmcore/ops/resizevolumegroupoperation.h>
#include <kpmcore/util/report.h>
ResizeVolumeGroupJob::ResizeVolumeGroupJob( LvmDevice* device, QVector< const Partition* >& partitionList )
: m_device( device )
, m_partitionList( partitionList )
{
}
QString
ResizeVolumeGroupJob::prettyName() const
{
return tr( "Resize volume group named %1 from %2 to %3." )
.arg( m_device->name() )
.arg( currentPartitions() )
.arg( targetPartitions() );
}
QString
ResizeVolumeGroupJob::prettyDescription() const
{
return tr( "Resize volume group named <strong>%1</strong> from <strong>%2</strong> to <strong>%3</strong>." )
.arg( m_device->name() )
.arg( currentPartitions() )
.arg( targetPartitions() );
}
QString
ResizeVolumeGroupJob::prettyStatusMessage() const
{
return tr( "Resize volume group named %1 from %2 to %3." )
.arg( m_device->name() )
.arg( currentPartitions() )
.arg( targetPartitions() );
}
Calamares::JobResult
ResizeVolumeGroupJob::exec()
{
Report report( nullptr );
ResizeVolumeGroupOperation op( *m_device, m_partitionList );
op.setStatus( Operation::OperationStatus::StatusRunning );
QString message = tr( "The installer failed to resize a volume group named '%1'." ).arg( m_device->name() );
if ( op.execute( report ) )
return Calamares::JobResult::ok();
return Calamares::JobResult::error( message, report.toText() );
}
QString
ResizeVolumeGroupJob::currentPartitions() const
{
QString result;
for ( const Partition *p : m_device->physicalVolumes() )
result += p->deviceNode() + ", ";
result.chop(2);
return result;
}
QString
ResizeVolumeGroupJob::targetPartitions() const
{
QString result;
for ( const Partition *p : m_partitionList )
result += p->deviceNode() + ", ";
result.chop(2);
return result;
}

View File

@ -0,0 +1,48 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2018, Caio Jordão Carvalho <caiojcarvalho@gmail.com>
*
* 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 RESIZEVOLUMEGROUPJOB_H
#define RESIZEVOLUMEGROUPJOB_H
#include <Job.h>
#include <QVector>
class LvmDevice;
class Partition;
class ResizeVolumeGroupJob : public Calamares::Job
{
public:
ResizeVolumeGroupJob( LvmDevice* device, QVector< const Partition* >& partitionList );
QString prettyName() const override;
QString prettyDescription() const override;
QString prettyStatusMessage() const override;
Calamares::JobResult exec() override;
private:
QString currentPartitions() const;
QString targetPartitions() const;
private:
LvmDevice* m_device;
QVector< const Partition* > m_partitionList;
};
#endif // RESIZEVOLUMEGROUPJOB_H