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