Convert copyblocks code from KAuth to DBus calls to helper daemon.
This commit is contained in:
parent
ef2b61d2ec
commit
bd54ba7c5d
|
@ -39,7 +39,7 @@ set(kpmcore_SRCS
|
|||
ki18n_wrap_ui(kpmcore_SRCS ${gui_UIFILES})
|
||||
|
||||
add_library(kpmcore SHARED ${kpmcore_SRCS})
|
||||
target_link_libraries( kpmcore
|
||||
target_link_libraries( kpmcore PUBLIC
|
||||
${UUID_LIBRARIES}
|
||||
${BLKID_LIBRARIES}
|
||||
Qt5::DBus
|
||||
|
|
|
@ -72,11 +72,18 @@ void CoreBackendManager::startExternalCommandHelper()
|
|||
m_Uuid = QUuid::createUuid().toString();
|
||||
arguments.insert(QStringLiteral("callerUuid"), Uuid());
|
||||
action.setArguments(arguments);
|
||||
KAuth::ExecuteJob *job = action.execute();
|
||||
job->start();
|
||||
m_job = action.execute();
|
||||
job()->start();
|
||||
QEventLoop loop;
|
||||
QObject::connect(job, &KAuth::ExecuteJob::newData, [&] () {loop.exit();});
|
||||
auto exitLoop = [&] () {loop.exit();};
|
||||
auto conn = QObject::connect(job(), &KAuth::ExecuteJob::newData, exitLoop);
|
||||
loop.exec();
|
||||
QObject::disconnect(conn);
|
||||
|
||||
}
|
||||
|
||||
KAuth::ExecuteJob* CoreBackendManager::job() {
|
||||
return m_job;
|
||||
}
|
||||
|
||||
bool CoreBackendManager::load(const QString& name)
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
||||
#include <KAuth>
|
||||
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
|
||||
|
@ -93,12 +95,18 @@ public:
|
|||
return m_Uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a pointer to the KAuth job
|
||||
*/
|
||||
KAuth::ExecuteJob* job();
|
||||
|
||||
private:
|
||||
void startExternalCommandHelper();
|
||||
|
||||
private:
|
||||
CoreBackend* m_Backend;
|
||||
QThread* m_KAuthThread;
|
||||
CoreBackend *m_Backend;
|
||||
QThread *m_KAuthThread;
|
||||
KAuth::ExecuteJob *m_job;
|
||||
|
||||
QString m_Uuid;
|
||||
};
|
||||
|
|
|
@ -63,62 +63,31 @@ bool ExternalCommand::startCopyBlocks()
|
|||
bool ExternalCommand::copyBlocks()
|
||||
{
|
||||
bool rval = true;
|
||||
qint64 blockSize = 10 * 1024 * 1024; // number of bytes per block to copy
|
||||
qint64 blocksToCopy = m_Source->length() / blockSize;
|
||||
const qint64 blockSize = 10 * 1024 * 1024; // number of bytes per block to copy
|
||||
|
||||
qint64 readOffset = m_Source->firstByte();
|
||||
qint64 writeOffset = m_Target->firstByte();
|
||||
qint32 copyDirection = 1;
|
||||
|
||||
if (m_Target->firstByte() > m_Source->firstByte()) {
|
||||
readOffset = m_Source->firstByte() + m_Source->length() - blockSize;
|
||||
writeOffset = m_Target->firstByte() + m_Source->length() - blockSize;
|
||||
copyDirection = -1;
|
||||
}
|
||||
qint64 lastBlock = m_Source->length() % blockSize;
|
||||
|
||||
//report()->line() << xi18nc("@info:progress", "Copying %1 blocks (%2 bytes) from %3 to %4, direction: %5.", blocksToCopy, m_source.length(), readOffset, writeOffset, copyDirection == 1 ? i18nc("direction: left", "left") : i18nc("direction: right", "right"));
|
||||
|
||||
QString cmd = QStandardPaths::findExecutable(QStringLiteral("dd"));
|
||||
|
||||
if (cmd.isEmpty())
|
||||
cmd = QStandardPaths::findExecutable(QStringLiteral("dd"), { QStringLiteral("/sbin/"), QStringLiteral("/usr/sbin/"), QStringLiteral("/usr/local/sbin/") });
|
||||
|
||||
KAuth::Action action(QStringLiteral("org.kde.kpmcore.externalcommand.copyblockshelper"));
|
||||
action.setHelperId(QStringLiteral("org.kde.kpmcore.externalcommand"));
|
||||
|
||||
arguments.insert(QStringLiteral("command"), cmd);
|
||||
arguments.insert(QStringLiteral("sourceDevice"), m_Source->path());
|
||||
arguments.insert(QStringLiteral("targetDevice"), m_Target->path());
|
||||
arguments.insert(QStringLiteral("blockSize"), blockSize);
|
||||
arguments.insert(QStringLiteral("blocksToCopy"), blocksToCopy);
|
||||
arguments.insert(QStringLiteral("readOffset"), readOffset);
|
||||
arguments.insert(QStringLiteral("writeOffset"), writeOffset);
|
||||
arguments.insert(QStringLiteral("copyDirection"), copyDirection);
|
||||
arguments.insert(QStringLiteral("sourceFirstByte"), m_Source->firstByte());
|
||||
arguments.insert(QStringLiteral("targetFirstByte"), m_Target->firstByte());
|
||||
arguments.insert(QStringLiteral("lastBlock"), lastBlock);
|
||||
arguments.insert(QStringLiteral("sourceLength"), m_Source->length());
|
||||
|
||||
action.setArguments(arguments);
|
||||
action.setTimeout(24 * 3600 * 1000); // set 1 day DBus timeout
|
||||
|
||||
KAuth::ExecuteJob *job = action.execute();
|
||||
// TODO KF6:Use new signal-slot syntax
|
||||
connect(job, SIGNAL(percent(KJob*, unsigned long)), this, SLOT(emitProgress(KJob*, unsigned long)));
|
||||
connect(job, &KAuth::ExecuteJob::newData, this, &ExternalCommand::emitReport);
|
||||
|
||||
if (!job->exec()) {
|
||||
qWarning() << "KAuth returned an error code: " << job->errorString();
|
||||
// return false;
|
||||
emit finished();
|
||||
if (!QDBusConnection::systemBus().isConnected()) {
|
||||
qWarning() << "Could not connect to DBus system bus";
|
||||
return false;
|
||||
}
|
||||
|
||||
rval = job->data()[QStringLiteral("success")].toInt();
|
||||
setExitCode(!rval);
|
||||
// TODO KF6:Use new signal-slot syntax
|
||||
connect(CoreBackendManager::self()->job(), SIGNAL(percent(KJob*, unsigned long)), this, SLOT(emitProgress(KJob*, unsigned long)));
|
||||
connect(CoreBackendManager::self()->job(), &KAuth::ExecuteJob::newData, this, &ExternalCommand::emitReport);
|
||||
|
||||
QDBusInterface iface(QStringLiteral("org.kde.kpmcore.helperinterface"), QStringLiteral("/Helper"), QStringLiteral("org.kde.kpmcore.externalcommand"), QDBusConnection::systemBus());
|
||||
if (iface.isValid()) {
|
||||
QDBusReply<QVariantMap> reply = iface.call(QStringLiteral("copyblocks"), CoreBackendManager::self()->Uuid(), m_Source->path(), m_Source->firstByte(), m_Source->length(), m_Target->path(), m_Target->firstByte(), blockSize);
|
||||
if (reply.isValid()) {
|
||||
rval = reply.value()[QStringLiteral("success")].toInt();
|
||||
qDebug() << rval;
|
||||
}
|
||||
else {
|
||||
qWarning() << reply.error().message();
|
||||
}
|
||||
}
|
||||
|
||||
emit finished();
|
||||
setExitCode(!rval);
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
@ -190,7 +159,7 @@ void ExternalCommand::execute()
|
|||
cmd = QStandardPaths::findExecutable(command(), { QStringLiteral("/sbin/"), QStringLiteral("/usr/sbin/"), QStringLiteral("/usr/local/sbin/") });
|
||||
|
||||
if (!QDBusConnection::systemBus().isConnected()) {
|
||||
qWarning() << "Could not connect to DBus session bus";
|
||||
qWarning() << "Could not connect to DBus system bus";
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ ActionReply ExternalCommandHelper::init(const QVariantMap& args)
|
|||
@param size the number of bytes to read
|
||||
@return true on success
|
||||
*/
|
||||
bool ExternalCommandHelper::readData(QString& sourceDevice, QByteArray& buffer, qint64 offset, qint64 size)
|
||||
bool ExternalCommandHelper::readData(const QString& sourceDevice, QByteArray& buffer, qint64 offset, qint64 size)
|
||||
{
|
||||
QFile device(sourceDevice);
|
||||
|
||||
|
@ -89,7 +89,7 @@ bool ExternalCommandHelper::readData(QString& sourceDevice, QByteArray& buffer,
|
|||
@param offset offset where to begin writing
|
||||
@return true on success
|
||||
*/
|
||||
bool ExternalCommandHelper::writeData(QString &targetDevice, QByteArray& buffer, qint64 offset)
|
||||
bool ExternalCommandHelper::writeData(const QString &targetDevice, const QByteArray& buffer, qint64 offset)
|
||||
{
|
||||
QFile device(targetDevice);
|
||||
if (!device.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Unbuffered)) {
|
||||
|
@ -109,26 +109,23 @@ bool ExternalCommandHelper::writeData(QString &targetDevice, QByteArray& buffer,
|
|||
return true;
|
||||
}
|
||||
|
||||
ActionReply ExternalCommandHelper::copyblockshelper(const QVariantMap& args)
|
||||
QVariantMap ExternalCommandHelper::copyblocks(const QString& Uuid, const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize)
|
||||
{
|
||||
m_command = args[QStringLiteral("command")].toString();
|
||||
qint64 blockSize = args[QStringLiteral("blockSize")].toLongLong();
|
||||
qint64 blocksToCopy = args[QStringLiteral("blocksToCopy")].toLongLong();
|
||||
qint64 readOffset = args[QStringLiteral("readOffset")].toLongLong();
|
||||
qint64 writeOffset = args[QStringLiteral("writeOffset")].toLongLong();
|
||||
qint32 copyDirection = args[QStringLiteral("copyDirection")].toLongLong();
|
||||
QString sourceDevice = args[QStringLiteral("sourceDevice")].toString();
|
||||
QString targetDevice = args[QStringLiteral("targetDevice")].toString();
|
||||
qint64 lastBlock = args[QStringLiteral("lastBlock")].toLongLong();
|
||||
qint64 sourceFirstByte = args[QStringLiteral("sourceFirstByte")].toLongLong();
|
||||
qint64 targetFirstByte = args[QStringLiteral("targetFirstByte")].toLongLong();
|
||||
qint64 sourceLength = args[QStringLiteral("sourceLength")].toLongLong();
|
||||
isCallerAuthorized(Uuid);
|
||||
QVariantMap reply;
|
||||
|
||||
QStringList environment = args[QStringLiteral("environment")].toStringList();
|
||||
const qint64 blocksToCopy = sourceLength / blockSize;
|
||||
qint64 readOffset = sourceFirstByte;
|
||||
qint64 writeOffset = targetFirstByte;
|
||||
qint32 copyDirection = 1;
|
||||
|
||||
ActionReply reply;
|
||||
if (targetFirstByte > sourceFirstByte) {
|
||||
readOffset = sourceFirstByte + sourceLength - blockSize;
|
||||
writeOffset = targetFirstByte + sourceLength - blockSize;
|
||||
copyDirection = -1;
|
||||
}
|
||||
|
||||
m_cmd.setEnvironment(environment);
|
||||
const qint64 lastBlock = sourceLength % blockSize;
|
||||
|
||||
qint64 bytesWritten = 0;
|
||||
qint64 blocksCopied = 0;
|
||||
|
@ -193,18 +190,15 @@ ActionReply ExternalCommandHelper::copyblockshelper(const QVariantMap& args)
|
|||
report[QStringLiteral("report")] = xi18ncp("@info:progress argument 2 is a string such as 7 bytes (localized accordingly)", "Copying 1 block (%2) finished.", "Copying %1 blocks (%2) finished.", blocksCopied, i18np("1 byte", "%1 bytes", bytesWritten));
|
||||
HelperSupport::progressStep(report);
|
||||
|
||||
reply.addData(QStringLiteral("success"), rval);
|
||||
reply[QStringLiteral("success")] = rval;
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
QVariantMap ExternalCommandHelper::start(const QString& Uuid, const QString& command, const QStringList& arguments, const QByteArray& input, const QStringList& environment)
|
||||
{
|
||||
isCallerAuthorized(Uuid);
|
||||
QVariantMap reply;
|
||||
if (Uuid != m_callerUuid) {
|
||||
qWarning() << "Caller is not authorized";
|
||||
return reply;
|
||||
}
|
||||
|
||||
// connect(&cmd, &QProcess::readyReadStandardOutput, this, &ExternalCommandHelper::onReadOutput);
|
||||
|
||||
|
@ -220,8 +214,19 @@ QVariantMap ExternalCommandHelper::start(const QString& Uuid, const QString& com
|
|||
return reply;
|
||||
}
|
||||
|
||||
bool ExternalCommandHelper::isCallerAuthorized(const QString& Uuid)
|
||||
{
|
||||
if (Uuid != m_callerUuid) {
|
||||
qWarning() << "Caller is not authorized";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExternalCommandHelper::exit(const QString& Uuid)
|
||||
{
|
||||
isCallerAuthorized(Uuid);
|
||||
m_loop.exit();
|
||||
}
|
||||
|
||||
|
|
|
@ -36,17 +36,18 @@ Q_SIGNALS:
|
|||
void quit();
|
||||
|
||||
public:
|
||||
bool readData(QString& sourceDevice, QByteArray& buffer, qint64 offset, qint64 size);
|
||||
bool writeData(QString& targetDevice, QByteArray& buffer, qint64 offset);
|
||||
bool readData(const QString& sourceDevice, QByteArray& buffer, qint64 offset, qint64 size);
|
||||
bool writeData(const QString& targetDevice, const QByteArray& buffer, qint64 offset);
|
||||
|
||||
public Q_SLOTS:
|
||||
ActionReply init(const QVariantMap& args);
|
||||
Q_SCRIPTABLE QVariantMap start(const QString& Uuid, const QString& command, const QStringList& arguments, const QByteArray& input, const QStringList& environment);
|
||||
Q_SCRIPTABLE QVariantMap copyblocks(const QString& Uuid, const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize);
|
||||
Q_SCRIPTABLE void exit(const QString& Uuid);
|
||||
ActionReply copyblockshelper(const QVariantMap& args);
|
||||
|
||||
private:
|
||||
void onReadOutput();
|
||||
bool isCallerAuthorized(const QString& Uuid);
|
||||
|
||||
QEventLoop m_loop;
|
||||
QString m_callerUuid;
|
||||
|
|
|
@ -15,11 +15,12 @@ add_compile_options(-fPIC)
|
|||
# Helper macro to link to the helper (for initialization of kpmcore)
|
||||
# and to add a test with the given name.
|
||||
#
|
||||
add_library(testhelpers OBJECT helpers.cpp)
|
||||
add_library(testhelpers STATIC helpers.cpp)
|
||||
target_link_libraries(testhelpers KF5::Auth)
|
||||
|
||||
macro (kpm_test name)
|
||||
add_executable(${name} ${ARGN} $<TARGET_OBJECTS:testhelpers>)
|
||||
target_link_libraries(${name} kpmcore)
|
||||
add_executable(${name} ${ARGN})
|
||||
target_link_libraries(${name} testhelpers kpmcore)
|
||||
endmacro()
|
||||
|
||||
###
|
||||
|
@ -29,13 +30,13 @@ kpm_test(testinit testinit.cpp) # Default backend
|
|||
if(TARGET pmdummybackendplugin)
|
||||
add_test(NAME testinit-dummy COMMAND testinit $<TARGET_FILE:pmdummybackendplugin>)
|
||||
endif()
|
||||
if(TARGET pmlibpartedbackendplugin)
|
||||
add_test(NAME testinit-parted COMMAND testinit $<TARGET_FILE:pmlibpartedbackendplugin>)
|
||||
if(TARGET pmsfdiskbackendplugin)
|
||||
add_test(NAME testinit-sfdisk COMMAND testinit $<TARGET_FILE:pmsfdiskbackendplugin>)
|
||||
else()
|
||||
return() # All the rest really needs a working backend
|
||||
endif()
|
||||
|
||||
set(BACKEND $<TARGET_FILE:pmlibpartedbackendplugin>)
|
||||
set(BACKEND $<TARGET_FILE:pmsfdiskbackendplugin>)
|
||||
|
||||
###
|
||||
#
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "core/partition.h"
|
||||
#include "util/capacity.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QList>
|
||||
|
||||
|
@ -63,6 +64,7 @@ PartitionList flatten(PartitionTable *table)
|
|||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
if (argc != 2)
|
||||
{
|
||||
KPMCoreInitializer i;
|
||||
|
|
|
@ -21,10 +21,13 @@
|
|||
// the current platform, or if one is named on the command line,
|
||||
// loads that one. Returns 0 on success.
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include "helpers.h"
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
if ( argc != 2 )
|
||||
{
|
||||
KPMCoreInitializer i;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "core/partition.h"
|
||||
#include "util/capacity.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QList>
|
||||
|
||||
|
@ -60,6 +61,8 @@ PartitionList flatten(PartitionTable *table)
|
|||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
KPMCoreInitializer i;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "core/smartstatus.h"
|
||||
#include "core/smartparser.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
|
||||
static QString getDefaultDevicePath();
|
||||
|
@ -15,7 +15,7 @@ static bool testSmartParser();
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
KPMCoreInitializer i;
|
||||
|
||||
|
|
Loading…
Reference in New Issue