阶段提交
This commit is contained in:
parent
2c2815d433
commit
2b1f31aef0
|
@ -37,6 +37,7 @@ HEADERS += \
|
||||||
myprocess/rsyncpathtodirprocess.h \
|
myprocess/rsyncpathtodirprocess.h \
|
||||||
parsebackuplist.h \
|
parsebackuplist.h \
|
||||||
systembackupproxy.h \
|
systembackupproxy.h \
|
||||||
|
udisksystembackupproxy.h \
|
||||||
workerfactory.h
|
workerfactory.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
@ -54,6 +55,7 @@ SOURCES += \
|
||||||
myprocess/rsyncpathtodirprocess.cpp \
|
myprocess/rsyncpathtodirprocess.cpp \
|
||||||
parsebackuplist.cpp \
|
parsebackuplist.cpp \
|
||||||
systembackupproxy.cpp \
|
systembackupproxy.cpp \
|
||||||
|
udisksystembackupproxy.cpp \
|
||||||
workerfactory.cpp
|
workerfactory.cpp
|
||||||
|
|
||||||
# Default rules for deployment.
|
# Default rules for deployment.
|
||||||
|
|
|
@ -35,6 +35,7 @@ int main(int argc, char *argv[])
|
||||||
QString qsAppPath = QCoreApplication::applicationDirPath();
|
QString qsAppPath = QCoreApplication::applicationDirPath();
|
||||||
Utils::initSysRootPath(qsAppPath);
|
Utils::initSysRootPath(qsAppPath);
|
||||||
qInstallMessageHandler(Utils::customMessageHandler);
|
qInstallMessageHandler(Utils::customMessageHandler);
|
||||||
|
Utils::initSystemInfo();
|
||||||
|
|
||||||
// test begin
|
// test begin
|
||||||
qDebug() << QString("测试 begin");
|
qDebug() << QString("测试 begin");
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#include "rsyncpathtodirprocess.h"
|
#include "rsyncpathtodirprocess.h"
|
||||||
#include <unistd.h>
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
RsyncPathToDirProcess::RsyncPathToDirProcess(QObject *parent) :
|
RsyncPathToDirProcess::RsyncPathToDirProcess(QObject *parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_p(new QProcess(this))
|
m_p(new QProcess(this)),
|
||||||
|
m_syncProcess(new QProcess(this))
|
||||||
{
|
{
|
||||||
m_currentRate = 0;
|
m_currentRate = 0;
|
||||||
m_bSuccess = false;
|
m_bSuccess = false;
|
||||||
|
@ -19,7 +19,6 @@ RsyncPathToDirProcess::RsyncPathToDirProcess(QObject *parent) :
|
||||||
if (m_currentRate == tmpRate)
|
if (m_currentRate == tmpRate)
|
||||||
return;
|
return;
|
||||||
m_currentRate = tmpRate;
|
m_currentRate = tmpRate;
|
||||||
sync();
|
|
||||||
emit progress(m_currentRate);
|
emit progress(m_currentRate);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -34,7 +33,13 @@ RsyncPathToDirProcess::RsyncPathToDirProcess(QObject *parent) :
|
||||||
m_p->kill();
|
m_p->kill();
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(m_p, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processFinished(int, QProcess::ExitStatus)));
|
connect(m_p, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(rsync_finished(int, QProcess::ExitStatus)));
|
||||||
|
|
||||||
|
connect(m_syncProcess, &QProcess::errorOccurred, this, [&](QProcess::ProcessError error) {
|
||||||
|
Q_UNUSED(error)
|
||||||
|
m_syncProcess->kill();
|
||||||
|
});
|
||||||
|
connect(m_syncProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(sync_finished(int, QProcess::ExitStatus)));
|
||||||
}
|
}
|
||||||
|
|
||||||
RsyncPathToDirProcess::~RsyncPathToDirProcess()
|
RsyncPathToDirProcess::~RsyncPathToDirProcess()
|
||||||
|
@ -49,6 +54,7 @@ bool RsyncPathToDirProcess::start(QStringList args, bool block)
|
||||||
qDebug() << "RsyncPathToDirProcess::start invoke begin";
|
qDebug() << "RsyncPathToDirProcess::start invoke begin";
|
||||||
m_currentRate = 0;
|
m_currentRate = 0;
|
||||||
m_bSuccess = false;
|
m_bSuccess = false;
|
||||||
|
m_block = block;
|
||||||
|
|
||||||
QString cmd("rsync");
|
QString cmd("rsync");
|
||||||
for (const QString& item : args) {
|
for (const QString& item : args) {
|
||||||
|
@ -63,7 +69,7 @@ bool RsyncPathToDirProcess::start(QStringList args, bool block)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block) {
|
if (m_block) {
|
||||||
if (!m_p->waitForFinished()) {
|
if (!m_p->waitForFinished()) {
|
||||||
qCritical("rsync finished failed");
|
qCritical("rsync finished failed");
|
||||||
return false;
|
return false;
|
||||||
|
@ -74,18 +80,40 @@ bool RsyncPathToDirProcess::start(QStringList args, bool block)
|
||||||
return m_bSuccess;
|
return m_bSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RsyncPathToDirProcess::processFinished(int exitCode, QProcess::ExitStatus)
|
void RsyncPathToDirProcess::rsync_finished(int exitCode, QProcess::ExitStatus)
|
||||||
{
|
{
|
||||||
qDebug() << "RsyncPathToDirProcess::processFinished invoke begin";
|
qDebug() << "RsyncPathToDirProcess::rsync_finished invoke begin";
|
||||||
|
|
||||||
if (exitCode == QProcess::NormalExit || exitCode == 24 || exitCode == 23) {
|
if (exitCode == QProcess::NormalExit || exitCode == 24 || exitCode == 23) {
|
||||||
sync();
|
if (m_block) {
|
||||||
m_bSuccess = true;
|
m_bSuccess = true;
|
||||||
emit progress(100);
|
emit progress(100);
|
||||||
emit finished(true);
|
emit finished(true);
|
||||||
} else {
|
} else {
|
||||||
|
m_syncProcess->start("sync");
|
||||||
|
if (!m_syncProcess->waitForStarted()) {
|
||||||
|
m_bSuccess = false;
|
||||||
|
emit finished(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_bSuccess = false;
|
||||||
|
emit finished(false);
|
||||||
|
}
|
||||||
|
qDebug() << "RsyncPathToDirProcess::rsync_finished invoke end";
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsyncPathToDirProcess::sync_finished(int exitCode, QProcess::ExitStatus)
|
||||||
|
{
|
||||||
|
qDebug() << "RsyncPathToDirProcess::sync_finished invoke begin";
|
||||||
|
|
||||||
|
if (exitCode == QProcess::NormalExit || exitCode == 24 || exitCode == 23) {
|
||||||
|
m_bSuccess = true;
|
||||||
|
emit progress(100);
|
||||||
|
emit finished(true);
|
||||||
|
} else {
|
||||||
|
m_bSuccess = false;
|
||||||
emit finished(false);
|
emit finished(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "RsyncPathToDirProcess::processFinished invoke end";
|
qDebug() << "RsyncPathToDirProcess::sync_finished invoke end";
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,11 @@ public:
|
||||||
|
|
||||||
bool start(QStringList args, bool block = true);
|
bool start(QStringList args, bool block = true);
|
||||||
|
|
||||||
|
inline void stop() {
|
||||||
|
m_p->kill();
|
||||||
|
m_syncProcess->kill();
|
||||||
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// 结果信号
|
// 结果信号
|
||||||
void finished(bool result);
|
void finished(bool result);
|
||||||
|
@ -20,12 +25,16 @@ signals:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
// m_p执行结束
|
// m_p执行结束
|
||||||
void processFinished(int exitCode, QProcess::ExitStatus);
|
void rsync_finished(int exitCode, QProcess::ExitStatus);
|
||||||
|
// m_syncProcess执行结束
|
||||||
|
void sync_finished(int exitCode, QProcess::ExitStatus);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QProcess * m_p;
|
QProcess * m_p;
|
||||||
|
QProcess* m_syncProcess;
|
||||||
int m_currentRate;
|
int m_currentRate;
|
||||||
bool m_bSuccess;
|
bool m_bSuccess;
|
||||||
|
bool m_block;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RSYNCPATHTODIRPROCESS_H
|
#endif // RSYNCPATHTODIRPROCESS_H
|
||||||
|
|
|
@ -31,6 +31,10 @@
|
||||||
#define TYPE "Type"
|
#define TYPE "Type"
|
||||||
#define POSITION "Position"
|
#define POSITION "Position"
|
||||||
#define USERID "UserId"
|
#define USERID "UserId"
|
||||||
|
#define OS "OS"
|
||||||
|
#define ARCH "Arch"
|
||||||
|
#define ARCHDETECT "ArchDetect"
|
||||||
|
|
||||||
#define STATUE_BACKUP_FINESHED "backup finished"
|
#define STATUE_BACKUP_FINESHED "backup finished"
|
||||||
|
|
||||||
ParseBackupList::ParseBackupList(const QString& xmlPath)
|
ParseBackupList::ParseBackupList(const QString& xmlPath)
|
||||||
|
@ -312,6 +316,18 @@ void ParseBackupList::elementNodeToBackupPoint(const QDomElement& node, BackupPo
|
||||||
QDomElement eleUserId = node.firstChildElement(USERID);
|
QDomElement eleUserId = node.firstChildElement(USERID);
|
||||||
if (!eleUserId.isNull())
|
if (!eleUserId.isNull())
|
||||||
backupPoint.m_userId = eleUserId.text();
|
backupPoint.m_userId = eleUserId.text();
|
||||||
|
|
||||||
|
QDomElement eleOS = node.firstChildElement(OS);
|
||||||
|
if (!eleOS.isNull())
|
||||||
|
backupPoint.m_os = eleOS.text();
|
||||||
|
|
||||||
|
QDomElement eleArch = node.firstChildElement(ARCH);
|
||||||
|
if (!eleArch.isNull())
|
||||||
|
backupPoint.m_arch = eleArch.text();
|
||||||
|
|
||||||
|
QDomElement eleArchDetect = node.firstChildElement(ARCHDETECT);
|
||||||
|
if (!eleArchDetect.isNull())
|
||||||
|
backupPoint.m_archdetect = eleArchDetect.text();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -328,8 +344,19 @@ void ParseBackupList::backupPointToElementNode(const BackupPoint& backupPoint, Q
|
||||||
node.appendChild(createTextElement(doc, STATE, backupPoint.m_state));
|
node.appendChild(createTextElement(doc, STATE, backupPoint.m_state));
|
||||||
node.appendChild(createTextElement(doc, TYPE, QString::number(backupPoint.m_type)));
|
node.appendChild(createTextElement(doc, TYPE, QString::number(backupPoint.m_type)));
|
||||||
node.appendChild(createTextElement(doc, POSITION, QString::number(backupPoint.m_iPosition)));
|
node.appendChild(createTextElement(doc, POSITION, QString::number(backupPoint.m_iPosition)));
|
||||||
|
if (!backupPoint.m_userId.isEmpty()) {
|
||||||
node.appendChild(createTextElement(doc, USERID, backupPoint.m_userId));
|
node.appendChild(createTextElement(doc, USERID, backupPoint.m_userId));
|
||||||
}
|
}
|
||||||
|
if (!backupPoint.m_os.isEmpty()) {
|
||||||
|
node.appendChild(createTextElement(doc, OS, backupPoint.m_os));
|
||||||
|
}
|
||||||
|
if (!backupPoint.m_arch.isEmpty()) {
|
||||||
|
node.appendChild(createTextElement(doc, ARCH, backupPoint.m_arch));
|
||||||
|
}
|
||||||
|
if (!backupPoint.m_archdetect.isEmpty()) {
|
||||||
|
node.appendChild(createTextElement(doc, ARCHDETECT, backupPoint.m_archdetect));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief createTextElement
|
* @brief createTextElement
|
||||||
|
|
|
@ -35,6 +35,14 @@ public:
|
||||||
QString m_state;
|
QString m_state;
|
||||||
// 备份用户id
|
// 备份用户id
|
||||||
QString m_userId;
|
QString m_userId;
|
||||||
|
// 备份机器操作系统
|
||||||
|
QString m_os;
|
||||||
|
// 备份机器架构
|
||||||
|
QString m_arch;
|
||||||
|
// 备份机器引导方式
|
||||||
|
QString m_archdetect;
|
||||||
|
// 备份点所在设备挂载路径(这个暂只在查询中界面展示选择中使用)
|
||||||
|
QString m_path;
|
||||||
|
|
||||||
bool isNull() { return m_uuid.isEmpty(); }
|
bool isNull() { return m_uuid.isEmpty(); }
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,349 @@
|
||||||
|
#include "udisksystembackupproxy.h"
|
||||||
|
|
||||||
|
#include "systembackupproxy.h"
|
||||||
|
#include <QStorageInfo>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <kysec/status.h>
|
||||||
|
#include "../common/utils.h"
|
||||||
|
#include "../common/mydusizetool.h"
|
||||||
|
#include "mymountproxy.h"
|
||||||
|
|
||||||
|
IMPLEMENT_DYNCREATE(UDiskSystemBackupProxy)
|
||||||
|
|
||||||
|
UDiskSystemBackupProxy::UDiskSystemBackupProxy()
|
||||||
|
{
|
||||||
|
m_bSuccess = false;
|
||||||
|
m_p = nullptr;
|
||||||
|
m_size = 0;
|
||||||
|
m_calc = new CalcBackupSize(this);
|
||||||
|
m_isOnlyCheck = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
UDiskSystemBackupProxy::~UDiskSystemBackupProxy()
|
||||||
|
{
|
||||||
|
delete m_p;
|
||||||
|
m_p = nullptr;
|
||||||
|
|
||||||
|
delete m_calc;
|
||||||
|
m_calc = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 环境检测
|
||||||
|
* @return false,检测失败;true,检测成功
|
||||||
|
*/
|
||||||
|
bool UDiskSystemBackupProxy::checkEnvEx()
|
||||||
|
{
|
||||||
|
qDebug() << "UDiskSystemBackupProxy::checkEnv invoke begin";
|
||||||
|
|
||||||
|
// 1、检查/backup分区是否挂载上(不管是本地磁盘还是u盘设备,都得保证/backup挂载上); 若没挂载,挂载
|
||||||
|
MyMountProxy mountProxy;
|
||||||
|
if ( MountResult::MOUNTED != mountProxy.mountBackupPartition() ) {
|
||||||
|
emit checkResult(int(BackupResult::BACKUP_PARTITION_MOUNT_FAIL));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2、计算备份大小
|
||||||
|
calcSizeForBackup();
|
||||||
|
|
||||||
|
qDebug() << "UDiskSystemBackupProxy::checkEnv invoke end";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 执行备份逻辑
|
||||||
|
*/
|
||||||
|
void UDiskSystemBackupProxy::doWorkEx()
|
||||||
|
{
|
||||||
|
qDebug() << "UDiskSystemBackupProxy::doWorkEx invoke begin";
|
||||||
|
|
||||||
|
m_isOnlyCheck = false;
|
||||||
|
// 环境检测
|
||||||
|
checkEnvEx();
|
||||||
|
|
||||||
|
qDebug() << "UDiskSystemBackupProxy::doWorkEx invoke end";
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDiskSystemBackupProxy::cancelEx()
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 判断是否增量备份
|
||||||
|
* @return true,增量备份; false,全量备份
|
||||||
|
*/
|
||||||
|
bool UDiskSystemBackupProxy::isIncBackup()
|
||||||
|
{
|
||||||
|
QString backupPath;
|
||||||
|
ParseBackupList::BackupPoint point;
|
||||||
|
if (m_backupWrapper.m_uuid.isEmpty()) {
|
||||||
|
QString xmlPath(m_backupWrapper.m_prefixDestPath + BACKUP_XML_PATH);
|
||||||
|
xmlPath.replace("//", "/");
|
||||||
|
ParseBackupList parser(xmlPath);
|
||||||
|
point = parser.getLastSysBackupPoint();
|
||||||
|
if (point.m_uuid.isEmpty())
|
||||||
|
return false;
|
||||||
|
backupPath = m_backupWrapper.m_prefixDestPath + BACKUP_SNAPSHOTS_PATH + "/" + point.m_uuid + "/data";
|
||||||
|
} else {
|
||||||
|
backupPath = m_backupWrapper.m_prefixDestPath + BACKUP_SNAPSHOTS_PATH + "/" + m_backupWrapper.m_uuid + "/data";
|
||||||
|
}
|
||||||
|
|
||||||
|
backupPath.replace("//", "/");
|
||||||
|
if (Utils::isDirExist(backupPath)) {
|
||||||
|
m_backupWrapper.m_baseUuid = point.m_uuid;
|
||||||
|
m_backupWrapper.m_bIncrement = true;
|
||||||
|
m_backupWrapper.m_type = BackupType::INC_BACKUP_SYSTEM;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 校验剩余空间是否满足备份
|
||||||
|
*/
|
||||||
|
void UDiskSystemBackupProxy::checkFreeCapacity(qint64 itotalSize)
|
||||||
|
{
|
||||||
|
qDebug() << "UDiskSystemBackupProxy::checkFreeCapacity invoke begin";
|
||||||
|
|
||||||
|
// 1、计算待备份数据的大小
|
||||||
|
m_size = itotalSize;
|
||||||
|
// 备份过程中会有一些临时文件产生,会占用一部分空间,故我们预留500M的空间
|
||||||
|
itotalSize += 500 * MB;
|
||||||
|
|
||||||
|
// 2、计算备份分区剩余空间大小
|
||||||
|
QString backupPath(m_backupWrapper.m_prefixDestPath);
|
||||||
|
backupPath.replace("//", "/");
|
||||||
|
QStorageInfo backupDisk(backupPath);
|
||||||
|
qint64 freeSize = backupDisk.bytesFree();
|
||||||
|
|
||||||
|
// 3、校验空间是否足够
|
||||||
|
if (itotalSize > freeSize) {
|
||||||
|
emit checkResult(int(BackupResult::BACKUP_CAPACITY_IS_NOT_ENOUGH));
|
||||||
|
} else {
|
||||||
|
emit checkResult(int(BackupResult::CHECK_ENV_SUCCESS));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_isOnlyCheck)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
// 开始备份
|
||||||
|
doBackup();
|
||||||
|
|
||||||
|
qDebug() << "UDiskSystemBackupProxy::checkFreeCapacity invoke end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 计算备份所需空间大小
|
||||||
|
* @return 计算备份所需空间大小,单位字节
|
||||||
|
*/
|
||||||
|
void UDiskSystemBackupProxy::calcSizeForBackup()
|
||||||
|
{
|
||||||
|
// 拼接备份源路径和目标路径,测试所需备份空间大小;目标路径为一虚拟路径
|
||||||
|
QString srcPath = Utils::getSysRootPath();
|
||||||
|
srcPath += "/";
|
||||||
|
srcPath.replace("//", "/");
|
||||||
|
QString destPath = Utils::getSysRootPath();
|
||||||
|
destPath += CHECK_PATH;
|
||||||
|
destPath.replace("//", "/");
|
||||||
|
Utils::mkpath(destPath);
|
||||||
|
|
||||||
|
QStringList args = getRsyncArgs(UDiskSystemBackupScene::TRY_SYSTEM_BACKUP);
|
||||||
|
args << srcPath;
|
||||||
|
args << destPath;
|
||||||
|
|
||||||
|
connect(m_calc, &CalcBackupSize::finished, this, &UDiskSystemBackupProxy::checkFreeCapacity);
|
||||||
|
m_calc->start(args, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 根据场景获取rsync命令参数
|
||||||
|
* @param scene,场景
|
||||||
|
* @return rsync的参数信息
|
||||||
|
*/
|
||||||
|
QStringList UDiskSystemBackupProxy::getRsyncArgs(UDiskSystemBackupScene scene)
|
||||||
|
{
|
||||||
|
QStringList args;
|
||||||
|
|
||||||
|
switch (scene) {
|
||||||
|
case UDiskSystemBackupScene::SYSTEM_BACKUP :
|
||||||
|
args << "-avAHXW";
|
||||||
|
args << "--progress";
|
||||||
|
args << "--no-inc-recursive";
|
||||||
|
args << "--ignore-missing-args";
|
||||||
|
break ;
|
||||||
|
case UDiskSystemBackupScene::TRY_SYSTEM_BACKUP :
|
||||||
|
args << "-aAHXWn";
|
||||||
|
args << "--stats";
|
||||||
|
args << "--ignore-missing-args";
|
||||||
|
break ;
|
||||||
|
default:
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 备份
|
||||||
|
*/
|
||||||
|
void UDiskSystemBackupProxy::doBackup()
|
||||||
|
{
|
||||||
|
qDebug() << "UDiskSystemBackupProxy::doBackup invoke begin";
|
||||||
|
|
||||||
|
// 准备
|
||||||
|
if (!doPrepare())
|
||||||
|
return ;
|
||||||
|
|
||||||
|
// 启动备份efi, 修改为和其它目录统一备份,不再单独进行备份
|
||||||
|
// if (!backupEfi()) {
|
||||||
|
// emit checkResult(int(BackupResult::EFI_RSYNC_FAIL));
|
||||||
|
// return ;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 启动系统备份
|
||||||
|
backupSystem();
|
||||||
|
|
||||||
|
qDebug() << "UDiskSystemBackupProxy::doBackup invoke end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 备份准备
|
||||||
|
* @return true,准备成功;false,准备失败
|
||||||
|
*/
|
||||||
|
bool UDiskSystemBackupProxy::doPrepare()
|
||||||
|
{
|
||||||
|
qDebug() << "UDiskSystemBackupProxy::doPrepare invoke begin";
|
||||||
|
|
||||||
|
m_bSuccess = false;
|
||||||
|
|
||||||
|
// 1、设置当前备份的Uuid
|
||||||
|
m_curUuid += Utils::createUuid();
|
||||||
|
|
||||||
|
// 2、准备备份目录及文件
|
||||||
|
m_destPath = m_backupWrapper.m_prefixDestPath + BACKUP_SNAPSHOTS_PATH + "/" + m_curUuid + "/data";
|
||||||
|
m_destPath.replace("//", "/");
|
||||||
|
if (!Utils::mkpath(m_destPath)) {
|
||||||
|
emit checkResult(int(BackupResult::WRITE_BACKUP_PATHS_TO_USER_FAILED));
|
||||||
|
qCritical() << QString("mkdir %1 failed !").arg(m_destPath) ;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString userFile = m_backupWrapper.m_prefixDestPath + BACKUP_SNAPSHOTS_PATH + "/" + m_curUuid + "/" + PATHS_USER_FILE;
|
||||||
|
userFile.replace("//", "/");
|
||||||
|
if (!Utils::writeFileByLines(userFile, m_backupWrapper.m_backupPaths)) {
|
||||||
|
emit checkResult(int(BackupResult::WRITE_BACKUP_PATHS_TO_USER_FAILED));
|
||||||
|
qCritical() << QString("create file %1 failed !").arg(userFile) ;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString excludeUserFile = m_backupWrapper.m_prefixDestPath + BACKUP_SNAPSHOTS_PATH + "/" + m_curUuid + "/" + EXCLUDE_PATHS_USER_FILE;
|
||||||
|
excludeUserFile.replace("//", "/");
|
||||||
|
if (!Utils::writeFileByLines(excludeUserFile, m_backupWrapper.m_backupExcludePaths)) {
|
||||||
|
emit checkResult(int(BackupResult::WRITE_BACKUP_PATHS_TO_USER_FAILED));
|
||||||
|
qCritical() << QString("create file %1 failed !").arg(excludeUserFile) ;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3、记录/backup/snapshots/backuplist.xml文件
|
||||||
|
if (!recordBackupPoint()) {
|
||||||
|
qCritical() << "add or update item to backuplist.xml failed !";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "UDiskSystemBackupProxy::doPrepare invoke end";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 记录/backup/snapshots/backuplist.xml文件
|
||||||
|
* @return true-成功;false-失败
|
||||||
|
*/
|
||||||
|
bool UDiskSystemBackupProxy::recordBackupPoint()
|
||||||
|
{
|
||||||
|
m_backupPoint.m_backupName = m_backupWrapper.m_backupName;
|
||||||
|
m_backupPoint.m_uuid = m_curUuid;
|
||||||
|
m_backupPoint.m_iPosition = m_backupWrapper.m_iPosition;
|
||||||
|
m_backupPoint.m_type = m_backupWrapper.m_type;
|
||||||
|
m_backupPoint.m_size = Utils::StringBySize(m_size);
|
||||||
|
m_backupPoint.m_time = QDateTime::currentDateTime().toString("yy-MM-dd hh:mm:ss");
|
||||||
|
m_backupPoint.m_state = BACKUP_PARSE_STATE_FAIL_STRTING;
|
||||||
|
m_backupPoint.m_os = SystemInfo::m_os;
|
||||||
|
m_backupPoint.m_arch = SystemInfo::m_arch;
|
||||||
|
m_backupPoint.m_archdetect = SystemInfo::m_archDetect;
|
||||||
|
QString xmlPath = m_backupWrapper.m_prefixDestPath + BACKUP_XML_PATH;
|
||||||
|
xmlPath.replace("//", "/");
|
||||||
|
ParseBackupList parse(xmlPath);
|
||||||
|
if (m_backupWrapper.m_uuid.isEmpty() || !m_backupWrapper.m_bIncrement) {
|
||||||
|
if (parse.addItem(m_backupPoint) != ParseBackupList::SUCCESS) {
|
||||||
|
emit checkResult(int(BackupResult::WRITE_STORAGEINFO_ADD_ITEM_FAIL));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (parse.updateItem(m_backupPoint) != ParseBackupList::SUCCESS) {
|
||||||
|
emit checkResult(int(BackupResult::WRITE_STORAGEINFO_UPDATE_ITEM_FAIL));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 备份系统
|
||||||
|
* @return true,备份成功;false,备份失败
|
||||||
|
*/
|
||||||
|
bool UDiskSystemBackupProxy::backupSystem()
|
||||||
|
{
|
||||||
|
qDebug() << "UDiskSystemBackupProxy::backupSystem invoke begin";
|
||||||
|
|
||||||
|
// 全量备份场景
|
||||||
|
QStringList args = getRsyncArgs(UDiskSystemBackupScene::SYSTEM_BACKUP);
|
||||||
|
|
||||||
|
// 拼接备份源路径和目标路径
|
||||||
|
QString srcPath = Utils::getSysRootPath();
|
||||||
|
srcPath += "/";
|
||||||
|
srcPath.replace("//", "/");
|
||||||
|
args << srcPath;
|
||||||
|
QString destPath = m_destPath + "/";
|
||||||
|
destPath.replace("//", "/");
|
||||||
|
args << destPath;
|
||||||
|
|
||||||
|
m_p = new RsyncPathToDirProcess(this);
|
||||||
|
connect(m_p, &RsyncPathToDirProcess::progress, this, &UDiskSystemBackupProxy::progress);
|
||||||
|
connect(m_p, &RsyncPathToDirProcess::finished, this, [&](bool result) {
|
||||||
|
if (result) {
|
||||||
|
m_backupPoint.m_state = BACKUP_PARSE_STATE_SUCCESS_STRTING;
|
||||||
|
QString xmlPath = m_backupWrapper.m_prefixDestPath + BACKUP_XML_PATH;
|
||||||
|
xmlPath.replace("//", "/");
|
||||||
|
ParseBackupList parse(xmlPath);
|
||||||
|
parse.updateItem(m_backupPoint);
|
||||||
|
|
||||||
|
Utils::writeBackupLog(m_backupPoint.m_time + ","
|
||||||
|
+ m_curUuid + "," + QString::number(m_backupWrapper.m_type) + ","
|
||||||
|
+ m_backupWrapper.m_note + "," + m_backupPoint.m_size);
|
||||||
|
m_bSuccess = true;
|
||||||
|
}
|
||||||
|
emit this->workResult(result);
|
||||||
|
});
|
||||||
|
m_p->start(args, false);
|
||||||
|
|
||||||
|
do_kylin_security(m_destPath);
|
||||||
|
|
||||||
|
qDebug() << "UDiskSystemBackupProxy::backupSystem invoke end";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDiskSystemBackupProxy::do_kylin_security(const QString& dstDir)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
ret = kysec_getstatus();
|
||||||
|
if (ret > 0) {
|
||||||
|
QString seFilePath(dstDir + "/.exectl");
|
||||||
|
QFile file(seFilePath);
|
||||||
|
file.open(QIODevice::WriteOnly);
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
#ifndef UDISKSYSTEMBACKUPPROXY_H
|
||||||
|
#define UDISKSYSTEMBACKUPPROXY_H
|
||||||
|
|
||||||
|
#include "workerfactory.h"
|
||||||
|
#include "myprocess/rsyncpathtodirprocess.h"
|
||||||
|
#include "parsebackuplist.h"
|
||||||
|
#include "myprocess/calcbackupsize.h"
|
||||||
|
|
||||||
|
class UDiskSystemBackupProxy : public Worker
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
DECLARE_DYNCREATE(UDiskSystemBackupProxy)
|
||||||
|
|
||||||
|
public:
|
||||||
|
// 系统备份的几种场景
|
||||||
|
enum UDiskSystemBackupScene {
|
||||||
|
SYSTEM_BACKUP, // 系统备份
|
||||||
|
TRY_SYSTEM_BACKUP, // 测试系统备份,可用于计算备份传输数据大小
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit UDiskSystemBackupProxy();
|
||||||
|
virtual ~UDiskSystemBackupProxy();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// 环境检测
|
||||||
|
virtual bool checkEnvEx();
|
||||||
|
|
||||||
|
// 任务处理
|
||||||
|
virtual void doWorkEx();
|
||||||
|
|
||||||
|
// 任务取消
|
||||||
|
virtual void cancelEx();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
// 校验剩余空间是否满足备份
|
||||||
|
void checkFreeCapacity(qint64 itotalSize);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 判断是否增量备份
|
||||||
|
bool isIncBackup();
|
||||||
|
|
||||||
|
// 计算备份所需空间大小
|
||||||
|
void calcSizeForBackup();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 根据场景获取rsync命令参数
|
||||||
|
* @param scene,场景
|
||||||
|
* @return 组装好的rsync的参数信息
|
||||||
|
*/
|
||||||
|
QStringList getRsyncArgs(UDiskSystemBackupScene scene);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 记录/backup/snapshots/backuplist.xml文件
|
||||||
|
* @return true-成功;false-失败
|
||||||
|
*/
|
||||||
|
bool recordBackupPoint();
|
||||||
|
|
||||||
|
// 备份准备
|
||||||
|
bool doPrepare();
|
||||||
|
|
||||||
|
// 备份
|
||||||
|
void doBackup();
|
||||||
|
|
||||||
|
// 备份系统
|
||||||
|
bool backupSystem();
|
||||||
|
|
||||||
|
void do_kylin_security(const QString& dstDir);
|
||||||
|
|
||||||
|
// 计算备份空间大小的进程
|
||||||
|
CalcBackupSize *m_calc;
|
||||||
|
|
||||||
|
// 是否备份成功
|
||||||
|
bool m_bSuccess;
|
||||||
|
// 当前备份uuid
|
||||||
|
QString m_curUuid;
|
||||||
|
// 当前备份目标目录
|
||||||
|
QString m_destPath;
|
||||||
|
// 当前备份所需空间大小
|
||||||
|
qint64 m_size;
|
||||||
|
// 备份进程
|
||||||
|
RsyncPathToDirProcess *m_p;
|
||||||
|
// 当前备份节点
|
||||||
|
ParseBackupList::BackupPoint m_backupPoint;
|
||||||
|
// 是否只是检测
|
||||||
|
bool m_isOnlyCheck;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // UDISKSYSTEMBACKUPPROXY_H
|
|
@ -21,6 +21,10 @@
|
||||||
#include "mylittleparse.h"
|
#include "mylittleparse.h"
|
||||||
#include "mydefine.h"
|
#include "mydefine.h"
|
||||||
|
|
||||||
|
QString SystemInfo::m_os;
|
||||||
|
QString SystemInfo::m_arch;
|
||||||
|
QString SystemInfo::m_archDetect;
|
||||||
|
|
||||||
QString Utils::m_sysRootPath = "/";
|
QString Utils::m_sysRootPath = "/";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -897,3 +901,59 @@ QList<BackupWrapper> Utils::getBackupLogList()
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化系统信息
|
||||||
|
*/
|
||||||
|
void Utils::initSystemInfo()
|
||||||
|
{
|
||||||
|
SystemInfo::m_os = Utils::getOs();
|
||||||
|
SystemInfo::m_arch = Utils::getArch();
|
||||||
|
SystemInfo::m_archDetect = Utils::getArchDetect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief getOs
|
||||||
|
* @return 操作系统名字, 如:
|
||||||
|
* Kylin-Desktop V10-SP1
|
||||||
|
* Build 20210407
|
||||||
|
*/
|
||||||
|
QString Utils::getOs()
|
||||||
|
{
|
||||||
|
QString path = Utils::getSysRootPath() + "/etc/kylin-build";
|
||||||
|
path.replace("//", "/");
|
||||||
|
QFile file(path);
|
||||||
|
/* 文件内容形如:
|
||||||
|
Kylin-Desktop V10-SP1
|
||||||
|
Build 20210407
|
||||||
|
*/
|
||||||
|
QString os;
|
||||||
|
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
QTextStream in(&file);
|
||||||
|
if (!in.atEnd()) {
|
||||||
|
os = in.readLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief getArch
|
||||||
|
* @return 架构,arch命令的结果,如:x86_64
|
||||||
|
*/
|
||||||
|
QString Utils::getArch()
|
||||||
|
{
|
||||||
|
QString arch = Utils::executeCmd("arch");
|
||||||
|
return arch.replace("\n", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief getArchDetect
|
||||||
|
* @return archdetect命令的结果,如:amd64/efi
|
||||||
|
*/
|
||||||
|
QString Utils::getArchDetect()
|
||||||
|
{
|
||||||
|
QString arch = Utils::executeCmd("archdetect");
|
||||||
|
return arch.replace("\n", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,17 @@
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
#include "mydefine.h"
|
#include "mydefine.h"
|
||||||
|
|
||||||
|
class SystemInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// 操作系统
|
||||||
|
static QString m_os;
|
||||||
|
// 架构
|
||||||
|
static QString m_arch;
|
||||||
|
// 引导方式
|
||||||
|
static QString m_archDetect;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 工具类
|
* @brief 工具类
|
||||||
* @author zhaominyong
|
* @author zhaominyong
|
||||||
|
@ -212,6 +223,31 @@ public:
|
||||||
*/
|
*/
|
||||||
static QList<BackupWrapper> getBackupLogList();
|
static QList<BackupWrapper> getBackupLogList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化系统信息
|
||||||
|
*/
|
||||||
|
static void initSystemInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief getOs
|
||||||
|
* @return 操作系统名字, 如:
|
||||||
|
* Kylin-Desktop V10-SP1
|
||||||
|
* Build 20210407
|
||||||
|
*/
|
||||||
|
static QString getOs();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief getArch
|
||||||
|
* @return 架构,arch命令的结果,如:x86_64
|
||||||
|
*/
|
||||||
|
static QString getArch();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief getArchDetect
|
||||||
|
* @return archdetect命令的结果,如:amd64/efi
|
||||||
|
*/
|
||||||
|
static QString getArchDetect();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// 系统根目录,默认"/"
|
// 系统根目录,默认"/"
|
||||||
static QString m_sysRootPath;
|
static QString m_sysRootPath;
|
||||||
|
|
Loading…
Reference in New Issue