Repository: osbuild/osbuild-composer
Pull request #1241 (2021-02-19 20:40:27)

rhel84/grub2: set saved_entry
Explicitly set the kernel to boot into.

This hooks up the recent changes @gicmo made in osbuild to fix a rhel8.4 regression. No tests yet.

This pull request includes:

- [x] adequate testing for the new functionality or fixed issue
- [x] adequate documentation informing people about the change

ondrejbudai: I think we need to bump the osbuild dependency in both the spec file and README.
teg: > I think we need to bump the osbuild dependency in both the spec file and README. Also what about Fedora 32? Doesn't it need a pinned dependency?

Good points! Fixed.

Patch:
diff --git a/NEWS.md b/NEWS.md
index 2db7b5491..f6af8f1a0 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,5 +1,37 @@
 # OSBuild Composer - Operating System Image Composition Services
 
+## CHANGES WITH 28:
+
+  * OSBuild Composer can now build CentOS Stream 8 images!
+
+  * OSBuild Composer can now upload images to VMWare!
+
+  * Cloudapi contains new /openapi.json and /version endpoints. The already
+    existing `POST /compose` endpoint now supports specification of additional
+    packages.
+
+  * Blueprints now support definition of alternative kernels, such as kernel-rt,
+    using the `customizations.kernel.name` key.
+
+  * Attempt to use the `customization.kernel.append` key in a blueprint for the
+    OSTree image type now results in error, because the customization was ignored.
+
+  * OSBuild dependency now requires version 24 because of its new sysconfig and
+    RHSM stages.
+
+  * RHEL qcow2 images now come with disabled product-id and subscription-manager
+    plugins in dnf to make them consistent with images produced by imagefactory.
+
+  * OSTree `parent` can now be replaced with `url` pointing to a repository
+    that contains the parent commit.
+
+Contributions from: Achilleas Koutsou, Alexander Todorov, Antonio Murdaca,
+                    Brian C. Lane, Chloe Kaubisch, Jacob Kozol, Jozef Mikovic,
+                    Major Hayden, Martin Sehnoutka, Ondřej Budai, Sanne Raymaekers,
+                    Tomas Hozza, Tom Gundersen
+
+— Brno, 2021-02-20
+
 ## CHANGES WITH 27:
 
   * Starting from this release, we are putting longer news posts in
diff --git a/README.md b/README.md
index 1eb7630dc..03da623cf 100644
--- a/README.md
+++ b/README.md
@@ -45,7 +45,7 @@ provided infrastructure and services.
 
 The requirements for this project are:
 
- * `osbuild >= 24`
+ * `osbuild >= 26`
  * `systemd >= 244`
 
 At build-time, the following software is required:
