Blob Blame History Raw
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