Fix create partition job to work with LVM devices.

This commit is contained in:
Andrius Štikonas 2017-10-07 00:42:07 +01:00
parent 3f739563ef
commit 4912d8a6c2
3 changed files with 105 additions and 54 deletions

View File

@ -43,6 +43,8 @@
#include <QDir> #include <QDir>
#include <QListWidgetItem> #include <QListWidgetItem>
#include <QPushButton> #include <QPushButton>
#include <QRegularExpression>
#include <QRegularExpressionValidator>
#include <QSet> #include <QSet>
static QSet< FileSystem::Type > s_unmountableFS( static QSet< FileSystem::Type > s_unmountableFS(
@ -66,6 +68,19 @@ CreatePartitionDialog::CreatePartitionDialog( Device* device, PartitionNode* par
m_ui->encryptWidget->setText( tr( "En&crypt" ) ); m_ui->encryptWidget->setText( tr( "En&crypt" ) );
m_ui->encryptWidget->hide(); m_ui->encryptWidget->hide();
if (m_device->type() == Device::Disk_Device) {
m_ui->lvNameLabel->hide();
m_ui->lvNameLineEdit->hide();
}
if (m_device->type() == Device::LVM_Device) {
/* LVM logical volume name can consist of: letters numbers _ . - +
* It cannot start with underscore _ and must not be equal to . or .. or any entry in /dev/
* QLineEdit accepts QValidator::Intermediate, so we just disable . at the beginning */
QRegularExpression re(QStringLiteral(R"(^(?!_|\.)[\w\-.+]+)"));
QRegularExpressionValidator *validator = new QRegularExpressionValidator(re, this);
m_ui->lvNameLineEdit->setValidator(validator);
}
QStringList mountPoints = { "/", "/boot", "/home", "/opt", "/usr", "/var" }; QStringList mountPoints = { "/", "/boot", "/home", "/opt", "/usr", "/var" };
if ( PartUtils::isEfiSystem() ) if ( PartUtils::isEfiSystem() )
mountPoints << Calamares::JobQueue::instance()->globalStorage()->value( "efiSystemPartition" ).toString(); mountPoints << Calamares::JobQueue::instance()->globalStorage()->value( "efiSystemPartition" ).toString();
@ -227,6 +242,10 @@ CreatePartitionDialog::createPartition()
); );
} }
if (m_device->type() == Device::LVM_Device) {
partition->setPartitionPath(m_device->deviceNode() + QStringLiteral("/") + m_ui->lvNameLineEdit->text().trimmed());
}
PartitionInfo::setMountPoint( partition, m_ui->mountPointComboBox->currentText() ); PartitionInfo::setMountPoint( partition, m_ui->mountPointComboBox->currentText() );
PartitionInfo::setFormat( partition, true ); PartitionInfo::setFormat( partition, true );

View File

@ -146,6 +146,16 @@
</spacer> </spacer>
</item> </item>
<item row="6" column="0"> <item row="6" column="0">
<widget class="QLabel" name="lvNameLabel">
<property name="text">
<string>LVM LV name</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="lvNameLineEdit"/>
</item>
<item row="7" column="0">
<widget class="QLabel" name="mountPointLabel"> <widget class="QLabel" name="mountPointLabel">
<property name="text"> <property name="text">
<string>&amp;Mount Point:</string> <string>&amp;Mount Point:</string>
@ -155,7 +165,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="1"> <item row="7" column="1">
<widget class="QComboBox" name="mountPointComboBox"> <widget class="QComboBox" name="mountPointComboBox">
<property name="editable"> <property name="editable">
<bool>true</bool> <bool>true</bool>
@ -165,21 +175,21 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="1"> <item row="8" column="1">
<widget class="QLabel" name="labelMountPoint"> <widget class="QLabel" name="labelMountPoint">
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="0"> <item row="9" column="0">
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="label_3">
<property name="text"> <property name="text">
<string>Flags:</string> <string>Flags:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="1"> <item row="9" column="1">
<widget class="QListWidget" name="m_listFlags"> <widget class="QListWidget" name="m_listFlags">
<property name="alternatingRowColors"> <property name="alternatingRowColors">
<bool>true</bool> <bool>true</bool>
@ -192,7 +202,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="9" column="0"> <item row="10" column="0">
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>

View File

