]> git.ipfire.org Git - ipfire-3.x.git/blob - src/pomona/bootloader.py
Added quiet option to kernel command line of the final system.
[ipfire-3.x.git] / src / pomona / bootloader.py
1 #
2 # bootloader.py: anaconda bootloader shims
3 #
4 # Erik Troan <ewt@redhat.com>
5 # Jeremy Katz <katzj@redhat.com>
6 #
7 # Copyright 2001-2006 Red Hat, Inc.
8 #
9 # This software may be freely redistributed under the terms of the GNU
10 # general public license.
11 #
12 # You should have received a copy of the GNU General Public License
13 # along with this program; if not, write to the Free Software
14 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 #
16
17 import isys
18 import partedUtils
19 import os
20 import sys
21 import inutil
22 import string
23 import crypt
24 import random
25 import shutil
26 import struct
27 from copy import copy
28 from flags import flags
29 from constants import *
30
31 import gettext
32 _ = lambda x: gettext.ldgettext("pomona", x)
33
34 import logging
35 log = logging.getLogger("pomona")
36
37 from fsset import *
38
39 import pyfire.executil
40
41 dosFilesystems = ('FAT', 'fat16', 'fat32', 'ntfs', 'hpfs')
42
43 def doesDualBoot():
44 return 1
45
46 def checkForBootBlock(device):
47 fd = os.open(device, os.O_RDONLY)
48 buf = os.read(fd, 512)
49 os.close(fd)
50 if len(buf) >= 512 and struct.unpack("H", buf[0x1fe: 0x200]) == (0xaa55,):
51 return True
52 return False
53
54 # takes a line like #boot=/dev/hda and returns /dev/hda
55 # also handles cases like quoted versions and other nonsense
56 def getBootDevString(line):
57 dev = string.split(line, '=')[1]
58 dev = string.strip(dev)
59 dev = string.replace(dev, '"', '')
60 dev = string.replace(dev, "'", "")
61 return dev
62
63 # hack and a half
64 # there's no guarantee that data is written to the disk and grub
65 # reads both the filesystem and the disk. suck.
66 def syncDataToDisk(dev, mntpt, instRoot = "/"):
67 import isys, fsset
68 isys.sync()
69 isys.sync()
70 isys.sync()
71
72 # and xfs is even more "special" (#117968)
73 if fsset.isValidXFS(dev):
74 pyfire.executil.execWithRedirect("/usr/sbin/xfs_freeze",
75 ["/usr/sbin/xfs_freeze", "-f", mntpt],
76 stdout = "/dev/tty5",
77 stderr = "/dev/tty5",
78 root = instRoot)
79 pyfire.executil.execWithRedirect("/usr/sbin/xfs_freeze",
80 ["/usr/sbin/xfs_freeze", "-u", mntpt],
81 stdout = "/dev/tty5",
82 stderr = "/dev/tty5",
83 root = instRoot)
84
85 class BootyNoKernelWarning(Exception):
86 pass
87
88 class KernelArguments:
89
90 def get(self):
91 return self.args
92
93 def set(self, args):
94 self.args = args
95
96 def chandevget(self):
97 return self.cargs
98
99 def chandevset(self, args):
100 self.cargs = args
101
102 def append(self, args):
103 if self.args:
104 # don't duplicate the addition of an argument (#128492)
105 if self.args.find(args) != -1:
106 return
107 self.args = self.args + " "
108 self.args = self.args + "%s" % (args,)
109
110
111 def __init__(self):
112 newArgs = []
113 # look for kernel arguments we know should be preserved and add them
114 ourargs = ["speakup_synth=", "apic", "noapic", "apm=", "ide=nodma",
115 "noht", "acpi=", "video=", "pci="]
116 f = open("/proc/cmdline")
117 cmdline = f.read()[:-1]
118 f.close()
119 cmdlineargs = cmdline.split(" ")
120 for arg in cmdlineargs:
121 for check in ourargs:
122 if arg.startswith(check):
123 newArgs.append(arg)
124
125 self.args = " ".join(newArgs)
126
127 class BootImages:
128 """A collection to keep track of boot images available on the system.
129 Examples would be:
130 ('linux', 'Red Hat Linux', 'ext2'),
131 ('Other', 'Other', 'fat32'), ...
132 """
133 def __init__(self):
134 self.default = None
135 self.images = {}
136
137 def getImages(self):
138 """returns dictionary of (label, longlabel, devtype) pairs
139 indexed by device"""
140 # return a copy so users can modify it w/o affecting us
141 return copy(self.images)
142
143 def setImageLabel(self, dev, label, setLong = 0):
144 orig = self.images[dev]
145 if setLong:
146 self.images[dev] = (orig[0], label, orig[2])
147 else:
148 self.images[dev] = (label, orig[1], orig[2])
149
150 def setDefault(self, default):
151 # default is a device
152 self.default = default
153
154 def getDefault(self):
155 return self.default
156
157 # XXX this has internal anaconda-ish knowledge. ick
158 def setup(self, diskSet, fsset):
159 devices = {}
160 devs = self.availableBootDevices(diskSet, fsset)
161 for (dev, type) in devs:
162 devices[dev] = 1
163
164 # These partitions have disappeared
165 for dev in self.images.keys():
166 if not devices.has_key(dev):
167 del self.images[dev]
168
169 # These have appeared
170 for (dev, type) in devs:
171 if not self.images.has_key(dev):
172 if type in dosFilesystems and doesDualBoot():
173 self.images[dev] = ("Other", "Other", type)
174 else:
175 self.images[dev] = (None, None, type)
176
177 if not self.images.has_key(self.default):
178 entry = fsset.getEntryByMountPoint('/')
179 self.default = entry.device.getDevice()
180 (label, longlabel, type) = self.images[self.default]
181 if not label:
182 self.images[self.default] = ("linux", getProductName(), type)
183
184 # XXX more internal anaconda knowledge
185 def availableBootDevices(self, diskSet, fsset):
186 devs = []
187 foundDos = 0
188 for (dev, type) in diskSet.partitionTypes():
189 if type in dosFilesystems and not foundDos and doesDualBoot():
190 import isys
191 import partedUtils
192
193 part = partedUtils.get_partition_by_name(diskSet.disks, dev)
194 if part.native_type not in partedUtils.dosPartitionTypes:
195 continue
196
197 try:
198 bootable = checkForBootBlock(dev)
199 devs.append((dev, type))
200 foundDos = 1
201 except Exception, e:
202 #log("exception checking %s: %s" %(dev, e))
203 pass
204 elif ((type == 'ntfs' or type =='hpfs') and not foundDos and doesDualBoot()):
205 devs.append((dev, type))
206 # maybe questionable, but the first ntfs or fat is likely to
207 # be the correct one to boot with XP using ntfs
208 foundDos = 1
209
210 slash = fsset.getEntryByMountPoint('/')
211 if not slash or not slash.device or not slash.fsystem:
212 raise ValueError,("Trying to pick boot devices but do not have a "
213 "sane root partition. Aborting install.")
214 devs.append((slash.device.getDevice(), slash.fsystem.getName()))
215
216 devs.sort()
217 return devs
218
219 class bootloaderInfo:
220 def useGrub(self):
221 return self.useGrubVal
222
223 def setForceLBA(self, val):
224 pass
225
226 def setPassword(self, val, isCrypted = 1):
227 pass
228
229 def getPassword(self):
230 pass
231
232 def getDevice(self):
233 return self.device
234
235 def setDevice(self, device):
236 self.device = device
237
238 (dev, part) = getDiskPart(device)
239 if part is None:
240 self.defaultDevice = "mbr"
241 else:
242 self.defaultDevice = "partition"
243
244 def createDriveList(self):
245 # create a drive list that we can use for drive mappings
246 # XXX has pomona internals knowledge
247 import isys
248 drives = isys.hardDriveDict().keys()
249 drives.sort(isys.compareDrives)
250
251 # now filter out all of the drives without media present
252 drives = filter(lambda x: isys.mediaPresent(x), drives)
253
254 return drives
255
256 def updateDriveList(self, sortedList=[]):
257 self._drivelist = self.createDriveList()
258
259 # If we're given a sort order, make sure the drives listed in it
260 # are put at the head of the drivelist in that order. All other
261 # drives follow behind in whatever order they're found.
262 if sortedList != []:
263 revSortedList = sortedList
264 revSortedList.reverse()
265
266 for i in revSortedList:
267 try:
268 ele = self._drivelist.pop(self._drivelist.index(i))
269 self._drivelist.insert(0, ele)
270 except:
271 pass
272
273 def _getDriveList(self):
274 if self._drivelist is not None:
275 return self._drivelist
276 self.updateDriveList()
277 return self._drivelist
278
279 def _setDriveList(self, val):
280 self._drivelist = val
281 drivelist = property(_getDriveList, _setDriveList)
282
283 def __init__(self):
284 self.args = KernelArguments()
285 self.images = BootImages()
286 self.device = None
287 self.defaultDevice = None # XXX hack, used by kickstart
288 self.useGrubVal = 0 # only used on x86
289 self.configfile = None
290 self.kernelLocation = "/boot/"
291 self.forceLBA32 = 0
292 self.password = None
293 self.pure = None
294 self.above1024 = 0
295 self._drivelist = None
296
297 class x86BootloaderInfo(bootloaderInfo):
298 def setPassword(self, val, isCrypted = 1):
299 if not val:
300 self.password = val
301 self.pure = val
302 return
303
304 if isCrypted and self.useGrubVal == 0:
305 #log("requested crypted password with lilo; ignoring")
306 self.pure = None
307 return
308 elif isCrypted:
309 self.password = val
310 self.pure = None
311 else:
312 salt = "$1$"
313 saltLen = 8
314
315 saltchars = string.letters + string.digits + './'
316 for i in range(saltLen):
317 salt += random.choice(saltchars)
318
319 self.password = crypt.crypt(val, salt)
320 self.pure = val
321
322 def getPassword (self):
323 return self.pure
324
325 def setForceLBA(self, val):
326 self.forceLBA32 = val
327
328 def getPhysicalDevices(self, device):
329 # This finds a list of devices on which the given device name resides.
330 # Accepted values for "device" are physical disks ("hda"),
331 # and real partitions on physical disks ("hda1").
332 #
333 return [device]
334
335 def writeGrub(self, instRoot, fsset, bl, kernelList, chainList,
336 defaultDev):
337
338 images = bl.images.getImages()
339 rootDev = fsset.getEntryByMountPoint("/").device.getDevice()
340
341 if not os.path.isdir(instRoot + '/boot/grub/'):
342 os.mkdir(instRoot + '/boot/grub', 0755)
343
344 cf = '/boot/grub/grub.conf'
345 self.perms = 0600
346 if os.access (instRoot + cf, os.R_OK):
347 self.perms = os.stat(instRoot + cf)[0] & 0777
348 os.rename(instRoot + cf, instRoot + cf + '.backup')
349
350 grubTarget = bl.getDevice()
351 target = "mbr"
352 if (grubTarget.startswith('rd/') or grubTarget.startswith('ida/') or
353 grubTarget.startswith('cciss/') or
354 grubTarget.startswith('sx8/') or
355 grubTarget.startswith('mapper/')):
356 if grubTarget[-1].isdigit():
357 if grubTarget[-2] == 'p' or \
358 (grubTarget[-2].isdigit() and grubTarget[-3] == 'p'):
359 type = "partition"
360 elif grubTarget[-1].isdigit() and not grubTarget.startswith('md'):
361 target = "partition"
362
363 f = open(instRoot + cf, "w+")
364
365 f.write("# grub.conf generated by pomona\n")
366 f.write("#\n")
367
368 bootDev = fsset.getEntryByMountPoint("/boot")
369 grubPath = "/grub"
370 cfPath = "/"
371 if not bootDev:
372 bootDev = fsset.getEntryByMountPoint("/")
373 grubPath = "/boot/grub"
374 cfPath = "/boot/"
375 f.write("# NOTICE: You do not have a /boot partition. "
376 "This means that\n")
377 f.write("# all kernel and initrd paths are relative "
378 "to /, eg.\n")
379 else:
380 f.write("# NOTICE: You have a /boot partition. This means "
381 "that\n")
382 f.write("# all kernel and initrd paths are relative "
383 "to /boot/, eg.\n")
384
385 bootDevs = self.getPhysicalDevices(bootDev.device.getDevice())
386 bootDev = bootDev.device.getDevice()
387
388 f.write('# root %s\n' % self.grubbyPartitionName(bootDevs[0]))
389 f.write("# kernel %svmlinuz-version ro "
390 "root=/dev/%s\n" % (cfPath, rootDev))
391 f.write("# initrd %sinitramfs-version.img\n" % (cfPath))
392 f.write("#boot=/dev/%s\n" % (grubTarget))
393
394 # keep track of which devices are used for the device.map
395 usedDevs = {}
396
397 # get the default image to boot... first kernel image here
398 default = 0
399
400 f.write('default=%s\n' % (default))
401
402 # get the default timeout
403 timeout = 5
404 f.write('timeout=%d\n' %(timeout,))
405
406 # we only want splashimage if they're not using a serial console
407 if os.access("%s/boot/grub/splash.xpm.gz" %(instRoot,), os.R_OK):
408 f.write('splashimage=%s%sgrub/splash.xpm.gz\n'
409 % (self.grubbyPartitionName(bootDevs[0]), cfPath))
410 f.write("hiddenmenu\n")
411
412 for dev in self.getPhysicalDevices(grubTarget):
413 usedDevs[dev] = 1
414
415 if self.password:
416 f.write('password --md5 %s\n' % (self.password))
417
418 for (kernelName, kernelVersion, kernelTag, kernelDesc) in kernelList:
419 kernelFile = "%s%skernel%s" % (cfPath, sname, kernelTag,)
420
421 initrd = "/boot/initramfs-%s%s.img" % (kernelVersion, kernelTag,)
422
423 f.write('title %s (%s - %s)\n' % (name, kernelDesc, kernelVersion))
424 f.write('\troot %s\n' % self.grubbyPartitionName(bootDevs[0]))
425
426 realroot = getRootDevName(initrd, fsset, rootDev, instRoot)
427 realroot = " root=%s" %(realroot,)
428
429 f.write('\tkernel %s ro%s' % (kernelFile, realroot))
430 self.args.append("quiet")
431 if self.args.get():
432 f.write(' %s' % self.args.get())
433 f.write('\n')
434
435 if os.access (instRoot + initrd, os.R_OK):
436 # initrd is built in backend.postInstall
437 f.write('\tinitrd %sinitramfs-%s%s.img\n' % (cfPath, kernelVersion, kernelTag,))
438
439 for (label, longlabel, device) in chainList:
440 if ((not longlabel) or (longlabel == "")):
441 continue
442 f.write('title %s\n' % (longlabel))
443 f.write('\trootnoverify %s\n' % self.grubbyPartitionName(device))
444 # f.write('\tmakeactive\n')
445 f.write('\tchainloader +1')
446 f.write('\n')
447 usedDevs[device] = 1
448
449 f.close()
450 os.chmod(instRoot + "/boot/grub/grub.conf", self.perms)
451
452 try:
453 # make symlink for /etc/grub.conf (config files belong in /etc)
454 if os.access (instRoot + "/etc/grub.conf", os.R_OK):
455 os.rename(instRoot + "/etc/grub.conf", instRoot + "/etc/grub.conf.backup")
456 os.symlink("../boot/grub/grub.conf", instRoot + "/etc/grub.conf")
457 except:
458 pass
459
460 for dev in self.getPhysicalDevices(rootDev) + bootDevs:
461 usedDevs[dev] = 1
462
463 if os.access(instRoot + "/boot/grub/device.map", os.R_OK):
464 os.rename(instRoot + "/boot/grub/device.map", instRoot + "/boot/grub/device.map.backup")
465
466 f = open(instRoot + "/boot/grub/device.map", "w+")
467 f.write("# this device map was generated by pomona\n")
468 devs = usedDevs.keys()
469 usedDevs = {}
470 for dev in devs:
471 drive = getDiskPart(dev)[0]
472 if usedDevs.has_key(drive):
473 continue
474 usedDevs[drive] = 1
475 devs = usedDevs.keys()
476 devs.sort()
477 for drive in devs:
478 # XXX hack city. If they're not the sort of thing that'll
479 # be in the device map, they shouldn't still be in the list.
480 if not drive.startswith('md'):
481 f.write("(%s) /dev/%s\n" % (self.grubbyDiskName(drive), drive))
482 f.close()
483
484 args = "--stage2=/boot/grub/stage2 "
485 if self.forceLBA32:
486 args = "%s--force-lba " % (args,)
487
488 sysconf = '/etc/sysconfig/grub'
489 if os.access (instRoot + sysconf, os.R_OK):
490 self.perms = os.stat(instRoot + sysconf)[0] & 0777
491 os.rename(instRoot + sysconf, instRoot + sysconf + '.backup')
492 # if it's an absolute symlink, just get it out of our way
493 elif (os.path.islink(instRoot + sysconf) and
494 os.readlink(instRoot + sysconf)[0] == '/'):
495 os.rename(instRoot + sysconf, instRoot + sysconf + '.backup')
496 f = open(instRoot + sysconf, 'w+')
497 f.write("boot=/dev/%s\n" %(grubTarget,))
498 # XXX forcelba never gets read back...
499 if self.forceLBA32:
500 f.write("forcelba=1\n")
501 else:
502 f.write("forcelba=0\n")
503 f.close()
504
505 cmds = []
506 for bootDev in bootDevs:
507 gtPart = self.getMatchingPart(bootDev, grubTarget)
508 gtDisk = self.grubbyPartitionName(getDiskPart(gtPart)[0])
509 bPart = self.grubbyPartitionName(bootDev)
510 cmd = "root %s\n" % (bPart,)
511
512 stage1Target = gtDisk
513 if target == "partition":
514 stage1Target = self.grubbyPartitionName(gtPart)
515
516 cmd += "install %s%s/stage1 d %s %s/stage2 p %s%s/grub.conf" % \
517 (args, grubPath, stage1Target, grubPath, bPart, grubPath)
518 cmds.append(cmd)
519
520 log.info("GRUB commands:")
521 for cmd in cmds:
522 log.info("\t%s\n", cmd)
523
524 if cfPath == "/":
525 syncDataToDisk(bootDev, "/boot", instRoot)
526 else:
527 syncDataToDisk(bootDev, "/", instRoot)
528
529 # copy the stage files over into /boot
530 pyfire.executil.execWithRedirect("/usr/sbin/grub-install",
531 ["/usr/sbin/grub-install", "--just-copy"],
532 stdout = "/dev/tty5", stderr = "/dev/tty5",
533 root = instRoot)
534
535 # really install the bootloader
536 for cmd in cmds:
537 p = os.pipe()
538 os.write(p[1], cmd + '\n')
539 os.close(p[1])
540 import time
541
542 # FIXME: hack to try to make sure everything is written
543 # to the disk
544 if cfPath == "/":
545 syncDataToDisk(bootDev, "/boot", instRoot)
546 else:
547 syncDataToDisk(bootDev, "/", instRoot)
548
549 pyfire.executil.execWithRedirect("/usr/sbin/grub" ,
550 [ "grub", "--batch", "--no-floppy",
551 "--device-map=/boot/grub/device.map" ],
552 stdin = p[0],
553 stdout = "/dev/tty5", stderr = "/dev/tty5",
554 root = instRoot)
555 os.close(p[0])
556
557 return ""
558
559 def getMatchingPart(self, bootDev, target):
560 bootName, bootPartNum = getDiskPart(bootDev)
561 devices = self.getPhysicalDevices(target)
562 for device in devices:
563 name, partNum = getDiskPart(device)
564 if name == bootName:
565 return device
566 return devices[0]
567
568 def grubbyDiskName(self, name):
569 return "hd%d" % self.drivelist.index(name)
570
571 def grubbyPartitionName(self, dev):
572 (name, partNum) = getDiskPart(dev)
573 if partNum != None:
574 return "(%s,%d)" % (self.grubbyDiskName(name), partNum)
575 else:
576 return "(%s)" %(self.grubbyDiskName(name))
577
578 def write(self, instRoot, fsset, bl, kernelList, chainList, defaultDev, intf):
579 out = self.writeGrub(instRoot, fsset, bl, kernelList, chainList, defaultDev)
580
581 def getArgList(self):
582 args = []
583
584 if self.forceLBA32:
585 args.append("--lba32")
586 if self.password:
587 args.append("--md5pass=%s" %(self.password))
588
589 # XXX add location of bootloader here too
590
591 return args
592
593 def __init__(self):
594 bootloaderInfo.__init__(self)
595 self.useGrubVal = 1
596 self.kernelLocation = "/boot/"
597 self.configfile = "/etc/lilo.conf"
598 self.password = None
599 self.pure = None
600
601 ###############
602 # end of boot loader objects... these are just some utility functions used
603
604 # return (disk, partition number) eg ('hda', 1)
605 def getDiskPart(dev):
606 cut = len(dev)
607 if (dev.startswith('rd/') or dev.startswith('ida/') or
608 dev.startswith('cciss/') or dev.startswith('sx8/') or
609 dev.startswith('mapper/')):
610 if dev[-2] == 'p':
611 cut = -1
612 elif dev[-3] == 'p':
613 cut = -2
614 else:
615 if dev[-2] in string.digits:
616 cut = -2
617 elif dev[-1] in string.digits:
618 cut = -1
619
620 name = dev[:cut]
621
622 # hack off the trailing 'p' from /dev/cciss/*, for example
623 if name[-1] == 'p':
624 for letter in name:
625 if letter not in string.letters and letter != "/":
626 name = name[:-1]
627 break
628
629 if cut < 0:
630 partNum = int(dev[cut:]) - 1
631 else:
632 partNum = None
633
634 return (name, partNum)
635
636 # hackery to determine if we should do root=LABEL=/ or whatnot
637 # as usual, knows too much about pomona
638 def getRootDevName(initrd, fsset, rootDev, instRoot):
639 if not os.access(instRoot + initrd, os.R_OK):
640 return "/dev/%s" % (rootDev,)
641 try:
642 rootEntry = fsset.getEntryByMountPoint("/")
643 if rootEntry.getUuid() is not None:
644 return "UUID=%s" %(rootEntry.getUuid(),)
645 elif rootEntry.getLabel() is not None and rootEntry.device.doLabel is not None:
646 return "LABEL=%s" %(rootEntry.getLabel(),)
647 return "/dev/%s" %(rootDev,)
648 except:
649 return "/dev/%s" %(rootDev,)
650
651 # returns a product name to use for the boot loader string
652 def getProductName():
653 # XXX Check /etc/ipfire-release here...
654 return "IPFire Linux"
655
656 def bootloaderSetupChoices(pomona):
657 if pomona.dir == DISPATCH_BACK:
658 return
659 pomona.id.bootloader.updateDriveList()
660
661 choices = pomona.id.fsset.bootloaderChoices(pomona.id.diskset, pomona.id.bootloader)
662
663 pomona.id.bootloader.images.setup(pomona.id.diskset, pomona.id.fsset)
664
665 if pomona.id.bootloader.defaultDevice != None and choices:
666 keys = choices.keys()
667 # there are only two possible things that can be in the keys
668 # mbr and boot. boot is ALWAYS present. so if the dev isn't
669 # listed, it was mbr and we should nicely fall back to boot
670 if pomona.id.bootloader.defaultDevice not in keys:
671 log.warning("MBR not suitable as boot device; installing to partition")
672 pomona.id.bootloader.defaultDevice = "boot"
673 pomona.id.bootloader.setDevice(choices[pomona.id.bootloader.defaultDevice][0])
674 elif choices and choices.has_key("mbr"):
675 pomona.id.bootloader.setDevice(choices["mbr"][0])
676 elif choices and choices.has_key("boot"):
677 pomona.id.bootloader.setDevice(choices["boot"][0])
678
679 bootDev = pomona.id.fsset.getEntryByMountPoint("/")
680 if not bootDev:
681 bootDev = pomona.id.fsset.getEntryByMountPoint("/boot")
682 part = partedUtils.get_partition_by_name(pomona.id.diskset.disks,
683 bootDev.device.getDevice())
684 if part and partedUtils.end_sector_to_cyl(part.geom.dev, part.geom.end) >= 1024:
685 pomona.id.bootloader.above1024 = 1
686
687 def writeBootloader(pomona):
688 def dosync():
689 isys.sync()
690 isys.sync()
691 isys.sync()
692
693 if pomona.id.bootloader.defaultDevice == -1:
694 log.error("No default boot device set")
695 return
696
697 w = pomona.intf.waitWindow(_("Bootloader"), _("Installing bootloader..."))
698
699 kernelList = []
700 otherList = []
701 root = pomona.id.fsset.getEntryByMountPoint('/')
702 if root:
703 rootDev = root.device.getDevice()
704 else:
705 rootDev = None
706 defaultDev = pomona.id.bootloader.images.getDefault()
707
708 kernelLabel = None
709 kernelLongLabel = None
710
711 for (dev, (label, longlabel, type)) in pomona.id.bootloader.images.getImages().items():
712 if (dev == rootDev) or (rootDev is None and kernelLabel is None):
713 kernelLabel = label
714 kernelLongLabel = longlabel
715 elif dev == defaultDev:
716 otherList = [(label, longlabel, dev)] + otherList
717 else:
718 otherList.append((label, longlabel, dev))
719
720 if kernelLabel is None:
721 log.error("unable to find default image, bailing")
722
723 defkern = None
724 for (kernelName, kernelVersion, kernelTag, kernelDesc) in pomona.backend.kernelVersionList(pomona):
725 if not defkern:
726 defkern = "%s%s" % (kernelName, kernelTag)
727
728 if kernelTag == "-smp" and isys.smpAvailable():
729 defkern = "%s%s" % (kernelName, kernelTag)
730
731 kernelList.append((kernelName, kernelVersion, kernelTag, kernelDesc))
732
733 f = open(pomona.rootPath + "/etc/sysconfig/kernel", "w+")
734 f.write("# DEFAULTKERNEL specifies the default kernel package type\n")
735 f.write("DEFAULTKERNEL=%s\n" %(defkern,))
736 f.close()
737
738 dosync()
739 try:
740 pomona.id.bootloader.write(pomona.rootPath, pomona.id.fsset, pomona.id.bootloader,
741 kernelList, otherList, defaultDev, pomona.intf)
742 w.pop()
743 except BootyNoKernelWarning:
744 w.pop()
745 if pomona.intf:
746 pomona.intf.messageWindow(_("Warning"),
747 _("No kernel packages were installed on your "
748 "system. Your boot loader configuration "
749 "will not be changed."))
750 dosync()
751
752 # return instance of the appropriate bootloader for our arch
753 def getBootloader():
754 return x86BootloaderInfo()