Blame SOURCES/BZ-1047793-lvm-snapshot.patch

bb45c0
commit 13bbacb4dd25b83cd29389e0608fde1614537257
bb45c0
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
bb45c0
Date:   Mon Jan 12 15:21:46 2015 +0100
bb45c0
bb45c0
     Multiple lvm fixes. BZ 1047793, BZ 1145485
bb45c0
    - add fssnap_abort_on_errors config option
bb45c0
    - fix default for fssnap_automatic_keep in the man page
bb45c0
    - add logging for automatic fssnap events
bb45c0
    - add lvm binary path test to _FSSnap.available
bb45c0
    - check for lvm2 and lvm2-python-libs packages instead of python-lvm
bb45c0
bb45c0
diff --git a/docs/yum.8 b/docs/yum.8
bb45c0
index 998a5ad..a0038f6 100644
bb45c0
--- a/docs/yum.8
bb45c0
+++ b/docs/yum.8
bb45c0
@@ -741,7 +741,7 @@ then you can create and delete snapshots using:
bb45c0
 .br 
bb45c0
 
bb45c0
 .br
bb45c0
-Configuration Options: \fBfssnap_automatic_pre\fP, \fBfssnap_automatic_post\fP, \fBfssnap_automatic_keep\fP, \fBfssnap_percentage\fP, \fBfssnap_devices\fP
bb45c0
+Configuration Options: \fBfssnap_automatic_pre\fP, \fBfssnap_automatic_post\fP, \fBfssnap_automatic_keep\fP, \fBfssnap_percentage\fP, \fBfssnap_devices\fP, \fBfssnap_abort_on_errors\fP
bb45c0
 
bb45c0
 .IP
bb45c0
 .IP "\fBfs\fP"
bb45c0
diff --git a/docs/yum.conf.5 b/docs/yum.conf.5
bb45c0
index 0362e85..272e07b 100644
bb45c0
--- a/docs/yum.conf.5
bb45c0
+++ b/docs/yum.conf.5
bb45c0
@@ -873,7 +873,7 @@ Boolean (1, 0, True, False, yes, no) Defaults to False
bb45c0
 .IP
bb45c0
 \fBfssnap_automatic_keep\fR
bb45c0
 How many old snapshots should yum keep when trying to automatically create a 
bb45c0
-new snapshot. Setting to 0 disables this feature. Default is '0'.
bb45c0
+new snapshot. Setting to 0 disables this feature. Default is '1'.
bb45c0
 
bb45c0
 .IP
bb45c0
 \fBfssnap_automatic_percentage\fR