@ -30,6 +30,7 @@
#include <kpmcore/backend/corebackendpartition.h> #include <kpmcore/backend/corebackendpartition.h>
#include <kpmcore/backend/corebackendpartitiontable.h> #include <kpmcore/backend/corebackendpartitiontable.h>
#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/core/partitiontable.h> #include <kpmcore/core/partitiontable.h>
#include <kpmcore/fs/filesystem.h> #include <kpmcore/fs/filesystem.h>
@ -78,51 +79,81 @@ CreatePartitionJob::prettyStatusMessage() const
Calamares::JobResult Calamares::JobResult
CreatePartitionJob::exec() CreatePartitionJob::exec()
{ {
int step = 0; QString partitionPath;
const qreal stepCount = 4; FileSystem *fs;
Report report( nullptr ); Report report( nullptr );
QString message = tr( "The installer failed to create partition on disk '%1'." ).arg( m_device->name() );
progress( step++ / stepCount ); if (m_device->type() == Device::Disk_Device) {
CoreBackend* backend = CoreBackendManager::self()->backend(); int step = 0;
QScopedPointer<CoreBackendDevice> backendDevice( backend->openDevice( m_device->deviceNode() ) ); const qreal stepCount = 4;
if ( !backendDevice.data() ) QString message = tr( "The installer failed to create partition on disk '%1'." ).arg( m_device->name() );
progress( step++ / stepCount );
CoreBackend* backend = CoreBackendManager::self()->backend();
QScopedPointer<CoreBackendDevice> backendDevice( backend->openDevice( m_device->deviceNode() ) );
if ( !backendDevice.data() )
{
return Calamares::JobResult::error(
message,
tr( "Could not open device '%1'." ).arg( m_device->deviceNode() )
);
}
progress( step++ / stepCount );
QScopedPointer<CoreBackendPartitionTable> backendPartitionTable( backendDevice->openPartitionTable() );
if ( !backendPartitionTable.data() )
{
return Calamares::JobResult::error(
message,
tr( "Could not open partition table." )
);
}
progress( step++ / stepCount );
partitionPath = backendPartitionTable->createPartition( report, *m_partition );
if ( partitionPath.isEmpty() )
{
return Calamares::JobResult::error(
message,
report.toText()
);
}
m_partition->setPartitionPath( partitionPath );
backendPartitionTable->commit();
progress( step++ / stepCount );
fs = &m_partition->fileSystem();
if ( fs->type() == FileSystem::Unformatted || fs->type() == FileSystem::Extended )
return Calamares::JobResult::ok();
if ( !backendPartitionTable->setPartitionSystemType( report, *m_partition ) )
{
return Calamares::JobResult::error(
tr( "The installer failed to update partition table on disk '%1'." ).arg( m_device->name() ),
report.toText()
);
}
backendPartitionTable->commit();
}
else
{ {
return Calamares::JobResult::error( LvmDevice *dev = dynamic_cast<LvmDevice*>(m_device);
message, m_partition->setState(Partition::StateNone);
tr( "Could not open device '%1'." ).arg( m_device->deviceNode() )
); partitionPath = m_partition->partitionPath();
QString lvname = partitionPath.right(partitionPath.length() - partitionPath.lastIndexOf(QStringLiteral("/")) - 1);
if ( !LvmDevice::createLV(report, *dev, *m_partition, lvname))
{
return Calamares::JobResult::error(
tr( "The installer failed to create LVM logical volume %1." ).arg( lvname ),
report.toText()
);
}
fs = &m_partition->fileSystem();
} }
progress( step++ / stepCount ); if ( !fs->create( report, partitionPath ) )
QScopedPointer<CoreBackendPartitionTable> backendPartitionTable( backendDevice->openPartitionTable() );
if ( !backendPartitionTable.data() )
{
return Calamares::JobResult::error(
message,
tr( "Could not open partition table." )
);
}
progress( step++ / stepCount );
QString partitionPath = backendPartitionTable->createPartition( report, *m_partition );
if ( partitionPath.isEmpty() )
{
return Calamares::JobResult::error(
message,
report.toText()
);
}
m_partition->setPartitionPath( partitionPath );
backendPartitionTable->commit();
progress( step++ / stepCount );
FileSystem& fs = m_partition->fileSystem();
if ( fs.type() == FileSystem::Unformatted || fs.type() == FileSystem::Extended )
return Calamares::JobResult::ok();
if ( !fs.create( report, partitionPath ) )
{ {
return Calamares::JobResult::error( return Calamares::JobResult::error(
tr( "The installer failed to create file system on partition %1." ).arg( partitionPath ), tr( "The installer failed to create file system on partition %1." ).arg( partitionPath ),
@ -130,15 +161,6 @@ CreatePartitionJob::exec()
); );
} }
if ( !backendPartitionTable->setPartitionSystemType( report, *m_partition ) )
{
return Calamares::JobResult::error(
tr( "The installer failed to update partition table on disk '%1'." ).arg( m_device->name() ),
report.toText()
);
}
backendPartitionTable->commit();
return Calamares::JobResult::ok(); return Calamares::JobResult::ok();
} }