阶段提交
This commit is contained in:
parent
c2ba01b07e
commit
c1e7f440bd
|
@ -43,6 +43,7 @@ HEADERS += \
|
||||||
systembackupproxy.h \
|
systembackupproxy.h \
|
||||||
systemrestoreproxy.h \
|
systemrestoreproxy.h \
|
||||||
udisksystembackupproxy.h \
|
udisksystembackupproxy.h \
|
||||||
|
udisksystemrestoreproxy.h \
|
||||||
workerfactory.h
|
workerfactory.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
@ -65,6 +66,7 @@ SOURCES += \
|
||||||
systembackupproxy.cpp \
|
systembackupproxy.cpp \
|
||||||
systemrestoreproxy.cpp \
|
systemrestoreproxy.cpp \
|
||||||
udisksystembackupproxy.cpp \
|
udisksystembackupproxy.cpp \
|
||||||
|
udisksystemrestoreproxy.cpp \
|
||||||
workerfactory.cpp
|
workerfactory.cpp
|
||||||
|
|
||||||
# Default rules for deployment.
|
# Default rules for deployment.
|
||||||
|
|
|
@ -4,24 +4,6 @@
|
||||||
#include "../common/mydefine.h"
|
#include "../common/mydefine.h"
|
||||||
#include "backupmanager_adaptor.h"
|
#include "backupmanager_adaptor.h"
|
||||||
|
|
||||||
// test begin
|
|
||||||
#include <QDebug>
|
|
||||||
#include "../common/reflect.h"
|
|
||||||
#include "mymountproxy.h"
|
|
||||||
#include "parsebackuplist.h"
|
|
||||||
|
|
||||||
void testXml()
|
|
||||||
{
|
|
||||||
ParseBackupList parse("/backup/snapshots/backuplist.xml");
|
|
||||||
}
|
|
||||||
|
|
||||||
void testLog()
|
|
||||||
{
|
|
||||||
Utils::getBackupLogList();
|
|
||||||
}
|
|
||||||
|
|
||||||
// test end
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
// 以防客户端传入的参数中的中文信息乱码
|
// 以防客户端传入的参数中的中文信息乱码
|
||||||
|
@ -37,24 +19,6 @@ int main(int argc, char *argv[])
|
||||||
qInstallMessageHandler(Utils::customMessageHandler);
|
qInstallMessageHandler(Utils::customMessageHandler);
|
||||||
Utils::initSystemInfo();
|
Utils::initSystemInfo();
|
||||||
|
|
||||||
// test begin
|
|
||||||
qDebug() << QString("测试 begin");
|
|
||||||
|
|
||||||
// MyMountProxy * proxy = (MyMountProxy*)Reflect::createObject("MyMountProxy");
|
|
||||||
// proxy->mountBackupPartition();
|
|
||||||
|
|
||||||
// BackupWrapper backupWrapper;
|
|
||||||
// backupWrapper.m_backupName = "赵民勇test";
|
|
||||||
// backupWrapper.m_backupPaths << "/";
|
|
||||||
// backupWrapper.m_backupExcludePaths = Utils::getFromExcludePathsFile();
|
|
||||||
// MyBackupManager manager;
|
|
||||||
// manager.goBackup(backupWrapper);
|
|
||||||
|
|
||||||
testLog();
|
|
||||||
|
|
||||||
qDebug() << QString("测试 end");
|
|
||||||
// test end
|
|
||||||
|
|
||||||
MyBackupManager* backup_deamon = new MyBackupManager;
|
MyBackupManager* backup_deamon = new MyBackupManager;
|
||||||
new ManagerAdaptor(backup_deamon);
|
new ManagerAdaptor(backup_deamon);
|
||||||
QDBusConnection conn = QDBusConnection::systemBus();
|
QDBusConnection conn = QDBusConnection::systemBus();
|
||||||
|
|
|
@ -35,12 +35,12 @@ bool MountBackupProcess::Do(const QString& diskUuid)
|
||||||
|
|
||||||
m_p->start("mount", arguments);
|
m_p->start("mount", arguments);
|
||||||
if (!m_p->waitForStarted()) {
|
if (!m_p->waitForStarted()) {
|
||||||
qFatal("mount rw /backup process start failed!");
|
qCritical("mount rw /backup process start failed!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_p->waitForFinished()) {
|
if (!m_p->waitForFinished()) {
|
||||||
qFatal("mount rw backup process end failed!");
|
qCritical("mount rw backup process end failed!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,12 +53,55 @@ 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()) {
|
||||||
qFatal("mount ro backup process start failed!");
|
qCritical("mount ro backup process start failed!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_p->waitForFinished()) {
|
if (!m_p->waitForFinished()) {
|
||||||
qFatal("mount ro backup process end failed!");
|
qCritical("mount ro backup process end failed!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 卸载目录挂载
|
||||||
|
* @param mountPath,挂载的目录
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool MountBackupProcess::umount(const QString& mountPath)
|
||||||
|
{
|
||||||
|
if (0 == ::umount(mountPath.toUtf8().data()))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
qCritical() << QString("%1 umount failed, error is %2(%3)").arg(mountPath).arg(strerror(errno)).arg(QString::number(errno));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 挂载
|
||||||
|
* @param source 源
|
||||||
|
* @param target 目标目录
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool MountBackupProcess::mount(const QString& source, const QString& target, const QString& options)
|
||||||
|
{
|
||||||
|
QStringList arguments;
|
||||||
|
if (!options.isEmpty())
|
||||||
|
arguments << options;
|
||||||
|
arguments << source;
|
||||||
|
arguments << target;
|
||||||
|
|
||||||
|
m_p->start("mount", arguments);
|
||||||
|
if (!m_p->waitForStarted()) {
|
||||||
|
qCritical("mount process start failed!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_p->waitForFinished()) {
|
||||||
|
qCritical("mount process end failed!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define MOUNTBACKUPPROCESS_H
|
#define MOUNTBACKUPPROCESS_H
|
||||||
|
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
|
||||||
class MountBackupProcess : public QObject {
|
class MountBackupProcess : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -12,6 +13,9 @@ public:
|
||||||
|
|
||||||
bool umountBackupPartition();
|
bool umountBackupPartition();
|
||||||
|
|
||||||
|
static bool umount(const QString& mountPath);
|
||||||
|
bool mount(const QString& source, const QString& target, const QString& options = "");
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
QProcess* m_p;
|
QProcess* m_p;
|
||||||
|
|
|
@ -146,6 +146,20 @@ void SystemRestoreProxy::remountEfi()
|
||||||
QProcess::execute("mount", args);
|
QProcess::execute("mount", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 重新rw读写挂载boot分区
|
||||||
|
*/
|
||||||
|
void SystemRestoreProxy::remountBoot()
|
||||||
|
{
|
||||||
|
QString mountPath = Utils::getSysRootPath() + "/boot";
|
||||||
|
mountPath.replace("//", "/");
|
||||||
|
QStringList args;
|
||||||
|
args << "-o"
|
||||||
|
<< "rw,remount"
|
||||||
|
<< mountPath;
|
||||||
|
QProcess::execute("mount", args);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 同步efi
|
* @brief 同步efi
|
||||||
*/
|
*/
|
||||||
|
@ -292,6 +306,9 @@ void SystemRestoreProxy::restoreSystem()
|
||||||
m_srcPath = m_backupPath;
|
m_srcPath = m_backupPath;
|
||||||
QString destPath = Utils::getSysRootPath();
|
QString destPath = Utils::getSysRootPath();
|
||||||
|
|
||||||
|
// 以读写方式重新挂载boot分区,因为有的机器默认以只读挂载
|
||||||
|
remountBoot();
|
||||||
|
|
||||||
QStringList args;
|
QStringList args;
|
||||||
// 自动更新的备份还原时保留用户数据
|
// 自动更新的备份还原时保留用户数据
|
||||||
if (m_curUuid == AUTO_BACKUP_UUID || m_backupWrapper.m_type == BackupType::RESTORE_SYSTEM_WITH_DATA) {
|
if (m_curUuid == AUTO_BACKUP_UUID || m_backupWrapper.m_type == BackupType::RESTORE_SYSTEM_WITH_DATA) {
|
||||||
|
@ -316,7 +333,7 @@ void SystemRestoreProxy::restoreSystem()
|
||||||
QFileInfo file(fileIfSync);
|
QFileInfo file(fileIfSync);
|
||||||
QDateTime beginTime = file.fileTime(QFileDevice::FileModificationTime);
|
QDateTime beginTime = file.fileTime(QFileDevice::FileModificationTime);
|
||||||
if (Utils::isHuawei990() && FACTORY_BACKUP_UUID == m_curUuid && m_backupWrapper.m_type == BackupType::RESTORE_SYSTEM) {
|
if (Utils::isHuawei990() && FACTORY_BACKUP_UUID == m_curUuid && m_backupWrapper.m_type == BackupType::RESTORE_SYSTEM) {
|
||||||
// 出厂还原有的机器上删除/home/xxx有残留,故在此再强制删除一下,妈的sudo rm -rf命令一遍还删除不了(报错:无法删除/home/xx/.config:目录非空,应该是删除后又自动生成了),多删除几次还不是非常干净,贱 ^_^
|
// 出厂还原有的机器上删除/home/xxx有残留,故在此再强制删除一下,sudo rm -rf命令一遍还删除不了(报错:无法删除/home/xx/.config:目录非空,应该是删除后又自动生成了),多删除几次还不是非常干净,^_^
|
||||||
removeHome(Utils::getSysRootPath() + "/home");
|
removeHome(Utils::getSysRootPath() + "/home");
|
||||||
removeHome(Utils::getSysRootPath() + "/data/home");
|
removeHome(Utils::getSysRootPath() + "/data/home");
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ private:
|
||||||
void repairEfi();
|
void repairEfi();
|
||||||
// 以读写方式重新挂载efi分区
|
// 以读写方式重新挂载efi分区
|
||||||
void remountEfi();
|
void remountEfi();
|
||||||
|
// 以读写方式重新挂载boot分区
|
||||||
|
void remountBoot();
|
||||||
// 同步efi
|
// 同步efi
|
||||||
bool rsyncEfi();
|
bool rsyncEfi();
|
||||||
// 系统还原
|
// 系统还原
|
||||||
|
|
|
@ -0,0 +1,418 @@
|
||||||
|
#include "udisksystemrestoreproxy.h"
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/reboot.h>
|
||||||
|
#include "../common/utils.h"
|
||||||
|
#include "mymountproxy.h"
|
||||||
|
#include "myprocess/mksquashfsprocess.h"
|
||||||
|
|
||||||
|
IMPLEMENT_DYNCREATE(UDiskSystemRestoreProxy)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 构造函数
|
||||||
|
*/
|
||||||
|
UDiskSystemRestoreProxy::UDiskSystemRestoreProxy()
|
||||||
|
{
|
||||||
|
m_isFinished = false;
|
||||||
|
m_p = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 析构函数
|
||||||
|
*/
|
||||||
|
UDiskSystemRestoreProxy::~UDiskSystemRestoreProxy()
|
||||||
|
{
|
||||||
|
delete m_p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 环境检测
|
||||||
|
* @return false,检测失败;true,检测成功
|
||||||
|
*/
|
||||||
|
bool UDiskSystemRestoreProxy::checkEnvEx()
|
||||||
|
{
|
||||||
|
qDebug() << "UDiskSystemRestoreProxy::checkEnvEx invoke begin";
|
||||||
|
|
||||||
|
// 1、检测.user.txt是否存在
|
||||||
|
m_userFile = m_backupWrapper.m_prefixDestPath + BACKUP_SNAPSHOTS_PATH + "/" + m_backupWrapper.m_uuid + "/" + PATHS_USER_FILE;
|
||||||
|
m_userFile.replace("//", "/");
|
||||||
|
if (!Utils::filsExists(m_userFile)) {
|
||||||
|
qCritical(".user.txt文件不存在");
|
||||||
|
emit checkResult(int(BackupResult::WRITE_BACKUP_PATHS_TO_USER_FAILED));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2、检测.exclude.user.txt是否存在
|
||||||
|
m_excludeUserFile = m_backupWrapper.m_prefixDestPath + BACKUP_SNAPSHOTS_PATH + "/" + m_backupWrapper.m_uuid + "/" + EXCLUDE_PATHS_USER_FILE;
|
||||||
|
m_excludeUserFile.replace("//", "/");
|
||||||
|
if (!Utils::filsExists(m_excludeUserFile)) {
|
||||||
|
qCritical(".exclude.user.txt文件不存在");
|
||||||
|
emit checkResult(int(BackupResult::WRITE_EXCLUDE_BACKUP_PATHS_TO_USER_FAILED));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3、检测还原点是否存在
|
||||||
|
m_backupPath = m_backupWrapper.m_prefixDestPath + BACKUP_SNAPSHOTS_PATH + "/" + m_backupWrapper.m_uuid + "/data";
|
||||||
|
m_backupPath.replace("//", "/");
|
||||||
|
if (Utils::isDirEmpty(m_backupPath)) {
|
||||||
|
qCritical("还原点{uuid}/data目录不存在");
|
||||||
|
emit checkResult(int(BackupResult::INC_NOT_FOUND_DIR));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "UDiskSystemRestoreProxy::checkEnvEx invoke end";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 执行还原逻辑
|
||||||
|
*/
|
||||||
|
void UDiskSystemRestoreProxy::doWorkEx()
|
||||||
|
{
|
||||||
|
qDebug() << "UDiskSystemRestoreProxy::doWorkEx invoke begin";
|
||||||
|
|
||||||
|
// 1、校验
|
||||||
|
if (!checkEnvEx())
|
||||||
|
return ;
|
||||||
|
|
||||||
|
// 2、还原efi(兼容旧版本的备份)
|
||||||
|
if (!restoreEfi()) {
|
||||||
|
qCritical("/boot/efi目录同步失败");
|
||||||
|
emit checkResult(int(BackupResult::EFI_RSYNC_FAIL));
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3、还原系统
|
||||||
|
if (doPrepare())
|
||||||
|
restoreSystem();
|
||||||
|
|
||||||
|
qDebug() << "UDiskSystemRestoreProxy::doWorkEx invoke end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 还原efi(兼容旧版本的备份)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool UDiskSystemRestoreProxy::restoreEfi()
|
||||||
|
{
|
||||||
|
qDebug() << "UDiskSystemRestoreProxy::restoreEfi invoke begin";
|
||||||
|
|
||||||
|
// 是否有/boot/efi目录
|
||||||
|
QString efiPath = Utils::getSysRootPath() + "/boot/efi";
|
||||||
|
efiPath.replace("//", "/");
|
||||||
|
if (!Utils::isDirEmpty(efiPath)) {
|
||||||
|
// 1、修复源数据
|
||||||
|
repairEfi();
|
||||||
|
|
||||||
|
// 2、重新rw读写挂载
|
||||||
|
remountEfi();
|
||||||
|
|
||||||
|
// 3、同步efi
|
||||||
|
return rsyncEfi();
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "UDiskSystemRestoreProxy::restoreEfi invoke end";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 修复efi目录
|
||||||
|
*/
|
||||||
|
void UDiskSystemRestoreProxy::repairEfi()
|
||||||
|
{
|
||||||
|
QString qsEfiPath = m_backupPath + "/efi";
|
||||||
|
if (!Utils::isDirEmpty(qsEfiPath)) {
|
||||||
|
// 存在/efi说明是老备份数据,尽量修正老数据
|
||||||
|
QStringList args;
|
||||||
|
args << "-f";
|
||||||
|
args << qsEfiPath;
|
||||||
|
QString newPath = m_backupPath + "/boot";
|
||||||
|
args << newPath;
|
||||||
|
QProcess::execute("mv", args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 重新rw读写挂载efi分区
|
||||||
|
*/
|
||||||
|
void UDiskSystemRestoreProxy::remountEfi()
|
||||||
|
{
|
||||||
|
QString mountPath = Utils::getSysRootPath() + "/boot/efi";
|
||||||
|
mountPath.replace("//", "/");
|
||||||
|
QStringList args;
|
||||||
|
args << "-o"
|
||||||
|
<< "rw,remount"
|
||||||
|
<< mountPath;
|
||||||
|
QProcess::execute("mount", args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 重新rw读写挂载boot分区
|
||||||
|
*/
|
||||||
|
void UDiskSystemRestoreProxy::remountBoot()
|
||||||
|
{
|
||||||
|
QString mountPath = Utils::getSysRootPath() + "/boot";
|
||||||
|
mountPath.replace("//", "/");
|
||||||
|
QStringList args;
|
||||||
|
args << "-o"
|
||||||
|
<< "rw,remount"
|
||||||
|
<< mountPath;
|
||||||
|
QProcess::execute("mount", args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 同步efi
|
||||||
|
*/
|
||||||
|
bool UDiskSystemRestoreProxy::rsyncEfi()
|
||||||
|
{
|
||||||
|
QString efiPath = m_backupPath + "/boot/efi/";
|
||||||
|
if (Utils::isDirEmpty(efiPath))
|
||||||
|
efiPath = efiPath = m_backupPath + "/efi/";
|
||||||
|
if (Utils::isDirEmpty(efiPath))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
QStringList args = getRsyncArgs(SystemRestoreScene::EFI_RESTORE);
|
||||||
|
QString mountPath = Utils::getSysRootPath() + "/boot/efi/";
|
||||||
|
mountPath.replace("//", "/");
|
||||||
|
|
||||||
|
args << efiPath << mountPath;
|
||||||
|
|
||||||
|
m_p = new RsyncPathToDirProcess(this);
|
||||||
|
bool result = m_p->start(args);
|
||||||
|
delete m_p;
|
||||||
|
m_p = nullptr;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 根据场景获取rsync命令参数
|
||||||
|
* @param scene,场景
|
||||||
|
* @return 组装好的rsync的参数信息
|
||||||
|
*/
|
||||||
|
QStringList UDiskSystemRestoreProxy::getRsyncArgs(SystemRestoreScene scene)
|
||||||
|
{
|
||||||
|
QStringList args;
|
||||||
|
args << "-avAHXr";
|
||||||
|
args << "--info=progress2";
|
||||||
|
args << "--no-inc-recursive";
|
||||||
|
args << "--ignore-missing-args";
|
||||||
|
args << "--delete";
|
||||||
|
|
||||||
|
QDir dataDir(m_srcPath + "/data");
|
||||||
|
QFile file(m_srcPath + "/etc/uid_list");
|
||||||
|
QDir efiDir(m_srcPath + "/boot/efi");
|
||||||
|
QStringList excludes;
|
||||||
|
|
||||||
|
switch (scene) {
|
||||||
|
case SystemRestoreScene::SYSTEM_RESTORE :
|
||||||
|
// 还原工具不还原自身
|
||||||
|
args << "--exclude=/usr/bin/backup-daemon";
|
||||||
|
args << "--exclude=/usr/bin/kybackup";
|
||||||
|
args << "--exclude=/usr/bin/mount_fstab_efi";
|
||||||
|
args << "--exclude=/usr/bin/backup-auto-efi";
|
||||||
|
args << "--exclude=/usr/bin/backup-auto";
|
||||||
|
args << "--exclude=/usr/bin/rsync";
|
||||||
|
args << "--exclude=/usr/share/rsync";
|
||||||
|
args << "--exclude=/usr/share/initramfs-tools/hooks/kybackup-hooks";
|
||||||
|
args << "--exclude=/usr/share/initramfs-tools/scripts/local-bottom/kybackup";
|
||||||
|
|
||||||
|
// 以前的出厂备份和grub备份没有备份/data,还原时需要判断/data是否存在,如不存在需要屏蔽掉,不然会将主机上的/data删除,造成问题
|
||||||
|
// 此为兼容以前备份的老数据而改,等以后老的备份估计不存在了可已去掉
|
||||||
|
if (!dataDir.exists()) {
|
||||||
|
args << "--exclude=/data";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file.exists()) {
|
||||||
|
args << "--exclude=/etc/uid_list";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 为兼容以前的老备份数据,增加下面几行
|
||||||
|
if (efiDir.isEmpty()) {
|
||||||
|
args << QString("--exclude=/boot/efi");
|
||||||
|
}
|
||||||
|
// 系统安装后有的会将/data/home /data/root挂载到的/home /root上,实际文件是存放在/data/home /data/root下面
|
||||||
|
Utils::excludeFstabBindPath(excludes);
|
||||||
|
for (const QString& item : excludes) {
|
||||||
|
QDir itemDir(m_srcPath + item);
|
||||||
|
// 以后统一用/home /root这种路径, 兼容老备份数据(原来的U盘备份,在mksquashfs时排除bind挂载的任意一方时,都备份不上)
|
||||||
|
if (item == "/data/home") {
|
||||||
|
QDir homeDir(m_srcPath + "/home");
|
||||||
|
if (!homeDir.isEmpty()) {
|
||||||
|
args << QString("--exclude=/data/home");
|
||||||
|
} else if (!itemDir.isEmpty()) {
|
||||||
|
args << QString("--exclude=/home");
|
||||||
|
} else {
|
||||||
|
args << QString("--exclude=/data/home");
|
||||||
|
args << QString("--exclude=/home");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} else if (item == "/data/root") {
|
||||||
|
QDir homeDir(m_srcPath + "/root");
|
||||||
|
if (!homeDir.isEmpty()) {
|
||||||
|
args << QString("--exclude=/data/root");
|
||||||
|
} else if (!itemDir.isEmpty()) {
|
||||||
|
args << QString("--exclude=/root");
|
||||||
|
} else {
|
||||||
|
args << QString("--exclude=/data/root");
|
||||||
|
args << QString("--exclude=/root");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
args << QString("--exclude=") + item;
|
||||||
|
}
|
||||||
|
|
||||||
|
args << "--exclude-from" << m_excludeUserFile;
|
||||||
|
args << "--files-from" << m_userFile;
|
||||||
|
|
||||||
|
break ;
|
||||||
|
case SystemRestoreScene::EFI_RESTORE :
|
||||||
|
break ;
|
||||||
|
default:
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 还原前准备
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool UDiskSystemRestoreProxy::doPrepare()
|
||||||
|
{
|
||||||
|
// 移动设备系统备份如果有img,则需要先将img挂载到/backup/imgbackup目录
|
||||||
|
QString imgPath = m_backupPath + UDISK_MKSQUASHFS_IMG_NAME;
|
||||||
|
if (Utils::filsExists(imgPath)) {
|
||||||
|
// 1、检测目录/backup/imgbackup是否存在,不存在则创建此目录
|
||||||
|
QString dstImgMountPath = Utils::getSysRootPath() + BACKUP_IMGBACKUP_PATH;
|
||||||
|
dstImgMountPath.replace("//", "/");
|
||||||
|
Utils::mkpath(dstImgMountPath);
|
||||||
|
|
||||||
|
// 2、先卸载/backup/imgbackup上的mount
|
||||||
|
MountBackupProcess::umount(dstImgMountPath);
|
||||||
|
|
||||||
|
// 3、将img文件挂载到/backup/imgbackup上
|
||||||
|
MountBackupProcess *processMount = new MountBackupProcess;
|
||||||
|
if (processMount->mount(imgPath, dstImgMountPath)) {
|
||||||
|
emit checkResult(int(BackupResult::RESTOREDIR_PREPARE_FAILED));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_srcPath = dstImgMountPath;
|
||||||
|
} else
|
||||||
|
m_srcPath = m_backupPath;
|
||||||
|
|
||||||
|
// 以读写方式重新挂载boot分区,因为有的机器默认以只读挂载
|
||||||
|
remountBoot();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 系统还原
|
||||||
|
*/
|
||||||
|
void UDiskSystemRestoreProxy::restoreSystem()
|
||||||
|
{
|
||||||
|
QString destPath = Utils::getSysRootPath();
|
||||||
|
|
||||||
|
QStringList args = getRsyncArgs(SystemRestoreScene::SYSTEM_RESTORE);
|
||||||
|
|
||||||
|
args << m_srcPath + "/";
|
||||||
|
args << destPath + "/";
|
||||||
|
|
||||||
|
m_p = new RsyncPathToDirProcess(this);
|
||||||
|
connect(m_p, &RsyncPathToDirProcess::progress, this, &UDiskSystemRestoreProxy::progress);
|
||||||
|
connect(m_p, &RsyncPathToDirProcess::finished, this, [&](bool result) {
|
||||||
|
if (result) {
|
||||||
|
QString time = QDateTime::currentDateTime().toString("yy-MM-dd hh:mm:ss");
|
||||||
|
Utils::writeBackupLog(time + "," + m_curUuid + "," + QString::number(m_backupWrapper.m_type) + ",,," + QString::number(m_backupWrapper.m_frontUid));
|
||||||
|
|
||||||
|
Utils::updateSyncFile();
|
||||||
|
QString fileIfSync = Utils::getSysRootPath() + FILE_IF_SYNC;
|
||||||
|
fileIfSync.replace("//", "/");
|
||||||
|
QFileInfo file(fileIfSync);
|
||||||
|
QDateTime beginTime = file.fileTime(QFileDevice::FileModificationTime);
|
||||||
|
Utils::wait(10);
|
||||||
|
Utils::updateSyncFile();
|
||||||
|
while (1) {
|
||||||
|
Utils::wait(2);
|
||||||
|
QFileInfo file1(fileIfSync);
|
||||||
|
QDateTime UpdateTime = file1.fileTime(QFileDevice::FileModificationTime);
|
||||||
|
if (UpdateTime > beginTime)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_backupWrapper.m_isOtherMachine) {
|
||||||
|
Utils::wait(20);
|
||||||
|
updateGrubUUid();
|
||||||
|
sync();
|
||||||
|
Utils::wait(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit this->workResult(result);
|
||||||
|
Utils::wait(2);
|
||||||
|
reboot(RB_AUTOBOOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Utils::isDirEmpty(m_backupPath))
|
||||||
|
result = false;
|
||||||
|
emit this->workResult(result);
|
||||||
|
m_isFinished = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
QTimer::singleShot(1*1000, this, &UDiskSystemRestoreProxy::checkUdiskExists);
|
||||||
|
m_isFinished = false;
|
||||||
|
m_p->start(args, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 异机还原时更新grub.cfg中的分区UUID
|
||||||
|
*/
|
||||||
|
void UDiskSystemRestoreProxy::updateGrubUUid()
|
||||||
|
{
|
||||||
|
QString srcFstab = Utils::getSysRootPath() + BACKUP_IMGBACKUP_PATH;
|
||||||
|
srcFstab += FSTAB_PATH;
|
||||||
|
srcFstab.replace("//", "/");
|
||||||
|
QHash<QString, QString> srcPartToUuid = Utils::getPartUuidMap(srcFstab);
|
||||||
|
QString destFstab = Utils::getSysRootPath() + FSTAB_PATH;
|
||||||
|
QHash<QString, QString> destPartToUuid = Utils::getPartUuidMap(destFstab);
|
||||||
|
|
||||||
|
QString findGrub = Utils::executeCmd("find /boot -name grub.cfg");
|
||||||
|
QStringList grubs = findGrub.split("\n");
|
||||||
|
for (const QString &grub : grubs) {
|
||||||
|
if (grub.isEmpty())
|
||||||
|
continue;
|
||||||
|
QString root = QString("sed -i 's/%1/%2/g' %3").arg(srcPartToUuid.value("/")).arg(destPartToUuid.value("/")).arg(grub);
|
||||||
|
qDebug() << Utils::executeCmd(root);
|
||||||
|
|
||||||
|
QString boot = QString("sed -i 's/%1/%2/g' %3").arg(srcPartToUuid.value("/boot")).arg(destPartToUuid.value("/boot")).arg(grub);
|
||||||
|
qDebug() << Utils::executeCmd(boot);
|
||||||
|
|
||||||
|
QString swap = QString("sed -i 's/%1/%2/g' %3").arg(srcPartToUuid.value("swap")).arg(destPartToUuid.value("swap")).arg(grub);
|
||||||
|
qDebug() << Utils::executeCmd(swap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 监控移动设备是否还在
|
||||||
|
* @return true-在;false-不在
|
||||||
|
*/
|
||||||
|
bool UDiskSystemRestoreProxy::checkUdiskExists()
|
||||||
|
{
|
||||||
|
if (!m_isFinished) {
|
||||||
|
if (Utils::isDirEmpty(m_backupPath) && m_p != nullptr)
|
||||||
|
m_p->stop();
|
||||||
|
else
|
||||||
|
QTimer::singleShot(1*1000, this, &UDiskSystemRestoreProxy::checkUdiskExists);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
#ifndef UDISKSYSTEMRESTOREPROXY_H
|
||||||
|
#define UDISKSYSTEMRESTOREPROXY_H
|
||||||
|
|
||||||
|
#include "workerfactory.h"
|
||||||
|
#include "myprocess/rsyncpathtodirprocess.h"
|
||||||
|
#include "parsebackuplist.h"
|
||||||
|
|
||||||
|
class UDiskSystemRestoreProxy : public Worker
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
DECLARE_DYNCREATE(UDiskSystemRestoreProxy)
|
||||||
|
public:
|
||||||
|
// 系统还原的几种场景
|
||||||
|
enum SystemRestoreScene {
|
||||||
|
SYSTEM_RESTORE, // 系统还原
|
||||||
|
EFI_RESTORE, // efi还原
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit UDiskSystemRestoreProxy();
|
||||||
|
virtual ~UDiskSystemRestoreProxy();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// 环境检测
|
||||||
|
virtual bool checkEnvEx();
|
||||||
|
|
||||||
|
// 任务处理
|
||||||
|
virtual void doWorkEx();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
bool checkUdiskExists();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 还原efi
|
||||||
|
bool restoreEfi();
|
||||||
|
// 修复efi目录
|
||||||
|
void repairEfi();
|
||||||
|
// 以读写方式重新挂载efi分区
|
||||||
|
void remountEfi();
|
||||||
|
// 以读写方式重新挂载boot分区
|
||||||
|
void remountBoot();
|
||||||
|
// 同步efi
|
||||||
|
bool rsyncEfi();
|
||||||
|
// 系统还原
|
||||||
|
void restoreSystem();
|
||||||
|
// 还原前准备
|
||||||
|
bool doPrepare();
|
||||||
|
// 异机还原时更新grub.cfg中的分区UUID
|
||||||
|
void updateGrubUUid();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 根据场景获取rsync命令参数
|
||||||
|
* @param scene,场景
|
||||||
|
* @return 组装好的rsync的参数信息
|
||||||
|
*/
|
||||||
|
QStringList getRsyncArgs(SystemRestoreScene scene);
|
||||||
|
|
||||||
|
// .user.txt文件路径
|
||||||
|
QString m_userFile;
|
||||||
|
// .exclude.user.txt文件路径
|
||||||
|
QString m_excludeUserFile;
|
||||||
|
// 备份数据所在的data目录
|
||||||
|
QString m_backupPath;
|
||||||
|
|
||||||
|
// 是否还原结束
|
||||||
|
bool m_isFinished;
|
||||||
|
// 当前备份uuid
|
||||||
|
QString m_curUuid;
|
||||||
|
// 当前还原源目录
|
||||||
|
QString m_srcPath;
|
||||||
|
// 备份进程
|
||||||
|
RsyncPathToDirProcess *m_p;
|
||||||
|
// 当前备份节点
|
||||||
|
ParseBackupList::BackupPoint m_backupPoint;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // UDISKSYSTEMRESTOREPROXY_H
|
|
@ -8,7 +8,7 @@ QDBusArgument &operator<<(QDBusArgument &argument, const BackupWrapper &backupWr
|
||||||
argument << backupWrapper.m_type << backupWrapper.m_iPosition << backupWrapper.m_comment << backupWrapper.m_backupName
|
argument << backupWrapper.m_type << backupWrapper.m_iPosition << backupWrapper.m_comment << backupWrapper.m_backupName
|
||||||
<< backupWrapper.m_uuid << backupWrapper.m_backupPaths << backupWrapper.m_backupExcludePaths << backupWrapper.m_prefixDestPath
|
<< backupWrapper.m_uuid << backupWrapper.m_backupPaths << backupWrapper.m_backupExcludePaths << backupWrapper.m_prefixDestPath
|
||||||
<< backupWrapper.m_note << backupWrapper.m_frontUserName << backupWrapper.m_frontUid
|
<< backupWrapper.m_note << backupWrapper.m_frontUserName << backupWrapper.m_frontUid
|
||||||
<< backupWrapper.m_gid;
|
<< backupWrapper.m_gid << backupWrapper.m_isOtherMachine;
|
||||||
argument.endStructure();
|
argument.endStructure();
|
||||||
return argument;
|
return argument;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ const QDBusArgument &operator>>(const QDBusArgument &argument, BackupWrapper &ba
|
||||||
argument >> backupWrapper.m_type >> backupWrapper.m_iPosition >> backupWrapper.m_comment >> backupWrapper.m_backupName
|
argument >> backupWrapper.m_type >> backupWrapper.m_iPosition >> backupWrapper.m_comment >> backupWrapper.m_backupName
|
||||||
>> backupWrapper.m_uuid >> backupWrapper.m_backupPaths >> backupWrapper.m_backupExcludePaths >> backupWrapper.m_prefixDestPath
|
>> backupWrapper.m_uuid >> backupWrapper.m_backupPaths >> backupWrapper.m_backupExcludePaths >> backupWrapper.m_prefixDestPath
|
||||||
>> backupWrapper.m_note >> backupWrapper.m_frontUserName >> backupWrapper.m_frontUid
|
>> backupWrapper.m_note >> backupWrapper.m_frontUserName >> backupWrapper.m_frontUid
|
||||||
>> backupWrapper.m_gid;
|
>> backupWrapper.m_gid >> backupWrapper.m_isOtherMachine;
|
||||||
argument.endStructure();
|
argument.endStructure();
|
||||||
return argument;
|
return argument;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,9 @@ void RingsProgressbar::paintEvent(QPaintEvent *)
|
||||||
p.setBrush(QBrush(QColor(COLOR_BLUE)));
|
p.setBrush(QBrush(QColor(COLOR_BLUE)));
|
||||||
|
|
||||||
//画圆弧
|
//画圆弧
|
||||||
pen.setCapStyle(Qt::RoundCap);
|
// pen.setCapStyle(Qt::RoundCap);
|
||||||
p.setPen(pen);
|
// pen.setColor(QColor(COLOR_BLUE));
|
||||||
|
// p.setPen(pen);
|
||||||
p.drawPie(QRectF(5 , 5, side - 10, side - 10), (90-m_rotateAngle)*16, m_rotateAngle*16);
|
p.drawPie(QRectF(5 , 5, side - 10, side - 10), (90-m_rotateAngle)*16, m_rotateAngle*16);
|
||||||
|
|
||||||
//画遮罩
|
//画遮罩
|
||||||
|
|
|
@ -96,7 +96,7 @@ void SelectRestorePoint::insertLines(const QList<ParseBackupList::BackupPoint> &
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//hide factory backup
|
//hide factory backup
|
||||||
if (backupPoint.m_uuid == FACTORY_BACKUP_UUID)
|
if (backupPoint.m_uuid == FACTORY_BACKUP_UUID && Utils::isHuawei990())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//udisk unique
|
//udisk unique
|
||||||
|
|
|
@ -779,6 +779,7 @@ void SystemBackup::initFifthWidget()
|
||||||
labelTip->setGeometry(101, 261, 520, 30);
|
labelTip->setGeometry(101, 261, 520, 30);
|
||||||
labelTip->setAlignment(Qt::AlignCenter);
|
labelTip->setAlignment(Qt::AlignCenter);
|
||||||
labelTip->setFontWordWrap(true);
|
labelTip->setFontWordWrap(true);
|
||||||
|
// 不要使用电脑,以防数据丢失
|
||||||
labelTip->setDeplayText(tr("Do not use computers in case of data loss"));
|
labelTip->setDeplayText(tr("Do not use computers in case of data loss"));
|
||||||
connect(this, &SystemBackup::backupWarnning, labelTip, [=](const QString& msg) {
|
connect(this, &SystemBackup::backupWarnning, labelTip, [=](const QString& msg) {
|
||||||
labelTip->setDeplayText(msg);
|
labelTip->setDeplayText(msg);
|
||||||
|
|
|
@ -31,6 +31,8 @@ SystemRestore::SystemRestore(QWidget *parent) :
|
||||||
// 界面手写代码创建,作为练手
|
// 界面手写代码创建,作为练手
|
||||||
initFirstWidget();
|
initFirstWidget();
|
||||||
initSecondWidget();
|
initSecondWidget();
|
||||||
|
initThirdWidget();
|
||||||
|
initLastWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemRestore::~SystemRestore()
|
SystemRestore::~SystemRestore()
|
||||||
|
@ -184,12 +186,6 @@ void SystemRestore::on_next_clicked(bool checked)
|
||||||
*/
|
*/
|
||||||
void SystemRestore::on_button_beginRestore_clicked(bool checked)
|
void SystemRestore::on_button_beginRestore_clicked(bool checked)
|
||||||
{
|
{
|
||||||
on_next_clicked();
|
|
||||||
emit this->startCheckEnv();
|
|
||||||
return;
|
|
||||||
|
|
||||||
// -------以上为测试代码-------
|
|
||||||
|
|
||||||
Q_UNUSED(checked)
|
Q_UNUSED(checked)
|
||||||
|
|
||||||
// 出厂还原,不用去选择备份点
|
// 出厂还原,不用去选择备份点
|
||||||
|
@ -221,7 +217,7 @@ void SystemRestore::on_button_beginRestore_clicked(bool checked)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 初始化第二界面
|
* @brief 初始化第二界面--检测中
|
||||||
*/
|
*/
|
||||||
void SystemRestore::initSecondWidget()
|
void SystemRestore::initSecondWidget()
|
||||||
{
|
{
|
||||||
|
@ -340,6 +336,7 @@ void SystemRestore::initSecondWidget()
|
||||||
nextStep->setAutoRepeat(true);
|
nextStep->setAutoRepeat(true);
|
||||||
connect(nextStep, &MyPushButton::clicked, this, [=](bool checked) {
|
connect(nextStep, &MyPushButton::clicked, this, [=](bool checked) {
|
||||||
this->on_next_clicked(checked);
|
this->on_next_clicked(checked);
|
||||||
|
this->startRestore();
|
||||||
});
|
});
|
||||||
hlayoutCenterFont5->addWidget(nextStep);
|
hlayoutCenterFont5->addWidget(nextStep);
|
||||||
// 重新检测按钮
|
// 重新检测按钮
|
||||||
|
@ -348,10 +345,6 @@ void SystemRestore::initSecondWidget()
|
||||||
recheck->setText(tr("recheck"));
|
recheck->setText(tr("recheck"));
|
||||||
recheck->setEnabled(true);
|
recheck->setEnabled(true);
|
||||||
recheck->setAutoRepeat(true);
|
recheck->setAutoRepeat(true);
|
||||||
connect(recheck, &MyPushButton::clicked, this, [=](bool checked) {
|
|
||||||
Q_UNUSED(checked)
|
|
||||||
emit this->startCheckEnv();
|
|
||||||
});
|
|
||||||
hlayoutCenterFont5->addWidget(recheck);
|
hlayoutCenterFont5->addWidget(recheck);
|
||||||
hlayoutCenterFont5->addStretch();
|
hlayoutCenterFont5->addStretch();
|
||||||
vlayoutCenterFont->addLayout(hlayoutCenterFont5);
|
vlayoutCenterFont->addLayout(hlayoutCenterFont5);
|
||||||
|
@ -449,6 +442,12 @@ void SystemRestore::initSecondWidget()
|
||||||
preStep->setVisible(true);
|
preStep->setVisible(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 重新检查
|
||||||
|
connect(recheck, &MyPushButton::clicked, this, [=](bool checked) {
|
||||||
|
Q_UNUSED(checked)
|
||||||
|
emit this->startCheckEnv();
|
||||||
|
});
|
||||||
|
|
||||||
addWidget(second);
|
addWidget(second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,35 +500,29 @@ void SystemRestore::on_checkEnv_end(int result)
|
||||||
// 没有找到相应的处理逻辑
|
// 没有找到相应的处理逻辑
|
||||||
errTip = tr("No processing logic was found in the service");
|
errTip = tr("No processing logic was found in the service");
|
||||||
break;
|
break;
|
||||||
case int(BackupResult::BACKUP_PARTITION_MOUNT_FAIL):
|
case int(BackupResult::WRITE_BACKUP_PATHS_TO_USER_FAILED):
|
||||||
// 备份分区挂载失败
|
// ".user.txt文件不存在"
|
||||||
errMsg = tr("Failed to mount the backup partition");
|
errMsg = tr(".user.txt file is not exists");
|
||||||
// 检查是否有备份分区
|
// 备份点可能被损坏
|
||||||
errTip = tr("Check whether there is a backup partition");
|
errTip = tr("Backup points may be corrupted");
|
||||||
break;
|
break;
|
||||||
case int(BackupResult::UDISK_FILESYSTEM_TYPE_IS_VFAT):
|
case int(BackupResult::WRITE_EXCLUDE_BACKUP_PATHS_TO_USER_FAILED):
|
||||||
// 移动设备的文件系统是vfat格式
|
// .exclude.user.txt文件不存在
|
||||||
errMsg = tr("The filesystem of device is vfat format");
|
errMsg = tr(".exclude.user.txt file is not exists");
|
||||||
// 请换成ext4、ntfs等格式
|
// 备份点可能被损坏
|
||||||
errTip = tr("Please change filesystem format to ext3、ext4 or ntfs");
|
errTip = tr("Backup points may be corrupted");
|
||||||
break;
|
break;
|
||||||
case int(BackupResult::UDISK_FILESYSTEM_IS_READONLY):
|
case int(BackupResult::INC_NOT_FOUND_DIR):
|
||||||
// 移动设备是只读的
|
// 备份点数据目录不存在
|
||||||
errMsg = tr("The device is read only");
|
errMsg = tr("The backup point data directory does not exist");
|
||||||
// 请修改为可读写权限的
|
// 备份点可能被损坏
|
||||||
errTip = tr("Please chmod to rw");
|
errTip = tr("Backup points may be corrupted");
|
||||||
break;
|
break;
|
||||||
case int(BackupResult::BACKUP_CAPACITY_IS_NOT_ENOUGH):
|
case int(BackupResult::EFI_RSYNC_FAIL):
|
||||||
// 备份空间不足
|
// 同步/boot/efi失败
|
||||||
errMsg = tr("The storage for backup is not enough");
|
errMsg = tr("Failed to rsync /boot/efi");
|
||||||
// 建议释放空间后重试
|
// 请检查/boot/efi分区挂载方式
|
||||||
errTip = tr("Retry after release space");
|
errTip = tr("Check the mounting mode of the /boot/efi partition");
|
||||||
break;
|
|
||||||
case int(BackupResult::OTHER_BACKUP_OR_RESTORE_RUNNING):
|
|
||||||
// 其它备份还原等操作正在执行
|
|
||||||
errMsg = tr("Other backup or restore task is being performed");
|
|
||||||
// 请稍后重试
|
|
||||||
errTip = tr("Please try again later");
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
bRst = true;
|
bRst = true;
|
||||||
|
@ -543,4 +536,408 @@ void SystemRestore::on_checkEnv_end(int result)
|
||||||
m_pInterface = nullptr;
|
m_pInterface = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 第三个页面-还原中
|
||||||
|
*/
|
||||||
|
void SystemRestore::initThirdWidget()
|
||||||
|
{
|
||||||
|
QWidget *third = new QWidget;
|
||||||
|
|
||||||
|
// 流程进度提示栏
|
||||||
|
CircleLable *one = new CircleLable("1", third, 24, QColor(COLOR_BLUE));
|
||||||
|
LineLabel *line1 = new LineLabel(third, QColor(COLOR_BLUE), QSize(200, 24));
|
||||||
|
CircleLable *two = new CircleLable("2", third, 24, QColor(COLOR_BLUE));
|
||||||
|
LineLabel *line2 = new LineLabel(third, QColor(COLOR_GRAY), QSize(200, 24));
|
||||||
|
CircleLable *three = new CircleLable("3", third);
|
||||||
|
QHBoxLayout *layoutLine1 = new QHBoxLayout;
|
||||||
|
layoutLine1->addStretch();
|
||||||
|
layoutLine1->addWidget(one);
|
||||||
|
layoutLine1->addWidget(line1);
|
||||||
|
layoutLine1->addWidget(two);
|
||||||
|
layoutLine1->addWidget(line2);
|
||||||
|
layoutLine1->addWidget(three);
|
||||||
|
layoutLine1->addStretch();
|
||||||
|
|
||||||
|
MyLabel *label1 = new MyLabel(tr("checking"), third);
|
||||||
|
label1->setIsOriginal(true);
|
||||||
|
label1->setFontColor(QColor(COLOR_BLUE));
|
||||||
|
MyLabel *label2 = new MyLabel(tr("restoring"), third);
|
||||||
|
label2->setIsOriginal(true);
|
||||||
|
label2->setFontColor(QColor(COLOR_BLUE));
|
||||||
|
MyLabel *label3 = new MyLabel(tr("finished"), third);
|
||||||
|
label3->setIsOriginal(true);
|
||||||
|
QHBoxLayout *layoutLine2 = new QHBoxLayout;
|
||||||
|
layoutLine2->addSpacing(100);
|
||||||
|
layoutLine2->addWidget(label1);
|
||||||
|
layoutLine2->addStretch();
|
||||||
|
layoutLine2->addWidget(label2);
|
||||||
|
layoutLine2->addStretch();
|
||||||
|
layoutLine2->addWidget(label3);
|
||||||
|
layoutLine2->addSpacing(100);
|
||||||
|
|
||||||
|
// ------------ 中部布局begin-------------
|
||||||
|
QWidget *centerFont = new QWidget(third);
|
||||||
|
QVBoxLayout *vlayoutCenterFont = new QVBoxLayout;
|
||||||
|
|
||||||
|
// 中部第一行
|
||||||
|
QHBoxLayout *hlayoutCenterFont1 = new QHBoxLayout;
|
||||||
|
// 检测等待图标
|
||||||
|
QLabel *loadingGif = new QLabel(centerFont);
|
||||||
|
// 环境检测等待动画
|
||||||
|
QMovie *movie = new QMovie(":/images/loading.gif", QByteArray(), centerFont);
|
||||||
|
loadingGif->setMovie(movie);
|
||||||
|
// 进度条
|
||||||
|
RingsProgressbar *progressBar = new RingsProgressbar(centerFont);
|
||||||
|
progressBar->setFixedSize(100, 100);
|
||||||
|
hlayoutCenterFont1->addStretch();
|
||||||
|
hlayoutCenterFont1->addWidget(loadingGif);
|
||||||
|
hlayoutCenterFont1->addWidget(progressBar);
|
||||||
|
hlayoutCenterFont1->addStretch();
|
||||||
|
|
||||||
|
// 第二行
|
||||||
|
QHBoxLayout *hlayoutCenterFont2 = new QHBoxLayout;
|
||||||
|
// 提醒
|
||||||
|
MyLabel *labelTip = new MyLabel(centerFont);
|
||||||
|
labelTip->setAlignment(Qt::AlignCenter);
|
||||||
|
labelTip->setIsOriginal(true);
|
||||||
|
labelTip->setFontWordWrap(true);
|
||||||
|
// 不要使用电脑,以防数据丢失
|
||||||
|
labelTip->setDeplayText(tr("Do not use computers in case of data loss"));
|
||||||
|
hlayoutCenterFont2->addStretch();
|
||||||
|
hlayoutCenterFont2->addWidget(labelTip);
|
||||||
|
hlayoutCenterFont2->addStretch();
|
||||||
|
|
||||||
|
vlayoutCenterFont->addLayout(hlayoutCenterFont1);
|
||||||
|
vlayoutCenterFont->addLayout(hlayoutCenterFont2);
|
||||||
|
vlayoutCenterFont->addStretch();
|
||||||
|
centerFont->setLayout(vlayoutCenterFont);
|
||||||
|
|
||||||
|
// ------------ 中部布局end-------------
|
||||||
|
QHBoxLayout *layoutLine3 = new QHBoxLayout;
|
||||||
|
layoutLine3->addStretch();
|
||||||
|
layoutLine3->addSpacing(80);
|
||||||
|
layoutLine3->addWidget(centerFont);
|
||||||
|
layoutLine3->addStretch();
|
||||||
|
|
||||||
|
// 布局
|
||||||
|
QVBoxLayout *vlayout = new QVBoxLayout;
|
||||||
|
vlayout->addSpacing(40);
|
||||||
|
vlayout->addLayout(layoutLine1);
|
||||||
|
vlayout->addLayout(layoutLine2);
|
||||||
|
vlayout->addSpacing(50);
|
||||||
|
vlayout->addLayout(layoutLine3);
|
||||||
|
vlayout->addStretch();
|
||||||
|
third->setLayout(vlayout);
|
||||||
|
|
||||||
|
// 开始备份
|
||||||
|
connect(this, &SystemRestore::startRestore, this, [=] {
|
||||||
|
progressBar->setPersent(20);
|
||||||
|
movie->start();
|
||||||
|
|
||||||
|
// 开始备份
|
||||||
|
this->on_restore_start();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 进度
|
||||||
|
connect(this, &SystemRestore::progress, this, [=](int state, int rate) {
|
||||||
|
Q_UNUSED(state)
|
||||||
|
progressBar->setPersent(rate);
|
||||||
|
});
|
||||||
|
|
||||||
|
addWidget(third);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 开始还原
|
||||||
|
*/
|
||||||
|
void SystemRestore::on_restore_start()
|
||||||
|
{
|
||||||
|
GlobelBackupInfo::inst().setIsBusy(true);
|
||||||
|
m_systemRestoreState = SystemRestoreState::RESTORING;
|
||||||
|
m_pInterface = new ComKylinBackupManagerInterface("com.kylin.backup", "/", QDBusConnection::systemBus(), this);
|
||||||
|
connect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &SystemRestore::on_checkRestore_end);
|
||||||
|
connect(m_pInterface, &ComKylinBackupManagerInterface::progress, this, &SystemRestore::progress);
|
||||||
|
connect(m_pInterface, &ComKylinBackupManagerInterface::sendRestoreResult, this, &SystemRestore::on_restore_end);
|
||||||
|
|
||||||
|
// 是否已存在备份、还原等操作
|
||||||
|
bool isActive = false;
|
||||||
|
if(int(BackupState::BACKUP_STATE_INIT) != m_pInterface->getBackupState(isActive)){
|
||||||
|
on_checkEnv_end(int(BackupResult::OTHER_BACKUP_OR_RESTORE_RUNNING));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackupWrapper backupWrapper;
|
||||||
|
backupWrapper.m_type = m_isRetainUserData ? BackupType::RESTORE_SYSTEM_WITH_DATA : BackupType::RESTORE_SYSTEM;
|
||||||
|
backupWrapper.m_iPosition = m_devPath.isEmpty() ? BackupPosition::LOCAL : BackupPosition::UDISK;
|
||||||
|
backupWrapper.m_prefixDestPath = m_devPath;
|
||||||
|
backupWrapper.m_isOtherMachine = m_isOtherMachine ? 1 : 0;
|
||||||
|
backupWrapper.m_frontUid = getuid();
|
||||||
|
backupWrapper.m_gid = getgid();
|
||||||
|
m_pInterface->goRestore(backupWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 系统还原校验结果处理
|
||||||
|
* @param result
|
||||||
|
*/
|
||||||
|
void SystemRestore::on_checkRestore_end(int result)
|
||||||
|
{
|
||||||
|
bool bRst = false;
|
||||||
|
QString errMsg, errTip;
|
||||||
|
switch (result) {
|
||||||
|
case int(BackupResult::LOCK_PROGRAM_FAIL):
|
||||||
|
// 程序锁定失败,请重试
|
||||||
|
errMsg = tr("Program lock failed, please retry");
|
||||||
|
// 可能有其它备份/还原等任务在执行
|
||||||
|
errTip = tr("There may be other backups or restores being performed");
|
||||||
|
break;
|
||||||
|
case int(BackupResult::NO_FOUND_DEALCLASS):
|
||||||
|
// 不支持的任务类型
|
||||||
|
errMsg = tr("Unsupported task type");
|
||||||
|
// 没有找到相应的处理逻辑
|
||||||
|
errTip = tr("No processing logic was found in the service");
|
||||||
|
break;
|
||||||
|
case int(BackupResult::WRITE_BACKUP_PATHS_TO_USER_FAILED):
|
||||||
|
// ".user.txt文件不存在"
|
||||||
|
errMsg = tr("The .user.txt file is not exists");
|
||||||
|
// 备份点可能被损坏
|
||||||
|
errTip = tr("Backup points may be corrupted");
|
||||||
|
break;
|
||||||
|
case int(BackupResult::WRITE_EXCLUDE_BACKUP_PATHS_TO_USER_FAILED):
|
||||||
|
// .exclude.user.txt文件不存在
|
||||||
|
errMsg = tr("The .exclude.user.txt file is not exists");
|
||||||
|
// 备份点可能被损坏
|
||||||
|
errTip = tr("Backup points may be corrupted");
|
||||||
|
break;
|
||||||
|
case int(BackupResult::INC_NOT_FOUND_DIR):
|
||||||
|
// 备份点数据目录不存在
|
||||||
|
errMsg = tr("The backup point data directory does not exist");
|
||||||
|
// 备份点可能被损坏
|
||||||
|
errTip = tr("Backup points may be corrupted");
|
||||||
|
break;
|
||||||
|
case int(BackupResult::EFI_RSYNC_FAIL):
|
||||||
|
// 同步/boot/efi失败
|
||||||
|
errMsg = tr("Failed to rsync /boot/efi");
|
||||||
|
// 请检查/boot/efi分区挂载方式
|
||||||
|
errTip = tr("Check the mounting mode of the /boot/efi partition");
|
||||||
|
break;
|
||||||
|
case int(BackupResult::RESTOREDIR_PREPARE_FAILED):
|
||||||
|
// 还原目录准备失败
|
||||||
|
errMsg = tr("Failed to prepare the restore directory");
|
||||||
|
// 更多信息请参考日志/var/log/backup.log
|
||||||
|
errTip = tr("Refer to log :/var/log/backup.log for more information");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bRst = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bRst) {
|
||||||
|
GlobelBackupInfo::inst().setIsBusy(false);
|
||||||
|
m_systemRestoreState = SystemRestoreState::IDEL;
|
||||||
|
this->on_next_clicked(true);
|
||||||
|
emit this->checkRestoreResult(bRst, errMsg, errTip);
|
||||||
|
disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &SystemRestore::on_checkRestore_end);
|
||||||
|
disconnect(m_pInterface, &ComKylinBackupManagerInterface::progress, this, &SystemRestore::progress);
|
||||||
|
disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendRestoreResult, this, &SystemRestore::on_restore_end);
|
||||||
|
delete m_pInterface;
|
||||||
|
m_pInterface = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 系统还原结束
|
||||||
|
* @param result-false 失败; true 成功
|
||||||
|
*/
|
||||||
|
void SystemRestore::on_restore_end(bool result)
|
||||||
|
{
|
||||||
|
m_systemRestoreState = SystemRestoreState::IDEL;
|
||||||
|
|
||||||
|
this->on_next_clicked(true);
|
||||||
|
if (result) {
|
||||||
|
emit checkRestoreResult(result);
|
||||||
|
} else {
|
||||||
|
// 还原过程中出现错误
|
||||||
|
QString errMsg = tr("An error occurred during restore");
|
||||||
|
// 错误信息参考日志文件:/var/log/backup.log
|
||||||
|
QString errTip = tr("Error messages refer to log file : /var/log/backup.log");
|
||||||
|
emit checkRestoreResult(result, errMsg, errTip);
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobelBackupInfo::inst().setIsBusy(false);
|
||||||
|
disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &SystemRestore::on_checkRestore_end);
|
||||||
|
disconnect(m_pInterface, &ComKylinBackupManagerInterface::progress, this, &SystemRestore::progress);
|
||||||
|
disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendRestoreResult, this, &SystemRestore::on_restore_end);
|
||||||
|
delete m_pInterface;
|
||||||
|
m_pInterface = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化最后一页
|
||||||
|
*/
|
||||||
|
void SystemRestore::initLastWidget()
|
||||||
|
{
|
||||||
|
QWidget *last = new QWidget;
|
||||||
|
|
||||||
|
// 流程进度提示栏
|
||||||
|
CircleLable *one = new CircleLable("1", last, 24, QColor(COLOR_BLUE));
|
||||||
|
LineLabel *line1 = new LineLabel(last, QColor(COLOR_BLUE), QSize(200, 24));
|
||||||
|
CircleLable *two = new CircleLable("2", last, 24, QColor(COLOR_BLUE));
|
||||||
|
LineLabel *line2 = new LineLabel(last, QColor(COLOR_GRAY), QSize(200, 24));
|
||||||
|
CircleLable *three = new CircleLable("3", last, 24, QColor(COLOR_BLUE));
|
||||||
|
QHBoxLayout *layoutLine1 = new QHBoxLayout;
|
||||||
|
layoutLine1->addStretch();
|
||||||
|
layoutLine1->addWidget(one);
|
||||||
|
layoutLine1->addWidget(line1);
|
||||||
|
layoutLine1->addWidget(two);
|
||||||
|
layoutLine1->addWidget(line2);
|
||||||
|
layoutLine1->addWidget(three);
|
||||||
|
layoutLine1->addStretch();
|
||||||
|
|
||||||
|
MyLabel *label1 = new MyLabel(tr("checking"), last);
|
||||||
|
label1->setIsOriginal(true);
|
||||||
|
label1->setFontColor(QColor(COLOR_BLUE));
|
||||||
|
MyLabel *label2 = new MyLabel(tr("restoring"), last);
|
||||||
|
label2->setIsOriginal(true);
|
||||||
|
label2->setFontColor(QColor(COLOR_BLUE));
|
||||||
|
MyLabel *label3 = new MyLabel(tr("finished"), last);
|
||||||
|
label3->setIsOriginal(true);
|
||||||
|
label3->setFontColor(QColor(COLOR_BLUE));
|
||||||
|
QHBoxLayout *layoutLine2 = new QHBoxLayout;
|
||||||
|
layoutLine2->addSpacing(100);
|
||||||
|
layoutLine2->addWidget(label1);
|
||||||
|
layoutLine2->addStretch();
|
||||||
|
layoutLine2->addWidget(label2);
|
||||||
|
layoutLine2->addStretch();
|
||||||
|
layoutLine2->addWidget(label3);
|
||||||
|
layoutLine2->addSpacing(100);
|
||||||
|
|
||||||
|
// ------------ 中部布局begin-------------
|
||||||
|
QWidget *centerFont = new QWidget(last);
|
||||||
|
QVBoxLayout *vlayoutCenterFont = new QVBoxLayout;
|
||||||
|
|
||||||
|
// 中部第一行
|
||||||
|
QHBoxLayout *hlayoutCenterFont1 = new QHBoxLayout;
|
||||||
|
// 备份结果对错图标
|
||||||
|
QLabel *resultLogo = new QLabel(centerFont);
|
||||||
|
resultLogo->setFixedSize(20,20);
|
||||||
|
hlayoutCenterFont1->addWidget(resultLogo);
|
||||||
|
// 检测中大标题
|
||||||
|
MyLabel *bigTitle = new MyLabel(centerFont);
|
||||||
|
bigTitle->setFontSize(24);
|
||||||
|
bigTitle->setMaximumWidth(700);
|
||||||
|
hlayoutCenterFont1->addWidget(bigTitle);
|
||||||
|
hlayoutCenterFont1->addStretch();
|
||||||
|
vlayoutCenterFont->addLayout(hlayoutCenterFont1);
|
||||||
|
|
||||||
|
// 第二行
|
||||||
|
QHBoxLayout *hlayoutCenterFont2 = new QHBoxLayout;
|
||||||
|
hlayoutCenterFont2->addSpacing(10);
|
||||||
|
// 备份结果错误提示:黑点和文字
|
||||||
|
CircleLable *dot1 = new CircleLable(QString(""), centerFont, 6, Qt::black);
|
||||||
|
hlayoutCenterFont2->addWidget(dot1);
|
||||||
|
hlayoutCenterFont2->addSpacing(5);
|
||||||
|
MyLabel *labelError1 = new MyLabel(centerFont);
|
||||||
|
labelError1->setMinimumWidth(400);
|
||||||
|
labelError1->setMaximumWidth(600);
|
||||||
|
labelError1->setIsOriginal(true);
|
||||||
|
labelError1->setWordWrap(true);
|
||||||
|
labelError1->adjustSize();
|
||||||
|
hlayoutCenterFont2->addWidget(labelError1);
|
||||||
|
hlayoutCenterFont2->addStretch();
|
||||||
|
vlayoutCenterFont->addLayout(hlayoutCenterFont2);
|
||||||
|
|
||||||
|
// 第三行
|
||||||
|
QHBoxLayout *hlayoutCenterFont3 = new QHBoxLayout;
|
||||||
|
hlayoutCenterFont3->addSpacing(10);
|
||||||
|
// 检测中的记录:黑点2和文字2
|
||||||
|
CircleLable *dot2 = new CircleLable(QString(""), centerFont, 6, Qt::black);
|
||||||
|
hlayoutCenterFont3->addWidget(dot2);
|
||||||
|
hlayoutCenterFont3->addSpacing(5);
|
||||||
|
MyLabel *labelError2 = new MyLabel(centerFont);
|
||||||
|
//labelError2->setMinimumWidth(400);
|
||||||
|
//labelError2->setMaximumWidth(600);
|
||||||
|
labelError2->setIsOriginal(true);
|
||||||
|
labelError2->setWordWrap(true);
|
||||||
|
labelError2->adjustSize();
|
||||||
|
hlayoutCenterFont3->addWidget(labelError2);
|
||||||
|
hlayoutCenterFont3->addStretch();
|
||||||
|
vlayoutCenterFont->addLayout(hlayoutCenterFont3);
|
||||||
|
|
||||||
|
// 第四行
|
||||||
|
vlayoutCenterFont->addSpacing(30);
|
||||||
|
|
||||||
|
// 第五行
|
||||||
|
QHBoxLayout *hlayoutCenterFont5 = new QHBoxLayout;
|
||||||
|
hlayoutCenterFont5->addSpacing(100);
|
||||||
|
// 再试一次
|
||||||
|
MyPushButton *retry = new MyPushButton(centerFont);
|
||||||
|
retry->setFixedSize(97, 36);
|
||||||
|
retry->setText(tr("retry"));
|
||||||
|
retry->setEnabled(true);
|
||||||
|
retry->setAutoRepeat(true);
|
||||||
|
hlayoutCenterFont5->addWidget(retry);
|
||||||
|
hlayoutCenterFont5->addStretch();
|
||||||
|
vlayoutCenterFont->addLayout(hlayoutCenterFont5);
|
||||||
|
|
||||||
|
vlayoutCenterFont->addStretch();
|
||||||
|
centerFont->setLayout(vlayoutCenterFont);
|
||||||
|
// ------------ 中部布局end-------------
|
||||||
|
|
||||||
|
QHBoxLayout *layoutLine3 = new QHBoxLayout;
|
||||||
|
layoutLine3->addStretch();
|
||||||
|
layoutLine3->addWidget(centerFont);
|
||||||
|
layoutLine3->addStretch();
|
||||||
|
|
||||||
|
// 布局
|
||||||
|
QVBoxLayout *vlayout = new QVBoxLayout;
|
||||||
|
vlayout->addSpacing(40);
|
||||||
|
vlayout->addLayout(layoutLine1);
|
||||||
|
vlayout->addLayout(layoutLine2);
|
||||||
|
vlayout->addSpacing(50);
|
||||||
|
vlayout->addLayout(layoutLine3);
|
||||||
|
vlayout->addStretch();
|
||||||
|
last->setLayout(vlayout);
|
||||||
|
|
||||||
|
// 还原检测结果
|
||||||
|
connect(this, &SystemRestore::checkRestoreResult, this, [=](bool result, const QString &errMsg, const QString &errTip) {
|
||||||
|
if (result) {
|
||||||
|
QIcon icon = QIcon::fromTheme("ukui-dialog-success", QIcon(":/symbos/ukui-dialog-success.png"));
|
||||||
|
resultLogo->setPixmap(icon.pixmap(QSize(20,20)));
|
||||||
|
resultLogo->setVisible(true);
|
||||||
|
// 系统还原成功
|
||||||
|
bigTitle->setDeplayText(tr("Successfully restoring the system"));
|
||||||
|
dot1->setVisible(true);
|
||||||
|
dot2->setVisible(false);
|
||||||
|
labelError1->setVisible(true);
|
||||||
|
// 系统将自动重启
|
||||||
|
labelError1->setDeplayText(tr("The system will automatically reboot"));
|
||||||
|
labelError2->setVisible(false);
|
||||||
|
retry->setVisible(false);
|
||||||
|
} else {
|
||||||
|
QIcon icon = QIcon::fromTheme("dialog-error.png", QIcon(":/symbos/dialog-error.png"));
|
||||||
|
resultLogo->setPixmap(icon.pixmap(QSize(20,20)));
|
||||||
|
resultLogo->setVisible(true);
|
||||||
|
// 系统还原失败
|
||||||
|
bigTitle->setDeplayText(tr("Restoring the system failed"));
|
||||||
|
dot1->setVisible(true);
|
||||||
|
dot2->setVisible(true);
|
||||||
|
labelError1->setDeplayText(errMsg);
|
||||||
|
labelError2->setDeplayText(errTip);
|
||||||
|
retry->setVisible(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 再试一次
|
||||||
|
connect(retry, &MyPushButton::clicked, this, [=](bool checked) {
|
||||||
|
Q_UNUSED(checked)
|
||||||
|
this->setCurrentIndex(SystemRestorePage::RESTORE_PAGE);
|
||||||
|
this->startRestore();
|
||||||
|
});
|
||||||
|
|
||||||
|
addWidget(last);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,14 +13,14 @@ public:
|
||||||
{
|
{
|
||||||
IDEL = 0, // 空闲
|
IDEL = 0, // 空闲
|
||||||
CHECKING, // 环境校验中
|
CHECKING, // 环境校验中
|
||||||
BACKUPING // 备份中
|
RESTORING // 还原中
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SystemRestorePage
|
enum SystemRestorePage
|
||||||
{
|
{
|
||||||
HOME_PAGE, // 首页
|
HOME_PAGE, // 首页
|
||||||
CHECK_ENV_PAGE, // 环境检测页
|
CHECK_ENV_PAGE, // 环境检测页
|
||||||
BACKUP_PAGE, // 还原中页
|
RESTORE_PAGE, // 还原中页
|
||||||
LAST_PAGE, // 结束页
|
LAST_PAGE, // 结束页
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,10 +31,15 @@ public:
|
||||||
private:
|
private:
|
||||||
void initFirstWidget();
|
void initFirstWidget();
|
||||||
void initSecondWidget();
|
void initSecondWidget();
|
||||||
|
void initThirdWidget();
|
||||||
|
void initLastWidget();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void startCheckEnv();
|
void startCheckEnv();
|
||||||
void checkEnvResult(bool result, const QString &errMsg = "", const QString &errTip = "");
|
void checkEnvResult(bool result, const QString &errMsg = "", const QString &errTip = "");
|
||||||
|
void startRestore();
|
||||||
|
void progress(int state, int rate);
|
||||||
|
void checkRestoreResult(bool result, const QString &errMsg = "", const QString &errTip = "");
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void on_pre_clicked(bool checked = false);
|
void on_pre_clicked(bool checked = false);
|
||||||
|
@ -42,6 +47,9 @@ public slots:
|
||||||
void on_button_beginRestore_clicked(bool checked = false);
|
void on_button_beginRestore_clicked(bool checked = false);
|
||||||
void on_checkEnv_start();
|
void on_checkEnv_start();
|
||||||
void on_checkEnv_end(int result);
|
void on_checkEnv_end(int result);
|
||||||
|
void on_restore_start();
|
||||||
|
void on_checkRestore_end(int result);
|
||||||
|
void on_restore_end(bool result);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// 是否保留用户数据
|
// 是否保留用户数据
|
||||||
|
@ -54,7 +62,7 @@ private:
|
||||||
|
|
||||||
QString m_uuid; // 还原点的UUID
|
QString m_uuid; // 还原点的UUID
|
||||||
QString m_devPath; // 如果是从移动设备进行还原,此中保存移动设备挂载路径
|
QString m_devPath; // 如果是从移动设备进行还原,此中保存移动设备挂载路径
|
||||||
bool m_isOtherMachine;
|
bool m_isOtherMachine; // 是否异机备份点还原
|
||||||
// 系统备份状态
|
// 系统备份状态
|
||||||
int m_systemRestoreState;
|
int m_systemRestoreState;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue