From: "Samantha N. Bueno" sbueno+anaconda@redhat.com
The two dependencies we're eliminating here: blivet.osinstall.StorageDiscoveryConfig blivet.osinstall.find_existing_installations This has the added benefit of eliminating depedence on pykickstart.constants.
Unfortunately this means changing a lot of stuff all at once, but these are mostly moves without any changes. Stuff that's now out of blivet.blivet.Blivet and now in blivet.osinstall.InstallerStorageConfig: autopart_type (attr) _free_space_snapshot (attr) free_space_snapshot (prop) create_free_space_snapshot
Things which were changed in blivet.blivet.Blivet to eliminate dependence on anything in blivet.osinstall: reset get_free_space Those two methods exist as they originally were in blivet.osinstall.InstallerStorageConfig now.
InstallerStorageConfig instantiates its own devicetree now. This is mostly to keep track of all those installer-specific goodies (e.g. protected_dev_spacs). As a result of us now passing that attr in, modified headers in devicetree and populator init/reset methods to optionally handle this attr.
iSCSI, FCoE, and zFCP startup/config writes now take place in InstallerStorageConfig. --- blivet/autopart.py | 4 +- blivet/blivet.py | 82 ++--------------- blivet/devicetree.py | 8 +- blivet/osinstall.py | 205 +++++++----------------------------------- blivet/populator/populator.py | 9 +- 5 files changed, 53 insertions(+), 255 deletions(-)
diff --git a/blivet/autopart.py b/blivet/autopart.py index a75c567..a530a7c 100644 --- a/blivet/autopart.py +++ b/blivet/autopart.py @@ -110,8 +110,8 @@ def _get_candidate_disks(storage): for a default-sized (500MiB) partition. They must also be in :attr:`StorageDiscoveryConfig.clear_part_disks` if it is non-empty.
- :param storage: a Blivet instance - :type storage: :class:`~.Blivet` + :param storage: an InstallerStorageConfig instance + :type storage: :class:`~.osinstall.InstallerStorageConfig` :returns: a list of partitioned disks with at least 500MiB of free space :rtype: list of :class:`~.devices.StorageDevice` """ diff --git a/blivet/blivet.py b/blivet/blivet.py index a3b7407..ca403e0 100644 --- a/blivet/blivet.py +++ b/blivet/blivet.py @@ -28,8 +28,6 @@ import parted import functools
-from pykickstart.constants import AUTOPART_TYPE_LVM - from .storage_log import log_method_call, log_exception_info from .devices import BTRFSSubVolumeDevice, BTRFSVolumeDevice from .devices import LVMLogicalVolumeDevice, LVMVolumeGroupDevice @@ -46,11 +44,7 @@ from .flags import flags from .platform import platform as _platform from .formats import get_format -from .osinstall import StorageDiscoveryConfig find_existing_installations from . import arch -from .iscsi import iscsi -from .fcoe import fcoe -from .zfcp import zfcp from . import devicefactory from . import get_bootloader, get_sysroot, short_product_name, __version__ from .threads import SynchronizedMeta @@ -71,13 +65,10 @@ def __init__(self, ksdata=None): self.ksdata = ksdata self._bootloader = None
- self.config = StorageDiscoveryConfig() - # storage configuration variables self.do_autopart = False self.clear_part_choice = None self.encrypted_autopart = False - self.autopart_type = AUTOPART_TYPE_LVM self.encryption_passphrase = None self.encryption_cipher = None self.escrow_certificates = {} @@ -106,7 +97,6 @@ def __init__(self, ksdata=None): disk_images=self.disk_images) self.roots = [] self.services = set() - self._free_space_snapshot = None
def do_it(self, callbacks=None): """ @@ -207,20 +197,6 @@ def reset(self, cleanup_only=False): about the cleanup_only keyword argument. """ log.info("resetting Blivet (version %s) instance %s", __version__, self) - if flags.installer_mode: - # save passphrases for luks devices so we don't have to reprompt - self.encryption_passphrase = None - for device in self.devices: - if device.format.type == "luks" and device.format.exists: - self.save_passphrase(device) - - if self.ksdata: - self.config.update(self.ksdata) - - if flags.installer_mode and not flags.image_install: - iscsi.startup() - fcoe.startup() - zfcp.startup()
self.devicetree.reset(passphrase=self.encryption_passphrase, luks_dict=self.__luks_devs, @@ -235,14 +211,6 @@ def reset(self, cleanup_only=False): # no longer in the tree self.bootloader.reset()
- self.roots = [] - if flags.installer_mode: - self.roots = find_existing_installations(self.devicetree) - self.dump_state("initial") - - if not flags.installer_mode: - self.devicetree.handle_nodev_filesystems() - self.update_bootloader_disk_list()
@property @@ -493,23 +461,20 @@ def remove_empty_extended_partitions(self): extended = self.devicetree.get_device_by_name(extended_name) self.destroy_device(extended)
- def get_free_space(self, disks=None, clear_part_type=None): + def get_free_space(self, disks=None, partitions=None): """ Return a dict with free space info for each disk.
The dict values are 2-tuples: (disk_free, fs_free). fs_free is space available by shrinking filesystems. disk_free is space not allocated to any partition.
- disks and clear_part_type allow specifying a set of disks other than - self.disks and a clear_part_type value other than - self.config.clear_part_type. + disks and partitions allow specifying a set of disks other than + self.disks and partition values other than self.parttions.
:keyword disks: overrides :attr:`disks` :type disks: list - :keyword clear_part_type: overrides :attr:`self.config.clear_part_type` - :type clear_part_type: int - :returns: dict with disk name keys and tuple (disk, fs) free values - :rtype: dict + :keyword partitions: overrides :attr:`partitions` + :type partitions: list
.. note::
@@ -519,31 +484,17 @@ def get_free_space(self, disks=None, clear_part_type=None): if disks is None: disks = self.disks
- if clear_part_type is None: - clear_part_type = self.config.clear_part_type + if partitions is None: + partitions = self.partitions
free = {} for disk in disks: - should_clear = self.should_clear(disk, clear_part_type=clear_part_type, - clear_part_disks=[disk.name]) - if should_clear: - free[disk.name] = (disk.size, Size(0)) - continue - disk_free = Size(0) fs_free = Size(0) if disk.partitioned: disk_free = disk.format.free - for partition in [p for p in self.partitions if p.disk == disk]: - # only check actual filesystems since lvm &c require a bunch of - # operations to translate free filesystem space into free disk - # space - should_clear = self.should_clear(partition, - clear_part_type=clear_part_type, - clear_part_disks=[disk.name]) - if should_clear: - disk_free += partition.size - elif hasattr(partition.format, "free"): + for partition in [p for p in partitions if p.disk == disk]: + if hasattr(partition.format, "free"): fs_free += partition.format.free elif hasattr(disk.format, "free"): fs_free = disk.format.free @@ -1123,9 +1074,6 @@ def write(self): if not os.path.isdir("%s/etc" % get_sysroot()): os.mkdir("%s/etc" % get_sysroot())
- iscsi.write(get_sysroot(), self) - fcoe.write(get_sysroot()) - zfcp.write(get_sysroot()) self.write_dasd_conf(get_sysroot())
def write_dasd_conf(self, root): @@ -1425,15 +1373,3 @@ def copy(self):
log.debug("finished Blivet copy") return new - - @property - def free_space_snapshot(self): - # if no snapshot is available, do it now and return it - self._free_space_snapshot = self._free_space_snapshot or self.get_free_space() - - return self._free_space_snapshot - - def create_free_space_snapshot(self): - self._free_space_snapshot = self.get_free_space() - - return self._free_space_snapshot diff --git a/blivet/devicetree.py b/blivet/devicetree.py index d10d36d..911c949 100644 --- a/blivet/devicetree.py +++ b/blivet/devicetree.py @@ -899,12 +899,12 @@ def _hide_ignored_disks(self):
class DeviceTree(DeviceTreeBase, PopulatorMixin, EventHandlerMixin): - def __init__(self, passphrase=None, luks_dict=None, ignored_disks=None, exclusive_disks=None, disk_images=None): + def __init__(self, passphrase=None, luks_dict=None, ignored_disks=None, exclusive_disks=None, disk_images=None, protected_dev_specs=None): DeviceTreeBase.__init__(self, ignored_disks=ignored_disks, exclusive_disks=exclusive_disks) - PopulatorMixin.__init__(self, passphrase=passphrase, luks_dict=luks_dict, disk_images=disk_images) + PopulatorMixin.__init__(self, passphrase=passphrase, luks_dict=luks_dict, disk_images=disk_images, protected_dev_specs=protected_dev_specs) EventHandlerMixin.__init__(self)
# pylint: disable=arguments-differ - def reset(self, passphrase=None, luks_dict=None, ignored_disks=None, exclusive_disks=None, disk_images=None): + def reset(self, passphrase=None, luks_dict=None, ignored_disks=None, exclusive_disks=None, disk_images=None, protected_dev_specs=None): DeviceTreeBase.reset(self, ignored_disks=ignored_disks, exclusive_disks=exclusive_disks) - PopulatorMixin.reset(self, passphrase=passphrase, luks_dict=luks_dict, disk_images=disk_images) + PopulatorMixin.reset(self, passphrase=passphrase, luks_dict=luks_dict, disk_images=disk_images, protected_dev_specs=protected_dev_specs) diff --git a/blivet/osinstall.py b/blivet/osinstall.py index 75f67c4..d110782 100644 --- a/blivet/osinstall.py +++ b/blivet/osinstall.py @@ -31,9 +31,9 @@
from gi.repository import BlockDev as blockdev
-from pykickstart.constants import CLEARPART_TYPE_NONE, CLEARPART_TYPE_LINUX, CLEARPART_TYPE_ALL, CLEARPART_TYPE_LIST +from pykickstart.constants import AUTOPART_TYPE_LVM, CLEARPART_TYPE_NONE, CLEARPART_TYPE_LINUX, CLEARPART_TYPE_ALL, CLEARPART_TYPE_LIST
-from . import util +from . import util, __version__ from . import get_sysroot, get_target_physical_root, error_handler, ERROR_RAISE
from .blivet import Blivet @@ -41,10 +41,15 @@ from .devices import FileDevice, NFSDevice, NoDevice, OpticalDevice, NetworkStorageDevice, DirectoryDevice from .devices import PartitionDevice, BTRFSSubVolumeDevice, TmpFSDevice, LVMLogicalVolumeDevice, LVMVolumeGroupDevice from .devices import MDRaidArrayDevice, BTRFSDevice +from .devicelibs.edd import get_edd_dict +from .devicetree import DeviceTree from .errors import FSTabTypeMismatchError, UnrecognizedFSTabEntryError, StorageError, FSResizeError, FormatResizeError, UnknownSourceDeviceError from .formats import get_device_format_class from .formats import get_format from .flags import flags +from .iscsi import iscsi +from .fcoe import fcoe +from .zfcp import zfcp from .platform import platform as _platform from .platform import EFI from .size import Size @@ -313,7 +318,7 @@ def update(self, ksdata): self.clear_part_type = ksdata.clearpart.type self.clear_part_disks = ksdata.clearpart.drives[:] self.clear_part_devices = ksdata.clearpart.devices[:] - self.initialize_disks = ksdata.clearpart.init_all + self.initialize_disks = ksdata.clearpart.initAll self.zero_mbr = ksdata.zerombr.zerombr
@@ -1163,7 +1168,7 @@ def reset(self, cleanup_only=False): # no longer in the tree self.bootloader.reset() if self.ksdata: - self.config.updates(self.ksdata) + self.config.update(self.ksdata) self.roots = [] if flags.installer_mode: self.roots = find_existing_installations(self.devicetree) @@ -1395,176 +1400,22 @@ def _update_custom_storage_ksdata(self): parent = getattr(self.ksdata, list_attr) parent.dataList().append(data)
- self.fsset = FSSet(self.devicetree) + self.config = StorageDiscoveryConfig() + self.autopart_type = AUTOPART_TYPE_LVM
- def reset(self, cleanup_only=False): - Blivet.reset(self, cleanup_only) + self.__luks_devs = {}
+ # these will both be empty until our reset method gets called + # instantiate our own devicetree here to override the default created + # in Blivet so that protected_dev_specs gets handled + self.devicetree = DeviceTree(passphrase=self.encryption_passphrase, + luks_dict=self.__luks_devs, + ignored_disks=self.ignored_disks, + exclusive_disks=self.exclusive_disks, + disk_images=self.disk_images, + protected_dev_specs=self.config.protected_dev_specs) self.fsset = FSSet(self.devicetree) - - def write(self): - Blivet.write(self) - - self.fsset.write() - self.make_mtab() - - @property - def boot_device(self): - dev = None - if self.fsset: - dev = self.mountpoints.get("/boot", self.root_device) - return dev - - @property - def mountpoints(self): - return self.fsset.mountpoints - - @property - def root_device(self): - return self.fsset.root_device - - @property - def file_system_free_space(self): - """ Combined free space in / and /usr as :class:`~.size.Size`. """ - mountpoints = ["/", "/usr"] - free = Size(0) - btrfs_volumes = [] - for mountpoint in mountpoints: - device = self.mountpoints.get(mountpoint) - if not device: - continue - - # don't count the size of btrfs volumes repeatedly when multiple - # subvolumes are present - if isinstance(device, BTRFSSubVolumeDevice): - if device.volume in btrfs_volumes: - continue - else: - btrfs_volumes.append(device.volume) - - if device.format.exists: - free += device.format.free - else: - free += device.format.free_space_estimate(device.size) - - return free - def update_ksdata(self): - """ Update ksdata to reflect the settings of this Blivet instance. """ - if not self.ksdata or not self.mountpoints: - return - - # clear out whatever was there before - self.ksdata.partition.partitions = [] - self.ksdata.logvol.lvList = [] - self.ksdata.raid.raidList = [] - self.ksdata.volgroup.vgList = [] - self.ksdata.btrfs.btrfsList = [] - - # iscsi? - # fcoe? - # zfcp? - # dmraid? - - # bootloader - - # ignoredisk - if self.ignored_disks: - self.ksdata.ignoredisk.drives = self.ignored_disks[:] - elif self.exclusive_disks: - self.ksdata.ignoredisk.onlyuse = self.exclusive_disks[:] - - # autopart - self.ksdata.autopart.autopart = self.do_autopart - self.ksdata.autopart.type = self.autopart_type - self.ksdata.autopart.encrypted = self.encrypted_autopart - - # clearpart - self.ksdata.clearpart.type = self.config.clear_part_type - self.ksdata.clearpart.drives = self.config.clear_part_disks[:] - self.ksdata.clearpart.devices = self.config.clear_part_devices[:] - self.ksdata.clearpart.initAll = self.config.initialize_disks - if self.ksdata.clearpart.type == CLEARPART_TYPE_NONE: - # Make a list of initialized disks and of removed partitions. If any - # partitions were removed from disks that were not completely - # cleared we'll have to use CLEARPART_TYPE_LIST and provide a list - # of all removed partitions. If no partitions were removed from a - # disk that was not cleared/reinitialized we can use - # CLEARPART_TYPE_ALL. - self.ksdata.clearpart.devices = [] - self.ksdata.clearpart.drives = [] - fresh_disks = [d.name for d in self.disks if d.partitioned and - not d.format.exists] - - destroy_actions = self.devicetree.actions.find(action_type="destroy", - object_type="device") - - cleared_partitions = [] - partial = False - for action in destroy_actions: - if action.device.type == "partition": - if action.device.disk.name not in fresh_disks: - partial = True - - cleared_partitions.append(action.device.name) - - if not destroy_actions: - pass - elif partial: - # make a list of removed partitions - self.ksdata.clearpart.type = CLEARPART_TYPE_LIST - self.ksdata.clearpart.devices = cleared_partitions - else: - # if they didn't partially clear any disks, use the shorthand - self.ksdata.clearpart.type = CLEARPART_TYPE_ALL - self.ksdata.clearpart.drives = fresh_disks - - if self.do_autopart: - return - - self._update_custom_storage_ksdata() - - def _update_custom_storage_ksdata(self): - """ Update KSData for custom storage. """ - - # custom storage - ks_map = {PartitionDevice: ("PartData", "partition"), - TmpFSDevice: ("PartData", "partition"), - LVMLogicalVolumeDevice: ("LogVolData", "logvol"), - LVMVolumeGroupDevice: ("VolGroupData", "volgroup"), - MDRaidArrayDevice: ("RaidData", "raid"), - BTRFSDevice: ("BTRFSData", "btrfs")} - - # make a list of ancestors of all used devices - devices = list(set(a for d in list(self.mountpoints.values()) + self.swaps - for a in d.ancestors)) - - # devices which share information with their distinct raw device - complementary_devices = [d for d in devices if d.raw_device is not d] - - devices.sort(key=lambda d: len(d.ancestors)) - for device in devices: - cls = next((c for c in ks_map if isinstance(device, c)), None) - if cls is None: - log.info("omitting ksdata: %s", device) - continue - - class_attr, list_attr = ks_map[cls] - - cls = getattr(self.ksdata, class_attr) - data = cls() # all defaults - - complements = [d for d in complementary_devices if d.raw_device is device] - - if len(complements) > 1: - log.warning("omitting ksdata for %s, found too many (%d) complementary devices", device, len(complements)) - continue - - device = complements[0] if complements else device - - device.populate_ksdata(data) - - parent = getattr(self.ksdata, list_attr) - parent.dataList().append(data) + self._free_space_snapshot = None
def empty_device(self, device): empty = True @@ -1805,6 +1656,18 @@ def make_mtab(self):
os.symlink(target, path)
+ @property + def free_space_snapshot(self): + # if no snapshot is available, do it now and return it + self._free_space_snapshot = self._free_space_snapshot or self.get_free_space() + + return self._free_space_snapshot + + def create_free_space_snapshot(self): + self._free_space_snapshot = self.get_free_space() + + return self._free_space_snapshot + def add_fstab_swap(self, device): """ Add swap device to the list of swaps that should appear in the fstab. diff --git a/blivet/populator/populator.py b/blivet/populator/populator.py index 54fd53e..8661efd 100644 --- a/blivet/populator/populator.py +++ b/blivet/populator/populator.py @@ -63,7 +63,7 @@ def parted_exn_handler(exn_type, exn_options, exn_msg):
class PopulatorMixin(object, metaclass=SynchronizedMeta): - def __init__(self, passphrase=None, luks_dict=None, disk_images=None): + def __init__(self, passphrase=None, luks_dict=None, disk_images=None, protected_dev_specs=None): """ :keyword passphrase: default LUKS passphrase :keyword luks_dict: a dict with UUID keys and passphrase values @@ -72,17 +72,16 @@ def __init__(self, passphrase=None, luks_dict=None, disk_images=None): :type list: dict
""" - self.reset(passphrase=passphrase, luks_dict=luks_dict, disk_images=disk_images) + self.reset(passphrase=passphrase, luks_dict=luks_dict, disk_images=disk_images, protected_dev_specs=protected_dev_specs)
- def reset(self, conf=None, passphrase=None, luks_dict=None): - def reset(self, passphrase=None, luks_dict=None, disk_images=None): + def reset(self, passphrase=None, luks_dict=None, disk_images=None, protected_dev_specs=None): self.disk_images = {} if disk_images: # this will overwrite self.exclusive_disks self.set_disk_images(disk_images)
# protected device specs as provided by the user - self.protected_dev_specs = getattr(conf, "protected_dev_specs", []) + self.protected_dev_specs = protected_dev_specs self.live_backing_device = None
# names of protected devices at the time of tree population
anaconda-patches@lists.fedorahosted.org