diff options
Diffstat (limited to 'iw')
-rw-r--r-- | iw/autopart_type.py | 95 | ||||
-rw-r--r-- | iw/bootloader_main_gui.py | 33 | ||||
-rw-r--r-- | iw/examine_gui.py | 8 | ||||
-rw-r--r-- | iw/lvm_dialog_gui.py | 800 | ||||
-rw-r--r-- | iw/osbootwidget.py | 34 | ||||
-rw-r--r-- | iw/partition_dialog_gui.py | 436 | ||||
-rw-r--r-- | iw/partition_gui.py | 656 | ||||
-rw-r--r-- | iw/partition_ui_helpers_gui.py | 172 | ||||
-rw-r--r-- | iw/raid_dialog_gui.py | 374 | ||||
-rw-r--r-- | iw/timezone_gui.py | 2 | ||||
-rw-r--r-- | iw/upgrade_migratefs_gui.py | 54 | ||||
-rw-r--r-- | iw/upgrade_swap_gui.py | 16 |
12 files changed, 1265 insertions, 1415 deletions
diff --git a/iw/autopart_type.py b/iw/autopart_type.py index db6afb9f2..bb3853323 100644 --- a/iw/autopart_type.py +++ b/iw/autopart_type.py @@ -31,26 +31,25 @@ from netconfig_dialog import NetworkConfigurator from iw_gui import * from flags import flags import network -import partitions -import iscsi +from storage import iscsi import gettext _ = lambda x: gettext.ldgettext("anaconda", x) -def whichToResize(partitions, diskset, intf): +def whichToResize(storage, intf): def getActive(combo): act = combo.get_active_iter() return combo.get_model().get_value(act, 1) def comboCB(combo, resizeSB): # partition to resize changed, let's update our spinbutton - req = getActive(combo) - if req.targetSize is not None: - value = req.targetSize + part = getActive(combo) + if part.targetSize is not None: + value = part.targetSize else: - value = req.size - reqlower = req.getMinimumResizeMB(partitions) - requpper = req.getMaximumResizeMB(partitions) + value = part.size + reqlower = part.minSize + requpper = part.maxSize adj = resizeSB.get_adjustment() adj.lower = reqlower @@ -71,16 +70,17 @@ def whichToResize(partitions, diskset, intf): found = False biggest = -1 - for req in partitions.requests: - if req.type != REQUEST_PREEXIST: + for part in storage.partitions: + if not part.exists: continue - if req.isResizable(partitions): + + if part.resizable: i = store.append(None) - store[i] = ("%s (%s, %d MB)" %(req.device, - req.fstype.getName(), - math.floor(req.size)), - req) - if req.targetSize is not None: + store[i] = ("%s (%s, %d MB)" %(part.name, + part.format.name, + math.floor(part.size)), + part) + if part.targetSize is not None: combo.set_active_iter(i) found = True else: @@ -118,7 +118,7 @@ class PartitionTypeWindow(InstallWindow): ics.setNextEnabled(True) def getNext(self): - if self.diskset.checkNoDisks(): + if self.storage.checkNoDisks(): raise gui.StayOnScreen active = self.combo.get_active_iter() @@ -130,7 +130,7 @@ class PartitionTypeWindow(InstallWindow): self.dispatch.skipStep("bootloader", skip = 0) else: if val == -2: - rc = whichToResize(self.partitions, self.diskset, self.intf) + rc = whichToResize(self.storage, self.intf) if rc != gtk.RESPONSE_OK: raise gui.StayOnScreen @@ -140,14 +140,14 @@ class PartitionTypeWindow(InstallWindow): self.dispatch.skipStep("autopartitionexecute", skip = 0) if self.xml.get_widget("encryptButton").get_active(): - self.partitions.autoEncrypt = True + self.storage.encryptedAutoPart = True else: - self.partitions.encryptionPassphrase = "" - self.partitions.retrofitPassphrase = False - self.partitions.autoEncrypt = False + self.storage.encryptionPassphrase = "" + self.storage.retrofitPassphrase = False + self.storage.encryptedAutoPart = False - self.partitions.useAutopartitioning = 1 - self.partitions.autoClearPartType = val + self.storage.doAutoPart = True + self.storage.clearPartType = val allowdrives = [] model = self.drivelist.get_model() @@ -159,7 +159,7 @@ class PartitionTypeWindow(InstallWindow): mustHaveSelectedDrive(self.intf) raise gui.StayOnScreen - self.partitions.autoClearPartDrives = allowdrives + self.storage.clearPartDisks = allowdrives # pop the boot device to be first in the drive list defiter = self.bootcombo.get_active_iter() @@ -238,8 +238,8 @@ class PartitionTypeWindow(InstallWindow): # get the initiator name if it exists and don't allow changing # once set e = dxml.get_widget("iscsiInitiatorEntry") - e.set_text(self.anaconda.id.iscsi.initiator) - if self.anaconda.id.iscsi.initiatorSet: # this is uglyyyy.... + e.set_text(self.storage.iscsi.initiator) + if self.storage.iscsi.initiatorSet: # this is uglyyyy.... e.set_sensitive(False) while 1: @@ -254,7 +254,7 @@ class PartitionTypeWindow(InstallWindow): _("You must provide an initiator name.")) continue - self.anaconda.id.iscsi.initiator = initiator + self.storage.iscsi.initiator = initiator target = dxml.get_widget("iscsiAddrEntry").get_text().strip() user = dxml.get_widget("userEntry").get_text().strip() @@ -290,8 +290,8 @@ class PartitionTypeWindow(InstallWindow): continue try: - self.anaconda.id.iscsi.addTarget(ip, port, user, pw, user_in, pw_in, - self.intf) + self.storage.iscsi.addTarget(ip, port, user, pw, + user_in, pw_in, self.intf) except ValueError, e: self.intf.messageWindow(_("Error"), str(e)) continue @@ -323,7 +323,7 @@ class PartitionTypeWindow(InstallWindow): fcplun = dxml.get_widget("fcplunEntry").get_text().strip() try: - self.anaconda.id.zfcp.addFCP(devnum, wwpn, fcplun) + self.storage.zfcp.addFCP(devnum, wwpn, fcplun) except ValueError, e: self.intf.messageWindow(_("Error"), str(e)) continue @@ -365,9 +365,9 @@ class PartitionTypeWindow(InstallWindow): if rc != gtk.RESPONSE_CANCEL: w = self.intf.waitWindow(_("Rescanning disks"), _("Rescanning disks")) - partitions.partitionObjectsInitialize(self.anaconda) - createAllowedDrivesStore(self.diskset.disks, - self.partitions.autoClearPartDrives, + self.storage.reset() + createAllowedDrivesStore(self.storage, + self.storage.clearPartDisks, self.drivelist, disallowDrives=[self.anaconda.updateSrc]) self._fillBootStore() @@ -380,14 +380,16 @@ class PartitionTypeWindow(InstallWindow): defaultBoot = self.anaconda.id.bootloader.drivelist[0] else: defaultBoot = None - for disk in self.diskset.disks.values(): - if not disk.device.path[5:] in self.anaconda.id.bootloader.drivelist: + for disk in self.storage.disks: + partedDisk = disk.partedDisk + if partedDisk.device.path[5:] not in self.anaconda.id.bootloader.drivelist: continue - size = disk.device.getSize(unit="MB") - dispstr = "%s %8.0f MB %s" %(disk.device.path[5:], size, disk.device.model) + size = partedDisk.device.getSize(unit="MB") + dispstr = "%s %8.0f MB %s" %(partedDisk.device.path[5:], + size, partedDisk.device.model) i = bootstore.append(None) - bootstore[i] = (dispstr, disk.device.path[5:]) - if disk.device.path[5:] == defaultBoot: + bootstore[i] = (dispstr, partedDisk.device.path[5:]) + if disk.name == defaultBoot: self.bootcombo.set_active_iter(i) if len(bootstore) <= 1: @@ -396,8 +398,7 @@ class PartitionTypeWindow(InstallWindow): def getScreen(self, anaconda): self.anaconda = anaconda - self.diskset = anaconda.id.diskset - self.partitions = anaconda.id.partitions + self.storage = anaconda.id.storage self.intf = anaconda.intf self.dispatch = anaconda.dispatch @@ -427,15 +428,15 @@ class PartitionTypeWindow(InstallWindow): for (txt, val) in opts: iter = store.append(None) store[iter] = (txt, val) - if val == self.partitions.autoClearPartType: + if val == self.storage.clearPartType: self.combo.set_active_iter(iter) if ((self.combo.get_active() == -1) or self.dispatch.stepInSkipList("autopartitionexecute")): self.combo.set_active(len(opts) - 1) # yeah, it's a hack - self.drivelist = createAllowedDrivesList(self.diskset.disks, - self.partitions.autoClearPartDrives, + self.drivelist = createAllowedDrivesList(self.storage.disks, + self.storage.clearPartDisks, disallowDrives=[self.anaconda.updateSrc]) self.drivelist.set_size_request(375, 80) @@ -453,7 +454,7 @@ class PartitionTypeWindow(InstallWindow): self.review = not self.dispatch.stepInSkipList("partition") self.xml.get_widget("reviewButton").set_active(self.review) - self.xml.get_widget("encryptButton").set_active(self.partitions.autoEncrypt) + self.xml.get_widget("encryptButton").set_active(self.storage.encryptedAutoPart) active = self.combo.get_active_iter() val = self.combo.get_model().get_value(active, 1) diff --git a/iw/bootloader_main_gui.py b/iw/bootloader_main_gui.py index d11a73e89..452e880e9 100644 --- a/iw/bootloader_main_gui.py +++ b/iw/bootloader_main_gui.py @@ -21,7 +21,6 @@ import gtk import gobject -import partedUtils import gui from iw_gui import * from constants import * @@ -81,7 +80,12 @@ class MainBootloaderWindow(InstallWindow): def __driveChange(combo, dxml, choices): if not choices.has_key("mbr"): return - first = combo.get_model()[combo.get_active_iter()][1] + + iter = combo.get_active_iter() + if not iter: + return + + first = combo.get_model()[iter][1] desc = choices["mbr"][1] dxml.get_widget("mbrRadio").set_label("%s - /dev/%s" %(desc, first)) dxml.get_widget("mbrRadio").set_data("bootDevice", first) @@ -93,16 +97,14 @@ class MainBootloaderWindow(InstallWindow): combo.pack_start(cell, True) combo.set_attributes(cell, text = 0) - keys = disks.keys() - keys.sort() - - for d in keys: - size = disks[d].device.getSize(unit="MB") - m = disks[d].device.model + for disk in disks: + size = disk.size + m = disk.partedDisk.device.model i = model.append(None) - model[i] = ("%s %8.0f MB %s" %(d, size, m), "%s" %(d,)) - if d == active: + model[i] = ("%s %8.0f MB %s" %(disk.name, size, m), + "%s" %(disk.name,)) + if disk == active: combo.set_active_iter(i) return model @@ -113,8 +115,7 @@ class MainBootloaderWindow(InstallWindow): dialog.set_transient_for(self.parent) dialog.show() - choices = anaconda.id.fsset.bootloaderChoices(anaconda.id.diskset, - self.bl) + choices = anaconda.platform.bootloaderChoices(self.bl) for t in ("mbr", "boot"): if not choices.has_key(t): continue @@ -136,7 +137,7 @@ class MainBootloaderWindow(InstallWindow): lbl = dxml.get_widget("bd%dLabel" %(i,)) combo.show() lbl.show() - m = __genStore(combo, anaconda.id.diskset.disks, self.driveorder[i - 1]) + m = __genStore(combo, anaconda.id.storage.disks, self.driveorder[i - 1]) dxml.get_widget("bd1Combo").connect("changed", __driveChange, dxml, choices) __driveChange(dxml.get_widget("bd1Combo"), dxml, choices) @@ -185,10 +186,10 @@ class MainBootloaderWindow(InstallWindow): self.bl = anaconda.id.bootloader self.intf = anaconda.intf - drives = anaconda.id.diskset.disks + disks = anaconda.id.storage.disks self.driveorder = self.bl.drivelist if len(self.driveorder) == 0: - self.driveorder = drives.keys() + self.driveorder = [d.name for d in disks] if self.bl.getPassword(): self.usePass = 1 @@ -206,7 +207,7 @@ class MainBootloaderWindow(InstallWindow): else: # we don't know what it is yet... if mbr is possible, we want # it, else we want the boot dev - choices = anaconda.id.fsset.bootloaderChoices(anaconda.id.diskset, self.bl) + choices = anaconda.platform.bootloaderChoices(self.bl) if choices.has_key('mbr'): self.bldev = choices['mbr'][0] else: diff --git a/iw/examine_gui.py b/iw/examine_gui.py index 63abbade2..334f3d1e4 100644 --- a/iw/examine_gui.py +++ b/iw/examine_gui.py @@ -123,15 +123,11 @@ class UpgradeExamineWindow (InstallWindow): self.upgradecombo.pack_start(cell, True) self.upgradecombo.set_attributes(cell, markup=0) - for (part, filesystem, desc, label, uuid) in self.parts: + for (dev, desc) in self.parts: iter = model.append() if (desc is None) or len(desc) < 1: desc = _("Unknown Linux system") - if part[:5] != "/dev/": - devname = "/dev/" + part - else: - devname = part - model[iter][0] = "<small>%s (%s)</small>" %(desc, devname) + model[iter][0] = "<small>%s (%s)</small>" %(desc, dev.path) upboxtmp.pack_start(self.uplabel) diff --git a/iw/lvm_dialog_gui.py b/iw/lvm_dialog_gui.py index 25c0e6dda..b3e210101 100644 --- a/iw/lvm_dialog_gui.py +++ b/iw/lvm_dialog_gui.py @@ -1,5 +1,5 @@ # -# lvm_dialog_gui.py: dialog for editting a volume group request +# lvm_dialog_gui.py: dialog for editing a volume group request # # Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. # All rights reserved. @@ -27,12 +27,10 @@ import gtk import datacombo import gui -from fsset import * -from partRequests import * from partition_ui_helpers_gui import * from constants import * -import lvm -from cryptodev import LUKSDevice +from storage.devices import * +from storage.deviceaction import * import gettext _ = lambda x: gettext.ldgettext("anaconda", x) @@ -43,23 +41,13 @@ log = logging.getLogger("anaconda") class VolumeGroupEditor: def numAvailableLVSlots(self): - return max(0, lvm.MAX_LV_SLOTS - len(self.logvolreqs)) + return max(0, lvm.MAX_LV_SLOTS - len(self.vg.lvs)) - def computeSpaceValues(self, alt_pvlist=None, usepe=None): - if usepe is None: - pesize = long(self.peCombo.get_active_value()) - else: - pesize = long(usepe) - - if alt_pvlist is None: - pvlist = self.getSelectedPhysicalVolumes(self.lvmlist.get_model()) - else: - pvlist = alt_pvlist - tspace = self.computeVGSize(pvlist, pesize) - uspace = self.computeLVSpaceNeeded(self.logvolreqs) - fspace = tspace - uspace - - return (tspace, uspace, fspace) + def computeSpaceValues(self): + vgsize = self.vg.size + vgfree = self.vg.freeSpace + vgused = vgsize - vgfree + return (vgsize, vgused, vgfree) def getPVWastedRatio(self, newpe): """ given a new pe value, return percentage of smallest PV wasted @@ -69,10 +57,8 @@ class VolumeGroupEditor: pvlist = self.getSelectedPhysicalVolumes(self.lvmlist.get_model()) waste = 0.0 - for id in pvlist: - pvreq = self.partitions.getRequestByID(id) - pvsize = pvreq.getActualSize(self.partitions, self.diskset) - waste = max(waste, (long(pvsize*1024) % newpe)/(pvsize*1024.0)) + for pv in pvlist: + waste = max(waste, (long(pv.size*1024) % newpe)/(pv.size*1024.0)) return waste @@ -81,14 +67,14 @@ class VolumeGroupEditor: """ first = 1 pvlist = self.getSelectedPhysicalVolumes(self.lvmlist.get_model()) - for id in pvlist: + for pv in pvlist: try: pesize = int(self.peCombo.get_active_value()) except: - pesize = 32768 - pvreq = self.partitions.getRequestByID(id) - pvsize = pvreq.getActualSize(self.partitions, self.diskset) - pvsize = lvm.clampPVSize(pvsize, pesize) - int(pesize/1024) + pesize = self.vg.peSize + + # FIXME: move this logic into a property of LVMVolumeGroupDevice + pvsize = lvm.clampPVSize(pv.size, pesize) - int(pesize/1024) if first: minpvsize = pvsize first = 0 @@ -111,10 +97,10 @@ class VolumeGroupEditor: oldused = 0 used = 0 resize = 0 - for lv in self.logvolreqs: - osize = lv.getActualSize(self.partitions, self.diskset, True) + for lv in self.vg.lvs: + osize = lv.size oldused = oldused + osize - nsize = lvm.clampLVSizeRequest(osize, newpe, roundup=1) + nsize = lvm.clampSize(osize, newpe, roundup=1) if nsize != osize: resize = 1 @@ -144,11 +130,13 @@ class VolumeGroupEditor: custom_buttons=["gtk-cancel", _("C_ontinue")]) if not rc: return 0 - - for lv in self.logvolreqs: - osize = lv.getActualSize(self.partitions, self.diskset, True) - nsize = lvm.clampLVSizeRequest(osize, newpe, roundup=1) - lv.setSize(nsize) + + # XXX this is very sneaky, just changing the lvs' size attributes. + # will we suffer for it? almost certainly. + for lv in self.vg.lvs: + osize = lv.size + nsize = lvm.clampSize(osize, newpe, roundup=1) + lv.size = nsize return 1 @@ -161,24 +149,26 @@ class VolumeGroupEditor: """ curval = int(widget.get_active_value()) + # this one's in MB so we can stop with all this dividing by 1024 + curpe = curval / 1024.0 lastval = widget.get_data("lastpe") lastidx = widget.get_data("lastidx") # see if PE is too large compared to smallest PV - # remember PE is in KB, PV size is in MB maxpvsize = self.getSmallestPVSize() - if curval > maxpvsize * 1024: + if curpe > maxpvsize: self.intf.messageWindow(_("Not enough space"), _("The physical extent size cannot be " "changed because the value selected " "(%10.2f MB) is larger than the smallest " "physical volume (%10.2f MB) in the " - "volume group.") % (curval/1024.0, maxpvsize), custom_icon="error") + "volume group.") % (curpe, maxpvsize), + custom_icon="error") widget.set_active(lastidx) return 0 # see if new PE will make any PV useless due to overhead - if lvm.clampPVSize(maxpvsize, curval) * 1024 < curval: + if lvm.clampPVSize(maxpvsize, curpe) < curpe: self.intf.messageWindow(_("Not enough space"), _("The physical extent size cannot be " "changed because the value selected " @@ -186,14 +176,14 @@ class VolumeGroupEditor: "to the size of the " "smallest physical volume " "(%10.2f MB) in the " - "volume group.") % (curval/1024.0, + "volume group.") % (curpe, maxpvsize), custom_icon="error") widget.set_active(lastidx) return 0 - if self.getPVWastedRatio(curval) > 0.10: + if self.getPVWastedRatio(curpe) > 0.10: rc = self.intf.messageWindow(_("Too small"), _("This change in the value of the " "physical extent will waste " @@ -215,10 +205,9 @@ class VolumeGroupEditor: else: self.updateLogVolStore() else: - maxlv = lvm.getMaxLVSize(curval) - for lv in self.logvolreqs: - lvsize = lv.getActualSize(self.partitions, self.diskset, True) - if lvsize > maxlv: + maxlv = lvm.getMaxLVSize() + for lv in self.vg.lvs: + if lv.size > maxlv: self.intf.messageWindow(_("Not enough space"), _("The physical extent size " "cannot be changed because the " @@ -234,12 +223,15 @@ class VolumeGroupEditor: widget.set_data("lastpe", curval) widget.set_data("lastidx", widget.get_active()) + + # now actually set the VG's extent size + self.vg.peSize = curpe self.updateAllowedLvmPartitionsList(self.availlvmparts, - self.partitions, self.lvmlist) self.updateVGSpaceLabels() def prettyFormatPESize(self, val): + """ Pretty print for PE size in KB """ if val < 1024: return "%s KB" % (val,) elif val < 1024*1024: @@ -285,28 +277,31 @@ class VolumeGroupEditor: # changes the toggle state val = not model.get_value(iter, 0) partname = model.get_value(iter, 1) - id = self.partitions.getRequestByDeviceName(partname).uniqueID + pv = self.storage.devicetree.getDeviceByName(partname) if val: - pvlist.append(id) + pvlist.append(pv) else: - pvlist.remove(id) - - (availSpaceMB, neededSpaceMB, fspace) = self.computeSpaceValues(alt_pvlist=pvlist) - if availSpaceMB < neededSpaceMB: - self.intf.messageWindow(_("Not enough space"), - _("You cannot remove this physical " - "volume because otherwise the " - "volume group will be too small to " - "hold the currently defined logical " - "volumes."), custom_icon="error") - return False - - self.updateVGSpaceLabels(alt_pvlist = pvlist) + pvlist.remove(pv) + + if val: + self.vg._addPV(pv) + else: + try: + self.vg._removePV(pv) + except DeviceError as e: + self.intf.messageWindow(_("Not enough space"), + _("You cannot remove this physical " + "volume because otherwise the " + "volume group will be too small to " + "hold the currently defined logical " + "volumes."), custom_icon="error") + return False + + self.updateVGSpaceLabels() return True - def createAllowedLvmPartitionsList(self, alllvmparts, reqlvmpart, partitions, preexist = 0): - + def createAllowedLvmPartitionsList(self, alllvmparts, vgs): store = gtk.TreeStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_STRING) @@ -317,49 +312,52 @@ class VolumeGroupEditor: sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) sw.set_shadow_type(gtk.SHADOW_IN) - for part in alllvmparts: - uid = part[0] - request = partitions.getRequestByID(uid) - - if request.type != REQUEST_RAID: - partname = "%s" % (request.device,) - else: - partname = "md%d" % (request.raidminor,) + for device in alllvmparts: + # clip size to current PE + pesize = int(self.peCombo.get_active_value()) / 1024.0 + size = lvm.clampSize(device.size, pesize) + size_string = "%10.2f MB" % size + include = True + selected = False + + # now see if the pv is in use either by a vg in the tree or by + # the vg we are editing now + if device in self.vg.pvs: + selected = True + include = True + else: + for vg in vgs: + if vg.name == self.vg.name: + continue - size = request.getActualSize (partitions, self.diskset) - used = part[2] + if device in vg.pvs: + include = False + break - # clip size to current PE - pesize = int(self.peCombo.get_active_value()) - size = lvm.clampPVSize(size, pesize) - partsize = "%10.2f MB" % size - if used or not reqlvmpart: - selected = 1 - else: - selected = 0 + if include and not self.vg.pvs: + selected = True - if preexist == 0 or selected == 1: - partlist.append_row((partname, partsize), selected) + if include: + partlist.append_row((device.name, size_string), selected) + if selected: + self.vg._addPV(device) return (partlist, sw) - def updateAllowedLvmPartitionsList(self, alllvmparts, partitions, partlist): + def updateAllowedLvmPartitionsList(self, alllvmparts, partlist): """ update sizes in pv list alllvmparts - list of pv from partitions.getAvailLVMPartitions - partitions - object holding all partition requests partlist - the checklist containing pv list """ row = 0 for part in alllvmparts: - uid = part[0] - request = partitions.getRequestByID(uid) - size = request.getActualSize(partitions, self.diskset) + size = part.size # clip size to current PE - pesize = int(self.peCombo.get_active_value()) - size = lvm.clampPVSize(size, pesize) + pesize = int(self.peCombo.get_active_value()) / 1024.0 + size = lvm.clampSize(size, pesize) partsize = "%10.2f MB" % size iter = partlist.store.get_iter((int(row),)) @@ -371,14 +369,16 @@ class VolumeGroupEditor: (model, iter) = selection.get_selected() return iter + def editLogicalVolume(self, lv, isNew = 0): + if not lv: + return - def editLogicalVolume(self, logrequest, isNew = 0): if isNew: tstr = _("Make Logical Volume") else: try: - tstr = _("Edit Logical Volume: %s") % (logrequest.logicalVolumeName,) - except: + tstr = _("Edit Logical Volume: %s") % (lv.name,) + except AttributeError: tstr = _("Edit Logical Volume") dialog = gtk.Dialog(tstr, self.parent) @@ -392,17 +392,24 @@ class VolumeGroupEditor: maintable.set_col_spacings(5) row = 0 + if lv.format.type == "luks": + usedev = self.findLUKSDev(lv) + format = usedev.format + elif lv: + usedev = lv + format = lv.format + lbl = createAlignedLabel(_("_Mount Point:")) maintable.attach(lbl, 0, 1, row,row+1) - mountCombo = createMountPointCombo(logrequest, excludeMountPoints=["/boot"]) + mountCombo = createMountPointCombo(usedev, excludeMountPoints=["/boot"]) lbl.set_mnemonic_widget(mountCombo) maintable.attach(mountCombo, 1, 2, row, row + 1) row += 1 - if not logrequest or not logrequest.getPreExisting(): + if not format.exists: lbl = createAlignedLabel(_("_File System Type:")) maintable.attach(lbl, 0, 1, row, row + 1) - newfstypeCombo = createFSTypeMenu(logrequest.fstype, + newfstypeCombo = createFSTypeMenu(format, fstypechangeCB, mountCombo, ignorefs = ["software RAID", "physical volume (LVM)", "vfat", "efi", "PPC PReP Boot", "Apple Bootstrap"]) @@ -412,77 +419,65 @@ class VolumeGroupEditor: else: maintable.attach(createAlignedLabel(_("Original File System Type:")), 0, 1, row, row + 1) - if logrequest.origfstype and logrequest.origfstype.getName(): - newfstypeCombo = gtk.Label(logrequest.origfstype.getName()) + if format.type: + newfstypeCombo = gtk.Label(format.name) else: newfstypeCombo = gtk.Label(_("Unknown")) maintable.attach(newfstypeCombo, 1, 2, row, row + 1) row += 1 - if logrequest.fslabel: + if getattr(format, "label", None): maintable.attach(createAlignedLabel(_("Original File System " "Label:")), 0, 1, row, row + 1) - maintable.attach(gtk.Label(logrequest.fslabel), 1, 2, row, - row + 1) + maintable.attach(gtk.Label(format.label), + 1, 2, row, row + 1) row += 1 - - if not logrequest or not logrequest.getPreExisting(): + if not lv.exists: lbl = createAlignedLabel(_("_Logical Volume Name:")) lvnameEntry = gtk.Entry(32) lbl.set_mnemonic_widget(lvnameEntry) - if logrequest and logrequest.logicalVolumeName: - lvnameEntry.set_text(logrequest.logicalVolumeName) + if lv and lv.lvname: + lvnameEntry.set_text(lv.lvname) else: - lvnameEntry.set_text(lvm.createSuggestedLVName(self.logvolreqs)) + lvnameEntry.set_text(storage.createSuggestedLVName(self.vg)) else: lbl = createAlignedLabel(_("Logical Volume Name:")) - lvnameEntry = gtk.Label(logrequest.logicalVolumeName) + lvnameEntry = gtk.Label(lv.lvname) maintable.attach(lbl, 0, 1, row, row + 1) maintable.attach(lvnameEntry, 1, 2, row, row + 1) row += 1 - if not logrequest or not logrequest.getPreExisting(): + if not lv.exists: lbl = createAlignedLabel(_("_Size (MB):")) sizeEntry = gtk.Entry(16) lbl.set_mnemonic_widget(sizeEntry) - if logrequest: - sizeEntry.set_text("%Ld" % (logrequest.getActualSize(self.partitions, self.diskset, True),)) + sizeEntry.set_text("%Ld" % lv.size) else: lbl = createAlignedLabel(_("Size (MB):")) - sizeEntry = gtk.Label(str(logrequest.size)) + sizeEntry = gtk.Label(str(lv.size)) maintable.attach(lbl, 0, 1, row, row+1) maintable.attach(sizeEntry, 1, 2, row, row + 1) row += 1 - if not logrequest or not logrequest.getPreExisting(): - pesize = int(self.peCombo.get_active_value()) - (tspace, uspace, fspace) = self.computeSpaceValues(usepe=pesize) - maxlv = min(lvm.getMaxLVSize(pesize), fspace) - - # add in size of current logical volume if it has a size - if logrequest and not isNew: - maxlv = maxlv + logrequest.getActualSize(self.partitions, self.diskset) + if not lv.exists: + maxlv = min(lvm.getMaxLVSize(), lv.size) maxlabel = createAlignedLabel(_("(Max size is %s MB)") % (maxlv,)) maintable.attach(maxlabel, 1, 2, row, row + 1) self.fsoptionsDict = {} - if logrequest.getPreExisting(): - (row, self.fsoptionsDict) = createPreExistFSOptionSection(logrequest, maintable, row, mountCombo, self.partitions, ignorefs = ["software RAID", "physical volume (LVM)", "vfat"]) + if lv.exists: + (row, self.fsoptionsDict) = createPreExistFSOptionSection(usedev, maintable, row, mountCombo, self.storage, ignorefs = ["software RAID", "physical volume (LVM)", "vfat"]) # checkbutton for encryption using dm-crypt/LUKS - if not logrequest.getPreExisting(): + if not lv.exists: self.lukscb = gtk.CheckButton(_("_Encrypt")) - if logrequest.format or logrequest.type == REQUEST_NEW: - self.lukscb.set_data("formatstate", 1) - else: - self.lukscb.set_data("formatstate", 0) - - if logrequest.encryption: + self.lukscb.set_data("formatstate", 1) + if lv.format.type == "luks": self.lukscb.set_active(1) else: self.lukscb.set_active(0) @@ -500,79 +495,76 @@ class VolumeGroupEditor: dialog.destroy() return - if not logrequest or not logrequest.getPreExisting(): - fsystem = newfstypeCombo.get_active_value() - format = 1 - migrate = 0 - targetSize = None - else: - if self.fsoptionsDict.has_key("formatcb"): - format = self.fsoptionsDict["formatcb"].get_active() - if format: - fsystem = self.fsoptionsDict["fstypeCombo"].get_active_value() - else: - format = 0 + actions = [] + luksdev = None + targetSize = None + migrate = None + format = None - if self.fsoptionsDict.has_key("migratecb"): - migrate = self.fsoptionsDict["migratecb"].get_active() - if migrate: - fsystem = self.fsoptionsDict["migfstypeCombo"].get_active_value() - else: - migrate = 0 + if lv.format.type == "luks": + usedev = self.findLUKSDev(lv) + format = usedev.format + else: + usedev = lv + format = lv.format - if self.fsoptionsDict.has_key("resizecb") and self.fsoptionsDict["resizecb"].get_active(): - targetSize = self.fsoptionsDict["resizesb"].get_value_as_int() - else: - targetSize = None + if not lv.exists: + fmt_class = newfstypeCombo.get_active_value() + else: + # existing lv + fmt_class = self.fsoptionsDict["fstypeCombo"].get_active_value() - # set back if we are not formatting or migrating - origfstype = logrequest.origfstype - if not format and not migrate: - fsystem = origfstype + mountpoint = mountCombo.get_children()[0].get_text().strip() - mntpt = string.strip(mountCombo.get_children()[0].get_text()) + # validate logical volume name + lvname = lvnameEntry.get_text().strip() + if not lv.exists: + err = sanityCheckLogicalVolumeName(lvname) + if err: + self.intf.messageWindow(_("Illegal Logical Volume Name"), + err, custom_icon="error") + continue - if not logrequest or not logrequest.getPreExisting(): - # check size specification - badsize = 0 - try: - size = long(sizeEntry.get_text()) - except: - badsize = 1 + # check that the name is not already in use + used = 0 + for _lv in self.vg.lvs: + if lvname and lv.lvname == lvname: + continue - if badsize or size <= 0: - self.intf.messageWindow(_("Illegal size"), - _("The requested size as entered is " - "not a valid number greater " - "than 0."), custom_icon="error") - continue - else: - size = logrequest.size + if lv.lvname == lvname: + used = 1 + break - # is this an existing logical volume or one we're editting - if logrequest: - preexist = logrequest.getPreExisting() - else: - preexist = 0 + if used: + self.intf.messageWindow(_("Illegal logical volume name"), + _("The logical volume name \"%s\" is " + "already in use. Please pick " + "another.") % (lvname,), custom_icon="error") + continue # test mount point # check in pending logical volume requests # these may not have been put in master list of requests # yet if we have not hit 'OK' for the volume group creation - if fsystem.isMountable(): + if fmt_class().mountable and mountpoint: used = 0 - if logrequest: - curmntpt = logrequest.mountpoint - else: - curmntpt = None + curmntpt = format.mountpoint - for lv in self.logvolreqs: - if curmntpt and lv.mountpoint == curmntpt: + for _lv in self.vg.lvs: + if _lv.format.type == "luks": + # XXX this won't work if the lvs haven't been + # added to the tree yet + _usedev = self.tree.getChildren(_lv)[0] + _format = _usedev.format + else: + _usedev = _lv + _format = _lv.format + + if not _format.mountable or curmntpt and \ + _format.mountpoint == curmntpt: continue - if len(mntpt) == 0: - continue - if lv.mountpoint == mntpt: + if _format.mountpoint == mountpoint: used = 1 break @@ -580,48 +572,31 @@ class VolumeGroupEditor: self.intf.messageWindow(_("Mount point in use"), _("The mount point \"%s\" is in " "use. Please pick another.") % - (mntpt,), custom_icon="error") + (mountpoint,), + custom_icon="error") continue - # check out logical volumne name - lvname = string.strip(lvnameEntry.get_text()) + # check that size specification is numeric and positive + if not lv.exists: + badsize = 0 + try: + size = long(sizeEntry.get_text()) + except: + badsize = 1 - if not logrequest or not logrequest.getPreExisting(): - err = sanityCheckLogicalVolumeName(lvname) - if err: - self.intf.messageWindow(_("Illegal Logical Volume Name"),err, custom_icon="error") + if badsize or size <= 0: + self.intf.messageWindow(_("Illegal size"), + _("The requested size as entered is " + "not a valid number greater " + "than 0."), custom_icon="error") continue + else: + size = lv.size - # is it in use? - used = 0 - if logrequest: - origlvname = logrequest.logicalVolumeName - else: - origlvname = None - - for lv in self.logvolreqs: - if origlvname and lv.logicalVolumeName == origlvname: - continue - - if lv.logicalVolumeName == lvname: - used = 1 - break - - if used: - self.intf.messageWindow(_("Illegal logical volume name"), - _("The logical volume name \"%s\" is " - "already in use. Please pick " - "another.") % (lvname,), custom_icon="error") - continue - - # create potential request - request = copy.copy(logrequest) - request.encryption = copy.deepcopy(logrequest.encryption) - pesize = int(self.peCombo.get_active_value()) - size = lvm.clampLVSizeRequest(size, pesize, roundup=1) - - # do some final tests - maxlv = lvm.getMaxLVSize(pesize) + # check that size specification is within limits + pesize = int(self.peCombo.get_active_value()) / 1024.0 + size = lvm.clampSize(size, pesize, roundup=True) + maxlv = lvm.getMaxLVSize() if size > maxlv: self.intf.messageWindow(_("Not enough space"), _("The current requested size " @@ -635,107 +610,98 @@ class VolumeGroupEditor: custom_icon="error") continue - request.fstype = fsystem - - if request.fstype.isMountable(): - request.mountpoint = mntpt - else: - request.mountpoint = None - - request.preexist = preexist - request.logicalVolumeName = lvname - request.size = size - request.format = format - request.migrate = migrate - request.targetSize = targetSize - request.grow = 0 - - # this is needed to clear out any cached info about the device - # only a workaround - need to change way this is handled in - # partRequest.py really. - request.dev = None - - if self.lukscb and self.lukscb.get_active(): - if not request.encryption: - request.encryption = LUKSDevice(passphrase=self.partitions.encryptionPassphrase, format=1) + # Ok -- now we've done all the checks to validate the + # user-specified parameters. Time to set up the device... + if not lv.exists: + lv._name = lvname + lv.size = size + lv.req_grow = False + format = fmt_class(mountpoint=mountpoint) + if self.lukscb and self.lukscb.get_active() and \ + lv.format.type != "luks": + luksformat = format + format = getFormat("luks", + passphrase=self.storage.encryptionPassphrase) + luksdev = LUKSDevice("luks-%s" % lv.name, + format=luksformat, + parents=lv) + elif self.lukscb and not self.lukscb.get_active() and \ + lv.format.type == "luks": + # destroy luks format and mapped device + luksdev = self.findLUKSDev(lv) + if luksdev: + actions.append(ActionDestroyFormat(luksdev.format)) + actions.append(ActionDestroyDevice(luksdev)) + luksdev = None + actions.append(ActionDestroyFormat(lv)) + + if lv.lvname not in self.lvs: + actions.append(ActionCreateDevice(lv)) + actions.append(ActionCreateFormat(lv)) + self.lvs[lv.lvname] = lv + + if luksdev: + actions.append(ActionCreateDevice(luksdev)) + actions.append(ActionCreateFormat(luksdev)) else: - request.encryption = None - - # make list of original logvol requests so we can skip them - # in tests below. We check for mount point name conflicts - # above within the current volume group, so it is not - # necessary to do now. - err = request.sanityCheckRequest(self.partitions, skipMntPtExistCheck=1, pesize=pesize) - if err is None: - skiplist = [] - for lv in self.origvolreqs: - skiplist.append(lv.uniqueID) - - err = request.isMountPointInUse(self.partitions, requestSkipList=skiplist) - - if err: - self.intf.messageWindow(_("Error With Request"), - "%s" % (err), custom_icon="error") - continue + # existing lv + if self.fsoptionsDict.has_key("formatcb") and \ + self.fsoptionsDict["formatcb"].get_active(): + format = fmt_class(mountpoint=mountpoint) + if self.lukscb and self.lukscb.get_active() and \ + lv.format.type != "luks": + luksformat = format + format = getFormat("luks", + device=lv.path, + passphrase=self.storage.encryptionPassphrase) + luksdev = LUKSDevice("luks-%s" % lv.name, + format=luksformat, + parents=lv) + elif self.lukscb and not self.lukscb.get_active() and \ + lv.format.type == "luks": + # destroy luks format and mapped device + luksdev = self.findLUKSDev(lv) + if luksdev: + actions.append(ActionDestroyFormat(luksdev.format)) + actions.append(ActionDestroyDevice(luksdev)) + luksdev = None + actions.append(ActionDestroyFormat(lv)) + elif lv.format.mountable: + lv.format.mountpoint = mountpoint + + if self.fsoptionsDict.has_key("migratecb") and \ + self.fsoptionsDict["migratecb"].get_active(): + migrate = True - if (not request.format and - request.mountpoint and request.formatByDefault()): - if not queryNoFormatPreExisting(self.intf): - continue + if self.fsoptionsDict.has_key("resizecb") and self.fsoptionsDict["resizecb"].get_active(): + targetSize = self.fsoptionsDict["resizesb"].get_value_as_int() + actions.append(ActionResizeDevice(lv, targetSize)) + if lv.format.type: + actions.append(ActionResizeFormat(lv, targetSize)) - # see if there is room for request - (availSpaceMB, neededSpaceMB, fspace) = self.computeSpaceValues(usepe=pesize) - tmplogreqs = [] - for l in self.logvolreqs: - if origlvname and l.logicalVolumeName == origlvname: - continue - - tmplogreqs.append(l) + if format: + actions.append(ActionDestroyFormat(usedev)) + actions.append(ActionCreateFormat(usedev, format)) + if luksdev: + actions.append(ActionCreateDevice(luksdev)) - tmplogreqs.append(request) - neededSpaceMB = self.computeLVSpaceNeeded(tmplogreqs) + if migrate: + actions.append(ActionMigrateFormat(usedev)) - if neededSpaceMB > availSpaceMB: - self.intf.messageWindow(_("Not enough space"), - _("The logical volumes you have " - "configured require %d MB, but the " - "volume group only has %d MB. Please " - "either make the volume group larger " - "or make the logical volume(s) smaller.") % (neededSpaceMB, availSpaceMB), custom_icon="error") - del tmplogreqs - continue + if usedev.format.exists and format.mountable and \ + self.storage.formatByDefault(usedev) and \ + not queryNoFormatPreExisting(self.intf): + continue # everything ok break - # now remove the previous request, insert request created above - if not isNew: - self.logvolreqs.remove(logrequest) - iter = self.getCurrentLogicalVolume() - self.logvolstore.remove(iter) - if request.targetSize is not None: - size = request.targetSize - # adjust the free space in the vg - if logrequest.targetSize is not None: - diff = request.targetSize - logrequest.targetSize - else: - diff = request.targetSize - request.size - self.origvgrequest.free -= diff - - self.logvolreqs.append(request) - - iter = self.logvolstore.append() - self.logvolstore.set_value(iter, 0, lvname) - if request.fstype and request.fstype.isMountable(): - self.logvolstore.set_value(iter, 1, mntpt) - else: - self.logvolstore.set_value(iter, 1, "N/A") - - self.logvolstore.set_value(iter, 2, "%Ld" % (size,)) - + self.actions.extend(actions) + self.updateLogVolStore() self.updateVGSpaceLabels() dialog.destroy() + return def editCurrentLogicalVolume(self): iter = self.getCurrentLogicalVolume() @@ -744,15 +710,8 @@ class VolumeGroupEditor: return logvolname = self.logvolstore.get_value(iter, 0) - logrequest = None - for lv in self.logvolreqs: - if lv.logicalVolumeName == logvolname: - logrequest = lv - - if logrequest is None: - return - - self.editLogicalVolume(logrequest) + lv = self.lvs[logvolname] + self.editLogicalVolume(lv) def addLogicalVolumeCB(self, widget): if self.numAvailableLVSlots() < 1: @@ -761,8 +720,8 @@ class VolumeGroupEditor: "volumes per volume group.") % (lvm.MAX_LV_SLOTS,), custom_icon="error") return - (tspace, uspace, fspace) = self.computeSpaceValues() - if fspace <= 0: + (total, used, free) = self.computeSpaceValues() + if free <= 0: self.intf.messageWindow(_("No free space"), _("There is no room left in the " "volume group to create new logical " @@ -773,9 +732,10 @@ class VolumeGroupEditor: "logical volumes"), custom_icon="error") return - request = LogicalVolumeRequestSpec(fileSystemTypeGetDefault(), - size = fspace) - self.editLogicalVolume(request, isNew = 1) + lv = self.storage.newLV(vg=self.vg, + fmt_type=self.storage.defaultFSType, + size=free) + self.editLogicalVolume(lv, isNew = 1) return def editLogicalVolumeCB(self, widget): @@ -798,12 +758,10 @@ class VolumeGroupEditor: if not rc: return - for lv in self.logvolreqs: - if lv.logicalVolumeName == logvolname: - self.logvolreqs.remove(lv) - + lv = self.lvs[logvolname] + action = ActionDestroyDevice(lv) + self.actions.append(action) self.logvolstore.remove(iter) - self.updateVGSpaceLabels() return @@ -820,9 +778,8 @@ class VolumeGroupEditor: partname = model.get_value(iter, 1) if val: - pvreq = self.partitions.getRequestByDeviceName(partname) - id = pvreq.uniqueID - pv.append(id) + dev = self.storage.devicetree.getDeviceByName(partname) + pv.append(dev) next = model.iter_next(iter) currow = currow + 1 @@ -831,10 +788,9 @@ class VolumeGroupEditor: def computeVGSize(self, pvlist, curpe): availSpaceMB = 0L - for id in pvlist: - pvreq = self.partitions.getRequestByID(id) - pvsize = pvreq.getActualSize(self.partitions, self.diskset) - pvsize = lvm.clampPVSize(pvsize, curpe) - (curpe/1024) + for pv in pvlist: + # XXX why the subtraction? + pvsize = lvm.clampSize(pv.size, curpe) - (curpe/1024) # have to clamp pvsize to multiple of PE availSpaceMB = availSpaceMB + pvsize @@ -845,51 +801,61 @@ class VolumeGroupEditor: def computeLVSpaceNeeded(self, logreqs): neededSpaceMB = 0 for lv in logreqs: - neededSpaceMB = neededSpaceMB + lv.getActualSize(self.partitions, self.diskset, True) + neededSpaceMB = neededSpaceMB + lv.size return neededSpaceMB + def findLUKSDev(self, lv): + if lv.format.type == "luks": + actions = self.actions[:] + actions.reverse() + usedev = None + for action in actions: + if action.isCreate() and action.isDevice() and \ + action.device.parents == [lv]: + usedev = action.device + break + if not usedev: + usedev = self.storage.devicetree.getChildren(lv)[0] + + return usedev + def updateLogVolStore(self): self.logvolstore.clear() - for lv in self.logvolreqs: + for lv in self.vg.lvs: iter = self.logvolstore.append() - size = lv.getActualSize(self.partitions, self.diskset, True) - lvname = lv.logicalVolumeName - mntpt = lv.mountpoint - if lvname: - self.logvolstore.set_value(iter, 0, lvname) + if lv.format.type == "luks": + usedev = self.findLUKSDev(lv) + else: + usedev = lv + + mntpt = getattr(usedev.format, "mountpoint", "") + if lv.lvname: + self.logvolstore.set_value(iter, 0, lv.lvname) - if lv.fstype and lv.fstype.isMountable(): - if mntpt: - self.logvolstore.set_value(iter, 1, mntpt) - else: - self.logvolstore.set_value(iter, 1, "") + if usedev.format.type and usedev.format.mountable: + self.logvolstore.set_value(iter, 1, mntpt) else: self.logvolstore.set_value(iter, 1, "N/A") - self.logvolstore.set_value(iter, 2, "%Ld" % (size,)) + self.logvolstore.set_value(iter, 2, "%Ld" % (lv.size,)) - def updateVGSpaceLabels(self, alt_pvlist=None): - if alt_pvlist == None: - pvlist = self.getSelectedPhysicalVolumes(self.lvmlist.get_model()) - else: - pvlist = alt_pvlist - - (tspace, uspace, fspace) = self.computeSpaceValues(alt_pvlist=pvlist) + def updateVGSpaceLabels(self): + (total, used, free) = self.computeSpaceValues() - self.totalSpaceLabel.set_text("%10.2f MB" % (tspace,)) - self.usedSpaceLabel.set_text("%10.2f MB" % (uspace,)) + self.totalSpaceLabel.set_text("%10.2f MB" % (total,)) + self.usedSpaceLabel.set_text("%10.2f MB" % (used,)) - if tspace > 0: - usedpercent = (100.0*uspace)/tspace + if total > 0: + usedpercent = (100.0*used)/total else: usedpercent = 0.0 self.usedPercentLabel.set_text("(%4.1f %%)" % (usedpercent,)) - self.freeSpaceLabel.set_text("%10.2f MB" % (fspace,)) - if tspace > 0: - freepercent = (100.0*fspace)/tspace + self.freeSpaceLabel.set_text("%10.2f MB" % (free,)) + if total > 0: + freepercent = (100.0*free)/total else: freepercent = 0.0 @@ -900,44 +866,33 @@ class VolumeGroupEditor: # def run(self): if self.dialog is None: - return None + return [] while 1: rc = self.dialog.run() if rc == 2: self.destroy() - return None + return [] pvlist = self.getSelectedPhysicalVolumes(self.lvmlist.get_model()) - pesize = int(self.peCombo.get_active_value()) - availSpaceMB = self.computeVGSize(pvlist, pesize) - neededSpaceMB = self.computeLVSpaceNeeded(self.logvolreqs) - - if neededSpaceMB > availSpaceMB: - self.intf.messageWindow(_("Not enough space"), - _("The logical volumes you have " - "configured require %d MB, but the " - "volume group only has %d MB. Please " - "either make the volume group larger " - "or make the logical volume(s) smaller.") % (neededSpaceMB, availSpaceMB), custom_icon="error") - continue # check volume name - volname = string.strip(self.volnameEntry.get_text()) + volname = self.volnameEntry.get_text().strip() err = sanityCheckVolumeGroupName(volname) if err: self.intf.messageWindow(_("Invalid Volume Group Name"), err, custom_icon="error") continue - if self.origvgrequest: - origvname = self.origvgrequest.volumeGroupName + if self.vg: + origvname = self.vg.name else: origname = None if origvname != volname: - if self.partitions.isVolumeGroupNameInUse(volname): + # maybe we should see if _any_ device has this name + if volname in [vg.name for vg in self.storage.vgs]: self.intf.messageWindow(_("Name in use"), _("The volume group name \"%s\" is " "already in use. Please pick " @@ -946,39 +901,36 @@ class VolumeGroupEditor: continue # get physical extent - pesize = int(self.peCombo.get_active_value()) + pesize = int(self.peCombo.get_active_value()) / 1024.0 # everything ok break - request = VolumeGroupRequestSpec(physvols = pvlist, vgname = volname, - pesize = pesize) - - # if it was preexisting, it still should be - if self.origvgrequest and self.origvgrequest.getPreExisting(): - request.preexist = 1 - elif self.origvgrequest: - request.format = self.origvgrequest.format - - return (request, self.logvolreqs) + # pvs, pesize are taken care of in widget callbacks + # (clickCB, peChangeCB) + self.vg.name = volname + if self.isNew: + self.actions.insert(0, ActionCreateDevice(self.vg)) + return self.actions def destroy(self): if self.dialog: self.dialog.destroy() self.dialog = None - def __init__(self, anaconda, partitions, diskset, intf, parent, origvgrequest, isNew = 0): - self.partitions = partitions - self.diskset = diskset - self.origvgrequest = origvgrequest + def __init__(self, anaconda, intf, parent, vg, isNew = 0): + self.storage = anaconda.id.storage + self.vg = vg + self.lvs = {} self.isNew = isNew self.intf = intf self.parent = parent + self.actions = [] + + for lv in self.vg.lvs: + self.lvs[lv.lvname] = lv - self.availlvmparts = self.partitions.getAvailLVMPartitions(self.origvgrequest, - self.diskset) - self.logvolreqs = self.partitions.getLVMLVForVG(self.origvgrequest) - self.origvolreqs = copy.copy(self.logvolreqs) + self.availlvmparts = self.storage.unusedPVs(vg=vg) # if no PV exist, raise an error message and return if len(self.availlvmparts) < 1: @@ -997,8 +949,8 @@ class VolumeGroupEditor: tstr = _("Make LVM Volume Group") else: try: - tstr = _("Edit LVM Volume Group: %s") % (origvgrequest.volumeGroupName,) - except: + tstr = _("Edit LVM Volume Group: %s") % (vg.name,) + except AttributeError: tstr = _("Edit LVM Volume Group") dialog = gtk.Dialog(tstr, self.parent) @@ -1014,17 +966,17 @@ class VolumeGroupEditor: row = 0 # volume group name - if not origvgrequest.getPreExisting(): + if not vg.exists: lbl = createAlignedLabel(_("_Volume Group Name:")) self.volnameEntry = gtk.Entry(16) lbl.set_mnemonic_widget(self.volnameEntry) if not self.isNew: - self.volnameEntry.set_text(self.origvgrequest.volumeGroupName) + self.volnameEntry.set_text(self.vg.name) else: - self.volnameEntry.set_text(lvm.createSuggestedVGName(self.partitions, anaconda.id.network)) + self.volnameEntry.set_text(self.storage.createSuggestedVGName(anaconda.id.network)) else: lbl = createAlignedLabel(_("Volume Group Name:")) - self.volnameEntry = gtk.Label(self.origvgrequest.volumeGroupName) + self.volnameEntry = gtk.Label(self.vg.name) maintable.attach(lbl, 0, 1, row, row + 1, gtk.EXPAND|gtk.FILL, gtk.SHRINK) @@ -1032,9 +984,9 @@ class VolumeGroupEditor: row = row + 1 lbl = createAlignedLabel(_("_Physical Extent:")) - self.peCombo = self.createPEOptionMenu(self.origvgrequest.pesize) + self.peCombo = self.createPEOptionMenu(self.vg.peSize * 1024) lbl.set_mnemonic_widget(self.peCombo) - if origvgrequest.getPreExisting(): + if vg.exists: self.peCombo.set_sensitive(False) maintable.attach(lbl, 0, 1, row, row + 1, @@ -1042,8 +994,8 @@ class VolumeGroupEditor: maintable.attach(self.peCombo, 1, 2, row, row + 1, gtk.EXPAND|gtk.FILL, gtk.SHRINK) row = row + 1 - (self.lvmlist, sw) = self.createAllowedLvmPartitionsList(self.availlvmparts, self.origvgrequest.physicalVolumes, self.partitions, origvgrequest.getPreExisting()) - if origvgrequest.getPreExisting(): + (self.lvmlist, sw) = self.createAllowedLvmPartitionsList(self.availlvmparts, self.storage.vgs) + if vg.exists: self.lvmlist.set_sensitive(False) self.lvmlist.set_size_request(275, 80) lbl = createAlignedLabel(_("Physical Volumes to _Use:")) @@ -1105,15 +1057,23 @@ class VolumeGroupEditor: gobject.TYPE_STRING, gobject.TYPE_STRING) - if self.logvolreqs: - for lvrequest in self.logvolreqs: + if self.vg.lvs: + for lv in self.vg.lvs: iter = self.logvolstore.append() - self.logvolstore.set_value(iter, 0, lvrequest.logicalVolumeName) - if lvrequest.mountpoint is not None: - self.logvolstore.set_value(iter, 1, lvrequest.mountpoint) + self.logvolstore.set_value(iter, 0, lv.lvname) + if lv.format.type == "luks": + usedev = self.storage.devicetree.getChildren(lv)[0] + format = usedev.format + else: + usedev = lv + format = usedev.format + + if getattr(format, "mountpoint", None): + self.logvolstore.set_value(iter, 1, + format.mountpoint) else: self.logvolstore.set_value(iter, 1, "") - self.logvolstore.set_value(iter, 2, "%Ld" % (lvrequest.getActualSize(self.partitions, self.diskset, True))) + self.logvolstore.set_value(iter, 2, "%Ld" % lv.size) self.logvollist = gtk.TreeView(self.logvolstore) col = gtk.TreeViewColumn(_("Logical Volume Name"), diff --git a/iw/osbootwidget.py b/iw/osbootwidget.py index 5263b853e..37a5eba39 100644 --- a/iw/osbootwidget.py +++ b/iw/osbootwidget.py @@ -23,7 +23,6 @@ import gtk import gobject import iutil import parted -import partedUtils import gui import datacombo from constants import * @@ -36,8 +35,7 @@ class OSBootWidget: def __init__(self, anaconda, parent, blname = None): self.bl = anaconda.id.bootloader - self.fsset = anaconda.id.fsset - self.diskset = anaconda.id.diskset + self.storage = anaconda.id.storage self.parent = parent self.intf = anaconda.intf if blname is not None: @@ -153,26 +151,22 @@ class OSBootWidget: label = gui.MnemonicLabel(_("_Device")) table.attach(label, 0, 1, 2, 3, gtk.FILL, 0, 10) if not isRoot: - # XXX should potentially abstract this out into a function - pedparts = [] parts = [] - disks = self.diskset.disks - func = lambda part: (part.active and - part.getFlag(parted.PARTITION_LVM) != 1 and - part.getFlag(parted.PARTITION_RAID) != 1) - for drive in disks.keys(): - pedparts.extend(partedUtils.filter_partitions(disks[drive], func)) - for part in pedparts: - parts.append(part.getDeviceNodeName()) - del pedparts - parts.sort() + + for part in self.storage.partitions: + if part.partedPartition.getFlag(parted.PARTITION_LVM) or \ + part.partedPartition.getFlag(parted.PARTITION_RAID) or \ + not part.partedPartition.active: + continue + + parts.append(part) deviceCombo = datacombo.DataComboBox() defindex = 0 i = 0 - for part in parts: - deviceCombo.append("/dev/%s" %(part,), part) - if oldDevice and oldDevice == part: + for part in parts: + deviceCombo.append(part.path, part.name) + if oldDevice and oldDevice == part.name: defindex = i i = i + 1 @@ -367,8 +361,8 @@ class OSBootWidget: continue isRoot = 0 - fsentry = self.fsset.getEntryByDeviceName(dev) - if fsentry and fsentry.getMountPoint() == '/': + rootDev = self.storage.fsset.rootDevice + if rootDev and rootDev.name == dev: isRoot = 1 iter = self.osStore.append() diff --git a/iw/partition_dialog_gui.py b/iw/partition_dialog_gui.py index 04e45db6a..f4ebdcaaf 100644 --- a/iw/partition_dialog_gui.py +++ b/iw/partition_dialog_gui.py @@ -26,9 +26,8 @@ import gobject import gtk import gui -from fsset import * -from cryptodev import LUKSDevice -from partRequests import * +from storage.devices import PartitionDevice, LUKSDevice +from storage.deviceaction import * from partition_ui_helpers_gui import * from constants import * @@ -50,13 +49,6 @@ class PartitionEditor: adj.clamp_page(size, adj.upper) fillmaxszsb.set_adjustment(adj) - def cylspinchangedCB(self, widget, data): - (dev, startcylspin, endcylspin, bycyl_sizelabel) = data - startsec = dev.startCylinderToSector(startcylspin.get_value_as_int()) - endsec = dev.endCylinderToSector(endcylspin.get_value_as_int()) - cursize = (endsec - startsec)/2048 - bycyl_sizelabel.set_text("%s" % (int(cursize))) - def fillmaxszCB(self, widget, spin): spin.set_sensitive(widget.get_active()) @@ -86,11 +78,11 @@ class PartitionEditor: # default to fixed, turn off max size spinbutton fillmaxszsb.set_sensitive(0) - if request.grow: - if request.maxSizeMB != None: + if request.req_grow: + if request.req_max_size: fillmaxszrb.set_active(1) fillmaxszsb.set_sensitive(1) - fillmaxszsb.set_value(request.maxSizeMB) + fillmaxszsb.set_value(request.req_max_size) else: fillunlimrb.set_active(1) else: @@ -107,154 +99,142 @@ class PartitionEditor: def run(self): if self.dialog is None: - return None + return [] while 1: rc = self.dialog.run() + actions = [] + luksdev = None # user hit cancel, do nothing if rc == 2: self.destroy() - return None + return [] - if self.origrequest.type == REQUEST_NEW: + if not self.origrequest.exists: # read out UI into a partition specification - filesystem = self.newfstypeCombo.get_active_value() - - request = copy.copy(self.origrequest) - request.fstype = filesystem - request.format = True - - if request.fstype.isMountable(): - request.mountpoint = self.mountCombo.get_children()[0].get_text() - else: - request.mountpoint = None + fmt_class = self.newfstypeCombo.get_active_value() + # there's nothing about origrequest we care about + #request = copy.copy(self.origrequest) + mountpoint = self.mountCombo.get_children()[0].get_text() if self.primonlycheckbutton.get_active(): - primonly = True + primary = True else: - primonly = None + primary = None - if self.lukscb and self.lukscb.get_active(): - if not request.encryption: - request.encryption = LUKSDevice(passphrase = self.partitions.encryptionPassphrase, format=1) + if self.fixedrb.get_active(): + grow = None else: - request.encryption = None - - if not self.newbycyl: - if self.fixedrb.get_active(): - grow = None - else: - grow = True - - self.sizespin.update() - - if self.fillmaxszrb.get_active(): - self.fillmaxszsb.update() - maxsize = self.fillmaxszsb.get_value_as_int() - else: - maxsize = None - - allowdrives = [] - model = self.driveview.get_model() - iter = model.get_iter_first() - while iter: - val = model.get_value(iter, 0) - drive = model.get_value(iter, 1) - - if val: - allowdrives.append(drive) - - iter = model.iter_next(iter) - - if len(allowdrives) == len(self.diskset.disks.keys()): - allowdrives = None - - request.size = self.sizespin.get_value_as_int() - request.drive = allowdrives - request.grow = grow - request.primary = primonly - request.maxSizeMB = maxsize - else: - self.startcylspin.update() - self.endcylspin.update() - - request.start = self.startcylspin.get_value_as_int() - request.end = self.endcylspin.get_value_as_int() - request.primary = primonly - - if request.end <= request.start: - self.intf.messageWindow(_("Error With Request"), - _("The end cylinder must be " - "greater than the start " - "cylinder."), custom_icon="error") + grow = True - continue + self.sizespin.update() - err = request.sanityCheckRequest(self.partitions) - if not err: - err = doUIRAIDLVMChecks(request, self.diskset) - - if err: - self.intf.messageWindow(_("Error With Request"), - "%s" % (err), custom_icon="error") - continue + if self.fillmaxszrb.get_active(): + self.fillmaxszsb.update() + maxsize = self.fillmaxszsb.get_value_as_int() + else: + maxsize = None + + allowdrives = [] + model = self.driveview.get_model() + iter = model.get_iter_first() + while iter: + val = model.get_value(iter, 0) + drive = model.get_value(iter, 1) + + if val: + allowdrives.append(drive) + + iter = model.iter_next(iter) + + if len(allowdrives) == len(self.storage.disks): + allowdrives = None + + size = self.sizespin.get_value_as_int() + disks = [] + if allowdrives: + for drive in allowdrives: + for disk in self.storage.disks: + if disk.name == drive: + disks.append(disk) + + # TODO: when will we set bootable? + request = self.storage.newPartition(size=size, + grow=grow, + maxsize=maxsize, + primary=primary, + parents=disks) + + format = fmt_class(mountpoint=mountpoint) + if self.lukscb and self.lukscb.get_active(): + luksformat = format + format = getFormat("luks", + passphrase=self.storage.encryptionPassphrase) + luksdev = LUKSDevice("luks%d" % self.storage.nextID, + format=luksformat, + parents=request) + elif self.lukscb and not self.lukscb.get_active() and \ + self.origrequest.format.type == "luks": + # destroy the luks format and the mapped device + luksdev = self.storage.devicetree.getChildren(self.origrequest)[0] + if luksdev: + actions.append(ActionDestroyFormat(luksdev.format)) + actions.append(ActionDestroyDevice(luksdev)) + luksdev = None + actions.append(ActionDestroyFormat(self.origrequest)) + + # we're all set, so create the actions + actions.append(ActionCreateDevice(request)) + actions.append(ActionCreateFormat(request, format)) + if luksdev: + actions.append(ActionCreateDevice(luksdev)) + actions.append(ActionCreateFormat(luksdev)) else: # preexisting partition, just set mount point and format flag - request = copy.copy(self.origrequest) - request.encryption = copy.deepcopy(self.origrequest.encryption) - - if self.fsoptionsDict.has_key("formatcb"): - request.format = self.fsoptionsDict["formatcb"].get_active() - if request.format: - request.fstype = self.fsoptionsDict["fstypeCombo"].get_active_value() - else: - request.format = 0 - - if self.fsoptionsDict.has_key("migratecb"): - request.migrate = self.fsoptionsDict["migratecb"].get_active() - if request.migrate: - request.fstype =self.fsoptionsDict["migfstypeCombo"].get_active_value() - else: - request.migrate = 0 - - if self.fsoptionsDict.has_key("resizecb") and self.fsoptionsDict["resizecb"].get_active(): - request.targetSize = self.fsoptionsDict["resizesb"].get_value_as_int() - else: - request.targetSize = None - - # set back if we are not formatting or migrating - origfstype = self.origrequest.origfstype - if not request.format and not request.migrate: - request.fstype = origfstype - - if request.fstype.isMountable(): - request.mountpoint = self.mountCombo.get_children()[0].get_text() - else: - request.mountpoint = None - - lukscb = self.fsoptionsDict.get("lukscb") - if lukscb and lukscb.get_active(): - if not request.encryption: - request.encryption = LUKSDevice(passphrase=self.partitions.encryptionPassphrase, format=1) - else: - request.encryption = None - - err = request.sanityCheckRequest(self.partitions) - if err: - self.intf.messageWindow(_("Error With Request"), - "%s" % (err), custom_icon="error") - continue - - if (not request.format and - request.mountpoint and request.formatByDefault()): + request = self.origrequest + mountpoint = self.mountCombo.get_children()[0].get_text() + if self.fsoptionsDict.has_key("formatcb") and \ + self.fsoptionsDict["formatcb"].get_active(): + fmt_class = self.fsoptionsDict["fstypeCombo"].get_active_value() + format = fmt_class(mountpoint=mountpoint) + luksdev = None + if self.fsoptionsDict.has_key("lukscb") and \ + self.fsoptionsDict["lukscb"].get_active() and \ + request.format.type != "luks": + luksdev = LUKSDevice("luks%d" % self.storage.nextID, + format=format, + parents=request) + format = getFormat("luks", + device=self.origrequest.path, + passphrase=self.storage.encryptionPassphrase) + actions.append(ActionCreateFormat(request, format)) + if luksdev: + actions.append(ActionCreateDevice(luksdev)) + elif request.format.mountable: + request.format.mountpoint = mountpoint + + if self.fsoptionsDict.has_key("migratecb") and \ + self.fsoptionsDict["migratecb"].get_active(): + actions.append(ActionMigrateFormat(request)) + + if self.fsoptionsDict.has_key("resizecb") and \ + self.fsoptionsDict["resizecb"].get_active(): + size = self.fsoptionsDict["resizesb"].get_value_as_int() + actions.append(ActionResizeDevice(request, size)) + if request.format.type: + actions.append(ActionResizeFormat(request, size)) + + if request.format.exists and \ + getattr(request, "mountpoint", None) and \ + self.storage.formatByDefault(request): if not queryNoFormatPreExisting(self.intf): continue - - # everything ok, fall out of loop + + # everything ok, fall out of loop break - - return request + + return actions def destroy(self): if self.dialog: @@ -265,8 +245,7 @@ class PartitionEditor: def __init__(self, anaconda, parent, origrequest, isNew = 0, restrictfs = None): self.anaconda = anaconda - self.partitions = self.anaconda.id.partitions - self.diskset = self.anaconda.id.diskset + self.storage = self.anaconda.id.storage self.intf = self.anaconda.intf self.origrequest = origrequest self.isNew = isNew @@ -275,10 +254,7 @@ class PartitionEditor: if isNew: tstr = _("Add Partition") else: - try: - tstr = _("Edit Partition: /dev/%s") % (origrequest.device,) - except: - tstr = _("Edit Partition") + tstr = _("Edit Partition: %s") % (origrequest.path,) self.dialog = gtk.Dialog(tstr, self.parent) gui.addFrame(self.dialog) @@ -291,24 +267,29 @@ class PartitionEditor: maintable.set_col_spacings(5) row = 0 - # see if we are creating a floating request or by cylinder - if self.origrequest.type == REQUEST_NEW: - self.newbycyl = self.origrequest.start != None + # if this is a luks device we need to grab info from two devices + # to make it seem like one device. wee! + if self.origrequest.format.type == "luks": + luksdev = self.storage.devicetree.getChildren(self.origrequest)[0] + usereq = luksdev + else: + luksdev = None + usereq = self.origrequest # Mount Point entry lbl = createAlignedLabel(_("_Mount Point:")) maintable.attach(lbl, 0, 1, row, row + 1) - self.mountCombo = createMountPointCombo(origrequest) + self.mountCombo = createMountPointCombo(usereq) lbl.set_mnemonic_widget(self.mountCombo) maintable.attach(self.mountCombo, 1, 2, row, row + 1) row = row + 1 # Partition Type - if self.origrequest.type == REQUEST_NEW: + if not self.origrequest.format.exists: lbl = createAlignedLabel(_("File System _Type:")) maintable.attach(lbl, 0, 1, row, row + 1) - self.newfstypeCombo = createFSTypeMenu(self.origrequest.fstype, + self.newfstypeCombo = createFSTypeMenu(usereq.format, fstypechangeCB, self.mountCombo, availablefstypes = restrictfs) @@ -320,103 +301,49 @@ class PartitionEditor: row = row + 1 # allowable drives - if self.origrequest.type == REQUEST_NEW: - if not self.newbycyl: - lbl = createAlignedLabel(_("Allowable _Drives:")) - maintable.attach(lbl, 0, 1, row, row + 1) - - self.driveview = createAllowedDrivesList(self.diskset.disks, - self.origrequest.drive, - selectDrives=False, - disallowDrives=[self.anaconda.updateSrc]) - lbl.set_mnemonic_widget(self.driveview) - sw = gtk.ScrolledWindow() - sw.add(self.driveview) - sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - sw.set_shadow_type(gtk.SHADOW_IN) - maintable.attach(sw, 1, 2, row, row + 1) - self.driveview.set_size_request(375, 80) - else: - maintable.attach(createAlignedLabel(_("Drive:")), - 0, 1, row, row + 1) - maintable.attach(createAlignedLabel(origrequest.drive[0]), - 1, 2, row, row + 1) + if not self.origrequest.exists: + lbl = createAlignedLabel(_("Allowable _Drives:")) + maintable.attach(lbl, 0, 1, row, row + 1) + + self.driveview = createAllowedDrivesList(self.storage.disks, + self.origrequest.req_disks, + selectDrives=False, + disallowDrives=[self.anaconda.updateSrc]) + lbl.set_mnemonic_widget(self.driveview) + sw = gtk.ScrolledWindow() + sw.add(self.driveview) + sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + sw.set_shadow_type(gtk.SHADOW_IN) + maintable.attach(sw, 1, 2, row, row + 1) + self.driveview.set_size_request(375, 80) row = row + 1 # original fs label - if self.origrequest.type != REQUEST_NEW and self.origrequest.fslabel: + if usereq.format.exists and \ + getattr(usereq.format, "label", None): maintable.attach(createAlignedLabel(_("Original File System " "Label:")), 0, 1, row, row + 1) - fslabel = gtk.Label(self.origrequest.fslabel) + fslabel = gtk.Label(usereq.format.label) maintable.attach(fslabel, 1, 2, row, row + 1) - row = row + 1 # size - if self.origrequest.type == REQUEST_NEW: - if not self.newbycyl: - # Size specification - lbl = createAlignedLabel(_("_Size (MB):")) - maintable.attach(lbl, 0, 1, row, row + 1) - sizeAdj = gtk.Adjustment(value = 1, lower = 1, - upper = MAX_PART_SIZE, step_incr = 1) - self.sizespin = gtk.SpinButton(sizeAdj, digits = 0) - self.sizespin.set_property('numeric', True) - - if self.origrequest.size: - self.sizespin.set_value(self.origrequest.size) - - lbl.set_mnemonic_widget(self.sizespin) - maintable.attach(self.sizespin, 1, 2, row, row + 1) - bycyl_sizelabel = None - else: - # XXX need to add partition by size and - # wire in limits between start and end - dev = self.diskset.disks[origrequest.drive[0]].dev - maintable.attach(createAlignedLabel(_("Size (MB):")), - 0, 1, row, row + 1) - bycyl_sizelabel = createAlignedLabel("") - maintable.attach(bycyl_sizelabel, 1, 2, row, row + 1) - row = row + 1 + if not self.origrequest.exists: + # Size specification + lbl = createAlignedLabel(_("_Size (MB):")) + maintable.attach(lbl, 0, 1, row, row + 1) + sizeAdj = gtk.Adjustment(value = 1, lower = 1, + upper = MAX_PART_SIZE, step_incr = 1) + self.sizespin = gtk.SpinButton(sizeAdj, digits = 0) + self.sizespin.set_property('numeric', True) - lbl = createAlignedLabel(_("_Start Cylinder:")) - maintable.attach(lbl, 0, 1, row, row + 1) - - (maxcyl, h, s) = self.diskset.disks[origrequest.drive[0]].device.biosGeometry - cylAdj = gtk.Adjustment(value=origrequest.start, - lower=origrequest.start, - upper=maxcyl, - step_incr=1) - self.startcylspin = gtk.SpinButton(cylAdj, digits=0) - self.startcylspin.set_property('numeric', True) - lbl.set_mnemonic_widget(self.startcylspin) - maintable.attach(self.startcylspin, 1, 2, row, row + 1) - row = row + 1 - - endcylAdj = gtk.Adjustment(value=origrequest.end, - lower=origrequest.start, - upper=maxcyl, - step_incr=1) - lbl = createAlignedLabel(_("_End Cylinder:")) - maintable.attach(lbl, 0, 1, row, row + 1) - self.endcylspin = gtk.SpinButton(endcylAdj, digits = 0) - self.endcylspin.set_property('numeric', True) - lbl.set_mnemonic_widget(self.endcylspin) - maintable.attach(self.endcylspin, 1, 2, row, row + 1) - - self.startcylspin.connect("value-changed", self.cylspinchangedCB, - (dev, self.startcylspin, - self.endcylspin, bycyl_sizelabel)) - self.endcylspin.connect("value-changed", self.cylspinchangedCB, - (dev, self.startcylspin, - self.endcylspin, bycyl_sizelabel)) - - startsec = dev.startCylinderToSector(origrequest.start) - endsec = dev.endCylinderToSector(origrequest.end) - cursize = (endsec - startsec)/2048 - bycyl_sizelabel.set_text("%s" % (int(cursize))) + if self.origrequest.req_size: + self.sizespin.set_value(self.origrequest.req_size) + + lbl.set_mnemonic_widget(self.sizespin) + maintable.attach(self.sizespin, 1, 2, row, row + 1) else: self.sizespin = None @@ -425,45 +352,42 @@ class PartitionEditor: # format/migrate options for pre-existing partitions, as long as they # aren't protected (we'd still like to be able to mount them, though) self.fsoptionsDict = {} - if self.origrequest.type == REQUEST_PREEXIST and self.origrequest.fstype and not self.origrequest.getProtected(): - (row, self.fsoptionsDict) = createPreExistFSOptionSection(self.origrequest, maintable, row, self.mountCombo, self.partitions) + if self.origrequest.exists and \ + not self.storage.isProtected(self.origrequest): + (row, self.fsoptionsDict) = createPreExistFSOptionSection(usereq, maintable, row, self.mountCombo, self.storage) # size options - if self.origrequest.type == REQUEST_NEW: - if not self.newbycyl: - (sizeframe, self.fixedrb, self.fillmaxszrb, - self.fillmaxszsb) = self.createSizeOptionsFrame(self.origrequest, - self.fillmaxszCB) - self.sizespin.connect("value-changed", self.sizespinchangedCB, - self.fillmaxszsb) - - maintable.attach(sizeframe, 0, 2, row, row + 1) - else: - # XXX need new by cyl options (if any) - pass + if not self.origrequest.exists: + (sizeframe, self.fixedrb, self.fillmaxszrb, + self.fillmaxszsb) = self.createSizeOptionsFrame(self.origrequest, + self.fillmaxszCB) + self.sizespin.connect("value-changed", self.sizespinchangedCB, + self.fillmaxszsb) + + maintable.attach(sizeframe, 0, 2, row, row + 1) row = row + 1 else: self.sizeoptiontable = None # create only as primary - if self.origrequest.type == REQUEST_NEW: + if not self.origrequest.exists: self.primonlycheckbutton = gtk.CheckButton(_("Force to be a _primary " "partition")) self.primonlycheckbutton.set_active(0) - if self.origrequest.primary: + if self.origrequest.req_primary: self.primonlycheckbutton.set_active(1) # only show if we have something other than primary - if not self.diskset.onlyPrimaryParts(): + if self.storage.extendedPartitionsSupported(): maintable.attach(self.primonlycheckbutton, 0, 2, row, row+1) row = row + 1 # checkbutton for encryption using dm-crypt/LUKS - if self.origrequest.type == REQUEST_NEW: + if not self.origrequest.exists: self.lukscb = gtk.CheckButton(_("_Encrypt")) self.lukscb.set_data("formatstate", 1) - if self.origrequest.encryption: + if self.origrequest.format.type == "luks": self.lukscb.set_active(1) else: self.lukscb.set_active(0) diff --git a/iw/partition_gui.py b/iw/partition_gui.py index 940c2525f..c704b0893 100644 --- a/iw/partition_gui.py +++ b/iw/partition_gui.py @@ -27,15 +27,13 @@ try: except ImportError: import gnome.canvas as gnomecanvas import pango -import autopart import gui import parted import string import types -import raid from constants import * -import lvm +import storage from iw_gui import * from flags import flags @@ -44,10 +42,10 @@ import raid_dialog_gui import partition_dialog_gui from partIntfHelpers import * -from partedUtils import * -from fsset import * -from partRequests import * +from constants import * from partition_ui_helpers_gui import * +from storage.partitioning import doPartitioning +from storage.devicelibs import lvm import gettext _ = lambda x: gettext.ldgettext("anaconda", x) @@ -98,7 +96,7 @@ class DiskStripeSlice: if event.button == 1: self.parent.selectSlice(self.partition, 1) elif event.type == gtk.gdk._2BUTTON_PRESS: - self.editCb() + self.editCB() return True @@ -182,12 +180,12 @@ class DiskStripeSlice: clip_width=xlength-1, clip_height=yheight-1) self.hideOrShowText() - def __init__(self, parent, partition, treeView, editCb): + def __init__(self, parent, partition, treeView, editCB): self.text = None self.partition = partition self.parent = parent self.treeView = treeView - self.editCb = editCb + self.editCB = editCB pgroup = parent.getGroup() self.group = pgroup.add(gnomecanvas.CanvasGroup) @@ -198,14 +196,14 @@ class DiskStripeSlice: self.update() class DiskStripe: - def __init__(self, drive, disk, group, tree, editCb): + def __init__(self, drive, disk, group, tree, editCB): self.disk = disk self.group = group self.tree = tree self.drive = drive self.slices = [] self.hash = {} - self.editCb = editCb + self.editCB = editCB self.selected = None # XXX hack but will work for now @@ -259,17 +257,17 @@ class DiskStripe: self.selected = None def add(self, partition): - stripe = DiskStripeSlice(self, partition, self.tree, self.editCb) + stripe = DiskStripeSlice(self, partition, self.tree, self.editCB) self.slices.append(stripe) self.hash[partition] = stripe class DiskStripeGraph: - def __init__(self, tree, editCb): + def __init__(self, tree, editCB): self.canvas = gnomecanvas.Canvas() self.diskStripes = [] self.textlabels = [] self.tree = tree - self.editCb = editCb + self.editCB = editCB self.next_ypos = 0.0 def __del__(self): @@ -334,7 +332,7 @@ class DiskStripeGraph: self.textlabels.append(text) group = self.canvas.root().add(gnomecanvas.CanvasGroup, x=0, y=yoff+textheight) - stripe = DiskStripe(drive, disk, group, self.tree, self.editCb) + stripe = DiskStripe(drive, disk, group, self.tree, self.editCB) self.diskStripes.append(stripe) self.next_ypos = self.next_ypos + STRIPE_HEIGHT+textheight+10 return stripe @@ -371,8 +369,6 @@ class DiskTreeModel(gtk.TreeStore): # (N_("Size (MB)"), gobject.TYPE_STRING, 1.0, 0, isLeaf), (N_("Format"), gobject.TYPE_OBJECT, 0.5, 0, isFormattable), (N_("Size (MB)"), gobject.TYPE_STRING, 1.0, 0, 0), - (N_("Start"), gobject.TYPE_STRING, 1.0, 0, 1), - (N_("End"), gobject.TYPE_STRING, 1.0, 0, 1), ("", gobject.TYPE_STRING, 0.0, 0, 0), # the following must be the last two ("IsLeaf", gobject.TYPE_BOOLEAN, 0.0, 1, 0), @@ -487,25 +483,7 @@ class DiskTreeModel(gtk.TreeStore): # not found the partition raise RuntimeError, "could not find partition" - """ returns partition 'id' of current selection in tree """ - def getCurrentPartition(self): - selection = self.view.get_selection() - model, iter = selection.get_selected() - if not iter: - return None - - pyobject = self.titleSlot['PyObject'] - try: - val = self.get_value(iter, pyobject) - if type(val) == type("/dev/"): - if val[:5] == '/dev/': - return None - - return val - except: - return None - - """ Return name of current selected drive (if a drive is highlighted) """ + """ Return the device representing the current selection """ def getCurrentDevice(self): selection = self.view.get_selection() model, iter = selection.get_selected() @@ -515,12 +493,10 @@ class DiskTreeModel(gtk.TreeStore): pyobject = self.titleSlot['PyObject'] try: val = self.get_value(iter, pyobject) - if type(val) == type("/dev/"): - if val[:5] == '/dev/': - return val - return None - except: - return None + except Exception: + val = None + + return val def resetSelection(self): pass @@ -631,8 +607,7 @@ class PartitionWindow(InstallWindow): return rc def getNext(self): - (errors, warnings) = self.partitions.sanityCheckAllRequests(self.diskset) - + (errors, warnings) = self.storage.sanityCheck() if errors: labelstr1 = _("The partitioning scheme you requested " "caused the following critical errors.") @@ -648,6 +623,7 @@ class PartitionWindow(InstallWindow): raise gui.StayOnScreen if warnings: + # "storage configuration" labelstr1 = _("The partitioning scheme you requested " "generated the following warnings.") labelstr2 = _("Would you like to continue with " @@ -662,8 +638,7 @@ class PartitionWindow(InstallWindow): if rc != 1: raise gui.StayOnScreen - formatWarnings = getPreExistFormatWarnings(self.partitions, - self.diskset) + formatWarnings = getPreExistFormatWarnings(self.storage) if formatWarnings: labelstr1 = _("The following pre-existing partitions have been " "selected to be formatted, destroying all data.") @@ -675,7 +650,7 @@ class PartitionWindow(InstallWindow): commentstr = "" for (dev, type, mntpt) in formatWarnings: commentstr = commentstr + \ - "/dev/%s %s %s\n" % (dev,type,mntpt) + "%s %s %s\n" % (dev,type,mntpt) rc = self.presentPartitioningComments(_("Format Warnings"), labelstr1, labelstr2, @@ -694,161 +669,164 @@ class PartitionWindow(InstallWindow): def getPrev(self): self.diskStripeGraph.shutDown() - self.diskset.refreshDevices() - self.partitions.setFromDisk(self.diskset) + self.storage.reset() self.tree.clear() del self.parent return None - def getShortFSTypeName(self, name): - if name == "physical volume (LVM)": - return "LVM PV" - - return name - def populate(self, initial = 0): - - drives = self.diskset.disks.keys() - drives.sort() - self.tree.resetSelection() self.tree.clearHiddenPartitionsList() # first do LVM - lvmrequests = self.partitions.getLVMRequests() - if lvmrequests: + vgs = self.storage.vgs + if vgs: lvmparent = self.tree.append(None) self.tree[lvmparent]['Device'] = _("LVM Volume Groups") - for vgname in lvmrequests.keys(): - vgrequest = self.partitions.getRequestByVolumeGroupName(vgname) - rsize = vgrequest.getActualSize(self.partitions, self.diskset) + for vg in vgs: + rsize = vg.size vgparent = self.tree.append(lvmparent) - self.tree[vgparent]['Device'] = "%s" % (vgname,) - if vgrequest and vgrequest.type != REQUEST_NEW and vgrequest.fslabel: - self.tree[vgparent]['Label'] = "%s" % (vgrequest.fslabel,) - else: - self.tree[vgparent]['Label'] = "" + self.tree[vgparent]['Device'] = "%s" % vg.name + self.tree[vgparent]['Label'] = "" self.tree[vgparent]['Mount Point'] = "" - self.tree[vgparent]['Start'] = "" - self.tree[vgparent]['End'] = "" self.tree[vgparent]['Size (MB)'] = "%Ld" % (rsize,) - self.tree[vgparent]['PyObject'] = str(vgrequest.uniqueID) - for lvrequest in lvmrequests[vgname]: + self.tree[vgparent]['PyObject'] = vg + for lv in vg.lvs: + if lv.format.type == "luks": + # we'll want to grab format info from the mapped + # device, not the encrypted one + dm_dev = self.storage.devicetree.getChildren(lv)[0] + format = dm_dev.format + else: + format = lv.format iter = self.tree.append(vgparent) - self.tree[iter]['Device'] = lvrequest.logicalVolumeName - if lvrequest.fstype and lvrequest.mountpoint: - self.tree[iter]['Mount Point'] = lvrequest.mountpoint + self.tree[iter]['Device'] = lv.lvname + if format.mountable and format.mountpoint: + self.tree[iter]['Mount Point'] = format.mountpoint else: self.tree[iter]['Mount Point'] = "" - self.tree[iter]['Size (MB)'] = "%Ld" % (lvrequest.getActualSize(self.partitions, self.diskset, True),) - self.tree[iter]['PyObject'] = str(lvrequest.uniqueID) + self.tree[iter]['Size (MB)'] = "%Ld" % lv.size + self.tree[iter]['PyObject'] = vg - ptype = lvrequest.fstype.getName() - if lvrequest.isEncrypted(self.partitions, True) and lvrequest.format: + if lv.format.type == "luks" and not lv.format.exists: + # we're creating the LUKS header self.tree[iter]['Format'] = self.lock_pixbuf - elif lvrequest.format: + elif not format.exists: + # we're creating a format on the device self.tree[iter]['Format'] = self.checkmark_pixbuf - self.tree[iter]['IsFormattable'] = lvrequest.fstype.isFormattable() + self.tree[iter]['IsFormattable'] = format.formattable self.tree[iter]['IsLeaf'] = True - self.tree[iter]['Type'] = ptype - self.tree[iter]['Start'] = "" - self.tree[iter]['End'] = "" + self.tree[iter]['Type'] = lv.format.name + #self.tree[iter]['Start'] = "" + #self.tree[iter]['End'] = "" # handle RAID next - raidrequests = self.partitions.getRaidRequests() - if raidrequests: + mdarrays = self.storage.mdarrays + if mdarrays: raidparent = self.tree.append(None) self.tree[raidparent]['Device'] = _("RAID Devices") - for request in raidrequests: + for array in mdarrays: mntpt = None - if request and request.fstype and request.fstype.getName() == "physical volume (LVM)": - vgreq = self.partitions.getLVMVolumeGroupMemberParent(request) - if vgreq and vgreq.volumeGroupName: - if self.show_uneditable: - mntpt = vgreq.volumeGroupName - else: - self.tree.appendToHiddenPartitionsList(str(request.uniqueID)) - continue + if array.format.type == "luks": + # look up the mapped/decrypted device since that's + # where we'll find the format we want to display + dm_dev = self.storage.getChildren(array)[0] + format = dm_dev.format + else: + format = array.format + + if format.type == "lvmpv": + vg = None + for _vg in self.storage.vgs: + if _vg.dependsOn(array): + vg = _vg + break + if vg and self.show_uneditable: + mntpt = vg.name + elif vg: + self.tree.appendToHiddenPartitionsList(array.path) + continue else: mntpt = "" + elif format.mountable and format.mountpoint: + mntpt = format.mountpoint iter = self.tree.append(raidparent) if mntpt: self.tree[iter]["Mount Point"] = mntpt + else: + self.tree[iter]["Mount Point"] = "" - if request and request.mountpoint: - self.tree[iter]["Mount Point"] = request.mountpoint - - if request.fstype: - ptype = self.getShortFSTypeName(request.fstype.getName()) - - if request.isEncrypted(self.partitions, True) and request.format: + if format.type: + ptype = format.name + if array.format.type == "luks" and \ + not array.format.exists: self.tree[iter]['Format'] = self.lock_pixbuf - elif request.format: + elif not format.exists: self.tree[iter]['Format'] = self.checkmark_pixbuf - self.tree[iter]['IsFormattable'] = request.fstype.isFormattable() + self.tree[iter]['IsFormattable'] = format.formattable else: ptype = _("None") self.tree[iter]['IsFormattable'] = False - try: - device = "/dev/md%d" % (request.raidminor,) - except: + if array.minor is not None: + device = "%s" % array.path + else: device = "Auto" self.tree[iter]['IsLeaf'] = True self.tree[iter]['Device'] = device - if request and request.type != REQUEST_NEW and request.fslabel: - self.tree[iter]['Label'] = "%s" % (request.fslabel,) + if array.format.exists and getattr(format, "label", None): + self.tree[iter]['Label'] = "%s" % format.label else: self.tree[iter]['Label'] = "" self.tree[iter]['Type'] = ptype - self.tree[iter]['Start'] = "" - self.tree[iter]['End'] = "" - self.tree[iter]['Size (MB)'] = "%Ld" % (request.getActualSize(self.partitions, self.diskset),) - self.tree[iter]['PyObject'] = str(request.uniqueID) + self.tree[iter]['Size (MB)'] = "%Ld" % array.size + self.tree[iter]['PyObject'] = array # now normal partitions + disks = self.storage.disks drvparent = self.tree.append(None) self.tree[drvparent]['Device'] = _("Hard Drives") - for drive in drives: - disk = self.diskset.disks[drive] - + for disk in disks: # add a disk stripe to the graph - stripe = self.diskStripeGraph.add(drive, disk) + stripe = self.diskStripeGraph.add(disk.name, disk.partedDisk) # add a parent node to the tree parent = self.tree.append(drvparent) - self.tree[parent]['Device'] = '/dev/%s' % (drive,) - self.tree[parent]['PyObject'] = str('/dev/%s' % (drive,)) - (cylinders, heads, sectors) = disk.device.biosGeometry + self.tree[parent]['Device'] = "%s" % disk.path + self.tree[parent]['PyObject'] = disk + (cylinders, heads, sectors) = disk.partedDisk.device.biosGeometry sectorsPerCyl = heads * sectors + part = disk.partedDisk.getFirstPartition() extendedParent = None - part = disk.getFirstPartition() while part: if part.type & parted.PARTITION_METADATA: part = part.nextPartition() continue + + partName = part.getDeviceNodeName() + device = self.storage.devicetree.getDeviceByName(partName) + if not device and not part.type & parted.PARTITION_FREESPACE: + raise RuntimeError("can't find partition %s in device" + " tree" % partName) + # ignore the tiny < 1 MB partitions (#119479) if part.getSize(unit="MB") <= 1.0: - if not part.active or not part.getFlag(parted.PARTITION_BOOT): - part = part.nextPartition() + if not part.active or not device.bootable: continue stripe.add(part) - device = part.getDeviceNodeName() - request = self.partitions.getRequestByDeviceName(device) - - if part.type == parted.PARTITION_EXTENDED: + if device and device.isExtended: if extendedParent: raise RuntimeError, ("can't handle more than " "one extended partition per disk") extendedParent = self.tree.append(parent) iter = extendedParent - elif part.type & parted.PARTITION_LOGICAL: + elif device and device.isLogical: if not extendedParent: raise RuntimeError, ("crossed logical partition " "before extended") @@ -858,16 +836,30 @@ class PartitionWindow(InstallWindow): iter = self.tree.append(parent) self.tree[iter]['IsLeaf'] = True - if request and request.mountpoint: - self.tree[iter]['Mount Point'] = request.mountpoint + if device and device.format.type == "luks": + # look up the mapped/decrypted device in the tree + # the format we care about will be on it + dm_dev = self.storage.devicetree.getChildren(device)[0] + format = dm_dev.format + elif device: + format = device.format + else: + format = None + + if format and format.mountable and format.mountpoint: + self.tree[iter]['Mount Point'] = format.mountpoint else: self.tree[iter]['Mount Point'] = "" - if request and request.fstype and request.fstype.getName() == "physical volume (LVM)": - vgreq = self.partitions.getLVMVolumeGroupMemberParent(request) - if vgreq and vgreq.volumeGroupName: + if format and format.type == "lvmpv": + vg = None + for _vg in self.storage.vgs: + if _vg.dependsOn(part): + vg = _vg + break + if vg and vg.name: if self.show_uneditable: - self.tree[iter]['Mount Point'] = vgreq.volumeGroupName + self.tree[iter]['Mount Point'] = vg.name else: self.tree.appendToHiddenPartitionsList(part) self.tree.remove(iter) @@ -875,26 +867,32 @@ class PartitionWindow(InstallWindow): else: self.tree[iter]['Mount Point'] = "" - if request.isEncrypted(self.partitions, True) and request.format: - self.tree[iter]['Format'] = self.lock_pixbuf - elif request.format: - self.tree[iter]['Format'] = self.checkmark_pixbuf + if device and device.format and \ + device.format.type == "luks" and \ + not device.format.exists: + self.tree[iter]['Format'] = self.lock_pixbuf + elif format and not format.exists: + self.tree[iter]['Format'] = self.checkmark_pixbuf - if request and request.fstype: - self.tree[iter]['IsFormattable'] = request.fstype.isFormattable() + if format and format.type: + self.tree[iter]['IsFormattable'] = device.format.formattable - if part.type & parted.PARTITION_FREESPACE: - ptype = _("Free space") - elif part.type == parted.PARTITION_EXTENDED: + if device and device.isExtended: ptype = _("Extended") - elif part.getFlag(parted.PARTITION_RAID) == 1: + elif format and format.type == "mdmember": ptype = _("software RAID") - parreq = self.partitions.getRaidMemberParent(request) - if parreq: + mds = self.storage.mdarrays + array = None + for _array in mds: + if _array.dependsOn(device): + array = _array + break + if array: if self.show_uneditable: - try: - mddevice = "/dev/md%d" % (parreq.raidminor,) - except: + if array.minor is not None: + mddevice = "%s" % array.path + else: + mddevice = "Auto" mddevice = "Auto" self.tree[iter]['Mount Point'] = mddevice else: @@ -905,48 +903,33 @@ class PartitionWindow(InstallWindow): else: self.tree[iter]['Mount Point'] = "" - if request and request.isEncrypted(self.partitions, True) and request.format: - self.tree[iter]['Format'] = self.lock_pixbuf - elif part.fileSystem: - if request and request.fstype != None: - ptype = self.getShortFSTypeName(request.fstype.getName()) - if ptype == "foreign": - ptype = map_foreign_to_fsname(part) - else: - ptype = part.fileSystem.type - - if request and request.isEncrypted(self.partitions, True) and request.format: + if device.format.type == "luks" and \ + not device.format.exists: self.tree[iter]['Format'] = self.lock_pixbuf - elif request and request.format: - self.tree[iter]['Format'] = self.checkmark_pixbuf else: - if request and request.fstype != None: - ptype = self.getShortFSTypeName(request.fstype.getName()) - - if ptype == "foreign": - ptype = map_foreign_to_fsname(part) + if format and format.type: + ptype = format.name else: ptype = _("None") if part.type & parted.PARTITION_FREESPACE: devname = _("Free") else: - devname = '/dev/%s' % (device,) + devname = "%s" % device.path self.tree[iter]['Device'] = devname - if request and request.type != REQUEST_NEW and request.fslabel: - self.tree[iter]['Label'] = "%s" % (request.fslabel,) + if format and format.exists and \ + getattr(format, "label", None): + self.tree[iter]['Label'] = "%s" % format.label else: self.tree[iter]['Label'] = "" self.tree[iter]['Type'] = ptype - self.tree[iter]['Start'] = str(disk.device.startSectorToCylinder(part.geometry.start)) - self.tree[iter]['End'] = str(disk.device.endSectorToCylinder(part.geometry.end)) size = part.getSize(unit="MB") if size < 1.0: sizestr = "< 1" else: sizestr = "%Ld" % (size) self.tree[iter]['Size (MB)'] = sizestr - self.tree[iter]['PyObject'] = part + self.tree[iter]['PyObject'] = device part = part.nextPartition() @@ -954,44 +937,53 @@ class PartitionWindow(InstallWindow): apply(canvas.set_scroll_region, canvas.root().get_bounds()) self.treeView.expand_all() - def treeActivateCb(self, view, path, col): - if self.tree.getCurrentPartition(): - self.editCb() + def treeActivateCB(self, view, path, col): + if isinstance(self.tree.getCurrentDevice(), + storage.devices.PartitionDevice): + self.editCB() - def treeSelectCb(self, selection, *args): + def treeSelectCB(self, selection, *args): model, iter = selection.get_selected() if not iter: return - partition = model[iter]['PyObject'] - if partition: + device = model[iter]['PyObject'] + if device: + # PyObject is always a Device but not always a PartitionDevice + try: + partition = device.partedPartition + except AttributeError: + return + self.diskStripeGraph.selectSlice(partition) def newCB(self, widget): - request = NewPartitionSpec(fileSystemTypeGetDefault(), size = 200) - - self.editPartitionRequest(request, isNew = 1) - - def deleteCb(self, widget): - curselection = self.tree.getCurrentPartition() - - if curselection: - if doDeletePartitionByRequest(self.intf, self.partitions, curselection): + device = self.storage.newPartition(fmt_type=self.storage.defaultFSType, + size=200) + self.editPartition(device, isNew=1) + + def deleteCB(self, widget): + """ Right now we can say that if the device is partitioned we + want to delete all of the devices it contains. At some point + we will want to support creation and removal of partitionable + devices. This will need some work when that time comes. + """ + device = self.tree.getCurrentDevice() + if hasattr(device, "partedDisk"): + if doDeleteDependentDevices(self.intf, + self.storage, + device): + self.refresh() + elif doDeleteDevice(self.intf, + self.storage, + device): self.refresh() - else: - curdevice = self.tree.getCurrentDevice() - if curdevice and len(curdevice) > 5: - if doDeletePartitionsByDevice(self.intf, self.partitions, self.diskset, curdevice[5:]): - self.refresh() - else: - return - def resetCb(self, *args): + def resetCB(self, *args): if not confirmResetPartitionState(self.intf): return self.diskStripeGraph.shutDown() - self.diskset.refreshDevices() - self.partitions.setFromDisk(self.diskset) + self.storage.reset() self.tree.clear() self.populate() @@ -999,25 +991,10 @@ class PartitionWindow(InstallWindow): self.diskStripeGraph.shutDown() self.tree.clear() - # XXXX - Backup some info which doPartitioning munges if it fails - origInfoDict = {} - for request in self.partitions.requests: - try: - origInfoDict[request.uniqueID] = (request.requestSize, request.currentDrive) - except: - pass - try: - autopart.doPartitioning(self.diskset, self.partitions) + doPartitioning(self.storage) rc = 0 except PartitioningError, msg: - try: - for request in self.partitions.requests: - if request.uniqueID in origInfoDict.keys(): - (request.requestSize, request.currentDrive) = origInfoDict[request.uniqueID] - except: - log.error("Failed to restore original info") - self.intf.messageWindow(_("Error Partitioning"), _("Could not allocate requested partitions: %s.") % (msg), custom_icon="error") @@ -1044,59 +1021,63 @@ class PartitionWindow(InstallWindow): rc = -1 else: rc = 0 - reqs = self.partitions.getBootableRequest() - if reqs: - for req in reqs: - req.ignoreBootConstraints = 1 + all_devices = self.storage.devicetree.devices.values() + bootDevs = [d for d in all_devices if d.bootable] + #if reqs: + # for req in reqs: + # req.ignoreBootConstraints = 1 if not rc == -1: self.populate() return rc - def editCb(self, *args): - part = self.tree.getCurrentPartition() - - (type, request) = doEditPartitionByRequest(self.intf, self.partitions, - part) - if request: - if type == "RAID": - self.editRaidRequest(request) - elif type == "LVMVG": - self.editLVMVolumeGroup(request) - elif type == "LVMLV": - vgrequest = self.partitions.getRequestByID(request.volumeGroup) - self.editLVMVolumeGroup(vgrequest) - elif type == "NEW": - self.editPartitionRequest(request, isNew = 1) - else: - self.editPartitionRequest(request) + def editCB(self, *args): + device = self.tree.getCurrentDevice() + if not device: + self.intf.messageWindow(_("Unable To Edit"), + _("You must select a device to edit"), + custom_icon="error") + return + + reason = self.storage.deviceImmutable(device) + if reason: + self.intf.messageWindow(_("Unable To Edit"), + _("You cannot edit this device:\n\n%s") + % reason, + custom_icon="error") + return + + if device.type == "mdarray": + self.editRaidArray(device) + elif device.type == "lvmvg": + self.editLVMVolumeGroup(device) + elif device.type == "lvmlv": + self.editLVMVolumeGroup(device) + elif device.type == "partition": + self.editPartition(device) # isNew implies that this request has never been successfully used before - def editRaidRequest(self, raidrequest, isNew = 0): - raideditor = raid_dialog_gui.RaidEditor(self.partitions, - self.diskset, self.intf, - self.parent, raidrequest, - isNew) - origpartitions = self.partitions.copy() + def editRaidArray(self, raiddev, isNew = 0): + raideditor = raid_dialog_gui.RaidEditor(self.storage, + self.intf, + self.parent, + raiddev, + isNew) + # is a shallow copy enough? + #origpartitions = self.storage.devicetree.copy() while 1: - request = raideditor.run() - - if request is None: - return - - if not isNew: - self.partitions.removeRequest(raidrequest) - if raidrequest.getPreExisting(): - delete = partRequests.DeleteRAIDSpec(raidrequest.raidminor) - self.partitions.addDelete(delete) + actions = raideditor.run() - self.partitions.addRequest(request) + for action in actions: + # FIXME: this needs to handle exceptions + self.storage.devicetree.registerAction(action) if self.refresh(): - if not isNew: - self.partitions = origpartitions.copy() + actions.reverse() + for action in actions: + self.storage.devicetree.cancelAction(action) if self.refresh(): raise RuntimeError, ("Returning partitions to state " "prior to RAID edit failed") @@ -1107,29 +1088,27 @@ class PartitionWindow(InstallWindow): raideditor.destroy() - def editPartitionRequest(self, origrequest, isNew = 0, restrictfs = None): + def editPartition(self, device, isNew = 0, restrictfs = None): parteditor = partition_dialog_gui.PartitionEditor(self.anaconda, self.parent, - origrequest, + device, isNew = isNew, restrictfs = restrictfs) while 1: - request = parteditor.run() + actions = parteditor.run() - if request is None: - return 0 + for action in actions: + # XXX we should handle exceptions here + self.anaconda.id.storage.devicetree.registerAction(action) - if not isNew: - self.partitions.removeRequest(origrequest) - - self.partitions.addRequest(request) if self.refresh(): - # the add failed; remove what we just added and put - # back what was there if we removed it - self.partitions.removeRequest(request) - if not isNew: - self.partitions.addRequest(origrequest) + # autopart failed -- cancel the actions and try to get + # back to previous state + actions.reverse() + for action in actions: + self.anaconda.id.storage.devicetree.cancelAction(action) + if self.refresh(): # this worked before and doesn't now... raise RuntimeError, ("Returning partitions to state " @@ -1140,66 +1119,30 @@ class PartitionWindow(InstallWindow): parteditor.destroy() return 1 - def editLVMVolumeGroup(self, origvgrequest, isNew = 0): - vgeditor = lvm_dialog_gui.VolumeGroupEditor(self.anaconda, - self.partitions, - self.diskset, - self.intf, self.parent, - origvgrequest, isNew) + def editLVMVolumeGroup(self, device, isNew = 0): + # we don't really need to pass in self.storage if we're passing + # self.anaconda already + vgeditor = lvm_dialog_gui.VolumeGroupEditor(self.anaconda, + self.intf, + self.parent, + device, + isNew) - origpartitions = self.partitions.copy() - origvolreqs = origpartitions.getLVMLVForVG(origvgrequest) - - while (1): - rc = vgeditor.run() - - # - # return code is either None or a tuple containing - # volume group request and logical volume requests - # - if rc is None: - return - - (vgrequest, logvolreqs) = rc - - # first add the volume group - if not isNew: - # if an lv was preexisting and isn't in the new lv requests, - # we need to add a delete for it. - for lv in origvolreqs: - if not lv.getPreExisting(): - continue - found = 0 - for newlv in logvolreqs: - if (newlv.getPreExisting() and - newlv.logicalVolumeName == lv.logicalVolumeName): - found = 1 - break - if found == 0: - delete = partRequests.DeleteLogicalVolumeSpec(lv.logicalVolumeName, - origvgrequest.volumeGroupName) - self.partitions.addDelete(delete) - - for lv in origvolreqs: - self.partitions.removeRequest(lv) - - self.partitions.removeRequest(origvgrequest) - - vgID = self.partitions.addRequest(vgrequest) + while True: + actions = vgeditor.run() - # now add the logical volumes - for lv in logvolreqs: - lv.volumeGroup = vgID - if not lv.getPreExisting(): - lv.format = 1 - self.partitions.addRequest(lv) + for action in actions: + # FIXME: handle exceptions + self.storage.devicetree.registerAction(action) if self.refresh(): - if not isNew: - self.partitions = origpartitions.copy() - if self.refresh(): - raise RuntimeError, ("Returning partitions to state " - "prior to edit failed") + actions.reverse() + for action in actions: + self.storage.devicetree.cancelAction(action) + + if self.refresh(): + raise RuntimeError, ("Returning partitions to state " + "prior to edit failed") continue else: break @@ -1207,31 +1150,27 @@ class PartitionWindow(InstallWindow): vgeditor.destroy() - def makeLvmCB(self, widget): - if (not fileSystemTypeGet('physical volume (LVM)').isSupported() or - not lvm.has_lvm()): + if not getFormat("lvmpv").supported or not lvm.has_lvm(): self.intf.messageWindow(_("Not supported"), _("LVM is NOT supported on " "this platform."), type="ok", custom_icon="error") return - request = VolumeGroupRequestSpec(format=True) - self.editLVMVolumeGroup(request, isNew = 1) - + vg = self.storage.newVG() + self.editLVMVolumeGroup(vg, isNew = 1) return def makeraidCB(self, widget): - - if not fileSystemTypeGet('software RAID').isSupported(): + if not getFormat("software RAID").supported: self.intf.messageWindow(_("Not supported"), _("Software RAID is NOT supported on " "this platform."), type="ok", custom_icon="error") return - availminors = self.partitions.getAvailableRaidMinors() + availminors = self.storage.unusedMDMinors if len(availminors) < 1: self.intf.messageWindow(_("No RAID minor device numbers available"), _("A software RAID device cannot " @@ -1244,9 +1183,7 @@ class PartitionWindow(InstallWindow): # see if we have enough free software RAID partitions first # if no raid partitions exist, raise an error message and return - request = RaidRequestSpec(fileSystemTypeGetDefault()) - availraidparts = self.partitions.getAvailRaidPartitions(request, - self.diskset) + availraidparts = self.storage.unusedMDMembers() dialog = gtk.Dialog(_("RAID Options"), self.parent) gui.addFrame(dialog) @@ -1299,7 +1236,7 @@ class PartitionWindow(InstallWindow): createRAIDpart.set_active(1) doRAIDclone.set_sensitive(0) createRAIDdev.set_sensitive(0) - if len(availraidparts) > 0 and len(self.diskset.disks.keys()) > 1: + if len(availraidparts) > 0 and len(self.storage.disks) > 1: doRAIDclone.set_sensitive(1) if len(availraidparts) > 1: @@ -1321,13 +1258,16 @@ class PartitionWindow(InstallWindow): # see which option they choose if createRAIDpart.get_active(): - rdrequest = NewPartitionSpec(fileSystemTypeGet("software RAID"), size = 200) - rc = self.editPartitionRequest(rdrequest, isNew = 1, restrictfs=["software RAID"]) + member = self.storage.newPartition(fmt_type="software RAID", + size=200) + rc = self.editPartitionRequest(member, + isNew = 1, + restrictfs=["software RAID"]) elif createRAIDdev.get_active(): - self.editRaidRequest(request, isNew=1) + array = self.storage.newMDArray(fmt_type=self.storage.defaultFSType) + self.editRaidArray(array, isNew=1) else: - cloneDialog = raid_dialog_gui.RaidCloneDialog(self.partitions, - self.diskset, + cloneDialog = raid_dialog_gui.RaidCloneDialog(self.storage, self.intf, self.parent) if cloneDialog is None: @@ -1337,16 +1277,12 @@ class PartitionWindow(InstallWindow): custom_icon="error") return - while 1: - rc = cloneDialog.run() + if cloneDialog.run(): + self.refresh() - if rc: - self.refresh() - - cloneDialog.destroy() - return + cloneDialog.destroy() + return - def viewButtonCB(self, widget): self.show_uneditable = not widget.get_active() self.diskStripeGraph.shutDown() @@ -1355,13 +1291,9 @@ class PartitionWindow(InstallWindow): def getScreen(self, anaconda): self.anaconda = anaconda - self.fsset = anaconda.id.fsset - self.diskset = anaconda.id.diskset + self.storage = anaconda.id.storage self.intf = anaconda.intf - self.diskset.openDevices() - self.partitions = anaconda.id.partitions - self.show_uneditable = 1 checkForSwapNoMatch(anaconda) @@ -1375,9 +1307,9 @@ class PartitionWindow(InstallWindow): buttonBox.set_layout(gtk.BUTTONBOX_SPREAD) ops = ((_("Ne_w"), self.newCB), - (_("_Edit"), self.editCb), - (_("_Delete"), self.deleteCb), - (_("Re_set"), self.resetCb), + (_("_Edit"), self.editCB), + (_("_Delete"), self.deleteCB), + (_("Re_set"), self.resetCB), (_("R_AID"), self.makeraidCB), (_("_LVM"), self.makeLvmCB)) @@ -1388,12 +1320,12 @@ class PartitionWindow(InstallWindow): self.tree = DiskTreeModel() self.treeView = self.tree.getTreeView() - self.treeView.connect('row-activated', self.treeActivateCb) + self.treeView.connect('row-activated', self.treeActivateCB) self.treeViewSelection = self.treeView.get_selection() - self.treeViewSelection.connect("changed", self.treeSelectCb) + self.treeViewSelection.connect("changed", self.treeSelectCB) # set up the canvas - self.diskStripeGraph = DiskStripeGraph(self.tree, self.editCb) + self.diskStripeGraph = DiskStripeGraph(self.tree, self.editCB) # do the initial population of the tree and the graph self.populate(initial = 1) diff --git a/iw/partition_ui_helpers_gui.py b/iw/partition_ui_helpers_gui.py index 5697d2b1a..b8cae4a6b 100644 --- a/iw/partition_ui_helpers_gui.py +++ b/iw/partition_ui_helpers_gui.py @@ -28,10 +28,9 @@ import datacombo import iutil from constants import * -from fsset import * from partIntfHelpers import * -from partRequests import * from partedUtils import * +from storage.formats import * import gettext _ = lambda x: gettext.ldgettext("anaconda", x) @@ -72,27 +71,37 @@ def createAlignedLabel(text): return label +defaultMountPoints = ['/', '/boot', '/home', '/tmp', '/usr', + '/var', '/usr/local', '/opt'] + +if iutil.isS390(): + # Many s390 have 2G DASDs, we recomment putting /usr/share on its own DASD + defaultMountPoints.insert(5, '/usr/share') + +if iutil.isEfi(): + defaultMountPoints.insert(2, '/boot/efi') + def createMountPointCombo(request, excludeMountPoints=[]): mountCombo = gtk.combo_box_entry_new_text() mntptlist = [] - - if request.type != REQUEST_NEW and request.fslabel: - mntptlist.append(request.fslabel) + label = getattr(request.format, "label", None) + if request.exists and label and label.startswith("/"): + mntptlist.append(label) idx = 0 - + for p in defaultMountPoints: - if p in excludeMountPoints: - continue - - if not p in mntptlist and (p[0] == "/"): - mntptlist.append(p) + if p in excludeMountPoints: + continue - map(mountCombo.append_text, mntptlist) + if not p in mntptlist and (p[0] == "/"): + mntptlist.append(p) - mountpoint = request.mountpoint + map(mountCombo.append_text, mntptlist) - if request.fstype and request.fstype.isMountable(): + if (request.format.type or request.format.migrate) and \ + request.format.mountable: + mountpoint = request.format.mountpoint mountCombo.set_sensitive(1) if mountpoint: mountCombo.get_children()[0].set_text(mountpoint) @@ -106,14 +115,15 @@ def createMountPointCombo(request, excludeMountPoints=[]): return mountCombo -def setMntPtComboStateFromType(fstype, mountCombo): +def setMntPtComboStateFromType(fmt_class, mountCombo): prevmountable = mountCombo.get_data("prevmountable") mountpoint = mountCombo.get_data("saved_mntpt") - if prevmountable and fstype.isMountable(): + format = fmt_class() + if prevmountable and format.mountable: return - if fstype.isMountable(): + if format.mountable: mountCombo.set_sensitive(1) if mountpoint != None: mountCombo.get_children()[0].set_text(mountpoint) @@ -125,7 +135,7 @@ def setMntPtComboStateFromType(fstype, mountCombo): mountCombo.get_children()[0].set_text(_("<Not Applicable>")) mountCombo.set_sensitive(0) - mountCombo.set_data("prevmountable", fstype.isMountable()) + mountCombo.set_data("prevmountable", format.mountable) def fstypechangeCB(widget, mountCombo): fstype = widget.get_active_value() @@ -134,24 +144,25 @@ def fstypechangeCB(widget, mountCombo): def createAllowedDrivesStore(disks, reqdrives, drivelist, selectDrives=True, disallowDrives=[]): drivelist.clear() - drives = disks.keys() - drives.sort() - for drive in drives: - size = disks[drive].device.getSize(unit="MB") + for disk in disks: selected = 0 if selectDrives: if reqdrives: - if drive in reqdrives: + if disk.name in reqdrives: selected = 1 else: - if drive not in disallowDrives: + if disk.name not in disallowDrives: selected = 1 - sizestr = "%8.0f MB" % size - drivelist.append_row((drive, sizestr, disks[drive].device.model), selected) + sizestr = "%8.0f MB" % disk.size + # TODO: abstract disk model so we don't have to reach into parted.Disk + drivelist.append_row((disk.name, + sizestr, + disk.partedDisk.device.model), + selected) - if len(disks.keys()) < 2: + if len(disks) < 2: drivelist.set_sensitive(False) else: drivelist.set_sensitive(True) @@ -170,36 +181,38 @@ def createAllowedDrivesList(disks, reqdrives, selectDrives=True, disallowDrives= # pass in callback for when fs changes because of python scope issues -def createFSTypeMenu(fstype, fstypechangeCB, mountCombo, +def createFSTypeMenu(format, fstypechangeCB, mountCombo, availablefstypes = None, ignorefs = None): store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT) fstypecombo = datacombo.DataComboBox(store) - types = fileSystemTypeGetTypes() if availablefstypes: names = availablefstypes else: - names = types.keys() - if fstype and fstype.isSupported() and fstype.isFormattable(): - default = fstype + names = device_formats.keys() + if format and format.supported and format.formattable: + default = format.name else: - default = fileSystemTypeGetDefault() + default = get_default_filesystem_type() names.sort() defindex = 0 i = 0 for name in names: - if not fileSystemTypeGet(name).isSupported(): + # we could avoid instantiating them all if we made a static class + # method that does what the supported property does + format = device_formats[name]() + if not format.supported: continue if ignorefs and name in ignorefs: continue - if fileSystemTypeGet(name).isFormattable(): - fstypecombo.append(name, types[name]) - if default and default.getName() == name: + if format.formattable: + fstypecombo.append(format.name, device_formats[name]) + if default == name: defindex = i - defismountable = types[name].isMountable() + defismountable = format.mountable i = i + 1 fstypecombo.set_active(defindex) @@ -209,7 +222,7 @@ def createFSTypeMenu(fstype, fstypechangeCB, mountCombo, if mountCombo: mountCombo.set_data("prevmountable", - fstypecombo.get_active_value().isMountable()) + fstypecombo.get_active_value()().mountable) mountCombo.connect("changed", mountptchangeCB, fstypecombo) return fstypecombo @@ -218,7 +231,7 @@ def mountptchangeCB(widget, fstypecombo): if iutil.isEfi() and widget.get_children()[0].get_text() == "/boot/efi": fstypecombo.set_active_text("efi") if widget.get_children()[0].get_text() == "/boot": - fstypecombo.set_active_text(fileSystemTypeGetDefaultBoot().getName()) + fstypecombo.set_active_text(get_default_filesystem_type(boot=True)) def resizeOptionCB(widget, resizesb): resizesb.set_sensitive(widget.get_active()) @@ -236,9 +249,21 @@ def formatOptionResizeCB(widget, resizesb): if resizesb.get_value_as_int() < lower: resizesb.set_value(adj.lower) -def formatOptionCB(widget, data): - (combowidget, mntptcombo, ofstype, lukscb) = data +def formatMigrateOptionCB(widget, data): + (sensitive,) = widget.get_properties('sensitive') + if not sensitive: + return + + (combowidget, mntptcombo, ofstype, lukscb, othercombo, othercb) = data combowidget.set_sensitive(widget.get_active()) + + if othercb is not None: + othercb.set_sensitive(not widget.get_active()) + othercb.set_active(False) + + if othercombo is not None: + othercombo.set_sensitive(not widget.get_active()) + if lukscb is not None: lukscb.set_data("formatstate", widget.get_active()) if not widget.get_active(): @@ -250,11 +275,14 @@ def formatOptionCB(widget, data): # inject event for fstype menu if widget.get_active(): - fstype = combowidget.get_active_value() - setMntPtComboStateFromType(fstype, mntptcombo) + fstype = combowidget.get_active_value() + setMntPtComboStateFromType(fstype, mntptcombo) combowidget.grab_focus() else: - setMntPtComboStateFromType(ofstype, mntptcombo) + if isinstance(ofstype, type(ofstype)): + ofstype = type(ofstype) + + setMntPtComboStateFromType(ofstype, mntptcombo) def noformatCB(widget, data): (combowidget, mntptcombo, ofstype) = data @@ -262,7 +290,7 @@ def noformatCB(widget, data): # inject event for fstype menu if widget.get_active(): - setMntPtComboStateFromType(ofstype, mntptcombo) + setMntPtComboStateFromType(ofstype, mntptcombo) """ createPreExistFSOptionSection: given inputs for a preexisting partition, @@ -282,11 +310,11 @@ def noformatCB(widget, data): def createPreExistFSOptionSection(origrequest, maintable, row, mountCombo, partitions, ignorefs=[]): rc = {} - ofstype = origrequest.fstype + ofstype = origrequest.format formatcb = gtk.CheckButton(label=_("_Format as:")) maintable.attach(formatcb, 0, 1, row, row + 1) - formatcb.set_active(istruefalse(origrequest.format)) + formatcb.set_active(istruefalse(not origrequest.format.exists)) rc["formatcb"] = formatcb fstypeCombo = createFSTypeMenu(ofstype, fstypechangeCB, @@ -296,39 +324,41 @@ def createPreExistFSOptionSection(origrequest, maintable, row, mountCombo, row += 1 rc["fstypeCombo"] = fstypeCombo - if not formatcb.get_active() and not origrequest.migrate: - mountCombo.set_data("prevmountable", ofstype.isMountable()) + if not formatcb.get_active() and not origrequest.format.migrate: + mountCombo.set_data("prevmountable", origrequest.format.mountable) # this gets added to the table a bit later on lukscb = gtk.CheckButton(_("_Encrypt")) - formatcb.connect("toggled", formatOptionCB, - (fstypeCombo, mountCombo, ofstype, lukscb)) - - - if origrequest.origfstype.isMigratable(): + if origrequest.format.migratable: migratecb = gtk.CheckButton(label=_("Mi_grate filesystem to:")) - migratecb.set_active(istruefalse(origrequest.migrate)) + migratecb.set_active(istruefalse(origrequest.format.migrate)) - migtypes = origrequest.origfstype.getMigratableFSTargets() + migtypes = [origrequest.format.migrationTarget] maintable.attach(migratecb, 0, 1, row, row + 1) - migfstypeCombo = createFSTypeMenu(ofstype, None, None, + migfstypeCombo = createFSTypeMenu(ofstype, + None, None, availablefstypes = migtypes) migfstypeCombo.set_sensitive(migratecb.get_active()) maintable.attach(migfstypeCombo, 1, 2, row, row + 1) row = row + 1 rc["migratecb"] = migratecb rc["migfstypeCombo"] = migfstypeCombo - migratecb.connect("toggled", formatOptionCB, - (migfstypeCombo, mountCombo, ofstype, None)) + migratecb.connect("toggled", formatMigrateOptionCB, + (migfstypeCombo, mountCombo, ofstype, None, + fstypeCombo, formatcb)) else: migratecb = None migfstypeCombo = None - if origrequest.isResizable(partitions): + formatcb.connect("toggled", formatMigrateOptionCB, + (fstypeCombo, mountCombo, ofstype, lukscb, + migfstypeCombo, migratecb)) + + if origrequest.resizable: resizecb = gtk.CheckButton(label=_("_Resize")) - resizecb.set_active(origrequest.targetSize is not None) + resizecb.set_active(origrequest.targetSize != origrequest.currentSize) rc["resizecb"] = resizecb maintable.attach(resizecb, 0, 1, row, row + 1) @@ -337,9 +367,9 @@ def createPreExistFSOptionSection(origrequest, maintable, row, mountCombo, else: value = origrequest.size - reqlower = origrequest.getMinimumResizeMB(partitions) - requpper = origrequest.getMaximumResizeMB(partitions) - if not origrequest.format: + reqlower = origrequest.minSize + requpper = origrequest.maxSize + if origrequest.format.exists: lower = reqlower else: lower = 1 @@ -357,7 +387,7 @@ def createPreExistFSOptionSection(origrequest, maintable, row, mountCombo, formatcb.connect("toggled", formatOptionResizeCB, resizesb) - if origrequest.encryption: + if origrequest.format.type == "luks": lukscb.set_active(1) lukscb.set_data("encrypted", 1) else: @@ -372,17 +402,17 @@ def createPreExistFSOptionSection(origrequest, maintable, row, mountCombo, return (row, rc) # do tests we just want in UI for now, not kickstart -def doUIRAIDLVMChecks(request, diskset): - fstype = request.fstype - numdrives = len(diskset.disks.keys()) +def doUIRAIDLVMChecks(request, storage): + fstype = request.format.name + numdrives = len(storage.disks) ## if fstype and fstype.getName() == "physical volume (LVM)": ## if request.grow: ## return (_("Partitions of type '%s' must be of fixed size, and " ## "cannot be marked to fill to use available space.")) % (fstype.getName(),) - if fstype and fstype.getName() in ["physical volume (LVM)", "software RAID"]: - if numdrives > 1 and (request.drive is None or len(request.drive) > 1): + if fstype in ["physical volume (LVM)", "software RAID"]: + if numdrives > 1 and (not request.req_disks or len(request.disks) > 1): return (_("Partitions of type '%s' must be constrained to " "a single drive. To do this, select the " "drive in the 'Allowable Drives' checklist.")) % (fstype.getName(),) diff --git a/iw/raid_dialog_gui.py b/iw/raid_dialog_gui.py index 21cb2bcb8..c9d99a24c 100644 --- a/iw/raid_dialog_gui.py +++ b/iw/raid_dialog_gui.py @@ -28,10 +28,9 @@ import gtk import datacombo import gui -from fsset import * -from raid import availRaidLevels -from cryptodev import LUKSDevice -from partRequests import * +from storage.devicelibs import mdraid +from storage.devices import * +from storage.deviceaction import * from partition_ui_helpers_gui import * from constants import * @@ -56,18 +55,17 @@ class RaidEditor: tempDevList = [] if not self.isNew: # We need this list if we are editing. - for id in reqraidpart: - tempDevList.append(self.partitions.getRequestByID(id).device) + for dev in reqraidpart: + tempDevList.append(dev) partrow = 0 - for part, size, used in allraidparts: - partname = "%s" % part - partsize = "%8.0f MB" % size + for part in allraidparts: + partname = "%s" % part.name + partsize = "%8.0f MB" % part.size if self.isNew: partlist.append_row((partname, partsize), False) else: - # Ask self.partitions what devices to list as selected. if part in tempDevList: #list the partition and put it as selected partlist.append_row((partname, partsize), True) @@ -117,7 +115,7 @@ class RaidEditor: numparts = sparesb.get_data("numparts") maxspares = raid.get_raid_max_spares(raidlevel, numparts) - if maxspares > 0 and raidlevel != "RAID0": + if maxspares > 0 and raidlevel != "raid0": adj = sparesb.get_adjustment() value = adj.value if adj.value > maxspares: @@ -135,7 +133,7 @@ class RaidEditor: def run(self): if self.dialog is None: - return None + return [] while 1: rc = self.dialog.run() @@ -143,23 +141,12 @@ class RaidEditor: # user hit cancel, do nothing if rc == 2: self.destroy() - return None - - # read out UI into a partition specification - request = copy.copy(self.origrequest) - request.encryption = copy.deepcopy(self.origrequest.encryption) - - # doesn't make sense for RAID device - if not self.origrequest.getPreExisting(): - filesystem = self.fstypeCombo.get_active_value() - request.fstype = filesystem - - if request.fstype.isMountable(): - request.mountpoint = self.mountCombo.get_children()[0].get_text() - else: - request.mountpoint = None + return [] + actions = [] + luksdev = None raidmembers = [] + migrate = None model = self.raidlist.get_model() iter = model.get_iter_first() while iter: @@ -167,82 +154,113 @@ class RaidEditor: part = model.get_value(iter, 1) if val: - req = self.partitions.getRequestByDeviceName(part) - raidmembers.append(req.uniqueID) + dev = self.storage.devicetree.getDeviceByName(part) + raidmembers.append(dev) iter = model.iter_next(iter) - if not self.origrequest.getPreExisting(): - request.raidminor = int(self.minorCombo.get_active_value()) + if not self.origrequest.exists: + # new device + fmt_class = self.fstypeCombo.get_active_value() + mountpoint = self.mountCombo.get_children()[0].get_text() + raidminor = int(self.minorCombo.get_active_value()) - request.raidmembers = raidmembers model = self.levelcombo.get_model() - request.raidlevel = model[self.levelcombo.get_active()][0] + raidlevel = model[self.levelcombo.get_active()][0] - if request.raidlevel != "RAID0": + if raidlevel != "RAID0": self.sparesb.update() - request.raidspares = self.sparesb.get_value_as_int() + spares = self.sparesb.get_value_as_int() else: - request.raidspares = 0 + spares = 0 + + format = fmt_class(mountpoint=mountpoint) + if self.fsoptionsDict.has_key("lukscb") and \ + self.fsoptionsDict["lukscb"].get_active() and \ + self.origrequest.format.type != "luks": + luksdev = LUKSDevice("luks-%s" % self.origrequest.name, + format=format, + parents=self.origrequest) + format = getFormat("luks", + passphrase=self.storage.encryptionPassphrase) + elif self.fsoptionsDict.has_key("lukscb") and \ + not self.fsoptionsDict["lukscb"].get_active() and \ + self.origrequest.format.type == "luks": + # destroy luks format and mapped device + luksdev = self.storage.devicetree.getChildren(self.origrequest)[0] + if luksdev: + actions.append(ActionDestroyFormat(luksdev.format)) + actions.append(ActionDestroyDevice(luksdev)) + luksdev = None + actions.append(ActionDestroyFormat(self.origrequest)) - if self.formatButton: - request.format = self.formatButton.get_active() - else: - request.format = 0 - - if self.lukscb and self.lukscb.get_active(): - if not request.encryption: - request.encryption = LUKSDevice(passphrase=self.partitions.encryptionPassphrase, format=1) - else: - request.encryption = None else: - if self.fsoptionsDict.has_key("formatcb"): - request.format = self.fsoptionsDict["formatcb"].get_active() - if request.format: - request.fsystem = self.fsoptionsDict["fstypeCombo"].get_active_value() - else: - request.format = 0 - - if self.fsoptionsDict.has_key("migratecb"): - request.migrate = self.fsoptionsDict["migratecb"].get_active() - if request.migrate: - request.fsystem = self.fsoptionsDict["migfstypeCombo"].get_active_value() - else: - request.migrate = 0 - - # set back if we are not formatting or migrating - origfstype = self.origrequest.origfstype - if not request.format and not request.migrate: - request.fstype = origfstype - - if request.fstype.isMountable(): - request.mountpoint = self.mountCombo.get_children()[0].get_text() - else: - request.mountpoint = None - - lukscb = self.fsoptionsDict.get("lukscb") - if lukscb and lukscb.get_active(): - if not request.encryption: - request.encryption = LUKSDevice(passphrase=self.partitions.encryptionPassphrase, format=1) - else: - request.encryption = None - - err = request.sanityCheckRequest(self.partitions) - if err: - self.intf.messageWindow(_("Error With Request"), - "%s" % (err), custom_icon="error") - continue - - if (not request.format and - request.mountpoint and request.formatByDefault()): + # existing device + fmt_class = self.fsoptionsDict["fstypeCombo"].get_active_value() + mountpoint = self.mountCombo.get_children()[0].get_text() + if self.fsoptionsDict.has_key("formatcb") and \ + self.fsoptionsDict["formatcb"].get_active(): + format = fmt_class(mountpoint=mountpoint) + if self.fsoptionsDict.has_key("lukscb") and \ + self.fsoptionsDict["lukscb"].get_active() and \ + self.origrequest.format.type != "luks": + luksdev = LUKSDevice("luks-%s" % self.origrequest.name, + format=format, + parents=self.origrequest) + format = getFormat("luks", + device=self.origrequest.path, + passphrase=self.storage.encryptionPassphrase) + elif self.fsoptionsDict.has_key("lukscb") and \ + not self.fsoptionsDict["lukscb"].get_active() and \ + self.origrequest.format.type == "luks": + # destroy luks format and mapped device + luksdev = self.storage.devicetree.getChildren(self.origrequest)[0] + if luksdev: + actions.append(ActionDestroyFormat(luksdev.format)) + actions.append(ActionDestroyDevice(luksdev)) + luksdev = None + actions.append(ActionDestroyFormat(self.origrequest)) + elif self.origrequest.format.mountable: + self.origrequest.format.mountpoint = mountpoint + + if self.fsoptionsDict.has_key("migratecb") and \ + self.fsoptionsDict["migratecb"].get_active(): + if origrequest.format.type == "luks": + usedev = self.storage.devicetree.getChildren(origrequest)[0] + else: + usedev = origrequest + migrate = True + + if self.origrequest.format.exists and \ + self.storage.formatByDefault(self.origrequest): if not queryNoFormatPreExisting(self.intf): continue # everything ok, break out break + if not self.origrequest.exists: + members = len(raidmembers) - spares + level = int(raidlevel.lower().replace("raid", "")) + request = self.storage.newMDArray(minor=raidminor, + level=level, + format=format, + parents=raidmembers, + memberDevices=members) + actions.append(ActionCreateDevice(request)) + actions.append(ActionCreateFormat(request)) + elif format: + actions.append(ActionCreateFormat(self.origreqest, format)) + + + if luksdev: + actions.append(ActionCreateDevice(luksdev)) + actions.append(ActionCreateFormat(luksdev)) - return request + if migrate: + actions.append(ActionMigrateFormat(usedev)) + + return actions def destroy(self): if self.dialog: @@ -250,9 +268,8 @@ class RaidEditor: self.dialog = None - def __init__(self, partitions, diskset, intf, parent, origrequest, isNew = 0): - self.partitions = partitions - self.diskset = diskset + def __init__(self, storage, intf, parent, origrequest, isNew = 0): + self.storage = storage self.origrequest = origrequest self.isNew = isNew self.intf = intf @@ -263,8 +280,8 @@ class RaidEditor: # # start of editRaidRequest # - availraidparts = self.partitions.getAvailRaidPartitions(origrequest, - self.diskset) + availraidparts = self.storage.unusedMDMembers(array=self.origrequest) + # if no raid partitions exist, raise an error message and return if len(availraidparts) < 2: dlg = gtk.MessageDialog(self.parent, 0, gtk.MESSAGE_ERROR, @@ -285,9 +302,9 @@ class RaidEditor: if isNew: tstr = _("Make RAID Device") else: - try: - tstr = _("Edit RAID Device: /dev/md%s") % (origrequest.raidminor,) - except: + if origrequest.minor is not None: + tstr = _("Edit RAID Device: %s") % (origrequest.path,) + else: tstr = _("Edit RAID Device") dialog = gtk.Dialog(tstr, self.parent) @@ -313,11 +330,18 @@ class RaidEditor: self.lukscb = gtk.CheckButton(_("_Encrypt")) self.lukscb.set_data("formatstate", 1) + if origrequest.format.type == "luks": + usedev = self.storage.devicetree.getChildren(origrequest)[0] + format = usedev.format + else: + usedev = origrequest + format = origrequest.format + # Filesystem Type - if not origrequest.getPreExisting(): + if not origrequest.exists: lbl = createAlignedLabel(_("_File System Type:")) maintable.attach(lbl, 0, 1, row, row + 1) - self.fstypeCombo = createFSTypeMenu(origrequest.fstype, + self.fstypeCombo = createFSTypeMenu(format, fstypechangeCB, self.mountCombo, ignorefs = ["software RAID", "efi", "PPC PReP Boot", "Apple Bootstrap"]) @@ -327,29 +351,29 @@ class RaidEditor: else: maintable.attach(createAlignedLabel(_("Original File System Type:")), 0, 1, row, row + 1) - if origrequest.fstype.getName(): - self.fstypeCombo = gtk.Label(origrequest.fstype.getName()) + if format.type: + self.fstypeCombo = gtk.Label(format.name) else: self.fstypeCombo = gtk.Label(_("Unknown")) maintable.attach(self.fstypeCombo, 1, 2, row, row + 1) row += 1 - if origrequest.fslabel: + if getattr(format, "label", None): maintable.attach(createAlignedLabel(_("Original File System " "Label:")), 0, 1, row, row + 1) - maintable.attach(gtk.Label(origrequest.fslabel), 1, 2, row, - row + 1) + maintable.attach(gtk.Label(format.label), + 1, 2, row, row + 1) row += 1 # raid minors lbl = createAlignedLabel(_("RAID _Device:")) maintable.attach(lbl, 0, 1, row, row + 1) - if not origrequest.getPreExisting(): - availminors = self.partitions.getAvailableRaidMinors()[:16] - reqminor = origrequest.raidminor + if not origrequest.exists: + availminors = self.storage.unusedMDMinors[:16] + reqminor = origrequest.minor if reqminor is not None: availminors.append(reqminor) @@ -357,7 +381,7 @@ class RaidEditor: self.minorCombo = self.createRaidMinorMenu(availminors, reqminor) lbl.set_mnemonic_widget(self.minorCombo) else: - self.minorCombo = gtk.Label("md%s" %(origrequest.raidminor,)) + self.minorCombo = gtk.Label("%s" %(origrequest.name,)) maintable.attach(self.minorCombo, 1, 2, row, row + 1) row = row + 1 @@ -365,16 +389,17 @@ class RaidEditor: lbl = createAlignedLabel(_("RAID _Level:")) maintable.attach(lbl, 0, 1, row, row + 1) - if not origrequest.getPreExisting(): + if not origrequest.exists: # Create here, pack below numparts = len(availraidparts) - if origrequest.raidspares: - nspares = origrequest.raidspares + if origrequest.spares: + nspares = origrequest.spares else: nspares = 0 - if origrequest.raidlevel: - maxspares = raid.get_raid_max_spares(origrequest.raidlevel, numparts) + if origrequest.level: + maxspares = raid.get_raid_max_spares(origrequest.level, + numparts) else: maxspares = 0 @@ -389,15 +414,15 @@ class RaidEditor: self.sparesb.set_value(0) self.sparesb.set_sensitive(0) else: - self.sparesb = gtk.Label(str(origrequest.raidspares)) + self.sparesb = gtk.Label(str(origrequest.spares)) - if not origrequest.getPreExisting(): - self.levelcombo = self.createRaidLevelMenu(availRaidLevels, - origrequest.raidlevel) + if not origrequest.exists: + self.levelcombo = self.createRaidLevelMenu(mdraid.raid_levels, + origrequest.level) lbl.set_mnemonic_widget(self.levelcombo) else: - self.levelcombo = gtk.Label(origrequest.raidlevel) + self.levelcombo = gtk.Label(origrequest.level) maintable.attach(self.levelcombo, 1, 2, row, row + 1) row = row + 1 @@ -408,15 +433,15 @@ class RaidEditor: # XXX need to pass in currently used partitions for this device (self.raidlist, sw) = self.createAllowedRaidPartitionsList(availraidparts, - origrequest.raidmembers, - origrequest.getPreExisting()) + origrequest.devices, + origrequest.exists) lbl.set_mnemonic_widget(self.raidlist) self.raidlist.set_size_request(275, 80) maintable.attach(sw, 1, 2, row, row + 1) row = row + 1 - if origrequest.getPreExisting(): + if origrequest.exists: self.raidlist.set_sensitive(False) # number of spares - created widget above @@ -429,26 +454,26 @@ class RaidEditor: # format or not? self.formatButton = None self.fsoptionsDict = {} - if (origrequest.fstype and origrequest.fstype.isFormattable()) and not origrequest.getPreExisting(): + if not format.exists: self.formatButton = gtk.CheckButton(_("_Format partition?")) - if origrequest.format == None or origrequest.format != 0: + if not format.type: self.formatButton.set_active(1) else: self.formatButton.set_active(0) # it only makes sense to show this for preexisting RAID - if origrequest.getPreExisting(): + if origrequest.exists: maintable.attach(self.formatButton, 0, 2, row, row + 1) row = row + 1 # checkbutton for encryption using dm-crypt/LUKS - if self.origrequest.encryption: + if origrequest.format.type == "luks": self.lukscb.set_active(1) else: self.lukscb.set_active(0) maintable.attach(self.lukscb, 0, 2, row, row + 1) row = row + 1 else: - (row, self.fsoptionsDict) = createPreExistFSOptionSection(self.origrequest, maintable, row, self.mountCombo, self.partitions) + (row, self.fsoptionsDict) = createPreExistFSOptionSection(usedev, maintable, row, self.mountCombo, self.storage) # put main table into dialog dialog.vbox.pack_start(maintable) @@ -460,7 +485,7 @@ class RaidEditor: class RaidCloneDialog: - def createDriveList(self, diskset): + def createDriveList(self, disks): store = gtk.ListStore(gobject.TYPE_STRING) view = gtk.TreeView(store) @@ -470,12 +495,9 @@ class RaidCloneDialog: sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) sw.set_shadow_type(gtk.SHADOW_IN) - drives = diskset.disks.keys() - drives.sort() - - for drive in drives: + for disk in disks: iter = store.append() - store.set_value(iter, 0, drive) + store.set_value(iter, 0, disk.name) view.set_property("headers-visible", False) @@ -485,27 +507,18 @@ class RaidCloneDialog: return (sw, view) def getInterestingRequestsForDrive(self, drive): - allrequests = self.partitions.getRequestsByDevice(self.diskset, drive) + disk = self.storage.devicetree.getDeviceByName(drive) + allrequests = self.storage.getDependentDevices(disk) - if allrequests is None or len(allrequests) == 0: + if not allrequests: return allrequests # remove extended partitions requests = [] for req in allrequests: - try: - part = parted.getPartitionByName(req.device) - except: - part = None - - if part: - if part.type & parted.PARTITION_EXTENDED: - continue - elif part.type & parted.PARTITION_FREESPACE: - continue - elif part.type & parted.PARTITION_METADATA: - continue - else: + if req.type == "partition" and req.isExtended: + continue + elif req.type != "partition": continue requests.append(req) @@ -525,7 +538,7 @@ class RaidCloneDialog: return 1 for req in requests: - if not req.fstype or req.fstype.getName() != "software RAID": + if req.format.type != "mdmember": self.intf.messageWindow(_("Source Drive Error"), _("The source drive you selected has " "partitions which are not of " @@ -536,21 +549,23 @@ class RaidCloneDialog: custom_icon="error") return 1 + sourceDev = self.storage.devicetree.getDeviceByName(self.sourceDrive) for req in requests: - if not req.drive or req.drive[0] != self.sourceDrive or len(req.drive) > 1: + if not req.req_disks or len(req.req_disks) > 1 or \ + req.req_disks[0] != self.sourceDrive: self.intf.messageWindow(_("Source Drive Error"), _("The source drive you selected has " "partitions which are not " - "constrained to the drive /dev/%s.\n\n" + "constrained to the drive %s.\n\n" "You must remove these partitions " "or restrict them to this " "drive " "before this drive can be cloned. ") - %(self.sourceDrive,), custom_icon="error") + %(sourceDev.path,), custom_icon="error") return 1 for req in requests: - if self.partitions.isRaidMember(req): + if req not in self.storage.unusedMDMembers(): self.intf.messageWindow(_("Source Drive Error"), _("The source drive you selected has " "software RAID partition(s) which " @@ -564,6 +579,7 @@ class RaidCloneDialog: return 0 def sanityCheckTargetDrives(self): + sourceDev = self.storage.devicetree.getDeviceByName(self.sourceDrive) if self.targetDrives is None or len(self.targetDrives) < 1: self.intf.messageWindow(_("Target Drive Error"), _("Please select the target drives " @@ -572,8 +588,10 @@ class RaidCloneDialog: if self.sourceDrive in self.targetDrives: self.intf.messageWindow(_("Target Drive Error"), - _("The source drive /dev/%s cannot be " - "selected as a target drive as well.") % (self.sourceDrive,), custom_icon="error") + _("The source drive %s cannot be " + "selected as a target drive as well.") + % (self.sourceDev.path,), + custom_icon="error") return 1 for drive in self.targetDrives: @@ -581,24 +599,20 @@ class RaidCloneDialog: if requests is None: continue + targetDev = self.storage.devicetree.getDeviceByName(drive) for req in requests: - rc = partIntfHelpers.isNotChangable(req, self.partitions) - - # If the partition is protected, we also can't delete it so - # specify a reason why. - if rc is None and req.getProtected(): - rc = _("This partition is holding the data for the hard " - "drive install.") + rc = self.storage.deviceImmutable(req) if rc: self.intf.messageWindow(_("Target Drive Error"), - _("The target drive /dev/%s " + _("The target drive %s " "has a partition which cannot " "be removed for the following " "reason:\n\n\"%s\"\n\n" "You must remove this partition " "before " "this drive can be a target.") % - (drive, rc), custom_icon="error") + (targetDev.path, rc), + custom_icon="error") return 1 return 0 @@ -609,27 +623,28 @@ class RaidCloneDialog: requests = self.getInterestingRequestsForDrive(self.sourceDrive) # no requests to clone, bail out - if requests is None or len(requests) == 0: + if not requests: return 0 # now try to clear the target drives - for device in self.targetDrives: - rc = doDeletePartitionsByDevice(self.intf, self.partitions, - self.diskset, device, - confirm=0, quiet=1) + for devname in self.targetDrives: + device = self.storage.devicetree.getDeviceByName(devname) + doDeleteDependentDevices(self.intf, self.storage, + device, confirm=0, quiet=1) # now clone! for req in requests: for drive in self.targetDrives: - newreq = copy.copy(req) - newreq.drive = [drive] - newreq.uniqueID = None - newreq.device = None - newreq.preexist = 0 - newreq.dev = None - self.partitions.addRequest(newreq) + # this feels really dirty + device = self.storage.devicetree.getDeviceByName(drive) + newdev = copy.deepcopy(req) + newdev.req_disks = [device] + newdev.exists = False + newdev.format.exists = False + newdev.format.device = None + self.storage.createDevice(newdev) - return 0 + return def targetSelectFunc(self, model, path, iter): @@ -672,10 +687,10 @@ class RaidCloneDialog: continue # now give them last chance to bail - msgtxt = _("The drive /dev/%s will now be cloned to the " + msgtxt = _("The drive %s will now be cloned to the " "following drives:\n\n" % (self.sourceDrive,)) for drive in self.targetDrives: - msgtxt = msgtxt + "\t" + "/dev/%s" % (drive,) + msgtxt = msgtxt + "\t" + "%s" % (drive,) msgtxt = msgtxt + _("\n\nWARNING! ALL DATA ON THE TARGET DRIVES " "WILL BE DESTROYED.") @@ -708,9 +723,8 @@ class RaidCloneDialog: self.dialog = None - def __init__(self, partitions, diskset, intf, parent): - self.partitions = partitions - self.diskset = diskset + def __init__(self, storage, intf, parent): + self.storage = storage self.intf = intf self.parent = parent @@ -748,7 +762,7 @@ class RaidCloneDialog: lbl = gtk.Label(_("Source Drive:")) lbl.set_alignment(0.0, 0.0) box.pack_start(lbl, padding=5) - (sw, self.sourceView) = self.createDriveList(diskset) + (sw, self.sourceView) = self.createDriveList(storage.disks) selection = self.sourceView.get_selection() selection.set_mode(gtk.SELECTION_SINGLE) box.pack_start(sw) @@ -756,7 +770,7 @@ class RaidCloneDialog: lbl = gtk.Label(_("Target Drive(s):")) lbl.set_alignment(0.0, 0.0) box.pack_start(lbl, padding=5) - (sw, self.targetView) = self.createDriveList(diskset) + (sw, self.targetView) = self.createDriveList(storage.disks) selection = self.targetView.get_selection() selection.set_mode(gtk.SELECTION_MULTIPLE) box.pack_start(sw) diff --git a/iw/timezone_gui.py b/iw/timezone_gui.py index 2b6290901..27657a946 100644 --- a/iw/timezone_gui.py +++ b/iw/timezone_gui.py @@ -29,7 +29,7 @@ import sys from timezone_map_gui import TimezoneMap, Enum from iw_gui import * -from bootloaderInfo import dosFilesystems +from booty.bootloaderInfo import dosFilesystems from bootloader import hasWindows from constants import * diff --git a/iw/upgrade_migratefs_gui.py b/iw/upgrade_migratefs_gui.py index bd683b68e..d71e3d8bc 100644 --- a/iw/upgrade_migratefs_gui.py +++ b/iw/upgrade_migratefs_gui.py @@ -24,7 +24,6 @@ from constants import * import string import isys import iutil -from fsset import * import gtk import gettext @@ -34,28 +33,30 @@ class UpgradeMigrateFSWindow (InstallWindow): windowTitle = N_("Migrate File Systems") def getNext (self): - for entry in self.migent: - entry.setFormat(0) - entry.setMigrate(0) - entry.fsystem = entry.origfsystem - + # I don't like this but I also don't see a better way right now for (cb, entry) in self.cbs: + action = self.devicetree.findActions(device=entry, + type="migrate") if cb.get_active(): - try: - newfs = entry.fsystem.migratetofs[0] - newfs = fileSystemTypeGet(newfs) - except Exception, e: - log.info("failed to get new filesystem type, defaulting to ext3: %s" %(e,)) - newfs = fileSystemTypeGet("ext3") - entry.setFileSystemType(newfs) - entry.setFormat(0) - entry.setMigrate(1) - + if action: + # the migrate action has already been scheduled + continue + + newfs = getFormat(entry.format.migrationTarget) + if not newfs: + log.warning("failed to get new filesystem type (%s)" + % entry.format.migrationTarget) + continue + action = ActionMigrateFormat(entry) + self.devicetree.registerAction(action) + elif action: + self.devicetree.cancelAction(action) + return None def getScreen (self, anaconda): - - self.fsset = anaconda.id.fsset + self.devicetree = anaconda.id.storage.devicetree + self.fsset = anaconda.id.storage.fsset self.migent = self.fsset.getMigratableEntries() box = gtk.VBox (False, 5) @@ -79,17 +80,16 @@ class UpgradeMigrateFSWindow (InstallWindow): self.cbs = [] for entry in self.migent: # don't allow the user to migrate /boot to ext4 (#439944) - if entry.mountpoint == "/boot" and entry.origfsystem.getName() == "ext3": + if (getattr(entry.format, "mountpoint", None) == "/boot" and + not entry.format.migrate and entry.format.type == "ext3"): continue - if entry.fsystem.getName() != entry.origfsystem.getName(): - migrating = 1 - else: - migrating = 0 - cb = gtk.CheckButton("/dev/%s - %s - %s" % (entry.device.getDevice(), - entry.origfsystem.getName(), - entry.mountpoint)) - cb.set_active(migrating) + cb = gtk.CheckButton("%s - %s - %s" % (entry.path, + entry.format.name, + getattr(entry.format, + "mountpoint", + None))) + cb.set_active(entry.format.migrate) cbox.pack_start(cb, False) self.cbs.append((cb, entry)) diff --git a/iw/upgrade_swap_gui.py b/iw/upgrade_swap_gui.py index 83e27c6dd..5197d9ea4 100644 --- a/iw/upgrade_swap_gui.py +++ b/iw/upgrade_swap_gui.py @@ -50,9 +50,8 @@ class UpgradeSwapWindow (InstallWindow): selection = self.view.get_selection() (model, iter) = selection.get_selected() if iter: - mnt = model.get_value(iter, 0) - part = model.get_value(iter, 1) - size = int(model.get_value(iter, 2)) + dev = model.get_value(iter, 0) + size = model.get_value(iter, 1) val = int(self.entry.get_text()) else: raise RuntimeError, "unknown value for upgrade swap location" @@ -67,7 +66,7 @@ class UpgradeSwapWindow (InstallWindow): else: if flags.setupFilesystems: - upgrade.createSwapFile(self.instPath, self.fsset, mnt, val) + self.fsset.createSwapFile(self.instPath, dev, val) self.dispatch.skipStep("addswap", 1) return None @@ -80,7 +79,7 @@ class UpgradeSwapWindow (InstallWindow): def getScreen (self, anaconda): self.neededSwap = 0 - self.fsset = anaconda.id.fsset + self.fsset = anaconda.id.storage.fsset self.instPath = anaconda.rootPath self.intf = anaconda.intf self.dispatch = anaconda.dispatch @@ -129,11 +128,10 @@ class UpgradeSwapWindow (InstallWindow): gobject.TYPE_STRING, gobject.TYPE_STRING) - for (mnt, part, size) in fsList: + for (dev, size) in fsList: iter = self.store.append() - self.store.set_value(iter, 0, mnt) - self.store.set_value(iter, 1, part) - self.store.set_value(iter, 2, str(size)) + self.store.set_value(iter, 0, dev) + self.store.set_value(iter, 1, str(size)) self.view=gtk.TreeView(self.store) label.set_mnemonic_widget(self.view) |