/*.iso
/*.tar.gz
*~
+*.py[co]
include Config
PKG_NAME = pyparted
-PKG_VER = 2.0.10
+PKG_VER = 2.0.12
THISAPP = $(PKG_NAME)-$(PKG_VER)
DL_FILE = $(THISAPP).tar.gz
# restore original exception handler
sys.excepthook = sys.__excepthook__
+ installer.log.error("Exception occured. Read more in /tmp/instdump.txt.")
+
# get traceback information
list = formatException(type, value, tb)
text = string.joinfields(list, "")
def critical(self, msg):
self.logfile.write(self.logline % (self.time(), "CRITICAL", msg,))
+ self.flush()
def info(self, msg):
self.logfile.write(self.logline % (self.time(), "INFO", msg,))
+ self.flush()
def debug(self, msg):
self.logfile.write(self.logline % (self.time(), "DEBUG", msg,))
+ self.flush()
def error(self, msg):
self.logfile.write(self.logline % (self.time(), "ERROR", msg,))
+ self.flush()
def warning(self, msg):
self.logfile.write(self.logline % (self.time(), "WARNING", msg,))
+ self.flush()
def stdout(self, msg):
self.logfile.write(self.logline % (self.time(), "STDOUT", msg,))
+ self.flush()
print msg
def time(self):
def __del__(self):
self.logfile.close()
+
+ def flush(self):
+ self.logfile.flush()
from snack import *
+from storage.deviceaction import *
+import storage
import storage.formats as formats
from storage.devicelibs.lvm import safeLvmName
return
row = 0
+ actions = []
if not device.exists:
tstr = _("Add Partition")
tstr = _("Edit Partition")
grid = GridForm(self.screen, tstr, 1, 6)
+ if device.exists:
+ if device.format.exists and getattr(device.format, "label", None):
+ lbl = Label("%s %s" % (_("Original File System Label:"), device.format.label))
+ grid.add(lbl, 0, row)
+ row += 1
+
(mountgrid, mountpoint) = self.makeMountPoint(device)
grid.add(mountgrid, 0, row)
row += 1
subgrid1 = Grid(2, 1)
(devgrid, drivelist) = self.makeDriveList(device)
- subgrid1.setField(devgrid, 0, 0, (0,1,0,0), growx=1)
+ subgrid1.setField(devgrid, 0, 0)
(fsgrid, fstype) = self.makeFileSystemList(device)
- subgrid1.setField(fsgrid, 1, 0)
+ subgrid1.setField(fsgrid, 1, 0, (1,0,0,0), growx=1)
grid.add(subgrid1, 0, row, (0,1,0,0), growx=1)
row += 1
+ else:
+ pass
bb = ButtonBar(self.screen, (TEXT_OK_BUTTON, TEXT_CANCEL_BUTTON))
grid.add(bb, 0, row, (0,1,0,0), growx = 1)
if device.format:
device.format.mountpoint = mountpoint.value()
+
+ if not device.exists:
+ actions.append(ActionCreateDevice(self.installer, device))
break
self.screen.popWindow()
+ return actions
def editVG(self, device):
if not device.exists:
self.installer.intf.messageWindow(_("Unable To Edit"),
_("You must first select a partition to edit."))
return
+
+ reason = self.storage.deviceImmutable(device)
+ if reason:
+ self.installer.intf.messageWindow(_("Unable To Edit"),
+ _("You cannot edit this device:\n\n%s")
+ % reason,)
+ return
- self.editPart(device)
+ actions = None
+ if device.type == "mdarray":
+ pass #self.editRaidArray(device)
+ elif device.type == "lvmvg":
+ actions = self.editVG(device)
+ elif device.type == "lvmlv":
+ actions = self.editLV(device)
+ elif isinstance(device, storage.devices.PartitionDevice):
+ actions = self.editPart(device)
+
+ for action in actions:
+ self.storage.devicetree.registerAction(action)
def deleteCb(self):
device = self.lb.current()
-
- self.installer.log.debug("%s" % device.type)
-
+
if not device:
self.installer.intf.messageWindow(_("Unable To Delete"),
_("You must first select a partition to delete."))
self.screen = self.installer.intf.screen
self.storage = self.installer.ds.storage
- self.installer.intf.setHelpline(_("F1-Help F2-New F3-Edit F4-Delete F5-Reset F12-OK"))
+ self.installer.intf.setHelpline(_("F2-New F3-Edit F4-Delete F5-Reset F12-OK"))
self.g = GridForm(self.screen, _("Partitioning"), 1, 5)
self.lb = CListbox(height=10, cols=4,
return lvtemplate
+ def deviceImmutable(self, device):
+ """ Return any reason the device cannot be modified/removed.
+
+ Return False if the device can be removed.
+
+ Devices that cannot be removed include:
+
+ - protected partitions
+ - devices that are part of an md array or lvm vg
+ - extended partition containing logical partitions that
+ meet any of the above criteria
+
+ """
+ if not isinstance(device, Device):
+ raise ValueError("arg1 (%s) must be a Device instance" % device)
+
+ if device.name in self.protectedDisks:
+ return _("This partition is holding the data for the hard "
+ "drive install.")
+ elif device.format.type == "mdmember":
+ for array in self.mdarrays:
+ if array.dependsOn(device):
+ if array.minor is not None:
+ return _("This device is part of the RAID "
+ "device %s.") % (array.path,)
+ else:
+ return _("This device is part of a RAID device.")
+ elif device.format.type == "lvmpv":
+ for vg in self.vgs:
+ if vg.dependsOn(device):
+ if vg.name is not None:
+ return _("This device is part of the LVM "
+ "volume group '%s'.") % (vg.name,)
+ else:
+ return _("This device is part of a LVM volume "
+ "group.")
+ elif device.format.type == "luks":
+ try:
+ luksdev = self.devicetree.getChildren(device)[0]
+ except IndexError:
+ pass
+ else:
+ return self.deviceImmutable(luksdev)
+ elif isinstance(device, PartitionDevice) and device.isExtended:
+ reasons = {}
+ for dep in self.deviceDeps(device):
+ reason = self.deviceImmutable(dep)
+ if reason:
+ reasons[dep.path] = reason
+ if reasons:
+ msg = _("This device is an extended partition which "
+ "contains logical partitions that cannot be "
+ "deleted:\n\n")
+ for dev in reasons:
+ msg += "%s: %s" % (dev, reasons[dev])
+ return msg
+
+ for i in self.devicetree.immutableDevices:
+ if i[0] == device.name:
+ return i[1]
+
+ return False
+
+
class FSSet(object):
""" A class to represent a set of filesystems. """
def __init__(self, installer):
#/usr/bin/python
+import copy
import math
import parted
+import _ped
+from errors import *
from formats import get_device_format_class, getFormat
from udev import *
from util import notify_kernel, numeric_type
for parent in self.parents:
parent.addChild()
+ def __deepcopy__(self, memo):
+ """ Create a deep copy of a Device 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 = ('partedDisk', '_partedDevice',
+ '_partedPartition', '_origPartedDisk',
+ '_raidSet', 'installer', 'screen')
+ for (attr, value) in self.__dict__.items():
+ if attr in shallow_copy_attrs:
+ setattr(new, attr, copy.copy(value))
+ else:
+ setattr(new, attr, copy.deepcopy(value, memo))
+
+ return new
+
def removeChild(self):
self.kids -= 1
else:
return self.format.maxSize
+class OpticalDevice(StorageDevice):
+ """ An optical drive, eg: cdrom, dvd+r, &c.
+
+ XXX Is this useful?
+ """
+ _type = "cdrom"
+
+ def __init__(self, installer, name, major=None, minor=None, exists=None,
+ format=None, parents=None, sysfsPath=''):
+ StorageDevice.__init__(self, installer, name, format=format,
+ major=major, minor=minor, exists=True,
+ parents=parents, sysfsPath=sysfsPath)
+
+ @property
+ def mediaPresent(self):
+ """ Return a boolean indicating whether or not the device contains
+ media.
+ """
+ if not self.exists:
+ raise DeviceError("device has not been created", self.path)
+
+ try:
+ fd = os.open(self.path, os.O_RDONLY)
+ except OSError as e:
+ # errno 123 = No medium found
+ if e.errno == 123:
+ return False
+ else:
+ return True
+ else:
+ os.close(fd)
+ return True
+
+ def eject(self):
+ """ Eject the drawer. """
+ #import _isys
+
+ if not self.exists:
+ raise DeviceError("device has not been created", self.path)
+
+ # Make a best effort attempt to do the eject. If it fails, it's not
+ # critical.
+ fd = os.open(self.path, os.O_RDONLY | os.O_NONBLOCK)
+
+ #try:
+ # _isys.ejectcdrom(fd)
+ #except SystemError as e:
+ # log.warning("error ejecting cdrom %s: %s" % (self.name, e))
+
+ os.close(fd)
+
class DMDevice(StorageDevice):
""" A device-mapper device """
_type = "dm"
#!/usr/bin/python
import os
+import block
import formats
self._actions = []
self._ignoredDisks = []
+ self.immutableDevices = []
for disk in self.storage.ignoredDisks:
self.addIgnoredDisk(disk)
sysfs_path = udev_device_get_sysfs_path(info)
if self.isIgnored(info):
- #self.installer.log.debug("Ignoring %s (%s)" % (name, sysfs_path))
+ self.installer.log.debug("Ignoring %s (%s)" % (name, sysfs_path))
return
- #self.installer.log.debug("Scanning %s (%s)..." % (name, sysfs_path))
+ self.installer.log.debug("Scanning %s (%s)..." % (name, sysfs_path))
device = self.getDeviceByName(name)
#
# The first step is to either look up or create the device
#
if udev_device_is_dm(info):
- pass
- # # try to look up the device
- # if device is None and uuid:
- # # try to find the device by uuid
- # device = self.getDeviceByUuid(uuid)
- #
- # if device is None:
- # device = self.addUdevDMDevice(info)
- #elif udev_device_is_md(info):
- # if device is None and uuid:
- # # try to find the device by uuid
- # device = self.getDeviceByUuid(uuid)
- #
- # if device is None:
- # device = self.addUdevMDDevice(info)
- #elif udev_device_is_cdrom(info):
- # if device is None:
- # device = self.addUdevOpticalDevice(info)
- #elif udev_device_is_dmraid(info):
+ # try to look up the device
+ if device is None and uuid:
+ # try to find the device by uuid
+ device = self.getDeviceByUuid(uuid)
+
+ if device is None:
+ device = self.addUdevDMDevice(info)
+ elif udev_device_is_md(info):
+ if device is None and uuid:
+ # try to find the device by uuid
+ device = self.getDeviceByUuid(uuid)
+
+ if device is None:
+ device = self.addUdevMDDevice(info)
+ elif udev_device_is_cdrom(info):
+ if device is None:
+ device = self.addUdevOpticalDevice(info)
+ elif udev_device_is_dmraid(info):
# This is special handling to avoid the "unrecognized disklabel"
# code since dmraid member disks won't have a disklabel. We
# use a StorageDevice because DiskDevices need disklabels.
# Quite lame, but it doesn't matter much since we won't use
# the StorageDevice instances for anything.
- # if device is None:
- # device = StorageDevice(name,
- # major=udev_device_get_major(info),
- # minor=udev_device_get_minor(info),
- # sysfsPath=sysfs_path, exists=True)
- # self._addDevice(device)
+ if device is None:
+ device = StorageDevice(name,
+ major=udev_device_get_major(info),
+ minor=udev_device_get_minor(info),
+ sysfsPath=sysfs_path, exists=True)
+ self._addDevice(device)
elif udev_device_is_disk(info):
if device is None:
device = self.addUdevDiskDevice(info)
device = self.addUdevPartitionDevice(info)
# now handle the device's formatting
- #self.handleUdevDeviceFormat(info, device)
+ self.handleUdevDeviceFormat(info, device)
def addUdevDiskDevice(self, info):
name = udev_device_get_name(info)
self._addDevice(device)
return device
+ def addUdevOpticalDevice(self, info):
+ # Looks like if it has ID_INSTANCE=0:1 we can ignore it.
+ device = OpticalDevice(self.installer, udev_device_get_name(info),
+ major=udev_device_get_major(info),
+ minor=udev_device_get_minor(info),
+ sysfsPath=udev_device_get_sysfs_path(info))
+ self._addDevice(device)
+ return device
+
+ def handleUdevDeviceFormat(self, info, device):
+ #log.debug("%s" % info)
+ name = udev_device_get_name(info)
+ sysfs_path = udev_device_get_sysfs_path(info)
+ uuid = udev_device_get_uuid(info)
+ label = udev_device_get_label(info)
+ format_type = udev_device_get_format(info)
+
+ format = None
+ if (not device) or (not format_type) or device.format.type:
+ # this device has no formatting or it has already been set up
+ # FIXME: this probably needs something special for disklabels
+ self.installer.log.debug("no type or existing type for %s, bailing" % (name,))
+ return
+
+ # set up the common arguments for the format constructor
+ args = [format_type]
+ kwargs = {"uuid": uuid,
+ "label": label,
+ "device": device.path,
+ "exists": True}
+
+ # set up type-specific arguments for the format constructor
+ if format_type == "crypto_LUKS":
+ # luks/dmcrypt
+ kwargs["name"] = "luks-%s" % uuid
+ elif format_type == "linux_raid_member":
+ # mdraid
+ try:
+ kwargs["mdUuid"] = udev_device_get_md_uuid(info)
+ except KeyError:
+ self.installer.log.debug("mdraid member %s has no md uuid" % name)
+ elif format_type == "LVM2_member":
+ # lvm
+ try:
+ kwargs["vgName"] = udev_device_get_vg_name(info)
+ except KeyError as e:
+ self.installer.log.debug("PV %s has no vg_name" % name)
+ try:
+ kwargs["vgUuid"] = udev_device_get_vg_uuid(info)
+ except KeyError:
+ self.installer.log.debug("PV %s has no vg_uuid" % name)
+ try:
+ kwargs["peStart"] = udev_device_get_pv_pe_start(info)
+ except KeyError:
+ self.installer.log.debug("PV %s has no pe_start" % name)
+
+ try:
+ self.installer.log.debug("type detected on '%s' is '%s'" % (name, format_type,))
+ device.format = formats.getFormat(format_type, *args, **kwargs)
+ except FSError, e:
+ self.installer.log.debug("type '%s' on '%s' invalid, assuming no format - %s" %
+ (format_type, name, e,))
+ device.format = formats.DeviceFormat(self.installer)
+ return
+
+ #
+ # now do any special handling required for the device's format
+ #
+ #if device.format.type == "luks":
+ # self.handleUdevLUKSFormat(info, device)
+ #elif device.format.type == "mdmember":
+ # self.handleUdevMDMemberFormat(info, device)
+ #elif device.format.type == "dmraidmember":
+ # self.handleUdevDMRaidMemberFormat(info, device)
+ #elif device.format.type == "lvmpv":
+ # self.handleUdevLVMPVFormat(info, device)
+
+ def handleUdevDMRaidMemberFormat(self, info, device):
+ name = udev_device_get_name(info)
+ sysfs_path = udev_device_get_sysfs_path(info)
+ uuid = udev_device_get_uuid(info)
+ major = udev_device_get_major(info)
+ minor = udev_device_get_minor(info)
+
+ def _all_ignored(rss):
+ retval = True
+ for rs in rss:
+ if rs.name not in self._ignoredDisks:
+ retval = False
+ break
+ return retval
+
+ # Have we already created the DMRaidArrayDevice?
+ rss = block.getRaidSetFromRelatedMem(uuid=uuid, name=name,
+ major=major, minor=minor)
+ if len(rss) == 0:
+ # we ignore the device in the hope that all the devices
+ # from this set will be ignored.
+ # FIXME: Can we reformat a raid device?
+ self.addIgnoredDisk(device.name)
+ return
+
+ # We ignore the device if all the rss are in self._ignoredDisks
+ if _all_ignored(rss):
+ self.addIgnoredDisk(device.name)
+ return
+
+ for rs in rss:
+ dm_array = self.getDeviceByName(rs.name)
+ if dm_array is not None:
+ # We add the new device.
+ dm_array._addDevice(device)
+ else:
+ # Activate the Raid set.
+ rs.activate(mknod=True)
+
+ # Create the DMRaidArray
+ if self.zeroMbr:
+ cb = lambda: True
+ else:
+ cb = lambda: questionInitializeDisk(self.intf,
+ rs.name)
+
+ # Create the DMRaidArray
+ if not self.clearPartDisks or \
+ rs.name in self.clearPartDisks:
+ # if the disk contains protected partitions
+ # we will not wipe the disklabel even if
+ # clearpart --initlabel was specified
+ initlabel = self.reinitializeDisks
+ for protected in self.protectedPartitions:
+ disk_name = re.sub(r'p\d+$', '', protected)
+ if disk_name != protected and \
+ disk_name == rs.name:
+ initlabel = False
+ break
+
+ try:
+ dm_array = DMRaidArrayDevice(rs.name,
+ raidSet=rs,
+ parents=[device],
+ initcb=cb,
+ initlabel=initlabel)
+
+ self._addDevice(dm_array)
+ # Use the rs's object on the device.
+ # pyblock can return the memebers of a set and the
+ # device has the attribute to hold it. But ATM we
+ # are not really using it. Commenting this out until
+ # we really need it.
+ #device.format.raidmem = block.getMemFromRaidSet(dm_array,
+ # major=major, minor=minor, uuid=uuid, name=name)
+ except DeviceUserDeniedFormatError:
+ # We should ignore the dmraid and its components
+ self.addIgnoredDisk(rs.name)
+ if _all_ignored(rss):
+ self.addIgnoredDisk(device.name)
+ rs.deactivate()
+
def getDependentDevices(self, dep):
""" Return a list of devices that depend on dep.
#!/usr/bin/python
import os
+import copy
device_formats = {}
def register_device_format(fmt_class):
raise DeviceFormatError("None of %s is supported by your kernel" % ",".join(fstypes))
-class DeviceFormat:
+class DeviceFormat(object):
""" Generic device format. """
_type = None
_name = "Unknown"
self.options = kwargs.get("options")
self._migrate = False
+ def __deepcopy__(self, memo):
+ new = self.__class__.__new__(self.__class__)
+ memo[id(self)] = new
+ shallow_copy_attrs = ('installer', 'screen')
+ for (attr, value) in self.__dict__.items():
+ if attr in shallow_copy_attrs:
+ setattr(new, attr, copy.copy(value))
+ else:
+ setattr(new, attr, copy.deepcopy(value, memo))
+
+ return new
+
def _setOptions(self, options):
self._options = options
from parted import PARTITION_SWAP
from . import DeviceFormat, register_device_format
+from ..devicelibs import swap
class SwapSpace(DeviceFormat):
""" Swap space """
def run(self):
self.rc = ButtonChoiceWindow(self.screen, _("Exception Occurred"),
- self.text, self.buttons)
+ self.text, self.buttons, width=60)
def getrc(self):
return 0