bb45c0
@@ -887,6 +887,21 @@ first match (positive or negative) wins.
bb45c0
 Default is: !*/swap !*/lv_swap glob:/etc/yum/fssnap.d/*.conf
bb45c0
 
bb45c0
 .IP
bb45c0
+\fBfssnap_abort_on_errors\fR
bb45c0
+When fssnap_automatic_pre or fssnap_automatic_post is enabled, it's possible to specify which
bb45c0
+fssnap errors should make the transaction fail. The default is `any'.
bb45c0
+
bb45c0
+`broken-setup' - Abort current transaction if snapshot support is unavailable because
bb45c0
+lvm is missing or broken.
bb45c0
+
bb45c0
+`snapshot-failure' - Abort current transaction if creating a snapshot fails (e.g. there is not enough
bb45c0
+free space to make a snapshot).
bb45c0
+
bb45c0
+`any' - Abort current transaction if any of the above occurs.
bb45c0
+
bb45c0
+`none' - Never abort a transaction in case of errors.
bb45c0
+
bb45c0
+.IP
bb45c0
 \fBdepsolve_loop_limit\fR
bb45c0
 Set the number of times any attempt to depsolve before we just give up. This
bb45c0
 shouldn't be needed as yum should always solve or fail, however it has been
bb45c0
diff --git a/yum/__init__.py b/yum/__init__.py
bb45c0
index 6d2c078..347aa7c 100644
bb45c0
--- a/yum/__init__.py
bb45c0
+++ b/yum/__init__.py
bb45c0
@@ -1727,6 +1727,13 @@ much more problems).
bb45c0
         :raises: :class:`yum.Errors.YumRPMTransError` if there is a
bb45c0
            transaction cannot be completed
bb45c0
         """
bb45c0
+        if (self.conf.fssnap_automatic_pre or self.conf.fssnap_automatic_post) and not self.fssnap.available:
bb45c0
+            msg = _("Snapshot support not available.")
bb45c0
+            if self.conf.fssnap_abort_on_errors in ('broken-setup', 'any'):
bb45c0
+                raise Errors.YumRPMTransError(msg="Aborting transaction.", errors=msg)
bb45c0
+            else:
bb45c0
+                self.verbose_logger.critical(msg)
bb45c0
+
bb45c0
         if self.fssnap.available and ((self.conf.fssnap_automatic_pre or
bb45c0
                                        self.conf.fssnap_automatic_post) and
bb45c0
                                       self.conf.fssnap_automatic_keep):
bb45c0
@@ -1748,17 +1755,30 @@ much more problems).
bb45c0
                 if num > self.conf.fssnap_automatic_keep:
bb45c0
                     todel.append(snap['dev'])
bb45c0
             # Display something to the user?
bb45c0
-            self.fssnap.del_snapshots(devices=todel)
bb45c0
+            snaps = self.fssnap.del_snapshots(devices=todel)
bb45c0
+            if len(snaps):
bb45c0
+                self.verbose_logger.info(_("Deleted %u snapshots.") % len(snaps))
bb45c0
 
bb45c0
         if (self.fssnap.available and
bb45c0
             (not self.ts.isTsFlagSet(rpm.RPMTRANS_FLAG_TEST) and
bb45c0
             self.conf.fssnap_automatic_pre)):
bb45c0
             if not self.fssnap.has_space(self.conf.fssnap_percentage):
bb45c0
-                msg = _("Not enough space to create pre. FS snapshot, aborting transaction.")
bb45c0
-                raise Errors.YumRPMTransError(msg=msg, errors=[])
bb45c0
+                msg = _("Not enough space to create pre. FS snapshot.")
bb45c0
+                if self.conf.fssnap_abort_on_errors in ('snapshot-failure', 'any'):
bb45c0
+                    raise Errors.YumRPMTransError(msg="Aborting transaction", errors=msg)
bb45c0
+                else:
bb45c0
+                    self.verbose_logger.critical(msg)
bb45c0
             else:
bb45c0
                 tags = {'*': ['reason=automatic']} # FIXME: pre. tags
bb45c0
-                self.fssnap.snapshot(self.conf.fssnap_percentage, tags=tags)
bb45c0
+                snaps = self.fssnap.snapshot(self.conf.fssnap_percentage, tags=tags)
bb45c0
+                if not snaps:
bb45c0
+                    msg = _("Failed to create snapshot")
bb45c0
+                    if self.conf.fssnap_abort_on_errors in ('snapshot-failure', 'any'):
bb45c0
+                        raise Errors.YumRPMTransError(msg="Aborting transaction", errors=msg)
bb45c0
+                    else:
bb45c0
+                        self.verbose_logger.critical(msg)
bb45c0
+                for (odev, ndev) in snaps:
bb45c0
+                    self.verbose_logger.info(_("Created snapshot from %s, results is: %s") % (odev, ndev))
bb45c0
 
bb45c0
         self.plugins.run('pretrans')
bb45c0
 
bb45c0
@@ -1895,11 +1915,14 @@ much more problems).
bb45c0
             self.conf.fssnap_automatic_post)):
bb45c0
             if not self.fssnap.has_space(self.conf.fssnap_percentage):
bb45c0
                 msg = _("Not enough space to create post trans FS snapshot.")
bb45c0
-                self.logger.critical(msg)
bb45c0
+                self.verbose_logger.critical(msg)
bb45c0
             else:
bb45c0
                 tags = {'*': ['reason=automatic']} # FIXME: post tags
bb45c0
-                self.fssnap.snapshot(self.conf.fssnap_percentage, tags=tags)
bb45c0
-
bb45c0
+                snaps = self.fssnap.snapshot(self.conf.fssnap_percentage, tags=tags)
bb45c0
+                if not snaps:
bb45c0
+                    self.verbose_logger.critical(_("Failed to create snapshot"))
bb45c0
+                for (odev, ndev) in snaps:
bb45c0
+                    self.verbose_logger.info(_("Created snapshot from %s, results is: %s") % (odev, ndev))
bb45c0
         return resultobject
bb45c0
 
bb45c0
     def verifyTransaction(self, resultobject=None, txmbr_cb=None):
bb45c0
diff --git a/yum/config.py b/yum/config.py
bb45c0
index 8eab5bc..02061ba 100644
bb45c0
--- a/yum/config.py
bb45c0
+++ b/yum/config.py
bb45c0
@@ -899,6 +899,7 @@ class YumConf(StartupConf):
bb45c0
     fssnap_devices = ListOption("!*/swap !*/lv_swap "
bb45c0
                                 "glob:/etc/yum/fssnap.d/*.conf",
bb45c0
                                 parse_default=True)
