anaconda/anaconda-40.22.3.13/pyanaconda/modules/storage/disk_initialization/configuration.py
2024-11-14 21:39:56 -08:00

146 lines
6.1 KiB
Python

#
# Configuration of the disk initialization.
#
# Copyright (C) 2019 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
# the GNU General Public License v.2, or (at your option) any later version.
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY expressed or implied, including the implied warranties of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details. You should have received a copy of the
# GNU General Public License along with this program; if not, write to the
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
# source code or documentation are not subject to the GNU General Public
# License and may only be used or replicated with the express permission of
# Red Hat, Inc.
#
import parted
from blivet.devices import PartitionDevice
from pyanaconda.anaconda_loggers import get_module_logger
from pyanaconda.core.constants import CLEAR_PARTITIONS_DEFAULT, CLEAR_PARTITIONS_NONE, \
CLEAR_PARTITIONS_LINUX, CLEAR_PARTITIONS_ALL, CLEAR_PARTITIONS_LIST
log = get_module_logger(__name__)
_all__ = ["DiskInitializationConfig"]
class DiskInitializationConfig(object):
"""Configuration of the disk initialization."""
def __init__(self):
self.initialization_mode = CLEAR_PARTITIONS_DEFAULT
self.drives_to_clear = []
self.devices_to_clear = []
self.initialize_labels = False
self.format_unrecognized = False
self.clear_non_existent = False
def can_remove(self, storage, device):
"""Can the given device be cleared based on the config?
:param storage: an instance of the Blivet's storage
:param device: an instance of the device we want to clear
:return: True or False
"""
for disk in device.disks:
# this will not include disks with hidden formats like multipath
# and firmware raid member disks
if self.drives_to_clear and disk.name not in self.drives_to_clear:
return False
if not self.clear_non_existent:
if (device.is_disk and not device.format.exists) or \
(not device.is_disk and not device.exists):
return False
# the only devices we want to clear when initialization_mode is
# CLEAR_PARTITIONS_NONE are uninitialized disks, or disks with no
# partitions, in drives_to_clear, and then only when we have been asked
# to initialize disks as needed
if self.initialization_mode in [CLEAR_PARTITIONS_NONE, CLEAR_PARTITIONS_DEFAULT]:
if not self.initialize_labels or not device.is_disk:
return False
if not device.is_empty:
return False
if isinstance(device, PartitionDevice):
# Never clear the special first partition on a Mac disk label, as
# that holds the partition table itself.
# Something similar for the third partition on a Sun disklabel.
if device.is_magic:
return False
# We don't want to fool with extended partitions, freespace, &c
if not device.is_primary and not device.is_logical:
return False
if self.initialization_mode == CLEAR_PARTITIONS_LINUX and \
not device.format.linux_native and \
not device.get_flag(parted.PARTITION_LVM) and \
not device.get_flag(parted.PARTITION_RAID) and \
not device.get_flag(parted.PARTITION_SWAP):
return False
elif device.is_disk:
if device.partitioned and self.initialization_mode != CLEAR_PARTITIONS_ALL:
# if initialization_mode is not CLEAR_PARTITIONS_ALL but we'll still be
# removing every partition from the disk, return True since we
# will want to be able to create a new disklabel on this disk
if not device.is_empty:
return False
# Never clear disks with hidden formats
if device.format.hidden:
return False
# When initialization_mode is CLEAR_PARTITIONS_LINUX and a disk has non-
# linux whole-disk formatting, do not clear it. The exception is
# the case of an uninitialized disk when we've been asked to
# initialize disks as needed
if (self.initialization_mode == CLEAR_PARTITIONS_LINUX and
not ((self.initialize_labels and device.is_empty) or
(not device.partitioned and device.format.linux_native))):
return False
# Don't clear devices holding install media.
descendants = storage.devicetree.get_dependent_devices(device)
if device.protected or any(d.protected for d in descendants):
return False
if self.initialization_mode == CLEAR_PARTITIONS_LIST and \
device.name not in self.devices_to_clear:
return False
return True
def can_initialize(self, storage, disk):
"""Can the given disk be initialized based on the config?
:param storage: an instance of the Blivet's storage
:param disk: an instance of the disk we want to format
:return: True or False
"""
log.debug("Can %s be initialized?", disk.name)
# Skip protected and readonly disks.
if disk.protected:
log.debug("A protected disk cannot be initialized.")
return False
# Initialize disks with unrecognized formatting.
if self.format_unrecognized and disk.format.type is None:
log.debug("A disk with unrecognized formatting can be initialized.")
return True
# Initialize disks that were removed.
if self.can_remove(storage, disk):
log.debug("The clearable disk can be initialized.")
return True
log.debug("The disk cannot be initialized.")
return False