数据备份代码阶段提交

This commit is contained in:
zhaominyong 2021-12-26 18:15:21 +08:00
parent 1314e236f2
commit c3d9dd085b
25 changed files with 2948 additions and 39 deletions

View File

@ -31,6 +31,7 @@ HEADERS += \
../common/spinlock_mutex.h \ ../common/spinlock_mutex.h \
../common/utils.h \ ../common/utils.h \
backupmanager_adaptor.h \ backupmanager_adaptor.h \
databackupproxy.h \
deletebackupproxy.h \ deletebackupproxy.h \
mybackupmanager.h \ mybackupmanager.h \
mymountproxy.h \ mymountproxy.h \
@ -42,6 +43,7 @@ HEADERS += \
parsebackuplist.h \ parsebackuplist.h \
systembackupproxy.h \ systembackupproxy.h \
systemrestoreproxy.h \ systemrestoreproxy.h \
udiskdatabackupproxy.h \
udisksystembackupproxy.h \ udisksystembackupproxy.h \
udisksystemrestoreproxy.h \ udisksystemrestoreproxy.h \
workerfactory.h workerfactory.h
@ -53,6 +55,7 @@ SOURCES += \
../common/reflect.cpp \ ../common/reflect.cpp \
../common/utils.cpp \ ../common/utils.cpp \
backupmanager_adaptor.cpp \ backupmanager_adaptor.cpp \
databackupproxy.cpp \
deletebackupproxy.cpp \ deletebackupproxy.cpp \
main.cpp \ main.cpp \
mybackupmanager.cpp \ mybackupmanager.cpp \
@ -65,6 +68,7 @@ SOURCES += \
parsebackuplist.cpp \ parsebackuplist.cpp \
systembackupproxy.cpp \ systembackupproxy.cpp \
systemrestoreproxy.cpp \ systemrestoreproxy.cpp \
udiskdatabackupproxy.cpp \
udisksystembackupproxy.cpp \ udisksystembackupproxy.cpp \
udisksystemrestoreproxy.cpp \ udisksystemrestoreproxy.cpp \
workerfactory.cpp workerfactory.cpp

View File

@ -0,0 +1,378 @@
#include "databackupproxy.h"
#include <QStorageInfo>
#include <QDateTime>
#include <QDebug>
#include <kysec/status.h>
#include "../common/utils.h"
#include "../common/mydusizetool.h"
#include "mymountproxy.h"
#include "myprocess/calcbackupsize.h"
IMPLEMENT_DYNCREATE(DataBackupProxy)
DataBackupProxy::DataBackupProxy()
{
m_bSuccess = false;
m_p = nullptr;
m_size = 0;
}
DataBackupProxy::~DataBackupProxy()
{
delete m_p;
m_p = nullptr;
}
/**
* @brief
* @return false,;true,
*/
bool DataBackupProxy::checkEnvEx()
{
qDebug() << "DataBackupProxy::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、判断备份是否增量备份
isIncBackup();
// 3、检测空间是否满足备份
bool result = checkFreeCapacity();
qDebug() << "DataBackupProxy::checkEnv invoke end";
return result;
}
/**
* @brief
*/
void DataBackupProxy::doWorkEx()
{
qDebug() << "DataBackupProxy::doWorkEx invoke begin";
// 环境检测
if (!checkEnvEx())
return ;
// 开始备份
doBackup();
qDebug() << "DataBackupProxy::doWorkEx invoke end";
}
void DataBackupProxy::cancelEx()
{}
/**
* @brief
* @return true, false
*/
bool DataBackupProxy::isIncBackup()
{
QString backupPath;
ParseBackupList::BackupPoint point;
if (m_backupWrapper.m_uuid.isEmpty()) {
return false;
} else {
backupPath = Utils::getSysRootPath() + BACKUP_SNAPSHOTS_PATH + "/" + m_backupWrapper.m_uuid + "/data";
}
backupPath.replace("//", "/");
if (Utils::isDirExist(backupPath)) {
m_backupWrapper.m_bIncrement = true;
m_backupWrapper.m_type = BackupType::INC_BACKUP_DATA;
return true;
}
return false;
}
/**
* @brief
*/
bool DataBackupProxy::checkFreeCapacity()
{
qDebug() << "DataBackupProxy::checkFreeCapacity invoke begin";
// 1、计算待备份数据的大小
qint64 itotalSize = calcSizeForBackup();
m_size = itotalSize;
// 备份过程中会有一些临时文件产生会占用一部分空间故我们预留500M的空间
itotalSize += 5 * MB;
// 2、计算备份分区剩余空间大小
QString backupPath(Utils::getSysRootPath() + BACKUP_PATH);
backupPath.replace("//", "/");
QStorageInfo backupDisk(backupPath);
qint64 freeSize = backupDisk.bytesFree();
// 3、校验空间是否足够
bool result = true;
if (itotalSize > freeSize) {
emit checkResult(int(BackupResult::BACKUP_CAPACITY_IS_NOT_ENOUGH));
result = false;
} else {
emit checkResult(int(BackupResult::CHECK_ENV_SUCCESS));
}
qDebug() << "DataBackupProxy::checkFreeCapacity invoke end";
return result;
}
/**
* @brief
* @return ,
*/
qint64 DataBackupProxy::calcSizeForBackup()
{
QString destPath = Utils::getSysRootPath();
QStringList args;
if (m_backupWrapper.m_bIncrement) {
// 在原来的备份点上增量备份场景
args = getRsyncArgs(DataBackupScene::TRY_INC_DATA_BACKUP);
destPath += BACKUP_SNAPSHOTS_PATH;
destPath += "/";
destPath += m_backupWrapper.m_uuid;
destPath += "/data/";
} else {
// 全量备份场景
args = getRsyncArgs(DataBackupScene::TRY_DATA_BACKUP);
destPath += CHECK_PATH;
}
// 拼接备份源路径和目标路径
QString srcPath = Utils::getSysRootPath();
srcPath += "/";
srcPath.replace("//", "/");
args << srcPath;
destPath.replace("//", "/");
args << destPath;
Utils::mkpath(destPath);
CalcBackupSize calcator;
return calcator.start(args);
}
/**
* @brief rsync命令参数
* @param scene
* @return rsync的参数信息
*/
QStringList DataBackupProxy::getRsyncArgs(DataBackupScene scene)
{
QStringList args;
QString backupFile = "/tmp/.backup.user";
Utils::writeFileByLines(backupFile, m_backupWrapper.m_backupPaths);
switch (scene) {
case DataBackupScene::DATA_BACKUP :
args << "-avAHXr";
args << "--info=progress2";
args << "--no-inc-recursive";
args << "--ignore-missing-args";
args << "--delete";
args << "--files-from" << backupFile;
break ;
case DataBackupScene::INC_DATA_BACKUP :
args << "-avAHXr";
args << "--info=progress2";
args << "--no-inc-recursive";
args << "--ignore-missing-args";
args << "--delete";
args << "--files-from" << backupFile;
break ;
case DataBackupScene::TRY_DATA_BACKUP :
args << "-aAHXrn";
args << "--stats";
args << "--ignore-missing-args";
args << "--files-from" << backupFile;
break ;
case DataBackupScene::TRY_INC_DATA_BACKUP :
args << "-aAHXrn";
args << "--stats";
args << "--ignore-missing-args";
args << "--delete";
args << "--files-from" << backupFile;
break ;
default:
return args;
}
return args;
}
/**
* @brief
*/
void DataBackupProxy::doBackup()
{
qDebug() << "DataBackupProxy::doBackup invoke begin";
// 准备
if (!doPrepare())
return ;
// 启动数据备份
backupData();
qDebug() << "DataBackupProxy::doBackup invoke end";
}
/**
* @brief
* @return true,false
*/
bool DataBackupProxy::doPrepare()
{
qDebug() << "DataBackupProxy::doPrepare invoke begin";
m_bSuccess = false;
// 1、设置当前备份的Uuid
if (m_backupWrapper.m_uuid.isEmpty()) {
// 新增备份点不指定uuid的场景
m_curUuid += Utils::createUuid();
} else {
// 指定uuid备份的场景
m_curUuid = m_backupWrapper.m_uuid;
}
// 2、准备备份目录及文件
m_destPath = Utils::getSysRootPath() + 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;
}
m_userFile = Utils::getSysRootPath() + BACKUP_SNAPSHOTS_PATH + "/" + m_curUuid + "/" + PATHS_USER_FILE;
m_userFile.replace("//", "/");
if (!Utils::writeFileByLines(m_userFile, m_backupWrapper.m_backupPaths)) {
emit checkResult(int(BackupResult::WRITE_BACKUP_PATHS_TO_USER_FAILED));
qCritical() << QString("create file %1 failed !").arg(m_userFile) ;
return false;
}
m_excludeUserFile = Utils::getSysRootPath() + BACKUP_SNAPSHOTS_PATH + "/" + m_curUuid + "/" + EXCLUDE_PATHS_USER_FILE;
m_excludeUserFile.replace("//", "/");
if (!Utils::writeFileByLines(m_excludeUserFile, m_backupWrapper.m_backupExcludePaths)) {
emit checkResult(int(BackupResult::WRITE_BACKUP_PATHS_TO_USER_FAILED));
qCritical() << QString("create file %1 failed !").arg(m_excludeUserFile) ;
return false;
}
// 3、记录/backup/snapshots/backuplist.xml文件
if (!recordBackupPoint()) {
qCritical() << "add or update item to backuplist.xml failed !";
return false;
}
qDebug() << "DataBackupProxy::doPrepare invoke end";
return true;
}
/**
* @brief /backup/snapshots/backuplist.xml文件
* @return true-false-
*/
bool DataBackupProxy::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 = Utils::getSysRootPath() + BACKUP_XML_PATH;
xmlPath.replace("//", "/");
ParseBackupList parse(xmlPath);
if (m_backupWrapper.m_bIncrement) {
if (parse.updateItem(m_backupPoint) != ParseBackupList::SUCCESS) {
emit checkResult(int(BackupResult::WRITE_STORAGEINFO_UPDATE_ITEM_FAIL));
return false;
}
} else {
if (parse.addItem(m_backupPoint) != ParseBackupList::SUCCESS) {
emit checkResult(int(BackupResult::WRITE_STORAGEINFO_ADD_ITEM_FAIL));
return false;
}
}
return true;
}
/**
* @brief
* @return truefalse
*/
bool DataBackupProxy::backupData()
{
qDebug() << "DataBackupProxy::backupData invoke begin";
QStringList args;
if (m_backupWrapper.m_bIncrement) {
// 在原来的备份点上增量备份场景
args = getRsyncArgs(DataBackupScene::INC_DATA_BACKUP);
} else {
// 全量备份场景
args = getRsyncArgs(DataBackupScene::DATA_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, &DataBackupProxy::progress);
connect(m_p, &RsyncPathToDirProcess::finished, this, [&](bool result) {
if (result) {
m_backupPoint.m_state = BACKUP_PARSE_STATE_SUCCESS_STRTING;
m_backupPoint.m_size = Utils::StringBySize(Utils::getDirOrFileSize(m_destPath));
QString xmlPath = Utils::getSysRootPath() + BACKUP_XML_PATH;
xmlPath.replace("//", "/");
ParseBackupList parse(xmlPath);
parse.updateItem(m_backupPoint);
// Utils::writeBackupLog(time + "," + m_curUuid + "," + QString::number(m_backupWrapper.m_type) + ","+ m_backupWrapper.m_note + "," + m_backupPoint.m_size+ "," + QString::number(m_backupWrapper.m_frontUid));
Utils::writeBackupLog(m_backupPoint.m_time + ","
+ m_curUuid + "," + QString::number(m_backupWrapper.m_type) + ","
+ m_backupWrapper.m_note + "," + m_backupPoint.m_size
+ "," + QString::number(m_backupWrapper.m_frontUid));
Utils::update_backup_unique_settings(m_curUuid, m_backupPoint.m_backupName);
m_bSuccess = true;
}
emit this->workResult(result);
});
m_p->start(args, false);
do_kylin_security(m_destPath);
qDebug() << "DataBackupProxy::backupData invoke end";
return true;
}
void DataBackupProxy::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();
}
}

