From d15ce56c9703f2509fb55b3b497d66ede2c806d9 Mon Sep 17 00:00:00 2001 From: Caio Date: Mon, 4 Jun 2018 16:31:58 -0300 Subject: [PATCH 01/10] [partition] Initial implementation of VolumeGroupBaseDialog. --- src/modules/partition/CMakeLists.txt | 4 + .../partition/core/PartitionCoreModule.cpp | 48 +++++ .../partition/core/PartitionCoreModule.h | 6 + src/modules/partition/core/PartitionInfo.cpp | 4 + .../gui/ListPhysicalVolumeWidgetItem.cpp | 36 ++++ .../gui/ListPhysicalVolumeWidgetItem.h | 37 ++++ src/modules/partition/gui/PartitionPage.cpp | 18 ++ src/modules/partition/gui/PartitionPage.h | 1 + src/modules/partition/gui/PartitionPage.ui | 9 +- .../partition/gui/VolumeGroupBaseDialog.cpp | 42 ++++ .../partition/gui/VolumeGroupBaseDialog.h | 48 +++++ .../partition/gui/VolumeGroupBaseDialog.ui | 193 ++++++++++++++++++ .../partition/jobs/CreateVolumeGroupJob.cpp | 88 ++++++++ .../partition/jobs/CreateVolumeGroupJob.h | 47 +++++ 14 files changed, 580 insertions(+), 1 deletion(-) create mode 100644 src/modules/partition/gui/ListPhysicalVolumeWidgetItem.cpp create mode 100644 src/modules/partition/gui/ListPhysicalVolumeWidgetItem.h create mode 100644 src/modules/partition/gui/VolumeGroupBaseDialog.cpp create mode 100644 src/modules/partition/gui/VolumeGroupBaseDialog.h create mode 100644 src/modules/partition/gui/VolumeGroupBaseDialog.ui create mode 100644 src/modules/partition/jobs/CreateVolumeGroupJob.cpp create mode 100644 src/modules/partition/jobs/CreateVolumeGroupJob.h diff --git a/src/modules/partition/CMakeLists.txt b/src/modules/partition/CMakeLists.txt index 156ff86f5..2f0e46bea 100644 --- a/src/modules/partition/CMakeLists.txt +++ b/src/modules/partition/CMakeLists.txt @@ -38,6 +38,7 @@ if ( KPMcore_FOUND ) gui/DeviceInfoWidget.cpp gui/EditExistingPartitionDialog.cpp gui/EncryptWidget.cpp + gui/ListPhysicalVolumeWidgetItem.cpp gui/PartitionPage.cpp gui/PartitionBarsView.cpp gui/PartitionLabelsView.cpp @@ -47,10 +48,12 @@ if ( KPMcore_FOUND ) gui/PrettyRadioButton.cpp gui/ScanningDialog.cpp gui/ReplaceWidget.cpp + gui/VolumeGroupBaseDialog.cpp jobs/ClearMountsJob.cpp jobs/ClearTempMountsJob.cpp jobs/CreatePartitionJob.cpp jobs/CreatePartitionTableJob.cpp + jobs/CreateVolumeGroupJob.cpp jobs/DeletePartitionJob.cpp jobs/FillGlobalStorageJob.cpp jobs/FormatPartitionJob.cpp @@ -65,6 +68,7 @@ if ( KPMcore_FOUND ) gui/EncryptWidget.ui gui/PartitionPage.ui gui/ReplaceWidget.ui + gui/VolumeGroupBaseDialog.ui LINK_PRIVATE_LIBRARIES kpmcore calamaresui diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index 43ba33d7b..7229c8305 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -33,6 +33,7 @@ #include "jobs/ClearTempMountsJob.h" #include "jobs/CreatePartitionJob.h" #include "jobs/CreatePartitionTableJob.h" +#include "jobs/CreateVolumeGroupJob.h" #include "jobs/DeletePartitionJob.h" #include "jobs/FillGlobalStorageJob.h" #include "jobs/FormatPartitionJob.h" @@ -44,10 +45,12 @@ // KPMcore #include +#include #include #include #include #include +#include // Qt #include @@ -177,6 +180,8 @@ PartitionCoreModule::doInit() m_bootLoaderModel->init( bootLoaderDevices ); + scanForLVMPVs(); + //FIXME: this should be removed in favor of // proper KPM support for EFI if ( PartUtils::isEfiSystem() ) @@ -263,6 +268,27 @@ PartitionCoreModule::createPartition( Device* device, refresh(); } +void +PartitionCoreModule::createVolumeGroup( QString &vgName, + QVector< const Partition* > pvList, + qint32 peSize ) +{ + 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 ); + + m_deviceInfos << deviceInfo; + deviceInfo->jobs << Calamares::job_ptr( job ); + + refresh(); +} + void PartitionCoreModule::deletePartition( Device* device, Partition* partition ) { @@ -432,6 +458,12 @@ PartitionCoreModule::efiSystemPartitions() const return m_efiSystemPartitions; } +QList< const Partition* > +PartitionCoreModule::lvmPVs() const +{ + return m_lvmPVs; +} + void PartitionCoreModule::dumpQueue() const { @@ -523,6 +555,22 @@ PartitionCoreModule::scanForEfiSystemPartitions() m_efiSystemPartitions = efiSystemPartitions; } +void +PartitionCoreModule::scanForLVMPVs() +{ + m_lvmPVs.clear(); + + QList< Device* > devices; + + for ( DeviceInfo* deviceInfo : m_deviceInfos ) + devices << deviceInfo->device.data(); + + LvmDevice::scanSystemLVM( devices ); + + for ( auto p : LVM::pvList ) + m_lvmPVs << p.partition().data(); +} + PartitionCoreModule::DeviceInfo* PartitionCoreModule::infoForDevice( const Device* device ) const { diff --git a/src/modules/partition/core/PartitionCoreModule.h b/src/modules/partition/core/PartitionCoreModule.h index 49564dad1..05c029381 100644 --- a/src/modules/partition/core/PartitionCoreModule.h +++ b/src/modules/partition/core/PartitionCoreModule.h @@ -111,6 +111,8 @@ public: void createPartition( Device* device, Partition* partition, PartitionTable::Flags flags = PartitionTable::FlagNone ); + void createVolumeGroup( QString &vgName, QVector< const Partition* > pvList, qint32 peSize ); + void deletePartition( Device* device, Partition* partition ); void formatPartition( Device* device, Partition* partition ); @@ -132,6 +134,8 @@ public: QList< Partition* > efiSystemPartitions() const; + QList< const Partition* > lvmPVs() const; + /** * @brief findPartitionByMountPoint returns a Partition* for a given mount point. * @param mountPoint the mount point to find a partition for. @@ -194,6 +198,7 @@ private: }; QList< DeviceInfo* > m_deviceInfos; QList< Partition* > m_efiSystemPartitions; + QList< const Partition* > m_lvmPVs; DeviceModel* m_deviceModel; BootLoaderModel* m_bootLoaderModel; @@ -205,6 +210,7 @@ private: void updateHasRootMountPoint(); void updateIsDirty(); void scanForEfiSystemPartitions(); + void scanForLVMPVs(); DeviceInfo* infoForDevice( const Device* ) const; diff --git a/src/modules/partition/core/PartitionInfo.cpp b/src/modules/partition/core/PartitionInfo.cpp index 72cca8976..20cd6f8a9 100644 --- a/src/modules/partition/core/PartitionInfo.cpp +++ b/src/modules/partition/core/PartitionInfo.cpp @@ -19,6 +19,7 @@ #include "core/PartitionInfo.h" // KPMcore +#include #include // Qt @@ -64,6 +65,9 @@ reset( Partition* partition ) bool isDirty( Partition* partition ) { + if ( LvmDevice::s_DirtyPVs.contains( partition ) ) + return true; + return !mountPoint( partition ).isEmpty() || format( partition ); } diff --git a/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.cpp b/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.cpp new file mode 100644 index 000000000..cd480aa55 --- /dev/null +++ b/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.cpp @@ -0,0 +1,36 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#include "ListPhysicalVolumeWidgetItem.h" + +#include + +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; +} diff --git a/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.h b/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.h new file mode 100644 index 000000000..44ba8c3bf --- /dev/null +++ b/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.h @@ -0,0 +1,37 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#ifndef LISTPHYSICALVOLUMEWIDGETITEM_H +#define LISTPHYSICALVOLUMEWIDGETITEM_H + +#include + +#include + +class ListPhysicalVolumeWidgetItem : public QListWidgetItem +{ +public: + ListPhysicalVolumeWidgetItem( const Partition* partition, bool checked ); + + const Partition* partition() const; + +private: + const Partition* m_partition; +}; + +#endif // LISTPHYSICALVOLUMEWIDGETITEM_H diff --git a/src/modules/partition/gui/PartitionPage.cpp b/src/modules/partition/gui/PartitionPage.cpp index c521604fb..adebb3418 100644 --- a/src/modules/partition/gui/PartitionPage.cpp +++ b/src/modules/partition/gui/PartitionPage.cpp @@ -30,6 +30,7 @@ #include "gui/CreatePartitionDialog.h" #include "gui/EditExistingPartitionDialog.h" #include "gui/ScanningDialog.h" +#include "gui/VolumeGroupBaseDialog.h" #include "ui_PartitionPage.h" #include "ui_CreatePartitionTableDialog.h" @@ -99,6 +100,7 @@ PartitionPage::PartitionPage( PartitionCoreModule* core, QWidget* parent ) connect( m_ui->partitionTreeView, &QAbstractItemView::doubleClicked, this, &PartitionPage::onPartitionViewActivated ); connect( m_ui->revertButton, &QAbstractButton::clicked, this, &PartitionPage::onRevertClicked ); + connect( m_ui->newVolumeGroupButton, &QAbstractButton::clicked, this, &PartitionPage::onNewVolumeGroupClicked ); connect( m_ui->newPartitionTableButton, &QAbstractButton::clicked, this, &PartitionPage::onNewPartitionTableClicked ); connect( m_ui->createButton, &QAbstractButton::clicked, this, &PartitionPage::onCreateClicked ); connect( m_ui->editButton, &QAbstractButton::clicked, this, &PartitionPage::onEditClicked ); @@ -178,6 +180,22 @@ PartitionPage::onNewPartitionTableClicked() updateBootLoaderIndex(); } +void +PartitionPage::onNewVolumeGroupClicked() +{ + QString vgName; + qint32 peSize = 4; + + QPointer< VolumeGroupBaseDialog > dlg = new VolumeGroupBaseDialog( vgName, m_core->lvmPVs(), peSize, this ); + + if ( dlg->exec() == QDialog::Accepted ) + { + + } + + delete dlg; +} + void PartitionPage::onCreateClicked() { diff --git a/src/modules/partition/gui/PartitionPage.h b/src/modules/partition/gui/PartitionPage.h index 24cf65675..ef6eeea15 100644 --- a/src/modules/partition/gui/PartitionPage.h +++ b/src/modules/partition/gui/PartitionPage.h @@ -50,6 +50,7 @@ private: PartitionCoreModule* m_core; void updateButtons(); void onNewPartitionTableClicked(); + void onNewVolumeGroupClicked(); void onCreateClicked(); void onEditClicked(); void onDeleteClicked(); diff --git a/src/modules/partition/gui/PartitionPage.ui b/src/modules/partition/gui/PartitionPage.ui index 7d24204c9..2b3d568cf 100644 --- a/src/modules/partition/gui/PartitionPage.ui +++ b/src/modules/partition/gui/PartitionPage.ui @@ -88,6 +88,13 @@ + + + + New Volume Group + + + @@ -145,7 +152,7 @@ - Install boot &loader on: + I&nstall boot loader on: bootLoaderComboBox diff --git a/src/modules/partition/gui/VolumeGroupBaseDialog.cpp b/src/modules/partition/gui/VolumeGroupBaseDialog.cpp new file mode 100644 index 000000000..b3535a004 --- /dev/null +++ b/src/modules/partition/gui/VolumeGroupBaseDialog.cpp @@ -0,0 +1,42 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#include "VolumeGroupBaseDialog.h" +#include "ui_VolumeGroupBaseDialog.h" + +#include "gui/ListPhysicalVolumeWidgetItem.h" + +VolumeGroupBaseDialog::VolumeGroupBaseDialog( QString& vgName, + QList< const Partition* > pvList, + qint32& peSize, + QWidget *parent) + : QDialog(parent) + , ui(new Ui::VolumeGroupBaseDialog) + , m_vgName(vgName) + , m_peSize(peSize) +{ + ui->setupUi(this); + + for ( const Partition* p : pvList ) + ui->pvList->addItem( new ListPhysicalVolumeWidgetItem(p, false) ); +} + +VolumeGroupBaseDialog::~VolumeGroupBaseDialog() +{ + delete ui; +} diff --git a/src/modules/partition/gui/VolumeGroupBaseDialog.h b/src/modules/partition/gui/VolumeGroupBaseDialog.h new file mode 100644 index 000000000..294effb1d --- /dev/null +++ b/src/modules/partition/gui/VolumeGroupBaseDialog.h @@ -0,0 +1,48 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#ifndef VOLUMEGROUPBASEDIALOG_H +#define VOLUMEGROUPBASEDIALOG_H + +#include + +#include + +namespace Ui { +class VolumeGroupBaseDialog; +} + +class VolumeGroupBaseDialog : public QDialog +{ + Q_OBJECT + +public: + explicit VolumeGroupBaseDialog(QString& vgName, + QList< const Partition* > pvList, + qint32& peSize, + QWidget* parent = 0); + ~VolumeGroupBaseDialog(); + +private: + Ui::VolumeGroupBaseDialog *ui; + + QString &m_vgName; + qint32 &m_peSize; +}; + +#endif // VOLUMEGROUPBASEDIALOG_H diff --git a/src/modules/partition/gui/VolumeGroupBaseDialog.ui b/src/modules/partition/gui/VolumeGroupBaseDialog.ui new file mode 100644 index 000000000..c9cb853b8 --- /dev/null +++ b/src/modules/partition/gui/VolumeGroupBaseDialog.ui @@ -0,0 +1,193 @@ + + + VolumeGroupBaseDialog + + + + 0 + 0 + 611 + 367 + + + + VolumeGroupDialog + + + + + + List of Physical Volumes + + + + + + + + + + Volume Group Name: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Volume Group Type: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Physical Extent Size: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Total Size: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + --- + + + Qt::AlignCenter + + + + + + + Used Size: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + --- + + + Qt::AlignCenter + + + + + + + Total Sectors: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + --- + + + Qt::AlignCenter + + + + + + + Quantity of LVs: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + --- + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + VolumeGroupBaseDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + VolumeGroupBaseDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/modules/partition/jobs/CreateVolumeGroupJob.cpp b/src/modules/partition/jobs/CreateVolumeGroupJob.cpp new file mode 100644 index 000000000..3b05b684a --- /dev/null +++ b/src/modules/partition/jobs/CreateVolumeGroupJob.cpp @@ -0,0 +1,88 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#include "CreateVolumeGroupJob.h" + +// KPMcore +#include +#include +#include +#include + +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 %1." ) + .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 ); + + QVector< const Partition* > pvList; + + pvList << m_pvList; + + 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 ); +} diff --git a/src/modules/partition/jobs/CreateVolumeGroupJob.h b/src/modules/partition/jobs/CreateVolumeGroupJob.h new file mode 100644 index 000000000..9e84fba73 --- /dev/null +++ b/src/modules/partition/jobs/CreateVolumeGroupJob.h @@ -0,0 +1,47 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#ifndef CREATEVOLUMEGROUPJOB_H +#define CREATEVOLUMEGROUPJOB_H + +#include + +#include + +#include + +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 From 208d58bcd93edfa31e80e8d1a99425573f929de5 Mon Sep 17 00:00:00 2001 From: Caio Date: Thu, 7 Jun 2018 17:22:22 -0300 Subject: [PATCH 02/10] [partition] Including CreateVolumeGroupDialog and fixing some of its GUI issues. --- src/modules/partition/CMakeLists.txt | 1 + src/modules/partition/core/DeviceModel.cpp | 16 ++ src/modules/partition/core/DeviceModel.h | 2 + .../partition/core/PartitionCoreModule.cpp | 37 ++++- .../partition/core/PartitionCoreModule.h | 9 +- .../partition/gui/CreateVolumeGroupDialog.cpp | 53 +++++++ .../partition/gui/CreateVolumeGroupDialog.h | 39 +++++ src/modules/partition/gui/PartitionPage.cpp | 47 +++++- .../partition/gui/VolumeGroupBaseDialog.cpp | 148 +++++++++++++++++- .../partition/gui/VolumeGroupBaseDialog.h | 49 +++++- .../partition/gui/VolumeGroupBaseDialog.ui | 41 +++-- .../partition/jobs/CreateVolumeGroupJob.cpp | 4 - 12 files changed, 409 insertions(+), 37 deletions(-) create mode 100644 src/modules/partition/gui/CreateVolumeGroupDialog.cpp create mode 100644 src/modules/partition/gui/CreateVolumeGroupDialog.h diff --git a/src/modules/partition/CMakeLists.txt b/src/modules/partition/CMakeLists.txt index 2f0e46bea..279eaf0ef 100644 --- a/src/modules/partition/CMakeLists.txt +++ b/src/modules/partition/CMakeLists.txt @@ -35,6 +35,7 @@ if ( KPMcore_FOUND ) gui/BootInfoWidget.cpp gui/ChoicePage.cpp gui/CreatePartitionDialog.cpp + gui/CreateVolumeGroupDialog.cpp gui/DeviceInfoWidget.cpp gui/EditExistingPartitionDialog.cpp gui/EncryptWidget.cpp diff --git a/src/modules/partition/core/DeviceModel.cpp b/src/modules/partition/core/DeviceModel.cpp index 00058bac4..95d7ddb72 100644 --- a/src/modules/partition/core/DeviceModel.cpp +++ b/src/modules/partition/core/DeviceModel.cpp @@ -25,10 +25,12 @@ // KPMcore #include +#include // KF5 #include +#include #include // STL @@ -116,3 +118,17 @@ DeviceModel::swapDevice( Device* oldDevice, Device* newDevice ) 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(); +} diff --git a/src/modules/partition/core/DeviceModel.h b/src/modules/partition/core/DeviceModel.h index ccca426bd..84f1c3c9d 100644 --- a/src/modules/partition/core/DeviceModel.h +++ b/src/modules/partition/core/DeviceModel.h @@ -49,6 +49,8 @@ public: void swapDevice( Device* oldDevice, Device* newDevice ); + void addDevice( Device* device ); + private: QList< Device* > m_devices; }; diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index 7229c8305..710f85378 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -273,6 +273,10 @@ 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(); @@ -283,6 +287,10 @@ PartitionCoreModule::createVolumeGroup( QString &vgName, DeviceInfo* deviceInfo = new DeviceInfo( device ); + deviceInfo->partitionModel->init( device, osproberEntries() ); + + m_deviceModel->addDevice( device ); + m_deviceInfos << deviceInfo; deviceInfo->jobs << Calamares::job_ptr( job ); @@ -458,12 +466,37 @@ PartitionCoreModule::efiSystemPartitions() const return m_efiSystemPartitions; } -QList< const Partition* > +QVector< const Partition* > PartitionCoreModule::lvmPVs() const { return m_lvmPVs; } +bool +PartitionCoreModule::hasVGwithThisName( const QString& name ) const +{ + for ( DeviceInfo* d : m_deviceInfos ) + if ( dynamic_cast(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( d->device.data() ); + + if ( vg && vg->physicalVolumes().contains( partition )) + return true; + } + + return false; +} + void PartitionCoreModule::dumpQueue() const { @@ -503,6 +536,8 @@ PartitionCoreModule::refresh() updateIsDirty(); m_bootLoaderModel->update(); + scanForLVMPVs(); + //FIXME: this should be removed in favor of // proper KPM support for EFI if ( PartUtils::isEfiSystem() ) diff --git a/src/modules/partition/core/PartitionCoreModule.h b/src/modules/partition/core/PartitionCoreModule.h index 05c029381..cedda391d 100644 --- a/src/modules/partition/core/PartitionCoreModule.h +++ b/src/modules/partition/core/PartitionCoreModule.h @@ -24,6 +24,7 @@ #include "Typedefs.h" // KPMcore +#include #include // Qt @@ -134,7 +135,11 @@ public: QList< Partition* > efiSystemPartitions() const; - QList< const Partition* > lvmPVs() 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. @@ -198,7 +203,7 @@ private: }; QList< DeviceInfo* > m_deviceInfos; QList< Partition* > m_efiSystemPartitions; - QList< const Partition* > m_lvmPVs; + QVector< const Partition* > m_lvmPVs; DeviceModel* m_deviceModel; BootLoaderModel* m_bootLoaderModel; diff --git a/src/modules/partition/gui/CreateVolumeGroupDialog.cpp b/src/modules/partition/gui/CreateVolumeGroupDialog.cpp new file mode 100644 index 000000000..f1ed32551 --- /dev/null +++ b/src/modules/partition/gui/CreateVolumeGroupDialog.cpp @@ -0,0 +1,53 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#include "CreateVolumeGroupDialog.h" + +#include +#include + +#include +#include +#include + +CreateVolumeGroupDialog::CreateVolumeGroupDialog( QString& vgName, + QVector< const Partition* >& selectedPVs, + QVector< const Partition* > pvList, + qint32& peSize, + QWidget* parent ) + : VolumeGroupBaseDialog( vgName, pvList, peSize, parent ) + , m_selectedPVs( selectedPVs ) +{ + setWindowTitle( "Create Volume Group" ); + + vgType()->setEnabled( false ); +} + +void +CreateVolumeGroupDialog::accept() +{ + QString& name = vgNameValue(); + name = vgName()->text(); + + m_selectedPVs << checkedItems(); + + qint32& pe = peSizeValue(); + pe = peSize()->value(); + + QDialog::accept(); +} diff --git a/src/modules/partition/gui/CreateVolumeGroupDialog.h b/src/modules/partition/gui/CreateVolumeGroupDialog.h new file mode 100644 index 000000000..eb2ced137 --- /dev/null +++ b/src/modules/partition/gui/CreateVolumeGroupDialog.h @@ -0,0 +1,39 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#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, + qint32& peSize, + QWidget* parent ); + + void accept() override; + +private: + QVector< const Partition* >& m_selectedPVs; +}; + +#endif // CREATEVOLUMEGROUPDIALOG_H diff --git a/src/modules/partition/gui/PartitionPage.cpp b/src/modules/partition/gui/PartitionPage.cpp index adebb3418..503a4e2ea 100644 --- a/src/modules/partition/gui/PartitionPage.cpp +++ b/src/modules/partition/gui/PartitionPage.cpp @@ -28,9 +28,9 @@ #include "core/PartUtils.h" #include "core/KPMHelpers.h" #include "gui/CreatePartitionDialog.h" +#include "gui/CreateVolumeGroupDialog.h" #include "gui/EditExistingPartitionDialog.h" #include "gui/ScanningDialog.h" -#include "gui/VolumeGroupBaseDialog.h" #include "ui_PartitionPage.h" #include "ui_CreatePartitionTableDialog.h" @@ -133,6 +133,8 @@ PartitionPage::updateButtons() bool isFree = KPMHelpers::isPartitionFreeSpace( partition ); bool isExtended = partition->roles().has( PartitionRole::Extended ); + bool isInVG = m_core->isInVG( partition ); + create = isFree; // Keep it simple for now: do not support editing extended partitions as // it does not work with our current edit implementation which is @@ -140,8 +142,9 @@ PartitionPage::updateButtons() // because they need to be created *before* creating logical partitions // inside them, so an edit must be applied without altering the job // order. + // TODO: See if LVM PVs can be edited in Calamares edit = !isFree && !isExtended; - del = !isFree; + del = !isFree && !isInVG; } if ( m_ui->deviceComboBox->currentIndex() >= 0 ) @@ -184,13 +187,51 @@ void PartitionPage::onNewVolumeGroupClicked() { QString vgName; + QVector< const Partition* > selectedPVs; qint32 peSize = 4; - QPointer< VolumeGroupBaseDialog > dlg = new VolumeGroupBaseDialog( vgName, m_core->lvmPVs(), peSize, this ); + 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 previousDeviceData = m_core->deviceModel()->data( deviceIndex, Qt::ToolTipRole ); + + 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( previousDeviceData, Qt::ToolTipRole ); + + if ( previousIndex != -1 ) + m_ui->deviceComboBox->setCurrentIndex( previousIndex ); } delete dlg; diff --git a/src/modules/partition/gui/VolumeGroupBaseDialog.cpp b/src/modules/partition/gui/VolumeGroupBaseDialog.cpp index b3535a004..e5da2c0ad 100644 --- a/src/modules/partition/gui/VolumeGroupBaseDialog.cpp +++ b/src/modules/partition/gui/VolumeGroupBaseDialog.cpp @@ -21,22 +21,160 @@ #include "gui/ListPhysicalVolumeWidgetItem.h" +#include + +#include +#include +#include +#include +#include +#include + VolumeGroupBaseDialog::VolumeGroupBaseDialog( QString& vgName, - QList< const Partition* > pvList, + QVector< const Partition* > pvList, qint32& peSize, - QWidget *parent) + QWidget *parent ) : QDialog(parent) , ui(new Ui::VolumeGroupBaseDialog) - , m_vgName(vgName) - , m_peSize(peSize) + , m_vgNameValue(vgName) + , m_peSizeValue(peSize) + , m_totalSizeValue(0) + , m_usedSizeValue(0) { ui->setupUi(this); for ( const Partition* p : pvList ) - ui->pvList->addItem( new ListPhysicalVolumeWidgetItem(p, false) ); + 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 ); + + ui->peSize->setValue( m_peSizeValue ); + + updateOkButton(); + updateTotalSize(); + + connect( ui->pvList, &QListWidget::itemChanged, this, + [&](QListWidgetItem*) { + updateTotalSize(); + updateOkButton(); + } ); + + connect( ui->peSize, qOverload(&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::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; +} + +qint32& +VolumeGroupBaseDialog::peSizeValue() const +{ + return m_peSizeValue; +} + +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 ); +} diff --git a/src/modules/partition/gui/VolumeGroupBaseDialog.h b/src/modules/partition/gui/VolumeGroupBaseDialog.h index 294effb1d..0b4a48372 100644 --- a/src/modules/partition/gui/VolumeGroupBaseDialog.h +++ b/src/modules/partition/gui/VolumeGroupBaseDialog.h @@ -27,22 +27,55 @@ namespace Ui { class VolumeGroupBaseDialog; } +class QComboBox; +class QLineEdit; +class QListWidget; +class QSpinBox; + class VolumeGroupBaseDialog : public QDialog { Q_OBJECT public: - explicit VolumeGroupBaseDialog(QString& vgName, - QList< const Partition* > pvList, - qint32& peSize, - QWidget* parent = 0); + explicit VolumeGroupBaseDialog( QString& vgName, + QVector< const Partition* > pvList, + qint32& peSize, + QWidget* parent = nullptr ); ~VolumeGroupBaseDialog(); -private: - Ui::VolumeGroupBaseDialog *ui; +protected: + virtual void updateOkButton(); - QString &m_vgName; - qint32 &m_peSize; + void updateTotalSize(); + + void updateTotalSectors(); + + QVector< const Partition* > checkedItems() const; + + bool isSizeValid() const; + + QString& vgNameValue() const; + + qint32& peSizeValue() const; + + QLineEdit* vgName() const; + + QComboBox* vgType() const; + + QSpinBox* peSize() const; + + QListWidget* pvList() const; + + QPushButton* okButton() const; + +private: + Ui::VolumeGroupBaseDialog* ui; + + QString& m_vgNameValue; + qint32& m_peSizeValue; + + qint64 m_totalSizeValue; + qint64 m_usedSizeValue; }; #endif // VOLUMEGROUPBASEDIALOG_H diff --git a/src/modules/partition/gui/VolumeGroupBaseDialog.ui b/src/modules/partition/gui/VolumeGroupBaseDialog.ui index c9cb853b8..b45d204e2 100644 --- a/src/modules/partition/gui/VolumeGroupBaseDialog.ui +++ b/src/modules/partition/gui/VolumeGroupBaseDialog.ui @@ -25,7 +25,7 @@ - + Volume Group Name: @@ -35,10 +35,10 @@ - + - + Volume Group Type: @@ -48,10 +48,10 @@ - + - + Physical Extent Size: @@ -61,10 +61,23 @@ - + + + MiB + + + 1 + + + 999 + + + 4 + + - + Total Size: @@ -74,7 +87,7 @@ - + --- @@ -84,7 +97,7 @@ - + Used Size: @@ -94,7 +107,7 @@ - + --- @@ -104,7 +117,7 @@ - + Total Sectors: @@ -114,7 +127,7 @@ - + --- @@ -124,7 +137,7 @@ - + Quantity of LVs: @@ -134,7 +147,7 @@ - + --- diff --git a/src/modules/partition/jobs/CreateVolumeGroupJob.cpp b/src/modules/partition/jobs/CreateVolumeGroupJob.cpp index 3b05b684a..7debd9475 100644 --- a/src/modules/partition/jobs/CreateVolumeGroupJob.cpp +++ b/src/modules/partition/jobs/CreateVolumeGroupJob.cpp @@ -58,10 +58,6 @@ CreateVolumeGroupJob::exec() { Report report( nullptr ); - QVector< const Partition* > pvList; - - pvList << m_pvList; - CreateVolumeGroupOperation op( m_vgName, m_pvList, m_peSize ); op.setStatus( Operation::StatusRunning ); From e5351cdf3c0d3d548ed4f82456acb942fe960eef Mon Sep 17 00:00:00 2001 From: Caio Date: Thu, 7 Jun 2018 17:49:25 -0300 Subject: [PATCH 03/10] [partition] Don't show capacity of new LVM VGs in DeviceModel. --- src/modules/partition/core/DeviceModel.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/modules/partition/core/DeviceModel.cpp b/src/modules/partition/core/DeviceModel.cpp index 95d7ddb72..fe4f71b4f 100644 --- a/src/modules/partition/core/DeviceModel.cpp +++ b/src/modules/partition/core/DeviceModel.cpp @@ -79,10 +79,18 @@ DeviceModel::data( const QModelIndex& index, int role ) const if ( device->name().isEmpty() ) return device->deviceNode(); else - return tr( "%1 - %2 (%3)" ) - .arg( device->name() ) - .arg( KFormat().formatByteSize( device->capacity() ) ) - .arg( device->deviceNode() ); + { + if ( device->capacity() != 1 ) + return tr( "%1 - %2 (%3)" ) + .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: return CalamaresUtils::defaultPixmap( CalamaresUtils::PartitionDisk, CalamaresUtils::Original, From f8897e0e0b7800dbac9f5d95fd7a05debf697702 Mon Sep 17 00:00:00 2001 From: Caio Date: Fri, 8 Jun 2018 18:52:53 -0300 Subject: [PATCH 04/10] [partition] Including new LVM PVs in LVM VG creation GUI. --- src/modules/partition/core/DeviceModel.cpp | 3 +-- .../partition/core/PartitionCoreModule.cpp | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/modules/partition/core/DeviceModel.cpp b/src/modules/partition/core/DeviceModel.cpp index fe4f71b4f..ba0df2c18 100644 --- a/src/modules/partition/core/DeviceModel.cpp +++ b/src/modules/partition/core/DeviceModel.cpp @@ -25,7 +25,6 @@ // KPMcore #include -#include // KF5 #include @@ -80,7 +79,7 @@ DeviceModel::data( const QModelIndex& index, int role ) const return device->deviceNode(); else { - if ( device->capacity() != 1 ) + if ( device->logicalSize() >= 0 && device->totalLogical() >= 0 ) return tr( "%1 - %2 (%3)" ) .arg( device->name() ) .arg( KFormat().formatByteSize( device->capacity() ) ) diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index 710f85378..d6be78844 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include // Qt @@ -604,6 +605,30 @@ PartitionCoreModule::scanForLVMPVs() for ( auto p : LVM::pvList ) m_lvmPVs << p.partition().data(); + + for ( DeviceInfo* d : m_deviceInfos ) + { + for ( auto job : d->jobs ) + { + // Including new LVM PVs + CreatePartitionJob* partJob = dynamic_cast( 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 || p->fileSystem().type() == FileSystem::Type::Luks2 ) + { + // Encrypted LVM PVs + FileSystem* innerFS = static_cast(&p->fileSystem())->innerFS(); + + if ( innerFS && innerFS->type() == FileSystem::Type::Lvm2_PV ) + m_lvmPVs << p; + } + } + } + } } PartitionCoreModule::DeviceInfo* From 0465cc4214cf6fc47c15c003067cb731eb1d021e Mon Sep 17 00:00:00 2001 From: Caio Date: Fri, 8 Jun 2018 20:20:05 -0300 Subject: [PATCH 05/10] [partition] Including revert on creation of LVM VGs. --- src/modules/partition/core/DeviceModel.cpp | 14 +++++++++ src/modules/partition/core/DeviceModel.h | 2 ++ .../partition/core/PartitionCoreModule.cpp | 30 +++++++++++++++++-- src/modules/partition/gui/PartitionPage.cpp | 11 +++---- 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/modules/partition/core/DeviceModel.cpp b/src/modules/partition/core/DeviceModel.cpp index ba0df2c18..260315729 100644 --- a/src/modules/partition/core/DeviceModel.cpp +++ b/src/modules/partition/core/DeviceModel.cpp @@ -139,3 +139,17 @@ DeviceModel::addDevice( Device *device ) 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(); +} diff --git a/src/modules/partition/core/DeviceModel.h b/src/modules/partition/core/DeviceModel.h index 84f1c3c9d..2e2f99342 100644 --- a/src/modules/partition/core/DeviceModel.h +++ b/src/modules/partition/core/DeviceModel.h @@ -51,6 +51,8 @@ public: void addDevice( Device* device ); + void removeDevice( Device* device ); + private: QList< Device* > m_devices; }; diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index d6be78844..fc7ce9753 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -680,8 +680,33 @@ PartitionCoreModule::revert() void PartitionCoreModule::revertAllDevices() { - foreach ( DeviceInfo* devInfo, m_deviceInfos ) - revertDevice( devInfo->device.data() ); + for ( auto it = m_deviceInfos.begin(); it != m_deviceInfos.end(); ) + { + // In new VGs device info, there will be always a CreateVolumeGroupJob as the first job in jobs list + if ( !( *it )->jobs.empty() ) + { + CreateVolumeGroupJob* vgJob = dynamic_cast( ( *it )->jobs[0].data() ); + + if ( vgJob ) + { + vgJob->undoPreview(); + + ( *it )->forgetChanges(); + + m_deviceModel->removeDevice( ( *it )->device.data() ); + + it = m_deviceInfos.erase( it ); + + scanForLVMPVs(); + } + } + else + { + revertDevice( ( *it )->device.data() ); + ++it; + } + } + refresh(); } @@ -691,6 +716,7 @@ PartitionCoreModule::revertDevice( Device* dev ) { QMutexLocker locker( &m_revertMutex ); DeviceInfo* devInfo = infoForDevice( dev ); + if ( !devInfo ) return; devInfo->forgetChanges(); diff --git a/src/modules/partition/gui/PartitionPage.cpp b/src/modules/partition/gui/PartitionPage.cpp index 503a4e2ea..550e356c0 100644 --- a/src/modules/partition/gui/PartitionPage.cpp +++ b/src/modules/partition/gui/PartitionPage.cpp @@ -222,16 +222,17 @@ PartitionPage::onNewVolumeGroupClicked() QModelIndex deviceIndex = m_core->deviceModel()->index( m_ui->deviceComboBox->currentIndex(), 0 ); Q_ASSERT( deviceIndex.isValid() ); - QVariant previousDeviceData = m_core->deviceModel()->data( deviceIndex, Qt::ToolTipRole ); + 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( previousDeviceData, Qt::ToolTipRole ); + int previousIndex = m_ui->deviceComboBox->findData( previousIndexDeviceData, Qt::ToolTipRole ); - if ( previousIndex != -1 ) - m_ui->deviceComboBox->setCurrentIndex( previousIndex ); + m_ui->deviceComboBox->setCurrentIndex( ( previousIndex < 0 ) ? 0 : previousIndex ); + updateFromCurrentDevice(); } delete dlg; @@ -301,7 +302,7 @@ PartitionPage::onRevertClicked() int oldIndex = m_ui->deviceComboBox->currentIndex(); m_core->revertAllDevices(); - m_ui->deviceComboBox->setCurrentIndex( oldIndex ); + m_ui->deviceComboBox->setCurrentIndex( ( oldIndex < 0 ) ? 0 : oldIndex ); updateFromCurrentDevice(); } ), [ this ]{ From 3b6c764f753f92cac394c4b57b371719b8c2cc5c Mon Sep 17 00:00:00 2001 From: Caio Carvalho Date: Mon, 11 Jun 2018 18:38:57 -0300 Subject: [PATCH 06/10] [partition] Fixing revert device loop error in PartitionCoreModule::revertAllDevices. --- src/modules/partition/core/PartitionCoreModule.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index fc7ce9753..1f84e55be 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -683,7 +683,7 @@ PartitionCoreModule::revertAllDevices() for ( auto it = m_deviceInfos.begin(); it != m_deviceInfos.end(); ) { // In new VGs device info, there will be always a CreateVolumeGroupJob as the first job in jobs list - if ( !( *it )->jobs.empty() ) + if ( dynamic_cast( ( *it )->device.data() ) && !( *it )->jobs.empty() ) { CreateVolumeGroupJob* vgJob = dynamic_cast( ( *it )->jobs[0].data() ); @@ -697,14 +697,12 @@ PartitionCoreModule::revertAllDevices() it = m_deviceInfos.erase( it ); - scanForLVMPVs(); + continue; } } - else - { - revertDevice( ( *it )->device.data() ); - ++it; - } + + revertDevice( ( *it )->device.data() ); + ++it; } refresh(); From 98a158c6e5d3920cd92423921c3b25805a914e74 Mon Sep 17 00:00:00 2001 From: Caio Carvalho Date: Thu, 14 Jun 2018 15:37:00 -0300 Subject: [PATCH 07/10] [partition] kpmcore latest release doesn't support FileSystem::Type::Luks2 --- src/modules/partition/CMakeLists.txt | 4 ++++ src/modules/partition/core/PartitionCoreModule.cpp | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/modules/partition/CMakeLists.txt b/src/modules/partition/CMakeLists.txt index 279eaf0ef..874440177 100644 --- a/src/modules/partition/CMakeLists.txt +++ b/src/modules/partition/CMakeLists.txt @@ -12,6 +12,10 @@ set_package_properties( ) 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( ${PROJECT_BINARY_DIR}/src/libcalamaresui ) diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index 1f84e55be..9646d31cd 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -618,7 +618,7 @@ PartitionCoreModule::scanForLVMPVs() if ( p->fileSystem().type() == FileSystem::Type::Lvm2_PV ) m_lvmPVs << p; - else if ( p->fileSystem().type() == FileSystem::Type::Luks || p->fileSystem().type() == FileSystem::Type::Luks2 ) + else if ( p->fileSystem().type() == FileSystem::Type::Luks ) { // Encrypted LVM PVs FileSystem* innerFS = static_cast(&p->fileSystem())->innerFS(); @@ -626,6 +626,16 @@ PartitionCoreModule::scanForLVMPVs() 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(&p->fileSystem())->innerFS(); + + if ( innerFS && innerFS->type() == FileSystem::Type::Lvm2_PV ) + m_lvmPVs << p; + } +#endif } } } From 295e14530e4e1f3c1ae86032962d048ff3259597 Mon Sep 17 00:00:00 2001 From: Caio Carvalho Date: Tue, 26 Jun 2018 00:38:52 -0300 Subject: [PATCH 08/10] [partition] Adding resizing, deactivating and removing procedures for LVM VGs. --- src/modules/partition/CMakeLists.txt | 4 + .../partition/core/PartitionCoreModule.cpp | 116 ++++++++++++++++-- .../partition/core/PartitionCoreModule.h | 11 ++ .../partition/gui/CreateVolumeGroupDialog.cpp | 9 +- .../partition/gui/CreateVolumeGroupDialog.h | 4 +- src/modules/partition/gui/PartitionPage.cpp | 80 +++++++++++- src/modules/partition/gui/PartitionPage.h | 3 + src/modules/partition/gui/PartitionPage.ui | 54 ++++++-- .../partition/gui/ResizeVolumeGroupDialog.cpp | 62 ++++++++++ .../partition/gui/ResizeVolumeGroupDialog.h | 40 ++++++ .../partition/gui/VolumeGroupBaseDialog.cpp | 24 ++-- .../partition/gui/VolumeGroupBaseDialog.h | 8 +- .../jobs/DeactivateVolumeGroupJob.cpp | 69 +++++++++++ .../partition/jobs/DeactivateVolumeGroupJob.h | 40 ++++++ .../partition/jobs/RemoveVolumeGroupJob.cpp | 66 ++++++++++ .../partition/jobs/RemoveVolumeGroupJob.h | 40 ++++++ .../partition/jobs/ResizeVolumeGroupJob.cpp | 101 +++++++++++++++ .../partition/jobs/ResizeVolumeGroupJob.h | 48 ++++++++ 18 files changed, 738 insertions(+), 41 deletions(-) create mode 100644 src/modules/partition/gui/ResizeVolumeGroupDialog.cpp create mode 100644 src/modules/partition/gui/ResizeVolumeGroupDialog.h create mode 100644 src/modules/partition/jobs/DeactivateVolumeGroupJob.cpp create mode 100644 src/modules/partition/jobs/DeactivateVolumeGroupJob.h create mode 100644 src/modules/partition/jobs/RemoveVolumeGroupJob.cpp create mode 100644 src/modules/partition/jobs/RemoveVolumeGroupJob.h create mode 100644 src/modules/partition/jobs/ResizeVolumeGroupJob.cpp create mode 100644 src/modules/partition/jobs/ResizeVolumeGroupJob.h diff --git a/src/modules/partition/CMakeLists.txt b/src/modules/partition/CMakeLists.txt index 874440177..bfc967f3d 100644 --- a/src/modules/partition/CMakeLists.txt +++ b/src/modules/partition/CMakeLists.txt @@ -51,6 +51,7 @@ if ( KPMcore_FOUND ) gui/PartitionSplitterWidget.cpp gui/PartitionViewStep.cpp gui/PrettyRadioButton.cpp + gui/ResizeVolumeGroupDialog.cpp gui/ScanningDialog.cpp gui/ReplaceWidget.cpp gui/VolumeGroupBaseDialog.cpp @@ -59,11 +60,14 @@ if ( KPMcore_FOUND ) jobs/CreatePartitionJob.cpp jobs/CreatePartitionTableJob.cpp jobs/CreateVolumeGroupJob.cpp + jobs/DeactivateVolumeGroupJob.cpp jobs/DeletePartitionJob.cpp jobs/FillGlobalStorageJob.cpp jobs/FormatPartitionJob.cpp jobs/PartitionJob.cpp + jobs/RemoveVolumeGroupJob.cpp jobs/ResizePartitionJob.cpp + jobs/ResizeVolumeGroupJob.cpp jobs/SetPartitionFlagsJob.cpp UI gui/ChoicePage.ui diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index 9646d31cd..e82c7c64d 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -34,10 +34,13 @@ #include "jobs/CreatePartitionJob.h" #include "jobs/CreatePartitionTableJob.h" #include "jobs/CreateVolumeGroupJob.h" +#include "jobs/DeactivateVolumeGroupJob.h" #include "jobs/DeletePartitionJob.h" #include "jobs/FillGlobalStorageJob.h" #include "jobs/FormatPartitionJob.h" +#include "jobs/RemoveVolumeGroupJob.h" #include "jobs/ResizePartitionJob.h" +#include "jobs/ResizeVolumeGroupJob.h" #include "jobs/SetPartitionFlagsJob.h" #include "Typedefs.h" @@ -65,6 +68,7 @@ PartitionCoreModule::DeviceInfo::DeviceInfo( Device* _device ) : device( _device ) , partitionModel( new PartitionModel ) , immutableDevice( new Device( *_device ) ) + , isAvailable( true ) {} PartitionCoreModule::DeviceInfo::~DeviceInfo() @@ -298,6 +302,48 @@ PartitionCoreModule::createVolumeGroup( QString &vgName, 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 PartitionCoreModule::deletePartition( Device* device, Partition* partition ) { @@ -596,16 +642,40 @@ PartitionCoreModule::scanForLVMPVs() { m_lvmPVs.clear(); - QList< Device* > devices; + QList< Device* > physicalDevices; + QList< LvmDevice* > vgDevices; for ( DeviceInfo* deviceInfo : m_deviceInfos ) - devices << deviceInfo->device.data(); + { + 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(deviceInfo->device.data()); - LvmDevice::scanSystemLVM( devices ); + // 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 ) @@ -693,21 +763,26 @@ PartitionCoreModule::revertAllDevices() for ( auto it = m_deviceInfos.begin(); it != m_deviceInfos.end(); ) { // In new VGs device info, there will be always a CreateVolumeGroupJob as the first job in jobs list - if ( dynamic_cast( ( *it )->device.data() ) && !( *it )->jobs.empty() ) + if ( dynamic_cast( ( *it )->device.data() ) ) { - CreateVolumeGroupJob* vgJob = dynamic_cast( ( *it )->jobs[0].data() ); + ( *it )->isAvailable = true; - if ( vgJob ) + if ( !( *it )->jobs.empty() ) { - vgJob->undoPreview(); + CreateVolumeGroupJob* vgJob = dynamic_cast( ( *it )->jobs[0].data() ); - ( *it )->forgetChanges(); + if ( vgJob ) + { + vgJob->undoPreview(); - m_deviceModel->removeDevice( ( *it )->device.data() ); + ( *it )->forgetChanges(); - it = m_deviceInfos.erase( it ); + m_deviceModel->removeDevice( ( *it )->device.data() ); - continue; + it = m_deviceInfos.erase( it ); + + continue; + } } } @@ -736,8 +811,13 @@ PartitionCoreModule::revertDevice( Device* dev ) m_deviceModel->swapDevice( dev, newDev ); QList< Device* > devices; - foreach ( auto info, m_deviceInfos ) - devices.append( info->device.data() ); + for ( auto info : m_deviceInfos ) + { + if ( info->device.data()->type() != Device::Type::Disk_Device ) + continue; + else + devices.append( info->device.data() ); + } m_bootLoaderModel->init( devices ); @@ -777,6 +857,16 @@ PartitionCoreModule::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 > PartitionCoreModule::createSummaryInfo() const { diff --git a/src/modules/partition/core/PartitionCoreModule.h b/src/modules/partition/core/PartitionCoreModule.h index cedda391d..d61311c8a 100644 --- a/src/modules/partition/core/PartitionCoreModule.h +++ b/src/modules/partition/core/PartitionCoreModule.h @@ -114,6 +114,12 @@ public: 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 formatPartition( Device* device, Partition* partition ); @@ -160,6 +166,8 @@ public: 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 * which do not affect its size, because changes which affect the partition size @@ -198,6 +206,9 @@ private: const QScopedPointer< Device > immutableDevice; QList< Calamares::job_ptr > jobs; + // To check if LVM VGs are deactivated + bool isAvailable; + void forgetChanges(); bool isDirty() const; }; diff --git a/src/modules/partition/gui/CreateVolumeGroupDialog.cpp b/src/modules/partition/gui/CreateVolumeGroupDialog.cpp index f1ed32551..fe5c40be8 100644 --- a/src/modules/partition/gui/CreateVolumeGroupDialog.cpp +++ b/src/modules/partition/gui/CreateVolumeGroupDialog.cpp @@ -28,13 +28,16 @@ CreateVolumeGroupDialog::CreateVolumeGroupDialog( QString& vgName, QVector< const Partition* >& selectedPVs, QVector< const Partition* > pvList, - qint32& peSize, + qint64& pSize, QWidget* parent ) - : VolumeGroupBaseDialog( vgName, pvList, peSize, parent ) + : VolumeGroupBaseDialog( vgName, pvList, parent ) , m_selectedPVs( selectedPVs ) + , m_peSize( pSize ) { setWindowTitle( "Create Volume Group" ); + peSize()->setValue( pSize ); + vgType()->setEnabled( false ); } @@ -46,7 +49,7 @@ CreateVolumeGroupDialog::accept() m_selectedPVs << checkedItems(); - qint32& pe = peSizeValue(); + qint64& pe = m_peSize; pe = peSize()->value(); QDialog::accept(); diff --git a/src/modules/partition/gui/CreateVolumeGroupDialog.h b/src/modules/partition/gui/CreateVolumeGroupDialog.h index eb2ced137..b0d5b874c 100644 --- a/src/modules/partition/gui/CreateVolumeGroupDialog.h +++ b/src/modules/partition/gui/CreateVolumeGroupDialog.h @@ -27,13 +27,15 @@ public: CreateVolumeGroupDialog( QString& vgName, QVector< const Partition* >& selectedPVs, QVector< const Partition* > pvList, - qint32& peSize, + qint64& pSize, QWidget* parent ); void accept() override; private: QVector< const Partition* >& m_selectedPVs; + + qint64& m_peSize; }; #endif // CREATEVOLUMEGROUPDIALOG_H diff --git a/src/modules/partition/gui/PartitionPage.cpp b/src/modules/partition/gui/PartitionPage.cpp index 550e356c0..ada6cc15b 100644 --- a/src/modules/partition/gui/PartitionPage.cpp +++ b/src/modules/partition/gui/PartitionPage.cpp @@ -30,6 +30,7 @@ #include "gui/CreatePartitionDialog.h" #include "gui/CreateVolumeGroupDialog.h" #include "gui/EditExistingPartitionDialog.h" +#include "gui/ResizeVolumeGroupDialog.h" #include "gui/ScanningDialog.h" #include "ui_PartitionPage.h" @@ -43,6 +44,8 @@ // KPMcore #include #include +#include +#include // Qt #include @@ -101,6 +104,9 @@ PartitionPage::PartitionPage( PartitionCoreModule* core, QWidget* parent ) connect( m_ui->partitionTreeView, &QAbstractItemView::doubleClicked, this, &PartitionPage::onPartitionViewActivated ); 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->createButton, &QAbstractButton::clicked, this, &PartitionPage::onCreateClicked ); connect( m_ui->editButton, &QAbstractButton::clicked, this, &PartitionPage::onEditClicked ); @@ -121,7 +127,8 @@ PartitionPage::~PartitionPage() void 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(); if ( index.isValid() ) @@ -152,12 +159,28 @@ PartitionPage::updateButtons() QModelIndex deviceIndex = m_core->deviceModel()->index( m_ui->deviceComboBox->currentIndex(), 0 ); if ( m_core->deviceModel()->deviceForIndex( deviceIndex )->type() != Device::Type::LVM_Device ) createTable = true; + else + { + currentDeviceIsVG = true; + + LvmDevice* lvmDevice = dynamic_cast(m_core->deviceModel()->deviceForIndex( deviceIndex )); + + isDeactivable = DeactivateVolumeGroupOperation::isDeactivatable( lvmDevice ); + isRemovable = RemoveVolumeGroupOperation::isRemovable( lvmDevice ); + + isVGdeactivated = m_core->isVGdeactivated( lvmDevice ); + + m_ui->revertButton->setEnabled( isVGdeactivated ); + } } m_ui->createButton->setEnabled( create ); m_ui->editButton->setEnabled( edit ); m_ui->deleteButton->setEnabled( del ); 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 @@ -188,7 +211,7 @@ PartitionPage::onNewVolumeGroupClicked() { QString vgName; QVector< const Partition* > selectedPVs; - qint32 peSize = 4; + qint64 peSize = 4; QVector< const Partition* > availablePVs; @@ -238,6 +261,59 @@ PartitionPage::onNewVolumeGroupClicked() 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 PartitionPage::onCreateClicked() { diff --git a/src/modules/partition/gui/PartitionPage.h b/src/modules/partition/gui/PartitionPage.h index ef6eeea15..f4ce330dd 100644 --- a/src/modules/partition/gui/PartitionPage.h +++ b/src/modules/partition/gui/PartitionPage.h @@ -51,6 +51,9 @@ private: void updateButtons(); void onNewPartitionTableClicked(); void onNewVolumeGroupClicked(); + void onResizeVolumeGroupClicked(); + void onDeactivateVolumeGroupClicked(); + void onRemoveVolumeGroupClicked(); void onCreateClicked(); void onEditClicked(); void onDeleteClicked(); diff --git a/src/modules/partition/gui/PartitionPage.ui b/src/modules/partition/gui/PartitionPage.ui index 2b3d568cf..612bff7ba 100644 --- a/src/modules/partition/gui/PartitionPage.ui +++ b/src/modules/partition/gui/PartitionPage.ui @@ -6,7 +6,7 @@ 0 0 - 655 + 684 304 @@ -88,13 +88,6 @@ - - - - New Volume Group - - - @@ -131,6 +124,51 @@ + + + + + + New Volume Group + + + + + + + Resize Volume Group + + + + + + + Deactivate Volume Group + + + + + + + Remove Volume Group + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + diff --git a/src/modules/partition/gui/ResizeVolumeGroupDialog.cpp b/src/modules/partition/gui/ResizeVolumeGroupDialog.cpp new file mode 100644 index 000000000..b3173096d --- /dev/null +++ b/src/modules/partition/gui/ResizeVolumeGroupDialog.cpp @@ -0,0 +1,62 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#include "ResizeVolumeGroupDialog.h" + +#include "gui/ListPhysicalVolumeWidgetItem.h" + +#include +#include + +#include +#include +#include +#include + +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(); +} diff --git a/src/modules/partition/gui/ResizeVolumeGroupDialog.h b/src/modules/partition/gui/ResizeVolumeGroupDialog.h new file mode 100644 index 000000000..1d6015329 --- /dev/null +++ b/src/modules/partition/gui/ResizeVolumeGroupDialog.h @@ -0,0 +1,40 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#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 diff --git a/src/modules/partition/gui/VolumeGroupBaseDialog.cpp b/src/modules/partition/gui/VolumeGroupBaseDialog.cpp index e5da2c0ad..a727fe42a 100644 --- a/src/modules/partition/gui/VolumeGroupBaseDialog.cpp +++ b/src/modules/partition/gui/VolumeGroupBaseDialog.cpp @@ -32,12 +32,10 @@ VolumeGroupBaseDialog::VolumeGroupBaseDialog( QString& vgName, QVector< const Partition* > pvList, - qint32& peSize, QWidget *parent ) : QDialog(parent) , ui(new Ui::VolumeGroupBaseDialog) , m_vgNameValue(vgName) - , m_peSizeValue(peSize) , m_totalSizeValue(0) , m_usedSizeValue(0) { @@ -53,8 +51,6 @@ VolumeGroupBaseDialog::VolumeGroupBaseDialog( QString& vgName, ui->vgName->setValidator( new QRegularExpressionValidator( re, this ) ); ui->vgName->setText( m_vgNameValue ); - ui->peSize->setValue( m_peSizeValue ); - updateOkButton(); updateTotalSize(); @@ -111,6 +107,20 @@ VolumeGroupBaseDialog::updateOkButton() 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() { @@ -143,12 +153,6 @@ VolumeGroupBaseDialog::vgNameValue() const return m_vgNameValue; } -qint32& -VolumeGroupBaseDialog::peSizeValue() const -{ - return m_peSizeValue; -} - QLineEdit* VolumeGroupBaseDialog::vgName() const { diff --git a/src/modules/partition/gui/VolumeGroupBaseDialog.h b/src/modules/partition/gui/VolumeGroupBaseDialog.h index 0b4a48372..e6011ce62 100644 --- a/src/modules/partition/gui/VolumeGroupBaseDialog.h +++ b/src/modules/partition/gui/VolumeGroupBaseDialog.h @@ -39,13 +39,16 @@ class VolumeGroupBaseDialog : public QDialog public: explicit VolumeGroupBaseDialog( QString& vgName, QVector< const Partition* > pvList, - qint32& peSize, QWidget* parent = nullptr ); ~VolumeGroupBaseDialog(); protected: virtual void updateOkButton(); + void setUsedSizeValue( qint64 usedSize ); + + void setLVQuantity( qint32 lvQuantity ); + void updateTotalSize(); void updateTotalSectors(); @@ -56,8 +59,6 @@ protected: QString& vgNameValue() const; - qint32& peSizeValue() const; - QLineEdit* vgName() const; QComboBox* vgType() const; @@ -72,7 +73,6 @@ private: Ui::VolumeGroupBaseDialog* ui; QString& m_vgNameValue; - qint32& m_peSizeValue; qint64 m_totalSizeValue; qint64 m_usedSizeValue; diff --git a/src/modules/partition/jobs/DeactivateVolumeGroupJob.cpp b/src/modules/partition/jobs/DeactivateVolumeGroupJob.cpp new file mode 100644 index 000000000..f772b3e5a --- /dev/null +++ b/src/modules/partition/jobs/DeactivateVolumeGroupJob.cpp @@ -0,0 +1,69 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#include "DeactivateVolumeGroupJob.h" + +#include +#include +#include + +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 %1." ) + .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()); +} diff --git a/src/modules/partition/jobs/DeactivateVolumeGroupJob.h b/src/modules/partition/jobs/DeactivateVolumeGroupJob.h new file mode 100644 index 000000000..5b59c2c4f --- /dev/null +++ b/src/modules/partition/jobs/DeactivateVolumeGroupJob.h @@ -0,0 +1,40 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#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 diff --git a/src/modules/partition/jobs/RemoveVolumeGroupJob.cpp b/src/modules/partition/jobs/RemoveVolumeGroupJob.cpp new file mode 100644 index 000000000..69b510754 --- /dev/null +++ b/src/modules/partition/jobs/RemoveVolumeGroupJob.cpp @@ -0,0 +1,66 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#include "RemoveVolumeGroupJob.h" + +#include +#include +#include + +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 %1.") + .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()); +} diff --git a/src/modules/partition/jobs/RemoveVolumeGroupJob.h b/src/modules/partition/jobs/RemoveVolumeGroupJob.h new file mode 100644 index 000000000..426dde7fb --- /dev/null +++ b/src/modules/partition/jobs/RemoveVolumeGroupJob.h @@ -0,0 +1,40 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#ifndef REMOVEVOLUMEGROUPJOB_H +#define REMOVEVOLUMEGROUPJOB_H + +#include + +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 diff --git a/src/modules/partition/jobs/ResizeVolumeGroupJob.cpp b/src/modules/partition/jobs/ResizeVolumeGroupJob.cpp new file mode 100644 index 000000000..bc7ef264d --- /dev/null +++ b/src/modules/partition/jobs/ResizeVolumeGroupJob.cpp @@ -0,0 +1,101 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#include "ResizeVolumeGroupJob.h" + +// KPMcore +#include +#include +#include +#include + +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 %1 from %2 to %3." ) + .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; +} diff --git a/src/modules/partition/jobs/ResizeVolumeGroupJob.h b/src/modules/partition/jobs/ResizeVolumeGroupJob.h new file mode 100644 index 000000000..380bee416 --- /dev/null +++ b/src/modules/partition/jobs/ResizeVolumeGroupJob.h @@ -0,0 +1,48 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#ifndef RESIZEVOLUMEGROUPJOB_H +#define RESIZEVOLUMEGROUPJOB_H + +#include + +#include + +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 From 67d9ebbfc0b4195b0576f04f285a7d2585d6700f Mon Sep 17 00:00:00 2001 From: Caio Carvalho Date: Tue, 26 Jun 2018 01:29:57 -0300 Subject: [PATCH 09/10] [partition] Setting revertButton enabled after deactivating VG. --- src/modules/partition/gui/PartitionPage.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/partition/gui/PartitionPage.cpp b/src/modules/partition/gui/PartitionPage.cpp index ada6cc15b..37d90f65d 100644 --- a/src/modules/partition/gui/PartitionPage.cpp +++ b/src/modules/partition/gui/PartitionPage.cpp @@ -170,7 +170,8 @@ PartitionPage::updateButtons() isVGdeactivated = m_core->isVGdeactivated( lvmDevice ); - m_ui->revertButton->setEnabled( isVGdeactivated ); + if ( isVGdeactivated ) + m_ui->revertButton->setEnabled( true ); } } From 589628bb9af32fcd5315fa91d544cef812e9e0f0 Mon Sep 17 00:00:00 2001 From: Caio Carvalho Date: Tue, 26 Jun 2018 01:44:35 -0300 Subject: [PATCH 10/10] [partition] Removing unnecessary horizontal spacer on Partition Page. --- src/modules/partition/gui/PartitionPage.ui | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/modules/partition/gui/PartitionPage.ui b/src/modules/partition/gui/PartitionPage.ui index 612bff7ba..e72f08518 100644 --- a/src/modules/partition/gui/PartitionPage.ui +++ b/src/modules/partition/gui/PartitionPage.ui @@ -154,19 +154,6 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - -