[master 13/19] Hoist doResize to DeviceFormat and rename it resize().

mulkieran installerbot-noreply at redhat.com
Thu Jun 18 21:04:14 UTC 2015


From: mulhern <amulhern at redhat.com>

Related: #56

Use similar formula to setup, teardown, etc. methods.

Signed-off-by: mulhern <amulhern at redhat.com>
---
 blivet/deviceaction.py          |  2 +-
 blivet/formats/__init__.py      | 88 ++++++++++++++++++++++++++++++++++++++++-
 blivet/formats/fs.py            | 81 +++++++++----------------------------
 blivet/tasks/fsresize.py        |  2 +-
 tests/formats_test/fs_test.py   |  2 +-
 tests/formats_test/fstesting.py | 20 +++++-----
 6 files changed, 118 insertions(+), 77 deletions(-)

diff --git a/blivet/deviceaction.py b/blivet/deviceaction.py
index 4fd6df2..cbfbd1f 100644
--- a/blivet/deviceaction.py
+++ b/blivet/deviceaction.py
@@ -778,7 +778,7 @@ def execute(self, callbacks=None):
             callbacks.resize_format_pre(ResizeFormatPreData(msg))
 
         self.device.setup(orig=True)
-        self.device.format.doResize()
+        self.device.format.resize()
 
         if callbacks and callbacks.resize_format_post:
             msg = _("Resized filesystem on %(device)s") % {"device": self.device.path}
diff --git a/blivet/formats/__init__.py b/blivet/formats/__init__.py
index e57cf20..7fa25cb 100644
--- a/blivet/formats/__init__.py
+++ b/blivet/formats/__init__.py
@@ -32,7 +32,8 @@
 from ..storage_log import log_method_call
 from ..errors import DeviceFormatError, FormatCreateError, FormatDestroyError, FormatSetupError
 from ..i18n import N_
-from ..size import Size
+from ..size import Size, unitStr, ROUND_DOWN
+from ..tasks import dfresize
 
 import logging
 log = logging.getLogger("blivet")
@@ -160,6 +161,7 @@ class DeviceFormat(ObjectID):
     _check = False
     _hidden = False                     # hide devices with this formatting?
     _ksMountpoint = None
+    _resizeClass = dfresize.UnimplementedDFResize
 
     def __init__(self, **kwargs):
         """
@@ -179,6 +181,9 @@ def __init__(self, **kwargs):
                 it via the 'device' kwarg to the :meth:`create` method.
         """
         ObjectID.__init__(self)
+
+        self._resizeTask = self._resizeClass(self)
+
         self._label = None
         self._options = None
         self._device = None
@@ -584,6 +589,85 @@ def _teardown(self, **kwargs):
     def _postTeardown(self, **kwargs):
         pass
 
