manifest: add support for selecting grub2.legacy

Older OS versions (RHEL 7) with older versions of grub2 don't support
BLS entries.  Setting NoBLS to true configures the bootloader with
traditional menu entries through the grub2.legacy osbuild stage.  This
requires specifying extra information for the OS to the pipeline:
version, product, and nick.
This commit is contained in:
Achilleas Koutsou 2023-01-23 23:45:18 +01:00 committed by Tomáš Hozza
parent 83fc8218d6
commit b39d802155
3 changed files with 69 additions and 25 deletions

View file

@ -182,6 +182,10 @@ func liveImage(workload workload.Workload,
img.Workload = workload img.Workload = workload
img.Compression = t.compression img.Compression = t.compression
img.PartTool = osbuild.PTSgdisk // all RHEL 7 images should use sgdisk img.PartTool = osbuild.PTSgdisk // all RHEL 7 images should use sgdisk
img.NoBLS = true // RHEL 7 grub does not support BLS
img.OSProduct = t.arch.distro.product
img.OSVersion = t.arch.distro.osVersion
img.OSNick = t.arch.distro.nick
// TODO: move generation into LiveImage // TODO: move generation into LiveImage
pt, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng) pt, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng)

View file

@ -26,6 +26,11 @@ type LiveImage struct {
Filename string Filename string
Compression string Compression string
PartTool osbuild.PartTool PartTool osbuild.PartTool
NoBLS bool
OSProduct string
OSVersion string
OSNick string
} }
func NewLiveImage() *LiveImage { func NewLiveImage() *LiveImage {
@ -47,6 +52,10 @@ func (img *LiveImage) InstantiateManifest(m *manifest.Manifest,
osPipeline.OSCustomizations = img.OSCustomizations osPipeline.OSCustomizations = img.OSCustomizations
osPipeline.Environment = img.Environment osPipeline.Environment = img.Environment
osPipeline.Workload = img.Workload osPipeline.Workload = img.Workload
osPipeline.NoBLS = img.NoBLS
osPipeline.OSProduct = img.OSProduct
osPipeline.OSVersion = img.OSVersion
osPipeline.OSNick = img.OSNick
imagePipeline := manifest.NewRawImage(m, buildPipeline, osPipeline) imagePipeline := manifest.NewRawImage(m, buildPipeline, osPipeline)
imagePipeline.PartTool = img.PartTool imagePipeline.PartTool = img.PartTool

View file

@ -130,6 +130,13 @@ type OS struct {
packageSpecs []rpmmd.PackageSpec packageSpecs []rpmmd.PackageSpec
platform platform.Platform platform platform.Platform
kernelVer string kernelVer string
// NoBLS configures the image bootloader with traditional menu entries
// instead of BLS. Required for legacy systems like RHEL 7.
NoBLS bool
OSProduct string
OSVersion string
OSNick string
} }
// NewOS creates a new OS pipeline. build is the build pipeline to use for // NewOS creates a new OS pipeline. build is the build pipeline to use for
@ -287,11 +294,13 @@ func (p *OS) serialize() osbuild.Pipeline {
} }
pipeline.AddStage(osbuild.NewRPMStage(rpmOptions, osbuild.NewRpmStageSourceFilesInputs(p.packageSpecs))) pipeline.AddStage(osbuild.NewRPMStage(rpmOptions, osbuild.NewRpmStageSourceFilesInputs(p.packageSpecs)))
// If the /boot is on a separate partition, the prefix for the BLS stage must be "" if !p.NoBLS {
if p.PartitionTable == nil || p.PartitionTable.FindMountable("/boot") == nil { // If the /boot is on a separate partition, the prefix for the BLS stage must be ""
pipeline.AddStage(osbuild.NewFixBLSStage(&osbuild.FixBLSStageOptions{})) if p.PartitionTable == nil || p.PartitionTable.FindMountable("/boot") == nil {
} else { pipeline.AddStage(osbuild.NewFixBLSStage(&osbuild.FixBLSStageOptions{}))
pipeline.AddStage(osbuild.NewFixBLSStage(&osbuild.FixBLSStageOptions{Prefix: common.ToPtr("")})) } else {
pipeline.AddStage(osbuild.NewFixBLSStage(&osbuild.FixBLSStageOptions{Prefix: common.ToPtr("")}))
}
} }
if len(p.Containers) > 0 { if len(p.Containers) > 0 {
@ -507,30 +516,52 @@ func (p *OS) serialize() osbuild.Pipeline {
case platform.ARCH_S390X: case platform.ARCH_S390X:
bootloader = osbuild.NewZiplStage(new(osbuild.ZiplStageOptions)) bootloader = osbuild.NewZiplStage(new(osbuild.ZiplStageOptions))
default: default:
var options *osbuild.GRUB2StageOptions if p.NoBLS {
options = osbuild.NewGrub2StageOptionsUnified(pt, // BLS entries not supported: use grub2.legacy
p.kernelVer, id := "76a22bf4-f153-4541-b6c7-0332c0dfaeac"
p.platform.GetUEFIVendor() != "", product := osbuild.GRUB2Product{
p.platform.GetBIOSPlatform(), Name: p.OSProduct,
p.platform.GetUEFIVendor(), false) Version: p.OSVersion,
if cfg := p.Grub2Config; cfg != nil { Nick: p.OSNick,
// TODO: don't store Grub2Config in OSPipeline, making the overrides unnecessary
// grub2.Config.Default is owned and set by `NewGrub2StageOptionsUnified`
// and thus we need to preserve it
if options.Config != nil {
cfg.Default = options.Config.Default
} }
options.Config = cfg rescueVer, _ := rpmmd.GetVerStrFromPackageSpecList(p.packageSpecs, "dracut-config-rescue")
} hasRescue := rescueVer != ""
if p.KernelOptionsBootloader { bootloader = osbuild.NewGrub2LegacyStage(
options.WriteCmdLine = nil osbuild.NewGrub2LegacyStageOptions(
if options.UEFI != nil { p.Grub2Config,
options.UEFI.Unified = false p.PartitionTable,
kernelOptions,
p.platform.GetBIOSPlatform(),
p.platform.GetUEFIVendor(),
osbuild.MakeGrub2MenuEntries(id, p.kernelVer, product, hasRescue),
),
)
} else {
options := osbuild.NewGrub2StageOptionsUnified(pt,
p.kernelVer,
p.platform.GetUEFIVendor() != "",
p.platform.GetBIOSPlatform(),
p.platform.GetUEFIVendor(), false)
if cfg := p.Grub2Config; cfg != nil {
// TODO: don't store Grub2Config in OSPipeline, making the overrides unnecessary
// grub2.Config.Default is owned and set by `NewGrub2StageOptionsUnified`
// and thus we need to preserve it
if options.Config != nil {
cfg.Default = options.Config.Default
}
options.Config = cfg
} }
options.KernelOptions = strings.Join(kernelOptions, " ") if p.KernelOptionsBootloader {
options.WriteCmdLine = nil
if options.UEFI != nil {
options.UEFI.Unified = false
}
options.KernelOptions = strings.Join(kernelOptions, " ")
}
bootloader = osbuild.NewGRUB2Stage(options)
} }
bootloader = osbuild.NewGRUB2Stage(options)
} }
pipeline.AddStage(bootloader) pipeline.AddStage(bootloader)