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