[PATCH 2/9] Add a ContainerDevice class to consolidate member management code.
David Lehman
dlehman at redhat.com
Thu Mar 20 17:14:06 UTC 2014
---
blivet/devices.py | 488 ++++++++++++++++++++++----------------------------
blivet/devicetree.py | 4 +-
tests/devices_test.py | 88 ++++++---
3 files changed, 273 insertions(+), 307 deletions(-)
diff --git a/blivet/devices.py b/blivet/devices.py
index 750ce8a..5ffb265 100644
--- a/blivet/devices.py
+++ b/blivet/devices.py
@@ -1,7 +1,7 @@
# devices.py
-# Device classes for anaconda's storage configuration module.
+# Classes to represent various types of block devices.
#
-# Copyright (C) 2009-2013 Red Hat, Inc.
+# Copyright (C) 2009-2014 Red Hat, Inc.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions of
@@ -2031,7 +2031,137 @@ class LUKSDevice(DMCryptDevice):
data.encrypted = True
super(LUKSDevice, self).populateKSData(data)
-class LVMVolumeGroupDevice(DMDevice):
+class ContainerDevice(StorageDevice):
+ """ A device that contains at least one member device. """
+ _formatClassName = None
+ _formatUUIDAttr = None
+
+ def __init__(self, *args, **kwargs):
+ self.formatClass = get_device_format_class(self._formatClassName)
+ if not self.formatClass:
+ raise StorageError("cannot find '%s' class" % self._formatClassName)
+
+ # Instantiate the superclass without any parents so we can do some
+ # validation on them before adding them as parents.
+ parents = kwargs.pop("parents", [])
+ super(ContainerDevice, self).__init__(*args, **kwargs)
+
+ # could be None
+ for parent in parents or []:
+ self._addMember(parent)
+
+ # restore kwargs in case another class wants to use them further
+ kwargs["parents"] = parents
+
+ def _addMember(self, member):
+ """ Add a member device to the container.
+
+ :param member: the member device to add
+ :type member: :class:`.StorageDevice`
+
+ This operates on the in-memory model and does not alter disk
+ contents at all.
+ """
+ log_method_call(self,
+ self.name,
+ member=member.name,
+ status=self.status)
+ if not isinstance(member.format, self.formatClass):
+ raise ValueError("member has wrong format")
+
+ if member in self.parents:
+ raise ValueError("member is already part of this container")
+
+ if member.format.exists and self.uuid and self._formatUUIDAttr and \
+ getattr(member.format, self._formatUUIDAttr) != self.uuid:
+ raise ValueError("cannot add member with mismatched UUID")
+
+ self.parents.append(member)
+ member.addChild()
+
+ def _removeMember(self, member):
+ """ Remove a member device from the container.
+
+ :param member: the member device to add
+ :type member: :class:`.StorageDevice`
+
+ This operates on the in-memory model and does not alter disk
+ contents at all.
+ """
+ log_method_call(self,
+ self.name,
+ member=member.name,
+ status=self.status)
+ if member not in self.parents:
+ raise ValueError("member is not part of this container")
+
+ self.parents.remove(member)
+ member.removeChild()
+
+ def _add(self, member):
+ """ Device-type specific code to add a member to the container.
+
+ :param member: the member device to add
+ :type member: :class:`.StorageDevice`
+
+ This method writes the member addition to disk.
+ """
+ pass
+
+ def add(self, member):
+ """ Add a member to the container.
+
+ :param member: the member device to add
+ :type member: :class:`.StorageDevice`
+
+ This method writes the member addition to disk.
+ """
+ if not self.exists:
+ raise DeviceError("device has not been created", self.name)
+
+ if member.format.exists and self.uuid and self._formatUUIDAttr and \
+ getattr(member.format, self._formatUUIDAttr) == self.uuid:
+ log.error("cannot re-add member: %s" % member)
+ raise ValueError("cannot add members that are already part of the container")
+
+ self._add(member)
+
+ if member not in self.parents:
+ self._addMember(member)
+
+ def _remove(self, member):
+ """ Device-type specific code to remove a member from the container.
+
+ :param member: the member device to remove
+ :type member: :class:`.StorageDevice`
+
+ This method writes the member removal to disk.
+ """
+ pass
+
+ def remove(self, member):
+ """ Remove a member from the container.
+
+ :param member: the member device to remove
+ :type member: :class:`.StorageDevice`
+
+ This method writes the member removal to disk.
+ """
+ log_method_call(self, self.name, status=self.status)
+ if not self.exists:
+ raise DeviceError("device has not been created", self.name)
+
+ if self._formatUUIDAttr and self.uuid and \
+ getattr(member.format, self._formatUUIDAttr) != self.uuid:
+ log.error("cannot remove non-member: %s (%s/%s)", member, getattr(member.format, self._formatUUIDAttr), self.uuid)
+ raise ValueError("cannot remove members that are not part of the container")
+
+ self._remove(member)
+
+ if member in self.parents:
+ self._removeMember(member)
+
+class LVMVolumeGroupDevice(ContainerDevice):
""" An LVM Volume Group
XXX Maybe this should inherit from StorageDevice instead of
@@ -2039,6 +2169,8 @@ class LVMVolumeGroupDevice(DMDevice):
"""
_type = "lvmvg"
_packages = ["lvm2"]
+ _formatClassName = "lvmpv"
+ _formatUUIDAttr = "vgUuid"
def __init__(self, name, parents=None, size=None, free=None,
peSize=None, peCount=None, peFree=None, pvCount=None,
@@ -2070,41 +2202,31 @@ class LVMVolumeGroupDevice(DMDevice):
:keyword uuid: the VG UUID
:type uuid: str
"""
- self.pvClass = get_device_format_class("lvmpv")
- if not self.pvClass:
- raise StorageError("cannot find 'lvmpv' class")
-
- if isinstance(parents, list):
- for dev in parents:
- if not isinstance(dev.format, self.pvClass):
- raise ValueError("constructor requires a list of PVs")
- elif not isinstance(parents.format, self.pvClass):
- raise ValueError("constructor requires a list of PVs")
+ # These attributes are used by _addMember, so they must be initialized
+ # prior to instantiating the superclass.
+ self._lvs = []
+ self.hasDuplicate = False
+ self.pvCount = util.numeric_type(pvCount)
- DMDevice.__init__(self, name, parents=parents,
- exists=exists, sysfsPath=sysfsPath)
+ super(LVMVolumeGroupDevice, self).__init__(name, parents=parents,
+ exists=exists, sysfsPath=sysfsPath)
self.uuid = uuid
self.free = util.numeric_type(free)
self.peSize = util.numeric_type(peSize)
self.peCount = util.numeric_type(peCount)
self.peFree = util.numeric_type(peFree)
- self.pvCount = util.numeric_type(pvCount)
self.lv_names = []
self.lv_uuids = []
self.lv_sizes = []
self.lv_attr = []
self.lv_types = []
- self.hasDuplicate = False
self.reserved_percent = 0
self.reserved_space = Size(bytes=0)
# this will have to be covered by the 20% pad for non-existent pools
self.poolMetaData = 0
- # circular references, here I come
- self._lvs = []
-
# TODO: validate peSize if given
if not self.peSize:
self.peSize = lvm.LVM_PE_SIZE
@@ -2120,7 +2242,7 @@ class LVMVolumeGroupDevice(DMDevice):
self.size_policy = self.size
def __repr__(self):
- s = DMDevice.__repr__(self)
+ s = ContainerDevice.__repr__(self)
s += (" free = %(free)s PE Size = %(peSize)s PE Count = %(peCount)s\n"
" PE Free = %(peFree)s PV Count = %(pvCount)s\n"
" LV Names = %(lv_names)s modified = %(modified)s\n"
@@ -2197,56 +2319,6 @@ class LVMVolumeGroupDevice(DMDevice):
return True
- def _addDevice(self, device):
- """ Add a new physical volume device to the volume group.
-
- XXX This is for use by device probing routines and is not
- intended for modification of the VG.
- """
- log_method_call(self,
- self.name,
- device=device.name,
- status=self.status)
- if not self.exists:
- raise DeviceError("device does not exist", self.name)
-
- if not isinstance(device.format, self.pvClass):
- raise ValueError("addDevice requires a PV arg")
-
- if self.uuid and device.format.vgUuid != self.uuid:
- # this means there is another vg with the same name on the system
- # set hasDuplicate which will make complete return False
- # and let devicetree._handleInconsistencies() further handle this.
- # Note we still add the device to our parents for use by
- # devicetree._handleInconsistencies()
- self.hasDuplicate = True
-
- if device in self.pvs:
- raise ValueError("device is already a member of this VG")
-
- self.parents.append(device)
- device.addChild()
-
- # now see if the VG can be activated
- if self.complete and flags.installer_mode:
- self.setup()
-
- def _removeDevice(self, device):
- """ Remove a physical volume from the volume group.
-
- This is for cases like clearing of preexisting partitions.
- """
- log_method_call(self,
- self.name,
- device=device.name,
- status=self.status)
- try:
- self.parents.remove(device)
- except ValueError:
- raise ValueError("cannot remove non-member PV device from VG")
-
- device.removeChild()
-
def _preSetup(self, orig=False):
if self.exists and not self.complete:
raise DeviceError("cannot activate VG with missing PV(s)", self.name)
@@ -2320,42 +2392,27 @@ class LVMVolumeGroupDevice(DMDevice):
if self.poolMetaData and not self.thinpools:
self.poolMetaData = 0
- def _addPV(self, pv):
- """ Add a PV to this VG. """
- if pv in self.pvs:
- raise ValueError("pv is already part of this vg")
-
- # for the time being we will not allow vgextend
- if self.exists:
- raise DeviceError("cannot add pv to existing vg", self.name)
+ def _addMember(self, member):
+ super(LVMVolumeGroupDevice, self)._addMember(member)
- self.parents.append(pv)
- pv.addChild()
+ # now see if the VG can be activated
+ ## XXX TODO: remove this activation code
+ if self.exists and member.format.exists and self.complete and \
+ flags.installer_mode:
+ self.setup()
# and update our pv count
self.pvCount = len(self.parents)
- def addMember(self, member):
- self._addPV(member)
-
- def _removePV(self, pv):
- """ Remove an PV from this VG. """
- if not pv in self.pvs:
- raise ValueError("specified pv is not part of this vg")
-
- # for the time being we will not allow vgreduce
- if self.exists:
- raise DeviceError("cannot remove pv from existing vg", self.name)
-
- self.parents.remove(pv)
- pv.removeChild()
+ def _removeMember(self, member):
+ # XXX It would be nice to raise an exception if removing this member
+ # would not leave enough space, but the devicefactory relies on it
+ # being possible to _temporarily_ overcommit the VG.
+ super(LVMVolumeGroupDevice, self)._removeMember(member)
# and update our pv count
self.pvCount = len(self.parents)
- def removeMember(self, member):
- self._removePV(member)
-
# We can't rely on lvm to tell us about our size, free space, &c
# since we could have modifications queued, unless the VG and all of
# its PVs already exist.
@@ -2987,11 +3044,13 @@ class LVMThinLogicalVolumeDevice(LVMLogicalVolumeDevice):
data.thin_volume = True
data.pool_name = self.pool.lvname
-class MDRaidArrayDevice(StorageDevice):
+class MDRaidArrayDevice(ContainerDevice):
""" An mdraid (Linux RAID) device. """
_type = "mdarray"
_packages = ["mdadm"]
_devDir = "/dev/md"
+ _formatClassName = "mdmember"
+ _formatUUIDAttr = "mdUuid"
def __init__(self, name, level=None, major=None, minor=None, size=None,
memberDevices=None, totalDevices=None,
@@ -3020,9 +3079,15 @@ class MDRaidArrayDevice(StorageDevice):
:keyword minor: the device minor (obsolete?)
:type minor: int
"""
- StorageDevice.__init__(self, name, format=format, exists=exists,
- major=major, minor=minor, size=size,
- parents=parents, sysfsPath=sysfsPath)
+ # These attributes are used by _addMember, so they must be initialized
+ # prior to instantiating the superclass.
+ self._memberDevices = 0
+ self._totalDevices = 0
+
+ super(MDRaidArrayDevice, self).__init__(name, format=format,
+ exists=exists, size=size,
+ parents=parents,
+ sysfsPath=sysfsPath)
if level == "container":
self._type = "mdcontainer"
@@ -3054,12 +3119,6 @@ class MDRaidArrayDevice(StorageDevice):
self._size = self.currentSize
self._type = "mdbiosraidarray"
- self.formatClass = get_device_format_class("mdmember")
- if not self.formatClass:
- for dev in self.parents:
- dev.removeChild()
- raise DeviceError("cannot find class for 'mdmember'", self.name)
-
if self.exists and self.uuid and not flags.testing:
# this is a hack to work around mdadm's insistence on giving
# really high minors to arrays it has no config entry for
@@ -3254,83 +3313,38 @@ class MDRaidArrayDevice(StorageDevice):
else:
self.sysfsPath = ''
- def _addDevice(self, device):
- """ Add a new member device to the array.
-
- XXX This is for use when probing devices, not for modification
- of arrays.
- """
- log_method_call(self,
- self.name,
- device=device.name,
- status=self.status)
- if not self.exists:
- raise DeviceError("device has not been created", self.name)
-
- if not isinstance(device.format, self.formatClass):
- raise ValueError("invalid device format for mdraid member")
+ def _addMember(self, member):
+ super(MDRaidArrayDevice, self)._addMember(member)
- if self.uuid and device.format.mdUuid != self.uuid:
- raise ValueError("cannot add member with non-matching UUID")
-
- if device in self.devices:
- raise ValueError("device is already a member of this array")
-
- # we added it, so now set up the relations
- self.devices.append(device)
- device.addChild()
-
- if flags.installer_mode:
- device.setup()
+ ## XXX TODO: remove this whole block of activation code
+ if self.exists and member.format.exists and flags.installer_mode:
+ member.setup()
udev_settle()
- if self.spares > 0:
- # mdadm doesn't like it when you try to incrementally add spares
- return
-
- try:
- mdraid.mdadd(device.path)
- # mdadd causes udev events
- udev_settle()
- except MDRaidError as e:
- log.warning("failed to add member %s to md array %s: %s"
- % (device.path, self.path, e))
-
- if self.status:
+ if self.spares <= 0:
+ try:
+ mdraid.mdadd(None, [member.path], incremental=True)
+ # mdadd causes udev events
+ udev_settle()
+ except MDRaidError as e:
+ log.warning("failed to add member %s to md array %s: %s"
+ % (member.path, self.path, e))
+
+ if self.status and member.format.exists:
# we always probe since the device may not be set up when we want
# information about it
self._size = self.currentSize
- def _removeDevice(self, device):
- """ Remove a component device from the array.
-
- XXX This is for use by clearpart, not for reconfiguration.
- """
- log_method_call(self,
- self.name,
- device=device.name,
- status=self.status)
-
- if device not in self.devices:
- raise ValueError("cannot remove non-member device from array")
-
- self.devices.remove(device)
- device.removeChild()
-
- def addMember(self, member):
- if member in self.parents:
- raise ValueError("member is already part of this array")
-
- # for the time being we will not allow adding members to existing arrays
- if self.exists:
- raise DeviceError("cannot add member to existing array", self.name)
+ if not self.exists:
+ self._totalDevices += 1
- self.parents.append(member)
- member.addChild()
self.memberDevices += 1
- def removeMember(self, member):
- self._removeDevice(member)
+ def _removeMember(self, member):
+ if self.level.name == "raid0" and self.exists and member.format.exists:
+ raise DeviceError("cannot remove members from existing raid0")
+
+ super(MDRaidArrayDevice, self)._removeMember(member)
self.memberDevices -= 1
@property
@@ -3527,12 +3541,13 @@ class MDRaidArrayDevice(StorageDevice):
data.preexist = self.exists
data.device = self.name
-class DMRaidArrayDevice(DMDevice):
+class DMRaidArrayDevice(DMDevice, ContainerDevice):
""" A dmraid (device-mapper RAID) device """
_type = "dm-raid array"
_packages = ["dmraid"]
_partitionable = True
_isDisk = True
+ _formatClassName = "dmraidmember"
def __init__(self, name, raidSet=None, format=None,
size=None, parents=None, sysfsPath=''):
@@ -3553,16 +3568,9 @@ class DMRaidArrayDevice(DMDevice):
DMRaidArrayDevices always exist. Blivet cannot create or destroy
them.
"""
- if isinstance(parents, list):
- for parent in parents:
- if not parent.format or parent.format.type != "dmraidmember":
- raise ValueError("parent devices must contain dmraidmember format")
- DMDevice.__init__(self, name, format=format, size=size,
- parents=parents, sysfsPath=sysfsPath, exists=True)
-
- self.formatClass = get_device_format_class("dmraidmember")
- if not self.formatClass:
- raise StorageError("cannot find class for 'dmraidmember'")
+ super(DMRaidArrayDevice, self).__init__(name, format=format, size=size,
+ parents=parents, exists=True,
+ sysfsPath=sysfsPath)
self._raidSet = raidSet
@@ -3570,27 +3578,6 @@ class DMRaidArrayDevice(DMDevice):
def raidSet(self):
return self._raidSet
- def _addDevice(self, device):
- """ Add a new member device to the array.
-
- XXX This is for use when probing devices, not for modification
- of arrays.
- """
- log_method_call(self, self.name, device=device.name, status=self.status)
-
- if not self.exists:
- raise DeviceError("device has not been created", self.name)
-
- if not isinstance(device.format, self.formatClass):
- raise ValueError("invalid device format for dmraid member")
-
- if device in self.members:
- raise ValueError("device is already a member of this array")
-
- # we added it, so now set up the relations
- self.devices.append(device)
- device.addChild()
-
@property
def members(self):
return self.parents
@@ -4464,7 +4451,7 @@ class BTRFSDevice(StorageDevice):
@property
def path(self):
- return self.parents[0].path
+ return self.parents[0].path if self.parents else None
@property
def fstabSpec(self):
@@ -4474,9 +4461,11 @@ class BTRFSDevice(StorageDevice):
spec = super(BTRFSDevice, self).fstabSpec
return spec
-class BTRFSVolumeDevice(BTRFSDevice):
+class BTRFSVolumeDevice(BTRFSDevice, ContainerDevice):
_type = "btrfs volume"
vol_id = btrfs.MAIN_VOLUME_ID
+ _formatClassName = "btrfs"
+ _formatUUIDAttr = "volUUID"
def __init__(self, *args, **kwargs):
self.dataLevel = kwargs.pop("dataLevel", None)
@@ -4487,16 +4476,6 @@ class BTRFSVolumeDevice(BTRFSDevice):
self.subvolumes = []
self.size_policy = self.size
- for parent in self.parents:
- if parent.format.type != "btrfs":
- raise ValueError("member device %s is not BTRFS" % parent.name)
-
- if parent.format.exists and self.exists and \
- parent.format.volUUID != self.uuid:
- raise ValueError("BTRFS member device %s UUID %s does not "
- "match volume UUID %s" % (parent.name,
- parent.format.volUUID, self.uuid))
-
if self.parents and not self.format.type:
label = getattr(self.parents[0].format, "label", None)
self.format = getFormat("btrfs",
@@ -4524,67 +4503,24 @@ class BTRFSVolumeDevice(BTRFSDevice):
return size
- def _addDevice(self, device):
- """ Add a new device to this volume.
-
- XXX This is for use by device probing routines and is not
- intended for modification of the volume.
- """
- log_method_call(self,
- self.name,
- device=device.name,
- status=self.status)
- if not self.exists:
- raise DeviceError("device does not exist", self.name)
+ def _removeMember(self, member):
+ # btrfs won't let you degrade it
+ limits = []
+ levels = raid.RAIDLevels()
+ if self.dataLevel and self.dataLevel != "single":
+ limits.append(levels.raidLevel(self.dataLevel).min_members)
- if device.format.type != "btrfs":
- raise ValueError("addDevice requires a btrfs device as sole arg")
+ if self.metaDataLevel and self.metaDataLevel != "single":
+ limits.append(levels.raidLevel(self.metaDataLevel).min_members)
- if device.format.volUUID != self.uuid:
- raise ValueError("device UUID does not match the volume UUID")
+ if limits:
+ min_members = min(limits)
- if device in self.parents:
- raise ValueError("device is already a member of this volume")
+ if limits and len(self.parents) - 1 < min_members:
+ raise DeviceError("cannot remove member due to raid level "
+ "constraints")
- self.parents.append(device)
- device.addChild()
-
- def _removeDevice(self, device):
- """ Remove a device from the volume.
-
- This is for cases like clearing of preexisting partitions.
- """
- log_method_call(self,
- self.name,
- device=device.name,
- status=self.status)
- try:
- self.parents.remove(device)
- except ValueError:
- raise ValueError("cannot remove non-member device from volume")
-
- device.removeChild()
-
- def addMember(self, member):
- if member in self.parents:
- raise ValueError("member is already part of this volume")
-
- # for the time being we will not allow adding members to existing vols
- if self.exists:
- raise DeviceError("cannot add member to existing volume", self.name)
-
- self.parents.append(member)
- member.addChild()
-
- def removeMember(self, member):
- if member not in self.parents:
- raise ValueError("member is not part of this volume")
-
- if self.exists:
- raise DeviceError("cannot remove member from an existing volume")
-
- self.parents.remove(member)
- member.removeChild()
+ super(BTRFSVolumeDevice, self)._removeMember(member)
def _addSubVolume(self, vol):
if vol.name in [v.name for v in self.subvolumes]:
diff --git a/blivet/devicetree.py b/blivet/devicetree.py
index c166e3d..8ad0958 100644
--- a/blivet/devicetree.py
+++ b/blivet/devicetree.py
@@ -1,7 +1,7 @@
# devicetree.py
# Device management for anaconda's storage configuration module.
#
-# Copyright (C) 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
+# Copyright (C) 2009-2014 Red Hat, Inc.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions of
@@ -1488,7 +1488,7 @@ class DeviceTree(object):
return
vg_device = LVMVolumeGroupDevice(vg_name,
- device,
+ parents=[device],
uuid=vg_uuid,
size=vg_size,
free=vg_free,
diff --git a/tests/devices_test.py b/tests/devices_test.py
index f38dc31..c69389d 100644
--- a/tests/devices_test.py
+++ b/tests/devices_test.py
@@ -19,6 +19,8 @@ from blivet.devices import mdraid
from blivet.devicelibs import btrfs
from blivet.size import Size
+from blivet.formats import getFormat
+
class DeviceStateTestCase(unittest.TestCase):
"""A class which implements a simple method of checking the state
of a device object.
@@ -106,8 +108,10 @@ class MDRaidArrayDeviceTestCase(DeviceStateTestCase):
level="raid0",
memberDevices=2,
parents=[
- MDRaidArrayDevice("parent", level="container"),
- MDRaidArrayDevice("other", level=0)],
+ MDRaidArrayDevice("parent", level="container",
+ format=getFormat("mdmember")),
+ MDRaidArrayDevice("other", level=0,
+ format=getFormat("mdmember"))],
totalDevices=2)
self.dev10 = MDRaidArrayDevice(
@@ -120,8 +124,10 @@ class MDRaidArrayDeviceTestCase(DeviceStateTestCase):
level=1,
memberDevices=2,
parents=[
- MDRaidArrayDevice("parent", level="container"),
- MDRaidArrayDevice("other", level="raid0")],
+ MDRaidArrayDevice("parent", level="container",
+ format=getFormat("mdmember")),
+ MDRaidArrayDevice("other", level="raid0",
+ format=getFormat("mdmember"))],
size=Size(spec="32 MiB"),
totalDevices=2)
@@ -131,8 +137,10 @@ class MDRaidArrayDeviceTestCase(DeviceStateTestCase):
memberDevices=2,
parents=[
Mock(**{"type": "mdcontainer",
- "size": Size(spec="4 MiB")}),
- Mock(**{"size": Size(spec="2 MiB")})],
+ "size": Size(spec="4 MiB"),
+ "format": getFormat("mdmember")}),
+ Mock(**{"size": Size(spec="2 MiB"),
+ "format": getFormat("mdmember")})],
size=Size(spec="32 MiB"),
totalDevices=2)
@@ -141,8 +149,10 @@ class MDRaidArrayDeviceTestCase(DeviceStateTestCase):
level=0,
memberDevices=3,
parents=[
- Mock(**{"size": Size(spec="4 MiB")}),
- Mock(**{"size": Size(spec="2 MiB")})],
+ Mock(**{"size": Size(spec="4 MiB"),
+ "format": getFormat("mdmember")}),
+ Mock(**{"size": Size(spec="2 MiB"),
+ "format": getFormat("mdmember")})],
size=Size(spec="32 MiB"),
totalDevices=3)
@@ -151,9 +161,12 @@ class MDRaidArrayDeviceTestCase(DeviceStateTestCase):
level=4,
memberDevices=3,
parents=[
- Mock(**{"size": Size(spec="4 MiB")}),
- Mock(**{"size": Size(spec="2 MiB")}),
- Mock(**{"size": Size(spec="2 MiB")})],
+ Mock(**{"size": Size(spec="4 MiB"),
+ "format": getFormat("mdmember")}),
+ Mock(**{"size": Size(spec="2 MiB"),
+ "format": getFormat("mdmember")}),
+ Mock(**{"size": Size(spec="2 MiB"),
+ "format": getFormat("mdmember")})],
totalDevices=3)
self.dev15 = MDRaidArrayDevice(
@@ -161,9 +174,12 @@ class MDRaidArrayDeviceTestCase(DeviceStateTestCase):
level=5,
memberDevices=3,
parents=[
- Mock(**{"size": Size(spec="4 MiB")}),
- Mock(**{"size": Size(spec="2 MiB")}),
- Mock(**{"size": Size(spec="2 MiB")})],
+ Mock(**{"size": Size(spec="4 MiB"),
+ "format": getFormat("mdmember")}),
+ Mock(**{"size": Size(spec="2 MiB"),
+ "format": getFormat("mdmember")}),
+ Mock(**{"size": Size(spec="2 MiB"),
+ "format": getFormat("mdmember")})],
totalDevices=3)
self.dev16 = MDRaidArrayDevice(
@@ -171,10 +187,14 @@ class MDRaidArrayDeviceTestCase(DeviceStateTestCase):
level=6,
memberDevices=4,
parents=[
- Mock(**{"size": Size(spec="4 MiB")}),
- Mock(**{"size": Size(spec="4 MiB")}),
- Mock(**{"size": Size(spec="2 MiB")}),
- Mock(**{"size": Size(spec="2 MiB")})],
+ Mock(**{"size": Size(spec="4 MiB"),
+ "format": getFormat("mdmember")}),
+ Mock(**{"size": Size(spec="4 MiB"),
+ "format": getFormat("mdmember")}),
+ Mock(**{"size": Size(spec="2 MiB"),
+ "format": getFormat("mdmember")}),
+ Mock(**{"size": Size(spec="2 MiB"),
+ "format": getFormat("mdmember")})],
totalDevices=4)
self.dev17 = MDRaidArrayDevice(
@@ -182,10 +202,14 @@ class MDRaidArrayDeviceTestCase(DeviceStateTestCase):
level=10,
memberDevices=4,
parents=[
- Mock(**{"size": Size(spec="4 MiB")}),
- Mock(**{"size": Size(spec="4 MiB")}),
- Mock(**{"size": Size(spec="2 MiB")}),
- Mock(**{"size": Size(spec="2 MiB")})],
+ Mock(**{"size": Size(spec="4 MiB"),
+ "format": getFormat("mdmember")}),
+ Mock(**{"size": Size(spec="4 MiB"),
+ "format": getFormat("mdmember")}),
+ Mock(**{"size": Size(spec="2 MiB"),
+ "format": getFormat("mdmember")}),
+ Mock(**{"size": Size(spec="2 MiB"),
+ "format": getFormat("mdmember")})],
totalDevices=4)
self.dev18 = MDRaidArrayDevice(
@@ -193,10 +217,14 @@ class MDRaidArrayDeviceTestCase(DeviceStateTestCase):
level=10,
memberDevices=4,
parents=[
- Mock(**{"size": Size(spec="4 MiB")}),
- Mock(**{"size": Size(spec="4 MiB")}),
- Mock(**{"size": Size(spec="2 MiB")}),
- Mock(**{"size": Size(spec="2 MiB")})],
+ Mock(**{"size": Size(spec="4 MiB"),
+ "format": getFormat("mdmember")}),
+ Mock(**{"size": Size(spec="4 MiB"),
+ "format": getFormat("mdmember")}),
+ Mock(**{"size": Size(spec="2 MiB"),
+ "format": getFormat("mdmember")}),
+ Mock(**{"size": Size(spec="2 MiB"),
+ "format": getFormat("mdmember")})],
totalDevices=5)
@@ -367,14 +395,16 @@ class MDRaidArrayDeviceTestCase(DeviceStateTestCase):
"invalid RAID level",
MDRaidArrayDevice,
"dev",
- parents=[Device("parent")])
+ parents=[StorageDevice("parent",
+ format=getFormat("mdmember"))])
self.assertRaisesRegexp(DeviceError,
"set requires at least 2 members",
MDRaidArrayDevice,
"dev",
level="raid0",
- parents=[Device("parent")])
+ parents=[StorageDevice("parent",
+ format=getFormat("mdmember"))])
self.assertRaisesRegexp(mdraid.MDRaidError,
"invalid RAID level descriptor junk",
@@ -464,7 +494,7 @@ class BTRFSDeviceTestCase(DeviceStateTestCase):
"dev")
self.assertRaisesRegexp(ValueError,
- "member device.*is not BTRFS",
+ "member has wrong format",
BTRFSVolumeDevice,
"dev", parents=[OpticalDevice("deva")])
--
1.8.5.3
More information about the anaconda-patches
mailing list