diff options
Diffstat (limited to 'pyanaconda/storage/formats/__init__.py')
-rw-r--r-- | pyanaconda/storage/formats/__init__.py | 438 |
1 files changed, 0 insertions, 438 deletions
diff --git a/pyanaconda/storage/formats/__init__.py b/pyanaconda/storage/formats/__init__.py deleted file mode 100644 index 62bfb31c4..000000000 --- a/pyanaconda/storage/formats/__init__.py +++ /dev/null @@ -1,438 +0,0 @@ -# __init__.py -# Entry point for anaconda storage formats subpackage. -# -# Copyright (C) 2009 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. -# -# Red Hat Author(s): Dave Lehman <dlehman@redhat.com> -# - -import os - -from pyanaconda.product import productName -from pyanaconda.baseudev import udev_get_device -from ..util import notify_kernel -from ..util import get_sysfs_path_by_name -from ..util import run_program -from ..storage_log import log_method_call -from ..errors import * -from ..devicelibs.dm import dm_node_from_name -from ..devicelibs.mdraid import md_node_from_name -from ..udev import udev_device_get_major, udev_device_get_minor - -import gettext -_ = lambda x: gettext.ldgettext("anaconda", x) - -import logging -log = logging.getLogger("storage") - - -device_formats = {} -def register_device_format(fmt_class): - if not issubclass(fmt_class, DeviceFormat): - raise ValueError("arg1 must be a subclass of DeviceFormat") - - device_formats[fmt_class._type] = fmt_class - log.debug("registered device format class %s as %s" % (fmt_class.__name__, - fmt_class._type)) - -default_fstypes = ["ext4", "ext3", "ext2"] -if productName.startswith("Red Hat Enterprise Linux"): - default_fstypes.insert(0, "xfs") - -def get_default_filesystem_type(): - for fstype in default_fstypes: - try: - supported = get_device_format_class(fstype).supported - except AttributeError: - supported = None - - if supported: - return fstype - - raise DeviceFormatError("None of %s is supported by your kernel" % ",".join(default_fstypes)) - -def getFormat(fmt_type, *args, **kwargs): - """ Return a DeviceFormat instance based on fmt_type and args. - - Given a device format type and a set of constructor arguments, - return a DeviceFormat instance. - - Return None if no suitable format class is found. - - Arguments: - - fmt_type -- the name of the format type (eg: 'ext3', 'swap') - - Keyword Arguments: - - The keyword arguments may vary according to the format type, - but here is the common set: - - device -- path to the device on which the format resides - uuid -- the UUID of the (preexisting) formatted device - exists -- whether or not the format exists on the device - - """ - fmt_class = get_device_format_class(fmt_type) - fmt = None - if fmt_class: - fmt = fmt_class(*args, **kwargs) - try: - className = fmt.__class__.__name__ - except AttributeError: - className = None - log.debug("getFormat('%s') returning %s instance" % (fmt_type, className)) - return fmt - -def collect_device_format_classes(): - """ Pick up all device format classes from this directory. - - Note: Modules must call register_device_format(FormatClass) in - order for the format class to be picked up. - """ - dir = os.path.dirname(__file__) - for module_file in os.listdir(dir): - # make sure we're not importing this module - if module_file.endswith(".py") and module_file != __file__: - mod_name = module_file[:-3] - # imputil is deprecated in python 2.6 - try: - globals()[mod_name] = __import__(mod_name, globals(), locals(), [], -1) - except ImportError: - log.error("import of device format module '%s' failed" % mod_name) - from traceback import format_exc - log.debug(format_exc()) - -def get_device_format_class(fmt_type): - """ Return an appropriate format class based on fmt_type. """ - if not device_formats: - collect_device_format_classes() - - fmt = device_formats.get(fmt_type) - if not fmt: - for fmt_class in device_formats.values(): - if fmt_type and fmt_type == fmt_class._name: - fmt = fmt_class - break - elif fmt_type in fmt_class._udevTypes: - fmt = fmt_class - break - - # default to no formatting, AKA "Unknown" - if not fmt: - fmt = DeviceFormat - - return fmt - -class DeviceFormat(object): - """ Generic device format. """ - _type = None - _name = "Unknown" - _udevTypes = [] - partedFlag = None - partedSystem = None - _formattable = False # can be formatted - _supported = False # is supported - _linuxNative = False # for clearpart - _packages = [] # required packages - _services = [] # required services - _resizable = False # can be resized - _maxSize = 0 # maximum size in MB - _minSize = 0 # minimum size in MB - _dump = False - _check = False - _hidden = False # hide devices with this formatting? - - def __init__(self, *args, **kwargs): - """ Create a DeviceFormat instance. - - Keyword Arguments: - - device -- path to the underlying device - uuid -- this format's UUID - exists -- indicates whether this is an existing format - - """ - self.device = kwargs.get("device") - self.uuid = kwargs.get("uuid") - self.exists = kwargs.get("exists") - self.options = kwargs.get("options") - self._majorminor = None - - # don't worry about existence if this is a DeviceFormat instance - #if self.__class__ is DeviceFormat: - # self.exists = True - - def __repr__(self): - s = ("%(classname)s instance (%(id)s) --\n" - " type = %(type)s name = %(name)s status = %(status)s\n" - " device = %(device)s uuid = %(uuid)s exists = %(exists)s\n" - " options = %(options)s supported = %(supported)s" - " formattable = %(format)s resizable = %(resize)s\n" % - {"classname": self.__class__.__name__, "id": "%#x" % id(self), - "type": self.type, "name": self.name, "status": self.status, - "device": self.device, "uuid": self.uuid, "exists": self.exists, - "options": self.options, "supported": self.supported, - "format": self.formattable, "resize": self.resizable}) - return s - - @property - def _existence_str(self): - exist = "existing" - if not self.exists: - exist = "non-existent" - return exist - - @property - def desc(self): - return str(self.type) - - def __str__(self): - return "%s %s" % (self._existence_str, self.desc) - - @property - def dict(self): - d = {"type": self.type, "name": self.name, "device": self.device, - "uuid": self.uuid, "exists": self.exists, - "options": self.options, "supported": self.supported, - "resizable": self.resizable} - return d - - def _setOptions(self, options): - self._options = options - - def _getOptions(self): - return self._options - - options = property(_getOptions, _setOptions) - - def _setDevice(self, devspec): - if devspec and not devspec.startswith("/"): - raise ValueError("device must be a fully qualified path") - self._device = devspec - - def _getDevice(self): - return self._device - - device = property(lambda f: f._getDevice(), - lambda f,d: f._setDevice(d), - doc="Full path the device this format occupies") - - @property - def name(self): - if self._name: - name = self._name - else: - name = self.type - return name - - @property - def type(self): - return self._type - - def probe(self): - log_method_call(self, device=self.device, - type=self.type, status=self.status) - - def notifyKernel(self): - log_method_call(self, device=self.device, - type=self.type) - if not self.device: - return - - if self.device.startswith("/dev/mapper/"): - try: - name = dm_node_from_name(os.path.basename(self.device)) - except DMError: - log.warning("failed to get dm node for %s" % self.device) - return - elif self.device.startswith("/dev/md/"): - try: - name = md_node_from_name(os.path.basename(self.device)) - except MDRaidError: - log.warning("failed to get md node for %s" % self.device) - return - else: - name = self.device - - path = get_sysfs_path_by_name(name) - try: - notify_kernel(path, action="change") - except (ValueError, IOError) as e: - log.warning("failed to notify kernel of change: %s" % e) - - def cacheMajorminor(self): - """ Cache the value of self.majorminor. - - Once a device node of this format's device disappears (for instance - after a teardown), it is no longer possible to figure out the value - of self.majorminor pseudo-unique string. Call this method before - that happens for caching this. - """ - self._majorminor = None - try: - self.majorminor # this does the caching - except StorageError: - # entirely possible there's no majorminor, for instance an - # LVMVolumeGroup has got no device node and no sysfs path. In this - # case obviously, calling majorminor of this object later raises an - # exception. - pass - return self._majorminor - - def create(self, *args, **kwargs): - log_method_call(self, device=self.device, - type=self.type, status=self.status) - # allow late specification of device path - device = kwargs.get("device") - if device: - self.device = device - - if not os.path.exists(self.device): - raise FormatCreateError("invalid device specification", self.device) - - def destroy(self, *args, **kwargs): - log_method_call(self, device=self.device, - type=self.type, status=self.status) - try: - rc = run_program(["wipefs", "-a", self.device]) - except OSError as e: - err = str(e) - else: - err = "" - if rc: - err = str(rc) - - if err: - msg = "error wiping old signatures from %s: %s" % (self.device, err) - raise FormatDestroyError(msg) - - self.exists = False - - def setup(self, *args, **kwargs): - log_method_call(self, device=self.device, - type=self.type, status=self.status) - - 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: - self.device = device - - if not self.device or not os.path.exists(self.device): - raise FormatSetupError("invalid device specification") - - def teardown(self, *args, **kwargs): - log_method_call(self, device=self.device, - type=self.type, status=self.status) - - @property - def status(self): - return (self.exists and - self.__class__ is not DeviceFormat and - isinstance(self.device, str) and - self.device and - os.path.exists(self.device)) - - @property - def formattable(self): - """ Can we create formats of this type? """ - return self._formattable - - @property - def supported(self): - """ Is this format a supported type? """ - return self._supported - - @property - def packages(self): - """ Packages required to manage formats of this type. """ - return self._packages - - @property - def services(self): - """ Services required to manage formats of this type. """ - return self._services - - @property - def resizable(self): - """ Can formats of this type be resized? """ - return self._resizable and self.exists - - @property - def linuxNative(self): - """ Is this format type native to linux? """ - return self._linuxNative - - @property - def mountable(self): - """ Is this something we can mount? """ - return False - - @property - def dump(self): - """ Whether or not this format will be dumped by dump(8). """ - return self._dump - - @property - def check(self): - """ Whether or not this format is checked on boot. """ - return self._check - - @property - def maxSize(self): - """ Maximum size (in MB) for this format type. """ - return self._maxSize - - @property - def minSize(self): - """ Minimum size (in MB) for this format type. """ - return self._minSize - - @property - def hidden(self): - """ Whether devices with this formatting should be hidden in UIs. """ - return self._hidden - - @property - def majorminor(self): - """A string suitable for using as a pseudo-unique ID in kickstart.""" - if not self._majorminor: - # If this is a device-mapper device, we have to get the DM node and - # build the sysfs path from that. - try: - device = dm_node_from_name(os.path.basename(self.device)) - except DMError: - device = self.device - - try: - sysfs_path = get_sysfs_path_by_name(device) - except RuntimeError: - raise StorageError("DeviceFormat.majorminor: " - "can not get majorminor for '%s'" % device) - dev = udev_get_device(sysfs_path[4:]) - - self._majorminor = "%03d%03d" %\ - (udev_device_get_major(dev), udev_device_get_minor(dev)) - return self._majorminor - -collect_device_format_classes() |