rhel85: introduce BootType and use it for arch and image definitions

Previously, the support of UEFI has been captured only on the level or
architecture definition as a binary boolean value. In reality some of
the architectures are able to support legacy, UEFI or hybrid boot.

Introduce a new BootType value, defined on the architecture level, which
can be set to one of the three boot types mentioned above. The value set
on the architecture level can be overridden on the image type level in
the image type definition.

Add two unexported helper methods to the `imageType`, specifically
`getBootType()` which returns the boot type that  should be used for the
image type and architecture combination. The values set explicitly in
the image type or architecture definition should not be used directly.
Second added method is `supportsUEFI()`, which returns boolean value
representing the fact if the image type supports UEFI boot.

Split and define the boot package sets separately for the legacy and
UEFI boot. The `PackageSets()` method of the imageType structure is
modified to take the boot type into consideration and append appropriate
package sets to the "os" package set.

Signed-off-by: Tomas Hozza <thozza@redhat.com>
This commit is contained in:
Tomas Hozza 2021-07-30 16:26:36 +02:00 committed by Ondřej Budai
parent 02ff0fc606
commit 49ed70a565
3 changed files with 93 additions and 36 deletions

View file

@ -24,8 +24,11 @@ const (
// build package set name
buildPkgsKey = "build"
// bootable image package set name
bootPkgsKey = "boot"
// Legacy bootable image package set name
bootLegacyPkgsKey = "boot.legacy"
// UEFI bootable image package set name
bootUEFIPkgsKey = "boot.uefi"
// main/common os image package set name
osPkgsKey = "packages"
@ -55,6 +58,15 @@ const (
s390xArchName = "s390x"
)
type BootType string
const (
UnsetBootType BootType = ""
LegacyBootType BootType = "legacy"
UEFIBootType BootType = "uefi"
HybridBootType BootType = "hybrid"
)
type distribution struct {
name string
modulePlatformID string
@ -112,7 +124,7 @@ type architecture struct {
imageTypeAliases map[string]string
packageSets map[string]rpmmd.PackageSet
legacy string
uefi bool
bootType BootType
}
func (a *architecture) Name() string {
@ -190,6 +202,8 @@ type imageType struct {
rpmOstree bool
// bootable image
bootable bool
// If set to a value, it is preferred over the architecture value
bootType BootType
}
func (t *imageType) Name() string {
@ -252,8 +266,27 @@ func (t *imageType) PackageSets(bp blueprint.Blueprint) map[string]rpmmd.Package
// package sets from flags
if t.bootable {
// add boot sets
mergedSets[osPkgsKey] = mergedSets[osPkgsKey].Append(archSets[bootPkgsKey]).Append(distroSets[bootPkgsKey])
var addLegacyBootPkg bool
var addUEFIBootPkg bool
switch bt := t.getBootType(); bt {
case LegacyBootType:
addLegacyBootPkg = true
case UEFIBootType:
addUEFIBootPkg = true
case HybridBootType:
addLegacyBootPkg = true
addUEFIBootPkg = true
default:
panic(fmt.Sprintf("unsupported boot type: %q", bt))
}
if addLegacyBootPkg {
mergedSets[osPkgsKey] = mergedSets[osPkgsKey].Append(archSets[bootLegacyPkgsKey]).Append(distroSets[bootLegacyPkgsKey])
}
if addUEFIBootPkg {
mergedSets[osPkgsKey] = mergedSets[osPkgsKey].Append(archSets[bootUEFIPkgsKey]).Append(distroSets[bootUEFIPkgsKey])
}
}
if t.rpmOstree {
// add ostree sets
@ -286,6 +319,24 @@ func (t *imageType) Exports() []string {
return []string{"assembler"}
}
// getBootType returns the BootType which should be used for this particular
// combination of architecture and image type.
func (t *imageType) getBootType() BootType {
bootType := t.arch.bootType
if t.bootType != UnsetBootType {
bootType = t.bootType
}
return bootType
}
func (t *imageType) supportsUEFI() bool {
bootType := t.getBootType()
if bootType == HybridBootType || bootType == UEFIBootType {
return true
}
return false
}
// local type for ostree commit metadata used to define commit sources
type ostreeCommit struct {
Checksum string
@ -425,41 +476,42 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
name: x86_64ArchName,
distro: rd,
packageSets: map[string]rpmmd.PackageSet{
buildPkgsKey: x8664BuildPackageSet(),
bootPkgsKey: x8664BootPackageSet(),
edgePkgsKey: x8664EdgeCommitPackageSet(),
buildPkgsKey: x8664BuildPackageSet(),
bootLegacyPkgsKey: x8664LegacyBootPackageSet(),
bootUEFIPkgsKey: x8664UEFIBootPackageSet(),
edgePkgsKey: x8664EdgeCommitPackageSet(),
},
legacy: "i386-pc",
uefi: true,
legacy: "i386-pc",
bootType: HybridBootType,
}
aarch64 := architecture{
name: aarch64ArchName,
distro: rd,
packageSets: map[string]rpmmd.PackageSet{
bootPkgsKey: aarch64BootPackageSet(),
edgePkgsKey: aarch64EdgeCommitPackageSet(),
bootUEFIPkgsKey: aarch64UEFIBootPackageSet(),
edgePkgsKey: aarch64EdgeCommitPackageSet(),
},
uefi: true,
bootType: UEFIBootType,
}
ppc64le := architecture{
distro: rd,
name: ppc64leArchName,
packageSets: map[string]rpmmd.PackageSet{
bootPkgsKey: ppc64leBootPackageSet(),
buildPkgsKey: ppc64leBuildPackageSet(),
bootLegacyPkgsKey: ppc64leLegacyBootPackageSet(),
buildPkgsKey: ppc64leBuildPackageSet(),
},
legacy: "powerpc-ieee1275",
uefi: false,
legacy: "powerpc-ieee1275",
bootType: LegacyBootType,
}
s390x := architecture{
distro: rd,
name: s390xArchName,
packageSets: map[string]rpmmd.PackageSet{
bootPkgsKey: s390xBootPackageSet(),
bootLegacyPkgsKey: s390xLegacyBootPackageSet(),
},
uefi: false,
bootType: LegacyBootType,
}
// Shared Services
@ -609,6 +661,7 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
enabledServices: ec2EnabledServices,
kernelOptions: "console=ttyS0,115200n8 console=tty0 net.ifnames=0 rd.blacklist=nouveau nvme_core.io_timeout=4294967295 crashkernel=auto",
bootable: true,
bootType: LegacyBootType,
defaultSize: 10 * GigaByte,
pipelines: ec2Pipelines,
exports: []string{"image"},

View file

@ -64,15 +64,22 @@ func x8664InstallerBuildPackageSet() rpmmd.PackageSet {
// BOOT PACKAGE SETS
// x86_64 arch-specific boot package set
func x8664BootPackageSet() rpmmd.PackageSet {
// x86_64 Legacy arch-specific boot package set
func x8664LegacyBootPackageSet() rpmmd.PackageSet {
return rpmmd.PackageSet{
Include: []string{"dracut-config-generic", "grub2-pc", "grub2-efi-x64", "shim-x64"},
Include: []string{"dracut-config-generic", "grub2-pc"},
}
}
// aarch64 arch-specific boot package set
func aarch64BootPackageSet() rpmmd.PackageSet {
// x86_64 UEFI arch-specific boot package set
func x8664UEFIBootPackageSet() rpmmd.PackageSet {
return rpmmd.PackageSet{
Include: []string{"grub2-efi-x64", "shim-x64"},
}
}
// aarch64 UEFI arch-specific boot package set
func aarch64UEFIBootPackageSet() rpmmd.PackageSet {
return rpmmd.PackageSet{
Include: []string{
"dracut-config-generic", "efibootmgr", "grub2-efi-aa64",
@ -81,8 +88,8 @@ func aarch64BootPackageSet() rpmmd.PackageSet {
}
}
// ppc64le arch-specific boot package set
func ppc64leBootPackageSet() rpmmd.PackageSet {
// ppc64le Legacy arch-specific boot package set
func ppc64leLegacyBootPackageSet() rpmmd.PackageSet {
return rpmmd.PackageSet{
Include: []string{
"dracut-config-generic", "powerpc-utils", "grub2-ppc64le",
@ -91,8 +98,8 @@ func ppc64leBootPackageSet() rpmmd.PackageSet {
}
}
// s390x arch-specific boot package set
func s390xBootPackageSet() rpmmd.PackageSet {
// s390x Legacy arch-specific boot package set
func s390xLegacyBootPackageSet() rpmmd.PackageSet {
return rpmmd.PackageSet{
Include: []string{"dracut-config-generic", "s390utils-base"},
}

View file

@ -37,7 +37,7 @@ func qcow2Pipelines(t *imageType, customizations *blueprint.Customizations, opti
}
partitionTable := defaultPartitionTable(options, t.arch, rng)
treePipeline.AddStage(osbuild.NewFSTabStage(partitionTable.FSTabStageOptionsV2()))
treePipeline.AddStage(osbuild.NewGRUB2Stage(grub2StageOptions(&partitionTable, t.kernelOptions, customizations.GetKernel(), packageSetSpecs[blueprintPkgsKey], t.arch.uefi, t.arch.legacy)))
treePipeline.AddStage(osbuild.NewGRUB2Stage(grub2StageOptions(&partitionTable, t.kernelOptions, customizations.GetKernel(), packageSetSpecs[blueprintPkgsKey], t.supportsUEFI(), t.arch.legacy)))
treePipeline.AddStage(osbuild.NewSELinuxStage(selinuxStageOptions(false)))
pipelines = append(pipelines, *treePipeline)
@ -61,7 +61,7 @@ func vhdPipelines(t *imageType, customizations *blueprint.Customizations, option
partitionTable := defaultPartitionTable(options, t.arch, rng)
treePipeline.AddStage(osbuild.NewFSTabStage(partitionTable.FSTabStageOptionsV2()))
treePipeline.AddStage(osbuild.NewGRUB2Stage(grub2StageOptions(&partitionTable, t.kernelOptions, customizations.GetKernel(), packageSetSpecs[blueprintPkgsKey], t.arch.uefi, t.arch.legacy)))
treePipeline.AddStage(osbuild.NewGRUB2Stage(grub2StageOptions(&partitionTable, t.kernelOptions, customizations.GetKernel(), packageSetSpecs[blueprintPkgsKey], t.supportsUEFI(), t.arch.legacy)))
treePipeline.AddStage(osbuild.NewSELinuxStage(selinuxStageOptions(false)))
pipelines = append(pipelines, *treePipeline)
@ -87,7 +87,7 @@ func vmdkPipelines(t *imageType, customizations *blueprint.Customizations, optio
partitionTable := defaultPartitionTable(options, t.arch, rng)
treePipeline.AddStage(osbuild.NewFSTabStage(partitionTable.FSTabStageOptionsV2()))
treePipeline.AddStage(osbuild.NewGRUB2Stage(grub2StageOptions(&partitionTable, t.kernelOptions, customizations.GetKernel(), packageSetSpecs[blueprintPkgsKey], t.arch.uefi, t.arch.legacy)))
treePipeline.AddStage(osbuild.NewGRUB2Stage(grub2StageOptions(&partitionTable, t.kernelOptions, customizations.GetKernel(), packageSetSpecs[blueprintPkgsKey], t.supportsUEFI(), t.arch.legacy)))
treePipeline.AddStage(osbuild.NewSELinuxStage(selinuxStageOptions(false)))
pipelines = append(pipelines, *treePipeline)
@ -113,7 +113,7 @@ func openstackPipelines(t *imageType, customizations *blueprint.Customizations,
partitionTable := defaultPartitionTable(options, t.arch, rng)
treePipeline.AddStage(osbuild.NewFSTabStage(partitionTable.FSTabStageOptionsV2()))
treePipeline.AddStage(osbuild.NewGRUB2Stage(grub2StageOptions(&partitionTable, t.kernelOptions, customizations.GetKernel(), packageSetSpecs[blueprintPkgsKey], t.arch.uefi, t.arch.legacy)))
treePipeline.AddStage(osbuild.NewGRUB2Stage(grub2StageOptions(&partitionTable, t.kernelOptions, customizations.GetKernel(), packageSetSpecs[blueprintPkgsKey], t.supportsUEFI(), t.arch.legacy)))
treePipeline.AddStage(osbuild.NewSELinuxStage(selinuxStageOptions(false)))
pipelines = append(pipelines, *treePipeline)
@ -368,15 +368,12 @@ func ec2CommonPipelines(t *imageType, customizations *blueprint.Customizations,
var treePipeline *osbuild.Pipeline
var err error
var useUEFI bool
switch arch := t.arch.Name(); arch {
// rhel-ec2-x86_64, rhel-ha-ec2
case x86_64ArchName:
useUEFI = false
treePipeline, err = ec2X86_64BaseTreePipeline(repos, packageSetSpecs[osPkgsKey], packageSetSpecs[blueprintPkgsKey], customizations, options, t.enabledServices, t.disabledServices, t.defaultTarget, withRHUI)
// rhel-ec2-aarch64
case aarch64ArchName:
useUEFI = true
treePipeline, err = ec2BaseTreePipeline(repos, packageSetSpecs[osPkgsKey], packageSetSpecs[blueprintPkgsKey], customizations, options, t.enabledServices, t.disabledServices, t.defaultTarget, withRHUI)
default:
return nil, fmt.Errorf("ec2CommonPipelines: unsupported image architecture: %q", arch)
@ -386,7 +383,7 @@ func ec2CommonPipelines(t *imageType, customizations *blueprint.Customizations,
}
partitionTable := ec2PartitionTable(options, t.arch, rng)
treePipeline.AddStage(osbuild.NewFSTabStage(partitionTable.FSTabStageOptionsV2()))
treePipeline.AddStage(osbuild.NewGRUB2Stage(grub2StageOptions(&partitionTable, t.kernelOptions, customizations.GetKernel(), packageSetSpecs[blueprintPkgsKey], useUEFI, t.arch.legacy)))
treePipeline.AddStage(osbuild.NewGRUB2Stage(grub2StageOptions(&partitionTable, t.kernelOptions, customizations.GetKernel(), packageSetSpecs[blueprintPkgsKey], t.supportsUEFI(), t.arch.legacy)))
// The last stage must be the SELinux stage
treePipeline.AddStage(osbuild.NewSELinuxStage(selinuxStageOptions(false)))
pipelines = append(pipelines, *treePipeline)