[Yum-devel] [PATCH 3/3] Add history rollback command.

James Antill james at and.org
Thu Apr 21 20:28:31 UTC 2011


---
 docs/yum.8     |   15 ++++++++++-----
 yumcommands.py |   49 ++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 56 insertions(+), 8 deletions(-)

diff --git a/docs/yum.8 b/docs/yum.8
index 522f15f..ede03b9 100644
--- a/docs/yum.8
+++ b/docs/yum.8
@@ -77,7 +77,7 @@ gnome\-packagekit application\&.
 .br
 .I \fR * version [ all | installed | available | group-* | nogroups* | grouplist | groupinfo ]
 .br
-.I \fR * history [info|list|packages-list|summary|redo|undo|new|addon-info] 
+.I \fR * history [info|list|packages-list|summary|addon-info|redo|undo|rollback|new] 
 .br
 .I \fR * check
 .br 
@@ -331,16 +331,21 @@ and so takes sub-commands:
 .IP "\fBhistory\fP"
 The history command allows the user to view what has happened in past
 transactions (assuming the history_record config. option is set). You can use
-info/list/summary to view what happened, undo/redo to act on that information
-and new to start a new history file.
+info/list/packages-list/summary to view what happened, undo/redo/rollback to act
+on that information and new to start a new history file.
 
 The info/list/summary commands take either a transaction id or a package (with
 wildcards, as in \fBSpecifying package names\fP), all three can also be passed
 no arguments. list can be passed the keyword "all" to list all the transactions.
 
-The undo/redo commands take either a transaction id or the keyword last and
-an offset from the last transaction (Eg. if you've done 250 transactions,
+The packages-list command takes a package  (with wildcards, as in
+\fBSpecifying package names\fP).
+
+The undo/redo/rollback commands take either a transaction id or the keyword last
+and an offset from the last transaction (Eg. if you've done 250 transactions,
 "last" refers to transaction 250, and "last-4" refers to transaction 246).
+The undo/redo commands will act on the specified transaction, while the rollback
+command will undo all transactions upto the point of the specified transaction.
 
 The addon-info command takes a transaction ID, and the packages-list command
 takes a package (with wildcards).
diff --git a/yumcommands.py b/yumcommands.py
index d3014c5..74a1f00 100644
--- a/yumcommands.py
+++ b/yumcommands.py
@@ -1350,7 +1350,7 @@ class HistoryCommand(YumCommand):
         return ['history']
 
     def getUsage(self):
-        return "[info|list|summary|addon-info|package-list|redo|undo|new]"
+        return "[info|list|packages-list|summary|addon-info|redo|undo|rollback|new]"
 
     def getSummary(self):
         return _("Display, or use, the transaction history")
@@ -1375,11 +1375,52 @@ class HistoryCommand(YumCommand):
         if base.history_undo(old):
             return 2, ["Undoing transaction %u" % (old.tid,)]
 
+    def _hcmd_rollback(self, base, extcmds):
+        force = False
+        if len(extcmds) > 1 and extcmds[1] == 'force':
+            force = True
+            extcmds = extcmds[:]
+            extcmds.pop(0)
+
+        old = base._history_get_transaction(extcmds)
+        if old is None:
+            return 1, ['Failed history rollback, no transaction']
+        last = base.history.last()
+        if last is None:
+            return 1, ['Failed history rollback, no last?']
+        if old.tid == last.tid:
+            return 0, ['Rollback to current, nothing to do']
+
+        mobj = None
+        for tid in base.history.old(range(old.tid + 1, last.tid + 1)):
+            if not force and (tid.altered_lt_rpmdb or tid.altered_gt_rpmdb):
+                if tid.altered_lt_rpmdb:
+                    msg = "Transaction history is incomplete, before %u."
+                else:
+                    msg = "Transaction history is incomplete, after %u."
+                print msg % tid.tid
+                print " You can use 'history rollback force', to try anyway."
+                return 1, ['Failed history rollback, incomplete']
+
+            if mobj is None:
+                mobj = yum.history.YumMergedHistoryTransaction(tid)
+            else:
+                mobj.merge(tid)
+
+        tm = time.ctime(old.beg_timestamp)
+        print "Rollback to transaction %u, from %s" % (old.tid, tm)
+        print base.fmtKeyValFill("  Undoing the following transactions: ",
+                                 ", ".join((str(x) for x in mobj.tid)))
+        base.historyInfoCmdPkgsAltered(mobj)
+        if base.history_undo(mobj):
+            return 2, ["Rollback to transaction %u" % (old.tid,)]
+
     def _hcmd_new(self, base, extcmds):
         base.history._create_db_file()
 
     def doCheck(self, base, basecmd, extcmds):
         cmds = ('list', 'info', 'summary', 'repeat', 'redo', 'undo', 'new',
+                'rollback',
                 'addon', 'addon-info',
                 'pkg', 'pkgs', 'pkg-list', 'pkgs-list',
                 'package', 'package-list', 'packages', 'packages-list')
@@ -1387,7 +1428,7 @@ class HistoryCommand(YumCommand):
             base.logger.critical(_('Invalid history sub-command, use: %s.'),
                                  ", ".join(cmds))
             raise cli.CliError
-        if extcmds and extcmds[0] in ('repeat', 'redo', 'undo', 'new'):
+        if extcmds and extcmds[0] in ('repeat', 'redo', 'undo', 'rollback', 'new'):
             checkRootUID(base)
             checkGPGKey(base)
         elif not os.access(base.history._db_file, os.R_OK):
@@ -1415,6 +1456,8 @@ class HistoryCommand(YumCommand):
             ret = self._hcmd_undo(base, extcmds)
         elif vcmd in ('redo', 'repeat'):
             ret = self._hcmd_redo(base, extcmds)
+        elif vcmd == 'rollback':
+            ret = self._hcmd_rollback(base, extcmds)
         elif vcmd == 'new':
             ret = self._hcmd_new(base, extcmds)
 
@@ -1426,7 +1469,7 @@ class HistoryCommand(YumCommand):
         vcmd = 'list'
         if extcmds:
             vcmd = extcmds[0]
-        return vcmd in ('repeat', 'redo', 'undo')
+        return vcmd in ('repeat', 'redo', 'undo', 'rollback')
 
 
 class CheckRpmdbCommand(YumCommand):
-- 
1.7.3.4



More information about the Yum-devel mailing list