[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