Blob Blame History Raw
From 6ca072af941cd6f1fd2a094b2daa17219c9adc96 Mon Sep 17 00:00:00 2001
From: Jonathan Lebon <jlebon@redhat.com>
Date: Thu, 3 Aug 2017 06:41:18 -0700
Subject: [PATCH] rollback: allow users to undo a rollback

The new API to find pending and rollback deployments do so relative to
the booted deployment. This caused an interesting behaviour: the first
time a user uses "rpm-ostree rollback", it would (as expected) move the
previous deployment first. but the second call to "rpm-ostree rollback"
would fail since there were now no more rollback deployments.

We fine tune the logic here to allow this, as well as the more general
case of putting the booted deployment back on top.

This fixes a subtle regression from b7cf58e
(https://github.com/projectatomic/rpm-ostree/pull/767).

Closes: https://github.com/projectatomic/rpm-ostree/issues/906

Closes: #907
Approved by: cgwalters
---
 src/daemon/rpmostreed-transaction-types.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/src/daemon/rpmostreed-transaction-types.c b/src/daemon/rpmostreed-transaction-types.c
index 9f614e4..067adbf 100644
--- a/src/daemon/rpmostreed-transaction-types.c
+++ b/src/daemon/rpmostreed-transaction-types.c
@@ -322,11 +322,22 @@ rollback_transaction_execute (RpmostreedTransaction *transaction,
 {
   RollbackTransaction *self = (RollbackTransaction *) transaction;
   OstreeSysroot *sysroot = rpmostreed_transaction_get_sysroot (transaction);
+  OstreeDeployment *booted_deployment = ostree_sysroot_get_booted_deployment (sysroot);
 
+  g_autoptr(OstreeDeployment) pending_deployment = NULL;
   g_autoptr(OstreeDeployment) rollback_deployment = NULL;
-  rpmostree_syscore_query_deployments (sysroot, self->osname, NULL, &rollback_deployment);
-  if (!rollback_deployment)
+  rpmostree_syscore_query_deployments (sysroot, self->osname,
+                                       &pending_deployment, &rollback_deployment);
+
+  if (!rollback_deployment && !pending_deployment) /* i.e. do we just have 1 deployment? */
     return glnx_throw (error, "No rollback deployment found");
+  else if (!rollback_deployment)
+    {
+      /* If there isn't a rollback deployment, but there *is* a pending deployment, then we
+       * want "rpm-ostree rollback" to put the currently booted deployment back on top. This
+       * also allows users to effectively undo a rollback operation. */
+      rollback_deployment = g_object_ref (booted_deployment);
+    }
 
   g_autoptr(GPtrArray) old_deployments =
     ostree_sysroot_get_deployments (sysroot);
@@ -344,7 +355,7 @@ rollback_transaction_execute (RpmostreedTransaction *transaction,
   for (guint i = 0; i < old_deployments->len; i++)
     {
       OstreeDeployment *deployment = old_deployments->pdata[i];
-      if (deployment != rollback_deployment)
+      if (!ostree_deployment_equal (deployment, rollback_deployment))
         g_ptr_array_add (new_deployments, g_object_ref (deployment));
     }
 
-- 
2.14.0