View File

@ -0,0 +1,87 @@
#ifndef DATABACKUPPROXY_H
#define DATABACKUPPROXY_H
#include "workerfactory.h"
#include "myprocess/rsyncpathtodirprocess.h"
#include "parsebackuplist.h"
class DataBackupProxy : public Worker
{
Q_OBJECT
DECLARE_DYNCREATE(DataBackupProxy)
public:
// 系统备份的几种场景
enum DataBackupScene {
DATA_BACKUP, // 系统备份
INC_DATA_BACKUP, // 增量系统备份
TRY_DATA_BACKUP, // 测试系统备份,可用于计算备份传输数据大小
TRY_INC_DATA_BACKUP, // 测试增量系统备份,可用于计算备份传输数据大小
};
explicit DataBackupProxy();
virtual ~DataBackupProxy();
public:
// 环境检测
virtual bool checkEnvEx();
// 任务处理
virtual void doWorkEx();
// 任务取消
virtual void cancelEx();
private:
// 校验剩余空间是否满足备份
bool checkFreeCapacity();
// 计算备份所需空间大小
qint64 calcSizeForBackup();
/**
* @brief /backup/snapshots/backuplist.xml文件
* @return true-false-
*/
bool recordBackupPoint();
// 备份准备
bool doPrepare();
// 备份
void doBackup();
// 备份系统
bool backupData();
protected:
// 判断是否增量备份
bool isIncBackup();
/**
* @brief rsync命令参数
* @param scene
* @return rsync的参数信息
*/
QStringList getRsyncArgs(DataBackupScene scene);
void do_kylin_security(const QString& dstDir);
// 是否完成
bool m_bSuccess;
// 当前备份uuid
QString m_curUuid;
// 当前备份目标目录
QString m_destPath;
// 当前备份所需空间大小
qint64 m_size;
// 备份点用户备份路径文件
QString m_userFile;
// 备份点排除备份路径文件
QString m_excludeUserFile;
// 备份进程
RsyncPathToDirProcess *m_p;
// 当前备份节点
ParseBackupList::BackupPoint m_backupPoint;
};
#endif // DATABACKUPPROXY_H

View File

@ -53,12 +53,12 @@ bool MountBackupProcess::umountBackupPartition()
arguments << QString("/backup"); arguments << QString("/backup");
m_p->start("umount", arguments); m_p->start("umount", arguments);
if (!m_p->waitForStarted()) { if (!m_p->waitForStarted()) {
qCritical("mount ro backup process start failed!"); qCritical("umount /backup process start failed!");
return false; return false;
} }
if (!m_p->waitForFinished()) { if (!m_p->waitForFinished()) {
qCritical("mount ro backup process end failed!"); qCritical("umount /backup process end failed!");
return false; return false;
} }

View File

