[master 1/1] Consolidate common code in DeviceFormat class methods.
dwlehman
installerbot-noreply at redhat.com
Tue Apr 7 18:36:04 UTC 2015
From: David Lehman <dlehman at redhat.com>
This mirrors what was done long ago for the Device classes. The intention
is to improve consistency and reduce code duplication.
create and destroy are just split into pre/body/post with no way to bail.
setup and teardown pre methods return a boolean telling whether or not to
proceed with the operation.
---
blivet/formats/__init__.py | 88 +++++++++++++++++++++++++++--
blivet/formats/disklabel.py | 22 +-------
blivet/formats/fs.py | 133 +++++++++++++++++---------------------------
blivet/formats/luks.py | 91 ++++++++----------------------
blivet/formats/lvmpv.py | 54 ++++--------------
blivet/formats/mdraid.py | 17 +-----
blivet/formats/prepboot.py | 12 +---
blivet/formats/swap.py | 57 ++-----------------
8 files changed, 182 insertions(+), 292 deletions(-)
diff --git a/blivet/formats/__init__.py b/blivet/formats/__init__.py
index 4bd9105..0b56fef 100644
--- a/blivet/formats/__init__.py
+++ b/blivet/formats/__init__.py
@@ -367,6 +367,15 @@ def create(self, **kwargs):
"""
log_method_call(self, device=self.device,
type=self.type, status=self.status)
+ self._preCreate(**kwargs)
+ try:
+ self._create(**kwargs)
+ except Exception:
+ raise
+ self._postCreate(**kwargs)
+
+ def _preCreate(self, **kwargs):
+ """ Perform checks and setup prior to creating the format. """
# allow late specification of device path
device = kwargs.get("device")
if device:
@@ -375,21 +384,56 @@ def create(self, **kwargs):
if not os.path.exists(self.device):
raise FormatCreateError("invalid device specification", self.device)
+ if self.exists:
+ raise DeviceFormatError("format already exists")
+
+ if self.status:
+ raise DeviceFormatError("device exists and is active")
+
+ # pylint: disable=unused-argument
+ def _create(self, **kwargs):
+ """ Type-specific create method. """
+ pass
+
+ # pylint: disable=unused-argument
+ def _postCreate(self, **kwargs):
+ self.exists = True
+ self.notifyKernel()
+
def destroy(self, **kwargs):
""" Remove the formatting from the associated block device.
:raises: FormatDestroyError
:returns: None.
"""
- # pylint: disable=unused-argument
log_method_call(self, device=self.device,
type=self.type, status=self.status)
+ self._preDestroy(**kwargs)
+ try:
+ self._destroy(**kwargs)
+ except Exception:
+ raise
+ self._postDestroy(**kwargs)
+
+ # pylint: disable=unused-argument
+ def _preDestroy(self, **kwargs):
+ if not self.exists:
+ raise DeviceFormatError("format has not been created")
+
+ if self.status:
+ raise DeviceFormatError("device is active")
+
+ if not os.access(self.device, os.W_OK):
+ raise DeviceFormatError("device path does not exist")
+
+ def _destroy(self, **kwargs):
+ rc = 0
+ err = ""
try:
rc = run_program(["wipefs", "-f", "-a", self.device])
except OSError as e:
err = str(e)
else:
- err = ""
if rc:
err = str(rc)
@@ -397,7 +441,9 @@ def destroy(self, **kwargs):
msg = "error wiping old signatures from %s: %s" % (self.device, err)
raise FormatDestroyError(msg)
+ def _postDestroy(self, **kwargs):
self.exists = False
+ self.notifyKernel()
def setup(self, **kwargs):
""" Activate the formatting.
@@ -414,13 +460,17 @@ def setup(self, **kwargs):
"""
log_method_call(self, device=self.device,
type=self.type, status=self.status)
+ if not self._preSetup(**kwargs):
+ return
+
+ self._setup(**kwargs)
+ self._postSetup(**kwargs)
+ def _preSetup(self, **kwargs):
+ """ Return True if setup should proceed. """
if not self.exists:
raise FormatSetupError("format has not been created")
- if self.status:
- return
-
# allow late specification of device path
device = kwargs.get("device")
if device:
@@ -429,10 +479,38 @@ def setup(self, **kwargs):
if not self.device or not os.path.exists(self.device):
raise FormatSetupError("invalid device specification")
+ return not self.status
+
+ # pylint: disable=unused-argument
+ def _setup(self, **kwargs):
+ pass
+
+ # pylint: disable=unused-argument
+ def _postSetup(self, **kwargs):
+ pass
+
def teardown(self):
""" Deactivate the formatting. """
log_method_call(self, device=self.device,
type=self.type, status=self.status)
+ if not self._preTeardown():
+ return
+
+ self._teardown()
+ self._postTeardown()
+
+ def _preTeardown(self):
+ """ Return True if teardown should proceed. """
+ if not self.exists:
+ raise DeviceFormatError("format has not been created")
+
+ return self.status
+
+ def _teardown(self):
+ pass
+
+ def _postTeardown(self):
+ pass
@property
def status(self):
diff --git a/blivet/formats/disklabel.py b/blivet/formats/disklabel.py
index ed42bef..70dff6c 100644
--- a/blivet/formats/disklabel.py
+++ b/blivet/formats/disklabel.py
@@ -25,7 +25,7 @@
from ..storage_log import log_exception_info, log_method_call
import parted
import _ped
-from ..errors import DeviceFormatError, DiskLabelCommitError, InvalidDiskLabelError
+from ..errors import DiskLabelCommitError, InvalidDiskLabelError
from .. import arch
from .. import udev
from .. import util
@@ -229,37 +229,21 @@ def status(self):
""" Device status. """
return False
- def create(self, **kwargs):
+ def _create(self, **kwargs):
""" Create the device. """
log_method_call(self, device=self.device,
type=self.type, status=self.status)
- if self.exists:
- raise DeviceFormatError("format already exists")
-
- if self.status:
- raise DeviceFormatError("device exists and is active")
-
- DeviceFormat.create(self, **kwargs)
-
# We're relying on someone having called resetPartedDisk -- we
# could ensure a fresh disklabel by setting self._partedDisk to
# None right before calling self.commit(), but that might hide
# other problems.
self.commit()
- self.exists = True
- def destroy(self, **kwargs):
+ def _destroy(self, **kwargs):
""" Wipe the disklabel from the device. """
log_method_call(self, device=self.device,
type=self.type, status=self.status)
- if not self.exists:
- raise DeviceFormatError("format does not exist")
-
- if not os.access(self.device, os.W_OK):
- raise DeviceFormatError("device path does not exist")
-
self.partedDevice.clobber()
- self.exists = False
def commit(self):
""" Commit the current partition table to disk and notify the OS. """
diff --git a/blivet/formats/fs.py b/blivet/formats/fs.py
index 4e3d39f..eee386a 100644
--- a/blivet/formats/fs.py
+++ b/blivet/formats/fs.py
@@ -386,7 +386,12 @@ def _getFormatOptions(self, options=None, do_labeling=False):
argv.append(self.device)
return argv
- def doFormat(self, options=None):
+ def _preCreate(self, **kwargs):
+ super(FS, self)._preCreate(**kwargs)
+ if not self.mkfsProg:
+ return
+
+ def _create(self, **kwargs):
""" Create the filesystem.
:param options: options to pass to mkfs
@@ -395,22 +400,14 @@ def doFormat(self, options=None):
"""
log_method_call(self, type=self.mountType, device=self.device,
mountpoint=self.mountpoint)
-
- if self.exists:
- raise FormatCreateError("filesystem already exists", self.device)
-
if not self.formattable:
return
- if not self.mkfsProg:
- return
-
- if not os.path.exists(self.device):
- raise FormatCreateError("device does not exist", self.device)
-
- argv = self._getFormatOptions(options=options,
+ argv = self._getFormatOptions(options=kwargs.get("options"),
do_labeling=not self.relabels())
+ super(FS, self)._create()
+ ret = 0
try:
ret = util.run_program([self.mkfsProg] + argv)
except OSError as e:
@@ -419,9 +416,8 @@ def doFormat(self, options=None):
if ret:
raise FormatCreateError("format failed: %s" % ret, self.device)
- self.exists = True
- self.notifyKernel()
-
+ def _postCreate(self, **kwargs):
+ super(FS, self)._postCreate(**kwargs)
if self.label is not None and self.relabels():
try:
self.writeLabel()
@@ -620,30 +616,32 @@ def testMount(self):
return ret
- def mount(self, options="", chroot="/", mountpoint=None):
- """ Mount this filesystem.
-
- :keyword options: mount options (overrides all other option strings)
- :type options: str.
- :keyword chroot: prefix to apply to mountpoint
- :keyword mountpoint: mountpoint (overrides self.mountpoint)
- :raises: FSError
- """
+ def _preSetup(self, **kwargs):
if not self.exists:
raise FSError("filesystem has not been created")
- if not mountpoint:
- mountpoint = self.mountpoint
-
+ mountpoint = kwargs.get("mountpoint") or self.mountpoint
if not mountpoint:
raise FSError("no mountpoint given")
- if self.status:
- return
-
if not isinstance(self, NoDevFS) and not os.path.exists(self.device):
raise FSError("device %s does not exist" % self.device)
+ return not self.status
+
+ def _setup(self, **kwargs):
+ """ Mount this filesystem.
+
+ :keyword options: mount options (overrides all other option strings)
+ :type options: str.
+ :keyword chroot: prefix to apply to mountpoint
+ :keyword mountpoint: mountpoint (overrides self.mountpoint)
+ :raises: FSError
+ """
+ options = kwargs.get("options", "")
+ chroot = kwargs.get("chroot", "/")
+ mountpoint = kwargs.get("mountpoint") or self.mountpoint
+
# XXX os.path.join is FUBAR:
#
# os.path.join("/mnt/foo", "/") -> "/"
@@ -668,6 +666,11 @@ def mount(self, options="", chroot="/", mountpoint=None):
if rc:
raise FSError("mount failed: %s" % rc)
+ def _postSetup(self, **kwargs):
+ options = kwargs.get("options", "")
+ chroot = kwargs.get("chroot", "/")
+ mountpoint = kwargs.get("mountpoint") or self.mountpoint
+
if flags.selinux and "ro" not in options.split(",") and flags.installer_mode:
ret = util.reset_file_context(mountpoint, chroot)
if not ret:
@@ -678,19 +681,25 @@ def mount(self, options="", chroot="/", mountpoint=None):
if not ret:
log.warning("Failed to set SELinux context for newly mounted filesystem lost+found directory at %s to %s", lost_and_found_path, lost_and_found_context)
- def unmount(self):
+ def _preTeardown(self):
""" Unmount this filesystem. """
- if not self.exists:
- raise FSError("filesystem has not been created")
+ if not super(FS, self)._preTeardown():
+ return False
if not self.systemMountpoint:
# not mounted
- return
+ return False
if not os.path.exists(self.systemMountpoint):
raise FSError("mountpoint does not exist")
udev.settle()
+
+ return True
+
+ def _teardown(self):
+ """ Unmount this filesystem. """
+ udev.settle()
rc = util.umount(self.systemMountpoint)
if rc:
# try and catch whatever is causing the umount problem
@@ -858,27 +867,7 @@ def mountType(self):
# These methods just wrap filesystem-specific methods in more
# generically named methods so filesystems and formatted devices
# like swap and LVM physical volumes can have a common API.
- def create(self, **kwargs):
- """ Create the filesystem on the specified block device.
-
- :keyword device: path to device node
- :type device: str.
- :raises: FormatCreateError, FSError
- :returns: None.
-
- .. :note::
-
- If a device node path is passed to this method it will overwrite
- any previously set value of this instance's "device" attribute.
- """
- if self.exists:
- raise FSError("filesystem already exists")
-
- DeviceFormat.create(self, **kwargs)
-
- self.doFormat(options=kwargs.get('options'))
-
- def setup(self, **kwargs):
+ def mount(self, **kwargs):
""" Mount the filesystem.
The filesystem will be mounted at the directory indicated by
@@ -896,10 +885,10 @@ def setup(self, **kwargs):
If a device node path is passed to this method it will overwrite
any previously set value of this instance's "device" attribute.
"""
- return self.mount(**kwargs)
+ return self.setup(**kwargs)
- def teardown(self):
- return self.unmount()
+ def unmount(self):
+ return self.teardown()
@property
def status(self):
@@ -1139,32 +1128,12 @@ def destroy(self, **kwargs):
# filesystem deletion is done in blockdev.btrfs_delete_volume
self.exists = False
- def setup(self, **kwargs):
- """ Mount the filesystem.
-
- The filesystem will be mounted at the directory indicated by
- self.mountpoint unless overridden via the 'mountpoint' kwarg.
-
- :keyword device: device node path
- :type device: str.
- :keyword mountpoint: mountpoint (overrides self.mountpoint)
- :type mountpoint: str.
- :raises: FormatSetupError.
- :returns: None.
-
- .. :note::
-
- If a device node path is passed to this method it will overwrite
- any previously set value of this instance's "device" attribute.
- """
+ def _preSetup(self, **kwargs):
log_method_call(self, type=self.mountType, device=self.device,
mountpoint=self.mountpoint)
- if not self.mountpoint and "mountpoint" not in kwargs:
- # Since btrfs vols have subvols the format setup is automatic.
- # Don't try to mount it if there's no mountpoint.
- return
-
- return self.mount(**kwargs)
+ # Since btrfs vols have subvols the format setup is automatic.
+ # Don't try to mount it if there's no mountpoint.
+ return self.mountpoint or kwargs.get("mountpoint")
register_device_format(BTRFS)
diff --git a/blivet/formats/luks.py b/blivet/formats/luks.py
index a5abc4d..43de6c1 100644
--- a/blivet/formats/luks.py
+++ b/blivet/formats/luks.py
@@ -160,90 +160,47 @@ def status(self):
return False
return os.path.exists("/dev/mapper/%s" % self.mapName)
- def setup(self, **kwargs):
- """ Open the encrypted block device.
-
- :keyword device: device node path
- :type device: str.
- :raises: FormatSetupError.
- :returns: None.
-
- .. :note::
-
- If a device node path is passed to this method it will overwrite
- any previously set value of this instance's "device" attribute.
- """
- log_method_call(self, device=self.device, mapName=self.mapName,
- type=self.type, status=self.status)
+ def _preSetup(self, **kwargs):
if not self.configured:
raise LUKSError("luks device not configured")
- if self.status:
- return
+ return super(LUKS, self)._preSetup(**kwargs)
- DeviceFormat.setup(self, **kwargs)
+ def _setup(self, **kwargs):
+ log_method_call(self, device=self.device, mapName=self.mapName,
+ type=self.type, status=self.status)
blockdev.crypto_luks_open(self.device, self.mapName,
passphrase=self.__passphrase,
key_file=self._key_file)
- def teardown(self):
+ def _teardown(self):
""" Close, or tear down, the format. """
log_method_call(self, device=self.device,
type=self.type, status=self.status)
- if not self.exists:
- raise LUKSError("format has not been created")
-
- if self.status:
- log.debug("unmapping %s", self.mapName)
- blockdev.crypto_luks_close(self.mapName)
-
- def create(self, **kwargs):
- """ Write the formatting to the specified block device.
-
- :keyword device: path to device node
- :type device: str.
- :raises: FormatCreateError
- :returns: None.
+ log.debug("unmapping %s", self.mapName)
+ blockdev.crypto_luks_close(self.mapName)
- .. :note::
-
- If a device node path is passed to this method it will overwrite
- any previously set value of this instance's "device" attribute.
- """
- log_method_call(self, device=self.device,
- type=self.type, status=self.status)
+ def _preCreate(self, **kwargs):
+ super(LUKS, self)._preCreate(**kwargs)
if not self.hasKey:
raise LUKSError("luks device has no key/passphrase")
- try:
- DeviceFormat.create(self, **kwargs)
- blockdev.crypto_luks_format(self.device,
- passphrase=self.__passphrase,
- key_file=self._key_file,
- cipher=self.cipher,
- key_size=self.key_size,
- min_entropy=self.min_luks_entropy)
-
- except Exception:
- raise
- else:
- self.uuid = blockdev.crypto_luks_uuid(self.device)
- self.exists = True
- if flags.installer_mode:
- self.mapName = "luks-%s" % self.uuid
-
- self.notifyKernel()
-
- def destroy(self, **kwargs):
- """ Remove the formatting from the associated block device.
-
- :raises: FormatDestroyError
- :returns: None.
- """
+ def _create(self, **kwargs):
log_method_call(self, device=self.device,
type=self.type, status=self.status)
- self.teardown()
- DeviceFormat.destroy(self, **kwargs)
+ super(LUKS, self)._create(**kwargs) # set up the event sync
+ blockdev.crypto_luks_format(self.device,
+ passphrase=self.__passphrase,
+ key_file=self._key_file,
+ cipher=self.cipher,
+ key_size=self.key_size,
+ min_entropy=self.min_luks_entropy)
+
+ def _postCreate(self, **kwargs):
+ super(LUKS, self)._postCreate(**kwargs)
+ self.uuid = blockdev.crypto_luks_uuid(self.device)
+ if flags.installer_mode or not self.mapName:
+ self.mapName = "luks-%s" % self.uuid
@property
def keyFile(self):
diff --git a/blivet/formats/lvmpv.py b/blivet/formats/lvmpv.py
index 069cccf..e47ac1b 100644
--- a/blivet/formats/lvmpv.py
+++ b/blivet/formats/lvmpv.py
@@ -26,7 +26,6 @@
from ..storage_log import log_method_call
from parted import PARTITION_LVM
-from ..errors import PhysicalVolumeError
from ..devicelibs import lvm
from ..i18n import N_
from ..size import Size
@@ -96,55 +95,29 @@ def dict(self):
"peStart": self.peStart, "dataAlignment": self.dataAlignment})
return d
- def create(self, **kwargs):
- """ Write the formatting to the specified block device.
-
- :keyword device: path to device node
- :type device: str
- :raises: FormatCreateError
- :returns: None.
-
- .. :note::
-
- If a device node path is passed to this method it will overwrite
- any previously set value of this instance's "device" attribute.
- """
+ def _create(self, **kwargs):
log_method_call(self, device=self.device,
type=self.type, status=self.status)
- try:
- DeviceFormat.create(self, **kwargs)
- # Consider use of -Z|--zero
- # -f|--force or -y|--yes may be required
+ # Consider use of -Z|--zero
+ # -f|--force or -y|--yes may be required
- # lvm has issues with persistence of metadata, so here comes the
- # hammer...
+ # lvm has issues with persistence of metadata, so here comes the
+ # hammer...
+ self.exists = True
+ try:
DeviceFormat.destroy(self, **kwargs)
- blockdev.lvm_pvscan(self.device)
- blockdev.lvm_pvcreate(self.device, data_alignment=self.dataAlignment)
except Exception:
+ self.exists = False
raise
- finally:
- blockdev.lvm_pvscan(self.device)
-
- self.exists = True
- self.notifyKernel()
- def destroy(self, **kwargs):
- """ Remove the formatting from the associated block device.
+ blockdev.lvm_pvscan(self.device)
+ blockdev.lvm_pvcreate(self.device, data_alignment=self.dataAlignment)
+ blockdev.lvm_pvscan(self.device)
- :raises: FormatDestroyError
- :returns: None.
- """
+ def _destroy(self, **kwargs):
log_method_call(self, device=self.device,
type=self.type, status=self.status)
- if not self.exists:
- raise PhysicalVolumeError("format has not been created")
-
- if self.status:
- raise PhysicalVolumeError("device is active")
-
- # FIXME: verify path exists?
try:
blockdev.lvm_pvremove(self.device)
except GLib.GError:
@@ -152,9 +125,6 @@ def destroy(self, **kwargs):
finally:
blockdev.lvm_pvscan(self.device)
- self.exists = False
- self.notifyKernel()
-
@property
def status(self):
# XXX hack
diff --git a/blivet/formats/mdraid.py b/blivet/formats/mdraid.py
index f173a8d..1c7a02a 100644
--- a/blivet/formats/mdraid.py
+++ b/blivet/formats/mdraid.py
@@ -20,13 +20,10 @@
# Red Hat Author(s): Dave Lehman <dlehman at redhat.com>
#
-import os
-
from gi.repository import BlockDev as blockdev
from ..storage_log import log_method_call
from parted import PARTITION_RAID
-from ..errors import MDMemberError
from . import DeviceFormat, register_device_format
from ..flags import flags
from ..i18n import N_
@@ -77,20 +74,8 @@ def dict(self):
d.update({"mdUUID": self.mdUuid, "biosraid": self.biosraid})
return d
- def destroy(self, **kwargs):
- """ Remove the formatting from the associated block device.
-
- :raises: FormatDestroyError
- :returns: None.
- """
- if not self.exists:
- raise MDMemberError("format does not exist")
-
- if not os.access(self.device, os.W_OK):
- raise MDMemberError("device path does not exist")
-
+ def _destroy(self, **kwargs):
blockdev.md_destroy(self.device)
- self.exists = False
@property
def status(self):
diff --git a/blivet/formats/prepboot.py b/blivet/formats/prepboot.py
index 6655510..70240d5 100644
--- a/blivet/formats/prepboot.py
+++ b/blivet/formats/prepboot.py
@@ -20,7 +20,6 @@
# Red Hat Author(s): Dave Lehman <dlehman at redhat.com>
#
-from ..errors import FormatCreateError
from ..size import Size
from .. import platform
from ..i18n import N_
@@ -57,12 +56,11 @@ def __init__(self, **kwargs):
"""
DeviceFormat.__init__(self, **kwargs)
- def create(self, **kwargs):
+ def _create(self, **kwargs):
""" Write the formatting to the specified block device.
:keyword device: path to device node
:type device: str
- :raises: FormatCreateError
:returns: None.
.. :note::
@@ -70,11 +68,7 @@ def create(self, **kwargs):
If a device node path is passed to this method it will overwrite
any previously set value of this instance's "device" attribute.
"""
- if self.exists:
- raise FormatCreateError("PReP Boot format already exists")
-
- DeviceFormat.create(self, **kwargs)
-
+ super(PPCPRePBoot, self)._create(**kwargs)
try:
fd = os.open(self.device, os.O_RDWR)
length = os.lseek(fd, 0, os.SEEK_END)
@@ -88,9 +82,9 @@ def create(self, **kwargs):
buf = '\0' * length
os.write(fd, buf)
length = 0
- os.close(fd)
except OSError as e:
log.error("error zeroing out %s: %s", self.device, e)
+ finally:
if fd:
os.close(fd)
diff --git a/blivet/formats/swap.py b/blivet/formats/swap.py
index e355505..cf5ed61 100644
--- a/blivet/formats/swap.py
+++ b/blivet/formats/swap.py
@@ -22,7 +22,6 @@
from parted import PARTITION_SWAP, fileSystemType
from ..storage_log import log_method_call
-from ..errors import SwapSpaceError
from . import DeviceFormat, register_device_format
from ..size import Size
from gi.repository import BlockDev as blockdev
@@ -137,66 +136,20 @@ def status(self):
""" Device status. """
return self.exists and blockdev.swap_swapstatus(self.device)
- def setup(self, **kwargs):
- """ Activate the formatting.
-
- :keyword device: device node path
- :type device: str.
- :raises: FormatSetupError.
- :returns: None.
-
- .. :note::
-
- If a device node path is passed to this method it will overwrite
- any previously set value of this instance's "device" attribute.
- """
+ def _setup(self, **kwargs):
log_method_call(self, device=self.device,
type=self.type, status=self.status)
- if not self.exists:
- raise SwapSpaceError("format has not been created")
-
- if self.status:
- return
-
- DeviceFormat.setup(self, **kwargs)
blockdev.swap_swapon(self.device, priority=self.priority)
- def teardown(self):
+ def _teardown(self):
""" Close, or tear down, a device. """
log_method_call(self, device=self.device,
type=self.type, status=self.status)
- if not self.exists:
- raise SwapSpaceError("format has not been created")
+ blockdev.swap_swapoff(self.device)
- if self.status:
- blockdev.swap_swapoff(self.device)
-
- def create(self, **kwargs):
- """ Write the formatting to the specified block device.
-
- :keyword device: path to device node
- :type device: str.
- :raises: FormatCreateError
- :returns: None.
-
- .. :note::
-
- If a device node path is passed to this method it will overwrite
- any previously set value of this instance's "device" attribute.
- """
+ def _create(self, **kwargs):
log_method_call(self, device=self.device,
type=self.type, status=self.status)
- if self.exists:
- raise SwapSpaceError("format already exists")
-
- try:
- DeviceFormat.create(self, **kwargs)
- blockdev.swap_mkswap(self.device, label=self.label)
- except Exception:
- raise
- else:
- self.exists = True
- self.notifyKernel()
+ blockdev.swap_mkswap(self.device, label=self.label)
register_device_format(SwapSpace)
-
--
To view this commit on github, visit https://github.com/rhinstaller/blivet/commit/dbcfacb70e0e01502cf14f1db00f012d64de9f52
More information about the anaconda-patches
mailing list