diff -ruN yum-2.4.3.orig/cli.py yum-2.4.3/cli.py
--- yum-2.4.3.orig/cli.py 2007-04-29 11:57:45.000000000 +0200
+++ yum-2.4.3/cli.py 2007-04-29 11:58:42.000000000 +0200
@@ -37,6 +37,7 @@
from yum.logger import Logger, SysLogger, LogContainer
from yum.config import yumconf
from yum import pgpmsg
+from yum import defaultkernel
from i18n import _
import callback
import urlgrabber
@@ -717,6 +718,8 @@
self.log(2, 'Running Transaction')
self.runTransaction(cb=cb)
+ self.doDefaultKernelMagic()
+
# close things
self.log(1, self.postTransactionOutput())
return 0
@@ -1463,6 +1466,35 @@
else:
return 0, ['No packages to remove from groups']
+ def doDefaultKernelMagic(self):
+ kernels = defaultkernel.getInstalledKernels(self.tsInfo)
+ # Do something if any kernels were installed.
+ if len(kernels) > 0:
+ # Find the default kernel image file.
+ # provides this image file.
+ curDefaultKernel = defaultkernel.getDefaultKernel()
+ if not curDefaultKernel:
+ self.log(2, "Could not determine the default kernel!")
+ return
+
+ # Find the package that provides this image.
+ self.doRpmDBSetup()
+ defaultKernelTypeNaervs = self.rpmdb.whatProvides(curDefaultKernel, None, None)
+ if len(defaultKernelTypeNaervs) == 0:
+ self.log(2, "Could not determine which package provides %s!" % curDefaultKernel)
+ return
+
+ # There should not be more than one package providing the same kernel
+ # image, so pick the first one.
+ defaultKernelTypeNaerv = defaultKernelTypeNaervs[0]
+
+ # Check whether one of the kernel names matches the default kernel
+ # type. If so, the new kernel is probably a replacement of the old
+ # kernel, and we want to set it as the default kernel.
+ for kernel in kernels:
+ if kernel.name == defaultKernelTypeNaerv[0] and \
+ kernel.arch == defaultKernelTypeNaerv[1]:
+ defaultkernel.setDefaultKernel(self.log, kernel)
def _promptWanted(self):
# shortcut for the always-off/always-on options
diff -ruN yum-2.4.3.orig/yum/defaultkernel.py yum-2.4.3/yum/defaultkernel.py
--- yum-2.4.3.orig/yum/defaultkernel.py 1970-01-01 01:00:00.000000000 +0100
+++ yum-2.4.3/yum/defaultkernel.py 2007-04-29 11:58:04.000000000 +0200
@@ -0,0 +1,226 @@
+#!/usr/bin/env python
+#
+# Default kernel handling for CentOS 3 (helper functions).
+#
+# Copyright 2007 Daniel de Kok
+#
+# Bootloader detection:
+#
+# Jeremy Katz <katzj@redhat.com>
+# Copyright 2001-2002 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# Please report errors to Daniel de Kok <danieldk@pobox.com>
+
+import os
+import string
+import sys
+from i18n import _
+from yum.plugins import TYPE_CORE
+import yum
+
+requires_api_version = '2.1'
+plugin_type = (TYPE_CORE,)
+
+kernelNames = [
+ 'kernel', 'kernel-BOOT', 'kernel-hugemem',
+ 'kernel-hugemem-unsupported', 'kernel-smp',
+ 'kernel-smp-unsupported', 'kernel-unsupported'
+]
+
+grubConfigFile = "/boot/grub/grub.conf"
+liloConfigFile = "/etc/lilo.conf"
+
+# XXX: this is cut and pasted directly from booty/bootloaderInfo.py
+# should eventually just go from there
+def getDiskPart(dev):
+ """Return (disk, partition number) tuple for dev"""
+ cut = len(dev)
+ if (dev[:3] == "rd/" or dev[:4] == "ida/" or
+ dev[:6] == "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 getRaidDisks(raidDevice):
+ rc = []
+
+ try:
+ f = open("/proc/mdstat", "r")
+ lines = f.readlines()
+ f.close()
+ except:
+ return rc
+
+ for line in lines:
+ fields = string.split(line, ' ')
+ if fields[0] == raidDevice:
+ for field in fields[4:]:
+ if string.find(field, "[") == -1:
+ continue
+ dev = string.split(field, '[')[0]
+ if len(dev) == 0:
+ continue
+ disk = getDiskPart(dev)[0]
+ rc.append(disk)
+
+ return rc
+
+
+def getBootBlock(bootDev):
+ """Get the boot block from bootDev. Return a 512 byte string."""
+ block = " " * 512
+ if bootDev is None:
+ return block
+
+ # get the devices in the raid device
+ if bootDev[5:7] == "md":
+ bootDevs = getRaidDisks(bootDev[5:])
+ bootDevs.sort()
+ else:
+ bootDevs = [ bootDev[5:] ]
+
+ # FIXME: this is kind of a hack
+ # look at all of the devs in the raid device until we can read the
+ # boot block for one of them. should do this better at some point
+ # by looking at all of the drives properly
+ for dev in bootDevs:
+ try:
+# print "checking %s\n" %(dev,)
+ fd = os.open("/dev/%s" % (dev,), os.O_RDONLY)
+ block = os.read(fd, 512)
+ os.close(fd)
+ return block
+ except:
+ pass
+ return block
+
+# takes a line like #boot=/dev/hda and returns /dev/hda
+# also handles cases like quoted versions and other nonsense
+def getBootDevString(line):
+ dev = string.split(line, '=')[1]
+ dev = string.strip(dev)
+ dev = string.replace(dev, '"', '')
+ dev = string.replace(dev, "'", "")
+ return dev
+
+def whichBootLoader(instRoot = "/"):
+ haveGrubConf = 1
+ haveLiloConf = 1
+
+ bootDev = None
+
+ # make sure they have the config file, otherwise we definitely can't
+ # use that bootloader
+ if not os.access(instRoot + grubConfigFile, os.R_OK):
+ haveGrubConf = 0
+ if not os.access(instRoot + liloConfigFile, os.R_OK):
+ haveLiloConf = 0
+
+ if haveGrubConf:
+ f = open(grubConfigFile, "r")
+ lines = f.readlines()
+ for line in lines:
+ if line[0:6] == "#boot=":
+ bootDev = getBootDevString(line)
+ break
+
+ block = getBootBlock(bootDev)
+ # XXX I don't like this, but it's what the maintainer suggested :(
+ if string.find(block, "GRUB") >= 0:
+ return "GRUB"
+
+ if haveLiloConf:
+ f = open(liloConfigFile, "r")
+ lines = f.readlines()
+ for line in lines:
+ if line[0:5] == "boot=":
+ bootDev = getBootDevString(line)
+ break
+
+ block = getBootBlock(bootDev)
+ # this at least is well-defined
+ if block[6:10] == "LILO":
+ return "LILO"
+
+def getInstalledKernels(tsInfo):
+ """Get a list of kernels that were installed as a part of the
+ transaction."""
+ kernels = []
+ for tsMember in tsInfo.getMembers():
+ if tsMember.ts_state in ['i', 'u', 'ud', 'iu'] and tsMember.name in kernelNames:
+ kernels.append(tsMember.po)
+ return kernels
+
+def getDefaultKernel():
+ """Use grubby to figure out the default kernel."""
+ bootLoader = whichBootLoader()
+ try:
+ if bootLoader == 'GRUB':
+ pipe = os.popen("/sbin/grubby --grub --default-kernel")
+ elif bootLoader == 'LILO':
+ pipe = os.popen("/sbin/grubby --lilo --default-kernel")
+ else:
+ return None
+
+ defaultKernel = pipe.read().strip()
+ except:
+ return None
+
+ return defaultKernel
+
+def setDefaultKernel(logger, kernel):
+ """Use grubby to set the default kernel."""
+ bootLoader = whichBootLoader()
+ pkgTup = kernel.pkgtup
+ nameParts = pkgTup[0].split('-')
+ if len(nameParts) == 2:
+ flavor = nameParts[1]
+ else:
+ flavor = ""
+ newDefaultImage = "/boot/vmlinuz-%s-%s%s" % (pkgTup[3], pkgTup[4], flavor)
+
+ logger(2, "Setting default %s kernel to %s" % (bootLoader, newDefaultImage))
+
+ # Use the --grub or --lilo parameter, depending on the detected bootloader.
+ if bootLoader == 'GRUB':
+ ret = os.system("/sbin/grubby --grub --set-default %s" % newDefaultImage)
+ elif bootLoader == 'LILO':
+ ret = os.system("/sbin/grubby --lilo --set-default %s" % newDefaultImage)
+
+ if ret != 0:
+ logger(2, "Could not set %s as the default kernel!" % newDefaultImage)
+
+ return ret