@ -296,6 +296,8 @@ void ParseBackupList::elementNodeToBackupPoint(const QDomElement& node, BackupPo
QDomElement eleComment = node.firstChildElement(COMMENT); QDomElement eleComment = node.firstChildElement(COMMENT);
if (!eleComment.isNull()) if (!eleComment.isNull())
backupPoint.m_backupName = eleComment.text(); backupPoint.m_backupName = eleComment.text();
if (backupPoint.m_uuid == FACTORY_BACKUP_UUID)
backupPoint.m_backupName = QObject::tr("factory backup");
QDomElement eleTime = node.firstChildElement(TIME); QDomElement eleTime = node.firstChildElement(TIME);
if (!eleTime.isNull()) if (!eleTime.isNull())

View File

@ -184,6 +184,7 @@ QStringList SystemBackupProxy::getRsyncArgs(SystemBackupScene scene)
args << "--info=progress2"; args << "--info=progress2";
args << "--no-inc-recursive"; args << "--no-inc-recursive";
args << "--ignore-missing-args"; args << "--ignore-missing-args";
args << "--delete";
break ; break ;
case SystemBackupScene::INC_SYSTEM_BACKUP : case SystemBackupScene::INC_SYSTEM_BACKUP :
args << "-avAXr"; args << "-avAXr";

View File

@ -0,0 +1,357 @@
#include "udiskdatabackupproxy.h"
#include <QStorageInfo>
#include <QDateTime>
#include <QDebug>
#include <QTimer>
#include <kysec/status.h>
#include "../common/utils.h"
#include "../common/mydusizetool.h"
#include "mymountproxy.h"
#include "myprocess/calcbackupsize.h"
IMPLEMENT_DYNCREATE(UDiskDataBackupProxy)
UDiskDataBackupProxy::UDiskDataBackupProxy()
{
m_isFinished = false;
m_bSuccess = false;
m_p = nullptr;
m_size = 0;
m_calc = new CalcBackupSize(this);
m_isOnlyCheck = true;
}
UDiskDataBackupProxy::~UDiskDataBackupProxy()
{
delete m_p;
m_p = nullptr;
delete m_calc;
m_calc = nullptr;
}
/**
* @brief
* @return false,;true,
*/
bool UDiskDataBackupProxy::checkEnvEx()
{
qDebug() << "UDiskDataBackupProxy::checkEnv invoke begin";
// 1、检查/backup分区是否挂载上(不管是本地磁盘还是u盘设备都得保证/backup挂载上); 若没挂载,挂载
MyMountProxy mountProxy;
if ( MountResult::MOUNTED != mountProxy.mountBackupPartition() ) {
emit checkResult(int(BackupResult::BACKUP_PARTITION_MOUNT_FAIL));
return false;
}
QString backupPath(m_backupWrapper.m_prefixDestPath);
backupPath.replace("//", "/");
QStorageInfo udisk(backupPath);
QString udisk_type = udisk.fileSystemType();
if (udisk_type == "vfat") {
qCritical() << m_backupWrapper.m_prefixDestPath + " udisk's filesystemtype is vfat";
emit checkResult(int(BackupResult::UDISK_FILESYSTEM_TYPE_IS_VFAT));
return false;
}
if (udisk.isReadOnly()) {
// 只读挂载的U盘
qCritical() << QString("udisk(%s) is readonly filesystem").arg(m_backupWrapper.m_prefixDestPath);
emit checkResult(int(BackupResult::UDISK_FILESYSTEM_IS_READONLY));
return false;
}
QTimer::singleShot(1*1000, this, &UDiskDataBackupProxy::checkDestDirExists);
// 2、判断备份是否增量备份
isIncBackup();
// 3、检测空间是否满足备份
calcSizeForBackupToUdisk();
qDebug() << "UDiskDataBackupProxy::checkEnv invoke end";
return true;
}
/**
* @brief
*/
void UDiskDataBackupProxy::doWorkEx()
{
qDebug() << "UDiskDataBackupProxy::doWorkEx invoke begin";
m_isOnlyCheck = false;
// 环境检测
checkEnvEx();
qDebug() << "UDiskDataBackupProxy::doWorkEx invoke end";
}
void UDiskDataBackupProxy::cancelEx()
{}
/**
* @brief
*/
bool UDiskDataBackupProxy::checkFreeCapacityToUdisk(qint64 itotalSize)
{
qDebug() << "UDiskDataBackupProxy::checkFreeCapacityToUdisk invoke begin";
// 1、计算待备份数据的大小
m_size = itotalSize;
// 备份过程中会有一些临时文件产生会占用一部分空间故我们预留500M的空间
itotalSize += 5 * MB;
// 2、计算备份分区剩余空间大小
QString backupPath(m_backupWrapper.m_prefixDestPath);
backupPath.replace("//", "/");
QStorageInfo backupDisk(backupPath);
qint64 freeSize = backupDisk.bytesFree();
// 3、校验空间是否足够
bool result = true;
if (itotalSize > freeSize) {
emit checkResult(int(BackupResult::BACKUP_CAPACITY_IS_NOT_ENOUGH));
result = false;
} else {
emit checkResult(int(BackupResult::CHECK_ENV_SUCCESS));
}
if (m_isOnlyCheck)
return result;
// 开始备份
doBackupToUdisk();
qDebug() << "UDiskDataBackupProxy::checkFreeCapacityToUdisk invoke end";
return result;
}
/**
* @brief
* @return ,
*/
void UDiskDataBackupProxy::calcSizeForBackupToUdisk()
{
QString destPath;
QStringList args;
if (m_backupWrapper.m_bIncrement) {
// 在原来的备份点上增量备份场景
args = getRsyncArgs(DataBackupScene::TRY_INC_DATA_BACKUP);
destPath = m_backupWrapper.m_prefixDestPath;
destPath += BACKUP_SNAPSHOTS_PATH;
destPath += "/";
destPath += m_backupWrapper.m_uuid;
destPath += "/data/";
} else {
// 全量备份场景
args = getRsyncArgs(DataBackupScene::TRY_DATA_BACKUP);
destPath = Utils::getSysRootPath();
destPath += CHECK_PATH;
}
// 拼接备份源路径和目标路径
QString srcPath = Utils::getSysRootPath();
srcPath += "/";
srcPath.replace("//", "/");
args << srcPath;
destPath.replace("//", "/");
args << destPath;
Utils::mkpath(destPath);
connect(m_calc, &CalcBackupSize::finished, this, &UDiskDataBackupProxy::checkFreeCapacityToUdisk);
m_calc->start(args, false);
}
/**
* @brief
*/
void UDiskDataBackupProxy::doBackupToUdisk()
{
qDebug() << "UDiskDataBackupProxy::doBackupToUdisk invoke begin";
// 准备
if (!doPrepareToUdisk())
return ;
// 启动数据备份
backupDataToUdisk();
qDebug() << "UDiskDataBackupProxy::doBackupToUdisk invoke end";
}
/**
* @brief
* @return true,false
*/
bool UDiskDataBackupProxy::doPrepareToUdisk()
{
qDebug() << "UDiskDataBackupProxy::doPrepareToUdisk invoke begin";
m_bSuccess = false;
// 1、设置当前备份的Uuid
if (m_backupWrapper.m_uuid.isEmpty()) {
// 新增备份点不指定uuid的场景
m_curUuid += Utils::createUuid();
} else {
// 指定uuid备份的场景
m_curUuid = m_backupWrapper.m_uuid;
}
// 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;
}
m_userFile = m_backupWrapper.m_prefixDestPath + BACKUP_SNAPSHOTS_PATH + "/" + m_curUuid + "/" + PATHS_USER_FILE;
m_userFile.replace("//", "/");
if (!Utils::writeFileByLines(m_userFile, m_backupWrapper.m_backupPaths)) {
emit checkResult(int(BackupResult::WRITE_BACKUP_PATHS_TO_USER_FAILED));
qCritical() << QString("create file %1 failed !").arg(m_userFile) ;
return false;
}
m_excludeUserFile = m_backupWrapper.m_prefixDestPath + BACKUP_SNAPSHOTS_PATH + "/" + m_curUuid + "/" + EXCLUDE_PATHS_USER_FILE;
m_excludeUserFile.replace("//", "/");
if (!Utils::writeFileByLines(m_excludeUserFile, m_backupWrapper.m_backupExcludePaths)) {
emit checkResult(int(BackupResult::WRITE_BACKUP_PATHS_TO_USER_FAILED));
qCritical() << QString("create file %1 failed !").arg(m_excludeUserFile) ;
return false;
}
// 3、记录/backup/snapshots/backuplist.xml文件
if (!recordBackupPointToUdisk()) {
qCritical() << "add or update item to backuplist.xml failed !";
return false;
}
qDebug() << "UDiskDataBackupProxy::doPrepareToUdisk invoke end";
return true;
}
/**
* @brief /backup/snapshots/backuplist.xml文件
* @return true-false-
*/
bool UDiskDataBackupProxy::recordBackupPointToUdisk()
{
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_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 truefalse
*/
bool UDiskDataBackupProxy::backupDataToUdisk()
{
qDebug() << "UDiskDataBackupProxy::backupDataToUdisk invoke begin";
QStringList args;
if (m_backupWrapper.m_bIncrement) {
// 在原来的备份点上增量备份场景
args = getRsyncArgs(DataBackupScene::INC_DATA_BACKUP);
} else {
// 全量备份场景
args = getRsyncArgs(DataBackupScene::DATA_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, &UDiskDataBackupProxy::progress);
connect(m_p, &RsyncPathToDirProcess::finished, this, [&](bool result) {
m_isFinished = true;
if (result) {
m_backupPoint.m_state = BACKUP_PARSE_STATE_SUCCESS_STRTING;
m_backupPoint.m_size = Utils::StringBySize(Utils::getDirOrFileSize(m_destPath));
QString xmlPath = m_backupWrapper.m_prefixDestPath + BACKUP_XML_PATH;
xmlPath.replace("//", "/");
ParseBackupList parse(xmlPath);
if (ParseBackupList::ParseResult::SUCCESS != parse.updateItem(m_backupPoint)) {
qCritical() << "update backuplist.xml error in sendBackupResult";
result = false;
} else {
// Utils::writeBackupLog(time + "," + m_curUuid + "," + QString::number(m_backupWrapper.m_type) + ","+ m_backupWrapper.m_note + "," + m_backupPoint.m_size+ "," + QString::number(m_backupWrapper.m_frontUid));
Utils::writeBackupLog(m_backupPoint.m_time + ","
+ m_curUuid + "," + QString::number(m_backupWrapper.m_type) + ","
+ m_backupWrapper.m_note + "," + m_backupPoint.m_size
+ "," + QString::number(m_backupWrapper.m_frontUid));
Utils::update_backup_unique_settings(m_curUuid, m_backupPoint.m_backupName);
m_bSuccess = true;
}
}
emit this->workResult(result);
});
m_p->start(args, false);
do_kylin_security(m_destPath);
qDebug() << "UDiskDataBackupProxy::backupDataToUdisk invoke end";
return true;
}
/**
* @brief
* @return: bool,truefalse
* @author: zhaominyong
* @since: 2021/05/24
* @note:
* add by zhaominyong at 2021/05/24 for bug:54377 U盘的过程中拔出U盘
*/
bool UDiskDataBackupProxy::checkDestDirExists()
{
QDir dir(m_backupWrapper.m_prefixDestPath);
if (!dir.exists()) {
qCritical() << QString("dstDir %s is not exist!").arg(m_backupWrapper.m_prefixDestPath);
if (m_p)
m_p->stop();
return false;
}
if (!m_isFinished)
{
QTimer::singleShot(1*1000, this, &UDiskDataBackupProxy::checkDestDirExists);
}
return true;
}

View File

@ -0,0 +1,66 @@
#ifndef UDISKDATABACKUPPROXY_H
#define UDISKDATABACKUPPROXY_H
#include "databackupproxy.h"
#include "myprocess/calcbackupsize.h"
class UDiskDataBackupProxy : public DataBackupProxy
{
Q_OBJECT
DECLARE_DYNCREATE(UDiskDataBackupProxy)
public:
explicit UDiskDataBackupProxy();
virtual ~UDiskDataBackupProxy();
public:
// 环境检测
virtual bool checkEnvEx();
// 任务处理
virtual void doWorkEx();
// 任务取消
virtual void cancelEx();
private slots:
// 校验剩余空间是否满足备份
bool checkFreeCapacityToUdisk(qint64 itotalSize);
// 备份
void doBackupToUdisk();
/**
* @brief
* @return: bool,truefalse
* @author: zhaominyong
* @since: 2021/05/24
* @note:
* add by zhaominyong at 2021/05/24 for bug:54377 U盘的过程中拔出U盘
*/
bool checkDestDirExists();
private:
// 计算备份所需空间大小
void calcSizeForBackupToUdisk();
/**
* @brief /backup/snapshots/backuplist.xml文件
* @return true-false-
*/
bool recordBackupPointToUdisk();
// 备份准备
bool doPrepareToUdisk();
// 备份系统
bool backupDataToUdisk();
// 计算备份空间大小的进程
CalcBackupSize *m_calc;
// 是否只是检测
bool m_isOnlyCheck;
// 是否完成
bool m_isFinished;
};
#endif // UDISKDATABACKUPPROXY_H

View File

@ -15,6 +15,7 @@ IMPLEMENT_DYNCREATE(UDiskSystemBackupProxy)
UDiskSystemBackupProxy::UDiskSystemBackupProxy() UDiskSystemBackupProxy::UDiskSystemBackupProxy()
{ {
m_bSuccess = false; m_bSuccess = false;
m_isFinished = false;
m_p = nullptr; m_p = nullptr;
m_size = 0; m_size = 0;
m_calc = new CalcBackupSize(this); m_calc = new CalcBackupSize(this);
@ -455,14 +456,17 @@ bool UDiskSystemBackupProxy::backup(const QStringList &args)
m_p = new RsyncPathToDirProcess(this); m_p = new RsyncPathToDirProcess(this);
connect(m_p, &RsyncPathToDirProcess::progress, this, &UDiskSystemBackupProxy::progress); connect(m_p, &RsyncPathToDirProcess::progress, this, &UDiskSystemBackupProxy::progress);
connect(m_p, &RsyncPathToDirProcess::finished, this, [&](bool result) { connect(m_p, &RsyncPathToDirProcess::finished, this, [&](bool result) {
m_isFinished = true;
if (result) { if (result) {
m_backupPoint.m_state = BACKUP_PARSE_STATE_SUCCESS_STRTING; m_backupPoint.m_state = BACKUP_PARSE_STATE_SUCCESS_STRTING;
m_backupPoint.m_size = Utils::StringBySize(Utils::getDirOrFileSize(m_destPath)); m_backupPoint.m_size = Utils::StringBySize(Utils::getDirOrFileSize(m_destPath));
QString xmlPath = m_backupWrapper.m_prefixDestPath + BACKUP_XML_PATH; QString xmlPath = m_backupWrapper.m_prefixDestPath + BACKUP_XML_PATH;
xmlPath.replace("//", "/"); xmlPath.replace("//", "/");
ParseBackupList parse(xmlPath); ParseBackupList parse(xmlPath);
parse.updateItem(m_backupPoint); if (ParseBackupList::ParseResult::SUCCESS != parse.updateItem(m_backupPoint)) {
qCritical() << "update backuplist.xml error in sendBackupResult";
result = false;
} else {
// Utils::writeBackupLog(time + "," + m_curUuid + "," + QString::number(m_backupWrapper.m_type) + ","+ m_backupWrapper.m_note + "," + m_backupPoint.m_size+ "," + QString::number(m_backupWrapper.m_frontUid)); // Utils::writeBackupLog(time + "," + m_curUuid + "," + QString::number(m_backupWrapper.m_type) + ","+ m_backupWrapper.m_note + "," + m_backupPoint.m_size+ "," + QString::number(m_backupWrapper.m_frontUid));
Utils::writeBackupLog(m_backupPoint.m_time + "," Utils::writeBackupLog(m_backupPoint.m_time + ","
+ m_curUuid + "," + QString::number(m_backupWrapper.m_type) + "," + m_curUuid + "," + QString::number(m_backupWrapper.m_type) + ","
@ -471,6 +475,7 @@ bool UDiskSystemBackupProxy::backup(const QStringList &args)
Utils::update_backup_unique_settings(m_curUuid, m_backupPoint.m_backupName); Utils::update_backup_unique_settings(m_curUuid, m_backupPoint.m_backupName);
m_bSuccess = true; m_bSuccess = true;
} }
}
emit this->workResult(result); emit this->workResult(result);
}); });
m_p->start(args, false); m_p->start(args, false);
@ -518,7 +523,7 @@ bool UDiskSystemBackupProxy::checkDestDirExists()
return false; return false;
} }
if (!m_bSuccess) if (!m_isFinished)
{ {
QTimer::singleShot(1*1000, this, &UDiskSystemBackupProxy::checkDestDirExists); QTimer::singleShot(1*1000, this, &UDiskSystemBackupProxy::checkDestDirExists);
} }

View File

@ -46,6 +46,16 @@ private slots:
// 备份 // 备份
void doBackup(); void doBackup();
/**
* @brief
* @return: bool,truefalse
* @author: zhaominyong
* @since: 2021/05/24
* @note:
* add by zhaominyong at 2021/05/24 for bug:54377 U盘的过程中拔出U盘
*/
bool checkDestDirExists();
private: private:
// 判断是否增量备份 // 判断是否增量备份
bool isIncBackup(); bool isIncBackup();
@ -79,21 +89,13 @@ private:
void do_kylin_security(const QString& dstDir); void do_kylin_security(const QString& dstDir);
/**
* @brief
* @return: bool,truefalse
* @author: zhaominyong
* @since: 2021/05/24
* @note:
* add by zhaominyong at 2021/05/24 for bug:54377 U盘的过程中拔出U盘
*/
bool checkDestDirExists();
// 计算备份空间大小的进程 // 计算备份空间大小的进程
CalcBackupSize *m_calc; CalcBackupSize *m_calc;
// 压缩进程 // 压缩进程
MkSquashFSProcess *m_mksquashfs; MkSquashFSProcess *m_mksquashfs;
// 是否完成
bool m_isFinished;
// 是否备份成功 // 是否备份成功
bool m_bSuccess; bool m_bSuccess;
// 当前备份uuid // 当前备份uuid

View File

@ -32,6 +32,7 @@ public:
QList<ParseBackupList::BackupPoint> getBackupPointList(); QList<ParseBackupList::BackupPoint> getBackupPointList();
void setIsOnlyShowLocal(bool onlyShowLocal) { m_onlyShowLocal = onlyShowLocal; }
bool isOnlyShowLocal() const { return m_onlyShowLocal; } bool isOnlyShowLocal() const { return m_onlyShowLocal; }
signals: signals:

View File

@ -0,0 +1,168 @@
#include "backuplistwidget.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QPushButton>
#include <QMimeData>
#include <QFileInfo>
#include "mylabel.h"
#include "../messageboxutils.h"
BackupListWidget::BackupListWidget(QWidget *parent /*= nullptr*/) :
QListWidget(parent)
{
setSortingEnabled(false);
setAcceptDrops(true);
// 列表为空时,展示一个“+”号图标和拖拽文件提示
m_plusLogo = new MyIconLabel;
m_plusLogo->setFixedHeight(36);
m_plusLogo->setThemeIcon("list-add-symbolic", ":/symbos/list-add-symbolic.png");
m_plusLogo->setDesplayText(tr("File drag and drop area"));
m_plusLogo->setEnabled(false);
QHBoxLayout *hlayout = new QHBoxLayout;
hlayout->addStretch();
hlayout->addWidget(m_plusLogo);
hlayout->addStretch();
QVBoxLayout *vlayout = new QVBoxLayout;
vlayout->addStretch();
vlayout->addLayout(hlayout);
vlayout->addStretch();
setLayout(vlayout);
}
BackupListWidget::~BackupListWidget()
{}
int BackupListWidget::findIndexOfItem(QListWidgetItem *item)
{
int index = -1;
for (int row = 0; row < this->count(); ++row) {
if (item == this->item(row)) {
index = row;
break;
}
}
return index;
}
bool BackupListWidget::contains(const QString& text)
{
// 1、针对使用addItem等的正规使用场景展示内容在原生item上
if (findItems(text, Qt::MatchCaseSensitive).size() > 0)
return true;
// 2、针对使用setItemWidget添加项展示内容在widget上的特殊使用场景
return m_List.contains(text);
}
bool BackupListWidget::appendItem(const QString &text)
{
if (!checkPathLimit(text))
return false;
int count = this->count();
if (count > 0)
++count;
int width = this->width();
QListWidgetItem *item = new QListWidgetItem(this, m_type);
item->setSizeHint(QSize(width - 10, 36));
QWidget *widget = new QWidget;
QHBoxLayout *hlayout = new QHBoxLayout;
MyLabel *label = new MyLabel;
label->setDeplayText(text);
label->setToolTip(text);
label->setFixedSize(width - 50, 36);
label->setAlignment(Qt::AlignTop);
hlayout->addWidget(label);
m_List << text;
QPushButton *buttonDelete = new QPushButton;
buttonDelete->setProperty("isWindowButton", 0x2);
buttonDelete->setProperty("useIconHighlightEffect", 0x8);
buttonDelete->setFlat(true);
buttonDelete->setFixedSize(20, 20);
buttonDelete->setIcon(QIcon::fromTheme("window-close-symbolic"));
hlayout->addWidget(buttonDelete);
widget->setLayout(hlayout);
this->setItemWidget(item, widget);
this->setCurrentItem(item);
connect(buttonDelete, &QPushButton::clicked, [=]() {
this->m_List.removeOne(label->text());
this->takeItem(this->findIndexOfItem(item));
delete item;
if (this->count() == 0)
m_plusLogo->setVisible(true);
});
m_plusLogo->setVisible(false);
return true;
}
void BackupListWidget::dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasUrls()) {
for (QUrl url : event->mimeData()->urls()) {
QString file = url.toString();
if (file.startsWith("file://")) {
file.replace("file://", "");
appendItem(file);
}
}
}
}
bool BackupListWidget::checkPathLimit(const QString &path)
{
// 1、列表中是否已经存在
if (contains(path)) {
MessageBoxUtils::QMESSAGE_BOX_WARNING(this, QObject::tr("Warning"),
QObject::tr("Path already exists : ") + path,
QObject::tr("Ok"));
return false;
}
// 2、路径是否存在
QFileInfo fileInfo(path);
if (!fileInfo.exists()) {
MessageBoxUtils::QMESSAGE_BOX_WARNING(this, QObject::tr("Warning"),
QObject::tr("The file or directory does not exist : ") + path,
QObject::tr("Ok"));
return false;
}
// 3、是否是限定路径及其子路径
bool blimit = false;
QString dirCanBeSelected;
for (const QString &item : m_pathLimit) {
if (path.startsWith(item)) {
blimit = true;
break;
}
if (dirCanBeSelected.isEmpty())
dirCanBeSelected = item;
else {
dirCanBeSelected += ",";
dirCanBeSelected += item;
}
}
if (m_pathLimit.size() > 0 && !blimit) {
MessageBoxUtils::QMESSAGE_BOX_WARNING(this, QObject::tr("Warning"),
QObject::tr("Only data that exists in the follow directorys can be selected: ") + dirCanBeSelected,
QObject::tr("Ok"));
return false;
}
return true;
}

View File

@ -0,0 +1,50 @@
#ifndef REMOVABLELISTWIDGET_H
#define REMOVABLELISTWIDGET_H
#include <QListWidget>
#include <QStringList>
#include <QDropEvent>
#include "myiconlabel.h"
class BackupListWidget : public QListWidget
{
Q_OBJECT
public:
explicit BackupListWidget(QWidget *parent = nullptr);
virtual ~BackupListWidget();
// 添加列表项注意使用本类的功能不能用addItem等基类添加项的方法
bool appendItem(const QString &text);
// 根据QListWidgetItem*查找项对应的索引序号
int findIndexOfItem(QListWidgetItem *item);
// 判断列表项是否包含text注意使用时不能用findItems等基类查找方法
bool contains(const QString &text);
// 获取备份路径列表
QStringList getBackupPaths() { return m_List; }
// 设置备份路径限制为只能是pathLimit或其子路径
void setPathLimit(const QStringList &pathLimit) { m_pathLimit.append(pathLimit); }
// 清空
void clearData() {
this->clear();
m_List.clear();
}
protected:
void dropEvent(QDropEvent *e);
private:
bool checkPathLimit(const QString &path);
private:
MyIconLabel *m_plusLogo;
int m_type = QListWidgetItem::ItemType::UserType + 1;
QStringList m_List;
QStringList m_pathLimit;
};
#endif // REMOVABLELISTWIDGET_H

View File

@ -0,0 +1,25 @@
#include "myfileselect.h"
#include <QDialogButtonBox>
#include <QLineEdit>
MyFileSelect::MyFileSelect(QWidget* parent) :
QFileDialog(parent)
{
this->setViewMode(QFileDialog::List);
this->setFileMode(QFileDialog::ExistingFiles);
this->setFilter(QDir::System | QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
QDialogButtonBox* button = this->findChild<QDialogButtonBox*>("buttonBox");
disconnect(button, SIGNAL(accepted()), this, SLOT(accept()));
connect(button, SIGNAL(accepted()), this, SLOT(goAccept()));
QLineEdit *fileNameEdit = this->findChild<QLineEdit*>("fileNameEdit");
connect(this, &MyFileSelect::currentChanged, this, [=](const QString& path){
fileNameEdit->setText(path.section('/', -1));
});
}
void MyFileSelect::goAccept()
{
QDialog::accept();
}

View File

@ -0,0 +1,15 @@
#ifndef MYFILESELECT_H
#define MYFILESELECT_H
#include <QFileDialog>
class MyFileSelect : public QFileDialog {
Q_OBJECT
public:
explicit MyFileSelect(QWidget* parent = nullptr);
public slots:
void goAccept();
};
#endif // MYFILESELECT_H

View File

@ -11,6 +11,16 @@ public:
GlobelBackupInfo(token) {} GlobelBackupInfo(token) {}
~GlobelBackupInfo() {} ~GlobelBackupInfo() {}
// 设置是否管理员用户登录
void setIsManager(bool isManager) { m_isManager = isManager; }
// 是否管理员用户登录
bool isManager() { return m_isManager; }
// 设置是否以--restore参数启动的备份还原工具
void setHasArgRestore(bool hasArg_restore) { m_hasArg_restore = hasArg_restore; }
// 是否以--restore参数启动的备份还原工具
bool hasArgRestore() { return m_hasArg_restore; }
// 设置是否正在进行备份、还原等操作 // 设置是否正在进行备份、还原等操作
void setIsBusy(bool isBusy) { void setIsBusy(bool isBusy) {
std::lock_guard<spinlock_mutex> lock(m_interMutex); std::lock_guard<spinlock_mutex> lock(m_interMutex);
@ -61,12 +71,16 @@ public:
} }
private: private:
// 是否管理员
bool m_isManager = true;
// 是否正在进行备份、还原等操作 // 是否正在进行备份、还原等操作
bool m_isBusy = false; bool m_isBusy = false;
// 是否有备份分区 // 是否有备份分区
bool m_hasBackupPartition = true; bool m_hasBackupPartition = true;
// 当前功能类型 // 当前功能类型
FuncTypeConverter::FunType m_funcType = FuncTypeConverter::FunType::TOTALMODULES; FuncTypeConverter::FunType m_funcType = FuncTypeConverter::FunType::TOTALMODULES;
// 是否以--restore参数启动的备份还原工具
bool m_hasArg_restore = false;
// 全局信号对象 // 全局信号对象
GlobalSignals m_globalSignals; GlobalSignals m_globalSignals;

View File

@ -37,12 +37,14 @@ HEADERS += \
../common/utils.h \ ../common/utils.h \
backup_manager_interface.h \ backup_manager_interface.h \
backuppointlistdialog.h \ backuppointlistdialog.h \
component/backuplistwidget.h \
component/circlelabel.h \ component/circlelabel.h \
component/clicklabel.h \ component/clicklabel.h \
component/hoverwidget.h \ component/hoverwidget.h \
component/imageutil.h \ component/imageutil.h \
component/linelabel.h \ component/linelabel.h \
component/mycheckbox.h \ component/mycheckbox.h \
component/myfileselect.h \
component/myiconbutton.h \ component/myiconbutton.h \
component/myiconlabel.h \ component/myiconlabel.h \
component/mylabel.h \ component/mylabel.h \
@ -57,6 +59,7 @@ HEADERS += \
leftsiderbarwidget.h \ leftsiderbarwidget.h \
maindialog.h \ maindialog.h \
messageboxutils.h \ messageboxutils.h \
module/databackup.h \
module/managebackuppointlist.h \ module/managebackuppointlist.h \
module/selectrestorepoint.h \ module/selectrestorepoint.h \
module/systembackup.h \ module/systembackup.h \
@ -74,12 +77,14 @@ SOURCES += \
../common/utils.cpp \ ../common/utils.cpp \
backup_manager_interface.cpp \ backup_manager_interface.cpp \
backuppointlistdialog.cpp \ backuppointlistdialog.cpp \
component/backuplistwidget.cpp \
component/circlelabel.cpp \ component/circlelabel.cpp \
component/clicklabel.cpp \ component/clicklabel.cpp \
component/hoverwidget.cpp \ component/hoverwidget.cpp \
component/imageutil.cpp \ component/imageutil.cpp \
component/linelabel.cpp \ component/linelabel.cpp \
component/mycheckbox.cpp \ component/mycheckbox.cpp \
component/myfileselect.cpp \
component/myiconbutton.cpp \ component/myiconbutton.cpp \
component/myiconlabel.cpp \ component/myiconlabel.cpp \
component/mylabel.cpp \ component/mylabel.cpp \
@ -93,6 +98,7 @@ SOURCES += \
main.cpp \ main.cpp \
maindialog.cpp \ maindialog.cpp \
messageboxutils.cpp \ messageboxutils.cpp \
module/databackup.cpp \
module/managebackuppointlist.cpp \ module/managebackuppointlist.cpp \
module/selectrestorepoint.cpp \ module/selectrestorepoint.cpp \
module/systembackup.cpp \ module/systembackup.cpp \

View File

@ -14,6 +14,7 @@
#include "qtsingleapplication/qtsingleapplication.h" #include "qtsingleapplication/qtsingleapplication.h"
#include "../common/utils.h" #include "../common/utils.h"
#include "xatom-helper.h" #include "xatom-helper.h"
#include "globalbackupinfo.h"
// 声明 // 声明
void initApp(QApplication& a); void initApp(QApplication& a);
@ -35,7 +36,8 @@ int main(int argc, char *argv[])
initApp(a); initApp(a);
// 当前只支持管理员用户使用备份还原工具 // 当前只支持管理员用户使用备份还原工具
if (!isManager()) { GlobelBackupInfo::inst().setIsManager(isManager());
if (!GlobelBackupInfo::inst().isManager() && GlobelBackupInfo::inst().hasArgRestore()) {
QMessageBox box(QMessageBox::Warning, QObject::tr("Warning"), QObject::tr("This tool can only be used by administrator.")); QMessageBox box(QMessageBox::Warning, QObject::tr("Warning"), QObject::tr("This tool can only be used by administrator."));
box.setStandardButtons(QMessageBox::Ok); box.setStandardButtons(QMessageBox::Ok);
box.setButtonText(QMessageBox::Ok, QObject::tr("OK")); box.setButtonText(QMessageBox::Ok, QObject::tr("OK"));
@ -125,7 +127,6 @@ void initApp(QApplication& a)
QCoreApplication::setApplicationName(QObject::tr("kybackup")); QCoreApplication::setApplicationName(QObject::tr("kybackup"));
QCoreApplication::setApplicationVersion("4.0.14"); QCoreApplication::setApplicationVersion("4.0.14");
/*
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription("kybackup helper"); parser.setApplicationDescription("kybackup helper");
parser.addHelpOption(); parser.addHelpOption();
@ -134,8 +135,7 @@ void initApp(QApplication& a)
QCommandLineOption functionOption(QStringList() << "r" << "restore", QCoreApplication::translate("restore", "system restore")); QCommandLineOption functionOption(QStringList() << "r" << "restore", QCoreApplication::translate("restore", "system restore"));
parser.addOption(functionOption); parser.addOption(functionOption);
parser.process(a); parser.process(a);
bool isRestore = parser.isSet(functionOption); GlobelBackupInfo::inst().setHasArgRestore(parser.isSet(functionOption));
*/
QString qsAppPath = QCoreApplication::applicationDirPath(); QString qsAppPath = QCoreApplication::applicationDirPath();
Utils::initSysRootPath(qsAppPath); Utils::initSysRootPath(qsAppPath);

View File

@ -10,6 +10,7 @@
#include "../common/mydefine.h" #include "../common/mydefine.h"
#include "module/systembackup.h" #include "module/systembackup.h"
#include "module/systemrestore.h" #include "module/systemrestore.h"
#include "module/databackup.h"
#include "backup_manager_interface.h" #include "backup_manager_interface.h"
#include "globalbackupinfo.h" #include "globalbackupinfo.h"
@ -39,7 +40,10 @@ void MainDialog::initUI()
m_totalHLayout->setContentsMargins(0, 0, 0, 0); m_totalHLayout->setContentsMargins(0, 0, 0, 0);
ui->centralwidget->setLayout(m_totalHLayout); ui->centralwidget->setLayout(m_totalHLayout);
if (GlobelBackupInfo::inst().isManager())
m_leftSiderBarWidget = new LeftsiderbarWidget(ui->centralwidget); m_leftSiderBarWidget = new LeftsiderbarWidget(ui->centralwidget);
else
m_leftSiderBarWidget = new LeftsiderbarWidget(ui->centralwidget, LeftsiderbarWidget::StartMode::std_user);
m_leftSiderBarWidget->setObjectName(QString::fromUtf8("m_leftSiderBarWidget")); m_leftSiderBarWidget->setObjectName(QString::fromUtf8("m_leftSiderBarWidget"));
m_leftSiderBarWidget->setGeometry(QRect(0, 0, 200, 640)); m_leftSiderBarWidget->setGeometry(QRect(0, 0, 200, 640));
m_leftSiderBarWidget->setFixedSize(QSize(200, 640)); m_leftSiderBarWidget->setFixedSize(QSize(200, 640));
@ -55,6 +59,11 @@ void MainDialog::initUI()
m_titleWidget->setGeometry(QRect(201, 0, 760, 40)); m_titleWidget->setGeometry(QRect(201, 0, 760, 40));
m_rightVLayout->addWidget(m_titleWidget); m_rightVLayout->addWidget(m_titleWidget);
if (!GlobelBackupInfo::inst().isManager())
selected(FuncTypeConverter::FunType::BACKUP_DATA);
else if (GlobelBackupInfo::inst().hasArgRestore())
selected(FuncTypeConverter::FunType::RESTORE_SYSTEM);
else
selected(FuncTypeConverter::FunType::BACKUP_SYSTEM); selected(FuncTypeConverter::FunType::BACKUP_SYSTEM);
m_totalHLayout->addLayout(m_rightVLayout); m_totalHLayout->addLayout(m_rightVLayout);
@ -203,6 +212,10 @@ void MainDialog::selected(int func_type)
m_stackedWidget = new SystemRestore(ui->centralwidget); m_stackedWidget = new SystemRestore(ui->centralwidget);
GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::RESTORE_SYSTEM); GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::RESTORE_SYSTEM);
break; break;
case FuncTypeConverter::FunType::BACKUP_DATA:
m_stackedWidget = new DataBackup(ui->centralwidget);
GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::BACKUP_DATA);
break;
default: default:
m_stackedWidget = new SystemBackup(ui->centralwidget); m_stackedWidget = new SystemBackup(ui->centralwidget);
GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::BACKUP_SYSTEM); GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::BACKUP_SYSTEM);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,94 @@
#ifndef DATABACKUP_H
#define DATABACKUP_H
#include <QStackedWidget>
#include "udiskdetector.h"
#include "../backup_manager_interface.h"
#include "../backup-daemon/parsebackuplist.h"
#include "../component/backuplistwidget.h"
class DataBackup : public QStackedWidget
{
Q_OBJECT
public:
enum DataBackupState
{
IDEL = 0, // 空闲
CHECKING, // 环境校验中
BACKUPING // 备份中
};
enum DataBackupPage
{
HOME_PAGE, // 首页
SELECT_PATH_PAGE, // 选择备份路径页
INC_SELECT_PATH_PAGE, // 增量备份选择路径页
CHECK_ENV_PAGE, // 环境检测页
NAME_BACKUP_PAGE, // 备份命名页
BACKUP_PAGE, // 备份中页
LAST_PAGE, // 结束页
};
public:
explicit DataBackup(QWidget *parent = nullptr);
~DataBackup();
private:
void initFirstWidget();
void initSecondWidget();
void initSecondWidget_inc();
void initThirdWidget();
void initForthWidget();
void initFifthWidget();
void initLastWidget();
QList<ParseBackupList::BackupPoint> getBackupPointList();
bool isExistsBackupName(const QString & backupName);
signals:
void reset();
void initIncListWidget();
void startCheckEnv();
void checkEnvResult(bool result, const QString &errMsg = "", const QString &errTip = "");
void backupWarnning(const QString &warnning);
void checkBackupResult(bool result, const QString &errMsg = "", const QString &errTip = "");
void startBackup();
void progress(int state, int rate);
void clearBackupName();
public slots:
void on_pre_clicked(bool checked = false);
void on_next_clicked(bool checked = false);
void on_checkEnv_start();
void on_checkEnv_end(int result);
void on_backup_start();
void on_checkBackup_end(int result);
void on_backup_end(bool result);
private:
void getPathsLimit(QStringList &pathLimits, QList<QUrl> &siderUrls);
void addOldBackupPaths(BackupListWidget *listWidget);
// 是否增量备份
bool m_isIncrement;
// U盘探测
UdiskDetector* m_udector;
// U盘挂载路径列表
QStringList m_udiskPaths;
// 是否本地备份
bool m_isLocal;
// 备份路径列表
QStringList m_backupPaths;
// 数据备份状态
int m_DataBackupState;
// 增量备份选择的备份点uuid
QString m_uuid;
// 选中的备份目标路径前缀暂指udisk挂载路径
QString m_prefixDestPath;
// dbus接口
ComKylinBackupManagerInterface *m_pInterface;
// 备份点名称
QString m_backupName;
};
#endif // DATABACKUP_H

