diff --git a/internal/blueprint/blueprint.go b/internal/blueprint/blueprint.go index bb4d60e2a..c30a16a46 100644 --- a/internal/blueprint/blueprint.go +++ b/internal/blueprint/blueprint.go @@ -104,13 +104,10 @@ func (b *Blueprint) GetPackages() []string { packages = append(packages, "@"+group.Name) } - if kc := b.Customizations.GetKernel(); kc != nil && kc.Name != "" { - kpkg := Package{Name: b.Customizations.Kernel.Name} - packages = append(packages, kpkg.ToNameVersion()) - } else { // no Kernel specified; add default - kpkg := Package{Name: "kernel"} - packages = append(packages, kpkg.ToNameVersion()) - } + kc := b.Customizations.GetKernel() + kpkg := Package{Name: kc.Name} + packages = append(packages, kpkg.ToNameVersion()) + return packages } diff --git a/internal/blueprint/customizations.go b/internal/blueprint/customizations.go index f6867d7e0..ad88c51f9 100644 --- a/internal/blueprint/customizations.go +++ b/internal/blueprint/customizations.go @@ -155,11 +155,21 @@ func (c *Customizations) GetGroups() []GroupCustomization { } func (c *Customizations) GetKernel() *KernelCustomization { - if c == nil { - return nil + var name string + var append string + if c != nil && c.Kernel != nil { + name = c.Kernel.Name + append = c.Kernel.Append } - return c.Kernel + if name == "" { + name = "kernel" + } + + return &KernelCustomization{ + Name: name, + Append: append, + } } func (c *Customizations) GetFirewall() *FirewallCustomization { diff --git a/internal/blueprint/customizations_test.go b/internal/blueprint/customizations_test.go index 1ebe21c3c..8415dc473 100644 --- a/internal/blueprint/customizations_test.go +++ b/internal/blueprint/customizations_test.go @@ -1,8 +1,9 @@ package blueprint import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func TestGetHostname(t *testing.T) { @@ -22,6 +23,7 @@ func TestGetKernel(t *testing.T) { expectedKernel := KernelCustomization{ Append: "--test", + Name: "kernel", } TestCustomizations := Customizations{ @@ -214,7 +216,7 @@ func TestNoCustomizationsInBlueprint(t *testing.T) { assert.Nil(t, TestBP.Customizations.GetHostname()) assert.Nil(t, TestBP.Customizations.GetUsers()) assert.Nil(t, TestBP.Customizations.GetGroups()) - assert.Nil(t, TestBP.Customizations.GetKernel()) + assert.Equal(t, &KernelCustomization{Name: "kernel"}, TestBP.Customizations.GetKernel()) assert.Nil(t, TestBP.Customizations.GetFirewall()) assert.Nil(t, TestBP.Customizations.GetServices()) diff --git a/internal/distro/fedora32/distro.go b/internal/distro/fedora32/distro.go index 22b642c6d..69618b029 100644 --- a/internal/distro/fedora32/distro.go +++ b/internal/distro/fedora32/distro.go @@ -434,7 +434,7 @@ func (t *imageType) fsTabStageOptions(uefi bool) *osbuild.FSTabStageOptions { func (t *imageType) grub2StageOptions(kernelOptions string, kernel *blueprint.KernelCustomization, uefi bool) *osbuild.GRUB2StageOptions { id := uuid.MustParse("76a22bf4-f153-4541-b6c7-0332c0dfaeac") - if kernel != nil { + if kernel != nil && kernel.Append != "" { kernelOptions += " " + kernel.Append } diff --git a/internal/distro/fedora33/distro.go b/internal/distro/fedora33/distro.go index f7cd66e5b..a1867daaa 100644 --- a/internal/distro/fedora33/distro.go +++ b/internal/distro/fedora33/distro.go @@ -446,7 +446,7 @@ func (t *imageType) fsTabStageOptions(uefi bool) *osbuild.FSTabStageOptions { func (t *imageType) grub2StageOptions(kernelOptions string, kernel *blueprint.KernelCustomization, uefi bool) *osbuild.GRUB2StageOptions { id := uuid.MustParse("76a22bf4-f153-4541-b6c7-0332c0dfaeac") - if kernel != nil { + if kernel != nil && kernel.Append != "" { kernelOptions += " " + kernel.Append } diff --git a/internal/distro/rhel8/distro.go b/internal/distro/rhel8/distro.go index b019c5131..c1a154cd5 100644 --- a/internal/distro/rhel8/distro.go +++ b/internal/distro/rhel8/distro.go @@ -475,7 +475,7 @@ func (t *imageType) fsTabStageOptions(uefi bool) *osbuild.FSTabStageOptions { func (t *imageType) grub2StageOptions(kernelOptions string, kernel *blueprint.KernelCustomization, uefi bool) *osbuild.GRUB2StageOptions { id := uuid.MustParse("0bd700f8-090f-4556-b797-b340297ea1bd") - if kernel != nil { + if kernel != nil && kernel.Append != "" { kernelOptions += " " + kernel.Append } diff --git a/internal/distro/rhel84/distro.go b/internal/distro/rhel84/distro.go index 0f706f2e8..e4acbaa9e 100644 --- a/internal/distro/rhel84/distro.go +++ b/internal/distro/rhel84/distro.go @@ -303,7 +303,7 @@ func (t *imageType) pipeline(c *blueprint.Customizations, options distro.ImageOp if t.bootable { if t.arch.Name() != "s390x" { - p.AddStage(osbuild.NewGRUB2Stage(t.grub2StageOptions(pt, t.kernelOptions, c.GetKernel(), t.arch.uefi, t.arch.legacy))) + p.AddStage(osbuild.NewGRUB2Stage(t.grub2StageOptions(pt, t.kernelOptions, c.GetKernel(), packageSpecs, t.arch.uefi, t.arch.legacy))) } } @@ -523,7 +523,7 @@ func (t *imageType) systemdStageOptions(enabledServices, disabledServices []stri } } -func (t *imageType) grub2StageOptions(pt *disk.PartitionTable, kernelOptions string, kernel *blueprint.KernelCustomization, uefi bool, legacy string) *osbuild.GRUB2StageOptions { +func (t *imageType) grub2StageOptions(pt *disk.PartitionTable, kernelOptions string, kernel *blueprint.KernelCustomization, packages []rpmmd.PackageSpec, uefi bool, legacy string) *osbuild.GRUB2StageOptions { if pt == nil { panic("partition table must be defined for grub2 stage, this is a programming error") } @@ -532,13 +532,12 @@ func (t *imageType) grub2StageOptions(pt *disk.PartitionTable, kernelOptions str panic("root partition must be defined for grub2 stage, this is a programming error") } - id := uuid.MustParse(rootPartition.Filesystem.UUID) - - if kernel != nil { - kernelOptions += " " + kernel.Append + stageOptions := osbuild.GRUB2StageOptions{ + RootFilesystemUUID: uuid.MustParse(rootPartition.Filesystem.UUID), + KernelOptions: kernelOptions, + Legacy: legacy, } - var uefiOptions *osbuild.GRUB2UEFI if uefi { var vendor string if t.arch.distro.isCentos { @@ -546,21 +545,28 @@ func (t *imageType) grub2StageOptions(pt *disk.PartitionTable, kernelOptions str } else { vendor = "redhat" } - uefiOptions = &osbuild.GRUB2UEFI{ + stageOptions.UEFI = &osbuild.GRUB2UEFI{ Vendor: vendor, } } if !uefi { - legacy = t.arch.legacy + stageOptions.Legacy = t.arch.legacy } - return &osbuild.GRUB2StageOptions{ - RootFilesystemUUID: id, - KernelOptions: kernelOptions, - Legacy: legacy, - UEFI: uefiOptions, + if kernel != nil { + if kernel.Append != "" { + stageOptions.KernelOptions += " " + kernel.Append + } + for _, pkg := range packages { + if pkg.Name == kernel.Name { + stageOptions.SavedEntry = "ffffffffffffffffffffffffffffffff-" + pkg.Version + "-" + pkg.Release + "." + pkg.Arch + break + } + } } + + return &stageOptions } func (t *imageType) selinuxStageOptions() *osbuild.SELinuxStageOptions { diff --git a/internal/osbuild/grub2_stage.go b/internal/osbuild/grub2_stage.go index c52297381..1998b519e 100644 --- a/internal/osbuild/grub2_stage.go +++ b/internal/osbuild/grub2_stage.go @@ -16,6 +16,7 @@ type GRUB2StageOptions struct { KernelOptions string `json:"kernel_opts,omitempty"` Legacy string `json:"legacy,omitempty"` UEFI *GRUB2UEFI `json:"uefi,omitempty"` + SavedEntry string `json:"saved_entry,omitempty"` } type GRUB2UEFI struct {