diff options
author | Chris Lumens <clumens@redhat.com> | 2009-02-19 14:28:22 -0500 |
---|---|---|
committer | Chris Lumens <clumens@redhat.com> | 2009-03-04 15:37:04 -0500 |
commit | 38eee03b0803cc286f05c42c969912c576713685 (patch) | |
tree | b2eba0bd2c0131fdf4d4c911809fcf1fbceafd0a /booty | |
parent | 2c8c10290688b9c2038b1448e7bed9723012641e (diff) | |
download | anaconda-38eee03b0803cc286f05c42c969912c576713685.tar.gz anaconda-38eee03b0803cc286f05c42c969912c576713685.tar.xz anaconda-38eee03b0803cc286f05c42c969912c576713685.zip |
Move each bootloader class into its own file.
Diffstat (limited to 'booty')
-rw-r--r-- | booty/__init__.py | 1 | ||||
-rw-r--r-- | booty/alpha.py | 143 | ||||
-rw-r--r-- | booty/bootloaderInfo.py | 1264 | ||||
-rw-r--r-- | booty/ia64.py | 39 | ||||
-rw-r--r-- | booty/ppc.py | 179 | ||||
-rw-r--r-- | booty/s390.py | 179 | ||||
-rw-r--r-- | booty/sparc.py | 127 | ||||
-rw-r--r-- | booty/x86.py | 567 |
8 files changed, 1256 insertions, 1243 deletions
diff --git a/booty/__init__.py b/booty/__init__.py index c15ca6d06..a5bc97a6a 100644 --- a/booty/__init__.py +++ b/booty/__init__.py @@ -18,6 +18,7 @@ import rhpl from bootloaderInfo import * +from bootloader import * # return instance of the appropriate bootloader for our arch def getBootloader(): diff --git a/booty/alpha.py b/booty/alpha.py new file mode 100644 index 000000000..5e62c93ca --- /dev/null +++ b/booty/alpha.py @@ -0,0 +1,143 @@ +import os +import rhpl.executil + +from bootloaderInfo import * +import fsset + +class alphaBootloaderInfo(bootloaderInfo): + def wholeDevice (self, path): + (device, foo) = fsset.getDiskPart(path) + return device + + def partitionNum (self, path): + # getDiskPart returns part numbers 0-based; we need it one based + # *sigh* + (foo, partitionNumber) = getDiskPart(path) + return partitionNumber + 1 + + def writeAboot(self, instRoot, fsset, bl, kernelList, + chainList, defaultDev, justConfig): + # Get bootDevice and rootDevice + rootDevice = fsset.getEntryByMountPoint("/").device.getDevice() + if fsset.getEntryByMountPoint("/boot"): + bootDevice = fsset.getEntryByMountPoint("/boot").device.getDevice() + else: + bootDevice = rootDevice + bootnotroot = bootDevice != rootDevice + + # If /etc/aboot.conf already exists we rename it + # /etc/aboot.conf.rpmsave. + if os.path.isfile(instRoot + self.configfile): + os.rename (instRoot + self.configfile, + instRoot + self.configfile + ".rpmsave") + + # Then we create the necessary files. If the root device isn't + # the boot device, we create /boot/etc/ where the aboot.conf + # will live, and we create /etc/aboot.conf as a symlink to it. + if bootnotroot: + # Do we have /boot/etc ? If not, create one + if not os.path.isdir (instRoot + '/boot/etc'): + os.mkdir(instRoot + '/boot/etc', 0755) + + # We install the symlink (/etc/aboot.conf has already been + # renamed in necessary.) + os.symlink("../boot" + self.configfile, instRoot + self.configfile) + + cfPath = instRoot + "/boot" + self.configfile + # Kernel path is set to / because a boot partition will + # be a root on its own. + kernelPath = '/' + # Otherwise, we just need to create /etc/aboot.conf. + else: + cfPath = instRoot + self.configfile + kernelPath = self.kernelLocation + + # If we already have an aboot.conf, rename it + if os.access (cfPath, os.R_OK): + self.perms = os.stat(cfPath)[0] & 0777 + os.rename(cfPath, cfPath + '.rpmsave') + + # Now we're going to create and populate cfPath. + f = open (cfPath, 'w+') + f.write ("# aboot default configurations\n") + + if bootnotroot: + f.write ("# NOTICE: You have a /boot partition. This means that\n") + f.write ("# all kernel paths are relative to /boot/\n") + + # bpn is the boot partition number. + bpn = self.partitionNum(bootDevice) + lines = 0 + + # We write entries line using the following format: + # <line><bpn><kernel-name> root=<rootdev> [options] + # We get all the kernels we need to know about in kernelList. + + for (kernel, tag, version) in kernelList: + kernelTag = "-" + version + kernelFile = "%svmlinuz%s" %(kernelPath, kernelTag) + + f.write("%d:%d%s" %(lines, bpn, kernelFile)) + + # See if we can come up with an initrd argument that exists + initrd = self.makeInitrd(kernelTag) + if os.path.isfile(instRoot + initrd): + f.write(" initrd=%sinitrd%s.img" %(kernelPath, kernelTag)) + + realroot = getRootDevName(initrd, fsset, rootDevice, instRoot) + f.write(" root=%s" %(realroot,)) + + args = self.args.get() + if args: + f.write(" %s" %(args,)) + + f.write("\n") + lines = lines + 1 + + # We're done writing the file + f.close () + del f + + if not justConfig: + # Now we're ready to write the relevant boot information. wbd + # is the whole boot device, bdpn is the boot device partition + # number. + wbd = self.wholeDevice (bootDevice) + bdpn = self.partitionNum (bootDevice) + + # Calling swriteboot. The first argument is the disk to write + # to and the second argument is a path to the bootstrap loader + # file. + args = ("swriteboot", ("/dev/%s" % wbd), "/boot/bootlx") + rhpl.executil.execWithRedirect ('/sbin/swriteboot', args, + root = instRoot, + stdout = "/dev/tty5", + stderr = "/dev/tty5") + + # Calling abootconf to configure the installed aboot. The + # first argument is the disk to use, the second argument is + # the number of the partition on which aboot.conf resides. + # It's always the boot partition whether it's / or /boot (with + # the mount point being omitted.) + args = ("abootconf", ("/dev/%s" % wbd), str (bdpn)) + rhpl.executil.execWithRedirect ('/sbin/abootconf', args, + root = instRoot, + stdout = "/dev/tty5", + stderr = "/dev/tty5") + + + def write(self, instRoot, fsset, bl, kernelList, chainList, + defaultDev, justConfig, intf): + if len(kernelList) < 1: + self.noKernelsWarn(intf) + + self.writeAboot(instRoot, fsset, bl, kernelList, + chainList, defaultDev, justConfig) + + def __init__(self): + bootloaderInfo.__init__(self) + self.useGrubVal = 0 + self.configfile = "/etc/aboot.conf" + # self.kernelLocation is already set to what we need. + self.password = None + self.pure = None diff --git a/booty/bootloaderInfo.py b/booty/bootloaderInfo.py index 14d33835a..b33c11885 100644 --- a/booty/bootloaderInfo.py +++ b/booty/bootloaderInfo.py @@ -78,6 +78,27 @@ def syncDataToDisk(dev, mntpt, instRoot = "/"): stderr = "/dev/tty5", root = instRoot) +def rootIsDevice(dev): + if dev.startswith("LABEL=") or dev.startswith("UUID="): + return False + return True + +# hackery to determine if we should do root=LABEL=/ or whatnot +# as usual, knows too much about anaconda +def getRootDevName(initrd, fsset, rootDev, instRoot): + if not os.access(instRoot + initrd, os.R_OK): + return "/dev/%s" % (rootDev,) + + try: + rootEntry = fsset.getEntryByMountPoint("/") + if rootEntry.getUuid() is not None: + return "UUID=%s" %(rootEntry.getUuid(),) + elif rootEntry.getLabel() is not None and rootEntry.device.doLabel is not None: + return "LABEL=%s" %(rootEntry.getLabel(),) + return "/dev/%s" %(rootDev,) + except: + return "/dev/%s" %(rootDev,) + class BootyNoKernelWarning: def __init__ (self, value=""): self.value = value @@ -564,555 +585,6 @@ class bootloaderInfo: con = flags.virtpconsole self.args.append("console=%s" %(con,)) - -class grubBootloaderInfo(bootloaderInfo): - def setPassword(self, val, isCrypted = 1): - if not val: - self.password = val - self.pure = val - return - - if isCrypted and self.useGrubVal == 0: - self.pure = None - return - elif isCrypted: - self.password = val - self.pure = None - else: - salt = "$1$" - saltLen = 8 - - saltchars = string.letters + string.digits + './' - for i in range(saltLen): - salt += random.choice(saltchars) - - 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 getPhysicalDevices(self, device): - # This finds a list of devices on which the given device name resides. - # Accepted values for "device" are raid1 md devices (i.e. "md0"), - # physical disks ("hda"), and real partitions on physical disks - # ("hda1"). Volume groups/logical volumes are not accepted. - # - # XXX this has internal anaconda-ish knowledge. ick. - import isys - import lvm - - if string.split(device, '/', 1)[0] in map (lambda vg: vg[0], - lvm.vglist()): - return [] - - if device.startswith("mapper/luks-"): - return [] - - if device.startswith('md'): - bootable = 0 - parts = checkbootloader.getRaidDisks(device, 1, stripPart=0) - parts.sort() - return parts - - return [device] - - def runGrubInstall(self, instRoot, bootDev, cmds, cfPath): - if cfPath == "/": - syncDataToDisk(bootDev, "/boot", instRoot) - else: - syncDataToDisk(bootDev, "/", instRoot) - - # copy the stage files over into /boot - rhpl.executil.execWithRedirect( "/sbin/grub-install", - ["/sbin/grub-install", "--just-copy"], - stdout = "/dev/tty5", stderr = "/dev/tty5", - root = instRoot) - - # really install the bootloader - for cmd in cmds: - p = os.pipe() - os.write(p[1], cmd + '\n') - os.close(p[1]) - import time - - # FIXME: hack to try to make sure everything is written - # to the disk - if cfPath == "/": - syncDataToDisk(bootDev, "/boot", instRoot) - else: - syncDataToDisk(bootDev, "/", instRoot) - - rhpl.executil.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]) - - def installGrub(self, instRoot, bootDevs, grubTarget, grubPath, fsset, - target, cfPath): - args = "--stage2=/boot/grub/stage2 " - if self.forceLBA32: - args = "%s--force-lba " % (args,) - - cmds = [] - for bootDev in bootDevs: - gtPart = self.getMatchingPart(bootDev, grubTarget) - gtDisk = self.grubbyPartitionName(getDiskPart(gtPart)[0]) - bPart = self.grubbyPartitionName(bootDev) - cmd = "root %s\n" % (bPart,) - - stage1Target = gtDisk - if target == "partition": - stage1Target = self.grubbyPartitionName(gtPart) - - cmd += "install %s%s/stage1 d %s %s/stage2 p %s%s/grub.conf" % \ - (args, grubPath, stage1Target, grubPath, bPart, grubPath) - cmds.append(cmd) - - self.runGrubInstall(instRoot, bootDev, cmds, cfPath) - - def writeGrub(self, instRoot, fsset, bl, kernelList, chainList, - defaultDev, justConfigFile): - - images = bl.images.getImages() - rootDev = fsset.getEntryByMountPoint("/").device.getDevice() - - # XXX old config file should be read here for upgrade - - cf = "%s%s" % (instRoot, self.configfile) - self.perms = 0600 - if os.access (cf, os.R_OK): - self.perms = os.stat(cf)[0] & 0777 - os.rename(cf, cf + '.rpmsave') - - grubTarget = bl.getDevice() - target = "mbr" - if (grubTarget.startswith('rd/') or grubTarget.startswith('ida/') or - grubTarget.startswith('cciss/') or - grubTarget.startswith('sx8/') or - grubTarget.startswith('mapper/')): - if grubTarget[-1].isdigit(): - if grubTarget[-2] == 'p' or \ - (grubTarget[-2].isdigit() and grubTarget[-3] == 'p'): - target = "partition" - elif grubTarget[-1].isdigit() and not grubTarget.startswith('md'): - target = "partition" - - f = open(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") - - bootDevs = self.getPhysicalDevices(bootDev.device.getDevice()) - bootDev = bootDev.device.getDevice() - - f.write('# root %s\n' % self.grubbyPartitionName(bootDevs[0])) - 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=%d\n' % (self.timeout or 0)) - - if self.serial == 1: - # grub the 0-based number of the serial console device - unit = self.serialDevice[-1] - - # and we want to set the speed too - speedend = 0 - for char in self.serialOptions: - if char not in string.digits: - break - speedend = speedend + 1 - if speedend != 0: - speed = self.serialOptions[:speedend] - else: - # reasonable default - speed = "9600" - - f.write("serial --unit=%s --speed=%s\n" %(unit, speed)) - f.write("terminal --timeout=%s serial console\n" % (self.timeout or 5)) - else: - # we only want splashimage if they're not using a serial console - if os.access("%s/boot/grub/splash.xpm.gz" %(instRoot,), os.R_OK): - f.write('splashimage=%s%sgrub/splash.xpm.gz\n' - % (self.grubbyPartitionName(bootDevs[0]), cfPath)) - f.write("hiddenmenu\n") - - for dev in self.getPhysicalDevices(grubTarget): - usedDevs[dev] = 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 = self.makeInitrd(kernelTag) - - f.write('title %s (%s)\n' % (longlabel, version)) - f.write('\troot %s\n' % self.grubbyPartitionName(bootDevs[0])) - - realroot = getRootDevName(initrd, fsset, rootDev, instRoot) - realroot = " root=%s" %(realroot,) - - if version.endswith("xen0") or (version.endswith("xen") and not os.path.exists("/proc/xen")): - # hypervisor case - sermap = { "ttyS0": "com1", "ttyS1": "com2", - "ttyS2": "com3", "ttyS3": "com4" } - if self.serial and sermap.has_key(self.serialDevice) and \ - self.serialOptions: - hvs = "%s=%s" %(sermap[self.serialDevice], - self.serialOptions) - else: - hvs = "" - if version.endswith("xen0"): - hvFile = "%sxen.gz-%s %s" %(cfPath, - version.replace("xen0", ""), - hvs) - else: - hvFile = "%sxen.gz-%s %s" %(cfPath, - version.replace("xen", ""), - hvs) - f.write('\tkernel %s\n' %(hvFile,)) - f.write('\tmodule %s ro%s' %(kernelFile, realroot)) - if self.args.get(): - f.write(' %s' % self.args.get()) - f.write('\n') - - if os.access (instRoot + initrd, os.R_OK): - f.write('\tmodule %sinitrd%s.img\n' % (cfPath, kernelTag)) - else: # normal kernel - f.write('\tkernel %s ro%s' % (kernelFile, realroot)) - 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' % self.grubbyPartitionName(device)) -# f.write('\tmakeactive\n') - f.write('\tchainloader +1') - f.write('\n') - usedDevs[device] = 1 - - f.close() - - if not "/efi/" in cf: - os.chmod(cf, self.perms) - - try: - # make symlink for menu.lst (default config file name) - menulst = "%s%s/menu.lst" % (instRoot, self.configdir) - if os.access (menulst, os.R_OK): - os.rename(menulst, menulst + ".rpmsave") - os.symlink("./grub.conf", menulst) - except: - pass - - try: - # make symlink for /etc/grub.conf (config files belong in /etc) - etcgrub = "%s%s" % (instRoot, "/etc/grub.conf") - if os.access (etcgrub, os.R_OK): - os.rename(etcgrub, etcgrub + ".rpmsave") - os.symlink(".." + self.configfile, etcgrub) - except: - pass - - for dev in self.getPhysicalDevices(rootDev) + bootDevs: - usedDevs[dev] = 1 - - if os.access(instRoot + "/boot/grub/device.map", os.R_OK): - os.rename(instRoot + "/boot/grub/device.map", - instRoot + "/boot/grub/device.map.rpmsave") - if 1: # 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") - devs = usedDevs.keys() - usedDevs = {} - for dev in devs: - drive = getDiskPart(dev)[0] - if usedDevs.has_key(drive): - continue - usedDevs[drive] = 1 - devs = usedDevs.keys() - devs.sort() - for drive in devs: - # XXX hack city. If they're not the sort of thing that'll - # be in the device map, they shouldn't still be in the list. - if not drive.startswith('md'): - f.write("(%s) /dev/%s\n" % (self.grubbyDiskName(drive), - drive)) - f.close() - - sysconf = '/etc/sysconfig/grub' - if os.access (instRoot + sysconf, os.R_OK): - self.perms = os.stat(instRoot + sysconf)[0] & 0777 - os.rename(instRoot + sysconf, - instRoot + sysconf + '.rpmsave') - # if it's an absolute symlink, just get it out of our way - elif (os.path.islink(instRoot + sysconf) and - os.readlink(instRoot + sysconf)[0] == '/'): - os.rename(instRoot + sysconf, - instRoot + sysconf + '.rpmsave') - f = open(instRoot + sysconf, 'w+') - f.write("boot=/dev/%s\n" %(grubTarget,)) - # XXX forcelba never gets read back... - if self.forceLBA32: - f.write("forcelba=1\n") - else: - f.write("forcelba=0\n") - f.close() - - if not justConfigFile: - self.installGrub(instRoot, bootDevs, grubTarget, grubPath, fsset, \ - target, cfPath) - - return "" - - def getMatchingPart(self, bootDev, target): - bootName, bootPartNum = getDiskPart(bootDev) - devices = self.getPhysicalDevices(target) - for device in devices: - name, partNum = getDiskPart(device) - if name == bootName: - return device - return devices[0] - - def grubbyDiskName(self, name): - return "hd%d" % self.drivelist.index(name) - - def grubbyPartitionName(self, dev): - (name, partNum) = getDiskPart(dev) - if partNum != None: - return "(%s,%d)" % (self.grubbyDiskName(name), partNum) - else: - return "(%s)" %(self.grubbyDiskName(name)) - - - def getBootloaderConfig(self, instRoot, fsset, bl, kernelList, - chainList, defaultDev): - config = bootloaderInfo.getBootloaderConfig(self, instRoot, fsset, - bl, 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" - - if self.pure is not None and not self.useGrubVal: - config.addEntry("restricted", replace = 0) - config.addEntry("password", self.pure, replace = 0) - - if self.serial == 1: - # grab the 0-based number of the serial console device - unit = self.serialDevice[-1] - # FIXME: we should probably put some options, but lilo - # only supports up to 9600 baud so just use the defaults - # it's better than nothing :( - config.addEntry("serial=%s" %(unit,)) - else: - # message screws up serial console - if os.access(instRoot + message, os.R_OK): - config.addEntry("message", message, replace = 0) - - if not config.testEntry('lba32'): - if self.forceLBA32 or (bl.above1024 and - rhpl.getArch() != "x86_64"): - config.addEntry("lba32", replace = 0) - - return config - - # this is a hackish function that depends on the way anaconda writes - # out the grub.conf with a #boot= comment - # XXX this falls into the category of self.doUpgradeOnly - def upgradeGrub(self, instRoot, fsset, bl, kernelList, chainList, - defaultDev, justConfigFile): - if justConfigFile: - return "" - - theDev = None - for (fn, stanza) in [ ("/etc/sysconfig/grub", "boot="), - ("/boot/grub/grub.conf", "#boot=") ]: - try: - f = open(instRoot + fn, "r") - except: - continue - - # the following bits of code are straight from checkbootloader.py - lines = f.readlines() - f.close() - for line in lines: - if line.startswith(stanza): - theDev = checkbootloader.getBootDevString(line) - break - if theDev is not None: - break - - if theDev is None: - # we could find the dev before, but can't now... cry about it - return "" - - # migrate info to /etc/sysconfig/grub - self.writeSysconfig(instRoot, theDev) - - # more suckage. grub-install can't work without a valid /etc/mtab - # so we have to do shenanigans to get updated grub installed... - # steal some more code above - bootDev = fsset.getEntryByMountPoint("/boot") - grubPath = "/grub" - cfPath = "/" - if not bootDev: - bootDev = fsset.getEntryByMountPoint("/") - grubPath = "/boot/grub" - cfPath = "/boot/" - - masterBootDev = bootDev.device.getDevice(asBoot = 0) - if masterBootDev[0:2] == 'md': - rootDevs = checkbootloader.getRaidDisks(masterBootDev, raidLevel=1, - stripPart = 0) - else: - rootDevs = [masterBootDev] - - if theDev[5:7] == 'md': - stage1Devs = checkbootloader.getRaidDisks(theDev[5:], raidLevel=1) - else: - stage1Devs = [theDev[5:]] - - for stage1Dev in stage1Devs: - # cross fingers; if we can't find a root device on the same - # hardware as this boot device, we just blindly hope the first - # thing in the list works. - - grubbyStage1Dev = self.grubbyPartitionName(stage1Dev) - - grubbyRootPart = self.grubbyPartitionName(rootDevs[0]) - - for rootDev in rootDevs: - testGrubbyRootDev = getDiskPart(rootDev)[0] - testGrubbyRootDev = self.grubbyPartitionName(testGrubbyRootDev) - - if grubbyStage1Dev == testGrubbyRootDev: - grubbyRootPart = self.grubbyPartitionName(rootDev) - break - - args = "--stage2=/boot/grub/stage2 " - cmd ="root %s" % (grubbyRootPart,) - cmds = [ cmd ] - cmd = "install %s%s/stage1 d %s %s/stage2 p %s%s/grub.conf" \ - % (args, grubPath, grubbyStage1Dev, grubPath, grubbyRootPart, - grubPath) - cmds.append(cmd) - - if not justConfigFile: - self.runGrubInstall(instRoot, bootDev.device.setupDevice(), - cmds, cfPath) - - return "" - - def writeSysconfig(self, instRoot, installDev): - sysconf = '/etc/sysconfig/grub' - if not os.access(instRoot + sysconf, os.R_OK): - f = open(instRoot + sysconf, "w+") - f.write("boot=%s\n" %(installDev,)) - # XXX forcelba never gets read back at all... - if self.forceLBA32: - f.write("forcelba=1\n") - else: - f.write("forcelba=0\n") - f.close() - - def write(self, instRoot, fsset, bl, kernelList, chainList, - defaultDev, justConfig, intf): - if self.timeout is None and chainList: - self.timeout = 5 - - # XXX HACK ALERT - see declaration above - if self.doUpgradeOnly: - if self.useGrubVal: - self.upgradeGrub(instRoot, fsset, bl, kernelList, - chainList, defaultDev, justConfig) - return - - if len(kernelList) < 1: - self.noKernelsWarn(intf) - - out = self.writeGrub(instRoot, fsset, bl, kernelList, - chainList, defaultDev, - justConfig | (not self.useGrubVal)) - - - def getArgList(self): - args = bootloaderInfo.getArgList(self) - - if self.forceLBA32: - args.append("--lba32") - if self.password: - args.append("--md5pass=%s" %(self.password)) - - return args - - def __init__(self): - bootloaderInfo.__init__(self) - self._configdir = "/boot/grub" - self._configname = "grub.conf" - # XXX use checkbootloader to determine what to default to - self.useGrubVal = 1 - self.kernelLocation = "/boot/" - self.password = None - self.pure = None - - class efiBootloaderInfo(bootloaderInfo): def getBootloaderName(self): return self._bootloader @@ -1189,697 +661,3 @@ class efiBootloaderInfo(bootloaderInfo): self._bootloader = "grub.efi" self.useGrubVal = 1 self.kernelLocation = "" - -class x86BootloaderInfo(grubBootloaderInfo, efiBootloaderInfo): - def write(self, instRoot, fsset, bl, kernelList, chainList, - defaultDev, justConfig, intf): - grubBootloaderInfo.write(self, instRoot, fsset, bl, kernelList, - chainList, defaultDev, justConfig, intf) - - # 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 installGrub(self, *args): - args = [self] + list(args) - try: - apply(efiBootloaderInfo.installGrub, args, {}) - except EnvironmentError: - apply(grubBootloaderInfo.installGrub, args, {}) - - def __init__(self): - grubBootloaderInfo.__init__(self) - efiBootloaderInfo.__init__(self, initialize=False) - -class ia64BootloaderInfo(efiBootloaderInfo): - def getBootloaderConfig(self, instRoot, fsset, bl, kernelList, - chainList, defaultDev): - config = bootloaderInfo.getBootloaderConfig(self, instRoot, fsset, - bl, kernelList, chainList, - defaultDev) - # altix boxes need relocatable (#120851) - config.addEntry("relocatable") - - return config - - def writeLilo(self, instRoot, fsset, bl, kernelList, - chainList, defaultDev, justConfig): - config = self.getBootloaderConfig(instRoot, fsset, bl, - kernelList, chainList, defaultDev) - config.write(instRoot + self.configfile, perms = 0755) - - return "" - - def write(self, instRoot, fsset, bl, kernelList, chainList, - defaultDev, justConfig, intf): - if len(kernelList) >= 1: - out = self.writeLilo(instRoot, fsset, bl, kernelList, - chainList, defaultDev, justConfig) - else: - self.noKernelsWarn(intf) - - self.removeOldEfiEntries(instRoot) - self.addNewEfiEntry(instRoot, fsset) - - def makeInitrd(self, kernelTag): - return "/boot/efi/EFI/redhat/initrd%s.img" % kernelTag - - def __init__(self): - efiBootloaderInfo.__init__(self) - self._configname = "elilo.conf" - self._bootloader = "elilo.efi" - -class s390BootloaderInfo(bootloaderInfo): - def getBootloaderConfig(self, instRoot, fsset, bl, kernelList, - chainList, defaultDev): - images = bl.images.getImages() - - # on upgrade read in the lilo config file - lilo = LiloConfigFile () - self.perms = 0600 - 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, path, other) = lilo.getImage(label) - if fsType == "other": continue - - if not os.access(instRoot + sl.getPath(), os.R_OK): - lilo.delImage(label) - - rootDev = fsset.getEntryByMountPoint("/").device.getDevice() - if not rootDev: - raise RuntimeError, "Installing zipl, 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 = self.makeInitrd(kernelTag) - - 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, path, other) = 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, path, other) = 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, bl, instroot): # S/390 only - cf = "/etc/chandev.conf" - self.perms = 0644 - if bl.args.chandevget(): - fd = os.open(instroot + "/etc/chandev.conf", - os.O_WRONLY | os.O_CREAT) - os.write(fd, "noauto\n") - for cdev in bl.args.chandevget(): - os.write(fd,'%s\n' % cdev) - os.close(fd) - return "" - - - def writeZipl(self, instRoot, fsset, bl, 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') - f.write('target=%s\n' % (self.kernelLocation)) - - cfPath = "/boot/" - for (label, longlabel, version) in kernelList: - kernelTag = "-" + version - kernelFile = "%svmlinuz%s" % (cfPath, kernelTag) - - initrd = self.makeInitrd(kernelTag) - f.write('[%s]\n' % (label)) - f.write('\timage=%s\n' % (kernelFile)) - if os.access (instRoot + initrd, os.R_OK): - f.write('\tramdisk=%sinitrd%s.img\n' %(self.kernelLocation, - kernelTag)) - realroot = getRootDevName(initrd, fsset, rootDev, instRoot) - f.write('\tparameters="root=%s' %(realroot,)) - if bl.args.get(): - f.write(' %s' % (bl.args.get())) - f.write('"\n') - - f.close() - - if not justConfigFile: - argv = [ "/sbin/zipl" ] - rhpl.executil.execWithRedirect(argv[0], argv, root = instRoot, - stdout = "/dev/stdout", - stderr = "/dev/stderr") - - return "" - - def write(self, instRoot, fsset, bl, kernelList, chainList, - defaultDev, justConfig, intf): - out = self.writeZipl(instRoot, fsset, bl, kernelList, - chainList, defaultDev, - justConfig | (not self.useZiplVal)) - out = self.writeChandevConf(bl, instRoot) - - def __init__(self): - bootloaderInfo.__init__(self) - self.useZiplVal = 1 # only used on s390 - self.kernelLocation = "/boot/" - self.configfile = "/etc/zipl.conf" - - -class alphaBootloaderInfo(bootloaderInfo): - def wholeDevice (self, path): - (device, foo) = getDiskPart(path) - return device - - def partitionNum (self, path): - # getDiskPart returns part numbers 0-based; we need it one based - # *sigh* - (foo, partitionNumber) = getDiskPart(path) - return partitionNumber + 1 - - def writeAboot(self, instRoot, fsset, bl, kernelList, - chainList, defaultDev, justConfig): - # Get bootDevice and rootDevice - rootDevice = fsset.getEntryByMountPoint("/").device.getDevice() - if fsset.getEntryByMountPoint("/boot"): - bootDevice = fsset.getEntryByMountPoint("/boot").device.getDevice() - else: - bootDevice = rootDevice - bootnotroot = bootDevice != rootDevice - - # If /etc/aboot.conf already exists we rename it - # /etc/aboot.conf.rpmsave. - if os.path.isfile(instRoot + self.configfile): - os.rename (instRoot + self.configfile, - instRoot + self.configfile + ".rpmsave") - - # Then we create the necessary files. If the root device isn't - # the boot device, we create /boot/etc/ where the aboot.conf - # will live, and we create /etc/aboot.conf as a symlink to it. - if bootnotroot: - # Do we have /boot/etc ? If not, create one - if not os.path.isdir (instRoot + '/boot/etc'): - os.mkdir(instRoot + '/boot/etc', 0755) - - # We install the symlink (/etc/aboot.conf has already been - # renamed in necessary.) - os.symlink("../boot" + self.configfile, instRoot + self.configfile) - - cfPath = instRoot + "/boot" + self.configfile - # Kernel path is set to / because a boot partition will - # be a root on its own. - kernelPath = '/' - # Otherwise, we just need to create /etc/aboot.conf. - else: - cfPath = instRoot + self.configfile - kernelPath = self.kernelLocation - - # If we already have an aboot.conf, rename it - if os.access (cfPath, os.R_OK): - self.perms = os.stat(cfPath)[0] & 0777 - os.rename(cfPath, cfPath + '.rpmsave') - - # Now we're going to create and populate cfPath. - f = open (cfPath, 'w+') - f.write ("# aboot default configurations\n") - - if bootnotroot: - f.write ("# NOTICE: You have a /boot partition. This means that\n") - f.write ("# all kernel paths are relative to /boot/\n") - - # bpn is the boot partition number. - bpn = self.partitionNum(bootDevice) - lines = 0 - - # We write entries line using the following format: - # <line><bpn><kernel-name> root=<rootdev> [options] - # We get all the kernels we need to know about in kernelList. - - for (kernel, tag, version) in kernelList: - kernelTag = "-" + version - kernelFile = "%svmlinuz%s" %(kernelPath, kernelTag) - - f.write("%d:%d%s" %(lines, bpn, kernelFile)) - - # See if we can come up with an initrd argument that exists - initrd = self.makeInitrd(kernelTag) - if os.path.isfile(instRoot + initrd): - f.write(" initrd=%sinitrd%s.img" %(kernelPath, kernelTag)) - - realroot = getRootDevName(initrd, fsset, rootDevice, instRoot) - f.write(" root=%s" %(realroot,)) - - args = self.args.get() - if args: - f.write(" %s" %(args,)) - - f.write("\n") - lines = lines + 1 - - # We're done writing the file - f.close () - del f - - if not justConfig: - # Now we're ready to write the relevant boot information. wbd - # is the whole boot device, bdpn is the boot device partition - # number. - wbd = self.wholeDevice (bootDevice) - bdpn = self.partitionNum (bootDevice) - - # Calling swriteboot. The first argument is the disk to write - # to and the second argument is a path to the bootstrap loader - # file. - args = ("swriteboot", ("/dev/%s" % wbd), "/boot/bootlx") - rhpl.executil.execWithRedirect ('/sbin/swriteboot', args, - root = instRoot, - stdout = "/dev/tty5", - stderr = "/dev/tty5") - - # Calling abootconf to configure the installed aboot. The - # first argument is the disk to use, the second argument is - # the number of the partition on which aboot.conf resides. - # It's always the boot partition whether it's / or /boot (with - # the mount point being omitted.) - args = ("abootconf", ("/dev/%s" % wbd), str (bdpn)) - rhpl.executil.execWithRedirect ('/sbin/abootconf', args, - root = instRoot, - stdout = "/dev/tty5", - stderr = "/dev/tty5") - - - def write(self, instRoot, fsset, bl, kernelList, chainList, - defaultDev, justConfig, intf): - if len(kernelList) < 1: - self.noKernelsWarn(intf) - - self.writeAboot(instRoot, fsset, bl, kernelList, - chainList, defaultDev, justConfig) - - def __init__(self): - bootloaderInfo.__init__(self) - self.useGrubVal = 0 - self.configfile = "/etc/aboot.conf" - # self.kernelLocation is already set to what we need. - self.password = None - self.pure = None - - -class ppcBootloaderInfo(bootloaderInfo): - def getBootDevs(self, fs, bl): - import fsset - - devs = [] - machine = rhpl.getPPCMachine() - - if machine == 'pSeries': - for entry in fs.entries: - if isinstance(entry.fsystem, fsset.prepbootFileSystem) \ - and entry.format: - devs.append('/dev/%s' % (entry.device.getDevice(),)) - elif machine == 'PMac': - for entry in fs.entries: - if isinstance(entry.fsystem, fsset.applebootstrapFileSystem) \ - and entry.format: - devs.append('/dev/%s' % (entry.device.getDevice(),)) - - if len(devs) == 0: - # Try to get a boot device; bplan OF understands ext3 - if machine == 'Pegasos' or machine == 'Efika': - entry = fs.getEntryByMountPoint('/boot') - # Try / if we don't have this we're not going to work - if not entry: - entry = fs.getEntryByMountPoint('/') - if entry: - dev = "/dev/%s" % (entry.device.getDevice(asBoot=1),) - devs.append(dev) - else: - if bl.getDevice(): - devs.append("/dev/%s" % bl.getDevice()) - return devs - - - def writeYaboot(self, instRoot, fsset, bl, kernelList, - chainList, defaultDev, justConfigFile): - - yabootTarget = string.join(self.getBootDevs(fsset, bl)) - - bootDev = fsset.getEntryByMountPoint("/boot") - if bootDev: - cf = "/boot/etc/yaboot.conf" - cfPath = "" - if not os.path.isdir(instRoot + "/boot/etc"): - os.mkdir(instRoot + "/boot/etc") - else: - bootDev = fsset.getEntryByMountPoint("/") - cfPath = "/boot" - cf = "/etc/yaboot.conf" - bootDev = bootDev.device.getDevice(asBoot = 1) - - f = open(instRoot + cf, "w+") - - f.write("# yaboot.conf generated by anaconda\n\n") - - f.write("boot=%s\n" %(yabootTarget,)) - f.write("init-message=\"Welcome to %s!\\nHit <TAB> for boot options\"\n\n" - % productName) - - (name, partNum) = getDiskPart(bootDev) - partno = partNum + 1 # 1 based - - f.write("partition=%s\n" %(partno,)) - - f.write("timeout=%s\n" % (self.timeout or 80)) - f.write("install=/usr/lib/yaboot/yaboot\n") - f.write("delay=5\n") - f.write("enablecdboot\n") - f.write("enableofboot\n") - f.write("enablenetboot\n") - - yabootProg = "/sbin/mkofboot" - if rhpl.getPPCMachine() == "PMac": - # write out the first hfs/hfs+ partition as being macosx - for (label, longlabel, device) in chainList: - if ((not label) or (label == "")): - continue - f.write("macosx=/dev/%s\n" %(device,)) - break - - f.write("magicboot=/usr/lib/yaboot/ofboot\n") - - elif rhpl.getPPCMachine() == "pSeries": - f.write("nonvram\n") - f.write("fstype=raw\n") - - else: # Default non-destructive case for anything else. - f.write("nonvram\n") - f.write("mntpoint=/boot/yaboot\n") - f.write("usemount\n") - if not os.access(instRoot + "/boot/yaboot", os.R_OK): - os.mkdir(instRoot + "/boot/yaboot") - yabootProg = "/sbin/ybin" - - if self.password: - f.write("password=%s\n" %(self.password,)) - f.write("restricted\n") - - f.write("\n") - - rootDev = fsset.getEntryByMountPoint("/").device.getDevice() - - for (label, longlabel, version) in kernelList: - kernelTag = "-" + version - kernelFile = "%s/vmlinuz%s" %(cfPath, kernelTag) - - f.write("image=%s\n" %(kernelFile,)) - f.write("\tlabel=%s\n" %(label,)) - f.write("\tread-only\n") - - initrd = self.makeInitrd(kernelTag) - if os.access(instRoot + initrd, os.R_OK): - f.write("\tinitrd=%s/initrd%s.img\n" %(cfPath,kernelTag)) - - append = "%s" %(self.args.get(),) - - realroot = getRootDevName(initrd, fsset, rootDev, instRoot) - if rootIsDevice(realroot): - f.write("\troot=%s\n" %(realroot,)) - else: - if len(append) > 0: - append = "%s root=%s" %(append,realroot) - else: - append = "root=%s" %(realroot,) - - if len(append) > 0: - f.write("\tappend=\"%s\"\n" %(append,)) - f.write("\n") - - f.close() - os.chmod(instRoot + cf, 0600) - - # FIXME: hack to make sure things are written to disk - import isys - isys.sync() - isys.sync() - isys.sync() - - ybinargs = [ yabootProg, "-f", "-C", cf ] - - if not flags.test: - rhpl.executil.execWithRedirect(ybinargs[0], - ybinargs, - stdout = "/dev/tty5", - stderr = "/dev/tty5", - root = instRoot) - - if (not os.access(instRoot + "/etc/yaboot.conf", os.R_OK) and - os.access(instRoot + "/boot/etc/yaboot.conf", os.R_OK)): - os.symlink("../boot/etc/yaboot.conf", - instRoot + "/etc/yaboot.conf") - - return "" - - def setPassword(self, val, isCrypted = 1): - # yaboot just handles the password and doesn't care if its crypted - # or not - self.password = val - - def write(self, instRoot, fsset, bl, kernelList, chainList, - defaultDev, justConfig, intf): - if len(kernelList) >= 1: - out = self.writeYaboot(instRoot, fsset, bl, kernelList, - chainList, defaultDev, justConfig) - else: - self.noKernelsWarn(intf) - - def __init__(self): - bootloaderInfo.__init__(self) - self.useYabootVal = 1 - self.kernelLocation = "/boot" - self.configfile = "/etc/yaboot.conf" - -class sparcBootloaderInfo(bootloaderInfo): - def writeSilo(self, instRoot, fsset, bl, kernelList, - chainList, defaultDev, justConfigFile): - - bootDev = fsset.getEntryByMountPoint("/boot") - mf = '/silo.message' - if bootDev: - cf = "/boot/silo.conf" - mfdir = '/boot' - cfPath = "" - if not os.path.isdir(instRoot + "/boot"): - os.mkdir(instRoot + "/boot") - else: - bootDev = fsset.getEntryByMountPoint("/") - cf = "/etc/silo.conf" - mfdir = '/etc' - cfPath = "/boot" - bootDev = bootDev.device.getDevice(asBoot = 1) - - f = open(instRoot + mfdir + mf, "w+") - f.write("Welcome to %s!\nHit <TAB> for boot options\n\n" % productName) - f.close() - os.chmod(instRoot + mfdir + mf, 0600) - - f = open(instRoot + cf, "w+") - f.write("# silo.conf generated by anaconda\n\n") - - f.write("#boot=%s\n" % (bootDev,)) - f.write("message=%s\n" % (mf,)) - f.write("timeout=%s\n" % (self.timeout or 50)) - - (name, partNum) = getDiskPart(bootDev) - partno = partNum + 1 - f.write("partition=%s\n" % (partno,)) - - if self.password: - f.write("password=%s\n" % (self.password,)) - f.write("restricted\n") - - f.write("default=%s\n" % (kernelList[0][0],)) - f.write("\n") - - rootDev = fsset.getEntryByMountPoint("/").device.getDevice() - - for (label, longlabel, version) in kernelList: - kernelTag = "-" + version - kernelFile = "%s/vmlinuz%s" % (cfPath, kernelTag) - - f.write("image=%s\n" % (kernelFile,)) - f.write("\tlabel=%s\n" % (label,)) - f.write("\tread-only\n") - - initrd = self.makeInitrd(kernelTag) - if os.access(instRoot + initrd, os.R_OK): - f.write("\tinitrd=%s/initrd%s.img\n" % (cfPath, kernelTag)) - - append = "%s" % (self.args.get(),) - - realroot = getRootDevName(initrd, fsset, rootDev, instRoot) - if rootIsDevice(realroot): - f.write("\troot=%s\n" % (realroot,)) - else: - if len(append) > 0: - append = "%s root=%s" % (append, realroot) - else: - append = "root=%s" % (realroot,) - - if len(append) > 0: - f.write("\tappend=\"%s\"\n" % (append,)) - f.write("\n") - - f.close() - os.chmod(instRoot + cf, 0600) - - # FIXME: hack to make sure things are written to disk - import isys - isys.sync() - isys.sync() - isys.sync() - - backup = "%s/backup.b" % (cfPath,) - sbinargs = ["/sbin/silo", "-f", "-C", cf, "-S", backup] - # TODO!!! FIXME!!! XXX!!! - # butil is not defined!!! - assume this is in rhpl now? - if butil.getSparcMachine() == "sun4u": - sbinargs += ["-u"] - else: - sbinargs += ["-U"] - - if not flags.test: - rhpl.executil.execWithRedirect(sbinargs[0], - sbinargs, - stdout = "/dev/tty5", - stderr = "/dev/tty5", - root = instRoot) - - if (not os.access(instRoot + "/etc/silo.conf", os.R_OK) and - os.access(instRoot + "/boot/etc/silo.conf", os.R_OK)): - os.symlink("../boot/etc/silo.conf", - instRoot + "/etc/silo.conf") - - return "" - - def setPassword(self, val, isCrypted = 1): - # silo just handles the password unencrypted - self.password = val - - def write(self, instRoot, fsset, bl, kernelList, chainList, - defaultDev, justConfig, intf): - if len(kernelList) >= 1: - self.writeSilo(instRoot, fsset, bl, kernelList, chainList, - defaultDev, justConfig) - else: - self.noKernelsWarn(intf) - - def __init__(self): - bootloaderInfo.__init__(self) - self.useSiloVal = 1 - self.kernelLocation = "/boot" - self._configdir = "/etc" - self._configname = "silo.conf" - -############### -# end of boot loader objects... these are just some utility functions used - -def rootIsDevice(dev): - if dev.startswith("LABEL=") or dev.startswith("UUID="): - return False - return True - -# hackery to determine if we should do root=LABEL=/ or whatnot -# as usual, knows too much about anaconda -def getRootDevName(initrd, fsset, rootDev, instRoot): - if not os.access(instRoot + initrd, os.R_OK): - return "/dev/%s" % (rootDev,) - - try: - rootEntry = fsset.getEntryByMountPoint("/") - if rootEntry.getUuid() is not None: - return "UUID=%s" %(rootEntry.getUuid(),) - elif rootEntry.getLabel() is not None and rootEntry.device.doLabel is not None: - return "LABEL=%s" %(rootEntry.getLabel(),) - return "/dev/%s" %(rootDev,) - except: - return "/dev/%s" %(rootDev,) diff --git a/booty/ia64.py b/booty/ia64.py new file mode 100644 index 000000000..3f1e88393 --- /dev/null +++ b/booty/ia64.py @@ -0,0 +1,39 @@ +from bootloaderInfo import * + +class ia64BootloaderInfo(efiBootloaderInfo): + def getBootloaderConfig(self, instRoot, fsset, bl, kernelList, + chainList, defaultDev): + config = bootloaderInfo.getBootloaderConfig(self, instRoot, fsset, + bl, kernelList, chainList, + defaultDev) + # altix boxes need relocatable (#120851) + config.addEntry("relocatable") + + return config + + def writeLilo(self, instRoot, fsset, bl, kernelList, + chainList, defaultDev, justConfig): + config = self.getBootloaderConfig(instRoot, fsset, bl, + kernelList, chainList, defaultDev) + config.write(instRoot + self.configfile, perms = 0755) + + return "" + + def write(self, instRoot, fsset, bl, kernelList, chainList, + defaultDev, justConfig, intf): + if len(kernelList) >= 1: + out = self.writeLilo(instRoot, fsset, bl, kernelList, + chainList, defaultDev, justConfig) + else: + self.noKernelsWarn(intf) + + self.removeOldEfiEntries(instRoot) + self.addNewEfiEntry(instRoot, fsset) + + def makeInitrd(self, kernelTag): + return "/boot/efi/EFI/redhat/initrd%s.img" % kernelTag + + def __init__(self): + efiBootloaderInfo.__init__(self) + self._configname = "elilo.conf" + self._bootloader = "elilo.efi" diff --git a/booty/ppc.py b/booty/ppc.py new file mode 100644 index 000000000..26881ec80 --- /dev/null +++ b/booty/ppc.py @@ -0,0 +1,179 @@ +import string +import os + +from bootloaderInfo import * +import fsset +import rhpl + +class ppcBootloaderInfo(bootloaderInfo): + def getBootDevs(self, fs, bl): + import fsset + + devs = [] + machine = rhpl.getPPCMachine() + + if machine == 'pSeries': + for entry in fs.entries: + if isinstance(entry.fsystem, fsset.prepbootFileSystem) \ + and entry.format: + devs.append('/dev/%s' % (entry.device.getDevice(),)) + elif machine == 'PMac': + for entry in fs.entries: + if isinstance(entry.fsystem, fsset.applebootstrapFileSystem) \ + and entry.format: + devs.append('/dev/%s' % (entry.device.getDevice(),)) + + if len(devs) == 0: + # Try to get a boot device; bplan OF understands ext3 + if machine == 'Pegasos' or machine == 'Efika': + entry = fs.getEntryByMountPoint('/boot') + # Try / if we don't have this we're not going to work + if not entry: + entry = fs.getEntryByMountPoint('/') + if entry: + dev = "/dev/%s" % (entry.device.getDevice(asBoot=1),) + devs.append(dev) + else: + if bl.getDevice(): + devs.append("/dev/%s" % bl.getDevice()) + return devs + + + def writeYaboot(self, instRoot, fsset, bl, kernelList, + chainList, defaultDev, justConfigFile): + + yabootTarget = string.join(self.getBootDevs(fsset, bl)) + + bootDev = fsset.getEntryByMountPoint("/boot") + if bootDev: + cf = "/boot/etc/yaboot.conf" + cfPath = "" + if not os.path.isdir(instRoot + "/boot/etc"): + os.mkdir(instRoot + "/boot/etc") + else: + bootDev = fsset.getEntryByMountPoint("/") + cfPath = "/boot" + cf = "/etc/yaboot.conf" + bootDev = bootDev.device.getDevice(asBoot = 1) + + f = open(instRoot + cf, "w+") + + f.write("# yaboot.conf generated by anaconda\n\n") + + f.write("boot=%s\n" %(yabootTarget,)) + f.write("init-message=\"Welcome to %s!\\nHit <TAB> for boot options\"\n\n" + % productName) + + (name, partNum) = getDiskPart(bootDev) + partno = partNum + 1 # 1 based + + f.write("partition=%s\n" %(partno,)) + + f.write("timeout=%s\n" % (self.timeout or 80)) + f.write("install=/usr/lib/yaboot/yaboot\n") + f.write("delay=5\n") + f.write("enablecdboot\n") + f.write("enableofboot\n") + f.write("enablenetboot\n") + + yabootProg = "/sbin/mkofboot" + if rhpl.getPPCMachine() == "PMac": + # write out the first hfs/hfs+ partition as being macosx + for (label, longlabel, device) in chainList: + if ((not label) or (label == "")): + continue + f.write("macosx=/dev/%s\n" %(device,)) + break + + f.write("magicboot=/usr/lib/yaboot/ofboot\n") + + elif rhpl.getPPCMachine() == "pSeries": + f.write("nonvram\n") + f.write("fstype=raw\n") + + else: # Default non-destructive case for anything else. + f.write("nonvram\n") + f.write("mntpoint=/boot/yaboot\n") + f.write("usemount\n") + if not os.access(instRoot + "/boot/yaboot", os.R_OK): + os.mkdir(instRoot + "/boot/yaboot") + yabootProg = "/sbin/ybin" + + if self.password: + f.write("password=%s\n" %(self.password,)) + f.write("restricted\n") + + f.write("\n") + + rootDev = fsset.getEntryByMountPoint("/").device.getDevice() + + for (label, longlabel, version) in kernelList: + kernelTag = "-" + version + kernelFile = "%s/vmlinuz%s" %(cfPath, kernelTag) + + f.write("image=%s\n" %(kernelFile,)) + f.write("\tlabel=%s\n" %(label,)) + f.write("\tread-only\n") + + initrd = self.makeInitrd(kernelTag) + if os.access(instRoot + initrd, os.R_OK): + f.write("\tinitrd=%s/initrd%s.img\n" %(cfPath,kernelTag)) + + append = "%s" %(self.args.get(),) + + realroot = getRootDevName(initrd, fsset, rootDev, instRoot) + if rootIsDevice(realroot): + f.write("\troot=%s\n" %(realroot,)) + else: + if len(append) > 0: + append = "%s root=%s" %(append,realroot) + else: + append = "root=%s" %(realroot,) + + if len(append) > 0: + f.write("\tappend=\"%s\"\n" %(append,)) + f.write("\n") + + f.close() + os.chmod(instRoot + cf, 0600) + + # FIXME: hack to make sure things are written to disk + import isys + isys.sync() + isys.sync() + isys.sync() + + ybinargs = [ yabootProg, "-f", "-C", cf ] + + if not flags.test: + rhpl.executil.execWithRedirect(ybinargs[0], + ybinargs, + stdout = "/dev/tty5", + stderr = "/dev/tty5", + root = instRoot) + + if (not os.access(instRoot + "/etc/yaboot.conf", os.R_OK) and + os.access(instRoot + "/boot/etc/yaboot.conf", os.R_OK)): + os.symlink("../boot/etc/yaboot.conf", + instRoot + "/etc/yaboot.conf") + + return "" + + def setPassword(self, val, isCrypted = 1): + # yaboot just handles the password and doesn't care if its crypted + # or not + self.password = val + + def write(self, instRoot, fsset, bl, kernelList, chainList, + defaultDev, justConfig, intf): + if len(kernelList) >= 1: + out = self.writeYaboot(instRoot, fsset, bl, kernelList, + chainList, defaultDev, justConfig) + else: + self.noKernelsWarn(intf) + + def __init__(self): + bootloaderInfo.__init__(self) + self.useYabootVal = 1 + self.kernelLocation = "/boot" + self.configfile = "/etc/yaboot.conf" diff --git a/booty/s390.py b/booty/s390.py new file mode 100644 index 000000000..d48030d55 --- /dev/null +++ b/booty/s390.py @@ -0,0 +1,179 @@ +import os + +from bootloaderInfo import * +import fsset +import rhpl + +class s390BootloaderInfo(bootloaderInfo): + def getBootloaderConfig(self, instRoot, fsset, bl, kernelList, + chainList, defaultDev): + images = bl.images.getImages() + + # on upgrade read in the lilo config file + lilo = LiloConfigFile () + self.perms = 0600 + 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, path, other) = lilo.getImage(label) + if fsType == "other": continue + + if not os.access(instRoot + sl.getPath(), os.R_OK): + lilo.delImage(label) + + rootDev = fsset.getEntryByMountPoint("/").device.getDevice() + if not rootDev: + raise RuntimeError, "Installing zipl, 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 = self.makeInitrd(kernelTag) + + 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, path, other) = 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, path, other) = 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, bl, instroot): # S/390 only + cf = "/etc/chandev.conf" + self.perms = 0644 + if bl.args.chandevget(): + fd = os.open(instroot + "/etc/chandev.conf", + os.O_WRONLY | os.O_CREAT) + os.write(fd, "noauto\n") + for cdev in bl.args.chandevget(): + os.write(fd,'%s\n' % cdev) + os.close(fd) + return "" + + + def writeZipl(self, instRoot, fsset, bl, 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') + f.write('target=%s\n' % (self.kernelLocation)) + + cfPath = "/boot/" + for (label, longlabel, version) in kernelList: + kernelTag = "-" + version + kernelFile = "%svmlinuz%s" % (cfPath, kernelTag) + + initrd = self.makeInitrd(kernelTag) + f.write('[%s]\n' % (label)) + f.write('\timage=%s\n' % (kernelFile)) + if os.access (instRoot + initrd, os.R_OK): + f.write('\tramdisk=%sinitrd%s.img\n' %(self.kernelLocation, + kernelTag)) + realroot = getRootDevName(initrd, fsset, rootDev, instRoot) + f.write('\tparameters="root=%s' %(realroot,)) + if bl.args.get(): + f.write(' %s' % (bl.args.get())) + f.write('"\n') + + f.close() + + if not justConfigFile: + argv = [ "/sbin/zipl" ] + rhpl.executil.execWithRedirect(argv[0], argv, root = instRoot, + stdout = "/dev/stdout", + stderr = "/dev/stderr") + + return "" + + def write(self, instRoot, fsset, bl, kernelList, chainList, + defaultDev, justConfig, intf): + out = self.writeZipl(instRoot, fsset, bl, kernelList, + chainList, defaultDev, + justConfig | (not self.useZiplVal)) + out = self.writeChandevConf(bl, instRoot) + + def __init__(self): + bootloaderInfo.__init__(self) + self.useZiplVal = 1 # only used on s390 + self.kernelLocation = "/boot/" + self.configfile = "/etc/zipl.conf" diff --git a/booty/sparc.py b/booty/sparc.py new file mode 100644 index 000000000..471caa060 --- /dev/null +++ b/booty/sparc.py @@ -0,0 +1,127 @@ +import os + +from bootloaderInfo import * +import fsset +import rhpl + +class sparcBootloaderInfo(bootloaderInfo): + def writeSilo(self, instRoot, fsset, bl, kernelList, + chainList, defaultDev, justConfigFile): + + bootDev = fsset.getEntryByMountPoint("/boot") + mf = '/silo.message' + if bootDev: + cf = "/boot/silo.conf" + mfdir = '/boot' + cfPath = "" + if not os.path.isdir(instRoot + "/boot"): + os.mkdir(instRoot + "/boot") + else: + bootDev = fsset.getEntryByMountPoint("/") + cf = "/etc/silo.conf" + mfdir = '/etc' + cfPath = "/boot" + bootDev = bootDev.device.getDevice(asBoot = 1) + + f = open(instRoot + mfdir + mf, "w+") + f.write("Welcome to %s!\nHit <TAB> for boot options\n\n" % productName) + f.close() + os.chmod(instRoot + mfdir + mf, 0600) + + f = open(instRoot + cf, "w+") + f.write("# silo.conf generated by anaconda\n\n") + + f.write("#boot=%s\n" % (bootDev,)) + f.write("message=%s\n" % (mf,)) + f.write("timeout=%s\n" % (self.timeout or 50)) + + (name, partNum) = getDiskPart(bootDev) + partno = partNum + 1 + f.write("partition=%s\n" % (partno,)) + + if self.password: + f.write("password=%s\n" % (self.password,)) + f.write("restricted\n") + + f.write("default=%s\n" % (kernelList[0][0],)) + f.write("\n") + + rootDev = fsset.getEntryByMountPoint("/").device.getDevice() + + for (label, longlabel, version) in kernelList: + kernelTag = "-" + version + kernelFile = "%s/vmlinuz%s" % (cfPath, kernelTag) + + f.write("image=%s\n" % (kernelFile,)) + f.write("\tlabel=%s\n" % (label,)) + f.write("\tread-only\n") + + initrd = self.makeInitrd(kernelTag) + if os.access(instRoot + initrd, os.R_OK): + f.write("\tinitrd=%s/initrd%s.img\n" % (cfPath, kernelTag)) + + append = "%s" % (self.args.get(),) + + realroot = getRootDevName(initrd, fsset, rootDev, instRoot) + if rootIsDevice(realroot): + f.write("\troot=%s\n" % (realroot,)) + else: + if len(append) > 0: + append = "%s root=%s" % (append, realroot) + else: + append = "root=%s" % (realroot,) + + if len(append) > 0: + f.write("\tappend=\"%s\"\n" % (append,)) + f.write("\n") + + f.close() + os.chmod(instRoot + cf, 0600) + + # FIXME: hack to make sure things are written to disk + import isys + isys.sync() + isys.sync() + isys.sync() + + backup = "%s/backup.b" % (cfPath,) + sbinargs = ["/sbin/silo", "-f", "-C", cf, "-S", backup] + # TODO!!! FIXME!!! XXX!!! + # butil is not defined!!! - assume this is in rhpl now? + if butil.getSparcMachine() == "sun4u": + sbinargs += ["-u"] + else: + sbinargs += ["-U"] + + if not flags.test: + rhpl.executil.execWithRedirect(sbinargs[0], + sbinargs, + stdout = "/dev/tty5", + stderr = "/dev/tty5", + root = instRoot) + + if (not os.access(instRoot + "/etc/silo.conf", os.R_OK) and + os.access(instRoot + "/boot/etc/silo.conf", os.R_OK)): + os.symlink("../boot/etc/silo.conf", + instRoot + "/etc/silo.conf") + + return "" + + def setPassword(self, val, isCrypted = 1): + # silo just handles the password unencrypted + self.password = val + + def write(self, instRoot, fsset, bl, kernelList, chainList, + defaultDev, justConfig, intf): + if len(kernelList) >= 1: + self.writeSilo(instRoot, fsset, bl, kernelList, chainList, + defaultDev, justConfig) + else: + self.noKernelsWarn(intf) + + def __init__(self): + bootloaderInfo.__init__(self) + self.useSiloVal = 1 + self.kernelLocation = "/boot" + self._configdir = "/etc" + self._configname = "silo.conf" diff --git a/booty/x86.py b/booty/x86.py new file mode 100644 index 000000000..535aaab84 --- /dev/null +++ b/booty/x86.py @@ -0,0 +1,567 @@ +import os +import string + +from bootloaderInfo import * +import checkbootloader +import fsset +import iutil +import rhpl + +class x86BootloaderInfo(efiBootloaderInfo): + def setPassword(self, val, isCrypted = 1): + if not val: + self.password = val + self.pure = val + return + + if isCrypted and self.useGrubVal == 0: + self.pure = None + return + elif isCrypted: + self.password = val + self.pure = None + else: + salt = "$1$" + saltLen = 8 + + saltchars = string.letters + string.digits + './' + for i in range(saltLen): + salt += random.choice(saltchars) + + 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 getPhysicalDevices(self, device): + # This finds a list of devices on which the given device name resides. + # Accepted values for "device" are raid1 md devices (i.e. "md0"), + # physical disks ("hda"), and real partitions on physical disks + # ("hda1"). Volume groups/logical volumes are not accepted. + # + # XXX this has internal anaconda-ish knowledge. ick. + import isys + import lvm + + if string.split(device, '/', 1)[0] in map (lambda vg: vg[0], + lvm.vglist()): + return [] + + if device.startswith("mapper/luks-"): + return [] + + if device.startswith('md'): + bootable = 0 + parts = checkbootloader.getRaidDisks(device, 1, stripPart=0) + parts.sort() + return parts + + return [device] + + def runGrubInstall(self, instRoot, bootDev, cmds, cfPath): + if cfPath == "/": + syncDataToDisk(bootDev, "/boot", instRoot) + else: + syncDataToDisk(bootDev, "/", instRoot) + + # copy the stage files over into /boot + rhpl.executil.execWithRedirect( "/sbin/grub-install", + ["/sbin/grub-install", "--just-copy"], + stdout = "/dev/tty5", stderr = "/dev/tty5", + root = instRoot) + + # really install the bootloader + for cmd in cmds: + p = os.pipe() + os.write(p[1], cmd + '\n') + os.close(p[1]) + + # FIXME: hack to try to make sure everything is written + # to the disk + if cfPath == "/": + syncDataToDisk(bootDev, "/boot", instRoot) + else: + syncDataToDisk(bootDev, "/", instRoot) + + rhpl.executil.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]) + + def installGrub(self, instRoot, bootDevs, grubTarget, grubPath, fsset, + target, cfPath): + if iutil.isEfi(): + efiBootloaderInfo.installGrub(self, instRoot, bootDevs, grubTarget, + grubPath, fsset, target, cfPath) + return + + args = "--stage2=/boot/grub/stage2 " + if self.forceLBA32: + args = "%s--force-lba " % (args,) + + cmds = [] + for bootDev in bootDevs: + gtPart = self.getMatchingPart(bootDev, grubTarget) + gtDisk = self.grubbyPartitionName(fsset.getDiskPart(gtPart)[0]) + bPart = self.grubbyPartitionName(bootDev) + cmd = "root %s\n" % (bPart,) + + stage1Target = gtDisk + if target == "partition": + stage1Target = self.grubbyPartitionName(gtPart) + + cmd += "install %s%s/stage1 d %s %s/stage2 p %s%s/grub.conf" % \ + (args, grubPath, stage1Target, grubPath, bPart, grubPath) + cmds.append(cmd) + + self.runGrubInstall(instRoot, bootDev, cmds, cfPath) + + def writeGrub(self, instRoot, fsset, bl, kernelList, chainList, + defaultDev, justConfigFile): + + images = bl.images.getImages() + rootDev = fsset.getEntryByMountPoint("/").device.getDevice() + + # XXX old config file should be read here for upgrade + + cf = "%s%s" % (instRoot, self.configfile) + self.perms = 0600 + if os.access (cf, os.R_OK): + self.perms = os.stat(cf)[0] & 0777 + os.rename(cf, cf + '.rpmsave') + + grubTarget = bl.getDevice() + target = "mbr" + if (grubTarget.startswith('rd/') or grubTarget.startswith('ida/') or + grubTarget.startswith('cciss/') or + grubTarget.startswith('sx8/') or + grubTarget.startswith('mapper/')): + if grubTarget[-1].isdigit(): + if grubTarget[-2] == 'p' or \ + (grubTarget[-2].isdigit() and grubTarget[-3] == 'p'): + target = "partition" + elif grubTarget[-1].isdigit() and not grubTarget.startswith('md'): + target = "partition" + + f = open(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") + + bootDevs = self.getPhysicalDevices(bootDev.device.getDevice()) + bootDev = bootDev.device.getDevice() + + f.write('# root %s\n' % self.grubbyPartitionName(bootDevs[0])) + 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=%d\n' % (self.timeout or 0)) + + if self.serial == 1: + # grub the 0-based number of the serial console device + unit = self.serialDevice[-1] + + # and we want to set the speed too + speedend = 0 + for char in self.serialOptions: + if char not in string.digits: + break + speedend = speedend + 1 + if speedend != 0: + speed = self.serialOptions[:speedend] + else: + # reasonable default + speed = "9600" + + f.write("serial --unit=%s --speed=%s\n" %(unit, speed)) + f.write("terminal --timeout=%s serial console\n" % (self.timeout or 5)) + else: + # we only want splashimage if they're not using a serial console + if os.access("%s/boot/grub/splash.xpm.gz" %(instRoot,), os.R_OK): + f.write('splashimage=%s%sgrub/splash.xpm.gz\n' + % (self.grubbyPartitionName(bootDevs[0]), cfPath)) + f.write("hiddenmenu\n") + + for dev in self.getPhysicalDevices(grubTarget): + usedDevs[dev] = 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 = self.makeInitrd(kernelTag) + + f.write('title %s (%s)\n' % (longlabel, version)) + f.write('\troot %s\n' % self.grubbyPartitionName(bootDevs[0])) + + realroot = getRootDevName(initrd, fsset, rootDev, instRoot) + realroot = " root=%s" %(realroot,) + + if version.endswith("xen0") or (version.endswith("xen") and not os.path.exists("/proc/xen")): + # hypervisor case + sermap = { "ttyS0": "com1", "ttyS1": "com2", + "ttyS2": "com3", "ttyS3": "com4" } + if self.serial and sermap.has_key(self.serialDevice) and \ + self.serialOptions: + hvs = "%s=%s" %(sermap[self.serialDevice], + self.serialOptions) + else: + hvs = "" + if version.endswith("xen0"): + hvFile = "%sxen.gz-%s %s" %(cfPath, + version.replace("xen0", ""), + hvs) + else: + hvFile = "%sxen.gz-%s %s" %(cfPath, + version.replace("xen", ""), + hvs) + f.write('\tkernel %s\n' %(hvFile,)) + f.write('\tmodule %s ro%s' %(kernelFile, realroot)) + if self.args.get(): + f.write(' %s' % self.args.get()) + f.write('\n') + + if os.access (instRoot + initrd, os.R_OK): + f.write('\tmodule %sinitrd%s.img\n' % (cfPath, kernelTag)) + else: # normal kernel + f.write('\tkernel %s ro%s' % (kernelFile, realroot)) + 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' % self.grubbyPartitionName(device)) +# f.write('\tmakeactive\n') + f.write('\tchainloader +1') + f.write('\n') + usedDevs[device] = 1 + + f.close() + + if not "/efi/" in cf: + os.chmod(cf, self.perms) + + try: + # make symlink for menu.lst (default config file name) + menulst = "%s%s/menu.lst" % (instRoot, self.configdir) + if os.access (menulst, os.R_OK): + os.rename(menulst, menulst + ".rpmsave") + os.symlink("./grub.conf", menulst) + except: + pass + + try: + # make symlink for /etc/grub.conf (config files belong in /etc) + etcgrub = "%s%s" % (instRoot, "/etc/grub.conf") + if os.access (etcgrub, os.R_OK): + os.rename(etcgrub, etcgrub + ".rpmsave") + os.symlink(".." + self.configfile, etcgrub) + except: + pass + + for dev in self.getPhysicalDevices(rootDev) + bootDevs: + usedDevs[dev] = 1 + + if os.access(instRoot + "/boot/grub/device.map", os.R_OK): + os.rename(instRoot + "/boot/grub/device.map", + instRoot + "/boot/grub/device.map.rpmsave") + if 1: # 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") + devs = usedDevs.keys() + usedDevs = {} + for dev in devs: + drive = fsset.getDiskPart(dev)[0] + if usedDevs.has_key(drive): + continue + usedDevs[drive] = 1 + devs = usedDevs.keys() + devs.sort() + for drive in devs: + # XXX hack city. If they're not the sort of thing that'll + # be in the device map, they shouldn't still be in the list. + if not drive.startswith('md'): + f.write("(%s) /dev/%s\n" % (self.grubbyDiskName(drive), + drive)) + f.close() + + sysconf = '/etc/sysconfig/grub' + if os.access (instRoot + sysconf, os.R_OK): + self.perms = os.stat(instRoot + sysconf)[0] & 0777 + os.rename(instRoot + sysconf, + instRoot + sysconf + '.rpmsave') + # if it's an absolute symlink, just get it out of our way + elif (os.path.islink(instRoot + sysconf) and + os.readlink(instRoot + sysconf)[0] == '/'): + os.rename(instRoot + sysconf, + instRoot + sysconf + '.rpmsave') + f = open(instRoot + sysconf, 'w+') + f.write("boot=/dev/%s\n" %(grubTarget,)) + # XXX forcelba never gets read back... + if self.forceLBA32: + f.write("forcelba=1\n") + else: + f.write("forcelba=0\n") + f.close() + + if not justConfigFile: + self.installGrub(instRoot, bootDevs, grubTarget, grubPath, fsset, \ + target, cfPath) + + return "" + + def getMatchingPart(self, bootDev, target): + bootName, bootPartNum = fsset.getDiskPart(bootDev) + devices = self.getPhysicalDevices(target) + for device in devices: + name, partNum = fsset.getDiskPart(device) + if name == bootName: + return device + return devices[0] + + def grubbyDiskName(self, name): + return "hd%d" % self.drivelist.index(name) + + def grubbyPartitionName(self, dev): + (name, partNum) = fsset.getDiskPart(dev) + if partNum != None: + return "(%s,%d)" % (self.grubbyDiskName(name), partNum) + else: + return "(%s)" %(self.grubbyDiskName(name)) + + + def getBootloaderConfig(self, instRoot, fsset, bl, kernelList, + chainList, defaultDev): + config = bootloaderInfo.getBootloaderConfig(self, instRoot, fsset, + bl, 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" + + if self.pure is not None and not self.useGrubVal: + config.addEntry("restricted", replace = 0) + config.addEntry("password", self.pure, replace = 0) + + if self.serial == 1: + # grab the 0-based number of the serial console device + unit = self.serialDevice[-1] + # FIXME: we should probably put some options, but lilo + # only supports up to 9600 baud so just use the defaults + # it's better than nothing :( + config.addEntry("serial=%s" %(unit,)) + else: + # message screws up serial console + if os.access(instRoot + message, os.R_OK): + config.addEntry("message", message, replace = 0) + + if not config.testEntry('lba32'): + if self.forceLBA32 or (bl.above1024 and + rhpl.getArch() != "x86_64"): + config.addEntry("lba32", replace = 0) + + return config + + # this is a hackish function that depends on the way anaconda writes + # out the grub.conf with a #boot= comment + # XXX this falls into the category of self.doUpgradeOnly + def upgradeGrub(self, instRoot, fsset, bl, kernelList, chainList, + defaultDev, justConfigFile): + if justConfigFile: + return "" + + theDev = None + for (fn, stanza) in [ ("/etc/sysconfig/grub", "boot="), + ("/boot/grub/grub.conf", "#boot=") ]: + try: + f = open(instRoot + fn, "r") + except: + continue + + # the following bits of code are straight from checkbootloader.py + lines = f.readlines() + f.close() + for line in lines: + if line.startswith(stanza): + theDev = checkbootloader.getBootDevString(line) + break + if theDev is not None: + break + + if theDev is None: + # we could find the dev before, but can't now... cry about it + return "" + + # migrate info to /etc/sysconfig/grub + self.writeSysconfig(instRoot, theDev) + + # more suckage. grub-install can't work without a valid /etc/mtab + # so we have to do shenanigans to get updated grub installed... + # steal some more code above + bootDev = fsset.getEntryByMountPoint("/boot") + grubPath = "/grub" + cfPath = "/" + if not bootDev: + bootDev = fsset.getEntryByMountPoint("/") + grubPath = "/boot/grub" + cfPath = "/boot/" + + masterBootDev = bootDev.device.getDevice(asBoot = 0) + if masterBootDev[0:2] == 'md': + rootDevs = checkbootloader.getRaidDisks(masterBootDev, raidLevel=1, + stripPart = 0) + else: + rootDevs = [masterBootDev] + + if theDev[5:7] == 'md': + stage1Devs = checkbootloader.getRaidDisks(theDev[5:], raidLevel=1) + else: + stage1Devs = [theDev[5:]] + + for stage1Dev in stage1Devs: + # cross fingers; if we can't find a root device on the same + # hardware as this boot device, we just blindly hope the first + # thing in the list works. + + grubbyStage1Dev = self.grubbyPartitionName(stage1Dev) + + grubbyRootPart = self.grubbyPartitionName(rootDevs[0]) + + for rootDev in rootDevs: + testGrubbyRootDev = fsset.getDiskPart(rootDev)[0] + testGrubbyRootDev = self.grubbyPartitionName(testGrubbyRootDev) + + if grubbyStage1Dev == testGrubbyRootDev: + grubbyRootPart = self.grubbyPartitionName(rootDev) + break + + args = "--stage2=/boot/grub/stage2 " + cmd ="root %s" % (grubbyRootPart,) + cmds = [ cmd ] + cmd = "install %s%s/stage1 d %s %s/stage2 p %s%s/grub.conf" \ + % (args, grubPath, grubbyStage1Dev, grubPath, grubbyRootPart, + grubPath) + cmds.append(cmd) + + if not justConfigFile: + self.runGrubInstall(instRoot, bootDev.device.setupDevice(), + cmds, cfPath) + + return "" + + def writeSysconfig(self, instRoot, installDev): + sysconf = '/etc/sysconfig/grub' + if not os.access(instRoot + sysconf, os.R_OK): + f = open(instRoot + sysconf, "w+") + f.write("boot=%s\n" %(installDev,)) + # XXX forcelba never gets read back at all... + if self.forceLBA32: + f.write("forcelba=1\n") + else: + f.write("forcelba=0\n") + f.close() + + def write(self, instRoot, fsset, bl, kernelList, chainList, + defaultDev, justConfig, intf): + if self.timeout is None and chainList: + self.timeout = 5 + + # XXX HACK ALERT - see declaration above + if self.doUpgradeOnly: + if self.useGrubVal: + self.upgradeGrub(instRoot, fsset, bl, kernelList, + chainList, defaultDev, justConfig) + return + + if len(kernelList) < 1: + self.noKernelsWarn(intf) + + out = self.writeGrub(instRoot, fsset, bl, 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 self.forceLBA32: + args.append("--lba32") + if self.password: + args.append("--md5pass=%s" %(self.password)) + + return args + + def __init__(self): + bootloaderInfo.__init__(self) + efiBootloaderInfo.__init__(self, initialize=False) + + self._configdir = "/boot/grub" + self._configname = "grub.conf" + # XXX use checkbootloader to determine what to default to + self.useGrubVal = 1 + self.kernelLocation = "/boot/" + self.password = None + self.pure = None |