bb45c0
+    fssnap_abort_on_errors = SelectionOption('any', ('broken-setup', 'snapshot-failure', 'any', 'none'))
bb45c0
 
bb45c0
     depsolve_loop_limit = PositiveIntOption(100, names_of_0=["<forever>"])
bb45c0
 
bb45c0
diff --git a/yum/fssnapshots.py b/yum/fssnapshots.py
bb45c0
index e912ea1..9af252d 100755
bb45c0
--- a/yum/fssnapshots.py
bb45c0
+++ b/yum/fssnapshots.py
bb45c0
@@ -146,7 +143,8 @@ class _FSSnap(object):
bb45c0
             devices = []
bb45c0
 
bb45c0
         self.version = _ver
bb45c0
-        self.available = bool(lvm)
bb45c0
+        # Parts of the API seem to work even when lvm is not actually installed, hence the path test
bb45c0
+        self.available = bool(lvm and os.path.exists("/sbin/lvm"))
bb45c0
         self.postfix_static = "_yum_"
bb45c0
         self._postfix = None
bb45c0
         self._root = root
bb45c0
diff --git a/yumcommands.py b/yumcommands.py
bb45c0
index a18bc5c..e77d209 100644
bb45c0
--- a/yumcommands.py
bb45c0
+++ b/yumcommands.py
bb45c0
@@ -4264,11 +4264,13 @@ class FSSnapshotCommand(YumCommand):
bb45c0
             subcommand = 'summary'
bb45c0
 
bb45c0
         if not base.fssnap.available:
bb45c0
-            if not base.rpmdb.searchNames(['python-lvm']):
bb45c0
-                print _("Snapshot support not available, no python-lvm package installed.")
bb45c0
-            else:
bb45c0
-                print _("Snapshot support not available, python-lvm is old/broken.")
bb45c0
-            return 0, [basecmd + ' ' + subcommand + ' done']
bb45c0
+            msg = _("Snapshot support not available, please check your lvm installation.")
bb45c0
+            if not base.rpmdb.searchNames(['lvm2']):
bb45c0
+                msg += " " + _("No lvm2 package installed.")
bb45c0
+            if not base.rpmdb.searchNames(['lvm2-python-libs']):
bb45c0
+                msg += " " + _("No lvm2-python-libs package installed.")
bb45c0
+            print msg
bb45c0
+            return 1, [basecmd + ' ' + subcommand + ' done']
bb45c0
 
bb45c0
         if subcommand == 'list':
bb45c0
             snaps = base.fssnap.old_snapshots()
bb45c0
@@ -4301,10 +4303,11 @@ class FSSnapshotCommand(YumCommand):
bb45c0
         if subcommand == 'create':
bb45c0
             tags = {'*': ['reason=manual']}
bb45c0
             pc = base.conf.fssnap_percentage
bb45c0
-            for (odev, ndev) in base.fssnap.snapshot(pc, tags=tags):
bb45c0
-                print _("Created snapshot from %s, results is: %s") %(odev,ndev)
bb45c0
-            else:
bb45c0
+            snaps = base.fssnap.snapshot(pc, tags=tags)
bb45c0
+            if not snaps:
bb45c0
                 print _("Failed to create snapshots")
bb45c0
+            for (odev, ndev) in snaps:
bb45c0
+                print _("Created snapshot from %s, results is: %s") %(odev,ndev)
bb45c0
 
bb45c0
         if subcommand == 'summary':
bb45c0
             snaps = base.fssnap.old_snapshots()
bb45c0
commit 29440b1175411c3ccaca6010df8dec2d96088fbd
bb45c0
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
bb45c0
Date:   Thu Jul 9 15:26:29 2015 +0200
bb45c0
bb45c0
    Stop caching fssnapshot postfixes and add microseconds
bb45c0
bb45c0
diff --git a/yum/fssnapshots.py b/yum/fssnapshots.py
bb45c0
index a07271d..10ec012 100755
bb45c0
--- a/yum/fssnapshots.py
bb45c0
+++ b/yum/fssnapshots.py
bb45c0
@@ -3,6 +3,7 @@
bb45c0
 import os
bb45c0
 import fnmatch
bb45c0
 import time
bb45c0
+from datetime import datetime
bb45c0
 
bb45c0
 import subprocess
bb45c0
 
bb45c0
@@ -228,23 +229,13 @@ class _FSSnap(object):
bb45c0
 
bb45c0
         return ret
bb45c0
 
