summaryrefslogtreecommitdiffstats
path: root/pyanaconda/storage/formats
diff options
context:
space:
mode:
Diffstat (limited to 'pyanaconda/storage/formats')
-rw-r--r--pyanaconda/storage/formats/Makefile.am24
-rw-r--r--pyanaconda/storage/formats/__init__.py438
-rw-r--r--pyanaconda/storage/formats/biosboot.py60
-rw-r--r--pyanaconda/storage/formats/disklabel.py443
-rw-r--r--pyanaconda/storage/formats/dmraid.py114
-rw-r--r--pyanaconda/storage/formats/fs.py1433
-rw-r--r--pyanaconda/storage/formats/luks.py342
-rw-r--r--pyanaconda/storage/formats/lvmpv.py146
-rw-r--r--pyanaconda/storage/formats/mdraid.py120
-rw-r--r--pyanaconda/storage/formats/multipath.py94
-rw-r--r--pyanaconda/storage/formats/prepboot.py87
-rw-r--r--pyanaconda/storage/formats/swap.py171
12 files changed, 0 insertions, 3472 deletions
diff --git a/pyanaconda/storage/formats/Makefile.am b/pyanaconda/storage/formats/Makefile.am
deleted file mode 100644
index 7ecaf075d..000000000
--- a/pyanaconda/storage/formats/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-# storage/formats/Makefile.am for anaconda
-#
-# Copyright (C) 2009 Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@redhat.com>
-
-pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME)
-storageformatsdir = $(pkgpyexecdir)/storage/formats
-storageformats_PYTHON = *.py
-
-MAINTAINERCLEANFILES = Makefile.in
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()
diff --git a/pyanaconda/storage/formats/biosboot.py b/pyanaconda/storage/formats/biosboot.py
deleted file mode 100644
index c3aef8d2b..000000000
--- a/pyanaconda/storage/formats/biosboot.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# biosboot.py
-# Device format classes for anaconda's storage configuration module.
-#
-# Copyright (C) 2011 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>
-#
-
-from parted import PARTITION_BIOS_GRUB
-
-from ..errors import *
-from .. import platform
-from . import DeviceFormat, register_device_format
-
-class BIOSBoot(DeviceFormat):
- """ BIOS boot partition for GPT disklabels. """
- _type = "biosboot"
- _name = "BIOS Boot"
- _udevTypes = []
- partedFlag = PARTITION_BIOS_GRUB
- _formattable = True # can be formatted
- _linuxNative = True # for clearpart
- _maxSize = 2 # maximum size in MB
- _minSize = 0.5 # minimum size in MB
-
- def __init__(self, *args, **kwargs):
- """ Create a BIOSBoot instance.
-
- Keyword Arguments:
-
- device -- path to the underlying device
- exists -- indicates whether this is an existing format
-
- """
- DeviceFormat.__init__(self, *args, **kwargs)
-
- @property
- def status(self):
- return False
-
- @property
- def supported(self):
- return isinstance(platform.platform, platform.X86)
-
-register_device_format(BIOSBoot)
-
diff --git a/pyanaconda/storage/formats/disklabel.py b/pyanaconda/storage/formats/disklabel.py
deleted file mode 100644
index 018adf426..000000000
--- a/pyanaconda/storage/formats/disklabel.py
+++ /dev/null
@@ -1,443 +0,0 @@
-# disklabel.py
-# Device format classes for anaconda's storage configuration module.
-#
-# 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
-import copy
-
-from ..storage_log import log_method_call
-import parted
-import _ped
-from ..errors import *
-from .. import arch
-from ..flags import flags
-from ..udev import udev_settle
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-class DiskLabel(DeviceFormat):
- """ Disklabel """
- _type = "disklabel"
- _name = "partition table"
- _formattable = True # can be formatted
- _supported = False # is supported
-
- def __init__(self, *args, **kwargs):
- """ Create a DiskLabel instance.
-
- Keyword Arguments:
-
- labelType -- type of disklabel to create
- device -- path to the underlying device
- exists -- indicates whether this is an existing format
-
- """
- log_method_call(self, *args, **kwargs)
- DeviceFormat.__init__(self, *args, **kwargs)
-
- if not self.exists:
- self._labelType = kwargs.get("labelType", "msdos")
- else:
- self._labelType = ""
-
- self._size = None
-
- self._partedDevice = None
- self._partedDisk = None
- self._origPartedDisk = None
- self._alignment = None
- self._endAlignment = None
-
- if self.partedDevice:
- # set up the parted objects and raise exception on failure
- self._origPartedDisk = self.partedDisk.duplicate()
-
- def __deepcopy__(self, memo):
- """ Create a deep copy of a Disklabel instance.
-
- We can't do copy.deepcopy on parted objects, which is okay.
- For these parted objects, we just do a shallow copy.
- """
- new = self.__class__.__new__(self.__class__)
- memo[id(self)] = new
- shallow_copy_attrs = ('_partedDevice', '_alignment', '_endAlignment')
- duplicate_attrs = ('_partedDisk', '_origPartedDisk')
- for (attr, value) in self.__dict__.items():
- if attr in shallow_copy_attrs:
- setattr(new, attr, copy.copy(value))
- elif attr in duplicate_attrs:
- setattr(new, attr, value.duplicate())
- else:
- setattr(new, attr, copy.deepcopy(value, memo))
-
- return new
-
- def __repr__(self):
- s = DeviceFormat.__repr__(self)
- if flags.testing:
- return s
- s += (" type = %(type)s partition count = %(count)s"
- " sectorSize = %(sectorSize)s\n"
- " align_offset = %(offset)s align_grain = %(grain)s\n"
- " partedDisk = %(disk)s\n"
- " origPartedDisk = %(orig_disk)r\n"
- " partedDevice = %(dev)s\n" %
- {"type": self.labelType, "count": len(self.partitions),
- "sectorSize": self.partedDevice.sectorSize,
- "offset": self.alignment.offset,
- "grain": self.alignment.grainSize,
- "disk": self.partedDisk, "orig_disk": self._origPartedDisk,
- "dev": self.partedDevice})
- return s
-
- @property
- def desc(self):
- return "%s %s" % (self.labelType, self.type)
-
- @property
- def dict(self):
- d = super(DiskLabel, self).dict
- if flags.testing:
- return d
-
- d.update({"labelType": self.labelType,
- "partitionCount": len(self.partitions),
- "sectorSize": self.partedDevice.sectorSize,
- "offset": self.alignment.offset,
- "grainSize": self.alignment.grainSize})
- return d
-
- def resetPartedDisk(self):
- """ Set this instance's partedDisk to reflect the disk's contents. """
- log_method_call(self, device=self.device)
- self._partedDisk = self._origPartedDisk
-
- def freshPartedDisk(self):
- """ Return a new, empty parted.Disk instance for this device. """
- log_method_call(self, device=self.device, labelType=self._labelType)
- return parted.freshDisk(device=self.partedDevice, ty=self._labelType)
-
- @property
- def partedDisk(self):
- if not self._partedDisk:
- if self.exists:
- try:
- self._partedDisk = parted.Disk(device=self.partedDevice)
- except (_ped.DiskLabelException, _ped.IOException,
- NotImplementedError) as e:
- raise InvalidDiskLabelError()
-
- if self._partedDisk.type == "loop":
- # When the device has no partition table but it has a FS,
- # it will be created with label type loop. Treat the
- # same as if the device had no label (cause it really
- # doesn't).
- raise InvalidDiskLabelError()
-
- # here's where we correct the ctor-supplied disklabel type for
- # preexisting disklabels if the passed type was wrong
- self._labelType = self._partedDisk.type
- else:
- self._partedDisk = self.freshPartedDisk()
-
- # turn off cylinder alignment
- if self._partedDisk.isFlagAvailable(parted.DISK_CYLINDER_ALIGNMENT):
- self._partedDisk.unsetFlag(parted.DISK_CYLINDER_ALIGNMENT)
-
- # Set the boot flag on the GPT PMBR, this helps some BIOS systems boot
- if self._partedDisk.isFlagAvailable(parted.DISK_GPT_PMBR_BOOT):
- # MAC can boot as EFI or as BIOS, neither should have PMBR boot set
- if arch.isEfi() or arch.isMactel():
- self._partedDisk.unsetFlag(parted.DISK_GPT_PMBR_BOOT)
- log.debug("Clear pmbr_boot on %s" % (self._partedDisk,))
- else:
- self._partedDisk.setFlag(parted.DISK_GPT_PMBR_BOOT)
- log.debug("Set pmbr_boot on %s" % (self._partedDisk,))
- else:
- log.debug("Did not change pmbr_boot on %s" % (self._partedDisk,))
-
- return self._partedDisk
-
- @property
- def partedDevice(self):
- if not self._partedDevice and self.device:
- if os.path.exists(self.device):
- # We aren't guaranteed to be able to get a device. In
- # particular, built-in USB flash readers show up as devices but
- # do not always have any media present, so parted won't be able
- # to find a device.
- try:
- self._partedDevice = parted.Device(path=self.device)
- except (_ped.IOException, _ped.DeviceException) as e:
- log.error("DiskLabel.partedDevice: Parted exception: %s" % e)
- else:
- log.info("DiskLabel.partedDevice: %s does not exist" % self.device)
-
- if not self._partedDevice:
- log.info("DiskLabel.partedDevice returning None")
- return self._partedDevice
-
- @property
- def labelType(self):
- """ The disklabel type (eg: 'gpt', 'msdos') """
- try:
- lt = self.partedDisk.type
- except Exception:
- lt = self._labelType
- return lt
-
- @property
- def name(self):
- return "%s (%s)" % (self._name, self.labelType.upper())
-
- @property
- def size(self):
- size = self._size
- if not size:
- try:
- size = self.partedDevice.getSize(unit="MB")
- except Exception:
- size = 0
-
- return size
-
- @property
- def status(self):
- """ Device status. """
- return False
-
- def setup(self, *args, **kwargs):
- """ Open, or set up, a device. """
- log_method_call(self, device=self.device,
- type=self.type, status=self.status)
- if not self.exists:
- raise DeviceFormatError("format has not been created")
-
- if self.status:
- return
-
- DeviceFormat.setup(self, *args, **kwargs)
-
- def teardown(self, *args, **kwargs):
- """ Close, or tear down, a device. """
- log_method_call(self, device=self.device,
- type=self.type, status=self.status)
- if not self.exists:
- raise DeviceFormatError("format has not been created")
-
- def create(self, *args, **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, *args, **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, *args, **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. """
- log_method_call(self, device=self.device,
- numparts=len(self.partitions))
- try:
- self.partedDisk.commit()
- except parted.DiskException as msg:
- raise DiskLabelCommitError(msg)
- else:
- udev_settle()
-
- def commitToDisk(self):
- """ Commit the current partition table to disk. """
- log_method_call(self, device=self.device,
- numparts=len(self.partitions))
- try:
- self.partedDisk.commitToDevice()
- except parted.DiskException as msg:
- raise DiskLabelCommitError(msg)
-
- def addPartition(self, *args, **kwargs):
- partition = kwargs.get("partition", None)
- if not partition:
- partition = args[0]
- geometry = partition.geometry
- constraint = kwargs.get("constraint", None)
- if not constraint and len(args) > 1:
- constraint = args[1]
- elif not constraint:
- constraint = parted.Constraint(exactGeom=geometry)
-
- new_partition = parted.Partition(disk=self.partedDisk,
- type=partition.type,
- geometry=geometry)
- self.partedDisk.addPartition(partition=new_partition,
- constraint=constraint)
-
- def removePartition(self, partition):
- self.partedDisk.removePartition(partition)
-
- @property
- def extendedPartition(self):
- try:
- extended = self.partedDisk.getExtendedPartition()
- except Exception:
- extended = None
- return extended
-
- @property
- def logicalPartitions(self):
- try:
- logicals = self.partedDisk.getLogicalPartitions()
- except Exception:
- logicals = []
- return logicals
-
- @property
- def firstPartition(self):
- try:
- part = self.partedDisk.getFirstPartition()
- except Exception:
- part = None
- return part
-
- @property
- def partitions(self):
- try:
- parts = self.partedDisk.partitions
- except Exception:
- parts = []
- if flags.testing:
- sys_block_root = "/sys/class/block/"
-
- # FIXME: /dev/mapper/foo won't work without massaging
- disk_name = self.device.split("/")[-1]
-
- disk_root = sys_block_root + disk_name
- parts = [n for n in os.listdir(disk_root) if n.startswith(disk_name)]
- return parts
-
- @property
- def alignment(self):
- """ Alignment requirements for this device. """
- if not self._alignment:
- try:
- disklabel_alignment = self.partedDisk.partitionAlignment
- except _ped.CreateException:
- disklabel_alignment = parted.Alignment(offset=0, grainSize=1)
-
- try:
- optimum_device_alignment = self.partedDevice.optimumAlignment
- except _ped.CreateException:
- optimum_device_alignment = None
-
- try:
- minimum_device_alignment = self.partedDevice.minimumAlignment
- except _ped.CreateException:
- minimum_device_alignment = None
-
- try:
- a = optimum_device_alignment.intersect(disklabel_alignment)
- except (ArithmeticError, AttributeError):
- try:
- a = minimum_device_alignment.intersect(disklabel_alignment)
- except (ArithmeticError, AttributeError):
- a = disklabel_alignment
-
- self._alignment = a
-
- return self._alignment
-
- @property
- def endAlignment(self):
- if not self._endAlignment:
- self._endAlignment = parted.Alignment(
- offset = self.alignment.offset - 1,
- grainSize = self.alignment.grainSize)
-
- return self._endAlignment
-
- @property
- def free(self):
- def read_int_from_sys(path):
- return int(open(path).readline().strip())
-
- try:
- free = sum([f.getSize()
- for f in self.partedDisk.getFreeSpacePartitions()])
- except Exception:
- sys_block_root = "/sys/class/block/"
-
- # FIXME: /dev/mapper/foo won't work without massaging
- disk_name = self.device.split("/")[-1]
-
- disk_root = sys_block_root + disk_name
- disk_length = read_int_from_sys("%s/size" % disk_root)
- sector_size = read_int_from_sys("%s/queue/logical_block_size" % disk_root)
- partition_names = [n for n in os.listdir(disk_root) if n.startswith(disk_name)]
- used_sectors = 0
- for partition_name in partition_names:
- partition_root = sys_block_root + partition_name
- partition_length = read_int_from_sys("%s/size" % partition_root)
- used_sectors += partition_length
-
- free = ((disk_length - used_sectors) * sector_size) / (1024.0 * 1024.0)
-
- return free
-
- @property
- def magicPartitionNumber(self):
- """ Number of disklabel-type-specific special partition. """
- if self.labelType == "mac":
- return 1
- elif self.labelType == "sun":
- return 3
- else:
- return 0
-
-register_device_format(DiskLabel)
-
diff --git a/pyanaconda/storage/formats/dmraid.py b/pyanaconda/storage/formats/dmraid.py
deleted file mode 100644
index f37b2d33f..000000000
--- a/pyanaconda/storage/formats/dmraid.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# dmraid.py
-# dmraid device formats
-#
-# 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>
-#
-
-from ..storage_log import log_method_call
-from ..flags import flags
-from ..errors import *
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-class DMRaidMember(DeviceFormat):
- """ A dmraid member disk. """
- _type = "dmraidmember"
- _name = "dm-raid member device"
- # XXX This looks like trouble.
- #
- # Maybe a better approach is a RaidMember format with subclass
- # for MDRaidMember, letting all *_raid_member types fall through
- # to the generic RaidMember format, which is basically read-only.
- #
- # One problem that presents is the possibility of someone passing
- # a dmraid member to the MDRaidArrayDevice constructor.
- _udevTypes = ["adaptec_raid_member", "ddf_raid_member",
- "hpt37x_raid_member", "hpt45x_raid_member",
- "isw_raid_member",
- "jmicron_raid_member", "lsi_mega_raid_member",
- "nvidia_raid_member", "promise_fasttrack_raid_member",
- "silicon_medley_raid_member", "via_raid_member"]
- _formattable = False # can be formatted
- _supported = True # is supported
- _linuxNative = False # for clearpart
- _packages = ["dmraid"] # required packages
- _resizable = False # can be resized
- _maxSize = 0 # maximum size in MB
- _minSize = 0 # minimum size in MB
- _hidden = True # 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
-
- On initialization this format is like DeviceFormat
-
- """
- log_method_call(self, *args, **kwargs)
- DeviceFormat.__init__(self, *args, **kwargs)
-
- # Initialize the attribute that will hold the block object.
- self._raidmem = None
-
- def __repr__(self):
- s = DeviceFormat.__repr__(self)
- s += (" raidmem = %(raidmem)r" % {"raidmem": self.raidmem})
- return s
-
- def _getRaidmem(self):
- return self._raidmem
-
- def _setRaidmem(self, raidmem):
- self._raidmem = raidmem
-
- raidmem = property(lambda d: d._getRaidmem(),
- lambda d,r: d._setRaidmem(r))
-
- def create(self, *args, **kwargs):
- log_method_call(self, device=self.device,
- type=self.type, status=self.status)
- raise DMRaidMemberError("creation of dmraid members is non-sense")
-
- def destroy(self, *args, **kwargs):
- log_method_call(self, device=self.device,
- type=self.type, status=self.status)
- raise DMRaidMemberError("destruction of dmraid members is non-sense")
-
-
-if not flags.noiswmd:
- DMRaidMember._udevTypes.remove("isw_raid_member")
-
-# The anaconda cmdline has not been parsed yet when we're first imported,
-# so we can not use flags.dmraid here
-if not flags.dmraid:
- DMRaidMember._udevTypes = []
-
-register_device_format(DMRaidMember)
-
diff --git a/pyanaconda/storage/formats/fs.py b/pyanaconda/storage/formats/fs.py
deleted file mode 100644
index b472e8727..000000000
--- a/pyanaconda/storage/formats/fs.py
+++ /dev/null
@@ -1,1433 +0,0 @@
-# filesystems.py
-# Filesystem classes for anaconda's storage configuration module.
-#
-# 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>
-# David Cantrell <dcantrell@redhat.com>
-#
-
-""" Filesystem classes for use by anaconda.
-
- TODO:
- - bug 472127: allow creation of tmpfs filesystems (/tmp, /var/tmp, &c)
-"""
-import math
-import os
-import sys
-import tempfile
-import selinux
-
-from ..errors import *
-from . import DeviceFormat, register_device_format
-from .. import util
-from .. import platform
-from ..flags import flags
-from parted import fileSystemType
-from ..storage_log import log_method_call
-
-import logging
-log = logging.getLogger("storage")
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-try:
- lost_and_found_context = selinux.matchpathcon("/lost+found", 0)[1]
-except OSError:
- lost_and_found_context = None
-
-# these are for converting to/from SI for ntfsresize
-mb = 1000 * 1000.0
-mib = 1024 * 1024.0
-
-fs_configs = {}
-
-def get_kernel_filesystems():
- fs_list = []
- for line in open("/proc/filesystems").readlines():
- fs_list.append(line.split()[-1])
- return fs_list
-
-global kernel_filesystems
-kernel_filesystems = get_kernel_filesystems()
-
-def fsConfigFromFile(config_file):
- """ Generate a set of attribute name/value pairs with which a
- filesystem type can be defined.
-
- The following config file would define a filesystem identical to
- the static Ext3FS class definition:
-
- type = ext3
- mkfs = "mke2fs"
- resizefs = "resize2fs"
- labelfs = "e2label"
- fsck = "e2fsck"
- packages = ["e2fsprogs"]
- formattable = True
- supported = True
- resizable = True
- linuxNative = True
- maxSize = 8 * 1024 * 1024
- minSize = 0
- defaultFormatOptions = "-t ext3"
- defaultMountOptions = "defaults"
-
- """
- # XXX NOTUSED
- lines = open(config_file).readlines()
- fs_attrs = {}
- for line in lines:
- (key, value) = [t.strip() for t in line.split("=")]
- if not hasattr(FS, "_" + key):
- print "invalid key: %s" % key
- continue
-
- fs_attrs[key] = value
-
- if not fs_attrs.has_key("type"):
- raise ValueError, _("filesystem configuration missing a type")
-
- # XXX what's the policy about multiple configs for a given type?
- fs_configs[fs_attrs['type']] = fs_attrs
-
-class FS(DeviceFormat):
- """ Filesystem class. """
- _type = "Abstract Filesystem Class" # fs type name
- _mountType = None # like _type but for passing to mount
- _name = None
- _mkfs = "" # mkfs utility
- _modules = [] # kernel modules required for support
- _resizefs = "" # resize utility
- _labelfs = "" # labeling utility
- _fsck = "" # fs check utility
- _fsckErrors = {} # fs check command error codes & msgs
- _infofs = "" # fs info utility
- _defaultFormatOptions = [] # default options passed to mkfs
- _defaultMountOptions = ["defaults"] # default options passed to mount
- _defaultLabelOptions = []
- _defaultCheckOptions = []
- _defaultInfoOptions = []
- _existingSizeFields = []
- _fsProfileSpecifier = None # mkfs option specifying fsprofile
-
- def __init__(self, *args, **kwargs):
- """ Create a FS instance.
-
- Keyword Args:
-
- device -- path to the device containing the filesystem
- mountpoint -- the filesystem's mountpoint
- label -- the filesystem label
- uuid -- the filesystem UUID
- mountopts -- mount options for the filesystem
- size -- the filesystem's size in MiB
- exists -- indicates whether this is an existing filesystem
-
- """
- if self.__class__ is FS:
- raise TypeError("FS is an abstract class.")
-
- DeviceFormat.__init__(self, *args, **kwargs)
- self.mountpoint = kwargs.get("mountpoint")
- self.mountopts = kwargs.get("mountopts")
- self.label = kwargs.get("label")
- self.fsprofile = kwargs.get("fsprofile")
-
- # filesystem size does not necessarily equal device size
- self._size = kwargs.get("size", 0)
- self._minInstanceSize = None # min size of this FS instance
- self._mountpoint = None # the current mountpoint when mounted
- if self.exists:
- self._size = self._getExistingSize()
- foo = self.minSize # force calculation of minimum size
-
- self._targetSize = self._size
-
- if self.supported:
- self.loadModule()
-
- def __repr__(self):
- s = DeviceFormat.__repr__(self)
- s += (" mountpoint = %(mountpoint)s mountopts = %(mountopts)s\n"
- " label = %(label)s size = %(size)s"
- " targetSize = %(targetSize)s\n" %
- {"mountpoint": self.mountpoint, "mountopts": self.mountopts,
- "label": self.label, "size": self._size,
- "targetSize": self.targetSize})
- return s
-
- @property
- def desc(self):
- s = "%s filesystem" % self.type
- if self.mountpoint:
- s += " mounted at %s" % self.mountpoint
- return s
-
- @property
- def dict(self):
- d = super(FS, self).dict
- d.update({"mountpoint": self.mountpoint, "size": self._size,
- "label": self.label, "targetSize": self.targetSize,
- "mountable": self.mountable})
- return d
-
- def _setTargetSize(self, newsize):
- """ Set a target size for this filesystem. """
- if not self.exists:
- raise FSError("filesystem has not been created")
-
- if newsize is None:
- # unset any outstanding resize request
- self._targetSize = self._size
- return
-
- if not self.minSize <= newsize < self.maxSize:
- raise ValueError("invalid target size request")
-
- self._targetSize = newsize
-
- def _getTargetSize(self):
- """ Get this filesystem's target size. """
- return self._targetSize
-
- targetSize = property(_getTargetSize, _setTargetSize,
- doc="Target size for this filesystem")
-
- def _getSize(self):
- """ Get this filesystem's size. """
- size = self._size
- if self.resizable and self.targetSize != size:
- size = self.targetSize
- return size
-
- size = property(_getSize, doc="This filesystem's size, accounting "
- "for pending changes")
-
- def _getExistingSize(self):
- """ Determine the size of this filesystem. Filesystem must
- exist. Each filesystem varies, but the general procedure
- is to run the filesystem dump or info utility and read
- the block size and number of blocks for the filesystem
- and compute megabytes from that.
-
- The loop that reads the output from the infofsProg is meant
- to be simple, but take in to account variations in output.
- The general procedure:
- 1) Capture output from infofsProg.
- 2) Iterate over each line of the output:
- a) Trim leading and trailing whitespace.
- b) Break line into fields split on ' '
- c) If line begins with any of the strings in
- _existingSizeFields, start at the end of
- fields and take the first one that converts
- to a long. Store this in the values list.
- d) Repeat until the values list length equals
- the _existingSizeFields length.
- 3) If the length of the values list equals the length
- of _existingSizeFields, compute the size of this
- filesystem by multiplying all of the values together
- to get bytes, then convert to megabytes. Return
- this value.
- 4) If we were unable to capture all fields, return 0.
-
- The caller should catch exceptions from this method. Any
- exception raised indicates a need to change the fields we
- are looking for, the command to run and arguments, or
- something else. If you catch an exception from this method,
- assume the filesystem cannot be resized.
- """
- size = self._size
-
- if self.infofsProg and self.exists and not size and \
- util.find_program_in_path(self.infofsProg):
- try:
- values = []
- argv = self._defaultInfoOptions + [ self.device ]
-
- buf = util.capture_output([self.infofsProg] + argv)
-
- for line in buf.splitlines():
- found = False
-
- line = line.strip()
- tmp = line.split(' ')
- tmp.reverse()
-
- for field in self._existingSizeFields:
- if line.startswith(field):
- for subfield in tmp:
- try:
- values.append(long(subfield))
- found = True
- break
- except ValueError:
- continue
-
- if found:
- break
-
- if len(values) == len(self._existingSizeFields):
- break
-
- if len(values) != len(self._existingSizeFields):
- return 0
-
- size = 1
- for value in values:
- size *= value
-
- # report current size as megabytes
- size = math.floor(size / 1024.0 / 1024.0)
- except Exception as e:
- log.error("failed to obtain size of filesystem on %s: %s"
- % (self.device, e))
-
- return size
-
- @property
- def currentSize(self):
- """ The filesystem's current actual size. """
- size = 0
- if self.exists:
- size = self._size
- return float(size)
-
- @property
- def free(self):
- free = 0
- if self.exists:
- if self.currentSize and self.minSize and \
- self.currentSize != self.minSize:
- free = int(max(0, self.currentSize - self.minSize)) # truncate
-
- return free
-
- def _getFormatOptions(self, options=None):
- argv = []
- if options and isinstance(options, list):
- argv.extend(options)
- argv.extend(self.defaultFormatOptions)
- if self._fsProfileSpecifier and self.fsprofile:
- argv.extend([self._fsProfileSpecifier, self.fsprofile])
- argv.append(self.device)
- return argv
-
- def doFormat(self, *args, **kwargs):
- """ Create the filesystem.
-
- Arguments:
-
- None
-
- Keyword Arguments:
-
- options -- list of options to pass to mkfs
-
- """
- log_method_call(self, type=self.mountType, device=self.device,
- mountpoint=self.mountpoint)
-
- options = kwargs.get("options")
-
- if self.exists:
- raise FormatCreateError("filesystem already exists", self.device)
-
- if not self.formattable:
- return
-
- if not self.mkfsProg:
- return
-
- if self.exists:
- return
-
- if not os.path.exists(self.device):
- raise FormatCreateError("device does not exist", self.device)
-
- argv = self._getFormatOptions(options=options)
-
- try:
- ret = util.run_program([self.mkfsProg] + argv)
- except OSError as e:
- raise FormatCreateError(e, self.device)
-
- if ret:
- raise FormatCreateError("format failed: %s" % ret.rc, self.device)
-
- self.exists = True
- self.notifyKernel()
-
- if self.label:
- self.writeLabel(self.label)
-
- @property
- def resizeArgs(self):
- argv = [self.device, "%d" % (self.targetSize,)]
- return argv
-
- def doResize(self, *args, **kwargs):
- """ Resize this filesystem to new size @newsize.
-
- Arguments:
-
- None
- """
-
- if not self.exists:
- raise FSResizeError("filesystem does not exist", self.device)
-
- if not self.resizable:
- raise FSResizeError("filesystem not resizable", self.device)
-
- if self.targetSize == self.currentSize:
- return
-
- if not self.resizefsProg:
- return
-
- if not os.path.exists(self.device):
- raise FSResizeError("device does not exist", self.device)
-
- self.doCheck()
-
- # The first minimum size can be incorrect if the fs was not
- # properly unmounted. After doCheck the minimum size will be correct
- # so run the check one last time and bump up the size if it was too
- # small.
- self._minInstanceSize = None
- if self.targetSize < self.minSize:
- self.targetSize = self.minSize
- log.info("Minimum size changed, setting targetSize on %s to %s" \
- % (self.device, self.targetSize))
- try:
- ret = util.run_program([self.resizefsProg] + self.resizeArgs)
- except OSError as e:
- raise FSResizeError(e, self.device)
-
- if ret:
- raise FSResizeError("resize failed: %s" % ret, self.device)
-
- self.doCheck()
-
- # XXX must be a smarter way to do this
- self._size = self.targetSize
- self.notifyKernel()
-
- def _getCheckArgs(self):
- argv = []
- argv.extend(self.defaultCheckOptions)
- argv.append(self.device)
- return argv
-
- def _fsckFailed(self, rc):
- return False
-
- def _fsckErrorMessage(self, rc):
- return _("Unknown return code: %d.") % (rc,)
-
- def doCheck(self):
- if not self.exists:
- raise FSError("filesystem has not been created")
-
- if not self.fsckProg:
- return
-
- if not os.path.exists(self.device):
- raise FSError("device does not exist")
-
- try:
- ret = util.run_program([self.fsckProg] + self._getCheckArgs())
- except OSError as e:
- raise FSError("filesystem check failed: %s" % e)
-
- if self._fsckFailed(ret):
- hdr = _("%(type)s filesystem check failure on %(device)s: ") % \
- {"type": self.type, "device": self.device}
-
- msg = self._fsckErrorMessage(ret)
- raise FSError(hdr + msg)
-
- def loadModule(self):
- """Load whatever kernel module is required to support this filesystem."""
- global kernel_filesystems
-
- if not self._modules or self.mountType in kernel_filesystems:
- return
-
- for module in self._modules:
- try:
- rc = util.run_program(["modprobe", module])
- except OSError as e:
- log.error("Could not load kernel module %s: %s" % (module, e))
- self._supported = False
- return
-
- if rc:
- log.error("Could not load kernel module %s" % module)
- self._supported = False
- return
-
- # If we successfully loaded a kernel module, for this filesystem, we
- # also need to update the list of supported filesystems.
- kernel_filesystems = get_kernel_filesystems()
-
- def testMount(self, options=None):
- """ Try to mount the fs and return True if successful. """
- ret = False
-
- if self.status:
- raise RuntimeError("filesystem is already mounted")
-
- # create a temp dir
- prefix = "%s.%s" % (os.path.basename(self.device), self.type)
- mountpoint = tempfile.mkdtemp(prefix=prefix)
-
- # try the mount
- try:
- self.mount(mountpoint=mountpoint)
- except Exception as e:
- log.info("test mount failed: %s" % e)
- else:
- self.unmount()
- ret = True
- finally:
- os.rmdir(mountpoint)
-
- return ret
-
- def mount(self, *args, **kwargs):
- """ Mount this filesystem.
-
- Arguments:
-
- None
-
- Keyword Arguments:
-
- options -- mount options (overrides all other option strings)
- chroot -- prefix to apply to mountpoint
- mountpoint -- mountpoint (overrides self.mountpoint)
- """
- options = kwargs.get("options", "")
- chroot = kwargs.get("chroot", "/")
- mountpoint = kwargs.get("mountpoint")
-
- if not self.exists:
- raise FSError("filesystem has not been created")
-
- if not mountpoint:
- mountpoint = 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)
-
- # XXX os.path.join is FUBAR:
- #
- # os.path.join("/mnt/foo", "/") -> "/"
- #
- #mountpoint = os.path.join(chroot, mountpoint)
- chrootedMountpoint = os.path.normpath("%s/%s" % (chroot, mountpoint))
- util.makedirs(chrootedMountpoint)
- if flags.selinux:
- ret = util.reset_file_context(mountpoint, chroot)
- log.info("set SELinux context for mountpoint %s to %s" \
- % (mountpoint, ret))
-
- # passed in options override default options
- if not options or not isinstance(options, str):
- options = self.options
-
- if isinstance(self, BindFS):
- options = "bind," + options
-
- try:
- rc = util.mount(self.device, chrootedMountpoint,
- fstype=self.mountType,
- options=options)
- except Exception as e:
- raise FSError("mount failed: %s" % e)
-
- if rc:
- raise FSError("mount failed: %s" % rc)
-
- if flags.selinux and "ro" not in options.split(","):
- ret = util.reset_file_context(mountpoint, chroot)
- log.info("set SELinux context for newly mounted filesystem "
- "root at %s to %s" %(mountpoint, ret))
- util.set_file_context("%s/lost+found" % mountpoint,
- lost_and_found_context, chroot)
-
- self._mountpoint = chrootedMountpoint
-
- def unmount(self):
- """ Unmount this filesystem. """
- if not self.exists:
- raise FSError("filesystem has not been created")
-
- if not self._mountpoint:
- # not mounted
- return
-
- if not os.path.exists(self._mountpoint):
- raise FSError("mountpoint does not exist")
-
- rc = util.umount(self._mountpoint)
- if rc:
- raise FSError("umount failed")
-
- self._mountpoint = None
-
- def _getLabelArgs(self, label):
- argv = []
- argv.extend(self.defaultLabelOptions)
- argv.extend([self.device, label])
- return argv
-
- def writeLabel(self, label):
- """ Create a label for this filesystem. """
- if not self.exists:
- raise FSError("filesystem has not been created")
-
- if not self.labelfsProg:
- return
-
- if not os.path.exists(self.device):
- raise FSError("device does not exist")
-
- argv = self._getLabelArgs(label)
- rc = util.run_program([self.labelfsProg] + argv)
- if rc:
- raise FSError("label failed")
-
- self.label = label
- self.notifyKernel()
-
- def _getRandomUUID(self):
- uuid = util.capture_output(["uuidgen"]).strip()
- return uuid
-
- def writeRandomUUID(self):
- raise NotImplementedError("FS does not implement writeRandomUUID")
-
- @property
- def needsFSCheck(self):
- return False
-
- @property
- def mkfsProg(self):
- """ Program used to create filesystems of this type. """
- return self._mkfs
-
- @property
- def fsckProg(self):
- """ Program used to check filesystems of this type. """
- return self._fsck
-
- @property
- def resizefsProg(self):
- """ Program used to resize filesystems of this type. """
- return self._resizefs
-
- @property
- def labelfsProg(self):
- """ Program used to manage labels for this filesystem type. """
- return self._labelfs
-
- @property
- def infofsProg(self):
- """ Program used to get information for this filesystem type. """
- return self._infofs
-
- @property
- def utilsAvailable(self):
- # we aren't checking for fsck because we shouldn't need it
- for prog in [self.mkfsProg, self.resizefsProg, self.labelfsProg,
- self.infofsProg]:
- if not prog:
- continue
-
- if not util.find_program_in_path(prog):
- return False
-
- return True
-
- @property
- def supported(self):
- log_method_call(self, supported=self._supported)
- return self._supported and self.utilsAvailable
-
- @property
- def mountable(self):
- canmount = (self.mountType in kernel_filesystems) or \
- (os.access("/sbin/mount.%s" % (self.mountType,), os.X_OK))
- modpath = os.path.realpath(os.path.join("/lib/modules", os.uname()[2]))
- modname = "%s.ko" % self.mountType
-
- if not canmount and os.path.isdir(modpath):
- for root, dirs, files in os.walk(modpath):
- have = filter(lambda x: x.startswith(modname), files)
- if len(have) == 1 and have[0].startswith(modname):
- return True
-
- return canmount
-
- @property
- def resizable(self):
- """ Can formats of this filesystem type be resized? """
- return super(FS, self).resizable and self.utilsAvailable
-
- @property
- def defaultFormatOptions(self):
- """ Default options passed to mkfs for this filesystem type. """
- # return a copy to prevent modification
- return self._defaultFormatOptions[:]
-
- @property
- def defaultMountOptions(self):
- """ Default options passed to mount for this filesystem type. """
- # return a copy to prevent modification
- return self._defaultMountOptions[:]
-
- @property
- def defaultLabelOptions(self):
- """ Default options passed to labeler for this filesystem type. """
- # return a copy to prevent modification
- return self._defaultLabelOptions[:]
-
- @property
- def defaultCheckOptions(self):
- """ Default options passed to checker for this filesystem type. """
- # return a copy to prevent modification
- return self._defaultCheckOptions[:]
-
- def _getOptions(self):
- options = ",".join(self.defaultMountOptions)
- if self.mountopts:
- # XXX should we clobber or append?
- options = self.mountopts
- return options
-
- def _setOptions(self, options):
- self.mountopts = options
-
- options = property(_getOptions, _setOptions)
-
- @property
- def mountType(self):
- if not self._mountType:
- self._mountType = self._type
-
- return self._mountType
-
- # 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, *args, **kwargs):
- if self.exists:
- raise FSError("filesystem already exists")
-
- DeviceFormat.create(self, *args, **kwargs)
-
- return self.doFormat(*args, **kwargs)
-
- def setup(self, *args, **kwargs):
- """ Mount the filesystem.
-
- The filesystem will be mounted at the directory indicated by
- self.mountpoint.
- """
- return self.mount(**kwargs)
-
- def teardown(self, *args, **kwargs):
- return self.unmount(*args, **kwargs)
-
- @property
- def status(self):
- # FIXME check /proc/mounts or similar
- if not self.exists:
- return False
- return self._mountpoint is not None
-
- def sync(self, root="/"):
- pass
-
-class Ext2FS(FS):
- """ ext2 filesystem. """
- _type = "ext2"
- _mkfs = "mke2fs"
- _modules = ["ext2"]
- _resizefs = "resize2fs"
- _labelfs = "e2label"
- _fsck = "e2fsck"
- _fsckErrors = {4: _("File system errors left uncorrected."),
- 8: _("Operational error."),
- 16: _("Usage or syntax error."),
- 32: _("e2fsck cancelled by user request."),
- 128: _("Shared library error.")}
- _packages = ["e2fsprogs"]
- _formattable = True
- _supported = True
- _resizable = True
- _linuxNative = True
- _maxSize = 8 * 1024 * 1024
- _minSize = 0
- _defaultFormatOptions = []
- _defaultMountOptions = ["defaults"]
- _defaultCheckOptions = ["-f", "-p", "-C", "0"]
- _dump = True
- _check = True
- _infofs = "dumpe2fs"
- _defaultInfoOptions = ["-h"]
- _existingSizeFields = ["Block count:", "Block size:"]
- _fsProfileSpecifier = "-T"
- partedSystem = fileSystemType["ext2"]
-
- def __init__(self, *args, **kwargs):
- self.dirty = False
- self.errors = False
- super(Ext2FS, self).__init__(*args, **kwargs)
-
- def _fsckFailed(self, rc):
- for errorCode in self._fsckErrors.keys():
- if rc & errorCode:
- return True
- return False
-
- def _fsckErrorMessage(self, rc):
- msg = ''
-
- for errorCode in self._fsckErrors.keys():
- if rc & errorCode:
- msg += "\n" + self._fsckErrors[errorCode]
-
- return msg.strip()
-
- def writeRandomUUID(self):
- if not self.exists:
- raise FSError("filesystem does not exist")
-
- err = None
- try:
- rc = util.run_program(["tune2fs", "-U", "random", self.device])
- except OSError as e:
- err = str(e)
- else:
- if rc:
- err = rc
-
- if err:
- raise FSError("failed to set UUID for %s: %s" % (self.device, err))
-
- @property
- def minSize(self):
- """ Minimum size for this filesystem in MB. """
- if self._minInstanceSize is None:
- # try once in the beginning to get the minimum size for an
- # existing filesystem.
- size = self._minSize
- blockSize = None
-
- if self.exists and os.path.exists(self.device):
- # get block size
- buf = util.capture_output([self.infofsProg, "-h", self.device])
- for line in buf.splitlines():
- if line.startswith("Block size:"):
- blockSize = int(line.split(" ")[-1])
-
- if line.startswith("Filesystem state:"):
- self.dirty = "not clean" in line
- self.errors = "with errors" in line
-
- if blockSize is None:
- raise FSError("failed to get block size for %s filesystem "
- "on %s" % (self.mountType, self.device))
-
- # get minimum size according to resize2fs
- buf = util.capture_output([self.resizefsProg,
- "-P", self.device])
- for line in buf.splitlines():
- if "minimum size of the filesystem:" not in line:
- continue
-
- # line will look like:
- # Estimated minimum size of the filesystem: 1148649
- #
- # NOTE: The minimum size reported is in blocks. Convert
- # to bytes, then megabytes, and finally round up.
- (text, sep, minSize) = line.partition(": ")
- size = long(minSize) * blockSize
- size = math.ceil(size / 1024.0 / 1024.0)
- break
-
- if size is None:
- log.warning("failed to get minimum size for %s filesystem "
- "on %s" % (self.mountType, self.device))
- else:
- orig_size = size
- size = min(size * 1.1, size + 500, self.currentSize)
- if orig_size < size:
- log.debug("padding min size from %d up to %d" % (orig_size, size))
- else:
- log.debug("using current size %d as min size" % size)
-
- self._minInstanceSize = size
-
- return self._minInstanceSize
-
- @property
- def needsFSCheck(self):
- return self.dirty or self.errors
-
- @property
- def resizeArgs(self):
- argv = ["-p", self.device, "%dM" % (self.targetSize,)]
- return argv
-
-register_device_format(Ext2FS)
-
-
-class Ext3FS(Ext2FS):
- """ ext3 filesystem. """
- _type = "ext3"
- _defaultFormatOptions = ["-t", "ext3"]
- _modules = ["ext3"]
- partedSystem = fileSystemType["ext3"]
-
- # It is possible for a user to specify an fsprofile that defines a blocksize
- # smaller than the default of 4096 bytes and therefore to make liars of us
- # with regard to this maximum filesystem size, but if they're doing such
- # things they should know the implications of their chosen block size.
- _maxSize = 16 * 1024 * 1024
-
- @property
- def needsFSCheck(self):
- return self.errors
-
-register_device_format(Ext3FS)
-
-
-class Ext4FS(Ext3FS):
- """ ext4 filesystem. """
- _type = "ext4"
- _defaultFormatOptions = ["-t", "ext4"]
- _modules = ["ext4"]
- partedSystem = fileSystemType["ext4"]
-
-register_device_format(Ext4FS)
-
-
-class FATFS(FS):
- """ FAT filesystem. """
- _type = "vfat"
- _mkfs = "mkdosfs"
- _modules = ["vfat"]
- _labelfs = "dosfslabel"
- _fsck = "dosfsck"
- _fsckErrors = {1: _("Recoverable errors have been detected or dosfsck has "
- "discovered an internal inconsistency."),
- 2: _("Usage error.")}
- _supported = True
- _formattable = True
- _maxSize = 1024 * 1024
- _packages = [ "dosfstools" ]
- _defaultMountOptions = ["umask=0077", "shortname=winnt"]
- # FIXME this should be fat32 in some cases
- partedSystem = fileSystemType["fat16"]
-
- def _fsckFailed(self, rc):
- if rc >= 1:
- return True
- return False
-
- def _fsckErrorMessage(self, rc):
- return self._fsckErrors[rc]
-
-register_device_format(FATFS)
-
-
-class EFIFS(FATFS):
- _type = "efi"
- _mountType = "vfat"
- _modules = ["vfat"]
- _name = "EFI System Partition"
- _minSize = 50
-
- @property
- def supported(self):
- return (isinstance(platform.platform, platform.EFI) and
- self.utilsAvailable)
-
-register_device_format(EFIFS)
-
-
-class BTRFS(FS):
- """ btrfs filesystem """
- _type = "btrfs"
- _mkfs = "mkfs.btrfs"
- _modules = ["btrfs"]
- _resizefs = "btrfsctl"
- _formattable = True
- _linuxNative = True
- _maxLabelChars = 256
- _supported = True
- _dump = True
- _check = True
- _packages = ["btrfs-progs"]
- _minSize = 256
- _maxSize = 16 * 1024 * 1024
- # FIXME parted needs to be taught about btrfs so that we can set the
- # partition table type correctly for btrfs partitions
- # partedSystem = fileSystemType["btrfs"]
-
- def __init__(self, *args, **kwargs):
- super(BTRFS, self).__init__(*args, **kwargs)
- self.volUUID = kwargs.pop("volUUID", None)
-
- def create(self, *args, **kwargs):
- # filesystem creation is done in storage.devicelibs.btrfs.create_volume
- pass
-
- def destroy(self, *args, **kwargs):
- # filesystem creation is done in storage.devicelibs.btrfs.delete_volume
- pass
-
- def setup(self, *args, **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(*args, **kwargs)
-
- def _getFormatOptions(self, options=None):
- argv = []
- if options and isinstance(options, list):
- argv.extend(options)
- argv.extend(self.defaultFormatOptions)
- if self.label:
- argv.extend(["-L", self.label])
- argv.append(self.device)
- return argv
-
- @property
- def resizeArgs(self):
- argv = ["-r", "%dm" % (self.targetSize,), self.device]
- return argv
-
-register_device_format(BTRFS)
-
-
-class GFS2(FS):
- """ gfs2 filesystem. """
- _type = "gfs2"
- _mkfs = "mkfs.gfs2"
- _modules = ["dlm", "gfs2"]
- _formattable = True
- _defaultFormatOptions = ["-j", "1", "-p", "lock_nolock", "-O"]
- _linuxNative = True
- _supported = False
- _dump = True
- _check = True
- _packages = ["gfs2-utils"]
- # FIXME parted needs to be thaught about btrfs so that we can set the
- # partition table type correctly for btrfs partitions
- # partedSystem = fileSystemType["gfs2"]
-
- @property
- def supported(self):
- """ Is this filesystem a supported type? """
- supported = self._supported
- if flags.gfs2:
- supported = self.utilsAvailable
-
- return supported
-
-register_device_format(GFS2)
-
-
-class JFS(FS):
- """ JFS filesystem """
- _type = "jfs"
- _mkfs = "mkfs.jfs"
- _modules = ["jfs"]
- _labelfs = "jfs_tune"
- _defaultFormatOptions = ["-q"]
- _defaultLabelOptions = ["-L"]
- _maxLabelChars = 16
- _maxSize = 8 * 1024 * 1024
- _formattable = True
- _linuxNative = True
- _supported = False
- _dump = True
- _check = True
- _infofs = "jfs_tune"
- _defaultInfoOptions = ["-l"]
- _existingSizeFields = ["Aggregate block size:", "Aggregate size:"]
- partedSystem = fileSystemType["jfs"]
-
- @property
- def supported(self):
- """ Is this filesystem a supported type? """
- supported = self._supported
- if flags.jfs:
- supported = self.utilsAvailable
-
- return supported
-
-register_device_format(JFS)
-
-
-class ReiserFS(FS):
- """ reiserfs filesystem """
- _type = "reiserfs"
- _mkfs = "mkreiserfs"
- _resizefs = "resize_reiserfs"
- _labelfs = "reiserfstune"
- _modules = ["reiserfs"]
- _defaultFormatOptions = ["-f", "-f"]
- _defaultLabelOptions = ["-l"]
- _maxLabelChars = 16
- _maxSize = 16 * 1024 * 1024
- _formattable = True
- _linuxNative = True
- _supported = False
- _dump = True
- _check = True
- _packages = ["reiserfs-utils"]
- _infofs = "debugreiserfs"
- _defaultInfoOptions = []
- _existingSizeFields = ["Count of blocks on the device:", "Blocksize:"]
- partedSystem = fileSystemType["reiserfs"]
-
- @property
- def supported(self):
- """ Is this filesystem a supported type? """
- supported = self._supported
- if flags.reiserfs:
- supported = self.utilsAvailable
-
- return supported
-
- @property
- def resizeArgs(self):
- argv = ["-s", "%dM" % (self.targetSize,), self.device]
- return argv
-
-register_device_format(ReiserFS)
-
-
-class XFS(FS):
- """ XFS filesystem """
- _type = "xfs"
- _mkfs = "mkfs.xfs"
- _modules = ["xfs"]
- _labelfs = "xfs_admin"
- _defaultFormatOptions = ["-f"]
- _defaultLabelOptions = ["-L"]
- _maxLabelChars = 16
- _maxSize = 16 * 1024 * 1024
- _formattable = True
- _linuxNative = True
- _supported = True
- _dump = True
- _check = True
- _packages = ["xfsprogs"]
- _infofs = "xfs_db"
- _defaultInfoOptions = ["-c", "\"sb 0\"", "-c", "\"p dblocks\"",
- "-c", "\"p blocksize\""]
- _existingSizeFields = ["dblocks =", "blocksize ="]
- partedSystem = fileSystemType["xfs"]
-
- def _getLabelArgs(self, label):
- argv = []
- argv.extend(self.defaultLabelOptions)
- argv.extend([label, self.device])
- return argv
-
- def sync(self, root='/'):
- """ Ensure that data we've written is at least in the journal.
-
- This is a little odd because xfs_freeze will only be
- available under the install root.
- """
- if not self.status or not self._mountpoint.startswith(root):
- return
-
- try:
- util.run_program(["xfs_freeze", "-f", self.mountpoint], root=root)
- except OSError as e:
- log.error("failed to run xfs_freeze: %s" % e)
-
- try:
- util.run_program(["xfs_freeze", "-u", self.mountpoint], root=root)
- except OSError as e:
- log.error("failed to run xfs_freeze: %s" % e)
-
-register_device_format(XFS)
-
-
-class HFS(FS):
- _type = "hfs"
- _mkfs = "hformat"
- _modules = ["hfs"]
- _formattable = True
- partedSystem = fileSystemType["hfs"]
-
-register_device_format(HFS)
-
-
-class AppleBootstrapFS(HFS):
- _type = "appleboot"
- _mountType = "hfs"
- _name = "Apple Bootstrap"
- _minSize = 800.00 / 1024.00
- _maxSize = 1
-
- @property
- def supported(self):
- return (isinstance(platform.platform, platform.NewWorldPPC)
- and self.utilsAvailable)
-
-register_device_format(AppleBootstrapFS)
-
-
-class HFSPlus(FS):
- _type = "hfs+"
- _modules = ["hfsplus"]
- _udevTypes = ["hfsplus"]
- _mkfs = "mkfs.hfsplus"
- _fsck = "fsck.hfsplus"
- _packages = ["hfsplus-tools"]
- _formattable = True
- _mountType = "hfsplus"
- _minSize = 1
- _maxSize = 2 * 1024 * 1024
- _check = True
- partedSystem = fileSystemType["hfs+"]
-
-register_device_format(HFSPlus)
-
-
-class NTFS(FS):
- """ ntfs filesystem. """
- _type = "ntfs"
- _resizefs = "ntfsresize"
- _fsck = "ntfsresize"
- _resizable = True
- _minSize = 1
- _maxSize = 16 * 1024 * 1024
- _defaultMountOptions = ["defaults", "ro"]
- _defaultCheckOptions = ["-c"]
- _packages = ["ntfsprogs"]
- _infofs = "ntfsinfo"
- _defaultInfoOptions = ["-m"]
- _existingSizeFields = ["Cluster Size:", "Volume Size in Clusters:"]
- partedSystem = fileSystemType["ntfs"]
-
- @property
- def mountable(self):
- return False
-
- def _fsckFailed(self, rc):
- if rc != 0:
- return True
- return False
-
- @property
- def minSize(self):
- """ The minimum filesystem size in megabytes. """
- if self._minInstanceSize is None:
- # we try one time to determine the minimum size.
- size = self._minSize
- if self.exists and os.path.exists(self.device) and \
- util.find_program_in_path(self.resizefsProg):
- minSize = None
- buf = util.run_program([self.resizefsProg, "-m", self.device])
- for l in buf.split("\n"):
- if not l.startswith("Minsize"):
- continue
- try:
- minSize = int(l.split(":")[1].strip()) # MB
- minSize *= (mb / mib) # MiB
- except (IndexError, ValueError) as e:
- minSize = None
- log.warning("Unable to parse output for minimum size on %s: %s" %(self.device, e))
-
- if minSize is None:
- log.warning("Unable to discover minimum size of filesystem "
- "on %s" %(self.device,))
- else:
- size = min(minSize * 1.1, minSize + 500, self.currentSize)
- if minSize < size:
- log.debug("padding min size from %d up to %d" % (minSize, size))
- else:
- log.debug("using current size %d as min size" % size)
-
- self._minInstanceSize = size
-
- return self._minInstanceSize
-
- @property
- def resizeArgs(self):
- # You must supply at least two '-f' options to ntfsresize or
- # the proceed question will be presented to you.
-
- # FIXME: This -1 is because our partition alignment calculations plus
- # converting back and forth between MiB and MB means the filesystem is
- # getting resized to be slightly larger than the partition holding it.
- # This hack just makes the filesystem fit.
- targetSize = (mib / mb) * (self.targetSize-1) # convert MiB to MB
- argv = ["-ff", "-s", "%dM" % (targetSize,), self.device]
- return argv
-
-
-register_device_format(NTFS)
-
-
-# if this isn't going to be mountable it might as well not be here
-class NFS(FS):
- """ NFS filesystem. """
- _type = "nfs"
- _modules = ["nfs"]
-
- def _deviceCheck(self, devspec):
- if devspec is not None and ":" not in devspec:
- raise ValueError("device must be of the form <host>:<path>")
-
- @property
- def mountable(self):
- return False
-
- def _setDevice(self, devspec):
- self._deviceCheck(devspec)
- 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")
-
-register_device_format(NFS)
-
-
-class NFSv4(NFS):
- """ NFSv4 filesystem. """
- _type = "nfs4"
- _modules = ["nfs4"]
-
-register_device_format(NFSv4)
-
-
-class Iso9660FS(FS):
- """ ISO9660 filesystem. """
- _type = "iso9660"
- _formattable = False
- _supported = True
- _resizable = False
- _linuxNative = False
- _dump = False
- _check = False
- _defaultMountOptions = ["ro"]
-
-register_device_format(Iso9660FS)
-
-
-class NoDevFS(FS):
- """ nodev filesystem base class """
- _type = "nodev"
-
- def __init__(self, *args, **kwargs):
- FS.__init__(self, *args, **kwargs)
- self.exists = True
- self.device = self.type
-
- def _setDevice(self, devspec):
- self._device = devspec
-
- def _getExistingSize(self):
- pass
-
-register_device_format(NoDevFS)
-
-
-class DevPtsFS(NoDevFS):
- """ devpts filesystem. """
- _type = "devpts"
- _defaultMountOptions = ["gid=5", "mode=620"]
-
-register_device_format(DevPtsFS)
-
-
-# these don't really need to be here
-class ProcFS(NoDevFS):
- _type = "proc"
-
-register_device_format(ProcFS)
-
-
-class SysFS(NoDevFS):
- _type = "sysfs"
-
-register_device_format(SysFS)
-
-
-class TmpFS(NoDevFS):
- _type = "tmpfs"
-
-register_device_format(TmpFS)
-
-
-class BindFS(FS):
- _type = "bind"
-
- @property
- def mountable(self):
- return True
-
- def _getExistingSize(self):
- pass
-
-register_device_format(BindFS)
-
-
-class SELinuxFS(NoDevFS):
- _type = "selinuxfs"
-
- @property
- def mountable(self):
- return flags.selinux and super(SELinuxFS, self).mountable
-
-register_device_format(SELinuxFS)
-
-
-class USBFS(NoDevFS):
- _type = "usbfs"
-
-register_device_format(USBFS)
-
diff --git a/pyanaconda/storage/formats/luks.py b/pyanaconda/storage/formats/luks.py
deleted file mode 100644
index 4b37cb430..000000000
--- a/pyanaconda/storage/formats/luks.py
+++ /dev/null
@@ -1,342 +0,0 @@
-# luks.py
-# Device format classes for anaconda's storage configuration module.
-#
-# 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
-
-try:
- import volume_key
-except ImportError:
- volume_key = None
-
-from ..storage_log import log_method_call
-from ..errors import *
-from ..devicelibs import crypto
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-class LUKS(DeviceFormat):
- """ A LUKS device. """
- _type = "luks"
- _name = "LUKS"
- _lockedName = _("Encrypted")
- _udevTypes = ["crypto_LUKS"]
- _formattable = True # can be formatted
- _supported = False # is supported
- _linuxNative = True # for clearpart
- _packages = ["cryptsetup-luks"] # required packages
-
- def __init__(self, *args, **kwargs):
- """ Create a LUKS instance.
-
- Keyword Arguments:
-
- device -- the path to the underlying device
- name -- the name of the mapped device
- uuid -- this device's UUID
- passphrase -- device passphrase (string)
- key_file -- path to a file containing a key (string)
- cipher -- cipher mode string
- key_size -- key size in bits
- exists -- indicates whether this is an existing format
- escrow_cert -- certificate to use for key escrow
- add_backup_passphrase -- generate a backup passphrase?
- """
- log_method_call(self, *args, **kwargs)
- DeviceFormat.__init__(self, *args, **kwargs)
- self.cipher = kwargs.get("cipher")
- self.key_size = kwargs.get("key_size")
- self.mapName = kwargs.get("name")
-
- if not self.exists and not self.cipher:
- self.cipher = "aes-xts-plain64"
- if not self.key_size:
- # default to the max (512 bits) for aes-xts
- self.key_size = 512
-
- # FIXME: these should both be lists, but managing them will be a pain
- self.__passphrase = kwargs.get("passphrase")
- self._key_file = kwargs.get("key_file")
- self.escrow_cert = kwargs.get("escrow_cert")
- self.add_backup_passphrase = kwargs.get("add_backup_passphrase", False)
-
- if not self.mapName and self.exists and self.uuid:
- self.mapName = "luks-%s" % self.uuid
- elif not self.mapName and self.device:
- self.mapName = "luks-%s" % os.path.basename(self.device)
-
- def __repr__(self):
- s = DeviceFormat.__repr__(self)
- if self.__passphrase:
- passphrase = "(set)"
- else:
- passphrase = "(not set)"
- s += (" cipher = %(cipher)s keySize = %(keySize)s"
- " mapName = %(mapName)s\n"
- " keyFile = %(keyFile)s passphrase = %(passphrase)s\n"
- " escrowCert = %(escrowCert)s addBackup = %(backup)s" %
- {"cipher": self.cipher, "keySize": self.key_size,
- "mapName": self.mapName, "keyFile": self._key_file,
- "passphrase": passphrase, "escrowCert": self.escrow_cert,
- "backup": self.add_backup_passphrase})
- return s
-
- @property
- def dict(self):
- d = super(LUKS, self).dict
- d.update({"cipher": self.cipher, "keySize": self.key_size,
- "mapName": self.mapName, "hasKey": self.hasKey,
- "escrowCert": self.escrow_cert,
- "backup": self.add_backup_passphrase})
- return d
-
- @property
- def name(self):
- name = self._name
- # for existing locked devices, show "Encrypted" instead of LUKS
- if self.hasKey or not self.exists:
- name = self._name
- else:
- name = "%s (%s)" % (self._lockedName, self._name)
- return name
-
- def _setPassphrase(self, passphrase):
- """ Set the passphrase used to access this device. """
- self.__passphrase = passphrase
-
- passphrase = property(fset=_setPassphrase)
-
- @property
- def hasKey(self):
- return ((self.__passphrase not in ["", None]) or
- (self._key_file and os.access(self._key_file, os.R_OK)))
-
- @property
- def configured(self):
- """ To be ready we need a key or passphrase and a map name. """
- return self.hasKey and self.mapName
-
- @property
- def status(self):
- if not self.exists or not self.mapName:
- return False
- return os.path.exists("/dev/mapper/%s" % self.mapName)
-
- def probe(self):
- """ Probe for any missing information about this format.
-
- cipher mode, key size
- """
- raise NotImplementedError("probe method not defined for LUKS")
-
- def setup(self, *args, **kwargs):
- """ Open, or set up, the format. """
- log_method_call(self, device=self.device, mapName=self.mapName,
- type=self.type, status=self.status)
- if not self.configured:
- raise LUKSError("luks device not configured")
-
- if self.status:
- return
-
- DeviceFormat.setup(self, *args, **kwargs)
- crypto.luks_open(self.device, self.mapName,
- passphrase=self.__passphrase,
- key_file=self._key_file)
-
- def teardown(self, *args, **kwargs):
- """ 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)
- crypto.luks_close(self.mapName)
-
- def create(self, *args, **kwargs):
- """ Create the format. """
- log_method_call(self, device=self.device,
- type=self.type, status=self.status)
- if not self.hasKey:
- raise LUKSError("luks device has no key/passphrase")
-
- try:
- DeviceFormat.create(self, *args, **kwargs)
- crypto.luks_format(self.device,
- passphrase=self.__passphrase,
- key_file=self._key_file,
- cipher=self.cipher,
- key_size=self.key_size)
- except Exception:
- raise
- else:
- self.uuid = crypto.luks_uuid(self.device)
- self.exists = True
- self.mapName = "luks-%s" % self.uuid
- self.notifyKernel()
-
- def destroy(self, *args, **kwargs):
- """ Create the format. """
- log_method_call(self, device=self.device,
- type=self.type, status=self.status)
- self.teardown()
- DeviceFormat.destroy(self, *args, **kwargs)
-
- @property
- def keyFile(self):
- """ Path to key file to be used in /etc/crypttab """
- return self._key_file
-
- def addKeyFromFile(self, keyfile):
- """ Add a new key from a file.
-
- Add the contents of the specified key file to an available key
- slot in the LUKS header.
- """
- log_method_call(self, device=self.device,
- type=self.type, status=self.status, file=keyfile)
- if not self.exists:
- raise LUKSError("format has not been created")
-
- crypto.luks_add_key(self.device,
- passphrase=self.__passphrase,
- key_file=self._key_file,
- new_key_file=keyfile)
-
- def addPassphrase(self, passphrase):
- """ Add a new passphrase.
-
- Add the specified passphrase to an available key slot in the
- LUKS header.
- """
- log_method_call(self, device=self.device,
- type=self.type, status=self.status)
- if not self.exists:
- raise LUKSError("format has not been created")
-
- crypto.luks_add_key(self.device,
- passphrase=self.__passphrase,
- key_file=self._key_file,
- new_passphrase=passphrase)
-
- def removeKeyFromFile(self, keyfile):
- """ Remove a key contained in a file.
-
- Remove key contained in the specified key file from the LUKS
- header.
- """
- log_method_call(self, device=self.device,
- type=self.type, status=self.status, file=keyfile)
- if not self.exists:
- raise LUKSError("format has not been created")
-
- crypto.luks_remove_key(self.device,
- passphrase=self.__passphrase,
- key_file=self._key_file,
- del_key_file=keyfile)
-
-
- def removePassphrase(self, passphrase):
- """ Remove the specified passphrase from the LUKS header. """
- log_method_call(self, device=self.device,
- type=self.type, status=self.status)
- if not self.exists:
- raise LUKSError("format has not been created")
-
- crypto.luks_remove_key(self.device,
- passphrase=self.__passphrase,
- key_file=self._key_file,
- del_passphrase=passphrase)
-
- def _escrowVolumeIdent(self, vol):
- """ Return an escrow packet filename prefix for a volume_key.Volume. """
- label = vol.label
- if label is not None:
- label = label.replace("/", "_")
- uuid = vol.uuid
- if uuid is not None:
- uuid = uuid.replace("/", "_")
- # uuid is never None on LUKS volumes
- if label is not None and uuid is not None:
- volume_ident = "%s-%s" % (label, uuid)
- elif uuid is not None:
- volume_ident = uuid
- elif label is not None:
- volume_ident = label
- else:
- volume_ident = "_unknown"
- return volume_ident
-
- def escrow(self, directory, backupPassphrase):
- log.debug("escrow: escrowVolume start for %s" % self.device)
- if volume_key is None:
- raise LUKSError("Missing key escrow support libraries")
-
- vol = volume_key.Volume.open(self.device)
- volume_ident = self._escrowVolumeIdent(vol)
-
- ui = volume_key.UI()
- # This callback is not expected to be used, let it always fail
- ui.generic_cb = lambda unused_prompt, unused_echo: None
- def known_passphrase_cb(unused_prompt, failed_attempts):
- if failed_attempts == 0:
- return self.__passphrase
- return None
- ui.passphrase_cb = known_passphrase_cb
-
- log.debug("escrow: getting secret")
- vol.get_secret(volume_key.SECRET_DEFAULT, ui)
- log.debug("escrow: creating packet")
- default_packet = vol.create_packet_assymetric_from_cert_data \
- (volume_key.SECRET_DEFAULT, self.escrow_cert, ui)
- log.debug("escrow: packet created")
- with open("%s/%s-escrow" % (directory, volume_ident), "wb") as f:
- f.write(default_packet)
- log.debug("escrow: packet written")
-
- if self.add_backup_passphrase:
- log.debug("escrow: adding backup passphrase")
- vol.add_secret(volume_key.SECRET_PASSPHRASE, backupPassphrase)
- log.debug("escrow: creating backup packet")
- backup_passphrase_packet = \
- vol.create_packet_assymetric_from_cert_data \
- (volume_key.SECRET_PASSPHRASE, self.escrow_cert, ui)
- log.debug("escrow: backup packet created")
- with open("%s/%s-escrow-backup-passphrase" %
- (directory, volume_ident), "wb") as f:
- f.write(backup_passphrase_packet)
- log.debug("escrow: backup packet written")
-
- log.debug("escrow: escrowVolume done for %s" % repr(self.device))
-
-
-register_device_format(LUKS)
-
diff --git a/pyanaconda/storage/formats/lvmpv.py b/pyanaconda/storage/formats/lvmpv.py
deleted file mode 100644
index d804711fa..000000000
--- a/pyanaconda/storage/formats/lvmpv.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# lvmpv.py
-# Device format classes for anaconda's storage configuration module.
-#
-# 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 ..storage_log import log_method_call
-from parted import PARTITION_LVM
-from ..errors import *
-from ..devicelibs import lvm
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-class LVMPhysicalVolume(DeviceFormat):
- """ An LVM physical volume. """
- _type = "lvmpv"
- _name = "physical volume (LVM)"
- _udevTypes = ["LVM2_member"]
- partedFlag = PARTITION_LVM
- _formattable = True # can be formatted
- _supported = True # is supported
- _linuxNative = True # for clearpart
- _minSize = lvm.LVM_PE_SIZE * 2 # one for metadata and one for data
- _packages = ["lvm2"] # required packages
-
- def __init__(self, *args, **kwargs):
- """ Create an LVMPhysicalVolume instance.
-
- Keyword Arguments:
-
- device -- path to the underlying device
- uuid -- this PV's uuid (not the VG uuid)
- vgName -- the name of the VG this PV belongs to
- vgUuid -- the UUID of the VG this PV belongs to
- peStart -- offset of first physical extent
- exists -- indicates whether this is an existing format
-
- """
- log_method_call(self, *args, **kwargs)
- DeviceFormat.__init__(self, *args, **kwargs)
- self.vgName = kwargs.get("vgName")
- self.vgUuid = kwargs.get("vgUuid")
- # liblvm may be able to tell us this at some point, even
- # for not-yet-created devices
- self.peStart = kwargs.get("peStart", lvm.LVM_PE_START) # in MB
-
- self.inconsistentVG = False
-
- def __repr__(self):
- s = DeviceFormat.__repr__(self)
- s += (" vgName = %(vgName)s vgUUID = %(vgUUID)s"
- " peStart = %(peStart)s" %
- {"vgName": self.vgName, "vgUUID": self.vgUuid,
- "peStart": self.peStart})
- return s
-
- @property
- def dict(self):
- d = super(LVMPhysicalVolume, self).dict
- d.update({"vgName": self.vgName, "vgUUID": self.vgUuid,
- "peStart": self.peStart})
- return d
-
- def probe(self):
- """ Probe for any missing information about this device. """
- log_method_call(self, device=self.device,
- type=self.type, status=self.status)
- if not self.exists:
- raise PhysicalVolumeError("format has not been created")
-
- #info = lvm.pvinfo(self.device)
- #self.vgName = info['vg_name']
- #self.vgUuid = info['vg_uuid']
-
- def create(self, *args, **kwargs):
- """ Create the format. """
- log_method_call(self, device=self.device,
- type=self.type, status=self.status)
-
- try:
- DeviceFormat.create(self, *args, **kwargs)
- # 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...
- DeviceFormat.destroy(self, *args, **kwargs)
-
- lvm.pvcreate(self.device)
- except Exception:
- raise
- else:
- self.exists = True
- self.notifyKernel()
-
- def destroy(self, *args, **kwargs):
- """ Destroy the format. """
- 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:
- lvm.pvremove(self.device)
- except LVMError:
- DeviceFormat.destroy(self, *args, **kwargs)
-
- self.exists = False
- self.notifyKernel()
-
- @property
- def status(self):
- # XXX hack
- return (self.exists and self.vgName and
- os.path.isdir("/dev/mapper/%s" % self.vgName))
-
-register_device_format(LVMPhysicalVolume)
-
diff --git a/pyanaconda/storage/formats/mdraid.py b/pyanaconda/storage/formats/mdraid.py
deleted file mode 100644
index 9d1e26eed..000000000
--- a/pyanaconda/storage/formats/mdraid.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# mdraid.py
-# Device format classes for anaconda's storage configuration module.
-#
-# 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 ..storage_log import log_method_call
-from parted import PARTITION_RAID
-from ..errors import *
-from ..devicelibs import mdraid
-from . import DeviceFormat, register_device_format
-from ..flags import flags
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-class MDRaidMember(DeviceFormat):
- """ An mdraid member disk. """
- _type = "mdmember"
- _name = "software RAID"
- _udevTypes = ["linux_raid_member"]
- partedFlag = PARTITION_RAID
- _formattable = True # can be formatted
- _supported = True # is supported
- _linuxNative = True # for clearpart
- _packages = ["mdadm"] # required packages
-
- def __init__(self, *args, **kwargs):
- """ Create a MDRaidMember instance.
-
- Keyword Arguments:
-
- device -- path to underlying device
- uuid -- this member device's uuid
- mdUuid -- the uuid of the array this device belongs to
- exists -- indicates whether this is an existing format
-
- """
- log_method_call(self, *args, **kwargs)
- DeviceFormat.__init__(self, *args, **kwargs)
- self.mdUuid = kwargs.get("mdUuid")
- self.raidMinor = None
-
- #self.probe()
- self.biosraid = kwargs.get("biosraid")
-
- def __repr__(self):
- s = DeviceFormat.__repr__(self)
- s += (" mdUUID = %(mdUUID)s biosraid = %(biosraid)s" %
- {"mdUUID": self.mdUuid, "biosraid": self.biosraid})
- return s
-
- @property
- def dict(self):
- d = super(MDRaidMember, self).dict
- d.update({"mdUUID": self.mdUuid, "biosraid": self.biosraid})
- return d
-
- def probe(self):
- """ Probe for any missing information about this format. """
- log_method_call(self, device=self.device,
- type=self.type, status=self.status)
- if not self.exists:
- raise MDMemberError("format does not exist")
-
- info = mdraid.mdexamine(self.device)
- if self.uuid is None:
- self.uuid = info['uuid']
- if self.raidMinor is None:
- self.raidMinor = info['mdMinor']
-
- def destroy(self, *args, **kwargs):
- 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")
-
- mdraid.mddestroy(self.device)
- self.exists = False
-
- @property
- def status(self):
- # XXX hack -- we don't have a nice way to see if the array is active
- return False
-
- @property
- def hidden(self):
- return (self._hidden or self.biosraid)
-
-# nodmraid -> Wether to use BIOS RAID or not
-# Note the anaconda cmdline has not been parsed yet when we're first imported,
-# so we can not use flags.dmraid here
-if not flags.noiswmd and flags.dmraid:
- MDRaidMember._udevTypes.append("isw_raid_member")
-
-register_device_format(MDRaidMember)
-
diff --git a/pyanaconda/storage/formats/multipath.py b/pyanaconda/storage/formats/multipath.py
deleted file mode 100644
index 01d69ee3e..000000000
--- a/pyanaconda/storage/formats/multipath.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# multipath.py
-# multipath device formats
-#
-# Copyright (C) 2009 Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty 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, see <http://www.gnu.org/licenses/>.
-#
-# 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): Peter Jones <pjones@redhat.com>
-#
-
-from ..storage_log import log_method_call
-from ..errors import *
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-class MultipathMember(DeviceFormat):
- """ A multipath member disk. """
- _type = "multipath_member"
- _name = "multipath member device"
- _udev_types = ["multipath_member"]
- _formattable = False # can be formatted
- _supported = True # is supported
- _linuxNative = False # for clearpart
- _packages = ["device-mapper-multipath"] # required packages
- _resizable = False # can be resized
- _maxSize = 0 # maximum size in MB
- _minSize = 0 # minimum size in MB
- _hidden = True # 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
-
- On initialization this format is like DeviceFormat
-
- """
- log_method_call(self, *args, **kwargs)
- DeviceFormat.__init__(self, *args, **kwargs)
-
- # Initialize the attribute that will hold the block object.
- self._member = None
-
- def __repr__(self):
- s = DeviceFormat.__repr__(self)
- s += (" member = %(member)r" % {"member": self.member})
- return s
-
- def _getMember(self):
- return self._member
-
- def _setMember(self, member):
- self._member = member
-
- member = property(lambda s: s._getMember(),
- lambda s,m: s._setMember(m))
-
- def create(self, *args, **kwargs):
- log_method_call(self, device=self.device,
- type=self.type, status=self.status)
- raise MultipathMemberError("creation of multipath members is non-sense")
-
- def destroy(self, *args, **kwargs):
- log_method_call(self, device=self.device,
- type=self.type, status=self.status)
- raise MultipathMemberError("destruction of multipath members is non-sense")
-
-register_device_format(MultipathMember)
-
diff --git a/pyanaconda/storage/formats/prepboot.py b/pyanaconda/storage/formats/prepboot.py
deleted file mode 100644
index dd2cf8c82..000000000
--- a/pyanaconda/storage/formats/prepboot.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# prepboot.py
-# Format class for PPC PReP Boot.
-#
-# 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>
-#
-
-from ..errors import *
-from .. import platform
-from . import DeviceFormat, register_device_format
-from parted import PARTITION_PREP
-import os
-import logging
-log = logging.getLogger("storage")
-
-class PPCPRePBoot(DeviceFormat):
- """ Generic device format. """
- _type = "prepboot"
- _name = "PPC PReP Boot"
- _udevTypes = []
- partedFlag = PARTITION_PREP
- _formattable = True # can be formatted
- _linuxNative = True # for clearpart
- _maxSize = 10 # maximum size in MB
- _minSize = 4 # minimum size in MB
-
- def __init__(self, *args, **kwargs):
- """ Create a PRePBoot instance.
-
- Keyword Arguments:
-
- device -- path to the underlying device
- exists -- indicates whether this is an existing format
-
- """
- DeviceFormat.__init__(self, *args, **kwargs)
-
- def create(self, *args, **kwargs):
- if self.exists:
- raise FSError("PReP Boot format already exists")
-
- DeviceFormat.create(self, *args, **kwargs)
-
- try:
- fd = os.open(self.device, os.O_RDWR)
- length = os.lseek(fd, 0, os.SEEK_END)
- os.lseek(fd, 0, os.SEEK_SET)
- buf = '\0' * 1024 * 1024
- while length > 0:
- if length >= len(buf):
- os.write(fd, buf)
- length -= len(buf)
- else:
- 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))
- if fd:
- os.close(fd)
-
- @property
- def status(self):
- return False
-
- @property
- def supported(self):
- return isinstance(platform.platform, platform.IPSeriesPPC)
-
-register_device_format(PPCPRePBoot)
-
diff --git a/pyanaconda/storage/formats/swap.py b/pyanaconda/storage/formats/swap.py
deleted file mode 100644
index 903fe6e2c..000000000
--- a/pyanaconda/storage/formats/swap.py
+++ /dev/null
@@ -1,171 +0,0 @@
-# swap.py
-# Device format classes for anaconda's storage configuration module.
-#
-# 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>
-#
-
-from parted import PARTITION_SWAP, fileSystemType
-from ..storage_log import log_method_call
-from ..errors import *
-from ..util import numeric_type
-from ..devicelibs import swap
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-class SwapSpace(DeviceFormat):
- """ Swap space """
- _type = "swap"
- _name = None
- _udevTypes = ["swap"]
- partedFlag = PARTITION_SWAP
- partedSystem = fileSystemType["linux-swap(v1)"]
- _formattable = True # can be formatted
- _supported = True # is supported
- _linuxNative = True # for clearpart
-
- #see rhbz#744129 for details
- _maxSize = 128 * 1024
-
- def __init__(self, *args, **kwargs):
- """ Create a SwapSpace instance.
-
- Keyword Arguments:
-
- device -- path to the underlying device
- uuid -- this swap space's uuid
- label -- this swap space's label
- priority -- this swap space's priority
- exists -- indicates whether this is an existing format
-
- """
- log_method_call(self, *args, **kwargs)
- DeviceFormat.__init__(self, *args, **kwargs)
-
- self.priority = kwargs.get("priority")
- self.label = kwargs.get("label")
-
- def __repr__(self):
- s = DeviceFormat.__repr__(self)
- s += (" priority = %(priority)s label = %(label)s" %
- {"priority": self.priority, "label": self.label})
- return s
-
- @property
- def dict(self):
- d = super(SwapSpace, self).dict
- d.update({"priority": self.priority, "label": self.label})
- return d
-
- def _setPriority(self, priority):
- if priority is None:
- self._priority = None
- return
-
- if not isinstance(priority, int) or not 0 <= priority <= 32767:
- raise ValueError("swap priority must be an integer between 0 and 32767")
-
- self._priority = priority
-
- def _getPriority(self):
- return self._priority
-
- priority = property(_getPriority, _setPriority,
- doc="The priority of the swap device")
-
- def _getOptions(self):
- opts = ""
- if self.priority is not None:
- opts += "pri=%d" % self.priority
-
- return opts
-
- def _setOptions(self, opts):
- if not opts:
- self.priority = None
- return
-
- for option in opts.split(","):
- (opt, equals, arg) = option.partition("=")
- if equals and opt == "pri":
- try:
- self.priority = int(arg)
- except ValueError:
- log.info("invalid value for swap priority: %s" % arg)
-
- options = property(_getOptions, _setOptions,
- doc="The swap device's fstab options string")
-
- @property
- def status(self):
- """ Device status. """
- return self.exists and swap.swapstatus(self.device)
-
- def setup(self, *args, **kwargs):
- """ Open, or set up, 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")
-
- if self.status:
- return
-
- DeviceFormat.setup(self, *args, **kwargs)
- swap.swapon(self.device, priority=self.priority)
-
- def teardown(self, *args, **kwargs):
- """ 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")
-
- if self.status:
- swap.swapoff(self.device)
-
- def create(self, *args, **kwargs):
- """ Create the device. """
- log_method_call(self, device=self.device,
- type=self.type, status=self.status)
- force = kwargs.get("force")
- if not force and self.exists:
- raise SwapSpaceError("format already exists")
-
- if force:
- self.teardown()
- elif self.status:
- raise SwapSpaceError("device exists and is active")
-
- try:
- DeviceFormat.create(self, *args, **kwargs)
- swap.mkswap(self.device, label=self.label)
- except Exception:
- raise
- else:
- self.exists = True
- self.notifyKernel()
-
-register_device_format(SwapSpace)
-