View File

@ -120,8 +120,8 @@ void ManageBackupPointList::insertLines(const QList<ParseBackupList::BackupPoint
QString prefixPath_to_device; QString prefixPath_to_device;
if (backupPoint.m_path.startsWith(preDevPath)) { if (backupPoint.m_path.startsWith(preDevPath)) {
QStringList ql = backupPoint.m_path.split("/"); QStorageInfo storage(backupPoint.m_path);
QString udiskName = ql.last(); QString udiskName = storage.displayName();
prefixPath_to_device = QObject::tr("Udisk Device:") + " " + udiskName; prefixPath_to_device = QObject::tr("Udisk Device:") + " " + udiskName;
} else { } else {
prefixPath_to_device = QObject::tr("Local Disk"); prefixPath_to_device = QObject::tr("Local Disk");

View File

@ -26,6 +26,7 @@ SelectRestorePoint::SelectRestorePoint(QWidget *parent, BackupPointType backupTy
// 确定按钮 // 确定按钮
MyPushButton * buttonOk = new MyPushButton; MyPushButton * buttonOk = new MyPushButton;
buttonOk->setText(tr("Ok")); buttonOk->setText(tr("Ok"));
this->setResult(QDialog::Rejected);
m_bottomLayout->addStretch(); m_bottomLayout->addStretch();
m_bottomLayout->addWidget(buttonRefresh); m_bottomLayout->addWidget(buttonRefresh);
@ -40,6 +41,7 @@ SelectRestorePoint::SelectRestorePoint(QWidget *parent, BackupPointType backupTy
QList<QTableWidgetItem *> selectList = this->m_tableWidget->selectedItems(); QList<QTableWidgetItem *> selectList = this->m_tableWidget->selectedItems();
if (selectList.isEmpty()) { if (selectList.isEmpty()) {
MessageBoxUtils::QMESSAGE_BOX_WARNING(this, QObject::tr("Warning"), QObject::tr("Please select one backup to continue."), QObject::tr("Ok")); MessageBoxUtils::QMESSAGE_BOX_WARNING(this, QObject::tr("Warning"), QObject::tr("Please select one backup to continue."), QObject::tr("Ok"));
this->reject();
return; return;
} }
@ -55,8 +57,8 @@ SelectRestorePoint::SelectRestorePoint(QWidget *parent, BackupPointType backupTy
if (dev.startsWith(tr("Udisk Device:"))) if (dev.startsWith(tr("Udisk Device:")))
backupPoint.m_iPosition = BackupPosition::OTHER; backupPoint.m_iPosition = BackupPosition::OTHER;
emit selected(backupPoint); emit this->selected(backupPoint);
this->close(); this->accept();
} }
}); });
} }
@ -134,8 +136,8 @@ void SelectRestorePoint::insertLines(const QList<ParseBackupList::BackupPoint> &
QString prefixPath_to_device; QString prefixPath_to_device;
if (backupPoint.m_path.startsWith(preDevPath)) { if (backupPoint.m_path.startsWith(preDevPath)) {
QStringList ql = backupPoint.m_path.split("/"); QStorageInfo storage(backupPoint.m_path);
QString udiskName = ql.last(); QString udiskName = storage.displayName();
if (isOther) if (isOther)
prefixPath_to_device = QObject::tr("Other machine:") + " " + udiskName; prefixPath_to_device = QObject::tr("Other machine:") + " " + udiskName;
else else

View File

@ -724,6 +724,10 @@ bool SystemBackup::isExistsBackupName(const QString & backupName)
if (!uuidFound.isEmpty()) if (!uuidFound.isEmpty())
return true; return true;
// 不能取名为出厂备份
if (backupName == tr("factory backup"))
return true;
// 然后校验xml和log中的备份记录这一步只是为了保险而兼容老版本的备份以前的唯一性文件中只有U盘的备份 // 然后校验xml和log中的备份记录这一步只是为了保险而兼容老版本的备份以前的唯一性文件中只有U盘的备份
QList<ParseBackupList::BackupPoint> backupPointList = getBackupPointList(); QList<ParseBackupList::BackupPoint> backupPointList = getBackupPointList();
QList<BackupWrapper> list = Utils::getBackupLogList(); QList<BackupWrapper> list = Utils::getBackupLogList();
@ -820,6 +824,18 @@ void SystemBackup::initFifthWidget()
hlayoutCenterFont2->addStretch(); hlayoutCenterFont2->addStretch();
hlayoutCenterFont2->addWidget(labelTip); hlayoutCenterFont2->addWidget(labelTip);
hlayoutCenterFont2->addStretch(); hlayoutCenterFont2->addStretch();
// 第二行
QHBoxLayout *hlayoutCenterFont2_1 = new QHBoxLayout;
// 备份过程提醒信息
MyLabel *labelTip_1 = new MyLabel(centerFont);
labelTip_1->setAlignment(Qt::AlignCenter);
labelTip_1->setIsOriginal(true);
labelTip_1->setFontWordWrap(true);
labelTip_1->setMinimumWidth(700);
labelTip_1->setDeplayText("");
hlayoutCenterFont2_1->addStretch();
hlayoutCenterFont2_1->addWidget(labelTip_1);
hlayoutCenterFont2_1->addStretch();
// 第三行 // 第三行
QHBoxLayout *hlayoutCenterFont3 = new QHBoxLayout; QHBoxLayout *hlayoutCenterFont3 = new QHBoxLayout;
@ -835,6 +851,7 @@ void SystemBackup::initFifthWidget()
vlayoutCenterFont->addLayout(hlayoutCenterFont1); vlayoutCenterFont->addLayout(hlayoutCenterFont1);
vlayoutCenterFont->addLayout(hlayoutCenterFont2); vlayoutCenterFont->addLayout(hlayoutCenterFont2);
vlayoutCenterFont->addLayout(hlayoutCenterFont2_1);
vlayoutCenterFont->addSpacing(40); vlayoutCenterFont->addSpacing(40);
vlayoutCenterFont->addLayout(hlayoutCenterFont3); vlayoutCenterFont->addLayout(hlayoutCenterFont3);
vlayoutCenterFont->addStretch(); vlayoutCenterFont->addStretch();
@ -849,14 +866,17 @@ void SystemBackup::initFifthWidget()
// ------------ 中部布局end------------- // ------------ 中部布局end-------------
connect(this, &SystemBackup::backupWarnning, labelTip, [=](const QString& msg) { connect(this, &SystemBackup::backupWarnning, labelTip_1, [=](const QString& msg) {
labelTip->setDeplayText(msg); labelTip_1->setVisible(true);
labelTip_1->setDeplayText(msg);
}); });
// 开始备份 // 开始备份
connect(this, &SystemBackup::startBackup, this, [=] { connect(this, &SystemBackup::startBackup, this, [=] {
progressBar->setPersent(0); progressBar->setPersent(0);
movie->start(); movie->start();
labelTip_1->setVisible(false);
labelTip_1->setDeplayText("");
// 开始备份 // 开始备份
this->on_backup_start(); this->on_backup_start();
@ -892,7 +912,7 @@ void SystemBackup::on_backup_start()
// 是否已存在备份、还原等操作 // 是否已存在备份、还原等操作
bool isActive = false; bool isActive = false;
if(int(BackupState::BACKUP_STATE_INIT) != m_pInterface->getBackupState(isActive)){ if(int(BackupState::BACKUP_STATE_INIT) != m_pInterface->getBackupState(isActive)){
on_checkEnv_end(int(BackupResult::OTHER_BACKUP_OR_RESTORE_RUNNING)); on_checkBackup_end(int(BackupResult::OTHER_BACKUP_OR_RESTORE_RUNNING));
return; return;
} }

View File

@ -129,8 +129,8 @@ void SystemRestore::initFirstWidget()
bottomHBoxLayout->addStretch(); bottomHBoxLayout->addStretch();
// 恢复出厂复选框 // 恢复出厂复选框
MyCheckBox * checkFactoryRestore = new MyCheckBox(tr("Factory Restore"), first); MyCheckBox * checkFactoryRestore = new MyCheckBox(tr("Factory Restore"), first);
// if (!Utils::isHuawei990()) if (!Utils::isHuawei990())
// checkFactoryRestore->setVisible(false); checkFactoryRestore->setVisible(false);
// 保留用户数据复选框 // 保留用户数据复选框
MyCheckBox * retainUserData = new MyCheckBox(tr("Retaining User Data"), first); MyCheckBox * retainUserData = new MyCheckBox(tr("Retaining User Data"), first);
bottomHBoxLayout->addWidget(checkFactoryRestore); bottomHBoxLayout->addWidget(checkFactoryRestore);
@ -188,6 +188,10 @@ void SystemRestore::on_button_beginRestore_clicked(bool checked)
{ {
Q_UNUSED(checked) Q_UNUSED(checked)
this->m_uuid = "";
this->m_devPath = "";
this->m_isOtherMachine = "";
// 出厂还原,不用去选择备份点 // 出厂还原,不用去选择备份点
if (m_isFactoryRestore) { if (m_isFactoryRestore) {
// 出厂还原后,用户数据将会丢失 // 出厂还原后,用户数据将会丢失
@ -209,7 +213,11 @@ void SystemRestore::on_button_beginRestore_clicked(bool checked)
this->m_devPath = backupPoint.m_path; this->m_devPath = backupPoint.m_path;
this->m_isOtherMachine = backupPoint.m_iPosition == BackupPosition::OTHER ? true : false; this->m_isOtherMachine = backupPoint.m_iPosition == BackupPosition::OTHER ? true : false;
}); });
selectRestoreDialog->exec();
if (QDialog::Rejected == selectRestoreDialog->exec()) {
selectRestoreDialog->deleteLater();
return ;
}
selectRestoreDialog->deleteLater(); selectRestoreDialog->deleteLater();
} }