summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dispatch.py212
-rw-r--r--fsset.py859
-rw-r--r--partitioning.py561
3 files changed, 1632 insertions, 0 deletions
diff --git a/dispatch.py b/dispatch.py
new file mode 100644
index 000000000..031890ce4
--- /dev/null
+++ b/dispatch.py
@@ -0,0 +1,212 @@
+import string
+from types import *
+from packages import readPackages, checkDependencies, doInstall, handleX11Packages
+from packages import writeConfiguration, writeXConfiguration, writeKSConfiguration, turnOnFilesystems, queryUpgradeContinue
+from partitioning import AutoPartition
+from iutil import makeBootdisk
+from bootloader import partitioningComplete, writeBootloader
+from flags import flags
+
+DISPATCH_BACK = -1
+DISPATCH_FORWARD = 1
+DISPATCH_NOOP = None
+
+# These are all of the install steps, in order. Note that upgrade and
+# install steps are the same thing! Upgrades skip install steps, while
+# installs skip upgrade steps.
+
+#
+# items are one of
+#
+# ( name, tuple)
+# ( name, Function, tuple)
+#
+# in the second case, the function is called directly from the dispatcher
+
+installSteps = [
+# XXX for msw partition development
+# ( "partition", ("id.fsset", "id.diskset", "id.partrequests") ),
+ ( "language", ("intf", "id.instLanguage") ),
+ ( "keyboard", ("id.instLanguage", "id.keyboard") ),
+ ( "mouse", ("id.mouse", ) ),
+#
+# uncomment next 4 steps to debug X config easier
+#
+# ( "videocard", ("dispatch", "id.xconfig", "id.videocard")),
+# ( "monitor", ("id.xconfig", "id.monitor") ),
+# ( "xcustom", ("id.xconfig", "id.monitor", "id.videocard",
+# "id.desktop", "id.comps") ),
+# ( "writexconfig", writeXConfiguration, ("id", "instPath")),
+ ( "welcome", () ),
+ ( "reconfigwelcome", () ),
+ ( "reconfigkeyboard", ("id.instLanguage", "id.keyboard" ) ),
+ ( "installtype", ("dispatch", "id", "method",
+ "intf") ),
+ ( "partition", ("id.fsset", "id.diskset", "id.partrequests",
+ "intf")),
+ #( "partitionmethod", ( "dispatch", )),
+ #( "fdisk", ( "id.diskset", )),
+ #( "custom-upgrade", () ),
+ #( "addswap", () ),
+ #( "fdisk", () ),
+ #( "partition", () ),
+ ( "partitiondone", partitioningComplete,
+ ("dispatch", "id.bootloader",
+ "id.fsset", "id.diskset" ) ),
+ ( "bootloader", ("dispatch", "id.bootloader",
+ "id.fsset", "id.diskset") ),
+ ( "network", ("id.network",) ),
+ ( "firewall", ("id.network", "id.firewall") ),
+ ( "languagesupport", ("id.langSupport", ) ),
+ ( "timezone", ("id.instLanguage", "id.timezone", ) ),
+ ( "accounts", ("id.rootPassword", "id.accounts", ) ),
+ ( "authentication", ("id.auth", ) ),
+ ( "readcomps", readPackages, ("intf", "method", "id" )),
+ ( "upgradecontinue", queryUpgradeContinue, ("intf", "dir",
+ "dispatch")),
+ ( "package-selection", ("id.comps", "dispatch") ),
+ ( "indivpackage", ("id.comps", "id.hdList", ) ),
+ ( "handleX11pkgs", handleX11Packages,
+ ("dir", "intf", "dispatch", "id", "instPath" )),
+ ( "videocard", ("dispatch", "id.xconfig", "id.videocard")),
+ ( "checkdeps", checkDependencies,
+ ("dir", "intf", "dispatch", "id", "instPath" )),
+ ( "dependencies", ("id.comps", "id.dependencies",) ),
+ ( "confirminstall", () ),
+ ( "confirmupgrade", () ),
+ ( "install", ("dir", "intf", "id", ) ),
+ ( "enablefilesystems", turnOnFilesystems,
+ ( "dir", "id.fsset", "id.diskset",
+ "id.upgrade", "instPath") ),
+ ( "installpackages", doInstall,
+ ( "method", "id", "intf", "instPath" )),
+ ( "writeconfig", writeConfiguration,
+ ("id", "instPath" )),
+ ( "instbootloader", writeBootloader,
+ ("intf", "instPath", "id.fsset",
+ "id.bootloader", "id.langSupport", "id.comps") ),
+ ( "monitor", ("id.xconfig", "id.monitor") ),
+ ( "xcustom", ("id.xconfig", "id.monitor", "id.videocard",
+ "id.desktop", "id.comps") ),
+ ( "writexconfig", writeXConfiguration, ("id", "instPath")),
+ ( "writeksconfig", writeKSConfiguration, ("id", "instPath")),
+ ( "bootdisk", ("dir", "dispatch") ),
+ ( "makebootdisk", makeBootdisk, ("intf",) ),
+ ( "complete", () ),
+ ( "reconfigcomplete", () )
+ ]
+
+class Dispatcher:
+
+ def gotoPrev(self):
+ self.dir = -1
+ self.moveStep()
+
+ def gotoNext(self):
+ self.dir = 1
+ self.moveStep()
+
+ def setStepList(self, *steps):
+ self.skipSteps = {}
+ stepExists = {}
+ for step in installSteps:
+ name = step[0]
+ if not name in steps:
+ self.skipSteps[name] = 1
+
+ stepExists[name] = 1
+
+ for name in steps:
+ if not stepExists.has_key(name):
+ raise KeyError, ("step %s does not exist" % name)
+
+ def stepInSkipList(self, step):
+ return self.skipSteps.has_key(step)
+
+ def skipStep(self, stepToSkip, skip = 1):
+ for step in installSteps:
+ name = step[0]
+ if name == stepToSkip:
+ if skip:
+ self.skipSteps[name] = 1
+ elif self.skipSteps.has_key(name):
+ del self.skipSteps[name]
+ return
+
+ raise KeyError, ("unknown step %s" % stepToSkip)
+
+ def moveStep(self):
+ if self.step == None:
+ self.step = self.firstStep
+ else:
+ self.step = self.step + self.dir
+
+ if self.step == len(installSteps):
+ return None
+
+ while ((self.step >= self.firstStep
+ and self.step < len(installSteps))
+ and (self.skipSteps.has_key(installSteps[self.step][0])
+ or (type(installSteps[self.step][1]) == FunctionType))):
+ info = installSteps[self.step]
+ if ((type(info[1]) == FunctionType)
+ and (not self.skipSteps.has_key(info[0]))):
+ (func, args) = info[1:]
+ rc = apply(func, self.bindArgs(args))
+ if rc == DISPATCH_BACK:
+ self.dir = -1
+ elif rc == DISPATCH_FORWARD:
+ self.dir = 1
+ # if anything else, leave self.dir alone
+
+ self.step = self.step + self.dir
+ if self.step == len(installSteps):
+ return None
+
+ if (self.step < 0):
+ # pick the first step not in the skip list
+ self.step = 0
+ while self.skipSteps.has_key(installSteps[self.step][0]):
+ self.step = self.step + 1
+ elif self.step >= len(installSteps):
+ self.step = len(installSteps) - 1
+ while self.skipSteps.has_key(installSteps[self.step][0]):
+ self.step = self.step - 1
+
+ def bindArgs(self, args):
+ newArgs = ()
+ for arg in args:
+ obj = self
+ for item in string.split(arg, '.'):
+ if not obj.__dict__.has_key(item):
+ print "cannot find %s in %s" % (item, obj)
+ obj = obj.__dict__[item]
+ newArgs = newArgs + (obj,)
+
+ return newArgs
+
+ def currentStep(self):
+ if self.step == None:
+ self.gotoNext()
+ elif self.step == len(installSteps):
+ return (None, None)
+
+ stepInfo = installSteps[self.step]
+ step = stepInfo[0]
+ args = self.bindArgs(stepInfo[1])
+
+ return (step, args)
+
+ def __init__(self, intf, id, method, instPath):
+ self.dir = DISPATCH_FORWARD
+ self.step = None
+ self.skipSteps = {}
+ dispatch = self
+
+ self.id = id
+ self.flags = flags
+ self.intf = intf
+ self.method = method
+ self.dispatch = self
+ self.instPath = instPath
+ self.firstStep = 0
diff --git a/fsset.py b/fsset.py
new file mode 100644
index 000000000..927c6cd6d
--- /dev/null
+++ b/fsset.py
@@ -0,0 +1,859 @@
+#
+# fstab.py: filesystem management
+#
+# Matt Wilson <msw@redhat.com>
+#
+# Copyright 2001 Red Hat, Inc.
+#
+# This software may be freely redistributed under the terms of the GNU
+# library public license.
+#
+# You should have received a copy of the GNU Library Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+import string
+import isys
+import iutil
+import os
+import parted
+from log import log
+from translate import _, N_
+import partitioning
+
+defaultMountPoints = ('/', '/boot', '/home', '/tmp', '/usr', '/var')
+
+fileSystemTypes = {}
+
+def fileSystemTypeGetDefault():
+ return fileSystemTypeGet('ext2')
+
+def fileSystemTypeGet(key):
+ return fileSystemTypes[key]
+
+def fileSystemTypeRegister(klass):
+ fileSystemTypes[klass.getName()] = klass
+
+def fileSystemTypeGetTypes():
+ return fileSystemTypes.copy()
+
+def mountCompare(a, b):
+ one = a.mountpoint
+ two = b.mountpoint
+ if one < two:
+ return -1
+ elif two > one:
+ return 1
+ return 0
+
+def devify(device):
+ if device != "none":
+ return "/dev/" + device
+ return device
+
+class LabelFactory:
+ def __init__(self):
+ self.labels = {}
+
+ def createLabel(self, mountpoint):
+ if len(mountpoint) > 16:
+ mountpoint = mountpoint[0:16]
+ count = 0
+ while self.labels.has_key(mountpoint):
+ count = count + 1
+ s = "%s" % count
+ if (len(mountpoint) + len(s)) <= 16:
+ mountpoint = mountpoint + s
+ else:
+ strip = len(mountpoint) + len(s) - 16
+ mountpoint = mountpoint[0:len(mountpoint) - strip] + s
+ self.labels[mountpoint] = 1
+
+ return mountpoint
+
+ def reserveLabels(self, labels):
+ for device, label in labels.items():
+ self.labels[label] = 1
+
+labelFactory = LabelFactory()
+
+class FileSystemType:
+ kernelFilesystems = {}
+ def __init__(self):
+ self.deviceArguments = {}
+ self.formattable = 0
+ self.checked = 0
+ self.name = ""
+ self.linuxnativefs = 0
+ self.partedFileSystemType = None
+ self.partedPartitonFlags = []
+
+ def getName(self):
+ return self.name
+
+ def registerDeviceArgumentFunction(self, klass, function):
+ self.deviceArguments[klass] = function
+
+ def formatDevice(self, devicePath, device, progress, message, chroot='/'):
+ raise RuntimeError, "formatDevice method not defined"
+
+ def isFormattable(self):
+ return self.formattable
+
+ def isLinuxNativeFS(self):
+ return self.linuxnativefs
+
+ def readProcFilesystems(self):
+ f = open("/proc/filesystems", 'r')
+ if not f:
+ pass
+ lines = f.readlines()
+ for line in lines:
+ fields = string.split(line)
+ if fields[0] == "nodev":
+ fsystem = fields[1]
+ else:
+ fsystem = fields[0]
+ FileSystemType.kernelFilesystems[fsystem] = None
+
+ def isMountable(self):
+ if not FileSystemType.kernelFilesystems:
+ self.readProcFilesystems()
+
+ return FileSystemType.kernelFilesystems.has_key(self.getName())
+
+ def isChecked(self):
+ return self.checked
+
+ def getDeviceArgs(self, device):
+ deviceArgsFunction = self.deviceArguments.get(device.__class__)
+ if not deviceArgsFunction:
+ return []
+ return deviceArgsFunction(device)
+
+ def getPartedFileSystemType(self):
+ return self.partedFileSystemType
+
+ def getPartedPartitionFlags(self):
+ return self.partedPartitionFlags
+
+class ext2FileSystem(FileSystemType):
+ def __init__(self):
+ FileSystemType.__init__(self)
+ self.partedFileSystemType = parted.file_system_type_get("ext2")
+ self.formattable = 1
+ self.checked = 1
+ self.linuxnativefs = 1
+ self.name = "ext2"
+
+ def formatDevice(self, entry, progress, message, chroot='/'):
+ devicePath = entry.device.setupDevice(chroot)
+ devArgs = self.getDeviceArgs(entry.device)
+ label = labelFactory.createLabel(entry.mountpoint)
+ entry.setLabel(label)
+ args = [ "/usr/sbin/mke2fs", devicePath, '-L', label ]
+ args.extend(devArgs)
+
+ rc = ext2FormatFilesystem(args, "/dev/tty5",
+ progress,
+ entry.mountpoint)
+ if rc:
+ message and message(_("Error"),
+ _("An error occured trying to format %s. "
+ "This problem is serious, and the install "
+ "cannot continue.\n\n"
+ "Press Enter to reboot your "
+ "system.") % (entry.device.getDevice(),))
+ raise SystemError
+
+fileSystemTypeRegister(ext2FileSystem())
+
+class raidMemberDummyFileSystem(FileSystemType):
+ def __init__(self):
+ FileSystemType.__init__(self)
+ self.partedFileSystemType = parted.file_system_type_get("ext2")
+ self.partedPartitionFlags = [ parted.PARTITION_RAID ]
+ self.formattable = 1
+ self.checked = 0
+ self.linuxnativefs = 0
+ self.name = "software raid component"
+
+ def formatDevice(self, entry, progress, message, chroot='/'):
+ # mkraid did all we need to format this partition...
+ pass
+
+fileSystemTypeRegister(raidMemberDummyFileSystem())
+
+class swapFileSystem(FileSystemType):
+ def __init__(self):
+ FileSystemType.__init__(self)
+ self.partedFileSystemType = parted.file_system_type_get("linux-swap")
+ self.formattable = 1
+ self.name = "swap"
+
+ def formatDevice(self, entry, progress, message, chroot='/'):
+ file = entry.device.setupDevice(chroot)
+ rc = iutil.execWithRedirect ("/usr/sbin/mkswap",
+ [ "mkswap", '-v1', file ],
+ stdout = None, stderr = None,
+ searchPath = 1)
+
+fileSystemTypeRegister(swapFileSystem())
+
+class FATFileSystem(FileSystemType):
+ def __init__(self):
+ FileSystemType.__init__(self)
+ self.partedFileSystemType = parted.file_system_type_get("FAT")
+ self.formattable = 0
+ self.checked = 0
+ self.name = "vfat"
+
+fileSystemTypeRegister(FATFileSystem())
+
+class ForeignFileSystem(FileSystemType):
+ def __init__(self):
+ FileSystemType.__init__(self)
+ self.formattable = 0
+ self.checked = 0
+ self.name = "foreign"
+
+ def formatDevice(self, entry, progress, message, chroot='/'):
+ return
+
+fileSystemTypeRegister(ForeignFileSystem())
+
+class FileSystemSet:
+ def __init__(self):
+ self.entries = []
+ self.messageWindow = None
+ self.progressWindow = None
+
+ def registerMessageWindow(self, method):
+ self.messageWindow = method
+
+ def registerProgressWindow(self, method):
+ self.progressWindow = method
+
+ def reset (self):
+ self.entries = []
+
+ def add (self, entry):
+ self.entries.append(entry)
+ self.entries.sort (mountCompare)
+
+ def remove (self, entry):
+ self.entries.remove(entry)
+
+ def getEntryByMountPoint(self, mount):
+ for entry in self.entries:
+ if entry.mountpoint == mount:
+ return entry
+ return None
+
+ def getEntryByDeviceName(self, dev):
+ for entry in self.entries:
+ if entry.device.getDevice() == dev:
+ return entry
+ return None
+
+ def copy (self):
+ new = FileSystemSet()
+ for entry in self.entries:
+ new.add (entry)
+ return new
+
+ def fstab (self):
+ format = "%-23s %-23s %-7s %-15s %d %d\n";
+ fstab = ""
+ for entry in self.entries:
+ if entry.mountpoint:
+ if entry.getLabel():
+ device = "LABEL=%s" % (entry.getLabel(),)
+ else:
+ device = devify(entry.device.getDevice())
+ fstab = fstab + entry.device.getComment()
+ fstab = fstab + format % (device, entry.mountpoint,
+ entry.fsystem.getName(),
+ entry.options, entry.fsck,
+ entry.order)
+ return fstab
+
+ def raidtab(self):
+ # set up raidtab...
+ raidtab = ""
+ for entry in self.entries:
+ if entry.device.getName() == "RAIDDevice":
+ raidtab = raidtab + entry.device.raidTab()
+
+ return raidtab
+
+ def write (self, prefix):
+ f = open (prefix + "/etc/fstab", "w")
+ f.write (self.fstab())
+ f.close ()
+
+ raidtab = self.raidtab()
+
+ if raidtab:
+ f = open (prefix + "/etc/fstab", "w")
+ f.write (raidtab)
+ f.close ()
+
+ # touch mtab
+ open (prefix + "/etc/mtab", "w+")
+ f.close ()
+
+ def rootOnLoop (self):
+ for entry in self.entries:
+ if (entry.mountpoint == '/'
+ and entry.device.getName() == "LoopbackDevice"):
+ return 1
+ return 0
+
+ def bootloaderChoices(self, diskSet):
+ mntDict = {}
+
+ for entry in self.entries:
+ mntDict[entry.mountpoint] = entry.device
+
+ if mntDict.has_key("/boot"):
+ bootDev = mntDict['/boot']
+ else:
+ bootDev = mntDict['/']
+
+ if bootDev.getName() == "LoopbackDevice":
+ return None
+ elif bootDev.getName() == "RAIDDevice":
+ return [ bootDev.device, "RAID Device" ]
+
+ return [ (diskSet.driveList()[0], N_("Master Boot Record (MBR)") ),
+ (bootDev.device, N_("First sector of boot partition"))
+ ]
+
+ def formatSwap (self, chroot):
+ for entry in self.entries:
+ if entry.mountpoint and entry.fsystem.getName() == "swap":
+ entry.fsystem.formatDevice(entry, self.progressWindow,
+ self.messageWindow, chroot)
+
+ def turnOnSwap (self, chroot):
+ for entry in self.entries:
+ if entry.mountpoint and entry.fsystem.getName() == "swap":
+ if not entry.isMounted():
+ file = entry.device.setupDevice(chroot)
+ isys.swapon (file)
+ entry.setMounted(1)
+
+ def turnOffSwap(self, devices = 1, files = 0):
+ for entry in self.entries:
+ if entry.mountpoint and entry.fsystem.getName() == "swap":
+ if entry.isMounted():
+ isys.swapoff(n)
+ entry.setMounted(0)
+
+ def formattablePartitions(self):
+ list = []
+ for entry in self.entries:
+ if entry.fsystem.isFormattable():
+ list.append (entry)
+ return list
+
+ def makeFilesystems (self, chroot='/'):
+ for entry in self.entries:
+ if (not entry.format or entry.isMounted()
+ or not entry.fsystem.isFormattable()):
+ continue
+
+ entry.fsystem.formatDevice(entry, self.progressWindow,
+ self.messageWindow, chroot)
+
+ def mountFilesystems(self, instPath = '/', raiseErrors = 0, readOnly = 0):
+ for entry in self.entries:
+ if not entry.fsystem.isMountable():
+ continue
+ elif (entry.fsystem.isFormattable()
+ or (entry.fsystem.getName() == "vfat"
+ and entry.mountpoint == "/boot/efi")):
+ try:
+ iutil.mkdirChain(instPath + entry.mountpoint)
+ isys.mount(entry.device.getDevice(),
+ instPath + entry.mountpoint,
+ fstype = entry.fsystem.getName(),
+ readOnly = readOnly)
+ entry.setMounted(1)
+ except SystemError, (errno, msg):
+ if raiseErrors:
+ raise SystemError, (errno, msg)
+ self.messageWindow and self.messageWindow(_("Error"),
+ _("Error mounting device %s as %s: %s\n\n"
+ "This most likely means this partition has "
+ "not been formatted.\n\nPress OK to reboot your "
+ "system.") % (entry.device.getDevice(),
+ entry.mountpoint, msg))
+ sys.exit(0)
+
+ try:
+ os.mkdir (instPath + '/proc')
+ except:
+ pass
+
+ isys.mount('/proc', instPath + '/proc', 'proc')
+
+ def umountFilesystems(self, instPath, ignoreErrors = 0):
+ try:
+ isys.umount(instPath + '/proc/bus/usb', removeDir = 0)
+ log("Umount USB OK")
+ except:
+# log("Umount USB Fail")
+ pass
+
+ reverse = self.entries
+ reverse.reverse()
+
+ for entry in reverse:
+ if entry.isMounted():
+ isys.umount(instPath + entry.mountpoint, removeDir = 0)
+ entry.setMounted(0)
+
+class FileSystemSetEntry:
+ def __init__ (self, device, mountpoint,
+ fsystem=None, options="defaults",
+ order=-1, fsck=-1, format=0):
+ if not fsystem:
+ fsystem = fileSystemTypeGet("ext2")
+ self.device = device
+ self.mountpoint = mountpoint
+ self.fsystem = fsystem
+ self.options = options
+ self.mounted = 0
+ self.label = None
+ if fsck == -1:
+ self.fsck = fsystem.isChecked()
+ else:
+ self.fsck = fsck
+ if order == -1:
+ if mountpoint == '/':
+ self.order = 1
+ elif self.fsck:
+ self.order = 2
+ else:
+ self.order = 0
+ else:
+ self.order = order
+ if format and not fsystem.isFormattable():
+ raise RuntimeError, "file system type %s is not formattable, but has been added to fsset with format flag on" % fsystem.getName()
+ self.format = format
+
+ def setFormat (self, state):
+ self.format = state
+
+ def getFormat (self):
+ return self.format
+
+ def isMounted (self):
+ return self.mounted
+
+ def setMounted (self, state):
+ self.isMounted = state
+
+ def getLabel (self):
+ return self.label
+
+ def setLabel (self, label):
+ self.label = label
+
+class Device:
+ def __init__(self):
+ self.device = "none"
+ self.fsoptions = {}
+ self.label = None
+
+ def __repr__(self):
+ return self.device
+
+ def getComment (self):
+ return ""
+
+ def getDevice (self):
+ return self.device
+
+ def setupDevice (self, chroot='/tmp'):
+ pass
+
+ def cleanupDevice (self, chroot, devPrefix='/tmp'):
+ pass
+
+ def solidify (self):
+ pass
+
+ def getName(self):
+ return self.__class__.__name__
+
+class RAIDDevice(Device):
+ usedMajors = []
+
+ # members is a list of Device based instances that will be
+ # a part of this raid device
+ def __init__(self, level, members, minor=-1, spares=0):
+ Device.__init__(self)
+ self.level = level
+ self.members = members
+ self.spares = spares
+ self.numDisks = len(members) - spares
+
+ if len(members) < spares:
+ raise RuntimeError, "you requiested more spare devices than online devices!"
+
+ if level == 5:
+ if self.numDisks < 3:
+ raise RuntimeError, "RAID 5 requires at least 3 online members"
+
+ # there are 32 major md devices, 0...31
+ if minor == -1:
+ for I in range(32):
+ if not I in RAIDDevice.usedMajors:
+ minor = I
+ break
+ raise RuntimeError, "Unable to allocate minor number for raid device"
+ minor = I
+ RAIDDevice.usedMajors.append(minor)
+ self.device = "md" + str(minor)
+ self.minor = minor
+
+ def __del__ (self):
+ RAIDDevice.usedMajors.remove(minor)
+
+ def ext2Args (self):
+ if self.level == 5:
+ return [ '-R', 'stride=%d' % ((self.numDisks - 1) * 16) ]
+ elif self.level == 0:
+ return [ '-R', 'stride=%d' % (self.numDisks * 16) ]
+
+ def raidTab (self, devPrefix='/dev'):
+ entry = ""
+ entry = entry + "raiddev %s/%s\n" % (devPrefix,
+ self.device,)
+ entry = entry + "raid-level %d\n" % (self.level,)
+ entry = entry + "nr-raid-disks %d\n" % (self.numDisks,)
+ entry = entry + "chunk-size 64k\n"
+ entry = entry + "persistent-superblock 1\n"
+ entry = entry + "#nr-spare-disks %d\n" % (self.spares,)
+ i = 0
+ for device in self.members:
+ entry = entry + " device %s/%s\n" % (devPrefix,
+ device.getDevice())
+ entry = entry + " raid-disk %d\n" % (i,)
+ i = i + 1
+ return entry
+
+ def setupDevice (self, chroot, devPrefix='/tmp'):
+ raidtab = '/tmp/raidtab.%s' % (self.device,)
+ f = open(raidtab, 'w')
+ f.write(self.raidTab('/tmp'))
+ for device in self.members:
+ device.setupDevice()
+ node = "%s/%s" % (devPrefix, self.device)
+ isys.makeDevInode(self.device, node, devPrefix=devPrefix)
+ iutil.execWithRedirect ("/usr/sbin/mkraid",
+ [ 'mkraid', '--really-force', '--configfile',
+ raidtab, node ],
+ stderr = "/dev/tty5", stdout = "/dev/tty5")
+ return node
+
+ def solidify(self):
+ for device in self.members:
+ device.solidify()
+
+ext2 = fileSystemTypeGet("ext2")
+ext2.registerDeviceArgumentFunction(RAIDDevice, RAIDDevice.ext2Args)
+
+class LVMDevice(Device):
+ def __init__(self):
+ Device.__init__(self)
+
+class PartitionDevice(Device):
+ def __init__(self, partition):
+ Device.__init__(self)
+ self.device = partition
+
+ def setupDevice(self, chroot, devPrefix='/tmp'):
+ path = '%s/%s' % (devPrefix, self.getDevice(),)
+ isys.makeDevInode(self.getDevice(), path)
+ return path
+
+class PartedPartitionDevice(Device):
+ def __init__(self, partition):
+ Device.__init__(self)
+ self.partition = partition
+ self.device = None
+
+ def getDevice(self):
+ if not self.partition:
+ return self.device
+
+ if (self.partition.geom.disk.dev.type == parted.DEVICE_DAC960
+ or self.partition.geom.disk.dev.type == parted.DEVICE_CPQARRAY):
+ return "%sp%d" % (self.partition.geom.disk.dev.path[5:],
+ self.partition.num)
+ return "%s%d" % (self.partition.geom.disk.dev.path[5:],
+ self.partition.num)
+
+ def setupDevice(self, chroot, devPrefix='/tmp'):
+ path = '%d/%s' % (self.getDevice(), devPrefix)
+ isys.makeDevInode(self.getDevice(), path)
+ return path
+
+ def solidify(self):
+ self.device = self.getDevice()
+ self.partition = None
+
+class SwapFileDevice(Device):
+ def __init__(self, file):
+ Device.__init__(self)
+ self.device = file
+ self.device.size = 0
+
+ def setSize (self, size):
+ self.size = size
+
+ def setupDevice (self, chroot, devPrefix='/tmp'):
+ file = os.path.normpath(chroot + self.getDevice())
+ if not os.access(file, os.R_OK):
+ if self.size:
+ isys.ddfile(file, self.size, None)
+ else:
+ raise SystemError, ("swap file creation necessary, but "
+ "required size is unknown.")
+ return file
+
+class LoopbackDevice(Device):
+ def __init__(self, hostPartition, hostFs):
+ Device.__init__(self)
+ self.host = "/dev/" + hostPartition
+ self.hostfs = hostFs
+ self.device = "loop1"
+
+ def getComment (self):
+ return "# LOOP1: %s %s /redhat.img\n" % (self.host, self.hostfs)
+
+def readFstab (path):
+ fsset = FileSystemSet()
+
+ # first, we look at all the disks on the systems and get any ext2/3
+ # labels off of the filesystem.
+ # temporary, to get the labels
+ diskset = partitioning.DiskSet()
+ diskset.openDevices()
+ labels = diskset.getLabels()
+
+ labelToDevice = {}
+ for device, label in labels.items():
+ labelToDevice[label] = device
+
+ # mark these labels found on the system as used so the factory
+ # doesn't give them to another device
+ labelFactory.reserveLabels(labels)
+
+ loopIndex = {}
+
+ f = open (path, "r")
+ lines = f.readlines ()
+ f.close
+
+ for line in lines:
+ fields = string.split (line)
+
+ if not fields: continue
+
+ # pick up the magic comment in fstab that tells us which
+ # device is the loop host in a partionless upgrade
+ if fields[0] == "#" and len(fields) > 4 and fields[1][:4] == "LOOP":
+ device = string.lower(fields[1])
+ if device[len(device) - 1] == ":":
+ device = device[:len(device) - 1]
+ realDevice = fields[2]
+ if realDevice[:5] == "/dev/":
+ realDevice = realDevice[5:]
+ loopIndex[device] = (realDevice, fields[3])
+
+ if line[0] == "#":
+ # skip all comments
+ continue
+
+ # all valid fstab entries have 6 fields
+ if len (fields) < 4 or len (fields) > 6: continue
+
+ if not fileSystemTypes.has_key(fields[2]):
+ continue
+ if string.find(fields[3], "noauto") != -1: continue
+
+ fsystem = fileSystemTypeGet(fields[2])
+ label = None
+ if len(fields) >= 6 and fields[0][:6] == "LABEL=":
+ label = fields[0][6:]
+ if labelToDevice.has_key(label):
+ device = PartitionDevice(labelToDevice[label])
+ else:
+ log ("Warning: fstab file has LABEL=%s, but this label "
+ "could not be found on any filesystem", label)
+ # bad luck, skip this entry.
+ continue
+ elif (fields[2] == "swap" and fields[0][:5] != "/dev/"):
+ # swap files
+ file = fields[0]
+
+ # the loophost looks like /mnt/loophost to the install, not
+ # like /initrd/loopfs
+ if file[:15] == "/initrd/loopfs/":
+ file = "/mnt/loophost/" + file[14:]
+
+ device = SwapFileDevice(file)
+ elif fields[0][:9] == "/dev/loop":
+ # look up this loop device in the index to find the
+ # partition that houses the filesystem image
+ # XXX currently we assume /dev/loop1
+ if loopIndex.has_key(device):
+ (dev, fs) = loopIndex[device]
+ device = LoopbackDevice(dev, fs)
+ else:
+ device = PartitionDevice(fields[0][5:])
+
+ entry = FileSystemSetEntry(device, fields[1], fsystem, fields[3])
+ if label:
+ entry.setLabel(label)
+ fsset.add(entry)
+ return fsset
+
+def isValidExt2(device):
+ file = '/tmp/' + device
+ isys.makeDevInode(device, file)
+ try:
+ fd = os.open(file, os.O_RDONLY)
+ except:
+ return 0
+
+ buf = os.read(fd, 2048)
+ os.close(fd)
+
+ if len(buf) != 2048:
+ return 0
+
+ if struct.unpack("H", buf[1080:1082]) == (0xef53,):
+ return 1
+
+ return 0
+
+def ext2FormatFilesystem(argList, messageFile, windowCreator, mntpoint):
+ if windowCreator:
+ w = windowCreator(_("Formatting"),
+ _("Formatting %s filesystem...") % (mntpoint,), 100)
+ else:
+ w = None
+
+ fd = os.open(messageFile, os.O_RDWR | os.O_CREAT | os.O_APPEND)
+ p = os.pipe()
+ childpid = os.fork()
+ if (not childpid):
+ os.close(p[0])
+ os.dup2(p[1], 1)
+ os.dup2(fd, 2)
+ os.close(p[1])
+ os.close(fd)
+ os.execv(argList[0], argList)
+ log("failed to exec %s", argList)
+ sys.exit(1)
+
+ os.close(p[1])
+
+ # ignoring SIGCHLD would be cleaner then ignoring EINTR, but
+ # we can't use signal() in this thread?
+
+ s = 'a'
+ while s and s != '\b':
+ try:
+ s = os.read(p[0], 1)
+ except OSError, args:
+ (num, str) = args
+ if (num != 4):
+ raise IOError, args
+
+ os.write(fd, s)
+
+ num = ''
+ while s:
+ try:
+ s = os.read(p[0], 1)
+ os.write(fd, s)
+
+ if s != '\b':
+ try:
+ num = num + s
+ except:
+ pass
+ else:
+ if num:
+ l = string.split(num, '/')
+ w and w.set((int(l[0]) * 100) / int(l[1]))
+ isys.sync()
+ num = ''
+ except OSError, args:
+ (num, str) = args
+ if (num != 4):
+ raise IOError, args
+
+ try:
+ (pid, status) = os.waitpid(childpid, 0)
+ except OSError, (errno, msg):
+ print __name__, "waitpid:", msg
+ os.close(fd)
+
+ w and w.pop()
+
+ if os.WIFEXITED(status) and (os.WEXITSTATUS(status) == 0):
+ return 0
+
+ return 1
+
+def enabledSwapDict():
+ # returns a dict of swap areas currently being used
+ f = open("/proc/swaps", "r")
+ lines = f.readlines()
+ f.close()
+
+ # the first line is header
+ lines = lines[1:]
+
+ swaps = {}
+ for line in lines:
+ l = string.split(line)
+ swaps[l[0]] = 1
+
+ return swaps
+
+if __name__ == "__main__":
+ import sys
+ log.open("foo")
+
+ fsset = readFstab("fstab")
+
+ print fsset.fstab()
+ print fsset.rootOnLoop()
+
+ sys.exit(0)
+ fsset = FileSystemSet()
+ proc = FileSystemSetEntry(Device(), '/proc', 'proc')
+ fsset.add(proc)
+ devpts = FileSystemSetEntry(Device(), '/dev/pts', 'devpts',
+ 'gid=5,mode=620')
+ fsset.add(devpts)
+
+ device = LoopbackDevice("hda1", "vfat")
+ mountpoint = FileSystemSetEntry (device, '/')
+ fsset.add(mountpoint)
+
+ device = SwapFileDevice("/SWAP")
+ mountpoint = FileSystemSetEntry (device, "swap", "swap")
+ fsset.add(mountpoint)
+
+ print fsset.fstab()
diff --git a/partitioning.py b/partitioning.py
new file mode 100644
index 000000000..57809719f
--- /dev/null
+++ b/partitioning.py
@@ -0,0 +1,561 @@
+#
+# partitioning.py: partitioning and other disk management
+#
+# Matt Wilson <msw@redhat.com>
+#
+# Copyright 2001 Red Hat, Inc.
+#
+# This software may be freely redistributed under the terms of the GNU
+# library public license.
+#
+# You should have received a copy of the GNU Library Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+if __name__ == "__main__":
+ import sys
+ sys.path.append ("isys")
+ sys.path.append ("balkan")
+
+import isys
+import parted
+import math
+
+from fsset import *
+from translate import _
+
+# different types of partition requests
+# REQUEST_PREEXIST is a placeholder for a pre-existing partition on the system
+# REQUEST_NEW is a request for a partition which will be automatically
+# created based on various constraints on size, drive, etc
+#
+REQUEST_PREEXIST = 1
+REQUEST_NEW = 2
+REQUEST_RAID = 4
+
+fsTypes = {}
+
+fs_type = parted.file_system_type_get_next ()
+while fs_type:
+ fsTypes[fs_type.name] = fs_type
+ fs_type = parted.file_system_type_get_next (fs_type)
+
+class PartitioningError:
+ def __init__ (self, value):
+ self.value = value
+
+ def __str__ (self):
+ return self.value
+
+def get_flags (part):
+ string=""
+ if not part.is_active ():
+ return string
+ first=1
+ flag = parted.partition_flag_next (0)
+ while flag:
+ if part.get_flag (flag):
+ string = string + parted.partition_flag_get_name (flag)
+ if first:
+ first = 0
+ else:
+ string = string + ", "
+ flag = parted.partition_flag_next (flag)
+ return string
+
+def start_sector_to_cyl(device, sector):
+ return int(math.floor((float(sector)
+ / (device.heads * device.sectors)) + 1))
+
+def end_sector_to_cyl(device, sector):
+ return int(math.ceil(float((sector + 1))
+ / (device.heads * device.sectors)))
+
+def start_cyl_to_sector(device, cyl):
+ return long((cyl - 1) * (device.heads * device.sectors))
+
+def end_cyl_to_sector(device, cyl):
+ return long(((cyl) * (device.heads * device.sectors)) - 1)
+
+def getPartSize(partition):
+ return partition.geom.length * partition.geom.disk.dev.sector_size / 1024.0 / 1024.0
+
+def get_partition_name(partition):
+ if (partition.geom.disk.dev.type == parted.DEVICE_DAC960
+ or partition.geom.disk.dev.type == parted.DEVICE_CPQARRAY):
+ return "%sp%d" % (partition.geom.disk.dev.path[5:],
+ partition.num)
+ return "%s%d" % (partition.geom.disk.dev.path[5:],
+ partition.num)
+
+def get_logical_partitions(disk):
+ rc = []
+ part = disk.next_partition ()
+ while part:
+ if part.type & parted.PARTITION_LOGICAL:
+ rc.append(part)
+ part = disk.next_partition (part)
+
+ return rc
+
+def get_primary_partitions(disk):
+ rc = []
+ part = disk.next_partition()
+ while part:
+ if part.type == parted.PARTITION_PRIMARY:
+ rc.append(part)
+ part = disk.next_partition(part)
+
+ return rc
+
+
+def get_raid_partitions(disk):
+ rc = []
+ part = disk.next_partition()
+ while part:
+
+ if part.type & (parted.PARTITION_METADATA | parted.PARTITION_FREESPACE | parted.PARTITION_EXTENDED):
+ part = disk.next_partition(part)
+ continue
+
+ if part.get_flag(parted.PARTITION_RAID) == 1:
+ rc.append(part)
+ part = disk.next_partition(part)
+
+ return rc
+
+
+# returns error string if something not right about request
+# returns error string if something not right about request
+def sanityCheck(reqpartitions, newrequest):
+ # see if mount point is valid if its a new partition request
+
+ mustbeonroot = ['/bin','/dev','/sbin','/etc','/lib','/root','/mnt']
+ mustbeonlinuxfs = ['/', '/boot', '/var', '/tmp', '/usr', '/home']
+
+ mntpt = newrequest.mountpoint
+ fstype = newrequest.fstype
+
+ if mntpt:
+ passed = 1
+ if not mntpt:
+ passed = 0
+ else:
+ if mntpt[0] != '/' or (len(mntpt) > 1 and mntpt[-1:] == '/'):
+ passed = 0
+
+ if not passed:
+ return _("The mount point is invalid. Mount points must start "
+ "with '/' and cannot end with '/', and must contain "
+ "printable characters.")
+ else:
+ if newrequest.fstype.isMountable() and newrequest.type == REQUEST_NEW:
+ return _("Please specify a mount point for this partition.")
+ else:
+ # its an existing partition so don't force a mount point
+ return
+
+ # mount point is defined and is legal. now make sure its unique
+ if reqpartitions and reqpartitions.requests:
+ for request in reqpartitions.requests:
+ if request.mountpoint == mntpt and request.start != newrequest.start:
+ return _("The mount point %s is already in use, please "
+ "choose a different mount point." % (mntpt))
+
+
+ # further sanity checks
+ if fstype.isLinuxNativeFS():
+ if mntpt in mustbeonroot:
+ return _("This mount point is invalid. This directory must "
+ "be on the / filesystem.")
+
+ if fstype.getName() == "linux-swap":
+ if newrequest.size * 1024 > MAX_SWAP_PART_SIZE_KB:
+ return _("This swap partition exceeds the maximum size of "
+ "%s MB.") % (MAX_SWAP_PART_SIZE_KB / 1024)
+ else:
+ if mntpt in mustbeonlinuxfs:
+ return _("This mount point must be on a linux filesystem.")
+
+ return None
+
+class DeleteSpec:
+ def __init__(self, drive, start, end):
+ self.drive = drive
+ self.start = start
+ self.end = end
+
+
+class PartitionSpec:
+ def __init__(self, fstype, requesttype = REQUEST_NEW,
+ size = None, grow = 0, maxSize = 0,
+ mountpoint = None,
+ start = None, end = None, partnum = None,
+ drive = None, primary = None, secondary = None,
+ format = None, options = None,
+ constraint = None,
+ raidmembers = None, raidlevel = None,
+ raidspares = None):
+ #
+ # requesttype: REQUEST_PREEXIST or REQUEST_NEW or REQUEST_RAID
+ #
+ # XXX: unenforced requirements for a partition spec
+ # must have (size) || (start && end)
+ # fs_type, mountpoint
+ # if partnum, require drive
+ self.type = requesttype
+ self.fstype = fstype
+ self.size = size
+ self.grow = grow
+ self.maxSize = maxSize
+ self.mountpoint = mountpoint
+ self.start = start
+ self.end = end
+ self.partnum = partnum
+ self.drive = drive
+ self.primary = primary
+ self.secondary = secondary
+ self.format = format
+ self.options = options
+ self.constraint = constraint
+ self.partition = None
+ self.requestSize = size
+ self.raidmembers = raidmembers
+ self.raidlevel = raidlevel
+ self.raidspares = raidspares
+
+ # device is what we currently think the device is
+ # realDevice is used by partitions which are pre-existing
+ self.device = None
+ self.realDevice = None
+
+ # there has to be a way to go from device -> drive... but for now
+ self.currentDrive = None
+
+ def __str__(self):
+ return "mountpoint: %s type: %s\n" %(self.mountpoint, self.fstype.getName()) +\
+ " size: %sM requestSize: %sM grow: %s max: %s\n" %(self.size, self.requestSize, self.grow, self.maxSize) +\
+ " start: %s end: %s partnum: %s\n" %(self.start, self.end, self.partnum) +\
+ " drive: %s primary: %s secondary: %s\n" %(self.drive, self.primary, self.secondary) +\
+ " format: %s, options: %s" %(self.format, self.options) +\
+ " device: %s, realDevice: %s" %(self.device, self.realDevice)+\
+ " raidlevel: %s" % (self.raidlevel)+\
+ " raidspares: %s" % (self.raidspares)
+
+ # turn a partition request into a fsset entry
+ def toEntry(self):
+ if self.type == REQUEST_RAID:
+ device = RAIDDevice(int(self.raidlevel[-1:]), self.raidmembers,
+ spares = self.raidspares)
+ else:
+ device = PartitionDevice(self.device)
+
+ # pin down our partitions so that we can reread the table
+ device.solidify()
+
+ if self.fstype.getName() == "swap":
+ mountpoint = "swap"
+ else:
+ mountpoint = self.mountpoint
+
+ entry = FileSystemSetEntry(device, mountpoint, self.fstype)
+ if self.format:
+ entry.setFormat(self.format)
+ return entry
+
+class PartitionRequests:
+ def __init__ (self, diskset = None):
+ self.requests = []
+ self.deletes = []
+ if diskset:
+ self.setFromDisk(diskset)
+
+ def setFromDisk(self, diskset):
+ self.deletes = []
+ diskset.refreshDevices()
+ drives = diskset.disks.keys()
+ drives.sort()
+ for drive in drives:
+ disk = diskset.disks[drive]
+ part = disk.next_partition()
+ while part:
+ if part.type & parted.PARTITION_METADATA:
+ part = disk.next_partition(part)
+ continue
+
+ if part.type & parted.PARTITION_FREESPACE:
+ ptype = None
+ elif part.type & parted.PARTITION_EXTENDED:
+ ptype = None
+ elif part.fs_type:
+ if part.fs_type.name == "linux-swap":
+ ptype = fileSystemTypeGet("swap")
+ elif part.fs_type.name == "FAT":
+ ptype = fileSystemTypeGet("vfat")
+ else:
+ try:
+ ptype = fileSystemTypeGet(part.fs_type.name)
+ except:
+ ptype = fileSystemTypeGet("foreign")
+ else:
+ ptype = None
+
+ start = part.geom.start
+ end = part.geom.end
+ size = getPartSize(part)
+
+ spec = PartitionSpec(ptype, requesttype = REQUEST_PREEXIST,
+ start = start, end = end, size = size)
+ spec.device = PartedPartitionDevice(part).getDevice()
+ self.addRequest(spec)
+ part = disk.next_partition(part)
+
+ def addRequest (self, request):
+ self.requests.append(request)
+ self.requests.sort()
+
+ def addDelete (self, delete):
+ self.deletes.append(delete)
+ self.deletes.sort()
+
+ def removeRequest (self, request):
+ self.requests.remove(request)
+
+ def getRequestByMountPoint(self, mount):
+ for request in self.requests:
+ if request.mountpoint == mount:
+ return request
+ return None
+
+ def getRequestByDeviceName(self, device):
+ for request in self.requests:
+ if request.device == device:
+ return request
+ return None
+
+ def sortRequests(self):
+ n = 0
+ while n < len(self.requests):
+ for request in self.requests:
+ if request.size < self.requests[n].size:
+ tmp = self.requests[n]
+ index = self.requests.index(request)
+ self.requests[n] = request
+ self.requests[index] = tmp
+ n = n + 1
+
+ def copy (self):
+ new = PartitionRequests()
+ for request in self.requests:
+ new.addRequest(request)
+ for delete in self.deletes:
+ new.addDelete(delete)
+ return new
+
+
+class DiskSet:
+ def __init__ (self):
+ self.disks = {}
+
+ def getLabels(self):
+ labels = {}
+
+ drives = self.disks.keys()
+ drives.sort
+
+ for drive in drives:
+ disk = self.disks[drive]
+ part = disk.next_partition ()
+ while part:
+ if part.fs_type and (part.fs_type.name == "ext2"
+ or part.fs_type.name == "ext3"):
+ node = get_partition_name(part)
+ label = isys.readExt2Label(node)
+ if label:
+ labels[node] = label
+ part = disk.next_partition(part)
+
+ return labels
+
+ def driveList (self):
+ drives = isys.hardDriveDict().keys()
+ drives.sort (isys.compareDrives)
+ return drives
+
+ def drivesByName (self):
+ return isys.hardDriveDict()
+
+ def addPartition (self, device, type, spec):
+ if not self.disks.has_key (device):
+ raise PartitioningError, ("unknown device passed to "
+ "addPartition: %s" % (device,))
+ disk = self.disks[device]
+
+ part = disk.next_partition ()
+ status = 0
+ while part:
+ if (part.type == parted.PARTITION_FREESPACE
+ and part.geom.length >= spec.size):
+ newp = disk.partition_new (type, spec.fs_type,
+ part.geom.start,
+ part.geom.start + spec.size)
+ constraint = disk.constraint_any ()
+ try:
+ disk.add_partition (newp, constraint)
+ status = 1
+ break
+ except parted.error, msg:
+ raise PartitioningError, msg
+ part = disk.next_partition (part)
+ if not status:
+ raise PartitioningError, ("Not enough free space on %s to create "
+ "new partition" % (device,))
+ return newp
+
+ def deleteAllPartitions (self):
+ for disk in self.disks.values():
+ disk.delete_all ()
+
+ def savePartitions (self):
+ for disk in self.disks.values():
+ disk.write()
+ del disk
+ self.refreshDevices()
+
+ def refreshDevices (self):
+ self.disks = {}
+ self.openDevices()
+
+ def openDevices (self):
+ if self.disks:
+ return
+ for drive in self.driveList ():
+ isys.makeDevInode(drive, '/tmp/' + drive)
+ try:
+ dev = parted.PedDevice.get ('/tmp/' + drive)
+ except parted.error, msg:
+ raise PartitioningError, msg
+ try:
+ disk = parted.PedDisk.open(dev)
+ self.disks[drive] = disk
+ except parted.error, msg:
+ raise PartitioningError, msg
+
+ def partitionTypes (self):
+ rc = []
+ drives = self.disks.keys()
+ drives.sort
+
+ for drive in drives:
+ disk = self.disks[drive]
+ part = disk.next_partition ()
+ while part:
+ if part.type in (parted.PARTITION_PRIMARY,
+ parted.PARTITION_LOGICAL):
+ device = get_partition_name(part)
+ if part.fs_type:
+ ptype = part.fs_type.name
+ else:
+ ptype = None
+ rc.append (device, ptype)
+ part = disk.next_partition (part)
+
+ return rc
+
+ def diskState (self):
+ rc = ""
+ for disk in self.disks.values():
+ rc = rc + ("%s: %s length %ld, maximum "
+ "primary partitions: %d\n" %
+ (disk.dev.path,
+ disk.dev.model,
+ disk.dev.length,
+ disk.max_primary_partition_count))
+
+ part = disk.next_partition()
+ if part:
+ rc = rc + ("Device Type Filesystem Start "
+ "End Length Flags\n")
+ rc = rc + ("------ ---- ---------- ----- "
+ "--- ------ -----\n")
+ while part:
+ if not part.type & parted.PARTITION_METADATA:
+ device = ""
+ fs_type_name = ""
+ if part.num > 0:
+ device = get_partition_name(part)
+ if part.fs_type:
+ fs_type_name = part.fs_type.name
+ flags = get_flags (part)
+ rc = rc + ("%-9s %-12s %-12s %-10ld %-10ld %-10ld %7s\n"
+ % (device, part.type_name, fs_type_name,
+ part.geom.start, part.geom.end, part.geom.length,
+ flags))
+ part = disk.next_partition(part)
+ return rc
+
+def AutoPartition (fsset, diskset):
+ from fsset import *
+ diskset.deleteAllPartitions ()
+
+ spec = PartitionSpec (fsTypes['linux-swap'], (64L * 2048L))
+ diskset.addPartition (diskset.driveList()[0],
+ parted.PARTITION_PRIMARY, spec)
+
+ spec = PartitionSpec (fsTypes['ext2'], (1024L * 2048L))
+ diskset.addPartition (diskset.driveList()[0],
+ parted.PARTITION_PRIMARY, spec)
+
+ device = PartitionDevice (diskset.driveList()[0] + "1")
+ mountpoint = FileSystemSetEntry (device, 'swap', 'swap')
+ mountpoint.setFormat(1)
+ fsset.add(mountpoint)
+
+ device = PartitionDevice (diskset.driveList()[0] + "2")
+ mountpoint = FileSystemSetEntry (device, '/')
+ mountpoint.setFormat(1)
+ fsset.add(mountpoint)
+
+ from log import log
+ log (diskset.diskState())
+
+if __name__ == "__main__":
+ foo = DiskSet()
+ foo.deleteAllPartitions ()
+ print foo.diskState ()
+ print '---------------------'
+ spec = PartitionSpec (fsTypes['ext2'], 12060L)
+ foo.addPartition ("sda", parted.PARTITION_PRIMARY, spec)
+ print foo.diskState ()
+ spec = PartitionSpec (fsTypes['ext2'], 16060L)
+ foo.addPartition ("sda", parted.PARTITION_PRIMARY, spec)
+ print foo.diskState ()
+
+ spec = PartitionSpec (fsTypes['ext2'], 16060L)
+ foo.addPartition ("sda", parted.PARTITION_PRIMARY, spec)
+ print foo.diskState ()
+
+ spec = PartitionSpec (fsTypes['ext2'], 16060L)
+ foo.addPartition ("sda", parted.PARTITION_PRIMARY, spec)
+ print foo.diskState ()
+
+ spec = PartitionSpec (fsTypes['ext2'], 16060L)
+ foo.addPartition ("sda", parted.PARTITION_PRIMARY, spec)
+ print foo.diskState ()
+
+ spec = PartitionSpec (fsTypes['ext2'], 16060L)
+ foo.addPartition ("sda", parted.PARTITION_PRIMARY, spec)
+ print foo.diskState ()
+
+ spec = PartitionSpec (fsTypes['ext2'], 16060L)
+ foo.addPartition ("sda", parted.PARTITION_PRIMARY, spec)
+ print foo.diskState ()
+
+ spec = PartitionSpec (fsTypes['ext2'], 16060L)
+ foo.addPartition ("sda", parted.PARTITION_PRIMARY, spec)
+ print foo.diskState ()
+
+ spec = PartitionSpec (fsTypes['ext2'], 16060L)
+ foo.addPartition ("sda", parted.PARTITION_PRIMARY, spec)
+ print foo.diskState ()