+    def resize(self, **kwargs):
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        if not self._preResize(**kwargs):
+            return
+
+        self._resize(**kwargs)
+        self._postResize(**kwargs)
+
+    def _resize(self, **kwargs):
+        """ Do generic resizing actions. """
+        # Bump target size to nearest whole number of the resize tool's units.
+        # We always round down because the fs has to fit on whatever device
+        # contains it. To round up would risk quietly setting a target size too
+        # large for the device to hold.
+        rounded = self.targetSize.roundToNearest(self._resizeTask.unit,
+                                                 rounding=ROUND_DOWN)
+
+        # 1. target size was between the min size and max size values prior to
+        #    rounding (see _setTargetSize)
+        # 2. we've just rounded the target size down (or not at all)
+        # 3. the minimum size is already either rounded (see _getMinSize) or is
+        #    equal to the current size (see updateSizeInfo)
+        # 5. the minimum size is less than or equal to the current size (see
+        #    _getMinSize)
+        #
+        # This, I think, is sufficient to guarantee that the rounded target size
+        # is greater than or equal to the minimum size.
+
+        # It is possible that rounding down a target size greater than the
+        # current size would move it below the current size, thus changing the
+        # direction of the resize. That means the target size was less than one
+        # unit larger than the current size, and we should do nothing and return
+        # early.
+        if self.targetSize > self.currentSize and rounded < self.currentSize:
+            log.info("rounding target size down to next %s obviated resize of "
+                     "format on %s", unitStr(self._resizeTask.unit), self.device)
+            return
+        else:
+            self.targetSize = rounded
+
+        self._resizeTask.doTask()
+
+    def _deviceRequiredForResize(self):
+        """ Does this format need a device to be resized.
+
+            :rtype: bool
+            :returns: True if this format needs a device, otherwise False
+        """
+        return True
+
+    def _preResize(self, **kwargs):
+        """ Do all preparatory checks for resizing a format.
+
+            :rtype: bool
+            :returns: True if resize should proceed, otherwise False
+        """
+        if not self.exists:
+            raise DeviceFormatError("format has not been created")
+
+        if not self.resizable:
+            raise DeviceFormatError("format is not resizable")
+
+        if self.targetSize == self.currentSize:
+            return False
+
+        if not self._resizeTask.available:
+            return False
+
+        if self._deviceRequiredForResize() and not os.path.exists(self.device):
+            raise DeviceFormatError("device %s does not exist" % self.device)
+
+        return True
+
+    def _postResize(self, **kwargs):
+        """ Do what must be done after resizing a format. """
+        self._size = self.targetSize
+        self.notifyKernel()
+
     @property
     def status(self):
         return (self.exists and
@@ -615,7 +699,7 @@ def packages(self):
     @property
     def resizable(self):
         """ Can formats of this type be resized? """
-        return self._resizable and self.exists
+        return self._resizable and self.exists and self._resizeTask.available
 
     @property
     def linuxNative(self):
diff --git a/blivet/formats/fs.py b/blivet/formats/fs.py
index c63f1f4..f4547ca 100644
--- a/blivet/formats/fs.py
+++ b/blivet/formats/fs.py
@@ -46,7 +46,7 @@
 from parted import fileSystemType
 from ..storage_log import log_exception_info, log_method_call
 from .. import arch
-from ..size import Size, ROUND_UP, ROUND_DOWN, unitStr
+from ..size import Size, ROUND_UP
 from ..i18n import N_
 from .. import udev
 from ..mounts import mountsCache
@@ -106,7 +106,6 @@ def __init__(self, **kwargs):
         self._mkfs = self._mkfsClass(self)
         self._mount = self._mountClass(self)
         self._readlabel = self._readlabelClass(self)
-        self._resizeTask = self._resizeClass(self)
         self._sync = self._syncClass(self)
         self._writelabel = self._writelabelClass(self)
 
@@ -330,23 +329,19 @@ def _postCreate(self, **kwargs):
     def doResize(self):
         """ Resize this filesystem based on this instance's targetSize attr.
 
-            :raises: FSResizeError, FSError
-        """
-        if not self.exists:
-            raise FSResizeError("filesystem does not exist", self.device)
-
-        if not self.resizable:
-            raise FSResizeError("filesystem not resizable", self.device)
+            :raises: FSResizeError, FSError, DeviceFormatError
 
-        if self.targetSize == self.currentSize:
-            return
+            .. versionchanged:: 1.5
+               Raises :class:`~.errors.DeviceFormatError`
 
-        if not self._resizeTask.available:
-            return
+            .. deprecated:: 1.5
+               Use :func:`resize` instead.
+        """
+        self.resize()
 
-        # tmpfs mounts don't need an existing device node
-        if not self.device == "tmpfs" and not os.path.exists(self.device):
-            raise FSResizeError("device does not exist", self.device)
+    def _preResize(self, **kwargs):
+        if not super(FS, self)._preResize(**kwargs):
+            return False
 
         # The first minimum size can be incorrect if the fs was not
         # properly unmounted. After doCheck the minimum size will be correct
@@ -362,47 +357,11 @@ def doResize(self):
             self.targetSize = self.minSize
             log.info("Minimum size changed, setting targetSize on %s to %s",
                      self.device, self.targetSize)
+        return True
 
-        # Bump target size to nearest whole number of the resize tool's units.
-        # We always round down because the fs has to fit on whatever device
-        # contains it. To round up would risk quietly setting a target size too
-        # large for the device to hold.
-        rounded = self.targetSize.roundToNearest(self._resizeTask.unit,
-                                                 rounding=ROUND_DOWN)
-
-        # 1. target size was between the min size and max size values prior to
-        #    rounding (see _setTargetSize)
-        # 2. we've just rounded the target size down (or not at all)
-        # 3. the minimum size is already either rounded (see _getMinSize) or is
-        #    equal to the current size (see updateSizeInfo)
-        # 5. the minimum size is less than or equal to the current size (see
-        #    _getMinSize)
-        #
-        # This, I think, is sufficient to guarantee that the rounded target size
-        # is greater than or equal to the minimum size.
-
-        # It is possible that rounding down a target size greater than the
-        # current size would move it below the current size, thus changing the
-        # direction of the resize. That means the target size was less than one
-        # unit larger than the current size, and we should do nothing and return
-        # early.
-        if self.targetSize > self.currentSize and rounded < self.currentSize:
-            log.info("rounding target size down to next %s obviated resize of "
-                     "filesystem on %s", unitStr(self._resizeTask.unit), self.device)
-            return
-        else:
-            self.targetSize = rounded
-
-        try:
-            self._resizeTask.doTask()
-        except FSError as e:
-            raise FSResizeError(e, self.device)
-
+    def _postResize(self, **kwargs):
         self.doCheck()
-
-        # XXX must be a smarter way to do this
-        self._size = self.targetSize
-        self.notifyKernel()
+        super(FS, self)._postResize(**kwargs)
 
     def doCheck(self):
         """ Run a filesystem check.
@@ -659,11 +618,6 @@ def mountable(self):
     def formattable(self):
         return super(FS, self).formattable and self._mkfs.available
 
-    @property
-    def resizable(self):
-        """ Can formats of this filesystem type be resized? """
-        return super(FS, self).resizable and self._resizeTask.available
-
     def _getOptions(self):
         return self.mountopts or ",".join(self._mount.options)
 
@@ -1224,13 +1178,16 @@ def _setDevice(self, value):
         # same, nothing actually needs to be set
         pass
 
-    def doResize(self):
+    def _resize(self, **kwargs):
         # Override superclass method to record whether mount options
         # should include an explicit size specification.
         original_size = self._size
-        FS.doResize(self)
+        super(TmpFS, self)._resize(**kwargs)
         self._accept_default_size = self._accept_default_size and original_size == self._size
 
+    def _deviceRequiredForResize(self):
+        return False
+
 register_device_format(TmpFS)
 
 
diff --git a/blivet/tasks/fsresize.py b/blivet/tasks/fsresize.py
index c6db378..ee3238c 100644
--- a/blivet/tasks/fsresize.py
+++ b/blivet/tasks/fsresize.py
@@ -80,7 +80,7 @@ def doTask(self):
             raise FSError(e)
 
         if ret:
-            raise FSError("resize failed: %s" % ret)
+            raise FSError("resize of format on device %s failed: %s" % (self.fs.device, ret))
 
 class Ext2FSResize(FSResize):
     ext = availability.RESIZE2FS_APP
diff --git a/tests/formats_test/fs_test.py b/tests/formats_test/fs_test.py
index e981408..8a4c074 100644
--- a/tests/formats_test/fs_test.py
+++ b/tests/formats_test/fs_test.py
@@ -121,7 +121,7 @@ def testResize(self):
         self.an_fs.updateSizeInfo()
         newsize = self.an_fs.currentSize * 2
         self.an_fs.targetSize = newsize
-        self.assertIsNone(self.an_fs.doResize())
+        self.assertIsNone(self.an_fs.resize())
         self.assertEqual(self.an_fs.size, newsize.roundToNearest(self.an_fs._resizeTask.unit, rounding=ROUND_DOWN))
 
     def testShrink(self):
diff --git a/tests/formats_test/fstesting.py b/tests/formats_test/fstesting.py
index bf654f8..03eb156 100644
--- a/tests/formats_test/fstesting.py
+++ b/tests/formats_test/fstesting.py
@@ -6,7 +6,7 @@
 import tempfile
 
 from tests import loopbackedtestcase
-from blivet.errors import DeviceFormatError, FSError, FSResizeError
+from blivet.errors import DeviceFormatError, FSError
 from blivet.size import Size, ROUND_DOWN
 from blivet.formats import fs
 
@@ -200,7 +200,7 @@ def testResize(self):
             with self.assertRaises(DeviceFormatError):
                 an_fs.targetSize = Size("64 MiB")
             with self.assertRaises(DeviceFormatError):
-                an_fs.doResize()
+                an_fs.resize()
         else:
             self.assertTrue(an_fs.resizable)
             # Try a reasonable target size
@@ -208,7 +208,7 @@ def testResize(self):
             an_fs.targetSize = TARGET_SIZE
             self.assertEqual(an_fs.targetSize, TARGET_SIZE)
             self.assertNotEqual(an_fs._size, TARGET_SIZE)
-            self.assertIsNone(an_fs.doResize())
+            self.assertIsNone(an_fs.resize())
             ACTUAL_SIZE = TARGET_SIZE.roundToNearest(an_fs._resizeTask.unit, rounding=ROUND_DOWN)
             self.assertEqual(an_fs.size, ACTUAL_SIZE)
             self.assertEqual(an_fs._size, ACTUAL_SIZE)
@@ -237,7 +237,7 @@ def testNoExplicitTargetSize(self):
         self.assertNotEqual(an_fs.currentSize, an_fs.targetSize)
         self.assertEqual(an_fs.currentSize, an_fs._size)
         self.assertEqual(an_fs.targetSize, Size(0))
-        self.assertIsNone(an_fs.doResize())
+        self.assertIsNone(an_fs.resize())
         self.assertEqual(an_fs.currentSize, an_fs.minSize)
         self.assertEqual(an_fs.targetSize, an_fs.minSize)
         self._test_sizes(an_fs)
@@ -261,7 +261,7 @@ def testNoExplicitTargetSize2(self):
         # set in the constructor.
         self.assertNotEqual(an_fs.currentSize, an_fs.targetSize)
         self.assertEqual(an_fs.targetSize, SIZE)
-        self.assertIsNone(an_fs.doResize())
+        self.assertIsNone(an_fs.resize())
         self.assertEqual(an_fs.currentSize, SIZE)
         self.assertEqual(an_fs.targetSize, SIZE)
         self._test_sizes(an_fs)
@@ -279,7 +279,7 @@ def testShrink(self):
 
         TARGET_SIZE = Size("64 MiB")
         an_fs.targetSize = TARGET_SIZE
-        self.assertIsNone(an_fs.doResize())
+        self.assertIsNone(an_fs.resize())
 
         TARGET_SIZE = TARGET_SIZE / 2
         self.assertTrue(TARGET_SIZE > an_fs.minSize)
@@ -287,13 +287,13 @@ def testShrink(self):
         self.assertEqual(an_fs.targetSize, TARGET_SIZE)
         self.assertNotEqual(an_fs._size, TARGET_SIZE)
         # FIXME:
-        # doCheck() in updateSizeInfo() in doResize() does not complete tidily
+        # doCheck() in updateSizeInfo() in resize() does not complete tidily
         # here, so resizable becomes False and self.targetSize can not be
         # assigned to. This alerts us to the fact that now min size
         # and size are both incorrect values.
         if isinstance(an_fs, fs.NTFS):
             return
-        self.assertIsNone(an_fs.doResize())
+        self.assertIsNone(an_fs.resize())
         ACTUAL_SIZE = TARGET_SIZE.roundToNearest(an_fs._resizeTask.unit, rounding=ROUND_DOWN)
         self.assertEqual(an_fs._size, ACTUAL_SIZE)
         self._test_sizes(an_fs)
@@ -352,8 +352,8 @@ def testTooBig2(self):
         BIG_SIZE = an_fs.maxSize - Size(1)
         an_fs.targetSize = BIG_SIZE
         self.assertEqual(an_fs.targetSize, BIG_SIZE)
-        with self.assertRaises(FSResizeError):
-            an_fs.doResize()
+        with self.assertRaises(FSError):
+            an_fs.resize()
 
         # CHECKME: size and target size will be adjusted attempted values
         # while currentSize will be actual value


-- 
To view this commit on github, visit https://github.com/rhinstaller/blivet/commit/48d853d7b415e64d25fecdd748b1fcc5b6d45057


More information about the anaconda-patches mailing list