diff --git a/src/bin/patchmanager-daemon/dbus/org.SfietKonstantin.patchmanager.xml b/src/bin/patchmanager-daemon/dbus/org.SfietKonstantin.patchmanager.xml index ae7e5b198..a220ac7e7 100644 --- a/src/bin/patchmanager-daemon/dbus/org.SfietKonstantin.patchmanager.xml +++ b/src/bin/patchmanager-daemon/dbus/org.SfietKonstantin.patchmanager.xml @@ -107,6 +107,12 @@ + + + + + + diff --git a/src/bin/patchmanager-daemon/main.cpp b/src/bin/patchmanager-daemon/main.cpp index 8176d7689..73a954af4 100644 --- a/src/bin/patchmanager-daemon/main.cpp +++ b/src/bin/patchmanager-daemon/main.cpp @@ -57,11 +57,13 @@ void help() { std::cout << "Patchmanager " << BUILD_VERSION << std::endl; std::cout << "Usage:" << std::endl; - std::cout << " patchmanager [--help] : Print this help text" << std::endl; - std::cout << " patchmanager -a : Enable and activate a Patch" << std::endl; - std::cout << " patchmanager -u : Deactivate and disable (unapply) a Patch" << std::endl; - std::cout << " patchmanager --unapply-all : Deactivate and disable (unapply) all Patches" << std::endl; - std::cout << " patchmanager --daemon : Start Patchmanager as daemon" << std::endl; + std::cout << " patchmanager [--help] : Print this help text" << std::endl; + std::cout << " patchmanager -a : Enable and activate a Patch" << std::endl; + std::cout << " patchmanager -u : Deactivate and disable (unapply) a Patch" << std::endl; + std::cout << " patchmanager --unapply-all : Deactivate and disable (unapply) all Patches" << std::endl; + std::cout << " patchmanager --save-as-good : Save list of enabled Patches as 'known good'" << std::endl; + std::cout << " patchmanager --load-known-good : Enable 'known good' Patches" << std::endl; + std::cout << " patchmanager --daemon : Start Patchmanager as daemon" << std::endl; } int main(int argc, char **argv) diff --git a/src/bin/patchmanager-daemon/patchmanagerobject.cpp b/src/bin/patchmanager-daemon/patchmanagerobject.cpp index 530754a5f..eebdf4f30 100644 --- a/src/bin/patchmanager-daemon/patchmanagerobject.cpp +++ b/src/bin/patchmanager-daemon/patchmanagerobject.cpp @@ -359,6 +359,21 @@ void PatchManagerObject::setAppliedPatches(const QSet &patches) putSettings(QStringLiteral("applied"), QStringList(patches.toList())); } +QSet PatchManagerObject::getLastGoodPatches() const +{ + return getSettings(QStringLiteral("lastknowngood"), QStringList()).toStringList().toSet(); +} + +void PatchManagerObject::setLastGoodPatches(const QSet &patches) +{ + putSettings(QStringLiteral("lastknowngood"), QStringList(patches.toList())); +} + +void PatchManagerObject::setKnownGood() +{ + setLastGoodPatches(getAppliedPatches()); +} + QStringList PatchManagerObject::getMangleCandidates() { if (m_mangleCandidates.empty()) { @@ -592,6 +607,10 @@ void PatchManagerObject::doPrepareCacheRoot() emit m_adaptor->autoApplyingFinished(success); } + if (success) { + setLastGoodPatches(m_appliedPatches); + } + if (!success) { setAppliedPatches(m_appliedPatches); refreshPatchList(); @@ -1113,6 +1132,10 @@ void PatchManagerObject::process() } } else if (args[1] == QStringLiteral("--unapply-all")) { method = QStringLiteral("unapplyAllPatches"); + } else if (args[1] == QStringLiteral("--save-as-good")) { + method = QStringLiteral("setKnownGood"); + } else if (args[1] == QStringLiteral("--load-known-good")) { + method = QStringLiteral("revertToLastGood"); } else { return; } @@ -1562,20 +1585,30 @@ bool PatchManagerObject::getToggleServices() const /*! Returns the internal failure state. */ bool PatchManagerObject::getFailure() const { - return m_failed; + return m_failed; } /*! Returns the internal state whether the server thread is running. */ bool PatchManagerObject::getLoaded() const { - return m_serverThread->isRunning(); + return m_serverThread->isRunning(); } /*! - Reset internal failure state and re-initialize. + Reset internal failure state and re-initialize. + + \sa loadRequest() + */ +void PatchManagerObject::revertToLastGood() +{ + QSet patches = getLastGoodPatches(); + if (!patches.empty()) { + m_appliedPatches = patches; + setAppliedPatches(patches); + refreshPatchList(); + } +} - \sa loadRequest() -*/ void PatchManagerObject::resolveFailure() { qDebug() << Q_FUNC_INFO; diff --git a/src/bin/patchmanager-daemon/patchmanagerobject.h b/src/bin/patchmanager-daemon/patchmanagerobject.h index 7f262f4d9..71ccaa1d2 100644 --- a/src/bin/patchmanager-daemon/patchmanagerobject.h +++ b/src/bin/patchmanager-daemon/patchmanagerobject.h @@ -129,6 +129,7 @@ public slots: bool getFailure() const; bool getLoaded() const; void resolveFailure(); + void revertToLastGood(); void loadRequest(bool apply); void lipstickChanged(const QString &state); @@ -216,6 +217,10 @@ private slots: QSet getAppliedPatches() const; void setAppliedPatches(const QSet &patches); + QSet getLastGoodPatches() const; + void setLastGoodPatches(const QSet &patches); + void setKnownGood(); + void getVersion(); void lateInitialize(); diff --git a/src/qml/PatchManagerPage.qml b/src/qml/PatchManagerPage.qml index b0ed4ae69..25826184e 100644 --- a/src/qml/PatchManagerPage.qml +++ b/src/qml/PatchManagerPage.qml @@ -238,6 +238,12 @@ Page { onClicked: pageStack.push(Qt.resolvedUrl("RestartServicesDialog.qml")) } + MenuItem { + text: qsTranslate("", "Load Pre-Failure List") + visible: PatchManager.failure + onClicked: menuRemorse.execute( text, function() { PatchManager.call(PatchManager.revertToLastGood()) } ) + } + MenuItem { text: qsTranslate("", "Resolve failure") visible: PatchManager.failure diff --git a/src/qml/patchmanager.cpp b/src/qml/patchmanager.cpp index e34dea1f3..fe6ca0162 100644 --- a/src/qml/patchmanager.cpp +++ b/src/qml/patchmanager.cpp @@ -815,6 +815,20 @@ void PatchManager::onLoadedChanged(bool loaded) } /*! Calls the \e resolveFailure method on D-Bus */ +void PatchManager::revertToLastGood() +{ + qDebug() << Q_FUNC_INFO; + + m_interface->revertToLastGood(); +} + +void PatchManager::setKnownGood() +{ + qDebug() << Q_FUNC_INFO; + + m_interface->setKnownGood(); +} + void PatchManager::resolveFailure() { qDebug() << Q_FUNC_INFO; diff --git a/src/qml/patchmanager.h b/src/qml/patchmanager.h index e980a67dc..052197781 100644 --- a/src/qml/patchmanager.h +++ b/src/qml/patchmanager.h @@ -182,6 +182,8 @@ public slots: void onFailureChanged(bool failed); void onLoadedChanged(bool loaded); + void setKnownGood(); + void revertToLastGood(); void resolveFailure(); signals: diff --git a/src/tools/patchmanager-tool b/src/tools/patchmanager-tool index 35c1236f1..40113862d 100644 --- a/src/tools/patchmanager-tool +++ b/src/tools/patchmanager-tool @@ -23,6 +23,8 @@ function usage() { printf "\t-A | --activate-all\t\tActivate / apply all Patches formerly marked as active.\n" printf "\t-d | --deactivate\t\tDeactivate / unapply Patches from list or file (via -f).\n" printf "\t-D | --deactivate-all\t\tDeactivate / unapply all Patches.\n" + printf "\t-S | --save-as-good\t\tSave list of enabled Patches as 'known good'\n" + printf "\t-G | --load-known-good\t\tEnable 'known good' Patches\n" printf "\t-f | --file \t\tUse for the list of Patches.\n" printf "\t-e | --export\t\t\tExport list of Patches marked as active either to STDout or (via -f) to a file.\n" printf "\t-h | --help\t\t\tPrint this help.\n" @@ -93,6 +95,16 @@ case "$1" in shift surplus "$*" ;; + -S|--save-as-good) + operation="--save-as-good" + shift + surplus "$*" + ;; + -G|--load-known-good) + operation="--load-known-good" + shift + surplus "$*" + ;; --reset-system) operation="--reset-system" shift