diff --git a/Schutzfile b/Schutzfile
index 250979881..22972185d 100644
--- a/Schutzfile
+++ b/Schutzfile
@@ -1,5 +1,10 @@
 {
   "fedora-32": {
+    "dependencies": {
+      "osbuild": {
+        "commit": "6f1350d72d210767062a8e346e1472305703686b"
+      }
+    },
     "dependants": {
       "koji-osbuild": {
         "commit": "4fdc457745e1147475ea3ac1e3b073e592d7b174"
@@ -9,7 +14,7 @@
   "rhel-8.3": {
     "dependencies": {
       "osbuild": {
-        "commit": "755c07a142ce2e8e88420590be553d8a255f3326"
+        "commit": "6f1350d72d210767062a8e346e1472305703686b"
       }
     },
     "dependants": {
@@ -20,5 +25,26 @@
         ]
       }
     }
+  },
+  "fedora-33": {
+    "dependencies": {
+      "osbuild": {
+        "commit": "6f1350d72d210767062a8e346e1472305703686b"
+      }
+    }
+  },
+  "centos-8": {
+    "dependencies": {
+      "osbuild": {
+        "commit": "6f1350d72d210767062a8e346e1472305703686b"
+      }
+    }
+  },
+  "rhel-8.4": {
+    "dependencies": {
+      "osbuild": {
+        "commit": "6f1350d72d210767062a8e346e1472305703686b"
+      }
+    }
   }
 }
diff --git a/docs/news/unreleased/centos-stream.md b/docs/news/28/centos-stream.md
similarity index 100%
rename from docs/news/unreleased/centos-stream.md
rename to docs/news/28/centos-stream.md
diff --git a/docs/news/unreleased/cloudapi-packages.md b/docs/news/28/cloudapi-packages.md
similarity index 100%
rename from docs/news/unreleased/cloudapi-packages.md
rename to docs/news/28/cloudapi-packages.md
diff --git a/docs/news/unreleased/kernel-customizations-name.md b/docs/news/28/kernel-customizations-name.md
similarity index 100%
rename from docs/news/unreleased/kernel-customizations-name.md
rename to docs/news/28/kernel-customizations-name.md
diff --git a/docs/news/unreleased/openapi-endpoint-in-cloudapi.md b/docs/news/28/openapi-endpoint-in-cloudapi.md
similarity index 100%
rename from docs/news/unreleased/openapi-endpoint-in-cloudapi.md
rename to docs/news/28/openapi-endpoint-in-cloudapi.md
diff --git a/docs/news/unreleased/osbuild-24.md b/docs/news/28/osbuild-24.md
similarity index 100%
rename from docs/news/unreleased/osbuild-24.md
rename to docs/news/28/osbuild-24.md
diff --git a/docs/news/unreleased/osbuild-rhsm-stage.md b/docs/news/28/osbuild-rhsm-stage.md
similarity index 100%
rename from docs/news/unreleased/osbuild-rhsm-stage.md
rename to docs/news/28/osbuild-rhsm-stage.md
diff --git a/docs/news/unreleased/ostree-kernel-append.md b/docs/news/28/ostree-kernel-append.md
similarity index 100%
rename from docs/news/unreleased/ostree-kernel-append.md
rename to docs/news/28/ostree-kernel-append.md
diff --git a/docs/news/unreleased/sysconfig.md b/docs/news/28/sysconfig.md
similarity index 100%
rename from docs/news/unreleased/sysconfig.md
rename to docs/news/28/sysconfig.md
diff --git a/docs/news/unreleased/vmware-upload-target.md b/docs/news/28/vmware-upload-target.md
similarity index 100%
rename from docs/news/unreleased/vmware-upload-target.md
rename to docs/news/28/vmware-upload-target.md
diff --git a/docs/news/unreleased/weldr-ostree-url.md b/docs/news/28/weldr-ostree-url.md
similarity index 100%
rename from docs/news/unreleased/weldr-ostree-url.md
rename to docs/news/28/weldr-ostree-url.md
diff --git a/docs/news/unreleased/.gitkeep b/docs/news/unreleased/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/news/unreleased/rhel84-grub2-saved-entry.md b/docs/news/unreleased/rhel84-grub2-saved-entry.md
new file mode 100644
index 000000000..ed3f52b26
--- /dev/null
+++ b/docs/news/unreleased/rhel84-grub2-saved-entry.md
@@ -0,0 +1,5 @@
+# RHEL8.4: Fix grub2 kernel selection
+
+By marking the kernel we install as the `saved_entry`, we make sure that installing additional/subsequent kernels do not unintentienally change the default kernel to be booted into.
+
+Relevant PR: https://github.com/osbuild/osbuild-composer/pull/1241
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/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 {
diff --git a/osbuild-composer.spec b/osbuild-composer.spec
index b1aed56c8..492d578f1 100644
--- a/osbuild-composer.spec
+++ b/osbuild-composer.spec
@@ -4,7 +4,7 @@
 
 %global goipath         github.com/osbuild/osbuild-composer
 
-Version:        27
+Version:        28
 
 %gometa
 
@@ -273,8 +273,8 @@ The core osbuild-composer binary. This is suitable both for spawning in containe
 Summary:    The worker for osbuild-composer
 Requires:   systemd
 Requires:   qemu-img
-Requires:   osbuild >= 24
-Requires:   osbuild-ostree >= 24
+Requires:   osbuild >= 26
+Requires:   osbuild-ostree >= 26
 
 # remove in F34
 Obsoletes: golang-github-osbuild-composer-worker < %{version}-%{release}


Test patch:
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/test/data/manifests/centos_8-x86_64-ami-boot.json b/test/data/manifests/centos_8-x86_64-ami-boot.json
index fd918940b..69087db27 100644
--- a/test/data/manifests/centos_8-x86_64-ami-boot.json
+++ b/test/data/manifests/centos_8-x86_64-ami-boot.json
@@ -3858,7 +3858,8 @@
             "legacy": "i386-pc",
             "uefi": {
               "vendor": "centos"
-            }
+            },
+            "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-277.el8.x86_64"
           }
         },
         {
@@ -10257,7 +10258,8 @@
   },
   "image-info": {
     "boot-environment": {
-      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 console=ttyS0,115200n8 console=tty0 net.ifnames=0 rd.blacklist=nouveau nvme_core.io_timeout=4294967295 crashkernel=auto"
+      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 console=ttyS0,115200n8 console=tty0 net.ifnames=0 rd.blacklist=nouveau nvme_core.io_timeout=4294967295 crashkernel=auto",
+      "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-277.el8.x86_64"
     },
     "bootloader": "grub",
     "bootmenu": [
diff --git a/test/data/manifests/centos_8-x86_64-openstack-boot.json b/test/data/manifests/centos_8-x86_64-openstack-boot.json
index c389c6e0b..64e589920 100644
--- a/test/data/manifests/centos_8-x86_64-openstack-boot.json
+++ b/test/data/manifests/centos_8-x86_64-openstack-boot.json
@@ -4155,7 +4155,8 @@
             "legacy": "i386-pc",
             "uefi": {
               "vendor": "centos"
-            }
+            },
+            "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-277.el8.x86_64"
           }
         },
         {
@@ -10958,7 +10959,8 @@
   },
   "image-info": {
     "boot-environment": {
-      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 ro net.ifnames=0"
+      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 ro net.ifnames=0",
+      "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-277.el8.x86_64"
     },
     "bootloader": "grub",
     "bootmenu": [
diff --git a/test/data/manifests/centos_8-x86_64-qcow2-boot.json b/test/data/manifests/centos_8-x86_64-qcow2-boot.json
index d2304c472..e3988dd05 100644
--- a/test/data/manifests/centos_8-x86_64-qcow2-boot.json
+++ b/test/data/manifests/centos_8-x86_64-qcow2-boot.json
@@ -4132,7 +4132,8 @@
             "legacy": "i386-pc",
             "uefi": {
               "vendor": "centos"
-            }
+            },
+            "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-277.el8.x86_64"
           }
         },
         {
@@ -10934,7 +10935,8 @@
   },
   "image-info": {
     "boot-environment": {
-      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0 crashkernel=auto"
+      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0 crashkernel=auto",
+      "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-277.el8.x86_64"
     },
     "bootloader": "grub",
     "bootmenu": [
diff --git a/test/data/manifests/centos_8-x86_64-qcow2-customize.json b/test/data/manifests/centos_8-x86_64-qcow2-customize.json
index d1afa8ec3..c7062df63 100644
--- a/test/data/manifests/centos_8-x86_64-qcow2-customize.json
+++ b/test/data/manifests/centos_8-x86_64-qcow2-customize.json
@@ -4184,7 +4184,8 @@
             "legacy": "i386-pc",
             "uefi": {
               "vendor": "centos"
-            }
+            },
+            "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-277.el8.x86_64"
           }
         },
         {
@@ -11039,7 +11040,8 @@
   },
   "image-info": {
     "boot-environment": {
-      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0 crashkernel=auto debug"
+      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0 crashkernel=auto debug",
+      "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-277.el8.x86_64"
     },
     "bootloader": "grub",
     "bootmenu": [
diff --git a/test/data/manifests/centos_8-x86_64-vhd-boot.json b/test/data/manifests/centos_8-x86_64-vhd-boot.json
index b15e346ea..51e24620d 100644
--- a/test/data/manifests/centos_8-x86_64-vhd-boot.json
+++ b/test/data/manifests/centos_8-x86_64-vhd-boot.json
@@ -4111,7 +4111,8 @@
             "legacy": "i386-pc",
             "uefi": {
               "vendor": "centos"
-            }
+            },
+            "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-277.el8.x86_64"
           }
         },
         {
@@ -10874,7 +10875,8 @@
   },
   "image-info": {
     "boot-environment": {
-      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 ro biosdevname=0 rootdelay=300 console=ttyS0 earlyprintk=ttyS0 net.ifnames=0"
+      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 ro biosdevname=0 rootdelay=300 console=ttyS0 earlyprintk=ttyS0 net.ifnames=0",
+      "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-277.el8.x86_64"
     },
     "bootloader": "grub",
     "bootmenu": [
diff --git a/test/data/manifests/centos_8-x86_64-vmdk-boot.json b/test/data/manifests/centos_8-x86_64-vmdk-boot.json
index cd2d62ade..144cfacf7 100644
--- a/test/data/manifests/centos_8-x86_64-vmdk-boot.json
+++ b/test/data/manifests/centos_8-x86_64-vmdk-boot.json
@@ -3949,7 +3949,8 @@
             "legacy": "i386-pc",
             "uefi": {
               "vendor": "centos"
-            }
+            },
+            "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-277.el8.x86_64"
           }
         },
         {
@@ -10462,7 +10463,8 @@
   },
   "image-info": {
     "boot-environment": {
-      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 ro net.ifnames=0"
+      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 ro net.ifnames=0",
+      "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-277.el8.x86_64"
     },
     "bootloader": "grub",
     "bootmenu": [
diff --git a/test/data/manifests/rhel_84-aarch64-ami-boot.json b/test/data/manifests/rhel_84-aarch64-ami-boot.json
index 9861bc48f..d43729350 100644
--- a/test/data/manifests/rhel_84-aarch64-ami-boot.json
+++ b/test/data/manifests/rhel_84-aarch64-ami-boot.json
@@ -3213,7 +3213,8 @@
             "kernel_opts": "console=ttyS0,115200n8 console=tty0 net.ifnames=0 rd.blacklist=nouveau nvme_core.io_timeout=4294967295 crashkernel=auto",
             "uefi": {
               "vendor": "redhat"
-            }
+            },
+            "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.aarch64"
           }
         },
         {
@@ -8909,7 +8910,8 @@
   },
   "image-info": {
     "boot-environment": {
-      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 console=ttyS0,115200n8 console=tty0 net.ifnames=0 rd.blacklist=nouveau nvme_core.io_timeout=4294967295 crashkernel=auto"
+      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 console=ttyS0,115200n8 console=tty0 net.ifnames=0 rd.blacklist=nouveau nvme_core.io_timeout=4294967295 crashkernel=auto",
+      "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.aarch64"
     },
     "bootloader": "unknown",
     "bootmenu": [
diff --git a/test/data/manifests/rhel_84-aarch64-openstack-boot.json b/test/data/manifests/rhel_84-aarch64-openstack-boot.json
index 6c74a0837..47b8e5327 100644
--- a/test/data/manifests/rhel_84-aarch64-openstack-boot.json
+++ b/test/data/manifests/rhel_84-aarch64-openstack-boot.json
@@ -3446,7 +3446,8 @@
             "kernel_opts": "ro net.ifnames=0",
             "uefi": {
               "vendor": "redhat"
-            }
+            },
+            "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.aarch64"
           }
         },
         {
@@ -9470,7 +9471,8 @@
   },
   "image-info": {
     "boot-environment": {
-      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 ro net.ifnames=0"
+      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 ro net.ifnames=0",
+      "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.aarch64"
     },
     "bootloader": "unknown",
     "bootmenu": [
diff --git a/test/data/manifests/rhel_84-aarch64-qcow2-boot.json b/test/data/manifests/rhel_84-aarch64-qcow2-boot.json
index 8e896c3cd..498a0e1eb 100644
--- a/test/data/manifests/rhel_84-aarch64-qcow2-boot.json
+++ b/test/data/manifests/rhel_84-aarch64-qcow2-boot.json
@@ -3398,7 +3398,8 @@
             "kernel_opts": "console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0 crashkernel=auto",
             "uefi": {
               "vendor": "redhat"
-            }
+            },
+            "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.aarch64"
           }
         },
         {
@@ -9378,7 +9379,8 @@
   },
   "image-info": {
     "boot-environment": {
-      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0 crashkernel=auto"
+      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0 crashkernel=auto",
+      "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.aarch64"
     },
     "bootloader": "unknown",
     "bootmenu": [
diff --git a/test/data/manifests/rhel_84-ppc64le-qcow2-boot.json b/test/data/manifests/rhel_84-ppc64le-qcow2-boot.json
index a5599f831..e5264d4b4 100644
--- a/test/data/manifests/rhel_84-ppc64le-qcow2-boot.json
+++ b/test/data/manifests/rhel_84-ppc64le-qcow2-boot.json
@@ -3677,7 +3677,8 @@
           "options": {
             "root_fs_uuid": "0194fdc2-fa2f-4cc0-81d3-ff12045b73c8",
             "kernel_opts": "console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0 crashkernel=auto",
-            "legacy": "powerpc-ieee1275"
+            "legacy": "powerpc-ieee1275",
+            "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.ppc64le"
           }
         },
         {
@@ -10112,7 +10113,8 @@
   },
   "image-info": {
     "boot-environment": {
-      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0 crashkernel=auto"
+      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0 crashkernel=auto",
+      "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.ppc64le"
     },
     "bootloader": "unknown",
     "bootmenu": [
diff --git a/test/data/manifests/rhel_84-x86_64-ami-boot.json b/test/data/manifests/rhel_84-x86_64-ami-boot.json
index 154a69851..64640b46d 100644
--- a/test/data/manifests/rhel_84-x86_64-ami-boot.json
+++ b/test/data/manifests/rhel_84-x86_64-ami-boot.json
@@ -3265,7 +3265,8 @@
             "legacy": "i386-pc",
             "uefi": {
               "vendor": "redhat"
-            }
+            },
+            "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.x86_64"
           }
         },
         {
@@ -9070,7 +9071,8 @@
   },
   "image-info": {
     "boot-environment": {
-      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 console=ttyS0,115200n8 console=tty0 net.ifnames=0 rd.blacklist=nouveau nvme_core.io_timeout=4294967295 crashkernel=auto"
+      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 console=ttyS0,115200n8 console=tty0 net.ifnames=0 rd.blacklist=nouveau nvme_core.io_timeout=4294967295 crashkernel=auto",
+      "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.x86_64"
     },
     "bootloader": "grub",
     "bootmenu": [
diff --git a/test/data/manifests/rhel_84-x86_64-openstack-boot.json b/test/data/manifests/rhel_84-x86_64-openstack-boot.json
index d7878d67e..4437d7b12 100644
--- a/test/data/manifests/rhel_84-x86_64-openstack-boot.json
+++ b/test/data/manifests/rhel_84-x86_64-openstack-boot.json
@@ -3504,7 +3504,8 @@
             "legacy": "i386-pc",
             "uefi": {
               "vendor": "redhat"
-            }
+            },
+            "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.x86_64"
           }
         },
         {
@@ -9646,7 +9647,8 @@
   },
   "image-info": {
     "boot-environment": {
-      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 ro net.ifnames=0"
+      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 ro net.ifnames=0",
+      "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.x86_64"
     },
     "bootloader": "grub",
     "bootmenu": [
diff --git a/test/data/manifests/rhel_84-x86_64-qcow2-boot.json b/test/data/manifests/rhel_84-x86_64-qcow2-boot.json
index 305100c57..6cf8a0d71 100644
--- a/test/data/manifests/rhel_84-x86_64-qcow2-boot.json
+++ b/test/data/manifests/rhel_84-x86_64-qcow2-boot.json
@@ -3438,7 +3438,8 @@
             "legacy": "i386-pc",
             "uefi": {
               "vendor": "redhat"
-            }
+            },
+            "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.x86_64"
           }
         },
         {
@@ -9509,7 +9510,8 @@
   },
   "image-info": {
     "boot-environment": {
-      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0 crashkernel=auto"
+      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0 crashkernel=auto",
+      "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.x86_64"
     },
     "bootloader": "grub",
     "bootmenu": [
diff --git a/test/data/manifests/rhel_84-x86_64-qcow2-customize.json b/test/data/manifests/rhel_84-x86_64-qcow2-customize.json
index 64993444a..d3a134489 100644
--- a/test/data/manifests/rhel_84-x86_64-qcow2-customize.json
+++ b/test/data/manifests/rhel_84-x86_64-qcow2-customize.json
@@ -3490,7 +3490,8 @@
             "legacy": "i386-pc",
             "uefi": {
               "vendor": "redhat"
-            }
+            },
+            "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.x86_64"
           }
         },
         {
@@ -9614,7 +9615,8 @@
   },
   "image-info": {
     "boot-environment": {
-      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0 crashkernel=auto debug"
+      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0 crashkernel=auto debug",
+      "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.x86_64"
     },
     "bootloader": "grub",
     "bootmenu": [
diff --git a/test/data/manifests/rhel_84-x86_64-vhd-boot.json b/test/data/manifests/rhel_84-x86_64-vhd-boot.json
index 3f9cd1f6e..0dd3cd959 100644
--- a/test/data/manifests/rhel_84-x86_64-vhd-boot.json
+++ b/test/data/manifests/rhel_84-x86_64-vhd-boot.json
@@ -3465,7 +3465,8 @@
             "legacy": "i386-pc",
             "uefi": {
               "vendor": "redhat"
-            }
+            },
+            "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.x86_64"
           }
         },
         {
@@ -9572,7 +9573,8 @@
   },
   "image-info": {
     "boot-environment": {
-      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 ro biosdevname=0 rootdelay=300 console=ttyS0 earlyprintk=ttyS0 net.ifnames=0"
+      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 ro biosdevname=0 rootdelay=300 console=ttyS0 earlyprintk=ttyS0 net.ifnames=0",
+      "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.x86_64"
     },
     "bootloader": "grub",
     "bootmenu": [
diff --git a/test/data/manifests/rhel_84-x86_64-vmdk-boot.json b/test/data/manifests/rhel_84-x86_64-vmdk-boot.json
index 2b8bda678..fba3a583c 100644
--- a/test/data/manifests/rhel_84-x86_64-vmdk-boot.json
+++ b/test/data/manifests/rhel_84-x86_64-vmdk-boot.json
@@ -3333,7 +3333,8 @@
             "legacy": "i386-pc",
             "uefi": {
               "vendor": "redhat"
-            }
+            },
+            "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.x86_64"
           }
         },
         {
@@ -9223,7 +9224,8 @@
   },
   "image-info": {
     "boot-environment": {
-      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 ro net.ifnames=0"
+      "kernelopts": "root=UUID=0194fdc2-fa2f-4cc0-81d3-ff12045b73c8 ro net.ifnames=0",
+      "saved_entry": "ffffffffffffffffffffffffffffffff-4.18.0-275.el8.x86_64"
     },
     "bootloader": "grub",
     "bootmenu": [