bb45c0
-    def _get_postfix(self):
bb45c0
-        if self._postfix is None:
bb45c0
-            self._postfix = self.postfix_static
bb45c0
-            self._postfix += time.strftime("%Y%m%d%H%M%S")
bb45c0
-        return self._postfix
bb45c0
-
bb45c0
-    postfix = property(fget=lambda self: self._get_postfix(),
bb45c0
-                       fset=lambda self, value: setattr(self, "_postfix",value),
bb45c0
-                       fdel=lambda self: setattr(self, "_postfix", None),
bb45c0
-                       doc="postfix for snapshots")
bb45c0
 
bb45c0
     def snapshot(self, percentage=100, prefix='', postfix=None, tags={}):
bb45c0
         """ Attempt to take a snapshot, note that errors can happen after
bb45c0
             this function succeeds. """
bb45c0
 
bb45c0
         if postfix is None:
bb45c0
-            postfix = self.postfix
bb45c0
+            postfix = '%s%s' % (self.postfix_static, datetime.now().strftime("%Y%m%d%H%M%S.%f"))
bb45c0
 
bb45c0
         ret = []
bb45c0
         for vgname in self._vgnames:
bb45c0
commit 2678b0a2eb042e011bcafb507eae5ea3565c9110
bb45c0
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
bb45c0
Date:   Mon Jul 13 16:28:32 2015 +0200
bb45c0
bb45c0
    Test for lvm binary before using.
bb45c0
bb45c0
diff --git a/yum/fssnapshots.py b/yum/fssnapshots.py
bb45c0
index 10ec012..70f80a0 100755
bb45c0
--- a/yum/fssnapshots.py
bb45c0
+++ b/yum/fssnapshots.py
bb45c0
@@ -155,7 +155,7 @@ class _FSSnap(object):
bb45c0
         if not self._devs:
bb45c0
             return
bb45c0
 
bb45c0
-        self._vgnames = _list_vg_names()
bb45c0
+        self._vgnames = _list_vg_names() if self.available else []
bb45c0
 
bb45c0
     def _use_dev(self, vgname, lv=None):
bb45c0
 
bb45c0
commit e756473a1b01f40f087488f72d002d9993843a84
bb45c0
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
bb45c0
Date:   Wed Aug 12 12:54:55 2015 +0200
bb45c0
bb45c0
    Update not enough space messages for fssnapshot
bb45c0
bb45c0
diff --git a/yum/__init__.py b/yum/__init__.py
bb45c0
index 48956e9..84bea3e 100644
bb45c0
--- a/yum/__init__.py
bb45c0
+++ b/yum/__init__.py
bb45c0
@@ -1773,7 +1773,7 @@ much more problems).
bb45c0
             (not self.ts.isTsFlagSet(rpm.RPMTRANS_FLAG_TEST) and
bb45c0
             self.conf.fssnap_automatic_pre)):
bb45c0
             if not self.fssnap.has_space(self.conf.fssnap_percentage):
bb45c0
-                msg = _("Not enough space to create pre. FS snapshot.")
bb45c0
+                msg = _("Not enough space on logical volumes to create pre. FS snapshot.")
bb45c0
                 if self.conf.fssnap_abort_on_errors in ('snapshot-failure', 'any'):
bb45c0
                     raise Errors.YumRPMTransError(msg="Aborting transaction", errors=msg)
bb45c0
                 else:
bb45c0
@@ -1926,7 +1926,7 @@ much more problems).
bb45c0
             (not self.ts.isTsFlagSet(rpm.RPMTRANS_FLAG_TEST) and
bb45c0
             self.conf.fssnap_automatic_post)):
bb45c0
             if not self.fssnap.has_space(self.conf.fssnap_percentage):
bb45c0
-                msg = _("Not enough space to create post trans FS snapshot.")
bb45c0
+                msg = _("Not enough space on logical volumes to create post trans FS snapshot.")
bb45c0
                 self.verbose_logger.critical(msg)
bb45c0
             else:
bb45c0
                 tags = {'*': ['reason=automatic']} # FIXME: post tags
bb45c0
diff --git a/yumcommands.py b/yumcommands.py
bb45c0
index 4a39ddb..5234260 100644
bb45c0
--- a/yumcommands.py
bb45c0
+++ b/yumcommands.py
bb45c0
@@ -4311,7 +4311,7 @@ class FSSnapshotCommand(YumCommand):
bb45c0
             if base.fssnap.has_space(pc):
bb45c0
                 print _("Space available to take a snapshot.")
bb45c0
             else:
bb45c0
-                print _("Not enough space available to take a snapshot.")
bb45c0
+                print _("Not enough space available on logical volumes to take a snapshot.")
bb45c0
 
bb45c0
         if subcommand == 'create':
bb45c0
             tags = {'*': ['reason=manual']}