Sophie

Sophie

distrib > Mageia > 6 > x86_64 > by-pkgid > 76e57234f785767ea525881b86cab675 > files > 1

dnf-plugins-extras-2.0.1-1.1.mga6.src.rpm

From a6d9bc41a2ec8ef189efdc05fbd1e95dc16fa7fe Mon Sep 17 00:00:00 2001
From: Jaroslav Rohel <jrohel@redhat.com>
Date: Fri, 9 Jun 2017 12:02:56 +0200
Subject: [PATCH] snapper: Create pair of snapshots (RhBug:1248806)

Creates pair of snapshot - before and after transaction run.
Previously only one snapshot after transaction was created.
This was unusable for recovery from failed transaction.
---
 doc/snapper.rst    |  6 +++++-
 plugins/snapper.py | 46 +++++++++++++++++++++++++++++++++++++---------
 2 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/doc/snapper.rst b/doc/snapper.rst
index 8432c95..a73c019 100644
--- a/doc/snapper.rst
+++ b/doc/snapper.rst
@@ -1,5 +1,6 @@
 ..
   Copyright (C) 2014 Igor Gnatenko
+  Copyright (C) 2017 Red Hat
 
   This copyrighted material is made available to anyone wishing to use,
   modify, copy, or redistribute it subject to the terms and conditions of
@@ -20,4 +21,7 @@
 DNF snapper Plugin
 ==================
 
-Generates snapshots of root filesystem after transactions. The user is not supposed to interact with the plugin in any way.
+Creates a pair of snapshots of root filesystem. One snapshot is created just before the transaction run (Pre). This means after a successful transaction check and successful transaction test. And another snapshot is created when the transaction has finished (Post).
+The user is not supposed to interact with the plugin in any way.
+
+.. warning:: There is no mechanism to ensure data consistency during creating a snapshot. Files which are written at the same time as snapshot is created (eg. database files) can be corrupted or partialy written in snapshot. Restoring such files will cause problems. Moreover, some system files must never be restored. Recomended is only restore files that belong to the action you want to revert.
diff --git a/plugins/snapper.py b/plugins/snapper.py
index b2c1156..bc929b7 100644
--- a/plugins/snapper.py
+++ b/plugins/snapper.py
@@ -1,6 +1,7 @@
 # creates snapshots via 'snapper'.
 #
 # Copyright (C) 2014 Igor Gnatenko
+# Copyright (C) 2017 Red Hat
 #
 # This copyrighted material is made available to anyone wishing to use,
 # modify, copy, or redistribute it subject to the terms and conditions of
@@ -25,37 +26,64 @@ import sys
 _ = dnfpluginsextras._
 logger = dnfpluginsextras.logger
 
+
 class Snapper(dnf.Plugin):
     name = 'snapper'
 
     def __init__(self, base, cli):
         self.base = base
         self.description = " ".join(sys.argv)
+        self._pre_snap_created = False
+        self._snapper = None
+        self._pre_snap_number = None
 
-    def transaction(self):
+    def pre_transaction(self):
         if not len(self.base.transaction):
             return
 
         try:
             bus = SystemBus()
-            snapper = Interface(bus.get_object('org.opensuse.Snapper',
-                                               '/org/opensuse/Snapper'),
-                                dbus_interface='org.opensuse.Snapper')
+            self._snapper = Interface(bus.get_object('org.opensuse.Snapper',
+                                      '/org/opensuse/Snapper'),
+                                      dbus_interface='org.opensuse.Snapper')
         except DBusException as e:
             logger.critical(
                 "snapper: " + _("connect to snapperd failed: %s"), e
             )
             return
+
+        try:
+            logger.debug(
+                "snapper: " + _("creating pre_snapshot")
+            )
+            self._pre_snap_number = self._snapper.CreatePreSnapshot("root", self.description,
+                                                                    "number", {})
+            self._pre_snap_created = True
+            logger.debug(
+                "snapper: " + _("created pre_snapshot %d"), self._pre_snap_number
+            )
+        except DBusException as e:
+            logger.critical(
+                "snapper: " + _("creating pre_snapshot failed: %s"), e
+            )
+
+    def transaction(self):
+        if not self._pre_snap_created:
+            logger.debug(
+                "snapper: " + _("skipping post_snapshot because creation of pre_snapshot failed")
+            )
+            return
+
         try:
             logger.debug(
-                "snapper: " + _("creating snapshot")
+                "snapper: " + _("creating post_snapshot")
             )
-            snap = snapper.CreateSingleSnapshot("root", self.description,
-                                                "number", {})
+            snap_post_number = self._snapper.CreatePostSnapshot("root", self._pre_snap_number,
+                                                                self.description, "number", {})
             logger.debug(
-                "snapper: " + _("created snapshot %d"), snap
+                "snapper: " + _("created post_snapshot %d"), snap_post_number
             )
         except DBusException as e:
             logger.critical(
-                "snapper: " + _("creating snapshot failed: %s"), e
+                "snapper: " + _("creating post_snapshot failed: %s"), e
             )
-- 
2.13.2