Skip to content

Commit

Permalink
Implement creating LVs
Browse files Browse the repository at this point in the history
  • Loading branch information
vicr123 committed Aug 16, 2023
1 parent d505147 commit 37a77b4
Show file tree
Hide file tree
Showing 21 changed files with 851 additions and 24 deletions.
15 changes: 15 additions & 0 deletions application/lvm/volumegrouppage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <DriveObjects/diskobject.h>
#include <DriveObjects/logicalvolume.h>
#include <DriveObjects/volumegroup.h>
#include <operations/addlvpopover.h>
#include <operations/disbandvgpopover.h>
#include <tpopover.h>
#include <volumegrouplvmodel.h>
Expand Down Expand Up @@ -89,3 +90,17 @@ void VolumeGroupPage::on_disbandButton_clicked() {
connect(popover, &tPopover::dismissed, jp, &DisbandVgPopover::deleteLater);
popover->show(this->window());
}

void VolumeGroupPage::on_lvsView_activated(const QModelIndex& index) {
auto lv = index.data(VolumeGroupLvModel::LvRole).value<LogicalVolume*>();
if (!lv) {
auto* jp = new AddLvPopover(d->vg);
tPopover* popover = new tPopover(jp);
popover->setPopoverWidth(-200);
popover->setPopoverSide(tPopover::Bottom);
connect(jp, &AddLvPopover::done, popover, &tPopover::dismiss);
connect(popover, &tPopover::dismissed, popover, &tPopover::deleteLater);
connect(popover, &tPopover::dismissed, jp, &AddLvPopover::deleteLater);
popover->show(this->window());
}
}
2 changes: 2 additions & 0 deletions application/lvm/volumegrouppage.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class VolumeGroupPage : public QWidget {

void on_disbandButton_clicked();

void on_lvsView_activated(const QModelIndex& index);

private:
Ui::VolumeGroupPage* ui;
VolumeGroupPagePrivate* d;
Expand Down
2 changes: 2 additions & 0 deletions libthefrisbee/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ set(SOURCES
volumegrouppvmodel.h volumegrouppvmodel.cpp
operations/attachpvpopover.h operations/attachpvpopover.cpp operations/attachpvpopover.ui
operations/disbandvgpopover.h operations/disbandvgpopover.cpp operations/disbandvgpopover.ui
operations/addlvpopover.h operations/addlvpopover.cpp operations/addlvpopover.ui
components/sizerangebox.h components/sizerangebox.cpp components/sizerangebox.ui
)

set(STRUCTURES_HEADERS
Expand Down
27 changes: 27 additions & 0 deletions libthefrisbee/DriveObjects/volumegroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
struct VolumeGroupPrivate {
QDBusObjectPath path;
QString name;
quint64 size;
quint64 freeSize;
};

VolumeGroup::VolumeGroup(QDBusObjectPath path, QObject* parent) :
Expand All @@ -24,6 +26,12 @@ VolumeGroup::VolumeGroup(QDBusObjectPath path, QObject* parent) :
bindPropertyUpdater("Name", [this](QVariant value) {
d->name = value.toString();
});
bindPropertyUpdater("Size", [this](QVariant value) {
d->size = value.toULongLong();
});
bindPropertyUpdater("FreeSize", [this](QVariant value) {
d->freeSize = value.toULongLong();
});

connect(DriveObjectManager::instance(), &DriveObjectManager::logicalVolumeAdded, this, &VolumeGroup::lvsChanged);
connect(DriveObjectManager::instance(), &DriveObjectManager::logicalVolumeRemoved, this, &VolumeGroup::lvsChanged);
Expand Down Expand Up @@ -55,6 +63,14 @@ QString VolumeGroup::name() {
return d->name;
}

quint64 VolumeGroup::size() {
return d->size;
}

quint64 VolumeGroup::freeSize() {
return d->freeSize;
}

QCoro::Task<> VolumeGroup::deleteVg(bool wipe, QVariantMap options) {
QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.UDisks2", d->path.path(), interfaceName(), "Delete");
message.setArguments({wipe, options});
Expand All @@ -70,3 +86,14 @@ QCoro::Task<> VolumeGroup::addDevice(DiskObject* block, QVariantMap options) {
auto reply = co_await call;
if (call.isError()) throw FrisbeeException(call.error().message());
}

QCoro::Task<LogicalVolume*> VolumeGroup::createPlainVolume(QString name, quint64 size, QVariantMap options) {
QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.UDisks2", d->path.path(), interfaceName(), "CreatePlainVolume");
message.setArguments({name, size, options});
auto call = QDBusConnection::systemBus().asyncCall(message);
auto reply = co_await call;
if (call.isError()) throw FrisbeeException(call.error().message());

auto lvPath = reply.arguments().first().value<QDBusObjectPath>();
co_return DriveObjectManager::logicalVolumeForPath(lvPath);
}
3 changes: 3 additions & 0 deletions libthefrisbee/DriveObjects/volumegroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@ class VolumeGroup : public UdisksInterface {
tRange<DiskObject*> pvs();

QString name();
quint64 size();
quint64 freeSize();

QCoro::Task<> deleteVg(bool wipe, QVariantMap options);
QCoro::Task<> addDevice(DiskObject* block, QVariantMap options);
QCoro::Task<LogicalVolume*> createPlainVolume(QString name, quint64 size, QVariantMap options);

signals:
void lvsChanged();
Expand Down
52 changes: 28 additions & 24 deletions libthefrisbee/components/sizeeditbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,40 +20,41 @@
#include "sizeeditbox.h"

struct SizeEditBoxPrivate {
static QMap<QString, quint64> factors;
static QMap<QString, quint64> factors;
};

#define BYTE_FACTOR 1ULL
#define KILOBYTE_FACTOR 1024ULL
#define MEGABYTE_FACTOR KILOBYTE_FACTOR * KILOBYTE_FACTOR
#define GIGABYTE_FACTOR MEGABYTE_FACTOR * KILOBYTE_FACTOR
#define TERABYTE_FACTOR GIGABYTE_FACTOR * KILOBYTE_FACTOR
#define PETABYTE_FACTOR TERABYTE_FACTOR * KILOBYTE_FACTOR
#define EXABYTE_FACTOR PETABYTE_FACTOR * KILOBYTE_FACTOR
#define MEGABYTE_FACTOR KILOBYTE_FACTOR* KILOBYTE_FACTOR
#define GIGABYTE_FACTOR MEGABYTE_FACTOR* KILOBYTE_FACTOR
#define TERABYTE_FACTOR GIGABYTE_FACTOR* KILOBYTE_FACTOR
#define PETABYTE_FACTOR TERABYTE_FACTOR* KILOBYTE_FACTOR
#define EXABYTE_FACTOR PETABYTE_FACTOR* KILOBYTE_FACTOR

QMap<QString, quint64> SizeEditBoxPrivate::factors = {
{"B", BYTE_FACTOR},
{"K", KILOBYTE_FACTOR},
{"KB", KILOBYTE_FACTOR},
{"B", BYTE_FACTOR },
{"K", KILOBYTE_FACTOR},
{"KB", KILOBYTE_FACTOR},
{"KIB", KILOBYTE_FACTOR},
{"M", MEGABYTE_FACTOR},
{"MB", MEGABYTE_FACTOR},
{"M", MEGABYTE_FACTOR},
{"MB", MEGABYTE_FACTOR},
{"MIB", MEGABYTE_FACTOR},
{"G", GIGABYTE_FACTOR},
{"GB", GIGABYTE_FACTOR},
{"G", GIGABYTE_FACTOR},
{"GB", GIGABYTE_FACTOR},
{"GIB", GIGABYTE_FACTOR},
{"T", TERABYTE_FACTOR},
{"TB", TERABYTE_FACTOR},
{"T", TERABYTE_FACTOR},
{"TB", TERABYTE_FACTOR},
{"TIB", TERABYTE_FACTOR},
{"P", PETABYTE_FACTOR},
{"PB", PETABYTE_FACTOR},
{"P", PETABYTE_FACTOR},
{"PB", PETABYTE_FACTOR},
{"PIB", PETABYTE_FACTOR},
{"E", EXABYTE_FACTOR},
{"EB", EXABYTE_FACTOR},
{"EIB", EXABYTE_FACTOR}
{"E", EXABYTE_FACTOR },
{"EB", EXABYTE_FACTOR },
{"EIB", EXABYTE_FACTOR }
};

SizeEditBox::SizeEditBox(QWidget* parent) : QLineEdit(parent) {
SizeEditBox::SizeEditBox(QWidget* parent) :
QLineEdit(parent) {
d = new SizeEditBoxPrivate();
this->setValidator(new SizeEditValidator(this));
}
Expand Down Expand Up @@ -87,11 +88,15 @@ quint64 SizeEditBox::size() {
return size;
}

struct SizeEditValidatorPrivate {
void SizeEditBox::setSize(quint64 size) {
this->setText(QLocale().formattedDataSize(size));
}

struct SizeEditValidatorPrivate {
};

SizeEditValidator::SizeEditValidator(QObject* parent) : QValidator(parent) {
SizeEditValidator::SizeEditValidator(QObject* parent) :
QValidator(parent) {
d = new SizeEditValidatorPrivate();
}

Expand Down Expand Up @@ -133,7 +138,6 @@ QValidator::State SizeEditValidator::validate(QString& input, int& pos) const {
return Acceptable;
}


void SizeEditValidator::fixup(QString& input) const {
QString number;
QString unit;
Expand Down
1 change: 1 addition & 0 deletions libthefrisbee/components/sizeeditbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class SizeEditBox : public QLineEdit {

bool hasValidSize();
quint64 size();
void setSize(quint64 size);

signals:

Expand Down
38 changes: 38 additions & 0 deletions libthefrisbee/components/sizerangebox.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "sizerangebox.h"
#include "ui_sizerangebox.h"

struct SizeRangeBoxPrivate {
static constexpr int divisionFactor = 1024 * 1024;
};

SizeRangeBox::SizeRangeBox(QWidget* parent) :
QWidget(parent),
ui(new Ui::SizeRangeBox) {
ui->setupUi(this);
d = new SizeRangeBoxPrivate();
}

SizeRangeBox::~SizeRangeBox() {
delete ui;
delete d;
}

void SizeRangeBox::setMaximumSize(quint64 size) {
ui->slider->setMaximum(size / SizeRangeBoxPrivate::divisionFactor);
}

quint64 SizeRangeBox::size() {
return static_cast<quint64>(ui->slider->value()) * SizeRangeBoxPrivate::divisionFactor;
}

void SizeRangeBox::setSize(quint64 size) {
ui->slider->setValue(size / SizeRangeBoxPrivate::divisionFactor);
}

void SizeRangeBox::on_slider_valueChanged(int value) {
ui->sizeBox->setSize(static_cast<quint64>(value) * SizeRangeBoxPrivate::divisionFactor);
}

void SizeRangeBox::on_sizeBox_editingFinished() {
this->setSize(ui->sizeBox->size());
}
33 changes: 33 additions & 0 deletions libthefrisbee/components/sizerangebox.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef SIZERANGEBOX_H
#define SIZERANGEBOX_H

#include <QWidget>

namespace Ui {
class SizeRangeBox;
}

struct SizeRangeBoxPrivate;
class SizeRangeBox : public QWidget {
Q_OBJECT

public:
explicit SizeRangeBox(QWidget* parent = nullptr);
~SizeRangeBox();

void setMaximumSize(quint64 size);

quint64 size();
void setSize(quint64 size);

private slots:
void on_slider_valueChanged(int value);

void on_sizeBox_editingFinished();

private:
Ui::SizeRangeBox* ui;
SizeRangeBoxPrivate* d;
};

#endif // SIZERANGEBOX_H
38 changes: 38 additions & 0 deletions libthefrisbee/components/sizerangebox.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SizeRangeBox</class>
<widget class="QWidget" name="SizeRangeBox">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>49</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSlider" name="slider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="SizeEditBox" name="sizeBox"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>SizeEditBox</class>
<extends>QLineEdit</extends>
<header>components/sizeeditbox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
76 changes: 76 additions & 0 deletions libthefrisbee/operations/addlvpopover.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include "addlvpopover.h"
#include "ui_addlvpopover.h"

#include "DriveObjects/blockinterface.h"
#include "DriveObjects/diskobject.h"
#include "DriveObjects/logicalvolume.h"
#include "DriveObjects/volumegroup.h"
#include "partitioninformation.h"
#include <frisbeeexception.h>
#include <tcontentsizer.h>
#include <terrorflash.h>

struct AddLvPopoverPrivate {
VolumeGroup* vg;
};

AddLvPopover::AddLvPopover(VolumeGroup* vg, QWidget* parent) :
QWidget(parent),
ui(new Ui::AddLvPopover) {
ui->setupUi(this);
d = new AddLvPopoverPrivate();
d->vg = vg;

new tContentSizer(ui->optionsWidget);

ui->sizeRangeBox->setMaximumSize(d->vg->freeSize());
ui->sizeRangeBox->setSize(d->vg->freeSize());

for (QString type : PartitionInformation::availableFormatTypes()) {
if (type == QStringLiteral("lvmpv")) continue;
ui->formatBox->addItem(PartitionInformation::typeName(type), type);
}
ui->formatBox->addItem(tr("Leave Empty"), "empty");
}

AddLvPopover::~AddLvPopover() {
delete ui;
delete d;
}

QCoro::Task<> AddLvPopover::on_createButton_clicked() {
if (ui->nameBox->text().isEmpty()) {
tErrorFlash::flashError(ui->nameBox);
co_return;
}

if (ui->sizeRangeBox->size() == 0) {
tErrorFlash::flashError(ui->sizeRangeBox);
co_return;
}

auto format = ui->formatBox->currentData(Qt::UserRole).toString();
auto name = ui->nameBox->text();
auto size = ui->sizeRangeBox->size();

emit done();

try {
auto lv = co_await d->vg->createPlainVolume(name, size, {});
if (format != QStringLiteral("empty")) {
QVariantMap formatOptions{
{"label", name},
{"no-block", true},
{"update-partition-type", true},
{"tear-down", true}
};
co_await lv->block()->interface<BlockInterface>()->format(format, formatOptions);
}
} catch (FrisbeeException& exception) {
tWarn("AddLvPopover") << exception.response();
}
}

void AddLvPopover::on_titleLabel_backButtonClicked() {
emit done();
}
Loading

0 comments on commit 37a77b4

Please sign in to comment.