[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
[PATCH] add support for bootman to booty
- From: Elliot Peele <elliot rpath com>
- To: Discussion of Development and Customization of the Red Hat Linux Installer <anaconda-devel-list redhat com>
- Subject: [PATCH] add support for bootman to booty
- Date: Tue, 20 Nov 2007 17:18:37 -0500
These patches add support for bootman to booty as well as expose
extlinux as a choice in anaconda. For the time being I am trying to
maintain support for installs where bootman is not available.
The idea behind bootman is to use a single common bootloader config file
that could be used to generate a config file for any supported
bootloader. Currently grub and extlinux are the only supported
bootloaders. A snapshot of bootman can be found here:
ftp://download.rpath.com/autosource/bootman-0.20071120.tar.gz
Elliot
diff --exclude .hg -ruN anaconda/bootloader.py anaconda-syslinux/bootloader.py
--- anaconda/bootloader.py 2007-11-20 17:01:47.000000000 -0500
+++ anaconda-syslinux/bootloader.py 2007-11-20 17:02:41.000000000 -0500
@@ -209,6 +209,7 @@
bl = booty.getBootloader()
+ # Support legacy grub.template
template = None
defaults = None
for dir in ('/tmp/product', '/tmp/updates', '/mnt/runtime/etc/sysconfig/',
@@ -221,13 +222,30 @@
if not defaults and os.access(d, os.R_OK):
defaults = d
- if not template:
- raise IOError, "no such file %s" % template
+ blconf = False
+ for dir in ('/mnt/runtime/etc',
+ '/mnt/sysimage/etc',
+ '/tmp/product',
+ '/tmp/updates'):
+ file = '%s/bootloader.conf' % dir
+ if os.access(file, os.R_OK):
+ bl.loadConfig(file)
+ blconf = True
+
+ if blconf:
+ # At this point bootman is most likely avaiable and syslinux is a good
+ # guess.
+ bl.setBootLoader(BL_EXTLINUX)
+ else:
+ # If no bootloader.conf was found try to use the old grub.template
+ bl.setBootLoader(BL_GRUB_OLD)
+ if not template:
+ raise IOError, "no such file %s" % template
- bl.cfg = bootloaderConfig.GrubConfig(template)
+ bl.cfg = bootloaderConfig.GrubConfig(template)
- if defaults:
- bl.cfg.read(defaults)
+ if defaults:
+ bl.cfg.read(defaults)
return bl
diff --exclude .hg -ruN anaconda/conaryinstall.py anaconda-syslinux/conaryinstall.py
--- anaconda/conaryinstall.py 2007-11-20 17:01:47.000000000 -0500
+++ anaconda-syslinux/conaryinstall.py 2007-11-20 17:02:41.000000000 -0500
@@ -83,6 +83,46 @@
self.comps.selectTroveByName('kernel:runtime')
+ # Sanity check the bootloader selection
+ #
+ # if bootman:
+ # if have extlinux and bl.isExtlinux or not has grub
+ # select extlinux
+ # bl.setBootloader(extlinux)
+ # elif have grub and bl.isGrub
+ # select grub
+ # bl.setBootloder(grub.new)
+ # else:
+ # must have grub
+ # select grub
+ # bl.setBootloader(grub.old
+ bootman = self.comps.getTroveByName('bootman')
+ if len(trvs) >= 1:
+ if not bootman[0].isSelected():
+ bootman[0].select()
+ # bootman is in the group
+ extlinux = self.comps.getTroveByName('extlinux')
+ grub = self.comps.getTroveByName('grub')
+ curBL = anaconda.id.bootloader.getBootLoader()
+
+ if len(extlinux) >= 1 and (curBL == BL_EXTLINUX or
+ not len(grub) >= 1):
+ # need to use extlinux
+ if not extlinux[0].isSelected():
+ extlinux[0].select()
+ anaconda.id.bootloader.setBootLoader(BL_EXTLINUX)
+ elif len(grub) >= 1:
+ # don't have extlinux, use grub
+ if not grub[0].isSelected():
+ grub[0].select()
+ anaconda.id.bootloader.setBootLoader(BL_GRUB)
+ else:
+ # don't have bootman, fall back to old grub install method
+ assert len(grub) >= 1
+ if not grub[0].isSelected():
+ grub[0].select()
+ anaconda.id.bootloader.setBootLoader(BL_GRUB_OLD)
+
def doInstall(self, anaconda):
if flags.test:
return
diff --exclude .hg -ruN anaconda/constants.py anaconda-syslinux/constants.py
--- anaconda/constants.py 2007-11-20 17:01:47.000000000 -0500
+++ anaconda-syslinux/constants.py 2007-11-20 17:02:41.000000000 -0500
@@ -55,6 +55,8 @@
# or decrease over time
NUMBER_OF_CDS = 5
+# Pull in the bootloader id contants from booty
+from bootman.constants import *
# common string needs to be easy to change
import product
diff --exclude .hg -ruN anaconda/fsset.py anaconda-syslinux/fsset.py
--- anaconda/fsset.py 2007-11-20 17:01:47.000000000 -0500
+++ anaconda-syslinux/fsset.py 2007-11-20 17:02:42.000000000 -0500
@@ -1403,9 +1403,7 @@
# similarly, on pseries, we really only want the PReP partition active
if rhpl.getArch() == "ia64" \
or iutil.getPPCMachine() in ("pSeries", "iSeries", "PMac") \
- or (rhpl.getArch() in ("i386", "x86_64") \
- and (iutil.isEfi() \
- or partedUtils.hasGptLabel(diskset, drive))):
+ or rhpl.getArch() in ("i386", "x86_64"):
if part and part.is_flag_available(parted.PARTITION_BOOT):
part.set_flag(parted.PARTITION_BOOT, 1)
return
diff --exclude .hg -ruN anaconda/iw/bootloader_main_gui.py anaconda-syslinux/iw/bootloader_main_gui.py
--- anaconda/iw/bootloader_main_gui.py 2007-11-20 17:01:47.000000000 -0500
+++ anaconda-syslinux/iw/bootloader_main_gui.py 2007-11-20 17:02:42.000000000 -0500
@@ -20,6 +20,7 @@
import gui
import bootloader
from iw_gui import *
+from constants import *
from rhpl.translate import _, N_
from osbootwidget import OSBootWidget
@@ -56,6 +57,10 @@
self.dispatch.skipStep("instbootloader", skip = 0)
if self.blname == "GRUB":
self.bl.setUseGrub(1)
+ self.bl.setBootLoader(BL_GRUB)
+ elif self.blname == 'EXTLINUX':
+ self.bl.setUseGrub(1)
+ self.bl.setBootLoader(BL_EXTLINUX)
else:
self.bl.setUseGrub(0)
@@ -71,13 +76,22 @@
self.dispatch.skipStep("bootloaderadvanced", skip = 1)
def bootloaderChanged(self, *args):
- active = self.grub_radio.get_active()
+ active = self.grub_radio.get_active() or \
+ self.extlinux_radio.get_active()
for widget in [ self.oslist.getWidget(), self.blpass.getWidget(),
self.advanced ]:
widget.set_sensitive(active)
-
-
+
+ if self.grub_radio.get_active():
+ self.blname = 'GRUB'
+ elif self.extlinux_radio.get_active():
+ self.blname = 'EXTLINUX'
+ else:
+ self.blname = None
+
+ self.oslist.changeBootLoader(self.blname)
+
def getScreen(self, anaconda):
self.dispatch = anaconda.dispatch
self.bl = anaconda.id.bootloader
@@ -96,10 +110,8 @@
spacer.set_size_request(10, 1)
thebox.pack_start(spacer, False)
- if self.bl.useGrub():
- self.blname = "GRUB"
- else:
- self.blname = None
+ # Set extlinux as the default bootloader
+ self.blname = "EXTLINUX"
# make sure we get a valid device to say we're installing to
if self.bl.getDevice() is not None:
@@ -114,22 +126,35 @@
self.bldev = choices['boot'][0]
vb = gtk.VBox(False, 6)
- self.grub_radio = gtk.RadioButton(None, _("The %s boot loader will be "
- "installed on /dev/%s.") %
- ("GRUB", self.bldev))
- self.grub_radio.set_use_underline(False)
- vb.pack_start(self.grub_radio)
+
+ bltext = _("The %s boot loader will be installed on /dev/%s.")
+
+ self.extlinux_radio = gtk.RadioButton(None, bltext % ('EXTLINUX', self.bldev), False)
+ self.grub_radio = gtk.RadioButton(self.extlinux_radio, bltext % ('GRUB', self.bldev), False)
self.none_radio = gtk.RadioButton(self.grub_radio,
_("No boot loader will be installed."))
+
+ vb.pack_start(self.extlinux_radio)
+ vb.pack_start(self.grub_radio)
vb.pack_start(self.none_radio)
+
if self.blname is None:
+ self.extlinux_radio.set_active(False)
+ self.grub_radio.set_active(False)
self.none_radio.set_active(True)
+ elif self.blname == 'EXTLINUX':
+ self.extlinux_radio.set_active(True)
self.grub_radio.set_active(False)
+ self.none_radio.set_active(False)
else:
+ self.extlinux_radio.set_active(False)
self.grub_radio.set_active(True)
- self.none_radio.set_active(False)
+ self.none_radio.set_active(False)
+
+ self.extlinux_radio.connect('toggled', self.bootloaderChanged)
self.grub_radio.connect("toggled", self.bootloaderChanged)
self.none_radio.connect("toggled", self.bootloaderChanged)
+
thebox.pack_start(vb, False)
spacer = gtk.Label("")
diff --exclude .hg -ruN anaconda/iw/osbootwidget.py anaconda-syslinux/iw/osbootwidget.py
--- anaconda/iw/osbootwidget.py 2007-11-20 17:01:47.000000000 -0500
+++ anaconda-syslinux/iw/osbootwidget.py 2007-11-20 17:02:42.000000000 -0500
@@ -35,7 +35,7 @@
if blname is not None:
self.blname = blname
else:
- self.blname = "GRUB"
+ self.blname = "EXTLINUX"
self.setIllegalChars()
@@ -112,7 +112,7 @@
def setIllegalChars(self):
# illegal characters for boot loader labels
- if self.blname == "GRUB":
+ if self.blname == "GRUB" or self.blname == 'EXTLINUX':
self.illegalChars = [ "$", "=" ]
else:
self.illegalChars = [ "$", "=", " " ]
@@ -121,7 +121,7 @@
if blname is not None:
self.blname = blname
else:
- self.blname = "GRUB"
+ self.blname = "EXTLINUX"
self.setIllegalChars()
self.fillOSList()
@@ -236,7 +236,7 @@
for key in self.imagelist.keys():
if dev == key:
continue
- if self.blname == "GRUB":
+ if self.blname == "GRUB" or self.blname == 'EXTLINUX':
thisLabel = self.imagelist[key][1]
else:
thisLabel = self.imagelist[key][0]
@@ -280,7 +280,7 @@
del self.imagelist[oldDevice]
# go ahead and add it
- if self.blname == "GRUB":
+ if self.blname == "GRUB" or self.blname == 'EXTLINUX':
self.imagelist[dev] = (oldshort, label, isRoot)
else:
self.imagelist[dev] = (label, oldlong, isRoot)
@@ -356,7 +356,7 @@
for dev in keys:
(label, longlabel, fstype) = self.imagelist[dev]
- if self.blname == "GRUB":
+ if self.blname == "GRUB" or self.blname == 'EXTLINUX':
theLabel = longlabel
else:
theLabel = label
diff --exclude .hg -ruN anaconda/partitions.py anaconda-syslinux/partitions.py
--- anaconda/partitions.py 2007-11-20 17:01:47.000000000 -0500
+++ anaconda-syslinux/partitions.py 2007-11-20 17:02:42.000000000 -0500
@@ -868,6 +868,16 @@
"the first four partitions and thus "
"won't be bootable."))
+ # Require /boot to be ext2 or ext3 since extlinux might
+ # be the bootloader.
+ fskeys = ('ext2', 'ext3')
+ supBoot = [ fsset.fileSystemTypeGet(x) for x in fskeys ]
+ if br.fstype not in supBoot:
+ errors.append(_('You must select either a %s or %s '
+ 'filesystem for the boot partition.'
+ % fskeys))
+
+
if rhpl.getArch() == "ia64":
bootreq = self.getRequestByMountPoint("/boot/efi")
if not bootreq or bootreq.getActualSize(self, diskset) < 50:
diff --exclude .hg -ruN anaconda/tarinstall.py anaconda-syslinux/tarinstall.py
--- anaconda/tarinstall.py 2007-11-20 17:01:49.000000000 -0500
+++ anaconda-syslinux/tarinstall.py 2007-11-20 17:02:44.000000000 -0500
@@ -85,13 +85,27 @@
def doPostInstall(self, anaconda):
rPathBackendBase.doPostInstall(self, anaconda)
- if os.path.exists(self.instPath + '/boot/grub/device.map'):
- os.unlink(self.instPath + '/boot/grub/device.map')
-
# start in run level 5 if xdm is installed
if os.path.exists(self.instPath + '/usr/bin/xdm'):
anaconda.id.desktop.setDefaultRunLevel(5)
+ if os.path.exists(self.instPath + '/boot/grub/device.map'):
+ os.unlink(self.instPath + '/boot/grub/device.map')
+
+ # Sanity check the bootloader selection
+ hasGrub = os.access(self.instPath + '/sbin/grub', os.X_OK)
+ if os.access(self.instPath + '/sbin/bootman', os.X_OK):
+ hasExtLinux = os.access(self.instPath + '/sbin/extlinux', os.X_OK)
+ curBL = anaconda.id.bootloader.getBootLoader()
+
+ if hasExtLinux and (curBL == BL_EXTLINUX or not hasGrub):
+ anaconda.id.bootloader.setBootLoader(BL_EXTLINUX)
+ elif hasGrub:
+ anaconda.id.bootloader.setBootLoader(BL_GRUB)
+ else:
+ assert hasGrub
+ anaconda.id.bootloader.setBootLoader(BL_GRUB_OLD)
+
def getRequiredMedia(self):
return self.comps.getRequiredMedia()
diff --exclude .hg -ruN anaconda/textw/bootloader_text.py anaconda-syslinux/textw/bootloader_text.py
--- anaconda/textw/bootloader_text.py 2007-11-20 17:01:49.000000000 -0500
+++ anaconda-syslinux/textw/bootloader_text.py 2007-11-20 17:02:44.000000000 -0500
@@ -29,22 +29,26 @@
if anaconda.dispatch.stepInSkipList("instbootloader"):
useGrub = 0
+ useExtlinux = 0
noBl = 1
else:
- useGrub = 1
+ useGrub = 0
+ useExtlinux = 1
noBl = 0
blradio = RadioGroup()
+ extlinux = blradio.add(_('Use EXTLINUX Boot Loader'), 'extlinux', useExtlinux)
grub = blradio.add(_("Use GRUB Boot Loader"), "grub", useGrub)
skipbl = blradio.add(_("No Boot Loader"), "nobl", noBl)
buttons = ButtonBar(screen, [TEXT_OK_BUTTON, TEXT_BACK_BUTTON ] )
grid = GridFormHelp(screen, _("Boot Loader Configuration"),
- "btloadinstall", 1, 5)
+ "btloadinstall", 1, 6)
grid.add(t, 0, 0, (0,0,0,1))
- grid.add(grub, 0, 1, (0,0,0,0))
- grid.add(skipbl, 0, 3, (0,0,0,1))
- grid.add(buttons, 0, 4, growx = 1)
+ grid.add(extlinux, 0, 1, (0,0,0,0))
+ grid.add(grub, 0, 3, (0,0,0,1))
+ grid.add(skipbl, 0, 4, (0,0,0,2))
+ grid.add(buttons, 0, 5, growx = 1)
while 1:
result = grid.run()
@@ -79,6 +83,11 @@
anaconda.dispatch.skipStep("instbootloader", 0)
anaconda.dispatch.skipStep("bootloaderadvanced", 0)
+ if blradio.getSelection() == 'grub':
+ anaconda.id.bootloader.setBootLoader(BL_GRUB)
+ else:
+ anaconda.id.bootloader.setBootLoader(BL_EXTLINUX)
+
screen.popWindow()
return INSTALL_OK
@@ -140,6 +149,9 @@
def __call__(self, screen, anaconda):
if anaconda.dispatch.stepInSkipList("instbootloader"): return INSTALL_NOOP
+ if anaconda.id.bootloader.getBootLoader() == BL_EXTLINUX:
+ return INSTALL_NOOP
+
choices = anaconda.id.fsset.bootloaderChoices(anaconda.id.diskset, anaconda.id.bootloader)
if len(choices.keys()) == 1:
anaconda.id.bootloader.setDevice(choices[choices.keys()[0]][0])
@@ -393,7 +405,7 @@
g.add(text, 0, 0, (0,0,0,1), anchorLeft = 1)
- self.checkbox = Checkbox(_("Use a GRUB Password"))
+ self.checkbox = Checkbox(_("Use a Boot Loader Password"))
g.add(self.checkbox, 0, 1, (0,0,0,1))
if self.bl.password:
diff --exclude .hg -ruN booty/bootloaderInfo.py booty-syslinux/bootloaderInfo.py
--- booty/bootloaderInfo.py 2007-11-20 17:03:25.000000000 -0500
+++ booty-syslinux/bootloaderInfo.py 2007-11-20 17:03:31.000000000 -0500
@@ -1188,31 +1188,38 @@
if len(kernelList) < 1:
self.noKernelsWarn(intf)
- out = self.writeGrub(instRoot, fsset, bl, langs, kernelList,
- chainList, defaultDev,
- justConfig | (not self.useGrubVal))
+ self.bootman.write(instRoot, fsset, bl, langs, 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 setBootLoader(self, bootLoaderId):
+ self.bootman.setBootLoader(bootLoaderId)
+
+ def getBootLoader(self):
+ return self.bootman.getBootLoader()
+
+ def loadConfig(self, file):
+ self.bootman.loadConfig(file)
def getArgList(self):
args = bootloaderInfo.getArgList(self)
-
+
if self.forceLBA32:
args.append("--lba32")
if self.password:
args.append("--md5pass=%s" %(self.password))
-
-
- # XXX add location of bootloader here too
+ # XXX add location of bootloader here too
return args
def __init__(self):
+ from bootman import BootMan
bootloaderInfo.__init__(self)
# XXX use checkbootloader to determine what to default to
self.useGrubVal = 1
@@ -1221,6 +1228,7 @@
self.password = None
self.pure = None
self.cfg = bootloaderConfig.GrubConfig()
+ self.bootman = BootMan(self)
class s390BootloaderInfo(bootloaderInfo):
def getBootloaderConfig(self, instRoot, fsset, bl, langs, kernelList,
diff --exclude .hg -ruN booty/bootman/bman.py booty-syslinux/bootman/bman.py
--- booty/bootman/bman.py 1969-12-31 19:00:00.000000000 -0500
+++ booty-syslinux/bootman/bman.py 2007-11-20 17:03:31.000000000 -0500
@@ -0,0 +1,297 @@
+#
+# Copyright (c) 2007 rPath, Inc.
+#
+
+import os
+import string
+
+import rhpl
+
+import bootloaderInfo
+
+from bootman.constants import *
+from bootman.devicemap import DeviceMap
+from bootman.config import BootManConfig, BootLoaderConfig
+
+class BootMan(object):
+ def __init__(self, bootloader):
+ self.bootloader = bootloader
+
+ self._dmcfg = DeviceMap(self.bootloader)
+ self._bmcfg = BootManConfig()
+ self._cfg = BootLoaderConfig()
+
+ self._dmcfgfile = os.path.join('etc', 'grub', 'device.map')
+ self._bmcfgfile = os.path.join('etc', 'bootman.conf')
+ self._cfgfile = os.path.join('etc', 'bootloader.conf')
+
+ # Default to grub as used in rPath Linux 1.
+ self._blid = BL_GRUB_OLD
+
+ self._blmap = {BL_EXTLINUX: self.writeExtlinux,
+ BL_GRUB: self.writeGrub,
+ BL_GRUB_OLD: self.bootloader.writeGrub}
+
+ self._blnames = {BL_EXTLINUX: 'syslinux',
+ BL_GRUB: 'grub',
+ BL_GRUB_OLD: 'grub'}
+
+ def loadConfig(self, file):
+ self._cfg.read(file)
+
+ def setBootLoader(self, bootLoaderId):
+ assert bootLoaderId in BL_VALID
+ self._blid = bootLoaderId
+
+ def getBootLoader(self):
+ return self._blid
+
+ def write(self, *args, **kwargs):
+ self._blmap[self._blid](*args, **kwargs)
+
+ def writeExtlinux(self, instRoot, fsset, bl, langs, kernelList, chainList,
+ defaultDev, justConfigFile):
+ """
+ Syslinux install.
+ """
+
+ bootDev, baseBootDir = self._writeConfig(instRoot, fsset, bl, langs,
+ kernelList, chainList,
+ defaultDev, justConfigFile)
+
+ if justConfigFile:
+ return
+
+ for device in self.bootloader.getPhysicalDevices(bootDev):
+ if device[-1].isdigit():
+ device = device[:-1]
+
+ rhpl.executil.execWithRedirect('/bin/dd',
+ ['/bin/dd',
+ 'if=/boot/extlinux/mbr.bin',
+ 'of=/dev/%s' % device],
+ stdout='/dev/tty5',
+ stderr='/dev/tty5',
+ root=instRoot)
+
+ cmd = ['/sbin/extlinux', '--install']
+ if len(self.bootloader.getPhysicalDevices(bootDev)) > 1:
+ cmd.append('-r')
+ cmd.append('/boot/extlinux')
+
+ rhpl.executil.execWithRedirect('/sbin/extlinux',
+ cmd,
+ stdout='/dev/tty5',
+ stderr='/dev/tty5',
+ root=instRoot)
+
+ def writeGrub(self, instRoot, fsset, bl, langs, kernelList, chainList,
+ defaultDev, justConfigFile):
+ """
+ Grub install stub, bootman doesn't support grub.conf at this time.
+ """
+
+ bootDev, baseBootDir = self._writeConfig(instRoot, fsset, bl, langs,
+ kernelList, chainList,
+ defaultDev, justConfigFile)
+
+ if justConfigFile:
+ return
+
+ # Find where to install grub
+ grubTarget = self.bootloader.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'):
+ type = 'partition'
+ elif grubTarget[-1].isdigit() and not grubTarget.startswith('md'):
+ target = 'partition'
+
+ grubPath = os.path.join(baseBootDir, 'grub')
+
+ # assemble grub commands to run
+ args = '--stage2=/boot/grub/stage2 '
+ args += self.bootloader.forceLBA32 and '--force-lba ' or ''
+
+ cmds = []
+ for device in self.bootloader.getPhysicalDevices(bootDev):
+ gtPart = self.bootloader.getMatchingPart(device, grubTarget)
+ diskPart = bootloaderInfo.getDiskPart(gtPart)
+ gtDisk = self.bootloader.grubbyPartitionName(diskPart[0])
+ bPart = self.bootloader.grubbyPartitionName(device)
+
+ stage1Target = gtDisk
+ if target == 'partition':
+ stage1Target = self.bootloader.grubbyPartitionName(gtPart)
+
+ cmd = ('root %s\ninstall %s %s/stage1 d %s %s/stage2 p '
+ '%s%s/grub.conf') % (bPart, args, grubPath, stage1Target,
+ grubPath, bPart, grubPath)
+
+ cmds.append(cmd)
+
+ # install grub
+ for cmd in cmds:
+ p = os.pipe()
+ os.write(p[1], cmd + '\n')
+ os.close(p[1])
+
+ rhpl.executil.execWithRedirect('/sbin/grub',
+ [ 'grub', '--batch', '--no-floppy',
+ '--device-map=%s' % self._dmcfgfile ],
+ stdin = p[0],
+ stdout = '/dev/tty5',
+ stderr = '/dev/tty5',
+ root = instRoot)
+
+ os.close(p[0])
+
+ def _writeConfig(self, instRoot, fsset, bl, langs, kernelList, chainList,
+ defaultDev, justConfigFile):
+ """
+ Populate bootManConfig object from anaconda supplied data, write
+ bootloader.conf to disk, run bootman to generate extlinux.conf and grub.conf.
+ """
+
+ # Set bootloader
+ self._bmcfg.setBootLoader(self._blnames[self._blid])
+
+ # Find the root device
+ rootDev = fsset.getEntryByMountPoint("/").device.getDevice()
+
+ # Find the correct path for kernel/initramfs
+ baseBootDir = '/'
+ bootMount = '/boot'
+ bootDev = fsset.getEntryByMountPoint('/boot').device.getDevice()
+ if not bootDev:
+ baseBootDir = '/boot/'
+ bootMount = '/'
+ bootDev = fsset.getEntryByMountPoint('/').device.getDevice()
+
+ # Setup bootloader serial settings
+ if self.bootloader.serial == 1:
+ # grab the 0-based number of the serial console device
+ unit = self.bootloader.serialDevice[-1]
+
+ # and we want to set the speed too
+ speedend = 0
+ for char in self.bootloader.serialOptions:
+ if char not in string.digits:
+ break
+ speedend = speedend + 1
+ if speedend != 0:
+ speed = self.bootloader.serialOptions[:speedend]
+ else:
+ # reasonable default
+ speed = '9600'
+
+ settings = '%sn81' % speed
+
+ self._cfg.serial(unit, settings)
+
+ # don't set background image if using serial
+ self._cfg.background('')
+
+ # Set default timeout (5 seconds)
+ self._cfg.timeout(50)
+
+ # set readonly
+ self._cfg.readonly()
+
+ # Setup boot targets
+ defaultSet = False
+ for label, longlabel, version in kernelList:
+ title = '"%s (%s)"' % (longlabel, version)
+ kernelTag = "-" + version
+ kernelFile = '/boot/vmlinuz%s' % kernelTag
+
+ initrdFile = '/boot/initrd%s.img' % kernelTag
+
+ root = bootloaderInfo.getRootDevName(initrdFile, fsset, rootDev,
+ instRoot)
+ self._cfg.root(root)
+
+ if defaultDev in root:
+ defaultSet = True
+ self._cfg.default(version)
+
+ if self.bootloader.args.get():
+ self._cfg.options(self.bootloader.args.get())
+
+ 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.bootloader.serial and \
+ self.bootloader.serialDevice in sermap and \
+ self.bootloader.serialOptions:
+ self._cfg.xenoptions('%s=%s' %
+ (sermap[self.bootloader.serialDevice],
+ self.bootloader.serialOptions))
+
+ if version.endswith('xen0'):
+ hvVersion = version.replace('xen0', '')
+ else:
+ hvVersion = version.replace('xen', '')
+ hvfile = '/boot/xen.gz-%s' % hvVersion
+
+ self._cfg.xen(version, title, hvfile, kernelFile, initrdFile)
+ else: # normal kernel
+ self._cfg.linux(version, title, kernelFile, initrdFile)
+
+ for id, (label, longlabel, device) in enumerate(chainList):
+ if not longlabel:
+ continue
+
+ # If the default boot device has not been set use the first item
+ # in the chainList.
+ if not defaultSet:
+ defaultSet = True
+ self._cfg.default('other%s' % id)
+
+ self._cfg.other('other%s' % id, '"%s"' % longlabel, '/dev/%s' % device)
+ self._dmcfg.use(device)
+
+ # register devices with the device map
+ for devices in (self.bootloader.getDevice(), rootDev, bootDev):
+ for device in self.bootloader.getPhysicalDevices(devices):
+ self._dmcfg.use(device)
+
+ # check for user supplied password
+ if self.bootloader.password:
+ self._cfg.password(self.password)
+
+ # Write out bootman.conf
+ self._bmcfg.write(os.path.join(instRoot, self._bmcfgfile))
+
+ # Write out device.map
+ self._dmcfg.write(os.path.join(instRoot, self._dmcfgfile))
+
+ # Write out bootloader.conf
+ self._cfg.write(os.path.join(instRoot, self._cfgfile))
+
+ # copy the grub stage files over into /boot
+ if os.access(instRoot + '/sbin/grub-install', os.X_OK):
+ rhpl.executil.execWithRedirect('/sbin/grub-install',
+ ['/sbin/grub-install',
+ '--just-copy'],
+ stdout = '/dev/tty5',
+ stderr = '/dev/tty5',
+ root = instRoot)
+
+ # run bootman to generate extlinux.conf and grub.conf
+ rhpl.executil.execWithRedirect('/sbin/bootman',
+ ['/sbin/bootman'],
+ stdout = '/dev/tty5',
+ stderr = '/dev/tty5',
+ root = instRoot)
+
+ # Sync data to disk before installing bootloader
+ bootloaderInfo.syncDataToDisk(bootDev, bootMount, instRoot)
+
+ return bootDev, baseBootDir
diff --exclude .hg -ruN booty/bootman/config.py booty-syslinux/bootman/config.py
--- booty/bootman/config.py 1969-12-31 19:00:00.000000000 -0500
+++ booty-syslinux/bootman/config.py 2007-11-20 17:03:31.000000000 -0500
@@ -0,0 +1,335 @@
+#
+# Copyright (c) 2007 rPath, Inc.
+#
+
+import os
+
+class _QuotedLineTokenizer(object):
+ def __init__(self):
+ self._cur = None
+ self._list = None
+ self._singleQuotedString = False
+ self._doubleQuotedString = False
+ self._states = {' ': self._space,
+ '\'': self._singleQuote,
+ '"': self._doubleQuote,
+ 'other': self._add,
+ }
+
+ def tokenize(self, line):
+ self._list = ['']
+ for char in line:
+ self._cur = char
+ if char in self._states:
+ self._states[char]()
+ else:
+ self._states['other']()
+
+ if self._list[-1] == '':
+ self._list = self._list[:-1]
+
+ return self._list
+
+ def _space(self):
+ if not self._singleQuotedString and not self._doubleQuotedString:
+ self._list.append('')
+
+ def _singleQuote(self):
+ self._add()
+ self._singleQuotedString = not self._singleQuotedString
+
+ def _doubleQuote(self):
+ self._add()
+ self._doubleQuotedString = not self._doubleQuotedString
+
+ def _add(self):
+ self._list[-1] += self._cur
+
+
+class _BootManConfigElement(object):
+ key = None
+
+ def __init__(self):
+ self._data = {'key': self.key}
+
+ def __getitem__(self, key):
+ return self._data[key]
+
+ def __setitem__(self, key, value):
+ self._data[key] = value
+
+ def __contains__(self, key):
+ return key in self._data
+
+ def __hash__(self):
+ return hash(self.key)
+
+
+class _BootManLinuxConfig(_BootManConfigElement):
+ key = 'linux'
+
+ def __init__(self, version, title, kernelPath, initrdPath):
+ _BootManConfigElement.__init__(self)
+ self['version'] = version
+ self['title'] = title
+ self['kernelPath'] = kernelPath
+ self['initrdPath'] = initrdPath
+
+ def __str__(self):
+ return ('%(key)s %(version)s %(title)s %(kernelPath)s %(initrdPath)s'
+ % self._data)
+
+
+class _BootManXenConfig(_BootManLinuxConfig):
+ key = 'xen'
+
+ def __init__(self, version, title, xenImagePath, kernelPath, initrdPath):
+ _BootManLinuxConfig.__init__(self, version, title, kernelPath,
+ initrdPath)
+ self['xenImagePath'] = xenImagePath
+
+ def __str__(self):
+ return ('%(key)s %(version)s %(title)s %(xenImagePath)s %(kernelPath)s '
+ '%(initrdPath)s' % self._data)
+
+
+class _BootManOtherConfig(_BootManConfigElement):
+ key = 'other'
+
+ def __init__(self, version, title, device):
+ _BootManConfigElement.__init__(self)
+ self['version'] = version
+ self['title'] = title
+ self['device'] = device
+
+ def __str__(self):
+ return '%(key)s %(version)s %(title)s %(device)s' % self._data
+
+
+class _BootManIncludeConfig(_BootManConfigElement):
+ key = 'include'
+
+ def set(self, path):
+ if 'paths' not in self:
+ self['paths'] = set()
+
+ self['paths'].add(path)
+
+ def __str__(self):
+ s = ''
+ for path in self['paths']:
+ s += '%s %s\n' % (self.key, path)
+ return s
+
+
+class _BootManOptionsConfig(_BootManConfigElement):
+ key = 'options'
+
+ def set(self, options):
+ for option in options.split():
+ if '=' in option:
+ key, value = option.split('=')
+ else:
+ key = option
+ value = None
+
+ self[key] = value
+
+ def __str__(self):
+ options = [self.key]
+ for key, value in self._data.iteritems():
+ if key == 'key':
+ continue
+
+ if value is not None:
+ opt = '='.join([key, value])
+ else:
+ opt = key
+
+ options.append(opt)
+
+ return ' '.join(options)
+
+
+class _BootManXenOptionsConfig(_BootManOptionsConfig):
+ key = 'xen_options'
+
+
+class _BootManConfigParser(object):
+ def __init__(self, cfgobj):
+ self._line = None
+ self._cfgobj = cfgobj
+ self._lineTokenizer = _QuotedLineTokenizer()
+ self._states = {'serial': self._serial,
+ 'background': self._background,
+ 'default': self._default,
+ 'linux': self._linux,
+ 'xen': self._xen,
+ 'other': self._other,
+ 'root': self._root,
+ 'options': self._options,
+ 'xen_options': self._xenoptions,
+ 'read_only': self._readonly,
+ 'timeout': self._timeout,
+ 'password': self._password,
+ 'include': self._include,
+ }
+
+ def parse(self, cfgline):
+ self._line = self._lineTokenizer.tokenize(cfgline)
+ if len(self._line) > 0 and self._line[0] in self._states:
+ self._states[self._line[0]]()
+
+ def _checkLength(self, length, gt=False):
+ if gt: assert(len(self._line) > length)
+ else: assert(len(self._line) == length)
+
+ def _serial(self):
+ self._checkLength(3)
+ self._cfgobj.serial(self._line[1], self._line[2])
+
+ def _background(self):
+ self._checkLength(2)
+ self._cfgobj.background(self._line[1])
+
+ def _default(self):
+ self._checkLength(2)
+ self._cfgobj.default(self._line[1])
+
+ def _linux(self):
+ self._checkLength(5)
+ self._cfgobj.linux(*self._line[1:])
+
+ def _xen(self):
+ self._checkLength(6)
+ self._cfgobj.xen(*self._line[1:])
+
+ def _other(self):
+ self._checkLength(4)
+ self._cfgobj.other(*self._line[1:])
+
+ def _root(self):
+ self._checkLength(2)
+ self._cfgobj.root(self._line[1])
+
+ def _options(self):
+ self._checkLength(2, gt=True)
+ self._cfgobj.options(' '.join(self._line[:-1]))
+
+ def _xenoptions(self):
+ self._checkLength(2, gt=True)
+ self._cfgobj.xenoptions(' '.join(self._line[:-1]))
+
+ def _readonly(self):
+ self._checkLength(1)
+ self._cfgobj.readonly()
+
+ def _timeout(self):
+ self._checkLength(2)
+ self._cfgobj.timeout(self._line[1])
+
+ def _password(self):
+ self._checkLength(2)
+ self._cfgobj.password(self._line[1])
+
+ def _include(self):
+ self._checkLength(2)
+ self._cfgobj.include(self._line[1])
+
+
+class BaseConfig(object):
+ def _checkDirs(self, file):
+ path = os.path.dirname(file)
+ if not os.path.exists(path):
+ os.makedirs(path)
+
+
+class BootLoaderConfig(BaseConfig):
+ def __init__(self):
+ self._parser = _BootManConfigParser(self)
+ self._data = {'linux': [],
+ 'xen': [],
+ 'other': [],
+ 'include': _BootManIncludeConfig(),
+ 'options': _BootManOptionsConfig(),
+ 'xen_options': _BootManXenOptionsConfig(),
+ }
+
+ def read(self, file):
+ for line in open(file, 'r'):
+ self._parser.parse(line)
+
+ def write(self, file):
+ self._checkDirs(file)
+ fh = open(file, 'w')
+ deferred = []
+ for key, value in self._data.iteritems():
+ if type(value) == type([]):
+ for item in value:
+ deferred.append('%s\n' % item)
+ elif isinstance(value, _BootManConfigElement):
+ fh.write('%s\n' % value)
+ else:
+ fh.write('%s %s\n' % (key, value))
+ for value in deferred:
+ fh.write(value)
+ fh.close()
+
+ def serial(self, device, settings):
+ self._data['serialDevice'] = device
+ self._data['serialSettings'] = settings
+
+ def background(self, background):
+ self._data['background'] = background
+
+ def default(self, default):
+ self._data['default'] = default
+
+ def linux(self, version, title, kernelPath, initrdPath):
+ obj = _BootManLinuxConfig(version, title, kernelPath, initrdPath)
+ self._data['linux'].append(obj)
+
+ def xen(self, version, title, xenImagePath, kernelPath, initrdPath):
+ obj = _BootManXenConfig(version, title, xenImagePath, kernelPath,
+ initrdPath)
+ self._data['xen'].append(obj)
+
+ def other(self, version, title, device):
+ obj = _BootManOtherConfig(version, title, device)
+ self._data['other'].append(obj)
+
+ def root(self, root):
+ self._data['root'] = root
+
+ def options(self, options):
+ self._data['options'].set(options)
+
+ def xenoptions(self, options):
+ self._data['xen_options'].set(options)
+
+ def readonly(self):
+ self._data['read_only'] = True
+
+ def timeout(self, timeout):
+ self._data['timeout'] = timeout
+
+ def password(self, pasword):
+ self._data['password'] = password
+
+ def include(self, path):
+ self._data['include'].set(path)
+
+
+class BootManConfig(BaseConfig):
+ def __init__(self):
+ self._blname = None
+
+ def write(self, file):
+ self._checkDirs(file)
+ fh = open(file, 'w')
+ fh.write('BOOTLOADER=%s' % self._blname)
+ fh.write('SYSLINUX_MENU=vesamenu')
+ fh.close()
+
+ def setBootLoader(self, blname):
+ self._blname = blname
diff --exclude .hg -ruN booty/bootman/constants.py booty-syslinux/bootman/constants.py
--- booty/bootman/constants.py 1969-12-31 19:00:00.000000000 -0500
+++ booty-syslinux/bootman/constants.py 2007-11-20 17:03:31.000000000 -0500
@@ -0,0 +1,5 @@
+#
+# Copyright (c) 2007 rPath, Inc.
+#
+
+BL_EXTLINUX, BL_GRUB, BL_GRUB_OLD = BL_VALID = range(3)
diff --exclude .hg -ruN booty/bootman/devicemap.py booty-syslinux/bootman/devicemap.py
--- booty/bootman/devicemap.py 1969-12-31 19:00:00.000000000 -0500
+++ booty-syslinux/bootman/devicemap.py 2007-11-20 17:03:31.000000000 -0500
@@ -0,0 +1,31 @@
+#
+# Copyright (c) rPath, Inc.
+#
+
+from bootloaderInfo import getDiskPart
+
+from bootman.config import BaseConfig
+
+class DeviceMap(BaseConfig):
+ def __init__(self, bootloader):
+ self.bootloader = bootloader
+ self._devs = []
+ self._drives = []
+
+ def use(self, device):
+ if device not in self._devs:
+ self._devs.append(device)
+ drive = getDiskPart(device)[0]
+ if drive not in self._drives:
+ self._drives.append(drive)
+
+ def write(self, file):
+ self._drives.sort()
+
+ self._checkDirs(file)
+ fh = open(file, 'w')
+ for drive in self._drives:
+ if not drive.startswith('md'):
+ fh.write('(%s) /dev/%s\n'
+ % (self.bootloader.grubbyDiskName(drive), drive))
+ fh.close()
diff --exclude .hg -ruN booty/bootman/__init__.py booty-syslinux/bootman/__init__.py
--- booty/bootman/__init__.py 1969-12-31 19:00:00.000000000 -0500
+++ booty-syslinux/bootman/__init__.py 2007-11-20 17:03:31.000000000 -0500
@@ -0,0 +1,6 @@
+#
+# Copyright (c) 2007 rPath, Inc.
+#
+
+from bootman.constants import *
+from bootman.bman import BootMan
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]