diff options
-rw-r--r-- | autopart.py | 27 | ||||
-rw-r--r-- | fsset.py | 79 | ||||
-rw-r--r-- | iw/partition_gui.py | 153 | ||||
-rw-r--r-- | packages.py | 1 | ||||
-rw-r--r-- | partitioning.py | 37 | ||||
-rw-r--r-- | text.py | 3 |
6 files changed, 260 insertions, 40 deletions
diff --git a/autopart.py b/autopart.py index 9b43c6f48..729502a98 100644 --- a/autopart.py +++ b/autopart.py @@ -27,6 +27,33 @@ CLEARPART_TYPE_LINUX = 1 CLEARPART_TYPE_ALL = 2 CLEARPART_TYPE_NONE = 3 + +# XXX hack but these are common strings to TUI and GUI +PARTMETHOD_TYPE_DESCR_TEXT = N_("Automatic Partitioning sets up your " + "partitioning based on your installation type. " + "You also " + "can customize the resulting partitions " + "to meet your needs.\n\n" + "The manual disk paritioning tool Disk Druid " + "allows you " + "to set up your partitions in an interactive " + "environment. You can set the filesystem " + "types, mount points, size and more in this " + "easy to use, powerful interface.\n\n" + "fdisk is the traditional, text based " + "partitioning tool offered by Red Hat. " + "Although it is not as easy to use, there are " + "cases where fdisk is preferred.") + +AUTOPART_DISK_CHOICE_DESCR_TEXT = N_("Before automatic partitioning can be " + "set up by the installation program, you " + "must choose how to use the space on " + "hard drives.") + +CLEARPART_TYPE_ALL_DESCR_TEXT = N_("Remove all partitions on this system") +CLEARPART_TYPE_LINUX_DESCR_TEXT = N_("Remove all Linux Partitions on this system") +CLEARPART_TYPE_NONE_DESCR_TEXT = N_("Keep all partitions and use existing free space") + def printNewRequestsCyl(diskset, newRequest): for req in newRequest.requests: if req.type != REQUEST_NEW: @@ -112,6 +112,7 @@ class FileSystemType: self.maxSize = 2 * 1024 * 1024 self.supported = -1 self.defaultOptions = "defaults" + self.migratetofs = None def mount(self, device, mountpoint, readOnly=0): if not self.isMountable(): @@ -133,6 +134,10 @@ class FileSystemType: if self.isFormattable(): raise RuntimeError, "formatDevice method not defined" + def migrateFileSystem(self, device): + if self.isMigratable(): + raise RuntimeError, "migrateFileSystem method not defined" + def isFormattable(self): return self.formattable @@ -185,6 +190,23 @@ class FileSystemType: def getDefaultOptions(self, mountpoint): return self.defaultOptions + def getMigratableFSTargets(self): + retval = [] + if not self.migratetofs: + return retval + + for fs in self.migratetofs: + if fileSystemTypeGet(fs).isSupported(): + retval.append(fs) + + return retval + + def isMigratable(self): + if len(self.getMigratableFSTargets()) > 0: + return 1 + else: + return 0 + class reiserfsFileSystem(FileSystemType): def __init__(self): FileSystemType.__init__(self) @@ -247,6 +269,27 @@ class ext2FileSystem(extFileSystem): extFileSystem.__init__(self) self.name = "ext2" self.partedFileSystemType = parted.file_system_type_get("ext2") + self.migratetofs = ['ext3'] + + + def migrateFileSystem(self, entry, progress, chroot='/'): + devicePath = entry.device.setupDevice(chroot) + + if not entry.fsystem or not entry.origfsystem: + raise RuntimeError, ("Trying to migrate fs w/o fsystem or " + "origfsystem set") + if entry.fsystem.getName() != "ext3": + raise RuntimeError, ("Trying to migrate ext2 to something other " + "than ext3") + + rc = iutil.execWithRedirect("/usr/sbin/tune2fs", + ["tunefs", "-j", devicePath ], + stdout = "/dev/tty5", + stderr = "/dev/tty5") + + if rc: + raise SystemError + fileSystemTypeRegister(ext2FileSystem()) @@ -583,6 +626,28 @@ class FileSystemSet: % (entry.device.getDevice(),)) sys.exit(0) + def migrateFilesystems (self, chroot='/'): + for entry in self.entries: + if not entry.origfsystem: + continue + + if (not entry.origfsystem.isMigratable() or not entry.getMigrate() + or entry.isMounted()): + continue + try: + entry.origfsystem.migrateFileSystem(entry, self.progressWindow, + chroot) + except SystemError: + if self.messageWindow: + self.messageWindow(_("Error"), + _("An error occurred trying to " + "migrate %s. This problem is " + "serious, and the install cannot " + "continue.\n\n" + "Press Enter to reboot your system.") + % (entry.device.getDevice(),)) + sys.exit(0) + def mountFilesystems(self, instPath = '/', raiseErrors = 0, readOnly = 0): for entry in self.entries: if not entry.fsystem.isMountable(): @@ -665,12 +730,15 @@ class FileSystemSet: class FileSystemSetEntry: def __init__ (self, device, mountpoint, fsystem=None, options=None, + origfsystem=None, migrate=0, order=-1, fsck=-1, format=0): if not fsystem: fsystem = fileSystemTypeGet("ext2") self.device = device self.mountpoint = mountpoint self.fsystem = fsystem + self.origfsystem = origfsystem + self.migrate = migrate if options: self.options = options else: @@ -708,11 +776,22 @@ class FileSystemSetEntry: self.mountcount = self.mountcount - 1 def setFormat (self, state): + if self.migrate: + raise ValueError, "Trying to set format bit on when migrate is set!" self.format = state def getFormat (self): return self.format + def setMigrate (self, state): + if self.format: + raise ValueError, "Trying to set migrate bit on when format is set!" + + self.migrate = state + + def getMigrate (self): + return self.migrate + def isMounted (self): return self.mountcount > 0 diff --git a/iw/partition_gui.py b/iw/partition_gui.py index ff5c25624..ed3a22767 100644 --- a/iw/partition_gui.py +++ b/iw/partition_gui.py @@ -22,6 +22,9 @@ from partitioning import * from fsset import * from autopart import doPartitioning from autopart import CLEARPART_TYPE_LINUX, CLEARPART_TYPE_ALL, CLEARPART_TYPE_NONE +from autopart import CLEARPART_TYPE_LINUX_DESCR_TEXT, CLEARPART_TYPE_ALL_DESCR_TEXT, CLEARPART_TYPE_NONE_DESCR_TEXT +from autopart import AUTOPART_DISK_CHOICE_DESCR_TEXT + import gui import parted import string @@ -385,11 +388,15 @@ def createRaidLevelMenu(levels, reqlevel, raidlevelchangeCB, sparesb): return (leveloption, leveloptionmenu) # pass in callback for when fs changes because of python scope issues -def createFSTypeMenu(fstype, fstypechangeCB, mountCombo): +def createFSTypeMenu(fstype, fstypechangeCB, mountCombo, availablefstypes=None): fstypeoption = GtkOptionMenu () fstypeoptionMenu = GtkMenu () types = fileSystemTypeGetTypes() - names = types.keys() + if availablefstypes: + names = availablefstypes + else: + names = types.keys() + names.sort() defindex = None i = 0 @@ -413,7 +420,9 @@ def createFSTypeMenu(fstype, fstypechangeCB, mountCombo): if defindex: fstypeoption.set_history(defindex) - mountCombo.set_data("prevmountable", fstypeoptionMenu.get_active().get_data("type").isMountable()) + if mountCombo: + mountCombo.set_data("prevmountable", + fstypeoptionMenu.get_active().get_data("type").isMountable()) return (fstypeoption, fstypeoptionMenu) @@ -595,6 +604,9 @@ class PartitionWindow(InstallWindow): # edit a partition request def editPartitionRequest(self, origrequest): + def formatOptionCB(widget, menu): + menu.set_sensitive(widget.get_active()) + def sizespinchangedCB(widget, fillmaxszsb): size = widget.get_value_as_int() maxsize = fillmaxszsb.get_value_as_int() @@ -678,17 +690,24 @@ class PartitionWindow(InstallWindow): row = row + 1 # Partition Type - maintable.attach(createAlignedLabel(_("Filesystem Type:")), + maintable.attach(createAlignedLabel(_("Original Filesystem Type:")), 0, 1, row, row + 1) if origrequest.type == REQUEST_NEW: - (fstypeoption, fstypeoptionMenu) = createFSTypeMenu(origrequest.fstype, fstypechangeCB, mountCombo) - maintable.attach(fstypeoption, 1, 2, row, row + 1) + (newfstype, newfstypeMenu) = createFSTypeMenu(origrequest.fstype, + fstypechangeCB, + mountCombo) + maintable.attach(newfstype, 1, 2, row, row + 1) else: - fstypelabel = GtkLabel(origrequest.fstype.getName()) + if origrequest.origfstype: + typestr = origrequest.origfstype.getName() + else: + typestr = _("Unknown") + + fstypelabel = GtkLabel(typestr) maintable.attach(fstypelabel, 1, 2, row, row + 1) - fstypeoption = None - fstypeoptionMenu = None + newfstype = None + newfstypeMenu = None row = row + 1 @@ -710,6 +729,7 @@ class PartitionWindow(InstallWindow): row = row + 1 + # size if origrequest.type == REQUEST_NEW: if not newbycyl: # Size specification @@ -756,16 +776,72 @@ class PartitionWindow(InstallWindow): row = row + 1 - if origrequest.type == REQUEST_PREEXIST: - if origrequest.fstype and origrequest.fstype.isFormattable(): - formatButton = GtkCheckButton (_("Format partition?")) - formatButton.set_active(0) + + # format/migrate options for pre-existing partitions + if origrequest.type == REQUEST_PREEXIST and origrequest.fstype: + + ofstype = origrequest.fstype + + maintable.attach(GtkHSeparator(), 0, 2, row, row + 1) + row = row + 1 + + label = GtkLabel(_("How would you like to prepare the filesystem " + "on this partition?")) + label.set_line_wrap(1) + label.set_alignment(0.0, 0.0) + label.set_usize(400, -1) + + maintable.attach(label, 0, 2, row, row + 1) + row = row + 1 + + noformatrb = GtkRadioButton (label=_("Do not format")) + noformatrb.set_active(1) + maintable.attach(noformatrb, 0, 2, row, row + 1) + row = row + 1 + + if ofstype.isFormattable(): + formatrb = GtkRadioButton (label=_("Format partition as:"), + group = noformatrb) + formatrb.set_active(0) if origrequest.format: - formatButton.set_active(1) - maintable.attach(formatButton, 0, 2, row, row + 1) + formatrb.set_active(1) + + maintable.attach(formatrb, 0, 1, row, row + 1) + (fstype, fstypeMenu) = createFSTypeMenu(ofstype,fstypechangeCB, + mountCombo) + fstype.set_sensitive(formatrb.get_active()) + maintable.attach(fstype, 1, 2, row, row + 1) row = row + 1 + + formatrb.connect("toggled", formatOptionCB, fstype) else: - formatButton = None + formatrb = None + + if origrequest.origfstype.isMigratable(): + migraterb = GtkRadioButton (label=_("Migrate partition to:"), + group=noformatrb) + migraterb.set_active(0) + if origrequest.migrate: + migraterb.set_active(1) + + migtypes = origrequest.origfstype.getMigratableFSTargets() + + maintable.attach(migraterb, 0, 1, row, row + 1) + (migfstype, migfstypeMenu)=createFSTypeMenu(ofstype, + None, None, + availablefstypes = migtypes) + migfstype.set_sensitive(migraterb.get_active()) + maintable.attach(migfstype, 1, 2, row, row + 1) + row = row + 1 + + migraterb.connect("toggled", formatOptionCB, migfstype) + + else: + migraterb = None + else: + noformatrb = None + formatrb = None + migraterb = None # size options if origrequest.type == REQUEST_NEW: @@ -802,12 +878,10 @@ class PartitionWindow(InstallWindow): if rc == 1: dialog.close() return - elif rc == -1: - raise ValueError,"Error while running edit partition request dialog." if origrequest.type == REQUEST_NEW: # read out UI into a partition specification - filesystem = fstypeoptionMenu.get_active().get_data("type") + filesystem = newfstypeMenu.get_active().get_data("type") request = copy.copy(origrequest) request.fstype = filesystem @@ -867,16 +941,28 @@ class PartitionWindow(InstallWindow): else: # preexisting partition, just set mount point and format flag request = copy.copy(origrequest) - if origrequest.fstype.isMountable(): - request.mountpoint = mountCombo.entry.get_text() + if formatrb: + request.format = formatrb.get_active() + if request.format: + request.fstype = fstypeMenu.get_active().get_data("type") + else: + request.format = 0 + + if migraterb: + request.migrate = migraterb.get_active() + if request.migrate: + request.fstype =migfstypeMenu.get_active().get_data("type") + else: + request.migrate = 0 - # filesystem = fstypeoptionMenu.get_active().get_data("type") - # origrequest.fstype = filesystem + # set back if we are not formatting or migrating + if not request.format and not request.migrate: + request.fstype = origrequest.origfstype - if formatButton: - request.format = formatButton.get_active() + if request.fstype.isMountable(): + request.mountpoint = mountCombo.entry.get_text() else: - request.format = 0 + request.mountpoint = None err = sanityCheckPartitionRequest(self.partitions, request) if err: @@ -1191,7 +1277,7 @@ class PartitionWindow(InstallWindow): class AutoPartitionWindow(InstallWindow): def __init__(self, ics): InstallWindow.__init__(self, ics) - ics.setTitle (_("Automatic Disk Setup")) + ics.setTitle (_("Automatic Partitioning")) ics.setNextEnabled (TRUE) self.parent = ics.getICW().window @@ -1229,9 +1315,7 @@ class AutoPartitionWindow(InstallWindow): box = GtkVBox (FALSE) box.set_border_width (5) - label = GtkLabel( - _("Before we can autopartition we need to know how you want us " - "to use the space on your harddrives.")) + label = GtkLabel(AUTOPART_DISK_CHOICE_DESCR_TEXT) label.set_line_wrap(1) label.set_alignment(0.0, 0.0) @@ -1246,13 +1330,13 @@ class AutoPartitionWindow(InstallWindow): radioBox = GtkVBox (FALSE) self.clearLinuxRB = GtkRadioButton( - None, _("Remove all Linux partitions")) + None, CLEARPART_TYPE_LINUX_DESCR_TEXT) radioBox.pack_start(self.clearLinuxRB, FALSE, FALSE) self.clearAllRB = GtkRadioButton( - self.clearLinuxRB, _("Remove all partitions")) + self.clearLinuxRB, CLEARPART_TYPE_ALL_DESCR_TEXT) radioBox.pack_start(self.clearAllRB, FALSE, FALSE) self.clearNoneRB = GtkRadioButton( - self.clearLinuxRB, _("Remove no partitions and use existing free space")) + self.clearLinuxRB, CLEARPART_TYPE_NONE_DESCR_TEXT) radioBox.pack_start(self.clearNoneRB, FALSE, FALSE) if type == CLEARPART_TYPE_LINUX: @@ -1271,7 +1355,8 @@ class AutoPartitionWindow(InstallWindow): # which drives to use? drivesbox = GtkVBox(FALSE) - label = GtkLabel(_("Which drives do you want to use for Linux?")) + label = GtkLabel(_("Which drive(s) do you want to use for this " + "installation?")) label.set_alignment(0.0, 0.0) drivesbox.pack_start(label, FALSE, FALSE, 10) self.driveclist = createAllowedDrivesClist(diskset.disks, diff --git a/packages.py b/packages.py index 1dc92c933..4b4f5b340 100644 --- a/packages.py +++ b/packages.py @@ -301,6 +301,7 @@ def turnOnFilesystems(dir, thefsset, diskset, upgrade, instPath): diskset.savePartitions () thefsset.formatSwap(instPath) thefsset.turnOnSwap(instPath) + thefsset.migrateFilesystems (instPath) thefsset.makeFilesystems (instPath) thefsset.mountFilesystems (instPath) diff --git a/partitioning.py b/partitioning.py index 6704b1a5b..6865dcfa1 100644 --- a/partitioning.py +++ b/partitioning.py @@ -136,7 +136,20 @@ def get_partition_file_system_type(part): ptype = fsset.fileSystemTypeGet("foreign") return ptype - + +def set_partition_file_system_type(part, fstype): + if fstype == None: + return + try: + part.set_system(fstype.getPartedFileSystemType()) + for flag in fstype.getPartedPartitionFlags(): + if not part.is_flag_available(flag): + raise PartitioningError, ("requested FileSystemType needs " + "a flag that is not available.") + part.set_flag(flag, 1) + except: + print "Failed to set partition type to ",fstype.getName() + pass def get_partition_drive(partition): return "%s" %(partition.geom.disk.dev.path[5:]) @@ -176,6 +189,8 @@ def get_raid_partitions(disk): if part.type & (parted.PARTITION_METADATA | parted.PARTITION_FREESPACE | parted.PARTITION_EXTENDED): part = disk.next_partition(part) continue + + print get_partition_name(part), part.fs_type.name, part.get_flag(parted.PARTITION_RAID) if part.get_flag(parted.PARTITION_RAID) == 1: rc.append(part) @@ -438,10 +453,10 @@ class DeleteSpec: class PartitionSpec: def __init__(self, fstype, requesttype = REQUEST_NEW, size = None, grow = 0, maxSize = None, - mountpoint = None, + mountpoint = None, origfstype = None, start = None, end = None, partnum = None, drive = None, primary = None, secondary = None, - format = None, options = None, + format = None, migrate = None, options = None, constraint = None, raidmembers = None, raidlevel = None, raidspares = None): @@ -452,8 +467,14 @@ class PartitionSpec: # must have (size) || (start && end) # fs_type, mountpoint # if partnum, require drive + # + # Some notes: + # format - if is 1, format. + # migrate - if is 1, convert from origfstype to fstype. + # self.type = requesttype self.fstype = fstype + self.origfstype = origfstype self.size = size self.grow = grow self.maxSize = maxSize @@ -465,6 +486,7 @@ class PartitionSpec: self.primary = primary self.secondary = secondary self.format = format + self.migrate = migrate self.options = options self.constraint = constraint self.partition = None @@ -522,9 +544,13 @@ class PartitionSpec: else: mountpoint = self.mountpoint - entry = fsset.FileSystemSetEntry(device, mountpoint, self.fstype) + entry = fsset.FileSystemSetEntry(device, mountpoint, self.fstype, + origfsystem=self.origfstype) if self.format: entry.setFormat(self.format) + + if self.migrate: + entry.setMigrate(self.migrate) return entry class Partitions: @@ -598,7 +624,8 @@ class Partitions: size = getPartSizeMB(part) drive = get_partition_drive(part) - spec = PartitionSpec(ptype, requesttype = REQUEST_PREEXIST, + spec = PartitionSpec(ptype, origfstype = ptype, + requesttype = REQUEST_PREEXIST, start = start, end = end, size = size, drive = drive, format = format) spec.device = fsset.PartedPartitionDevice(part).getDevice() @@ -29,10 +29,11 @@ from flags import flags from constants_text import * stepToClasses = { + "welcome" : ( "complete_text", "FinishedWindow" ), "language" : ( "language_text", "LanguageWindow" ), "keyboard" : ( "keyboard_text", "KeyboardWindow" ), "mouse" : ( "mouse_text", ( "MouseWindow", "MouseDeviceWindow" ) ), - "welcome" : ("welcome_text", "WelcomeWindow" ), +# "welcome" : ("welcome_text", "WelcomeWindow" ), "reconfigwelcome" : ("welcome_text", "ReconfigWelcomeWindow" ), "installtype" : ("installpath_text", "InstallPathWindow" ), "autopartition" : ("partition_text", "AutoPartitionWindow"), |