diff options
author | Jeremy Katz <katzj@redhat.com> | 2002-01-21 21:24:40 +0000 |
---|---|---|
committer | Jeremy Katz <katzj@redhat.com> | 2002-01-21 21:24:40 +0000 |
commit | 8842f3f725af9dbfc41ce884da520f97a53d2a4f (patch) | |
tree | 64bc5c3ff1da2da1910f4b5dfe7254810448b685 | |
parent | a0908acbe832d7f76be25fe3fdd1288f25464d36 (diff) | |
download | anaconda-8842f3f725af9dbfc41ce884da520f97a53d2a4f.tar.gz anaconda-8842f3f725af9dbfc41ce884da520f97a53d2a4f.tar.xz anaconda-8842f3f725af9dbfc41ce884da520f97a53d2a4f.zip |
land boot loader changes to use booty backend infrastructure and switch
over to new screens. tagged as before_bootloader_merge and
after_bootloader_merge appropriately
-rw-r--r-- | Makefile | 3 | ||||
-rwxr-xr-x | anaconda | 7 | ||||
-rw-r--r-- | bootloader.py | 935 | ||||
-rw-r--r-- | dispatch.py | 3 | ||||
-rw-r--r-- | fsset.py | 18 | ||||
-rwxr-xr-x | gui.py | 6 | ||||
-rw-r--r-- | installclass.py | 5 | ||||
-rw-r--r-- | iw/bootloader_gui.py | 1209 | ||||
-rwxr-xr-x | scripts/upd-instroot | 3 | ||||
-rw-r--r-- | text.py | 6 | ||||
-rw-r--r-- | textw/bootloader_text.py | 65 |
11 files changed, 891 insertions, 1369 deletions
@@ -9,7 +9,7 @@ MINISLANG=minislang STUBS=stubs endif -SUBDIRSHD = balkan isys collage $(MINISLANG) loader po \ +SUBDIRSHD = balkan isys collage $(MINISLANG) po \ textw utils scripts bootdisk installclasses \ keymaps fonts iw pixmaps $(STUBS) iconvmodule SUBDIRS = $(SUBDIRSHD) @@ -102,6 +102,7 @@ create-snapshot: @cd /tmp/anaconda ; rm -rf comps @cd /tmp/anaconda ; rm -rf help @cd /tmp/anaconda ; rm -rf text-help + @cd /tmp/anaconda ; rm -rf booty @cd /tmp/anaconda ; sed -e "s/@@VERSION@@/$(VERSION)/g" -e "s/@@RELEASE@@/$(SNAPRELEASE)/g" < anaconda.spec.in > anaconda.spec @mv /tmp/anaconda /tmp/anaconda-$(VERSION) @cd /tmp ; tar --bzip2 -cSpf anaconda-$(VERSION).tar.bz2 anaconda-$(VERSION) @@ -29,7 +29,6 @@ import sys, os # For anaconda in test mode if (os.path.exists('isys')): - sys.path.append('edd') sys.path.append('libfdisk') sys.path.append('balkan') sys.path.append('gnome-map') @@ -37,13 +36,14 @@ if (os.path.exists('isys')): sys.path.append('textw') sys.path.append('iw') sys.path.append('installclasses') - sys.path.append('edd') sys.path.append('iconvmodule') + sys.path.append('booty') else: sys.path.append('/usr/lib/anaconda') sys.path.append('/usr/lib/anaconda/textw') sys.path.append('/usr/lib/anaconda/iw') sys.path.append('/usr/lib/anaconda/installclasses') + sys.path.append('/usr/lib/booty') try: import updates_disk_hook @@ -289,9 +289,6 @@ if traceOnly: installclass.availableClasses() - if iutil.getArch() == "i386": - import edd - if display_mode == 't': for step in stepToClasses.keys(): if stepToClasses[step]: diff --git a/bootloader.py b/bootloader.py index c9f6fee07..f6b6a8e0c 100644 --- a/bootloader.py +++ b/bootloader.py @@ -1,10 +1,10 @@ # -# bootloader.py: bootloader configuration data +# bootloader.py: anaconda bootloader shims # # Erik Troan <ewt@redhat.com> # Jeremy Katz <katzj@redhat.com> # -# Copyright 2001 Red Hat, Inc. +# Copyright 2001-2002 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. @@ -22,884 +22,14 @@ import whrandom import language import iutil import string -if iutil.getArch() == "i386": - import edd from flags import flags from log import log from constants import * -from lilo import LiloConfigFile from translate import _ -## if 0: -## if arch == "sparc": -## errors = self.silo.install (self.fstab, instPath, -## id.hdList, upgrade) -## elif arch == "i386": -## defaultlang = self.language.getLangNickByName(self.language.getDefault()) -## langlist = expandLangs(defaultlang) -## errors = self.lilo.install (self.fstab, instPath, -## id.hdList, upgrade, langlist) -## elif arch == "ia64": -## errors = self.eli.install (self.fstab, instPath, -## id.hdList, upgrade) -## elif arch == "alpha": -## errors = self.milo.write () -## else: -## raise RuntimeError, "What kind of machine is this, anyway?!" +from booty import * +from bootloaderInfo import * -## if errors: -## w.pop() -## mess = _("An error occured while installing " -## "the bootloader.\n\n" -## "We HIGHLY recommend you make a recovery " -## "boot floppy when prompted, otherwise you " -## "may not be able to reboot into Red Hat Linux." -## "\n\nThe error reported was:\n\n") + errors -## intf.messageWindow(_("Bootloader Errors"), mess) - -## # make sure bootdisk window appears -## if iutil.getArch () == "i386": -## self.instClass.removeFromSkipList('bootdisk') -## self.bootdisk = 1 - -## w = apply(apply, createWindow) - - -class KernelArguments: - - def get(self): - return self.args - - def set(self, args): - self.args = args - - def __init__(self): - str = "" - - if iutil.getArch() == "s390": - if os.environ.has_key("DASD"): - str = str + "dasd=" + os.environ["DASD"] - - cdrw = isys.ideCdRwList() - for device in cdrw: - if str: str = str + " " - str = str + ("%s=ide-scsi" % device) - - self.args = str - -class BootImages: - - # returns dictionary of (label, longlabel, devtype) pairs indexed by device - def getImages(self): - # return a copy so users can modify it w/o affecting us - - dict = {} - for key in self.images.keys(): - dict[key] = self.images[key] - - return dict - - def setImageLabel(self, dev, label, setLong = 0): - if setLong: - self.images[dev] = (self.images[dev][0], label, self.images[dev][2]) - else: - self.images[dev] = (label, self.images[dev][1], self.images[dev][2]) - - - # default is a device - def setDefault(self, default): - self.default = default - - def getDefault(self): - return self.default - - def setup(self, diskSet, fsset): - devices = {} - devs = availableBootDevices(diskSet, fsset) - for (dev, type) in devs: - devices[dev] = 1 - - # These partitions have disappeared - for dev in self.images.keys(): - if not devices.has_key(dev): del self.images[dev] - - # These have appeared - for (dev, type) in devs: - if not self.images.has_key(dev): - if type == "FAT": - self.images[dev] = ("DOS", "DOS", type) - else: - self.images[dev] = (None, None, type) - - if not self.images.has_key(self.default): - entry = fsset.getEntryByMountPoint('/') - self.default = entry.device.getDevice() - (label, longlabel, type) = self.images[self.default] - if not label: - self.images[self.default] = ("linux", "Red Hat Linux", type) - - def __init__(self): - self.default = None - self.images = {} - - -class bootloaderInfo: - def setUseGrub(self, val): - pass - - def useGrub(self): - return self.useGrubVal - - def setForceLBA(self, val): - pass - - def setPassword(self, val, isCrypted = 1): - pass - - def getPassword(self): - pass - - def getDevice(self): - return self.device - - def setDevice(self, device): - self.device = device - - def getBootloaderConfig(self, instRoot, fsset, bl, langs, kernelList, - chainList, defaultDev): - images = bl.images.getImages() - - # on upgrade read in the lilo config file - lilo = LiloConfigFile () - self.perms = 0644 - if os.access (instRoot + self.configfile, os.R_OK): - self.perms = os.stat(instRoot + self.configfile)[0] & 0777 - lilo.read (instRoot + self.configfile) - os.rename(instRoot + self.configfile, - instRoot + self.configfile + '.rpmsave') - - # Remove any invalid entries that are in the file; we probably - # just removed those kernels. - for label in lilo.listImages(): - (fsType, sl) = lilo.getImage(label) - if fsType == "other": continue - - if not os.access(instRoot + sl.getPath(), os.R_OK): - lilo.delImage(label) - - lilo.addEntry("prompt", replace = 0) - lilo.addEntry("timeout", "50", replace = 0) - - rootDev = fsset.getEntryByMountPoint("/").device.getDevice() - if not rootDev: - raise RuntimeError, "Installing lilo, but there is no root device" - - if rootDev == defaultDev: - lilo.addEntry("default", kernelList[0][0]) - else: - lilo.addEntry("default", chainList[0][0]) - - for (label, longlabel, version) in kernelList: - kernelTag = "-" + version - kernelFile = self.kernelLocation + "vmlinuz" + kernelTag - - try: - lilo.delImage(label) - except IndexError, msg: - pass - - sl = LiloConfigFile(imageType = "image", path = kernelFile) - - initrd = makeInitrd (kernelTag, instRoot) - - sl.addEntry("label", label) - if os.access (instRoot + initrd, os.R_OK): - sl.addEntry("initrd", "%sinitrd%s.img" %(self.kernelLocation, kernelTag)) - - sl.addEntry("read-only") - sl.addEntry("root", '/dev/' + rootDev) - - if self.args.get(): - sl.addEntry('append', '"%s"' % self.args.get()) - - lilo.addImage (sl) - - for (label, longlabel, device) in chainList: - if ((not label) or (label == "")): - continue - try: - (fsType, sl) = lilo.getImage(label) - lilo.delImage(label) - except IndexError: - sl = LiloConfigFile(imageType = "other", path = "/dev/%s" %(device)) - sl.addEntry("optional") - - sl.addEntry("label", label) - lilo.addImage (sl) - - # Sanity check #1. There could be aliases in sections which conflict - # with the new images we just created. If so, erase those aliases - imageNames = {} - for label in lilo.listImages(): - imageNames[label] = 1 - - for label in lilo.listImages(): - (fsType, sl) = lilo.getImage(label) - if sl.testEntry('alias'): - alias = sl.getEntry('alias') - if imageNames.has_key(alias): - sl.delEntry('alias') - imageNames[alias] = 1 - - # Sanity check #2. If single-key is turned on, go through all of - # the image names (including aliases) (we just built the list) and - # see if single-key will still work. - if lilo.testEntry('single-key'): - singleKeys = {} - turnOff = 0 - for label in imageNames.keys(): - l = label[0] - if singleKeys.has_key(l): - turnOff = 1 - singleKeys[l] = 1 - if turnOff: - lilo.delEntry('single-key') - - return lilo - - def write(self, instRoot, fsset, bl, langs, kernelList, chainList, - defaultDev, justConfig, intf): - if len(kernelList) >= 1: - config = self.getBootloaderConfig(instRoot, fsset, bl, langs, - kernelList, chainList, - defaultDev) - config.write(instRoot + self.configfile, perms = self.perms) - else: - self.noKernelsWarn(intf) - - return "" - - # XXX in the future we also should do some validation on the config - # file that's already there - def noKernelsWarn(self, intf): - intf.messageWindow(_("Warning"), - _("No kernel packages were installed on your " - "system. Your boot loader configuration " - "will not be changed.")) - - def getArgList(self): - args = [] - - if self.args.get(): - args.append("--append") - args.append(self.args.get()) - - return args - - def writeKS(self, f): - f.write("bootloader") - for arg in self.getArgList(): - f.write(" " + arg) - f.write("\n") - - def __init__(self): - self.args = KernelArguments() - self.images = BootImages() - self.device = None - self.useLinear = 1 # only used for kickstart compatibility - self.defaultDevice = None # XXX hack, used by kickstart - self.useGrubVal = 0 # only used on x86 - self.configfile = None - self.kernelLocation = "/boot/" - self.forceLBA32 = 0 - self.password = None - self.pure = None - self.above1024 = 0 - -class ia64BootloaderInfo(bootloaderInfo): - # XXX wouldn't it be nice to have a real interface to use efibootmgr from? - def removeOldEfiEntries(self, instRoot): - p = os.pipe() - iutil.execWithRedirect('/usr/sbin/efibootmgr', ["efibootmgr"], - root = instRoot, stdout = p[1]) - os.close(p[1]) - - c = os.read(p[0], 1) - buf = c - while (c): - c = os.read(p[0], 1) - buf = buf + c - os.close(p[0]) - lines = string.split(buf, '\n') - for line in lines: - fields = string.split(line) - if len(fields) < 4: - continue - if fields[1:4] == ["Red","Hat","Linux"]: - entry = fields[0][4:8] - iutil.execWithRedirect('/usr/sbin/efibootmgr', - ["efibootmgr", "-b", entry, "-B"], - root = instRoot, - stdout="/dev/tty5", stderr="/dev/tty5") - - - def writeLilo(self, instRoot, fsset, bl, langs, kernelList, - chainList, defaultDev, justConfig): - config = self.getBootloaderConfig(instRoot, fsset, bl, langs, - kernelList, chainList, defaultDev) - config.write(instRoot + self.configfile, perms = self.perms) - - return "" - - def write(self, instRoot, fsset, bl, langs, kernelList, chainList, - defaultDev, justConfig, intf): - if len(kernelList) >= 1: - str = self.writeLilo(instRoot, fsset, bl, langs, kernelList, - chainList, defaultDev, justConfig) - else: - self.noKernelsWarn(intf) - - bootdev = fsset.getEntryByMountPoint("/boot/efi").device.getDevice() - if not bootdev: - bootdev = fsset.getEntryByDeviceName("sda1").device.getDevice() - - ind = len(bootdev) - try: - while (bootdev[ind-1] in string.digits): - ind = ind - 1 - except IndexError: - ind = len(bootdev) - 1 - - bootdisk = bootdev[:ind] - bootpart = bootdev[ind:] - if (bootdisk.startswith('ida/') or bootdisk.startswith('cciss/') or - bootdisk.startswith('rd/')): - bootdisk = bootdisk[:-1] - - self.removeOldEfiEntries(instRoot) - - argv = [ "/usr/sbin/efibootmgr", "-c" , "-w", "-L", - "Red Hat Linux", "-d", "/dev/%s" % bootdisk, "-p", bootpart ] - iutil.execWithRedirect(argv[0], argv, root = instRoot, - stdout = "/dev/tty5", - stderr = "/dev/tty5") - - def __init__(self): - bootloaderInfo.__init__(self) - self.useGrubVal = 1 - self.kernelLocation = "" - self.configfile = "/boot/efi/elilo.conf" - - -class x86BootloaderInfo(bootloaderInfo): - def setPassword(self, val, isCrypted = 1): - if not val: - self.password = val - self.pure = val - return - - if isCrypted: - self.password = val - else: - salt = "$1$" - saltLen = 8 - - for i in range(saltLen): - salt = salt + whrandom.choice (string.letters + - string.digits + './') - - self.password = crypt.crypt (val, salt) - self.pure = val - - def getPassword (self): - return self.pure - - def setForceLBA(self, val): - self.forceLBA32 = val - - def setUseGrub(self, val): - self.useGrubVal = val - - def writeGrub(self, instRoot, fsset, bl, langs, kernelList, chainList, - defaultDev, justConfigFile): - if len(kernelList) < 1: - return "" - - images = bl.images.getImages() - rootDev = fsset.getEntryByMountPoint("/").device.getDevice() - - if not os.path.isdir(instRoot + '/boot/grub/'): - os.mkdir(instRoot + '/boot/grub', 0755) - - cf = '/boot/grub/grub.conf' - self.perms = 0600 - if os.access (instRoot + cf, os.R_OK): - self.perms = os.stat(instRoot + cf)[0] & 0777 - os.rename(instRoot + cf, - instRoot + cf + '.rpmsave') - - grubTarget = bl.getDevice() - # XXX wouldn't it be nice if grub really understood raid? :) - if grubTarget.startswith('md'): - device = fsset.getEntryByDeviceName(grubTarget).device.members[0] - (grubTarget, None) = getDiskPart(device) - - f = open(instRoot + cf, "w+") - - f.write("# grub.conf generated by anaconda\n") - f.write("#\n") - f.write("# Note that you do not have to rerun grub " - "after making changes to this file\n") - - bootDev = fsset.getEntryByMountPoint("/boot") - grubPath = "/grub" - cfPath = "/" - if not bootDev: - bootDev = fsset.getEntryByMountPoint("/") - grubPath = "/boot/grub" - cfPath = "/boot/" - f.write ("# NOTICE: You do not have a /boot partition. This means that\n") - f.write ("# all kernel and initrd paths are relative to /, eg.\n") - else: - f.write ("# NOTICE: You have a /boot partition. This means that\n") - f.write ("# all kernel and initrd paths are relative to /boot/, eg.\n") - - bootDev = bootDev.device.getDevice(asBoot = 1) - - f.write ('# root %s\n' % grubbyPartitionName(bootDev)) - f.write ("# kernel %svmlinuz-version ro root=/dev/%s\n" % (cfPath, rootDev)) - f.write ("# initrd %sinitrd-version.img\n" % (cfPath)) - f.write("#boot=/dev/%s\n" % (grubTarget)) - - # get the default image to boot... we have to walk and find it - # since grub indexes by where it is in the config file - if defaultDev == rootDev: - default = 0 - else: - # if the default isn't linux, it's the first thing in the - # chain list - default = len(kernelList) - - # keep track of which devices are used for the device.map - usedDevs = {} - - f.write('default=%s\n' % (default)) - f.write('timeout=10\n') - f.write('splashimage=%s%sgrub/splash.xpm.gz\n' - % (grubbyPartitionName(bootDev), cfPath)) - - usedDevs[bootDev] = 1 - usedDevs[grubTarget] = 1 - - if self.password: - f.write('password --md5 %s\n' %(self.password)) - - for (label, longlabel, version) in kernelList: - kernelTag = "-" + version - kernelFile = "%svmlinuz%s" % (cfPath, kernelTag) - - initrd = makeInitrd (kernelTag, instRoot) - - f.write('title %s (%s)\n' % (longlabel, version)) - f.write('\troot %s\n' % grubbyPartitionName(bootDev)) - f.write('\tkernel %s ro root=/dev/%s' % (kernelFile, rootDev)) - if self.args.get(): - f.write(' %s' % self.args.get()) - f.write('\n') - - if os.access (instRoot + initrd, os.R_OK): - f.write('\tinitrd %sinitrd%s.img\n' % (cfPath, kernelTag)) - - for (label, longlabel, device) in chainList: - if ((not longlabel) or (longlabel == "")): - continue - f.write('title %s\n' % (longlabel)) - f.write('\trootnoverify %s\n' % grubbyPartitionName(device)) -# f.write('\tmakeactive\n') - f.write('\tchainloader +1') - f.write('\n') - usedDevs[device] = 1 - - f.close() - os.chmod(instRoot + "/boot/grub/grub.conf", self.perms) - - # make a symlink for menu.lst since it's the default config file name - if os.access (instRoot + "/boot/grub/menu.lst", os.R_OK): - os.rename(instRoot + "/boot/grub/menu.lst", - instRoot + "/boot/grub/menu.lst.rpmsave") - os.symlink("./grub.conf", instRoot + "/boot/grub/menu.lst") - - # make a symlink for /etc/grub.conf since config files belong in /etc - if os.access (instRoot + "/etc/grub.conf", os.R_OK): - os.rename(instRoot + "/etc/grub.conf", - instRoot + "/etc/grub.conf.rpmsave") - os.symlink("../boot/grub/grub.conf", instRoot + "/etc/grub.conf") - - - if not os.access(instRoot + "/boot/grub/device.map", os.R_OK): - f = open(instRoot + "/boot/grub/device.map", "w+") - f.write("# this device map was generated by anaconda\n") - f.write("(fd0) /dev/fd0\n") - devs = usedDevs.keys() - devs.sort() - usedDevs = {} - for dev in devs: - drive = getDiskPart(dev)[0] - if usedDevs.has_key(drive): - continue - f.write("(%s) /dev/%s\n" % (grubbyDiskName(drive), drive)) - usedDevs[drive] = 1 - f.close() - - if self.forceLBA32: - forcelba = "--force-lba " - else: - forcelba = "" - - part = grubbyPartitionName(bootDev) - prefix = "%s/%s" % (grubbyPartitionName(bootDev), grubPath) - cmd = "root %s\ninstall %s%s/stage1 d %s %s/stage2 p %s%s/grub.conf" % \ - (part, forcelba, grubPath, grubbyPartitionName(grubTarget), - grubPath, part, grubPath) - - if not justConfigFile: - log("GRUB command %s", cmd) - - # copy the stage files over into /boot - iutil.execWithRedirect( "/sbin/grub-install", - ["/sbin/grub-install", "--just-copy"], - stdout = "/dev/tty5", stderr = "/dev/tty5", - root = instRoot) - - - # really install the bootloader - p = os.pipe() - os.write(p[1], cmd + '\n') - os.close(p[1]) - iutil.execWithRedirect('/sbin/grub' , - [ "grub", "--batch", "--no-floppy", - "--device-map=/boot/grub/device.map" ], - stdin = p[0], - stdout = "/dev/tty5", stderr = "/dev/tty5", - root = instRoot) - os.close(p[0]) - - return "" - - def getBootloaderConfig(self, instRoot, fsset, bl, langs, kernelList, - chainList, defaultDev): - config = bootloaderInfo.getBootloaderConfig(self, instRoot, fsset, bl, langs, - kernelList, chainList, - defaultDev) - - liloTarget = bl.getDevice() - - config.addEntry("boot", '/dev/' + liloTarget, replace = 0) - config.addEntry("map", "/boot/map", replace = 0) - config.addEntry("install", "/boot/boot.b", replace = 0) - message = "/boot/message" - for lang in language.expandLangs(langs.getDefault()): - fn = "/boot/message." + lang - if os.access(instRoot + fn, os.R_OK): - message = fn - break - - config.addEntry("message", message, replace = 0) - - if not config.testEntry('lba32') and not config.testEntry('linear'): - if self.forceLBA32 or (bl.above1024 and edd.detect()): - config.addEntry("lba32", replace = 0) - elif self.useLinear: - config.addEntry("linear", replace = 0) - else: - config.addEntry("nolinear", replace = 0) - - return config - - def writeLilo(self, instRoot, fsset, bl, langs, kernelList, - chainList, defaultDev, justConfig): - if len(kernelList) >= 1: - config = self.getBootloaderConfig(instRoot, fsset, bl, langs, - kernelList, chainList, defaultDev) - config.write(instRoot + self.configfile, perms = self.perms) - - if not justConfig: - # throw away stdout, catch stderr - str = iutil.execWithCapture(instRoot + '/sbin/lilo' , - [ "lilo", "-r", instRoot ], - catchfd = 2, closefd = 1) - else: - str = "" - - return str - - def write(self, instRoot, fsset, bl, langs, kernelList, chainList, - defaultDev, justConfig, intf): - if len(kernelList) < 1: - self.noKernelsWarn(intf) - - str = self.writeLilo(instRoot, fsset, bl, langs, kernelList, - chainList, defaultDev, - justConfig | (self.useGrubVal)) - str = self.writeGrub(instRoot, fsset, bl, langs, kernelList, - chainList, defaultDev, - justConfig | (not self.useGrubVal)) - # XXX move the lilo.conf out of the way if they're using GRUB - # so that /sbin/installkernel does a more correct thing - if self.useGrubVal and os.access(instRoot + '/etc/lilo.conf', os.R_OK): - os.rename(instRoot + "/etc/lilo.conf", - instRoot + "/etc/lilo.conf.anaconda") - - - - def getArgList(self): - args = bootloaderInfo.getArgList(self) - - if not self.useGrubVal: - args.append("--useLilo") - if self.forceLBA32: - args.append("--lba32") - if not self.useLinear: - args.append("--nolinear") - if self.password: - args.append("--md5pass=%s" %(self.password)) - - - # XXX add location of bootloader here too - - return args - - def __init__(self): - bootloaderInfo.__init__(self) - self.useGrubVal = 1 - self.kernelLocation = "/boot/" - self.configfile = "/etc/lilo.conf" - self.password = None - self.pure = None - -class s390BootloaderInfo(bootloaderInfo): - def getBootloaderConfig(self, instRoot, fsset, bl, langs, kernelList, - chainList, defaultDev): - images = bl.images.getImages() - - # on upgrade read in the lilo config file - lilo = LiloConfigFile () - self.perms = 0644 - if os.access (instRoot + self.configfile, os.R_OK): - self.perms = os.stat(instRoot + self.configfile)[0] & 0777 - lilo.read (instRoot + self.configfile) - os.rename(instRoot + self.configfile, - instRoot + self.configfile + '.rpmsave') - - # Remove any invalid entries that are in the file; we probably - # just removed those kernels. - for label in lilo.listImages(): - (fsType, sl) = lilo.getImage(label) - if fsType == "other": continue - - if not os.access(instRoot + sl.getPath(), os.R_OK): - lilo.delImage(label) - - #lilo.addEntry("prompt", replace = 0) - #lilo.addEntry("timeout", "50", replace = 0) - - rootDev = fsset.getEntryByMountPoint("/").device.getDevice() - if not rootDev: - raise RuntimeError, "Installing zilo, but there is no root device" - - if rootDev == defaultDev: - lilo.addEntry("default", kernelList[0][0]) - else: - lilo.addEntry("default", chainList[0][0]) - - for (label, longlabel, version) in kernelList: - kernelTag = "-" + version - kernelFile = self.kernelLocation + "vmlinuz" + kernelTag - - try: - lilo.delImage(label) - except IndexError, msg: - pass - - sl = LiloConfigFile(imageType = "image", path = kernelFile) - - initrd = makeInitrd (kernelTag, instRoot) - - sl.addEntry("label", label) - if os.access (instRoot + initrd, os.R_OK): - sl.addEntry("initrd", - "%sinitrd%s.img" %(self.kernelLocation, kernelTag)) - - sl.addEntry("read-only") - sl.addEntry("root", '/dev/' + rootDev) - sl.addEntry("ipldevice", '/dev/' + rootDev[:-1]) - - if self.args.get(): - sl.addEntry('append', '"%s"' % self.args.get()) - - lilo.addImage (sl) - - for (label, longlabel, device) in chainList: - if ((not label) or (label == "")): - continue - try: - (fsType, sl) = lilo.getImage(label) - lilo.delImage(label) - except IndexError: - sl = LiloConfigFile(imageType = "other", - path = "/dev/%s" %(device)) - sl.addEntry("optional") - - sl.addEntry("label", label) - lilo.addImage (sl) - - # Sanity check #1. There could be aliases in sections which conflict - # with the new images we just created. If so, erase those aliases - imageNames = {} - for label in lilo.listImages(): - imageNames[label] = 1 - - for label in lilo.listImages(): - (fsType, sl) = lilo.getImage(label) - if sl.testEntry('alias'): - alias = sl.getEntry('alias') - if imageNames.has_key(alias): - sl.delEntry('alias') - imageNames[alias] = 1 - - # Sanity check #2. If single-key is turned on, go through all of - # the image names (including aliases) (we just built the list) and - # see if single-key will still work. - if lilo.testEntry('single-key'): - singleKeys = {} - turnOff = 0 - for label in imageNames.keys(): - l = label[0] - if singleKeys.has_key(l): - turnOff = 1 - singleKeys[l] = 1 - if turnOff: - lilo.delEntry('single-key') - - return lilo - - def writeChandevConf(self, instroot): # S/390 only - cf = "/etc/chandev.conf" - self.perms = 0644 - if os.environ.has_key("CHANDEV"): - fd = os.open(instroot + "/etc/chandev.conf", - os.O_WRONLY | os.O_CREAT) - os.write(fd, os.environ["CHANDEV"]) - os.close(fd) - return "" - - - def writeZipl(self, instRoot, fsset, bl, langs, kernelList, chainList, - defaultDev, justConfigFile): - images = bl.images.getImages() - rootDev = fsset.getEntryByMountPoint("/").device.getDevice() - - cf = '/etc/zipl.conf' - self.perms = 0600 - if os.access (instRoot + cf, os.R_OK): - self.perms = os.stat(instRoot + cf)[0] & 0777 - os.rename(instRoot + cf, - instRoot + cf + '.rpmsave') - - f = open(instRoot + cf, "w+") - - f.write('[defaultboot]\n') - f.write('default=' + kernelList[0][0] + '\n') - - cfPath = "/boot/" - for (label, longlabel, version) in kernelList: - kernelTag = "-" + version - kernelFile = "%svmlinuz%s" % (cfPath, kernelTag) - - initrd = makeInitrd (kernelTag, instRoot) - f.write('[%s]\n' % (label)) - f.write('\ttarget=%s\n' % (self.kernelLocation)) - f.write('\timage=%s\n' % (kernelFile)) - if os.access (instRoot + initrd, os.R_OK): - f.write("ramdisk=%sinitrd%s.img\n" %(self.kernelLocation, - kernelTag)) - if self.args.get(): - f.write('\tparameters="root=/dev/%s %s"\n' % (rootDev, - self.args.get())) - f.write('\n') - - f.close() - - if not justConfigFile: - argv = [ "/sbin/zipl" ] - iutil.execWithRedirect(argv[0], argv, root = instRoot, - stdout = "/dev/tty5", - stderr = "/dev/tty5") - - return "" - - def writeZilo(self, instRoot, fsset, bl, langs, kernelList, - chainList, defaultDev, justConfig): - config = self.getBootloaderConfig(instRoot, fsset, bl, langs, - kernelList, chainList, defaultDev) - config.write(instRoot + self.configfile, perms = self.perms) - - if not justConfig: - # throw away stdout, catch stderr - str = iutil.execWithCapture(instRoot + '/sbin/zilo' , - [ "zilo", "-r", instRoot ], - catchfd = 2, closefd = 1) - else: - str = "" - - return str - - def write(self, instRoot, fsset, bl, langs, kernelList, chainList, - defaultDev, justConfig, intf): - str = self.writeZilo(instRoot, fsset, bl, langs, kernelList, - chainList, defaultDev, - justConfig | (self.useZiplVal)) - str = self.writeZipl(instRoot, fsset, bl, langs, kernelList, - chainList, defaultDev, - justConfig | (not self.useZiplVal)) - str = self.writeChandevConf(instRoot) - - def __init__(self): - bootloaderInfo.__init__(self) - self.useZiplVal = 1 # only used on s390 - self.kernelLocation = "/boot/" - self.configfile = "/etc/zilo.conf" - - -def availableBootDevices(diskSet, fsset): - devs = [] - foundDos = 0 - for (dev, type) in diskSet.partitionTypes(): - # XXX do we boot fat on anything other than i386? - if type == 'FAT' and not foundDos and iutil.getArch() == "i386": - isys.makeDevInode(dev, '/tmp/' + dev) - part = partitioning.get_partition_by_name(diskSet.disks, dev) - if part.native_type not in partitioning.dosPartitionTypes: - continue - - try: - bootable = isys.checkBoot('/tmp/' + dev) - devs.append((dev, type)) - foundDos = 1 - except: - pass - elif type == 'ntfs' or type =='hpfs': - devs.append((dev, type)) - - slash = fsset.getEntryByMountPoint('/') - if not slash or not slash.device or not slash.fsystem: - raise ValueError, ("Trying to pick boot devices but do not have a " - "sane root partition. Aborting install.") - devs.append((slash.device.getDevice(), slash.fsystem.getName())) - - devs.sort() - - return devs def bootloaderSetupChoices(dispatch, bl, fsset, diskSet, dir): if dir == DISPATCH_BACK: @@ -929,7 +59,8 @@ def bootloaderSetupChoices(dispatch, bl, fsset, diskSet, dir): bootDev = fsset.getEntryByMountPoint("/") if not bootDev: bootDev = fsset.getEntryByMountPoint("/boot") - part = partitioning.get_partition_by_name(diskSet.disks, bootDev.device.getDevice()) + part = partitioning.get_partition_by_name(diskSet.disks, + bootDev.device.getDevice()) if part and partitioning.end_sector_to_cyl(part.geom.disk.dev, part.geom.end) >= 1024: bl.above1024 = 1 @@ -982,57 +113,7 @@ def makeInitrd (kernelTag, instRoot): return initrd -# return (disk, partition number) eg ('hda', 1) -def getDiskPart(dev): - cut = len(dev) - if (dev.startswith('rd/') or dev.startswith('ida/') or - dev.startswith('cciss/')): - if dev[-2] == 'p': - cut = -1 - elif dev[-3] == 'p': - cut = -2 - else: - if dev[-2] in string.digits: - cut = -2 - elif dev[-1] in string.digits: - cut = -1 - - name = dev[:cut] - - # hack off the trailing 'p' from /dev/cciss/*, for example - if name[-1] == 'p': - for letter in name: - if letter not in string.letters and letter != "/": - name = name[:-1] - break - - if cut < 0: - partNum = int(dev[cut:]) - 1 - else: - partNum = None - - return (name, partNum) - -def grubbyDiskName(name): - drives = isys.hardDriveDict().keys() - drives.sort (isys.compareDrives) - - return "hd%d" % drives.index(name) - -def grubbyPartitionName(dev): - (name, partNum) = getDiskPart(dev) - if partNum != None: - return "(%s,%d)" % (grubbyDiskName(name), partNum) - else: - return "(%s)" %(grubbyDiskName(name)) - # return instance of the appropriate bootloader for our arch def getBootloader(): - if iutil.getArch() == 'i386': - return x86BootloaderInfo() - elif iutil.getArch() == 'ia64': - return ia64BootloaderInfo() - elif iutil.getArch() == 's390': - return s390BootloaderInfo() - else: - return bootloaderInfo() + import booty + return booty.getBootloader() diff --git a/dispatch.py b/dispatch.py index 4014274c1..54cab878e 100644 --- a/dispatch.py +++ b/dispatch.py @@ -84,7 +84,8 @@ installSteps = [ "id.fsset", "id.diskset", "dir")), ("bootloader", ("dispatch", "id.bootloader", "id.fsset", "id.diskset")), - ("bootloaderpassword", ("id.bootloader", "intf")), + ("bootloaderadvanced", ("dispatch", "id.bootloader", "id.fsset", + "id.diskset")), ("networkdevicecheck", networkDeviceCheck, ("id.network", "dispatch")), ("network", ("id.network",)), ("firewall", ("intf", "id.network", "id.firewall")), @@ -712,6 +712,7 @@ class FileSystemSet: def bootloaderChoices(self, diskSet): mntDict = {} + ret = {} for entry in self.entries: mntDict[entry.mountpoint] = entry.device @@ -724,13 +725,14 @@ class FileSystemSet: bootDev = mntDict['/'] if bootDev.getName() == "LoopbackDevice": - return None + return ret 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")) - ] + ret['boot'] = (bootDev.device, N_("RAID Device")) + return ret + + ret['boot'] = (bootDev.device, N_("First sector of boot partition")) + ret['mbr'] = (bootDev.device, N_("Master Boot Record (MBR)")) + return ret # set active partition on disks # if an active partition is set, leave it alone; if none set @@ -739,10 +741,8 @@ class FileSystemSet: choices = self.bootloaderChoices(diskset) if not choices: bootDev = None - elif len(choices) == 1: - bootDev = self.bootloaderChoices(diskset)[0][0] else: - bootDev = self.bootloaderChoices(diskset)[1][0] + bootDev = choices['boot'][0] # stupid itanium if iutil.getArch() == "ia64": @@ -44,8 +44,8 @@ stepToClass = { "upgrademigratefs" : ("upgrade_migratefs_gui", "UpgradeMigrateFSWindow"), "fdisk" : ("fdisk_gui", "FDiskWindow"), "fdasd" : ("fdasd_gui", "FDasdWindow"), - "bootloader": ("bootloader_gui", "BootloaderWindow"), - "bootloaderpassword" : ("bootloaderpassword_gui", "BootloaderPasswordWindow"), + "bootloader": ("bootloader_gui", "BootloaderWindow"), + "bootloaderadvanced": ("bootloader_gui", "AdvancedBootloaderWindow"), "network" : ("network_gui", "NetworkWindow"), "firewall" : ("firewall_gui", "FirewallWindow"), "languagesupport" : ("language_support_gui", "LanguageSupportWindow"), @@ -75,6 +75,8 @@ elif iutil.getArch() == 's390': stepToClass["bootloader"] = ("zipl_gui", "ZiplWindow") else: stepToClass["bootloader"] = ("bootloader_gui", "BootloaderWindow") + stepToClass["bootloaderadvanced"] = ("bootloader_gui", + "AdvancedBootloaderWindow") # setup globals diff --git a/installclass.py b/installclass.py index 1e7065fb1..6fe078467 100644 --- a/installclass.py +++ b/installclass.py @@ -82,7 +82,7 @@ class BaseInstallClass: "partitiondone", "bootloadersetup", "bootloader", - "bootloaderpassword", + "bootloaderadvanced", "networkdevicecheck", "network", "firewall", @@ -118,7 +118,7 @@ class BaseInstallClass: if iutil.getArch() == "alpha" or iutil.getArch() == "ia64": dispatch.skipStep("bootdisk") dispatch.skipStep("bootloader") - dispatch.skipStep("bootloaderpassword") + dispatch.skipStep("bootloaderadvanced") dispatch.skipStep("fdasd", permanent = 1) elif iutil.getArch() == "s390" or iutil.getArch() == "s390x": #dispatch.skipStep("language") @@ -129,7 +129,6 @@ class BaseInstallClass: dispatch.skipStep("autopartition", permanent = 1) dispatch.skipStep("autopartitionexecute", permanent = 1) dispatch.skipStep("fdisk", permanent = 1) - dispatch.skipStep("bootloaderpassword", permanent = 1) dispatch.skipStep("handleX11pkgs", permanent = 1) dispatch.skipStep("videocard", permanent = 1) diff --git a/iw/bootloader_gui.py b/iw/bootloader_gui.py index b6f961d0e..f7508561b 100644 --- a/iw/bootloader_gui.py +++ b/iw/bootloader_gui.py @@ -1,7 +1,9 @@ # # bootloader_gui.py: gui bootloader configuration dialog # -# Copyright 2001 Red Hat, Inc. +# Jeremy Katz <katzj@redhat.com> +# +# Copyright 2001-2002 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. @@ -12,42 +14,46 @@ # import gtk +import gobject import iutil import gui from iw_gui import * from translate import _, N_ -from package_gui import queryUpgradeContinue + +fbModes = {} +fbModes["8"] = { "640x480": 0x301, + "800x600": 0x303, + "1024x768": 0x305, + "1280x1024": 0x307 } +fbModes["16"] = { "640x480": 0x310, + "800x600": 0x313, + "1024x768": 0x316, + "1280x1024": 0x319} +fbModes["24"] = { "640x480": 0x311, + "800x600": 0x314, + "1024x768": 0x317, + "1280x1024": 0x31A } +fbModes["32"] = { "640x480": 0x312, + "800x600": 0x315, + "1024x768": 0x318, + "1280x1024": 0x31B } + class BootloaderWindow (InstallWindow): windowTitle = N_("Boot Loader Configuration") htmlTag = "bootloader" - def getPrev (self): - # avoid coming back in here if the user backs past and then tries - # to skip this screen - pass - - # XXX - # - # if doing an upgrade, offer choice of aborting upgrade. - # we can't allow them to go back in install, since we've - # started swap and mounted the systems filesystems - # if we've already started an upgrade, cannot back out - # - # if we are skipping indivual package selection, must stop it here - # very messy. - # - #if self.todo.upgrade and self.todo.instClass.skipStep("indivpackage"): - #rc = queryUpgradeContinue(self.todo.intf) - #if not rc: - #raise gui.StayOnScreen - #else: - #import sys - #print _("Aborting upgrade") - #sys.exit(0) - - def getNext (self): - if self.lba.get_active() and not self.bl.forceLBA32: + def __init__(self, ics): + InstallWindow.__init__(self, ics) + self.parent = ics.getICW().window + + + def getPrev(self): + pass + + + def getNext(self): + if self.forceLBA.get_active() and not self.bl.forceLBA32: rc = self.intf.messageWindow(_("Warning"), _("Forcing the use of LBA32 for your bootloader when " "not supported by the BIOS can cause your machine " @@ -58,435 +64,860 @@ class BootloaderWindow (InstallWindow): type = "yesno") if rc != 1: raise gui.StayOnScreen - - if self.none_radio.get_active (): - self.dispatch.skipStep("instbootloader") - self.dispatch.skipStep("bootloaderpassword") + + # set the bootloader type + if self.none_radio.get_active(): + self.dispatch.skipStep("instbootloader") return - elif self.lilo_radio.get_active (): - self.dispatch.skipStep("bootloaderpassword") - elif self.grub_radio.get_active (): - self.dispatch.skipStep("bootloaderpassword", skip = 0) - - if len(self.bootDevice.keys()) > 0: - self.dispatch.skipStep("instbootloader", skip = 0) + else: + self.bl.setUseGrub(self.grub_radio.get_active()) + self.dispatch.skipStep("instbootloader", skip = 0) + + if self.useFbcb.get_active(): + (res, depth) = self.fbMode + video = " vga=%s" % (fbModes[depth][res],) + else: + video = "" - for (widget, device) in self.bootDevice.items(): - if widget.get_active(): - self.bl.setDevice(device) + # set the bootloader pass XXX should handle the only crypted pass case + if self.usePassCb and self.password: + self.bl.setPassword(self.password, isCrypted = 0) + else: + self.bl.setPassword(None) - self.bl.setUseGrub(self.grub_radio.get_active()) - self.bl.args.set(self.appendEntry.get_text()) - - default = None - linuxDevice = None - for index in range(self.numImages): - device = self.imageList.get_text(index, 1)[5:] - type = self.types[index] - label = self.imageList.get_text(index, 3) + # set kernel args + self.bl.args.set(self.appendEntry.get_text() + video) - self.bl.images.setImageLabel(device, label, self.bl.useGrub()) + # set forcelba + self.bl.setForceLBA(self.forceLBA.get_active()) - if self.default == index: - default = device - if type == 2: - linuxDevice = device + def bootloaderChanged(self, widget, *args): + if widget == self.grub_radio and self.grub_radio.get_active(): + self.options_vbox.set_sensitive(gtk.TRUE) + elif widget == self.lilo_radio and self.lilo_radio.get_active(): + self.options_vbox.set_sensitive(gtk.TRUE) + elif widget == self.none_radio and self.none_radio.get_active(): + self.options_vbox.set_sensitive(gtk.FALSE) + else: + # punt + pass + - if not default: - default = linuxDevice + def fbModeWindow(self, *args): + resolutions = [ "640x480", "800x600", "1024x768", "1280x1024" ] + depths = [ 8, 16, 24, 32 ] - self.bl.images.setDefault(default) - self.bl.setForceLBA(self.lba.get_active()) + if self.fbMode: + theResolution = self.fbMode[0] + theDepth = self.fbMode[1] + else: + # XXX better defaults + theResolution = resolutions[0] + theDepth = depths[0] + + dialog = gtk.Dialog(_("Select framebuffer resolution"), self.parent) + dialog.add_button('gtk-ok', 1) + dialog.add_button('gtk-cancel', 2) + dialog.set_position(gtk.WIN_POS_CENTER) + + label = gui.WrappingLabel(_("Please select the resolution and bit " + "depth that you would prefer to use as " + "your framebuffer settings.")) + dialog.vbox.pack_start(label) + + + hbox = gtk.HBox(gtk.FALSE, 5) + + frame = gtk.Frame(_("Resolution")) + bbox = gtk.VButtonBox() + + resRadio = None + group = [] + # XXX need to make sure the resolutions are actually viable for + # their vidcard/monitor + for resolution in resolutions: + resRadio = gtk.RadioButton(resRadio, resolution) + if resolution == theResolution: + resRadio.set_active(gtk.TRUE) + bbox.pack_start(resRadio) + group.append(resRadio) + resRadio.group = group + + frame.add(bbox) + hbox.pack_start(frame) + + frame = gtk.Frame(_("Bit Depth")) + bbox = gtk.VButtonBox() + + depthRadio = None + group = [] + # XXX need to make sure the depths are actually viable for + # their vidcard/monitor + for depth in depths: + depthRadio = gtk.RadioButton(depthRadio, _("%d") % (depth,)) + if "%d" % (depth,) == theDepth: + depthRadio.set_active(gtk.TRUE) + bbox.pack_start(depthRadio) + group.append(depthRadio) + depthRadio.group = group + + frame.add(bbox) + hbox.pack_start(frame) + dialog.vbox.pack_start(hbox) + dialog.show_all() + + rc = dialog.run() + # user hit cancel, destroy the dialog and return + if rc == 2: + dialog.destroy() + return rc + + for radio in resRadio.group: + if radio.get_active(): + resolution = radio.get_label() + break - def typeName(self, type): - if (type == "FAT"): - return "DOS/Windows" - elif (type == "hpfs"): - return "OS/2 / Windows NT" + for radio in depthRadio.group: + if radio.get_active(): + depth = radio.get_label() + break + + self.fbMode = (resolution, depth) + dialog.destroy() + return rc + + # set the label on the button for the framebuffer mode + def setFbModeLabel(self): + if not self.useFbcb.get_active() or not self.fbMode: + self.fbButton.set_label(_("No Framebuffer")) else: - return type - - def checkLiloReqs(self): - if self.default == None: - return 0 - - defaultlabel = self.imageList.get_text(self.default, 3) - if defaultlabel == "" or defaultlabel == None: - return 0 - - device = None - label = None - for i in range(self.numImages): - device = self.imageList.get_text(i, 1)[5:] - label = self.imageList.get_text(i, 3) - if device == self.rootdev: + # XXX need to translate numeric -> text properly + self.fbButton.set_label("%s @ %s" % self.fbMode) + self.fbButton.set_sensitive(gtk.TRUE) + + # callback for when the framebuffer mode checkbox is clicked + def fbCallback(self, widget, *args): + if not widget.get_active(): + self.fbButton.set_sensitive(gtk.FALSE) + self.setFbModeLabel() + else: + if self.fbModeWindow() == 2: + widget.set_active(0) + self.setFbModeLabel() + + # callback for when the framebuffer mode button is clicked + def fbButtonCallback(self, widget, *args): + self.fbModeWindow() + self.setFbModeLabel() + + # get the bootloader password + def passwordWindow(self, *args): + dialog = gtk.Dialog(_("Enter Boot Loader Password"), self.parent) + dialog.add_button('gtk-ok', 1) + dialog.add_button('gtk-cancel', 2) + dialog.set_position(gtk.WIN_POS_CENTER) + + label = gui.WrappingLabel(_("A boot loader password prevents users " + "from passing arbitrary options to the " + "kernel. For highest security, we " + "recommend setting a password, but this " + "is not necessary for more casual users.")) + label.set_alignment(0.0, 0.0) + dialog.vbox.pack_start(label) + + table = gtk.Table(2, 2) + table.set_row_spacings(5) + table.set_col_spacings(5) + table.attach(gtk.Label(_("Password:")), 0, 1, 2, 3, + gtk.FILL, 0, 10) + pwEntry = gtk.Entry (16) + pwEntry.set_visibility (gtk.FALSE) + table.attach(pwEntry, 1, 2, 2, 3, gtk.FILL, 0, 10) + table.attach(gtk.Label(_("Confirm:")), 0, 1, 3, 4, + gtk.FILL, 0, 10) + confirmEntry = gtk.Entry (16) + confirmEntry.set_visibility (gtk.FALSE) + table.attach(confirmEntry, 1, 2, 3, 4, gtk.FILL, 0, 10) + dialog.vbox.pack_start(table) + + # set the default + if self.password: + pwEntry.set_text(self.password) + confirmEntry.set_text(self.password) + + dialog.show_all() + + while 1: + rc = dialog.run() + if rc == 2: break - if label == "": - return 0 + if pwEntry.get_text() != confirmEntry.get_text(): + self.intf.messageWindow(_("Passwords don't match"), + _("Passwords do not match"), + type='warning') + continue + + thePass = pwEntry.get_text() + if not thePass: + continue + if len(thePass) < 6: + ret = self.intf.messageWindow(_("Warning"), + _("Your boot loader password is less than " + "six characters. We recommend a longer " + "boot loader password." + "\n\n" + "Would you like to continue with this " + "password?"), + type = "yesno") + if ret == 0: + continue + + self.password = thePass + break + + dialog.destroy() + return rc + + # set the label on the button for the bootloader password + def setPassLabel(self): + if not self.usePassCb.get_active() or not self.password: + self.passButton.set_label(_("No password")) + else: + self.passButton.set_label(_("Change password")) + self.passButton.set_sensitive(gtk.TRUE) + + # callback for when the password checkbox is clicked + def passCallback(self, widget, *args): + if not widget.get_active(): + self.passButton.set_sensitive(gtk.FALSE) + self.setPassLabel() + else: + if self.passwordWindow() == 2: + widget.set_active(0) + self.setPassLabel() + + # callback for when the password button is clicked + def passButtonCallback(self, widget, *args): + self.passwordWindow() + self.setPassLabel() + + # LiloWindow tag="lilo" + def getScreen(self, dispatch, bl, fsset, diskSet): + self.dispatch = dispatch + self.bl = bl + self.intf = dispatch.intf + + self.useFb = 0 + self.fbMode = None + + # find the video mode... this is pretty ugly + args = self.bl.args.get() + if args and args.find("vga=") != -1: + start = args.find("vga=") + end = args[start:].find(" ") + if end == -1: + end = len(args) + # grab just the number + video = args[start + 4:end] + args = args[:start] + args[end:] + + # traverse the dictionary looking for the mode + for depth in fbModes.keys(): + for res in fbModes[depth].keys(): + if int(video) == int(fbModes[depth][res]): + self.fbMode = (res, depth) + self.useFb = 1 + + if self.bl.getPassword(): + self.usePass = 1 + self.password = self.bl.getPassword() + else: + self.usePass = 0 + self.password = None - for i in range(self.numImages): - label1 = self.imageList.get_text(i, 3) - j = i+1 - while j < self.numImages: - label2 = self.imageList.get_text(j, 3) - if label1 == label2 and label1 != "": - return 0 - j = j + 1 + # main vbox + thebox = gtk.VBox (gtk.FALSE, 10) - return 1 + # radio buttons for type of boot loader to use + self.radio_vbox = gtk.VBox(gtk.FALSE, 2) + self.radio_vbox.set_border_width(5) - def toggled (self, widget, *args): - if self.ignoreSignals: - return + label = gui.WrappingLabel(_("Please select the boot loader that " + "the computer will use. GRUB is the " + "default boot loader. However, if you " + "do not wish to overwrite your current " + "boot loader, select \"Do not install " + "a boot loader.\" ")) + label.set_alignment(0.0, 0.0) + + self.grub_radio = gtk.RadioButton(None, (_("Use _GRUB as the " + "boot loader"))) + self.lilo_radio = gtk.RadioButton(self.grub_radio, (_("Use _LILO as " + "the boot loader"))) + self.none_radio = gtk.RadioButton(self.grub_radio, (_("Do not " + "install a " + "boot loader"))) + + + self.radio_vbox.pack_start(label, gtk.FALSE) + self.radio_vbox.pack_start(self.grub_radio, gtk.FALSE) + self.radio_vbox.pack_start(self.lilo_radio, gtk.FALSE) + self.radio_vbox.pack_start(self.none_radio, gtk.FALSE) + + # XXX this is kind of ugly + if dispatch.stepInSkipList("instbootloader"): + self.none_radio.set_active(gtk.TRUE) + elif not bl.useGrub(): + self.lilo_radio.set_active(gtk.TRUE) + else: + self.grub_radio.set_active(gtk.TRUE) + + self.grub_radio.connect("toggled", self.bootloaderChanged) + self.lilo_radio.connect("toggled", self.bootloaderChanged) + self.none_radio.connect("toggled", self.bootloaderChanged) + thebox.pack_start(self.radio_vbox, gtk.FALSE) + + thebox.pack_start (gtk.HSeparator(), gtk.FALSE) + + # kernel parameters: append, fb, password, lba32 + self.options_vbox = gtk.VBox(gtk.FALSE, 5) + spacer = gtk.Label("") + spacer.set_size_request(10, 1) + self.options_vbox.pack_start(spacer, gtk.FALSE) - if not widget.get_active (): - state = gtk.TRUE - if self.checkLiloReqs(): - self.ics.setNextEnabled (1) - else: - self.ics.setNextEnabled (0) + label = gui.WrappingLabel(_("The following affect options passed to " + "the kernel on boot. FIXME." + "Obviously there needs to be more explanatory text here and throughout and better spacing")) + label.set_alignment(0.0, 0.5) + self.options_vbox.pack_start(label, gtk.FALSE) + + # framebuffer mode widgets + callbacks + self.useFbcb = gtk.CheckButton(_("Use Framebuffer Mode")) + self.fbButton = gtk.Button() + if self.useFb: + self.useFbcb.set_active(gtk.TRUE) + self.fbButton.set_sensitive(gtk.TRUE) else: - state = gtk.FALSE - self.ics.setNextEnabled(1) - - list = self.bootDevice.keys() - list.extend ([self.appendEntry, self.editBox, self.imageList, - self.liloLocationBox, self.radioBox, self.sw]) - for n in list: - n.set_sensitive (state) - -# if state and not len(self.bootDevice.keys()) < 2: -# self.liloLocationBox.set_sensitive(0) -# self.grubCheck.set_sensitive(0) -# print "here" -# self.radio_hbox.set_sensitive(0) -# for n in self.bootDevice.keys(): -# n.set_sensitive(0) - - def labelInsertText(self, entry, text, len, data): - i = 0 - while i < len: - cur = text[i] - - # lilo did not allow ' '!, grub does - if self.lilo_radio.get_active() and (cur == ' ' or cur == '#' or cur == '$' or cur == '='): - entry.emit_stop_by_name("insert_text") - return - elif cur == '#' or cur == '$' or cur == '=': - entry.emit_stop_by_name ("insert_text") - return - i = i + 1 - - def labelUpdated(self, *args): - index = self.imageList.selection[0] - - label = self.labelEntry.get_text() - self.imageList.set_text(index, 3, label) - - # cannot allow user to select as default is zero length - if label: - self.defaultCheck.set_sensitive (gtk.TRUE) + self.useFbcb.set_active(gtk.FALSE) + self.fbButton.set_sensitive(gtk.FALSE) + self.useFbcb.connect("toggled", self.fbCallback) + self.fbButton.connect("clicked", self.fbButtonCallback) + self.setFbModeLabel() + + box = gtk.HBox(gtk.FALSE, 5) + box.pack_start(self.useFbcb) + box.pack_start(self.fbButton) + self.options_vbox.pack_start(box, gtk.FALSE) + + # password widgets + callback + self.usePassCb = gtk.CheckButton(_("Use a Boot Loader Password")) + self.passButton = gtk.Button(_("Set Password")) + if self.usePass: + self.usePassCb.set_active(gtk.TRUE) + self.passButton.set_sensitive(gtk.TRUE) else: - self.ignoreSignals = 1 - self.defaultCheck.set_active(0) - self.defaultCheck.set_sensitive (gtk.FALSE) - if self.default != None and self.default == index: - self.imageList.set_text(self.default, 0, "") - self.default = None - self.ignoreSignals = 0 + self.usePassCb.set_active(gtk.FALSE) + self.passButton.set_sensitive(gtk.FALSE) + self.usePassCb.connect("toggled", self.passCallback) + self.passButton.connect("clicked", self.passButtonCallback) - if self.checkLiloReqs(): - self.ics.setNextEnabled (1) - else: - self.ics.setNextEnabled (0) + box = gtk.HBox(gtk.FALSE, 5) + box.pack_start(self.usePassCb) + box.pack_start(self.passButton) + self.options_vbox.pack_start(box, gtk.FALSE) + self.forceLBA = gtk.CheckButton(_("Force LBA32")) + self.options_vbox.pack_start(self.forceLBA, gtk.FALSE) + self.forceLBA.set_active(self.bl.forceLBA32) - def defaultUpdated(self, *args): - if self.ignoreSignals: return + label = gtk.Label(_("General kernel parameters")) + self.appendEntry = gtk.Entry() + if args: + self.appendEntry.set_text(args) + box = gtk.HBox(gtk.FALSE, 5) + box.pack_start(label) + box.pack_start(self.appendEntry) + self.options_vbox.pack_start(box, gtk.FALSE) + if self.none_radio.get_active(): + self.options_vbox.set_sensitive(gtk.FALSE) + + alignment = gtk.Alignment() + alignment.set(0.1, 0.5, 0, 1.0) + alignment.add(self.options_vbox) - index = self.imageList.selection[0] + thebox.pack_start(alignment, gtk.FALSE) - if range(self.count) > 0: - for i in range(self.count): - self.imageList.set_pixmap(i, 0, self.checkMark_Off) + return thebox + + +class AdvancedBootloaderWindow (InstallWindow): + windowTitle = N_("Boot Loader Configuration") + htmlTag = "bootloader" + + def __init__(self, ics): + InstallWindow.__init__(self, ics) + self.parent = ics.getICW().window - if self.defaultCheck.get_active(): - if self.default != None: - self.imageList.set_pixmap(self.default, 0, self.checkMark_Off) - self.imageList.set_pixmap(index, 0, self.checkMark) - self.default = index - else: - self.imageList.set_pixmap(index, 0, self.checkMark_Off) - self.default = None + def getPrev(self): + pass + + + def getNext(self): + # make a copy of our image list to shove into the bl struct + self.bl.images.images = {} + for key in self.imagelist.keys(): + self.bl.images.images[key] = self.imagelist[key] + self.bl.images.setDefault(self.defaultDev) + + for key in self.bootDevices.keys(): + if self.bootDevices[key][0].get_active(): +# print "setting device to %s" % (self.bootDevices[key][1],) + self.bl.setDevice(self.bootDevices[key][1]) + + self.bl.drivelist = self.driveOrder + + + # adds/edits a new "other" os to the boot loader config + def editOther(self, oldDevice, oldLabel, isDefault, isRoot = 0): + dialog = gtk.Dialog(_("Image"), self.parent) + dialog.add_button('gtk-ok', 1) + dialog.add_button('gtk-cancel', 2) + dialog.set_position(gtk.WIN_POS_CENTER) + + dialog.vbox.pack_start(gui.WrappingLabel( + _("The label is what is displayed in the boot loader to " + "choose to boot this operating system. The device " + "is the device which it boots from."))) - if self.checkLiloReqs(): - self.ics.setNextEnabled (1) + spacer = gtk.Label("") + spacer.set_size_request(10, 1) + dialog.vbox.pack_start(spacer, gtk.FALSE) + + table = gtk.Table(2, 5) + table.set_row_spacings(5) + table.set_col_spacings(5) + + table.attach(gtk.Label(_("Label")), 0, 1, 1, 2, gtk.FILL, 0, 10) + labelEntry = gtk.Entry(16) + table.attach(labelEntry, 1, 2, 1, 2, gtk.FILL, 0, 10) + if oldLabel: + labelEntry.set_text(oldLabel) + + table.attach(gtk.Label(_("Device")), 0, 1, 2, 3, gtk.FILL, 0, 10) + if not isRoot: + # XXX switch to a combo of the partitions on the system + deviceEntry = gtk.Entry(16) + table.attach(deviceEntry, 1, 2, 2, 3, gtk.FILL, 0, 10) + if oldDevice: + deviceEntry.set_text(oldDevice) else: - self.ics.setNextEnabled (0) + table.attach(gtk.Label(oldDevice), 1, 2, 2, 3, gtk.FILL, 0, 10) + + default = gtk.CheckButton(_("Default Boot Target")) + table.attach(default, 0, 2, 3, 4, gtk.FILL, 0, 10) + if isDefault != 0: + default.set_active(gtk.TRUE) + dialog.vbox.pack_start(table) + dialog.show_all() + + while 1: + rc = dialog.run() + + # cancel + if rc == 2: + break - def labelSelected(self, *args): - index = self.imageList.selection[0] - device = self.imageList.get_text(index, 1) - type = self.imageList.get_text(index, 2) - label = self.imageList.get_text(index, 3) + label = labelEntry.get_text() - self.deviceLabel.set_text(_("Partition") + ": " + device) - device = device[5:] + if not isRoot: + dev = deviceEntry.get_text() + else: + dev = oldDevice + + if not label: + self.intf.messageWindow(_("Error"), + _("You must specify a label for the " + "entry"), + type="warning") + continue + + foundBad = 0 + for char in self.illegalChars: + if char in label: + self.intf.messageWindow(_("Error"), + _("Boot label contains illegal " + "characters"), + type="warning") + foundBad = 1 + break + if foundBad: + continue + + # verify that the label hasn't been used + foundBad = 0 + for key in self.imagelist.keys(): + if dev == key: + continue + if self.bl.useGrub(): + thisLabel = self.imagelist[key][1] + else: + thisLabel = self.imagelist[key][0] + + if thisLabel == label: + self.intf.messageWindow(_("Duplicate Label"), + _("This label is already in " + "use for another boot entry."), + type="warning") + foundBad = 1 + break + if foundBad: + continue + + # XXX need to do some sort of validation of the device? + + # they could be duplicating a device, which we don't handle + if dev in self.imagelist.keys() and (not oldDevice or + dev != oldDevice): + self.intf.messageWindow(_("Duplicate Device"), + _("This device is already being " + "used for another boot entry."), + type="warning") + continue + + # if we're editing and the device has changed, delete the old + if oldDevice and dev != oldDevice: + del self.imagelist[oldDevice] + + + # go ahead and add it + if self.bl.useGrub(): + self.imagelist[dev] = (None, label, isRoot) + else: + self.imagelist[dev] = (label, None, isRoot) + + if default.get_active(): + self.defaultDev = dev - self.typeLabel.set_text(_("Type") + ":" + type) - self.labelEntry.set_text(label) + # refill the os list store + self.fillOSList() + break - # do not allow blank label to be default - if not label: - self.defaultCheck.set_active(0) - self.defaultCheck.set_sensitive (gtk.FALSE) - - self.ignoreSignals = 1 - if index == self.default: - self.defaultCheck.set_active(1) + dialog.destroy() + + def getSelected(self): + selection = self.osTreeView.get_selection() + rc = selection.get_selected() + if not rc: + return None + model, iter = rc + + dev = model.get_value(iter, 2) + theDev = dev[5:] # strip /dev/ + + label = model.get_value(iter, 1) + isRoot = model.get_value(iter, 3) + isDefault = model.get_value(iter, 0) + return (theDev, label, isDefault, isRoot) + + + def addEntry(self, widget, *args): + self.editOther(None, None, 0) + + def deleteEntry(self, widget, *args): + rc = self.getSelected() + if not rc: + return + (dev, label, isDefault, isRoot) = rc + if not isRoot: + del self.imagelist[dev] + self.fillOSList() else: - self.defaultCheck.set_active(0) - self.ignoreSignals = 0 - - def bootloaderchange(self, widget): - if self.lilo_radio.get_active(): - selected = "lilo" - elif self.grub_radio.get_active(): - selected = "grub" - elif self.none_radio.get_active(): + self.intf.messageWindow(_("Cannot Delete"), + _("You cannot remove the system being " + "installed from the bootloader " + "options."), + type="warning") + + def editEntry(self, widget, *args): + rc = self.getSelected() + if not rc: return + (dev, label, isDefault, isRoot) = rc + self.editOther(dev, label, isDefault, isRoot) - if not self.lastselected or selected == self.lastselected: + # the default os was changed in the treeview + def toggledDefault(self, widget, *args): + if widget.get_active(): return - self.lastselected = selected - # swap the label for what it was "last"... this is conveniently - # also the long form if we're switching back to grub or vice versa - for index in range(self.numImages): - tmp = self.oldLabels[index] - self.oldLabels[index] = self.imageList.get_text(index, 3) - self.imageList.set_text(index, 3, tmp) - self.labelSelected() + rc = self.getSelected() + if not rc: + return + self.defaultDev = rc[0] + self.fillOSList() + + # fill in the os list tree view + def fillOSList(self): + self.osStore.clear() + + keys = self.imagelist.keys() + keys.sort() + for dev in keys: + (label, longlabel, isRoot) = self.imagelist[dev] + if self.bl.useGrub(): + theLabel = longlabel + else: + theLabel = label + + # if the label is empty, remove from the image list and don't + # worry about it + if not theLabel: + del self.imagelist[dev] + continue + + iter = self.osStore.append() + self.osStore.set_value(iter, 1, theLabel) + self.osStore.set_value(iter, 2, "/dev/%s" % (dev,)) + self.osStore.set_value(iter, 3, isRoot) + if self.defaultDev == dev: + self.osStore.set_value(iter, 0, gtk.TRUE) + else: + self.osStore.set_value(iter, 0, gtk.FALSE) + def arrowClicked(self, widget, direction, *args): + selection = self.driveOrderView.get_selection() + rc = selection.get_selected() + if not rc: + return + model, iter = rc + + # there has got to be a better way to do this =\ + drive = model.get_value(iter, 0)[5:] + index = self.driveOrder.index(drive) + if direction == gtk.ARROW_DOWN: + self.driveOrder.remove(drive) + self.driveOrder.insert(index + 1, drive) + elif direction == gtk.ARROW_UP: + self.driveOrder.remove(drive) + self.driveOrder.insert(index - 1, drive) + self.makeDriveOrderStore() + + self.setMbrLabel(self.driveOrder[0]) + + + # make the store for the drive order + def makeDriveOrderStore(self): + self.driveOrderStore.clear() + iter = self.driveOrderStore.append() + for drive in self.driveOrder: + self.driveOrderStore.set_value(iter, 0, "/dev/%s" % (drive,)) + iter = self.driveOrderStore.append() + + # set the label on the mbr radio button to show the right device. + # kind of a hack + def setMbrLabel(self, firstDrive): + if not self.bootDevices.has_key("mbr"): + return + + (radio, olddev, desc) = self.bootDevices["mbr"] + radio.set_label("/dev/%s %s" % (firstDrive, _(desc))) + self.bootDevices["mbr"] = (radio, firstDrive, desc) + + # LiloWindow tag="lilo" def getScreen(self, dispatch, bl, fsset, diskSet): - fn = self.ics.findPixmap("checkbox-on.png") - if fn: - pixbuf = gtk.gdk.pixbuf_new_from_file(fn) - self.checkMark = pixbuf.render_pixmap_and_mask()[0] - fn = self.ics.findPixmap("checkbox-off.png") - if fn: - pixbuf = gtk.gdk.pixbuf_new_from_file(fn) - self.checkMark_Off = pixbuf.render_pixmap_and_mask()[0] - self.dispatch = dispatch self.bl = bl self.intf = dispatch.intf - self.rootdev = fsset.getEntryByMountPoint("/").device.getDevice() + # illegal characters for boot loader labels + if self.bl.useGrub(): + self.illegalChars = [ "$", "=" ] + else: + self.illegalChars = [ "$", "=", " " ] + + # main vbox + thebox = gtk.VBox (gtk.FALSE, 10) - imageList = bl.images.getImages() - defaultDevice = bl.images.getDefault() - self.ignoreSignals = 0 + vbox = gtk.VBox(gtk.FALSE, 5) + label = gui.WrappingLabel(_("Insert some text about booting other operating systems")) + vbox.pack_start(label, gtk.FALSE) - self.radioBox = gtk.Table(2, 6) - self.bootDevice = {} - self.radioBox.set_border_width (5) - spacer = gtk.Label("") spacer.set_size_request(10, 1) - self.radioBox.attach(spacer, 0, 1, 2, 4, gtk.FALSE) + vbox.pack_start(spacer, gtk.FALSE) + + box = gtk.HBox (gtk.FALSE, 5) + sw = gtk.ScrolledWindow() + sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) + sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) + sw.set_size_request(300, 100) + box.pack_start(sw, gtk.TRUE) + + + self.osStore = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, + gobject.TYPE_STRING, gobject.TYPE_BOOLEAN) + self.osTreeView = gtk.TreeView(self.osStore) + theColumns = [ "Default", "Label", "Device" ] + + self.checkboxrenderer = gtk.CellRendererToggle() + column = gtk.TreeViewColumn(theColumns[0], self.checkboxrenderer, + active = 0) + column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) + self.checkboxrenderer.connect("toggled", self.toggledDefault) + self.osTreeView.append_column(column) + + for columnTitle in theColumns[1:]: + renderer = gtk.CellRendererText() + column = gtk.TreeViewColumn(columnTitle, renderer, + text = theColumns.index(columnTitle)) + column.set_clickable(gtk.FALSE) + self.osTreeView.append_column(column) + + self.osTreeView.set_headers_visible(gtk.TRUE) + self.osTreeView.columns_autosize() + self.osTreeView.set_size_request(100, 100) + sw.add(self.osTreeView) + + self.imagelist = self.bl.images.getImages() + self.defaultDev = self.bl.images.getDefault() + + # XXX debug spew, remove me +## if len(self.imagelist.keys()) <= 1: +## self.imagelist = { 'hda2': ('linux', 'Red Hat Linux', 1), +## 'hda1': ('windows', 'Windows', 0) } +## self.defaultDev = 'hda1' + + self.fillOSList() + + buttonbar = gtk.VButtonBox() + buttonbar.set_layout(gtk.BUTTONBOX_START) + buttonbar.set_border_width(5) + add = gtk.Button(_("_Add")) + buttonbar.pack_start(add, gtk.FALSE) + add.connect("clicked", self.addEntry) + + edit = gtk.Button(_("_Edit")) + buttonbar.pack_start(edit, gtk.FALSE) + edit.connect("clicked", self.editEntry) + + delete = gtk.Button(_("_Delete")) + buttonbar.pack_start(delete, gtk.FALSE) + delete.connect("clicked", self.deleteEntry) + box.pack_start(buttonbar, gtk.FALSE) + + vbox.pack_start(box, gtk.FALSE) + + alignment = gtk.Alignment() + alignment.set(0.1, 0, 0, 0) + alignment.add(vbox) + thebox.pack_start(alignment, gtk.FALSE) + + thebox.pack_start (gtk.HSeparator(), gtk.FALSE) label = gtk.Label(_("Install Boot Loader record on:")) label.set_alignment(0.0, 0.5) - self.liloLocationBox = gtk.VBox (gtk.FALSE, 0) - self.liloLocationBox.pack_start(label) - self.radioBox.attach(self.liloLocationBox, 0, 2, 1, 2) + locationBox = gtk.VBox (gtk.FALSE, 2) + locationBox.pack_start(label) - choices = fsset.bootloaderChoices(diskSet) + spacer = gtk.Label("") + spacer.set_size_request(10, 1) + locationBox.pack_start(spacer, gtk.FALSE) + + # XXX switch over to real and not debug crap +# choices = { 'mbr': ("hda", "MBR"), 'boot': ("hda2", "/boot") } + choices = fsset.bootloaderChoices(diskSet) + self.bootDevices = {} + if choices: radio = None - count = 0 - for (device, desc) in choices: + keys = choices.keys() + keys.reverse() + for key in keys: + (device, desc) = choices[key] radio = gtk.RadioButton(radio, ("/dev/%s %s" % (device, _(desc)))) - self.radioBox.attach(radio, 1, 2, count + 2, count + 3) - self.bootDevice[radio] = device - - if bl.getDevice() == device: - radio.set_active(1) + locationBox.pack_start(radio, gtk.FALSE) + self.bootDevices[key] = (radio, device, desc) - count = count + 1 + if self.bl.getDevice() == device: + radio.set_active(gtk.TRUE) + else: + radio.set_active(gtk.FALSE) - label = gtk.Label(_("Kernel Parameters") + ":") - label.set_alignment(0.0, 0.5) - self.appendEntry = gtk.Entry() - if bl.args.get(): - self.appendEntry.set_text(bl.args.get()) - box = gtk.HBox(gtk.FALSE, 5) - box.pack_start(label) - box.pack_start(self.appendEntry) alignment = gtk.Alignment() - alignment.set(0.0, 0.5, 0, 1.0) - alignment.add(box) - self.lba = gtk.CheckButton(_("Force use of LBA32 (not normally required)")) - self.lba.set_active(self.bl.forceLBA32) - vbox = gtk.VBox(gtk.FALSE, 5) - vbox.pack_start(alignment) - vbox.pack_end(self.lba) - self.radioBox.attach(vbox, 0, 2, 5, 6) - - box = gtk.VBox (gtk.FALSE, 0) - - label = gui.WrappingLabel(_("Please select the boot loader that " - "the computer will use. GRUB is the " - "default boot loader. However, if you " - "do not wish to overwrite your current " - "boot loader, select \"Do not install " - "a boot loader.\" ")) - label.set_alignment(0.0, 0.0) - self.editBox = gtk.VBox () - self.imageList = gtk.CList (4, ( _("Default"), _("Device"), - _("Partition type"), _("Boot label"))) - self.sw = gtk.ScrolledWindow () - - - self.grub_radio = gtk.RadioButton(None, (_("Use GRUB as the boot loader"))) - self.lilo_radio = gtk.RadioButton(self.grub_radio, (_("Use LILO as the boot loader"))) - self.none_radio = gtk.RadioButton(self.grub_radio, (_("Do not install a boot loader"))) + alignment.set(0.1, 0, 0, 0) + alignment.add(locationBox) + thebox.pack_start(alignment, gtk.FALSE) + if not self.bl.useGrub(): + return thebox + + thebox.pack_start (gtk.HSeparator(), gtk.FALSE) - self.lilo_radio.connect("toggled", self.bootloaderchange) - self.grub_radio.connect("toggled", self.bootloaderchange) - self.none_radio.connect("toggled", self.toggled) - - if not dispatch.stepInSkipList("instbootloader"): - self.none_radio.set_active (gtk.FALSE) - else: - self.none_radio.set_active (gtk.TRUE) - self.toggled (self.none_radio) - - for n in (self.appendEntry, self.editBox, - self.imageList, self.liloLocationBox, self.radioBox ): - n.set_sensitive (gtk.FALSE) + drivebox = gtk.VBox(gtk.FALSE, 5) + label = gui.WrappingLabel(_("Blah, this is the BIOS drive order, more information, etc")) + drivebox.pack_start(label, gtk.FALSE) - self.lastselected = None + hbox = gtk.HBox(gtk.FALSE, 5) - self.radio_vbox = gtk.VBox(gtk.FALSE, 2) - self.radio_vbox.set_border_width(5) - self.radio_vbox.pack_start(label, gtk.FALSE) - self.radio_vbox.pack_start(self.grub_radio, gtk.FALSE) - self.radio_vbox.pack_start(self.lilo_radio, gtk.FALSE) - self.radio_vbox.pack_start(self.none_radio, gtk.FALSE) + # different widget for this maybe? + self.driveOrderStore = gtk.ListStore(gobject.TYPE_STRING) + sw = gtk.ScrolledWindow() + sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) + sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) - box.pack_start(self.radio_vbox, gtk.FALSE) - - box.pack_start (gtk.HSeparator (), gtk.FALSE) - box.pack_start (self.radioBox, gtk.FALSE) + self.driveOrderView = gtk.TreeView(self.driveOrderStore) + renderer = gtk.CellRendererText() + column = gtk.TreeViewColumn('Text', renderer, text = 0) + column.set_clickable(gtk.FALSE) + self.driveOrderView.append_column(column) + self.driveOrderView.set_rules_hint(gtk.FALSE) + self.driveOrderView.set_headers_visible(gtk.FALSE) + self.driveOrderView.set_enable_search(gtk.FALSE) + + # XXX more debug fun +# self.driveOrder = ["hda", "hdb"] + self.driveOrder = self.bl.drivelist + self.makeDriveOrderStore() + + sw.add(self.driveOrderView) + sw.set_size_request(100, 100) + hbox.pack_start(sw, gtk.FALSE) + + arrowbox = gtk.VBox(gtk.FALSE, 5) + arrowButton = gtk.Button() + arrow = gtk.Arrow(gtk.ARROW_UP, gtk.SHADOW_ETCHED_IN) + arrowButton.add(arrow) + arrowButton.connect("clicked", self.arrowClicked, gtk.ARROW_UP) + arrowbox.pack_start(arrowButton, gtk.FALSE) - sortedKeys = imageList.keys() - sortedKeys.sort() - self.numImages = len(sortedKeys) - - if not bl.useGrub(): - self.lilo_radio.set_active(1) - self.lastselected = "lilo" - else: - self.grub_radio.set_active(1) - self.lastselected = "grub" - - self.default = None - self.count = 0 - self.types = [] - self.oldLabels = [] - for n in sortedKeys: - (label, longlabel, type) = imageList[n] - self.types.append(type) - if label == None: - label = "" - if longlabel == None: - longlabel = "" - if self.lastselected == "lilo": - row = ("", "/dev/" + n, self.typeName(type), label) - self.oldLabels.append(longlabel) - else: - row = ("", "/dev/" + n, self.typeName(type), longlabel) - self.oldLabels.append(label) - self.imageList.append(row) - - if (n == defaultDevice): - self.default = self.count - self.imageList.set_pixmap(self.count, 0, self.checkMark) - else: - self.imageList.set_pixmap(self.count, 0, self.checkMark_Off) - self.count = self.count + 1 - - self.imageList.columns_autosize () - self.imageList.column_title_passive (1) - self.imageList.set_border_width (5) - - self.deviceLabel = gtk.Label(_("Partition") + ":") - self.typeLabel = gtk.Label(_("Type") + ":") - - tempBox = gtk.HBox(gtk.TRUE) - self.deviceLabel.set_alignment(0.0, 0.0) - self.typeLabel.set_alignment(0.0, 0.0) - tempBox.pack_start(self.deviceLabel, gtk.FALSE) - tempBox.pack_start(self.typeLabel, gtk.FALSE) - self.defaultCheck = gtk.CheckButton(_("Default boot image")) - - # Alliteration! - self.labelLabel = gtk.Label(_("Boot label") + ":") - self.labelEntry = gtk.Entry(15) - - self.imageList.connect("select_row", self.labelSelected) - self.defaultCheck.connect("toggled", self.defaultUpdated) - self.labelEntry.connect("changed", self.labelUpdated) - self.labelEntry.connect("insert_text", self.labelInsertText) - - tempBox2 = gtk.HBox(gtk.FALSE, 5) - self.labelLabel.set_alignment(0.0, 0.5) - tempBox2.pack_start(self.labelLabel, gtk.FALSE) - tempBox2.pack_start(self.labelEntry, gtk.FALSE) - - self.editBox.pack_start (tempBox, gtk.FALSE) - self.editBox.pack_start (self.defaultCheck, gtk.FALSE) - self.editBox.pack_start (tempBox2, gtk.FALSE) - self.editBox.set_border_width (5) - - box.pack_start (gtk.HSeparator (), gtk.FALSE) - box.pack_start (self.editBox, gtk.FALSE) - - self.imageList.set_selection_mode (gtk.SELECTION_BROWSE) - - self.sw.set_policy (gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - self.sw.add (self.imageList) - box.pack_start (self.sw, gtk.TRUE) - - if not dispatch.stepInSkipList("instbootloader"): - self.editBox.set_sensitive(gtk.TRUE) - tempBox2.set_sensitive(gtk.TRUE) - self.radioBox.set_sensitive(gtk.TRUE) - self.sw.set_sensitive(gtk.TRUE) - else: - self.editBox.set_sensitive(gtk.FALSE) - self.radioBox.set_sensitive(gtk.FALSE) - self.sw.set_sensitive(gtk.FALSE) - - self.ignoreSignals = 0 - - return box - - - - + spacer = gtk.Label("") + spacer.set_size_request(10, 1) + arrowbox.pack_start(spacer, gtk.FALSE) + arrowButton = gtk.Button() + arrow = gtk.Arrow(gtk.ARROW_DOWN, gtk.SHADOW_ETCHED_IN) + arrowButton.add(arrow) + arrowButton.connect("clicked", self.arrowClicked, gtk.ARROW_DOWN) + arrowbox.pack_start(arrowButton, gtk.FALSE) + alignment = gtk.Alignment() + alignment.set(0, 0.5, 0, 0) + alignment.add(arrowbox) + hbox.pack_start(alignment, gtk.FALSE) + drivebox.pack_start(hbox, gtk.FALSE) + alignment = gtk.Alignment() + alignment.set(0.1, 0, 0, 0) + alignment.add(drivebox) + thebox.pack_start(alignment, gtk.FALSE) + self.setMbrLabel(self.driveOrder[0]) + return thebox diff --git a/scripts/upd-instroot b/scripts/upd-instroot index 26bbf14a6..d69cafd73 100755 --- a/scripts/upd-instroot +++ b/scripts/upd-instroot @@ -95,7 +95,7 @@ PACKAGES="glibc glibc-common setup openssl python python2 newt libtermcap zlib ash kon2 e2fsprogs util-linux raidtools popt mount procps rpm XFree86 Xconfigurator anaconda anaconda-runtime kudzu-devel kudzu db3 rpm-python2.2 bzip2 bzip2-libs dosfstools pciutils - reiserfs-utils parted busybox-anaconda rpm-python anaconda-help" + reiserfs-utils parted busybox-anaconda rpm-python anaconda-help booty" if [ $ARCH = i386 ]; then PACKAGES="$PACKAGES kernel-pcmcia-cs lilo" @@ -231,6 +231,7 @@ usr/lib/anaconda-runtime/* usr/lib/anaconda/* usr/lib/anaconda/installclasses/* usr/lib/anaconda/textw/* +usr/lib/booty/* usr/lib/gtk/themes/engines/libraleigh.so usr/lib/libssl* usr/lib/libcrypto* @@ -49,10 +49,10 @@ stepToClasses = { "CustomizeUpgradeWindow")), "addswap" : ("upgrade_text", "UpgradeSwapWindow"), "bootloader" : ("bootloader_text", ("BootloaderChoiceWindow", - "BootloaderWindow", "BootloaderAppendWindow", - "BootloaderImagesWindow")), - "bootloaderpassword" : ("bootloader_text", "BootloaderPassword"), + "BootloaderPasswordWindow")), + "bootloaderadvanced" : ("bootloader_text", ("BootloaderImagesWindow", + "BootloaderLocationWindow")), "network" : ("network_text", ("NetworkWindow", "HostnameWindow")), "firewall" : ("firewall_text", "FirewallWindow"), "languagesupport" : ("language_text", ("LanguageSupportWindow", diff --git a/textw/bootloader_text.py b/textw/bootloader_text.py index 8b1c49077..c7190b924 100644 --- a/textw/bootloader_text.py +++ b/textw/bootloader_text.py @@ -80,14 +80,12 @@ class BootloaderChoiceWindow: if rc == "no": continue dispatch.skipStep("instbootloader", skip = (rc == "yes")) - dispatch.skipStep("bootloaderpassword") elif blradio.getSelection() == "lilo": bl.setUseGrub(0) dispatch.skipStep("instbootloader", 0) else: bl.setUseGrub(1) dispatch.skipStep("instbootloader", 0) - dispatch.skipStep("bootloaderpassword", 0) screen.popWindow() return INSTALL_OK @@ -148,19 +146,25 @@ class BootloaderAppendWindow: screen.popWindow() return INSTALL_OK -class BootloaderWindow: +class BootloaderLocationWindow: def __call__(self, screen, dispatch, bl, fsset, diskSet): if dispatch.stepInSkipList("instbootloader"): return INSTALL_NOOP choices = fsset.bootloaderChoices(diskSet) - if len(choices) == 1: - bl.setDevice(choices[0][0]) + if len(choices.keys()) == 1: + bl.setDevice(choices[choices.keys()[0]][0]) return INSTALL_NOOP + if len(choices.keys()) == 0: + return INSTALL_NOOP format = "/dev/%-11s %s" locations = [] default = 0 - for (device, desc) in choices: + + keys = choices.keys() + keys.reverse() + for key in keys: + (device, desc) = choices[key] if device == bl.getDevice(): default = len(locations) locations.append (format % (device, _(desc))) @@ -174,7 +178,8 @@ class BootloaderWindow: if rc == TEXT_BACK_CHECK: return INSTALL_BACK - bl.setDevice(choices[sel][0]) + # XXX this is obviously not right :) + bl.setDevice(choices[choices.keys()[0]][0]) return INSTALL_OK @@ -240,12 +245,7 @@ class BootloaderImagesWindow: return newLabel.value() - def formatDevice(self, type, label, device, default): - if (type == "FAT"): - type = "DOS/Windows" - elif (type == "ntfs" or type == "hpfs"): - type = "OS/2 / Windows NT" - + def formatDevice(self, label, device, default): if default == device: default = '*' else: @@ -254,28 +254,35 @@ class BootloaderImagesWindow: if not label: label = "" - return "%-10s %-25s %-7s %-10s" % ( "/dev/" + device, type, default, label) + return " %-12s %-7s %-25s" % ( "/dev/" + device, default, label) def __call__(self, screen, dispatch, bl, fsset, diskSet): if dispatch.stepInSkipList("instbootloader"): return INSTALL_NOOP images = bl.images.getImages() default = bl.images.getDefault() + + # XXX debug crap +## images = { 'hda2': ('linux', 'Red Hat Linux', 1), +## 'hda1': ('windows', 'Windows', 0) } +## default = 'hda1' + self.bl = bl - listboxLabel = Label("%-10s %-25s %-7s %-10s" % - ( _("Device"), _("Partition type"), _("Default"), _("Boot label"))) + listboxLabel = Label( "%-12s %-7s %-25s" % + ( _("Device"), _("Default"), _("Boot label"))) listbox = Listbox(5, scroll = 1, returnExit = 1) sortedKeys = images.keys() sortedKeys.sort() + print sortedKeys for dev in sortedKeys: - (label, longlabel, type) = images[dev] + (label, longlabel, isRoot) = images[dev] if not bl.useGrub(): - listbox.append(self.formatDevice(type, label, dev, default), dev) + listbox.append(self.formatDevice(label, dev, default), dev) else: - listbox.append(self.formatDevice(type, longlabel, dev, default), dev) + listbox.append(self.formatDevice(longlabel, dev, default), dev) listbox.setCurrent(dev) @@ -298,6 +305,7 @@ class BootloaderImagesWindow: # g.addHotKey(" ") rootdev = fsset.getEntryByMountPoint("/").device.getDevice() +# rootdev = "hda2" result = None while (result != TEXT_OK_CHECK and result != TEXT_BACK_CHECK and result != TEXT_F12_CHECK): @@ -317,24 +325,24 @@ class BootloaderImagesWindow: images[item] = (label, label, type) if (default == item and not label): default = "" - listbox.replace(self.formatDevice(type, label, item, default), item) + listbox.replace(self.formatDevice(label, item, default), item) listbox.setCurrent(item) elif result == "F2": # elif result == " ": item = listbox.current() - (label, longlabel, type) = images[item] + (label, longlabel, isRoot) = images[item] if bl.useGrub(): label = longlabel if (label): if (default): - (oldLabel, oldLong, oldType) = images[default] + (oldLabel, oldLong, oldIsRoot) = images[default] if bl.useGrub(): oldLabel = oldLong - listbox.replace(self.formatDevice(oldType, oldLabel, default, + listbox.replace(self.formatDevice(oldLabel, default, ""), default) default = item - listbox.replace(self.formatDevice(type, label, item, default), + listbox.replace(self.formatDevice(label, item, default), item) listbox.setCurrent(item) @@ -343,7 +351,7 @@ class BootloaderImagesWindow: if (result == TEXT_BACK_CHECK): return INSTALL_BACK - for (dev, (label, longlabel, type)) in images.items(): + for (dev, (label, longlabel, isRoot)) in images.items(): if not bl.useGrub(): bl.images.setImageLabel(dev, label, setLong = 0) else: @@ -352,18 +360,19 @@ class BootloaderImagesWindow: return INSTALL_OK -class BootloaderPassword: +class BootloaderPasswordWindow: def usepasscb(self, *args): flag = FLAGS_RESET if not self.checkbox.selected(): flag = FLAGS_SET self.entry1.setFlags(FLAG_DISABLED, flag) self.entry2.setFlags(FLAG_DISABLED, flag) - - def __call__(self, screen, bl, intf): + + def __call__(self, screen, dispatch, bl, fsset, diskSet): if not bl.useGrub(): return INSTALL_NOOP + intf = dispatch.intf self.bl = bl buttons = ButtonBar(screen, [TEXT_OK_BUTTON, TEXT_BACK_BUTTON]) |