Repository: osbuild/osbuild-composer
Pull request #1667 (2021-08-24 18:44:46)

distro/rhel85: add support for rhel for edge raw images
- Refactor package sets
- installer build and os packages support for aarch64
- aarch64 support for boot iso mono, thus the anaconda based installer
- extract edge raw image pipelines
- add support for rhel for edge raw images

TODO:
 - [x] testing
 - [x] raw images need parent commit (needs to be enforced)

This pull request includes:

- [x] adequate testing for the new functionality or fixed issue
- [x] adequate documentation informing people about the change such as
  - [x] create a file in [news/unreleased](https://github.com/osbuild/osbuild-composer/tree/main/docs/news/unreleased) directory if this change should be mentioned in the release news
  - [ ] submit a PR for the [guides](https://github.com/osbuild/guides) repository if this PR changed any behavior described there: https://www.osbuild.org/guides/




Patch:
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 250cb7b99..0c5667389 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -4,8 +4,14 @@
     "dockerfile": "Dockerfile",
     "context": ".."
   },
+  "mounts": [
+    "source=osbuild-share,target=/root/.local/share,type=volume"
+  ],
+  "runArgs": [
+    "--privileged"
+  ],
   "extensions": [
     "laurenttreguier.rpm-spec",
     "golang.Go"
   ]
-}
+}
\ No newline at end of file
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 705a96931..aba080463 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -177,6 +177,28 @@ New OSTree:
       - RUNNER:
           - openstack/rhel-8.5-x86_64
 
+OSTree simplified installer:
+  stage: test
+  extends: OSTree
+  script:
+    - schutzbot/deploy.sh
+    - /usr/libexec/tests/osbuild-composer/ostree-simplified-installer.sh
+  parallel:
+    matrix:
+      - RUNNER:
+          - openstack/rhel-8.5-x86_64
+
+OSTree raw image:
+  stage: test
+  extends: OSTree
+  script:
+    - schutzbot/deploy.sh
+    - /usr/libexec/tests/osbuild-composer/ostree-raw-image.sh
+  parallel:
+    matrix:
+      - RUNNER:
+          - openstack/rhel-8.5-x86_64
+
 .INTEGRATION_TESTS: &INTEGRATION_TESTS
   SCRIPT:
     - koji.sh
diff --git a/Schutzfile b/Schutzfile
index 7e98040bd..0a9ac890e 100644
--- a/Schutzfile
+++ b/Schutzfile
@@ -39,19 +39,5 @@
         "commit": "35de3093a7b52569512bdc61d2105febbb9b0c7e"
       }
     }
-  },
-  "rhel-8.5": {
-    "dependencies": {
-      "osbuild": {
-        "commit": "ca3941feb67202f7165c7dde0ff12fae5601f0cf"
-      }
-    }
-  },
-  "rhel-9.0": {
-    "dependencies": {
-      "osbuild": {
-        "commit": "152b14a0d6c5deccfce2096308230f6d9067d23e"
-      }
-    }
   }
 }
diff --git a/docs/news/unreleased/rhel8.5-edge-raw-images.md b/docs/news/unreleased/rhel8.5-edge-raw-images.md
new file mode 100644
index 000000000..d8d40f3e5
--- /dev/null
+++ b/docs/news/unreleased/rhel8.5-edge-raw-images.md
@@ -0,0 +1,10 @@
+# Add RHEL for Edge Raw Images for 8.5
+
+OSBuild Composer can now build the RHEL 8.5 Raw Images. This images are
+compressed raw images, i.e. a file that has a partition layout with an
+deployed OSTree commit in it. It can be used to flash onto a hard drive
+or booted in a virtual machine. An existing OSTree commit needs to
+be provided.
+The following image new types are supported: edge-raw-image.
+
+Relevant PR: https://github.com/osbuild/osbuild-composer/pull/1667
diff --git a/docs/news/unreleased/rhel8.5-edge-simplified-installer.md b/docs/news/unreleased/rhel8.5-edge-simplified-installer.md
new file mode 100644
index 000000000..560c77a0e
--- /dev/null
+++ b/docs/news/unreleased/rhel8.5-edge-simplified-installer.md
@@ -0,0 +1,12 @@
+# Add a new Simplified Installer for RHEL for Edge 8.5
+
+OSBuild Composer can now build the RHEL 8.5 for Edge Simplified Installer.
+This installer is optimized for unattended installation to a device, which
+can be specified via a new blueprint option, `installation_device`. As for
+the existing RHEL for Edge installer, an existing OSTree commit needs to
+be provided. A raw image will be created with that commit deployed in it
+and the installer will flash this raw image to the specified installation
+device.
+The following image new types are supported: edge-simplified-installer.
+
+Relevant PR: https://github.com/osbuild/osbuild-composer/pull/1654
\ No newline at end of file
diff --git a/internal/blueprint/customizations.go b/internal/blueprint/customizations.go
index e6b00db5e..27828edb1 100644
--- a/internal/blueprint/customizations.go
+++ b/internal/blueprint/customizations.go
@@ -1,16 +1,22 @@
 package blueprint
 
+import (
+	"fmt"
+	"reflect"
+)
+
 type Customizations struct {
-	Hostname   *string                   `json:"hostname,omitempty" toml:"hostname,omitempty"`
-	Kernel     *KernelCustomization      `json:"kernel,omitempty" toml:"kernel,omitempty"`
-	SSHKey     []SSHKeyCustomization     `json:"sshkey,omitempty" toml:"sshkey,omitempty"`
-	User       []UserCustomization       `json:"user,omitempty" toml:"user,omitempty"`
-	Group      []GroupCustomization      `json:"group,omitempty" toml:"group,omitempty"`
-	Timezone   *TimezoneCustomization    `json:"timezone,omitempty" toml:"timezone,omitempty"`
-	Locale     *LocaleCustomization      `json:"locale,omitempty" toml:"locale,omitempty"`
-	Firewall   *FirewallCustomization    `json:"firewall,omitempty" toml:"firewall,omitempty"`
-	Services   *ServicesCustomization    `json:"services,omitempty" toml:"services,omitempty"`
-	Filesystem []FilesystemCustomization `json:"filesystem,omitempty" toml:"filesystem,omitempty"`
+	Hostname           *string                   `json:"hostname,omitempty" toml:"hostname,omitempty"`
+	Kernel             *KernelCustomization      `json:"kernel,omitempty" toml:"kernel,omitempty"`
+	SSHKey             []SSHKeyCustomization     `json:"sshkey,omitempty" toml:"sshkey,omitempty"`
+	User               []UserCustomization       `json:"user,omitempty" toml:"user,omitempty"`
+	Group              []GroupCustomization      `json:"group,omitempty" toml:"group,omitempty"`
+	Timezone           *TimezoneCustomization    `json:"timezone,omitempty" toml:"timezone,omitempty"`
+	Locale             *LocaleCustomization      `json:"locale,omitempty" toml:"locale,omitempty"`
+	Firewall           *FirewallCustomization    `json:"firewall,omitempty" toml:"firewall,omitempty"`
+	Services           *ServicesCustomization    `json:"services,omitempty" toml:"services,omitempty"`
+	Filesystem         []FilesystemCustomization `json:"filesystem,omitempty" toml:"filesystem,omitempty"`
+	InstallationDevice string                    `json:"installation_device,omitempty" toml:"installation_device,omitempty"`
 }
 
 type KernelCustomization struct {
@@ -78,6 +84,53 @@ func (e *CustomizationError) Error() string {
 	return e.Message
 }
 
+//CheckCustomizations returns an error of type `CustomizationError`
+//if `c` has any customizations not specified in `allowed`
+func (c *Customizations) CheckAllowed(allowed ...string) error {
+	if c == nil {
+		return nil
+	}
+
+	allowMap := make(map[string]bool)
+
+	for _, a := range allowed {
+		allowMap[a] = true
+	}
+
+	t := reflect.TypeOf(*c)
+	v := reflect.ValueOf(*c)
+
+	for i := 0; i < t.NumField(); i++ {
+
+		empty := false
+		field := v.Field(i)
+
+		switch field.Kind() {
+		case reflect.String:
+			if field.String() == "" {
+				empty = true
+			}
+		case reflect.Array, reflect.Slice:
+			if field.Len() == 0 {
+				empty = true
+			}
+		case reflect.Ptr:
+			if field.IsNil() {
+				empty = true
+			}
+		default:
+			panic(fmt.Sprintf("unhandled customization field type %s, %s", v.Kind(), t.Field(i).Name))
+
+		}
+
+		if !empty && !allowMap[t.Field(i).Name] {
+			return &CustomizationError{fmt.Sprintf("'%s' is not allowed", t.Field(i).Name)}
+		}
+	}
+
+	return nil
+}
+
 func (c *Customizations) GetHostname() *string {
 	if c == nil {
 		return nil
@@ -216,3 +269,11 @@ func (c *Customizations) GetFilesystemsMinSize() uint64 {
 	}
 	return uint64(agg)
 }
+
+func (c *Customizations) GetInstallationDevice() string {
+	defaultDevice := "/dev/sda"
+	if c == nil || c.InstallationDevice == "" {
+		return defaultDevice
+	}
+	return c.InstallationDevice
+}
diff --git a/internal/distro/rhel84/distro_v2.go b/internal/distro/rhel84/distro_v2.go
index 707a41e52..6c30b0e29 100644
--- a/internal/distro/rhel84/distro_v2.go
+++ b/internal/distro/rhel84/distro_v2.go
@@ -780,7 +780,7 @@ func (t *imageTypeS2) xorrisofsStageOptions() *osbuild.XorrisofsStageOptions {
 		Filename: t.Filename(),
 		VolID:    fmt.Sprintf("RHEL-8-4-0-BaseOS-%s", t.Arch().Name()),
 		SysID:    "LINUX",
-		Boot: osbuild.XorrisofsBoot{
+		Boot: &osbuild.XorrisofsBoot{
 			Image:   "isolinux/isolinux.bin",
 			Catalog: "isolinux/boot.cat",
 		},
diff --git a/internal/distro/rhel85/distro.go b/internal/distro/rhel85/distro.go
index a0d6468ab..be1a00eaf 100644
--- a/internal/distro/rhel85/distro.go
+++ b/internal/distro/rhel85/distro.go
@@ -28,21 +28,9 @@ const (
 	// build package set name
 	buildPkgsKey = "build"
 
-	// 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"
 
-	// edge os image package set name
-	edgePkgsKey = "edge"
-
-	// edge build package set name
-	edgeBuildPkgsKey = "build.edge"
-
 	// container package set name
 	containerPkgsKey = "container"
 
@@ -64,7 +52,6 @@ type distribution struct {
 	modulePlatformID string
 	ostreeRef        string
 	arches           map[string]distro.Arch
-	packageSets      map[string]rpmmd.PackageSet
 }
 
 func (d *distribution) Name() string {
@@ -118,7 +105,6 @@ type architecture struct {
 	name             string
 	imageTypes       map[string]distro.ImageType
 	imageTypeAliases map[string]string
-	packageSets      map[string]rpmmd.PackageSet
 	legacy           string
 	bootType         distro.BootType
 }
@@ -177,13 +163,15 @@ func (a *architecture) Distro() distro.Distro {
 
 type pipelinesFunc func(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec, rng *rand.Rand) ([]osbuild.Pipeline, error)
 
+type packageSetFunc func(t *imageType) rpmmd.PackageSet
+
 type imageType struct {
 	arch             *architecture
 	name             string
 	nameAliases      []string
 	filename         string
 	mimeType         string
-	packageSets      map[string]rpmmd.PackageSet
+	packageSets      map[string]packageSetFunc
 	enabledServices  []string
 	disabledServices []string
 	defaultTarget    string
@@ -239,16 +227,24 @@ func (t *imageType) Size(size uint64) uint64 {
 	return size
 }
 
+func (t *imageType) getPackages(name string) rpmmd.PackageSet {
+	getter := t.packageSets[name]
+	if getter == nil {
+		return rpmmd.PackageSet{}
+	}
+
+	return getter(t)
+}
+
 func (t *imageType) PackageSets(bp blueprint.Blueprint) map[string]rpmmd.PackageSet {
 	// merge package sets that appear in the image type with the package sets
 	// of the same name from the distro and arch
 	mergedSets := make(map[string]rpmmd.PackageSet)
 
 	imageSets := t.packageSets
-	archSets := t.arch.packageSets
-	distroSets := t.arch.distro.packageSets
+
 	for name := range imageSets {
-		mergedSets[name] = imageSets[name].Append(archSets[name]).Append(distroSets[name])
+		mergedSets[name] = t.getPackages(name)
 	}
 
 	if _, hasPackages := imageSets[osPkgsKey]; !hasPackages {
@@ -256,40 +252,9 @@ func (t *imageType) PackageSets(bp blueprint.Blueprint) map[string]rpmmd.Package
 		mergedSets[osPkgsKey] = rpmmd.PackageSet{}
 	}
 
-	// build is usually not defined on the image type
-	// handle it explicitly when it's not
+	// every image type must define a 'build' package set
 	if _, hasBuild := imageSets[buildPkgsKey]; !hasBuild {
-		mergedSets[buildPkgsKey] = archSets[buildPkgsKey].Append(distroSets[buildPkgsKey])
-	}
-
-	// package sets from flags
-	if t.bootable {
-		var addLegacyBootPkg bool
-		var addUEFIBootPkg bool
-
-		switch bt := t.getBootType(); bt {
-		case distro.LegacyBootType:
-			addLegacyBootPkg = true
-		case distro.UEFIBootType:
-			addUEFIBootPkg = true
-		case distro.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
-		mergedSets[buildPkgsKey] = mergedSets[buildPkgsKey].Append(archSets[edgeBuildPkgsKey]).Append(distroSets[edgeBuildPkgsKey])
-		mergedSets[osPkgsKey] = mergedSets[osPkgsKey].Append(archSets[edgePkgsKey]).Append(distroSets[edgePkgsKey])
+		panic(fmt.Sprintf("'%s' image type has no '%s' package set defined", t.name, buildPkgsKey))
 	}
 
 	// blueprint packages
@@ -445,12 +410,21 @@ func (t *imageType) checkOptions(customizations *blueprint.Customizations, optio
 		if options.OSTree.Parent == "" {
 			return fmt.Errorf("boot ISO image type %q requires specifying a URL from which to retrieve the OSTree commit", t.name)
 		}
-		if customizations != nil {
+
+		if t.name == "edge-simplified-installer" {
+			if err := customizations.CheckAllowed("InstallationDevice"); err != nil {
+				return fmt.Errorf("boot ISO image type %q contains unsupported blueprint customizations: %v", t.name, err)
+			}
+		} else if customizations != nil {
 			return fmt.Errorf("boot ISO image type %q does not support blueprint customizations", t.name)
 		}
 	}
 
-	if kernelOpts := customizations.GetKernel(); kernelOpts.Append != "" && t.rpmOstree {
+	if t.name == "edge-raw-image" && options.OSTree.Parent == "" {
+		return fmt.Errorf("edge raw images require specifying a URL from which to retrieve the OSTree commit")
+	}
+
+	if kernelOpts := customizations.GetKernel(); kernelOpts.Append != "" && t.rpmOstree && (!t.bootable || t.bootISO) {
 		return fmt.Errorf("kernel boot parameter customizations are not supported for ostree types")
 	}
 
@@ -497,52 +471,31 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
 		name:             name,
 		modulePlatformID: modulePlatformID,
 		ostreeRef:        ostreeRef,
-		packageSets: map[string]rpmmd.PackageSet{
-			buildPkgsKey:     distroBuildPackageSet(),
-			edgeBuildPkgsKey: edgeBuildPackageSet(),
-		},
 	}
 
 	// Architecture definitions
 	x86_64 := architecture{
-		name:   distro.X86_64ArchName,
-		distro: rd,
-		packageSets: map[string]rpmmd.PackageSet{
-			buildPkgsKey:      x8664BuildPackageSet(),
-			bootLegacyPkgsKey: x8664LegacyBootPackageSet(),
-			bootUEFIPkgsKey:   x8664UEFIBootPackageSet(),
-			edgePkgsKey:       x8664EdgeCommitPackageSet(),
-		},
+		name:     distro.X86_64ArchName,
+		distro:   rd,
 		legacy:   "i386-pc",
 		bootType: distro.HybridBootType,
 	}
 
 	aarch64 := architecture{
-		name:   distro.Aarch64ArchName,
-		distro: rd,
-		packageSets: map[string]rpmmd.PackageSet{
-			bootUEFIPkgsKey: aarch64UEFIBootPackageSet(),
-			edgePkgsKey:     aarch64EdgeCommitPackageSet(),
-		},
+		name:     distro.Aarch64ArchName,
+		distro:   rd,
 		bootType: distro.UEFIBootType,
 	}
 
 	ppc64le := architecture{
-		distro: rd,
-		name:   distro.Ppc64leArchName,
-		packageSets: map[string]rpmmd.PackageSet{
-			bootLegacyPkgsKey: ppc64leLegacyBootPackageSet(),
-			buildPkgsKey:      ppc64leBuildPackageSet(),
-		},
+		distro:   rd,
+		name:     distro.Ppc64leArchName,
 		legacy:   "powerpc-ieee1275",
 		bootType: distro.LegacyBootType,
 	}
 	s390x := architecture{
-		distro: rd,
-		name:   distro.S390xArchName,
-		packageSets: map[string]rpmmd.PackageSet{
-			bootLegacyPkgsKey: s390xLegacyBootPackageSet(),
-		},
+		distro:   rd,
+		name:     distro.S390xArchName,
 		bootType: distro.LegacyBootType,
 	}
 
@@ -557,24 +510,29 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
 		nameAliases: []string{"rhel-edge-commit"},
 		filename:    "commit.tar",
 		mimeType:    "application/x-tar",
-		packageSets: map[string]rpmmd.PackageSet{
-			buildPkgsKey: edgeBuildPackageSet(),
-			osPkgsKey:    edgeCommitPackageSet(),
+		packageSets: map[string]packageSetFunc{
+			buildPkgsKey: edgeBuildPackageSet,
+			osPkgsKey:    edgeCommitPackageSet,
 		},
 		enabledServices: edgeServices,
 		rpmOstree:       true,
 		pipelines:       edgeCommitPipelines,
 		exports:         []string{"commit-archive"},
 	}
+
 	edgeOCIImgType := imageType{
 		name:        "edge-container",
 		nameAliases: []string{"rhel-edge-container"},
 		filename:    "container.tar",
 		mimeType:    "application/x-tar",
-		packageSets: map[string]rpmmd.PackageSet{
-			buildPkgsKey:     edgeBuildPackageSet(),
-			osPkgsKey:        edgeCommitPackageSet(),
-			containerPkgsKey: {Include: []string{"nginx"}},
+		packageSets: map[string]packageSetFunc{
+			buildPkgsKey: edgeBuildPackageSet,
+			osPkgsKey:    edgeCommitPackageSet,
+			containerPkgsKey: func(t *imageType) rpmmd.PackageSet {
+				return rpmmd.PackageSet{
+					Include: []string{"nginx"},
+				}
+			},
 		},
 		enabledServices: edgeServices,
 		rpmOstree:       true,
@@ -582,12 +540,30 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
 		pipelines:       edgeContainerPipelines,
 		exports:         []string{"container"},
 	}
+
+	edgeRawImgType := imageType{
+		name:        "edge-raw-image",
+		nameAliases: []string{"rhel-edge-raw-image"},
+		filename:    "image.raw.xz",
+		mimeType:    "application/xz",
+		packageSets: map[string]packageSetFunc{
+			buildPkgsKey: edgeRawImageBuildPackageSet,
+		},
+		defaultSize:         10 * GigaByte,
+		rpmOstree:           true,
+		bootable:            true,
+		bootISO:             false,
+		pipelines:           edgeRawImagePipelines,
+		exports:             []string{"archive"},
+		basePartitionTables: edgeBasePartitionTables,
+	}
+
 	edgeInstallerImgType := imageType{
 		name:        "edge-installer",
 		nameAliases: []string{"rhel-edge-installer"},
 		filename:    "installer.iso",
 		mimeType:    "application/x-iso9660-image",
-		packageSets: map[string]rpmmd.PackageSet{
+		packageSets: map[string]packageSetFunc{
 			// TODO: non-arch-specific package set handling for installers
 			// This image type requires build packages for installers and
 			// ostree/edge.  For now we only have x86-64 installer build
@@ -595,9 +571,9 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
 			// for other architectures, this will need to be moved to the
 			// architecture and the merging will happen in the PackageSets()
 			// method like the other sets.
-			buildPkgsKey:     x8664InstallerBuildPackageSet().Append(edgeBuildPackageSet()),
-			osPkgsKey:        edgeCommitPackageSet(),
-			installerPkgsKey: edgeInstallerPackageSet(),
+			buildPkgsKey:     edgeInstallerBuildPackageSet,
+			osPkgsKey:        edgeCommitPackageSet,
+			installerPkgsKey: edgeInstallerPackageSet,
 		},
 		enabledServices: edgeServices,
 		rpmOstree:       true,
@@ -606,14 +582,41 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
 		exports:         []string{"bootiso"},
 	}
 
+	edgeSimplifiedInstallerImgType := imageType{
+		name:        "edge-simplified-installer",
+		nameAliases: []string{"rhel-edge-simplified-installer"},
+		filename:    "simplified-installer.iso",
+		mimeType:    "application/x-iso9660-image",
+		packageSets: map[string]packageSetFunc{
+			// TODO: non-arch-specific package set handling for installers
+			// This image type requires build packages for installers and
+			// ostree/edge.  For now we only have x86-64 installer build
+			// package sets defined.  When we add installer build package sets
+			// for other architectures, this will need to be moved to the
+			// architecture and the merging will happen in the PackageSets()
+			// method like the other sets.
+			buildPkgsKey:     edgeInstallerBuildPackageSet,
+			installerPkgsKey: edgeSimplifiedInstallerPackageSet,
+		},
+		enabledServices:     edgeServices,
+		defaultSize:         10 * GigaByte,
+		rpmOstree:           true,
+		bootable:            true,
+		bootISO:             true,
+		pipelines:           edgeSimplifiedInstallerPipelines,
+		exports:             []string{"bootiso"},
+		basePartitionTables: edgeBasePartitionTables,
+	}
+
 	qcow2ImgType := imageType{
 		name:          "qcow2",
 		filename:      "disk.qcow2",
 		mimeType:      "application/x-qemu-disk",
 		defaultTarget: "multi-user.target",
 		kernelOptions: "console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0 crashkernel=auto",
-		packageSets: map[string]rpmmd.PackageSet{
-			osPkgsKey: qcow2CommonPackageSet(),
+		packageSets: map[string]packageSetFunc{
+			buildPkgsKey: distroBuildPackageSet,
+			osPkgsKey:    qcow2CommonPackageSet,
 		},
 		bootable:            true,
 		defaultSize:         10 * GigaByte,
@@ -626,8 +629,9 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
 		name:     "vhd",
 		filename: "disk.vhd",
 		mimeType: "application/x-vhd",
-		packageSets: map[string]rpmmd.PackageSet{
-			osPkgsKey: vhdCommonPackageSet(),
+		packageSets: map[string]packageSetFunc{
+			buildPkgsKey: distroBuildPackageSet,
+			osPkgsKey:    vhdCommonPackageSet,
 		},
 		enabledServices: []string{
 			"sshd",
@@ -646,8 +650,9 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
 		name:     "vmdk",
 		filename: "disk.vmdk",
 		mimeType: "application/x-vmdk",
-		packageSets: map[string]rpmmd.PackageSet{
-			osPkgsKey: vmdkCommonPackageSet(),
+		packageSets: map[string]packageSetFunc{
+			buildPkgsKey: distroBuildPackageSet,
+			osPkgsKey:    vmdkCommonPackageSet,
 		},
 		kernelOptions:       "ro net.ifnames=0",
 		bootable:            true,
@@ -661,8 +666,9 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
 		name:     "openstack",
 		filename: "disk.qcow2",
 		mimeType: "application/x-qemu-disk",
-		packageSets: map[string]rpmmd.PackageSet{
-			osPkgsKey: openstackCommonPackageSet(),
+		packageSets: map[string]packageSetFunc{
+			buildPkgsKey: distroBuildPackageSet,
+			osPkgsKey:    openstackCommonPackageSet,
 		},
 		kernelOptions:       "ro net.ifnames=0",
 		bootable:            true,
@@ -689,9 +695,9 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
 		name:     "ami",
 		filename: "image.raw",
 		mimeType: "application/octet-stream",
-		packageSets: map[string]rpmmd.PackageSet{
-			buildPkgsKey: ec2BuildPackageSet(),
-			osPkgsKey:    ec2CommonPackageSet(),
+		packageSets: map[string]packageSetFunc{
+			buildPkgsKey: ec2BuildPackageSet,
+			osPkgsKey:    ec2CommonPackageSet,
 		},
 		defaultTarget:       "multi-user.target",
 		enabledServices:     ec2EnabledServices,
@@ -708,9 +714,9 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
 		name:     "ami",
 		filename: "image.raw",
 		mimeType: "application/octet-stream",
-		packageSets: map[string]rpmmd.PackageSet{
-			buildPkgsKey: ec2BuildPackageSet(),
-			osPkgsKey:    ec2CommonPackageSet(),
+		packageSets: map[string]packageSetFunc{
+			buildPkgsKey: ec2BuildPackageSet,
+			osPkgsKey:    ec2CommonPackageSet,
 		},
 		defaultTarget:       "multi-user.target",
 		enabledServices:     ec2EnabledServices,
@@ -726,9 +732,9 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
 		name:     "ec2",
 		filename: "image.raw.xz",
 		mimeType: "application/xz",
-		packageSets: map[string]rpmmd.PackageSet{
-			buildPkgsKey: ec2BuildPackageSet(),
-			osPkgsKey:    rhelEc2PackageSet(),
+		packageSets: map[string]packageSetFunc{
+			buildPkgsKey: ec2BuildPackageSet,
+			osPkgsKey:    rhelEc2PackageSet,
 		},
 		defaultTarget:       "multi-user.target",
 		enabledServices:     ec2EnabledServices,
@@ -745,9 +751,9 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
 		name:     "ec2",
 		filename: "image.raw.xz",
 		mimeType: "application/xz",
-		packageSets: map[string]rpmmd.PackageSet{
-			buildPkgsKey: ec2BuildPackageSet(),
-			osPkgsKey:    rhelEc2PackageSet(),
+		packageSets: map[string]packageSetFunc{
+			buildPkgsKey: ec2BuildPackageSet,
+			osPkgsKey:    rhelEc2PackageSet,
 		},
 		defaultTarget:       "multi-user.target",
 		enabledServices:     ec2EnabledServices,
@@ -763,9 +769,9 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
 		name:     "ec2-ha",
 		filename: "image.raw.xz",
 		mimeType: "application/xz",
-		packageSets: map[string]rpmmd.PackageSet{
-			buildPkgsKey: ec2BuildPackageSet(),
-			osPkgsKey:    rhelEc2HaPackageSet(),
+		packageSets: map[string]packageSetFunc{
+			buildPkgsKey: ec2BuildPackageSet,
+			osPkgsKey:    rhelEc2HaPackageSet,
 		},
 		defaultTarget:       "multi-user.target",
 		enabledServices:     ec2EnabledServices,
@@ -782,10 +788,13 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
 		name:     "tar",
 		filename: "root.tar.xz",
 		mimeType: "application/x-tar",
-		packageSets: map[string]rpmmd.PackageSet{
-			osPkgsKey: {
-				Include: []string{"policycoreutils", "selinux-policy-targeted"},
-				Exclude: []string{"rng-tools"},
+		packageSets: map[string]packageSetFunc{
+			buildPkgsKey: distroBuildPackageSet,
+			osPkgsKey: func(t *imageType) rpmmd.PackageSet {
+				return rpmmd.PackageSet{
+					Include: []string{"policycoreutils", "selinux-policy-targeted"},
+					Exclude: []string{"rng-tools"},
+				}
 			},
 		},
 		pipelines: tarPipelines,
@@ -795,10 +804,10 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
 		name:     "image-installer",
 		filename: "installer.iso",
 		mimeType: "application/x-iso9660-image",
-		packageSets: map[string]rpmmd.PackageSet{
-			buildPkgsKey:     x8664InstallerBuildPackageSet(),
-			osPkgsKey:        bareMetalPackageSet(),
-			installerPkgsKey: installerPackageSet(),
+		packageSets: map[string]packageSetFunc{
+			buildPkgsKey:     anacondaBuildPackageSet,
+			osPkgsKey:        bareMetalPackageSet,
+			installerPkgsKey: anacondaPackageSet,
 		},
 		rpmOstree: false,
 		bootISO:   true,
@@ -807,8 +816,8 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
 		exports:   []string{"bootiso"},
 	}
 
-	x86_64.addImageTypes(qcow2ImgType, vhdImgType, vmdkImgType, openstackImgType, amiImgTypeX86_64, ec2ImgTypeX86_64, ec2HaImgTypeX86_64, tarImgType, tarInstallerImgTypeX86_64, edgeCommitImgType, edgeInstallerImgType, edgeOCIImgType)
-	aarch64.addImageTypes(qcow2ImgType, openstackImgType, amiImgTypeAarch64, ec2ImgTypeAarch64, tarImgType, edgeCommitImgType, edgeOCIImgType)
+	x86_64.addImageTypes(qcow2ImgType, vhdImgType, vmdkImgType, openstackImgType, amiImgTypeX86_64, ec2ImgTypeX86_64, ec2HaImgTypeX86_64, tarImgType, tarInstallerImgTypeX86_64, edgeCommitImgType, edgeInstallerImgType, edgeOCIImgType, edgeRawImgType, edgeSimplifiedInstallerImgType)
+	aarch64.addImageTypes(qcow2ImgType, openstackImgType, amiImgTypeAarch64, ec2ImgTypeAarch64, tarImgType, edgeCommitImgType, edgeInstallerImgType, edgeOCIImgType, edgeRawImgType, edgeSimplifiedInstallerImgType)
 	ppc64le.addImageTypes(qcow2ImgType, tarImgType)
 	s390x.addImageTypes(qcow2ImgType, tarImgType)
 
diff --git a/internal/distro/rhel85/package_sets.go b/internal/distro/rhel85/package_sets.go
index b85278cf1..b7bd76723 100644
--- a/internal/distro/rhel85/package_sets.go
+++ b/internal/distro/rhel85/package_sets.go
@@ -2,13 +2,18 @@ package rhel85
 
 // This file defines package sets that are used by more than one image type.
 
-import "github.com/osbuild/osbuild-composer/internal/rpmmd"
+import (
+	"fmt"
+
+	"github.com/osbuild/osbuild-composer/internal/distro"
+	"github.com/osbuild/osbuild-composer/internal/rpmmd"
+)
 
 // BUILD PACKAGE SETS
 
 // distro-wide build package set
-func distroBuildPackageSet() rpmmd.PackageSet {
-	return rpmmd.PackageSet{
+func distroBuildPackageSet(t *imageType) rpmmd.PackageSet {
+	ps := rpmmd.PackageSet{
 		Include: []string{
 			"dnf", "dosfstools", "e2fsprogs", "glibc", "lorax-templates-generic",
 			"lorax-templates-rhel", "policycoreutils", "python36",
@@ -16,70 +21,211 @@ func distroBuildPackageSet() rpmmd.PackageSet {
 			"tar", "xfsprogs", "xz",
 		},
 	}
+
+	switch t.arch.Name() {
+
+	case distro.X86_64ArchName:
+		ps = ps.Append(x8664BuildPackageSet(t))
+
+	case distro.Ppc64leArchName:
+		ps = ps.Append(ppc64leBuildPackageSet(t))
+	}
+
+	return ps
 }
 
 // x86_64 build package set
-func x8664BuildPackageSet() rpmmd.PackageSet {
+func x8664BuildPackageSet(t *imageType) rpmmd.PackageSet {
 	return rpmmd.PackageSet{
 		Include: []string{"grub2-pc"},
 	}
 }
 
 // ppc64le build package set
-func ppc64leBuildPackageSet() rpmmd.PackageSet {
+func ppc64leBuildPackageSet(t *imageType) rpmmd.PackageSet {
 	return rpmmd.PackageSet{
 		Include: []string{"grub2-ppc64le", "grub2-ppc64le-modules"},
 	}
 }
 
 // common ec2 image build package set
-func ec2BuildPackageSet() rpmmd.PackageSet {
-	return rpmmd.PackageSet{
-		Include: []string{"python3-pyyaml"},
-	}
+func ec2BuildPackageSet(t *imageType) rpmmd.PackageSet {
+	return distroBuildPackageSet(t).Append(
+		rpmmd.PackageSet{
+			Include: []string{"python3-pyyaml"},
+		})
 }
 
 // common edge image build package set
-func edgeBuildPackageSet() rpmmd.PackageSet {
-	return rpmmd.PackageSet{
-		Include: []string{"rpm-ostree"},
-		Exclude: nil,
+func edgeBuildPackageSet(t *imageType) rpmmd.PackageSet {
+	return distroBuildPackageSet(t).Append(
+		rpmmd.PackageSet{
+			Include: []string{"rpm-ostree"},
+			Exclude: nil,
+		})
+}
+
+func edgeRawImageBuildPackageSet(t *imageType) rpmmd.PackageSet {
+	return edgeBuildPackageSet(t).Append(
+		bootPackageSet(t),
+	)
+}
+
+// installer boot package sets, needed for booting and
+// also in the build host
+
+func anacondaBootPackageSet(t *imageType) rpmmd.PackageSet {
+	ps := rpmmd.PackageSet{}
+
+	grubCommon := rpmmd.PackageSet{
+		Include: []string{
+			"grub2-tools",
+			"grub2-tools-extra",
+			"grub2-tools-minimal",
+		},
+	}
+
+	efiCommon := rpmmd.PackageSet{
+		Include: []string{
+			"efibootmgr",
+		},
 	}
+
+	switch t.arch.Name() {
+	case distro.X86_64ArchName:
+		ps = ps.Append(grubCommon)
+		ps = ps.Append(efiCommon)
+		ps = ps.Append(rpmmd.PackageSet{
+			Include: []string{
+				"grub2-efi-ia32-cdboot",
+				"grub2-efi-x64",
+				"grub2-efi-x64-cdboot",
+				"grub2-pc",
+				"grub2-pc-modules",
+				"shim-ia32",
+				"shim-x64",
+				"syslinux",
+				"syslinux-nonlinux",
+			},
+		})
+	case distro.Aarch64ArchName:
+		ps = ps.Append(grubCommon)
+		ps = ps.Append(efiCommon)
+		ps = ps.Append(rpmmd.PackageSet{
+			Include: []string{
+				"grub2-efi-aa64-cdboot",
+				"grub2-efi-aa64",
+				"shim-aa64",
+			},
+		})
+
+	default:
+		panic(fmt.Sprintf("unsupported arch: %s", t.arch.Name()))
+	}
+
+	return ps
 }
 
-// x86_64 installer ISO build package set
-// TODO: separate into common installer and arch specific sets
-func x8664InstallerBuildPackageSet() rpmmd.PackageSet {
-	return rpmmd.PackageSet{
+func installerBuildPackageSet(t *imageType) rpmmd.PackageSet {
+	return distroBuildPackageSet(t).Append(
+		rpmmd.PackageSet{
+			Include: []string{
+				"genisoimage",
+				"isomd5sum",
+				"xorriso",
+			},
+		})
+}
+
+func anacondaBuildPackageSet(t *imageType) rpmmd.PackageSet {
+	ps := rpmmd.PackageSet{
 		Include: []string{
-			"efibootmgr", "genisoimage", "grub2-efi-ia32-cdboot",
-			"grub2-efi-x64", "grub2-efi-x64-cdboot", "grub2-pc",
-			"grub2-pc-modules", "grub2-tools", "grub2-tools-efi",
-			"grub2-tools-extra", "grub2-tools-minimal", "isomd5sum",
-			"rpm-ostree", "shim-ia32", "shim-x64", "squashfs-tools",
-			"syslinux", "syslinux-nonlinux", "xorriso",
+			"squashfs-tools",
 		},
 	}
+
+	ps = ps.Append(installerBuildPackageSet(t))
+	ps = ps.Append(anacondaBootPackageSet(t))
+
+	return ps
+}
+
+func edgeInstallerBuildPackageSet(t *imageType) rpmmd.PackageSet {
+	return anacondaBuildPackageSet(t).Append(
+		edgeBuildPackageSet(t),
+	)
 }
 
 // BOOT PACKAGE SETS
 
+func bootPackageSet(t *imageType) rpmmd.PackageSet {
+	if !t.bootable {
+		return rpmmd.PackageSet{}
+	}
+
+	var addLegacyBootPkg bool
+	var addUEFIBootPkg bool
+
+	switch bt := t.getBootType(); bt {
+	case distro.LegacyBootType:
+		addLegacyBootPkg = true
+	case distro.UEFIBootType:
+		addUEFIBootPkg = true
+	case distro.HybridBootType:
+		addLegacyBootPkg = true
+		addUEFIBootPkg = true
+	default:
+		panic(fmt.Sprintf("unsupported boot type: %q", bt))
+	}
+
+	ps := rpmmd.PackageSet{}
+
+	switch t.arch.Name() {
+	case distro.X86_64ArchName:
+		if addLegacyBootPkg {
+			ps = ps.Append(x8664LegacyBootPackageSet(t))
+		}
+		if addUEFIBootPkg {
+			ps = ps.Append(x8664UEFIBootPackageSet(t))
+		}
+
+	case distro.Aarch64ArchName:
+		ps = ps.Append(aarch64UEFIBootPackageSet(t))
+
+	case distro.Ppc64leArchName:
+		ps = ps.Append(ppc64leLegacyBootPackageSet(t))
+
+	case distro.S390xArchName:
+		ps = ps.Append(s390xLegacyBootPackageSet(t))
+
+	default:
+		panic(fmt.Sprintf("unsupported boot arch: %s", t.arch.Name()))
+	}
+
+	return ps
+}
+
 // x86_64 Legacy arch-specific boot package set
-func x8664LegacyBootPackageSet() rpmmd.PackageSet {
+func x8664LegacyBootPackageSet(t *imageType) rpmmd.PackageSet {
 	return rpmmd.PackageSet{
 		Include: []string{"dracut-config-generic", "grub2-pc"},
 	}
 }
 
 // x86_64 UEFI arch-specific boot package set
-func x8664UEFIBootPackageSet() rpmmd.PackageSet {
+func x8664UEFIBootPackageSet(t *imageType) rpmmd.PackageSet {
 	return rpmmd.PackageSet{
-		Include: []string{"dracut-config-generic", "grub2-efi-x64", "shim-x64"},
+		Include: []string{
+			"dracut-config-generic",
+			"efibootmgr",
+			"grub2-efi-x64",
+			"shim-x64",
+		},
 	}
 }
 
 // aarch64 UEFI arch-specific boot package set
-func aarch64UEFIBootPackageSet() rpmmd.PackageSet {
+func aarch64UEFIBootPackageSet(t *imageType) rpmmd.PackageSet {
 	return rpmmd.PackageSet{
 		Include: []string{
 			"dracut-config-generic", "efibootmgr", "grub2-efi-aa64",
@@ -89,7 +235,7 @@ func aarch64UEFIBootPackageSet() rpmmd.PackageSet {
 }
 
 // ppc64le Legacy arch-specific boot package set
-func ppc64leLegacyBootPackageSet() rpmmd.PackageSet {
+func ppc64leLegacyBootPackageSet(t *imageType) rpmmd.PackageSet {
 	return rpmmd.PackageSet{
 		Include: []string{
 			"dracut-config-generic", "powerpc-utils", "grub2-ppc64le",
@@ -99,7 +245,7 @@ func ppc64leLegacyBootPackageSet() rpmmd.PackageSet {
 }
 
 // s390x Legacy arch-specific boot package set
-func s390xLegacyBootPackageSet() rpmmd.PackageSet {
+func s390xLegacyBootPackageSet(t *imageType) rpmmd.PackageSet {
 	return rpmmd.PackageSet{
 		Include: []string{"dracut-config-generic", "s390utils-base"},
 	}
@@ -107,7 +253,7 @@ func s390xLegacyBootPackageSet() rpmmd.PackageSet {
 
 // OS package sets
 
-func qcow2CommonPackageSet() rpmmd.PackageSet {
+func qcow2CommonPackageSet(t *imageType) rpmmd.PackageSet {
 	return rpmmd.PackageSet{
 		Include: []string{
 			"@core", "authselect-compat", "chrony", "cloud-init",
@@ -133,10 +279,10 @@ func qcow2CommonPackageSet() rpmmd.PackageSet {
 			"libertas-usb8388-firmware", "nss", "plymouth", "rng-tools",
 			"udisks2",
 		},
-	}
+	}.Append(bootPackageSet(t))
 }
 
-func vhdCommonPackageSet() rpmmd.PackageSet {
+func vhdCommonPackageSet(t *imageType) rpmmd.PackageSet {
 	return rpmmd.PackageSet{
 		Include: []string{
 			// Defaults
@@ -152,10 +298,10 @@ func vhdCommonPackageSet() rpmmd.PackageSet {
 		Exclude: []string{
 			"dracut-config-rescue", "rng-tools",
 		},
-	}
+	}.Append(bootPackageSet(t))
 }
 
-func vmdkCommonPackageSet() rpmmd.PackageSet {
+func vmdkCommonPackageSet(t *imageType) rpmmd.PackageSet {
 	return rpmmd.PackageSet{
 		Include: []string{
 			"@core", "chrony", "firewalld", "langpacks-en", "open-vm-tools",
@@ -164,11 +310,11 @@ func vmdkCommonPackageSet() rpmmd.PackageSet {
 		Exclude: []string{
 			"dracut-config-rescue", "rng-tools",
 		},
-	}
+	}.Append(bootPackageSet(t))
 
 }
 
-func openstackCommonPackageSet() rpmmd.PackageSet {
+func openstackCommonPackageSet(t *imageType) rpmmd.PackageSet {
 	return rpmmd.PackageSet{
 		Include: []string{
 			// Defaults
@@ -181,11 +327,11 @@ func openstackCommonPackageSet() rpmmd.PackageSet {
 		Exclude: []string{
 			"dracut-config-rescue", "rng-tools",
 		},
-	}
+	}.Append(bootPackageSet(t))
 
 }
 
-func ec2CommonPackageSet() rpmmd.PackageSet {
+func ec2CommonPackageSet(t *imageType) rpmmd.PackageSet {
 	return rpmmd.PackageSet{
 		Include: []string{
 			"@core", "authselect-compat", "chrony", "cloud-init", "cloud-utils-growpart",
@@ -206,19 +352,19 @@ func ec2CommonPackageSet() rpmmd.PackageSet {
 			"libertas-sd8787-firmware", "libertas-usb8388-firmware",
 			"plymouth",
 		},
-	}
+	}.Append(bootPackageSet(t))
 }
 
 // rhel-ec2 image package set
-func rhelEc2PackageSet() rpmmd.PackageSet {
-	ec2PackageSet := ec2CommonPackageSet()
+func rhelEc2PackageSet(t *imageType) rpmmd.PackageSet {
+	ec2PackageSet := ec2CommonPackageSet(t)
 	ec2PackageSet.Include = append(ec2PackageSet.Include, "rh-amazon-rhui-client")
 	return ec2PackageSet
 }
 
 // rhel-ha-ec2 image package set
-func rhelEc2HaPackageSet() rpmmd.PackageSet {
-	ec2HaPackageSet := ec2CommonPackageSet()
+func rhelEc2HaPackageSet(t *imageType) rpmmd.PackageSet {
+	ec2HaPackageSet := ec2CommonPackageSet(t)
 	ec2HaPackageSet.Include = append(ec2HaPackageSet.Include,
 		"fence-agents-all",
 		"pacemaker",
@@ -229,8 +375,8 @@ func rhelEc2HaPackageSet() rpmmd.PackageSet {
 }
 
 // edge commit OS package set
-func edgeCommitPackageSet() rpmmd.PackageSet {
-	return rpmmd.PackageSet{
+func edgeCommitPackageSet(t *imageType) rpmmd.PackageSet {
+	ps := rpmmd.PackageSet{
 		Include: []string{
 			"redhat-release", "glibc", "glibc-minimal-langpack",
 			"nss-altfiles", "dracut-config-generic", "dracut-network",
@@ -253,9 +399,22 @@ func edgeCommitPackageSet() rpmmd.PackageSet {
 		},
 		Exclude: []string{"rng-tools"},
 	}
+
+	ps = ps.Append(bootPackageSet(t))
+
+	switch t.arch.Name() {
+	case distro.X86_64ArchName:
+		ps = ps.Append(x8664EdgeCommitPackageSet(t))
+
+	case distro.Aarch64ArchName:
+		ps = ps.Append(aarch64EdgeCommitPackageSet(t))
+	}
+
+	return ps
+
 }
 
-func x8664EdgeCommitPackageSet() rpmmd.PackageSet {
+func x8664EdgeCommitPackageSet(t *imageType) rpmmd.PackageSet {
 	return rpmmd.PackageSet{
 		Include: []string{
 			"grub2", "grub2-efi-x64", "efibootmgr", "shim-x64",
@@ -269,14 +428,14 @@ func x8664EdgeCommitPackageSet() rpmmd.PackageSet {
 	}
 }
 
-func aarch64EdgeCommitPackageSet() rpmmd.PackageSet {
+func aarch64EdgeCommitPackageSet(t *imageType) rpmmd.PackageSet {
 	return rpmmd.PackageSet{
 		Include: []string{"grub2-efi-aa64", "efibootmgr", "shim-aa64", "iwl7260-firmware"},
 		Exclude: nil,
 	}
 }
 
-func bareMetalPackageSet() rpmmd.PackageSet {
+func bareMetalPackageSet(t *imageType) rpmmd.PackageSet {
 	return rpmmd.PackageSet{
 		Include: []string{
 			"authselect-compat", "chrony", "cockpit-system", "cockpit-ws",
@@ -294,114 +453,262 @@ func bareMetalPackageSet() rpmmd.PackageSet {
 			"subscription-manager-cockpit", "tar", "tcpdump", "yum",
 		},
 		Exclude: nil,
-	}
+	}.Append(bootPackageSet(t))
 }
 
 // INSTALLER PACKAGE SET
-func installerPackageSet() rpmmd.PackageSet {
-	// TODO: simplify
-	return rpmmd.PackageSet{
+
+func installerPackageSet(t *imageType) rpmmd.PackageSet {
+	ps := rpmmd.PackageSet{
 		Include: []string{
-			"aajohan-comfortaa-fonts", "abattis-cantarell-fonts",
-			"alsa-firmware", "alsa-tools-firmware", "anaconda",
-			"anaconda-dracut", "anaconda-install-env-deps", "anaconda-widgets",
-			"audit", "bind-utils", "biosdevname", "bitmap-fangsongti-fonts",
-			"bzip2", "cryptsetup", "curl", "dbus-x11", "dejavu-sans-fonts",
-			"dejavu-sans-mono-fonts", "device-mapper-persistent-data",
-			"dmidecode", "dnf", "dracut-config-generic", "dracut-network",
-			"dump", "efibootmgr", "ethtool", "ftp", "gdb-gdbserver", "gdisk",
-			"gfs2-utils", "glibc-all-langpacks",
-			"google-noto-sans-cjk-ttc-fonts", "grub2-efi-ia32-cdboot",
-			"grub2-efi-x64-cdboot", "grub2-tools", "grub2-tools-efi",
-			"grub2-tools-extra", "grub2-tools-minimal", "grubby",
-			"gsettings-desktop-schemas", "hdparm", "hexedit", "hostname",
-			"initscripts", "ipmitool", "iwl1000-firmware", "iwl100-firmware",
-			"iwl105-firmware", "iwl135-firmware", "iwl2000-firmware",
-			"iwl2030-firmware", "iwl3160-firmware", "iwl3945-firmware",
-			"iwl4965-firmware", "iwl5000-firmware", "iwl5150-firmware",
-			"iwl6000-firmware", "iwl6000g2a-firmware", "iwl6000g2b-firmware",
-			"iwl6050-firmware", "iwl7260-firmware", "jomolhari-fonts",
-			"kacst-farsi-fonts", "kacst-qurn-fonts", "kbd", "kbd-misc",
-			"kdump-anaconda-addon", "kernel", "khmeros-base-fonts", "less",
-			"libblockdev-lvm-dbus", "libertas-sd8686-firmware",
-			"libertas-sd8787-firmware", "libertas-usb8388-firmware",
-			"libertas-usb8388-olpc-firmware", "libibverbs",
-			"libreport-plugin-bugzilla", "libreport-plugin-reportuploader",
-			"libreport-rhel-anaconda-bugzilla", "librsvg2", "linux-firmware",
-			"lklug-fonts", "lohit-assamese-fonts", "lohit-bengali-fonts",
-			"lohit-devanagari-fonts", "lohit-gujarati-fonts",
-			"lohit-gurmukhi-fonts", "lohit-kannada-fonts", "lohit-odia-fonts",
-			"lohit-tamil-fonts", "lohit-telugu-fonts", "lsof", "madan-fonts",
-			"memtest86+", "metacity", "mtr", "mt-st", "net-tools", "nfs-utils",
-			"nmap-ncat", "nm-connection-editor", "nss-tools",
-			"openssh-clients", "openssh-server", "oscap-anaconda-addon",
-			"ostree", "pciutils", "perl-interpreter", "pigz", "plymouth",
-			"prefixdevname", "python3-pyatspi", "rdma-core",
-			"redhat-release-eula", "rng-tools", "rpcbind", "rpm-ostree",
-			"rsync", "rsyslog", "selinux-policy-targeted", "sg3_utils",
-			"shim-ia32", "shim-x64", "sil-abyssinica-fonts",
-			"sil-padauk-fonts", "sil-scheherazade-fonts", "smartmontools",
-			"smc-meera-fonts", "spice-vdagent", "strace", "syslinux",
-			"systemd", "system-storage-manager", "tar",
-			"thai-scalable-waree-fonts", "tigervnc-server-minimal",
-			"tigervnc-server-module", "udisks2", "udisks2-iscsi", "usbutils",
-			"vim-minimal", "volume_key", "wget", "xfsdump", "xfsprogs",
-			"xorg-x11-drivers", "xorg-x11-fonts-misc", "xorg-x11-server-utils",
-			"xorg-x11-server-Xorg", "xorg-x11-xauth", "xz",
+			"anaconda-dracut",
+			"curl",
+			"dracut-config-generic",
+			"dracut-network",
+			"hostname",
+			"iwl100-firmware",
+			"iwl1000-firmware",
+			"iwl105-firmware",
+			"iwl135-firmware",
+			"iwl2000-firmware",
+			"iwl2030-firmware",
+			"iwl3160-firmware",
+			"iwl5000-firmware",
+			"iwl5150-firmware",
+			"iwl6000-firmware",
+			"iwl6050-firmware",
+			"iwl7260-firmware",
+			"kernel",
+			"less",
+			"nfs-utils",
+			"openssh-clients",
+			"ostree",
+			"plymouth",
+			"prefixdevname",
+			"rng-tools",
+			"rpcbind",
+			"selinux-policy-targeted",
+			"systemd",
+			"tar",
+			"xfsprogs",
+			"xz",
 		},
 	}
+
+	switch t.arch.Name() {
+	case distro.X86_64ArchName:
+		ps = ps.Append(rpmmd.PackageSet{
+			Include: []string{
+				"biosdevname",
+			},
+		})
+	}
+
+	return ps
 }
 
-func edgeInstallerPackageSet() rpmmd.PackageSet {
-	return rpmmd.PackageSet{
+func anacondaPackageSet(t *imageType) rpmmd.PackageSet {
+
+	// common installer packages
+	ps := installerPackageSet(t)
+
+	ps = ps.Append(rpmmd.PackageSet{
 		Include: []string{
-			"aajohan-comfortaa-fonts", "abattis-cantarell-fonts",
-			"alsa-firmware", "alsa-tools-firmware", "anaconda",
-			"anaconda-dracut", "anaconda-install-env-deps", "anaconda-widgets",
-			"audit", "bind-utils", "biosdevname", "bitmap-fangsongti-fonts",
-			"bzip2", "cryptsetup", "curl", "dbus-x11", "dejavu-sans-fonts",
-			"dejavu-sans-mono-fonts", "device-mapper-persistent-data",
-			"dmidecode", "dnf", "dracut-config-generic", "dracut-network",
-			"dump", "efibootmgr", "ethtool", "ftp", "gdb-gdbserver", "gdisk",
-			"gfs2-utils", "glibc-all-langpacks",
-			"google-noto-sans-cjk-ttc-fonts", "grub2-efi-ia32-cdboot",
-			"grub2-efi-x64-cdboot", "grub2-tools", "grub2-tools-efi",
-			"grub2-tools-extra", "grub2-tools-minimal", "grubby",
-			"gsettings-desktop-schemas", "hdparm", "hexedit", "hostname",
-			"initscripts", "ipmitool", "iwl1000-firmware", "iwl100-firmware",
-			"iwl105-firmware", "iwl135-firmware", "iwl2000-firmware",
-			"iwl2030-firmware", "iwl3160-firmware", "iwl3945-firmware",
-			"iwl4965-firmware", "iwl5000-firmware", "iwl5150-firmware",
-			"iwl6000-firmware", "iwl6000g2a-firmware", "iwl6000g2b-firmware",
-			"iwl6050-firmware", "iwl7260-firmware", "jomolhari-fonts",
-			"kacst-farsi-fonts", "kacst-qurn-fonts", "kbd", "kbd-misc",
-			"kdump-anaconda-addon", "kernel", "khmeros-base-fonts", "less",
-			"libblockdev-lvm-dbus", "libertas-sd8686-firmware",
-			"libertas-sd8787-firmware", "libertas-usb8388-firmware",
-			"libertas-usb8388-olpc-firmware", "libibverbs",
-			"libreport-plugin-bugzilla", "libreport-plugin-reportuploader",
-			"libreport-rhel-anaconda-bugzilla", "librsvg2", "linux-firmware",
-			"lklug-fonts", "lohit-assamese-fonts", "lohit-bengali-fonts",
-			"lohit-devanagari-fonts", "lohit-gujarati-fonts",
-			"lohit-gurmukhi-fonts", "lohit-kannada-fonts", "lohit-odia-fonts",
-			"lohit-tamil-fonts", "lohit-telugu-fonts", "lsof", "madan-fonts",
-			"memtest86+", "metacity", "mtr", "mt-st", "net-tools", "nfs-utils",
-			"nmap-ncat", "nm-connection-editor", "nss-tools",
-			"openssh-clients", "openssh-server", "oscap-anaconda-addon",
-			"ostree", "pciutils", "perl-interpreter", "pigz", "plymouth",
-			"prefixdevname", "python3-pyatspi", "rdma-core",
-			"redhat-release-eula", "rng-tools", "rpcbind", "rpm-ostree",
-			"rsync", "rsyslog", "selinux-policy-targeted", "sg3_utils",
-			"shim-ia32", "shim-x64", "sil-abyssinica-fonts",
-			"sil-padauk-fonts", "sil-scheherazade-fonts", "smartmontools",
-			"smc-meera-fonts", "spice-vdagent", "strace", "syslinux",
-			"systemd", "system-storage-manager", "tar",
-			"thai-scalable-waree-fonts", "tigervnc-server-minimal",
-			"tigervnc-server-module", "udisks2", "udisks2-iscsi", "usbutils",
-			"vim-minimal", "volume_key", "wget", "xfsdump", "xfsprogs",
-			"xorg-x11-drivers", "xorg-x11-fonts-misc", "xorg-x11-server-utils",
-			"xorg-x11-server-Xorg", "xorg-x11-xauth", "xz",
+			"aajohan-comfortaa-fonts",
+			"abattis-cantarell-fonts",
+			"alsa-firmware",
+			"alsa-tools-firmware",
+			"anaconda",
+			"anaconda-install-env-deps",
+			"anaconda-widgets",
+			"audit",
+			"bind-utils",
+			"bitmap-fangsongti-fonts",
+			"bzip2",
+			"cryptsetup",
+			"dbus-x11",
+			"dejavu-sans-fonts",
+			"dejavu-sans-mono-fonts",
+			"device-mapper-persistent-data",
+			"dnf",
+			"dump",
+			"ethtool",
+			"fcoe-utils",
+			"ftp",
+			"gdb-gdbserver",
+			"gdisk",
+			"gfs2-utils",
+			"glibc-all-langpacks",
+			"google-noto-sans-cjk-ttc-fonts",
+			"gsettings-desktop-schemas",
+			"hdparm",
+			"hexedit",
+			"gsettings-desktop-schemas",
+			"hdparm",
+			"hexedit",
+			"initscripts",
+			"ipmitool",
+			"iwl3945-firmware",
+			"iwl4965-firmware",
+			"iwl6000g2a-firmware",
+			"iwl6000g2b-firmware",
+			"jomolhari-fonts",
+			"kacst-farsi-fonts",
+			"kacst-qurn-fonts",
+			"kbd",
+			"kbd-misc",
+			"kdump-anaconda-addon",
+			"khmeros-base-fonts",
+			"libblockdev-lvm-dbus",
+			"libertas-sd8686-firmware",
+			"libertas-sd8787-firmware",
+			"libertas-usb8388-firmware",
+			"libertas-usb8388-olpc-firmware",
+			"libibverbs",
+			"libreport-plugin-bugzilla",
+			"libreport-plugin-reportuploader",
+			"libreport-rhel-anaconda-bugzilla",
+			"librsvg2",
+			"linux-firmware",
+			"lklug-fonts",
+			"lohit-assamese-fonts",
+			"lohit-bengali-fonts",
+			"lohit-devanagari-fonts",
+			"lohit-gujarati-fonts",
+			"lohit-gurmukhi-fonts",
+			"lohit-kannada-fonts",
+			"lohit-odia-fonts",
+			"lohit-tamil-fonts",
+			"lohit-telugu-fonts",
+			"lsof",
+			"madan-fonts",
+			"metacity",
+			"mt-st",
+			"mtr",
+			"net-tools",
+			"nm-connection-editor",
+			"nmap-ncat",
+			"nss-tools",
+			"openssh-server",
+			"oscap-anaconda-addon",
+			"pciutils",
+			"perl-interpreter",
+			"pigz",
+			"python3-pyatspi",
+			"rdma-core",
+			"redhat-release-eula",
+			"rpm-ostree",
+			"rsync",
+			"rsyslog",
+			"sg3_utils",
+			"sil-abyssinica-fonts",
+			"sil-padauk-fonts",
+			"sil-scheherazade-fonts",
+			"smartmontools",
+			"smc-meera-fonts",
+			"spice-vdagent",
+			"strace",
+			"system-storage-manager",
+			"thai-scalable-waree-fonts",
+			"tigervnc-server-minimal",
+			"tigervnc-server-module",
+			"udisks2",
+			"udisks2-iscsi",
+			"usbutils",
+			"vim-minimal",
+			"volume_key",
+			"wget",
+			"xfsdump",
+			"xorg-x11-drivers",
+			"xorg-x11-fonts-misc",
+			"xorg-x11-server-Xorg",
+			"xorg-x11-server-utils",
+			"xorg-x11-xauth",
+		},
+	})
+
+	ps = ps.Append(anacondaBootPackageSet(t))
+
+	switch t.arch.Name() {
+	case distro.X86_64ArchName:
+		ps = ps.Append(rpmmd.PackageSet{
+			Include: []string{
+				"biosdevname",
+				"dmidecode",
+				"memtest86+",
+			},
+		})
+
+	case distro.Aarch64ArchName:
+		ps = ps.Append(rpmmd.PackageSet{
+			Include: []string{
+				"dmidecode",
+			},
+		})
+
+	default:
+		panic(fmt.Sprintf("unsupported arch: %s", t.arch.Name()))
+	}
+
+	return ps
+}
+
+func edgeInstallerPackageSet(t *imageType) rpmmd.PackageSet {
+	return anacondaPackageSet(t)
+}
+
+func edgeSimplifiedInstallerPackageSet(t *imageType) rpmmd.PackageSet {
+	// common installer packages
+	ps := installerPackageSet(t)
+
+	ps = ps.Append(rpmmd.PackageSet{
+		Include: []string{
+			"attr",
+			"basesystem",
+			"binutils",
+			"bsdtar",
+			"cloud-utils-growpart",
+			"coreos-installer",
+			"coreos-installer-bootinfra",
+			"coreutils",
+			"device-mapper-multipath",
+			"dnsmasq",
+			"dosfstools",
+			"dracut-live",
+			"e2fsprogs",
+			"fcoe-utils",
+			"gzip",
+			"ima-evm-utils",
+			"iproute",
+			"iptables",
+			"iputils",
+			"iscsi-initiator-utils",
+			"keyutils",
+			"lldpad",
+			"lvm2",
+			"passwd",
+			"policycoreutils",
+			"policycoreutils-python-utils",
+			"procps-ng",
+			"rootfiles",
+			"setools-console",
+			"sudo",
+			"traceroute",
+			"util-linux",
 		},
 		Exclude: nil,
+	})
+
+	switch t.arch.Name() {
+
+	case distro.X86_64ArchName:
+		ps = ps.Append(x8664EdgeCommitPackageSet(t))
+	case distro.Aarch64ArchName:
+		ps = ps.Append(aarch64EdgeCommitPackageSet(t))
+
+	default:
+		panic(fmt.Sprintf("unsupported arch: %s", t.arch.Name()))
 	}
+
+	return ps
 }
diff --git a/internal/distro/rhel85/partition_tables.go b/internal/distro/rhel85/partition_tables.go
index 9b2f3d4e4..3546d114e 100644
--- a/internal/distro/rhel85/partition_tables.go
+++ b/internal/distro/rhel85/partition_tables.go
@@ -181,3 +181,102 @@ var ec2BasePartitionTables = distro.BasePartitionTableMap{
 		},
 	},
 }
+
+var edgeBasePartitionTables = distro.BasePartitionTableMap{
+	distro.X86_64ArchName: disk.PartitionTable{
+		UUID: "D209C89E-EA5E-4FBD-B161-B461CCE297E0",
+		Type: "gpt",
+		Partitions: []disk.Partition{
+			{
+				Size:     2048, // 2MB
+				Bootable: true,
+				Type:     disk.BIOSBootPartitionGUID,
+				UUID:     disk.BIOSBootPartitionUUID,
+			},
+			{
+				Size: 260096, // 127 MB
+				Type: disk.EFISystemPartitionGUID,
+				UUID: disk.EFISystemPartitionUUID,
+				Filesystem: &disk.Filesystem{
+					Type:         "vfat",
+					UUID:         disk.EFIFilesystemUUID,
+					Mountpoint:   "/boot/efi",
+					Label:        "EFI-SYSTEM",
+					FSTabOptions: "defaults,uid=0,gid=0,umask=077,shortname=winnt",
+					FSTabFreq:    0,
+					FSTabPassNo:  2,
+				},
+			},
+			{
+				Size: 786432, // 384 MB
+				Type: disk.FilesystemDataGUID,
+				UUID: disk.FilesystemDataUUID,
+				Filesystem: &disk.Filesystem{
+					Type:         "xfs",
+					Mountpoint:   "/boot",
+					Label:        "boot",
+					FSTabOptions: "defaults",
+					FSTabFreq:    1,
+					FSTabPassNo:  1,
+				},
+			},
+			{
+				Type: disk.FilesystemDataGUID,
+				UUID: disk.RootPartitionUUID,
+				Filesystem: &disk.Filesystem{
+					Type:         "xfs",
+					Label:        "root",
+					Mountpoint:   "/",
+					FSTabOptions: "defaults",
+					FSTabFreq:    0,
+					FSTabPassNo:  0,
+				},
+			},
+		},
+	},
+	distro.Aarch64ArchName: disk.PartitionTable{
+		UUID: "D209C89E-EA5E-4FBD-B161-B461CCE297E0",
+		Type: "gpt",
+		Partitions: []disk.Partition{
+			{
+				Size: 260096, // 127 MB
+				Type: disk.EFISystemPartitionGUID,
+				UUID: disk.EFISystemPartitionUUID,
+				Filesystem: &disk.Filesystem{
+					Type:         "vfat",
+					UUID:         disk.EFIFilesystemUUID,
+					Mountpoint:   "/boot/efi",
+					Label:        "EFI-SYSTEM",
+					FSTabOptions: "defaults,uid=0,gid=0,umask=077,shortname=winnt",
+					FSTabFreq:    0,
+					FSTabPassNo:  2,
+				},
+			},
+			{
+				Size: 786432, // 384 MB
+				Type: disk.FilesystemDataGUID,
+				UUID: disk.FilesystemDataUUID,
+				Filesystem: &disk.Filesystem{
+					Type:         "xfs",
+					Mountpoint:   "/boot",
+					Label:        "boot",
+					FSTabOptions: "defaults",
+					FSTabFreq:    1,
+					FSTabPassNo:  1,
+				},
+			},
+			{
+				Type: disk.FilesystemDataGUID,
+				UUID: disk.RootPartitionUUID,
+				Filesystem: &disk.Filesystem{
+					Type:         "xfs",
+					Label:        "root",
+					Mountpoint:   "/",
+					FSTabOptions: "defaults",
+					FSTabFreq:    0,
+					FSTabPassNo:  0,
+				},
+			},
+		},
+	},
+}
diff --git a/internal/distro/rhel85/pipelines.go b/internal/distro/rhel85/pipelines.go
index ff0767b63..db817f921 100644
--- a/internal/distro/rhel85/pipelines.go
+++ b/internal/distro/rhel85/pipelines.go
@@ -47,7 +47,7 @@ func qcow2Pipelines(t *imageType, customizations *blueprint.Customizations, opti
 
 	treePipeline.AddStage(osbuild.NewFSTabStage(partitionTable.FSTabStageOptionsV2()))
 	kernelVer := kernelVerStr(packageSetSpecs[blueprintPkgsKey], customizations.GetKernel().Name, t.Arch().Name())
-	treePipeline.AddStage(bootloaderConfigStage(t, partitionTable, customizations.GetKernel(), kernelVer))
+	treePipeline.AddStage(bootloaderConfigStage(t, partitionTable, customizations.GetKernel(), kernelVer, false, false))
 	treePipeline.AddStage(osbuild.NewSELinuxStage(selinuxStageOptions(false)))
 	pipelines = append(pipelines, *treePipeline)
 
@@ -88,7 +88,7 @@ func vhdPipelines(t *imageType, customizations *blueprint.Customizations, option
 
 	treePipeline.AddStage(osbuild.NewFSTabStage(partitionTable.FSTabStageOptionsV2()))
 	kernelVer := kernelVerStr(packageSetSpecs[blueprintPkgsKey], customizations.GetKernel().Name, t.Arch().Name())
-	treePipeline.AddStage(bootloaderConfigStage(t, partitionTable, customizations.GetKernel(), kernelVer))
+	treePipeline.AddStage(bootloaderConfigStage(t, partitionTable, customizations.GetKernel(), kernelVer, false, false))
 	treePipeline.AddStage(osbuild.NewSELinuxStage(selinuxStageOptions(false)))
 	pipelines = append(pipelines, *treePipeline)
 
@@ -119,7 +119,7 @@ func vmdkPipelines(t *imageType, customizations *blueprint.Customizations, optio
 
 	treePipeline.AddStage(osbuild.NewFSTabStage(partitionTable.FSTabStageOptionsV2()))
 	kernelVer := kernelVerStr(packageSetSpecs[blueprintPkgsKey], customizations.GetKernel().Name, t.Arch().Name())
-	treePipeline.AddStage(bootloaderConfigStage(t, partitionTable, customizations.GetKernel(), kernelVer))
+	treePipeline.AddStage(bootloaderConfigStage(t, partitionTable, customizations.GetKernel(), kernelVer, false, false))
 	treePipeline.AddStage(osbuild.NewSELinuxStage(selinuxStageOptions(false)))
 	pipelines = append(pipelines, *treePipeline)
 
@@ -150,7 +150,7 @@ func openstackPipelines(t *imageType, customizations *blueprint.Customizations,
 
 	treePipeline.AddStage(osbuild.NewFSTabStage(partitionTable.FSTabStageOptionsV2()))
 	kernelVer := kernelVerStr(packageSetSpecs[blueprintPkgsKey], customizations.GetKernel().Name, t.Arch().Name())
-	treePipeline.AddStage(bootloaderConfigStage(t, partitionTable, customizations.GetKernel(), kernelVer))
+	treePipeline.AddStage(bootloaderConfigStage(t, partitionTable, customizations.GetKernel(), kernelVer, false, false))
 	treePipeline.AddStage(osbuild.NewSELinuxStage(selinuxStageOptions(false)))
 	pipelines = append(pipelines, *treePipeline)
 
@@ -433,7 +433,7 @@ func ec2CommonPipelines(t *imageType, customizations *blueprint.Customizations,
 
 	treePipeline.AddStage(osbuild.NewFSTabStage(partitionTable.FSTabStageOptionsV2()))
 	kernelVer := kernelVerStr(packageSetSpecs[blueprintPkgsKey], customizations.GetKernel().Name, t.Arch().Name())
-	treePipeline.AddStage(bootloaderConfigStage(t, partitionTable, customizations.GetKernel(), kernelVer))
+	treePipeline.AddStage(bootloaderConfigStage(t, partitionTable, customizations.GetKernel(), kernelVer, false, false))
 	// The last stage must be the SELinux stage
 	treePipeline.AddStage(osbuild.NewSELinuxStage(selinuxStageOptions(false)))
 	pipelines = append(pipelines, *treePipeline)
@@ -490,7 +490,7 @@ func edgeInstallerPipelines(t *imageType, customizations *blueprint.Customizatio
 	ostreeRepoPath := "/ostree/repo"
 	pipelines = append(pipelines, *anacondaTreePipeline(repos, installerPackages, kernelVer, t.Arch().Name(), ostreePayloadStages(options, ostreeRepoPath)))
 	pipelines = append(pipelines, *bootISOTreePipeline(kernelVer, t.Arch().Name(), ostreeKickstartStageOptions(fmt.Sprintf("file://%s", ostreeRepoPath), options.OSTree.Ref)))
-	pipelines = append(pipelines, *bootISOPipeline(t.Filename(), t.Arch().Name()))
+	pipelines = append(pipelines, *bootISOPipeline(t.Filename(), t.Arch().Name(), false))
 	return pipelines, nil
 }
 
@@ -522,7 +522,7 @@ func tarInstallerPipelines(t *imageType, customizations *blueprint.Customization
 	tarPayloadStages := []*osbuild.Stage{tarStage("os", tarPath)}
 	pipelines = append(pipelines, *anacondaTreePipeline(repos, installerPackages, kernelVer, t.Arch().Name(), tarPayloadStages))
 	pipelines = append(pipelines, *bootISOTreePipeline(kernelVer, t.Arch().Name(), tarKickstartStageOptions(fmt.Sprintf("file://%s", tarPath))))
-	pipelines = append(pipelines, *bootISOPipeline(t.Filename(), t.Arch().Name()))
+	pipelines = append(pipelines, *bootISOPipeline(t.Filename(), t.Arch().Name(), true))
 	return pipelines, nil
 }
 
@@ -568,6 +568,48 @@ func edgeContainerPipelines(t *imageType, customizations *blueprint.Customizatio
 	return pipelines, nil
 }
 
+func edgeImagePipelines(t *imageType, filename string, options distro.ImageOptions, rng *rand.Rand) ([]osbuild.Pipeline, string, error) {
+	pipelines := make([]osbuild.Pipeline, 0)
+	ostreeRepoPath := "/ostree/repo"
+	imgName := "image.raw"
+
+	partitionTable, err := t.getPartitionTable(nil, options, rng)
+	if err != nil {
+		return nil, "", err
+	}
+
+	// prepare ostree deployment tree
+	treePipeline := ostreeDeployPipeline(t, &partitionTable, ostreeRepoPath, nil, "", rng, options)
+	pipelines = append(pipelines, *treePipeline)
+
+	// make raw image from tree
+	imagePipeline := liveImagePipeline(treePipeline.Name, imgName, &partitionTable, t.arch, "")
+	pipelines = append(pipelines, *imagePipeline)
+
+	// compress image
+	xzPipeline := xzArchivePipeline(imagePipeline.Name, imgName, filename)
+	pipelines = append(pipelines, *xzPipeline)
+
+	return pipelines, xzPipeline.Name, nil
+}
+
+func edgeRawImagePipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec, rng *rand.Rand) ([]osbuild.Pipeline, error) {
+	pipelines := make([]osbuild.Pipeline, 0)
+	pipelines = append(pipelines, *buildPipeline(repos, packageSetSpecs[buildPkgsKey]))
+
+	imgName := t.filename
+
+	// create the raw image
+	imagePipelines, _, err := edgeImagePipelines(t, imgName, options, rng)
+	if err != nil {
+		return nil, err
+	}
+
+	pipelines = append(pipelines, imagePipelines...)
+
+	return pipelines, nil
+}
+
 func buildPipeline(repos []rpmmd.RepoConfig, buildPackageSpecs []rpmmd.PackageSpec) *osbuild.Pipeline {
 	p := new(osbuild.Pipeline)
 	p.Name = "build"
@@ -844,6 +886,259 @@ func ostreePayloadStages(options distro.ImageOptions, ostreeRepoPath string) []*
 	return stages
 }
 
+func edgeSimplifiedInstallerPipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec, rng *rand.Rand) ([]osbuild.Pipeline, error) {
+	pipelines := make([]osbuild.Pipeline, 0)
+	pipelines = append(pipelines, *buildPipeline(repos, packageSetSpecs[buildPkgsKey]))
+	installerPackages := packageSetSpecs[installerPkgsKey]
+	kernelVer := kernelVerStr(installerPackages, "kernel", t.Arch().Name())
+	imgName := "disk.img.xz"
+	installDevice := customizations.GetInstallationDevice()
+
+	// create the raw image
+	imagePipelines, imgPipelineName, err := edgeImagePipelines(t, imgName, options, rng)
+	if err != nil {
+		return nil, err
+	}
+
+	pipelines = append(pipelines, imagePipelines...)
+
+	// create boot ISO with raw image
+	installerTreePipeline := simplifiedInstallerTreePipeline(repos, installerPackages, kernelVer, t.Arch().Name())
+	efibootTreePipeline := simplifiedInstallerEFIBootTreePipeline(installDevice, kernelVer, t.Arch().Name())
+	bootISOTreePipeline := simplifiedInstallerBootISOTreePipeline(imgPipelineName, kernelVer)
+
+	pipelines = append(pipelines, *installerTreePipeline, *efibootTreePipeline, *bootISOTreePipeline)
+	pipelines = append(pipelines, *bootISOPipeline(t.Filename(), t.Arch().Name(), false))
+
+	return pipelines, nil
+}
+
+func simplifiedInstallerBootISOTreePipeline(archivePipelineName, kver string) *osbuild.Pipeline {
+	p := new(osbuild.Pipeline)
+	p.Name = "bootiso-tree"
+	p.Build = "name:build"
+
+	p.AddStage(osbuild.NewCopyStageSimple(
+		&osbuild.CopyStageOptions{
+			Paths: []osbuild.CopyStagePath{
+				{
+					From: "input://file/disk.img.xz",
+					To:   "tree:///disk.img.xz",
+				},
+			},
+		},
+		osbuild.NewFilesInputs(osbuild.NewFilesInputReferencesPipeline(archivePipelineName, "disk.img.xz")),
+	))
+
+	p.AddStage(osbuild.NewMkdirStage(
+		&osbuild.MkdirStageOptions{
+			Paths: []osbuild.Path{
+				{
+					Path: "images",
+				},
+				{
+					Path: "images/pxeboot",
+				},
+			},
+		},
+	))
+
+	var sectorSize uint64 = 512
+	pt := disk.PartitionTable{
+		Size: 20971520,
+		Partitions: []disk.Partition{
+			{
+				Start: 0,
+				Size:  20971520 / sectorSize,
+				Filesystem: &disk.Filesystem{
+					Type:       "vfat",
+					Mountpoint: "/",
+				},
+			},
+		},
+	}
+
+	filename := "images/efiboot.img"
+	loopback := osbuild.NewLoopbackDevice(&osbuild.LoopbackDeviceOptions{Filename: filename})
+	p.AddStage(osbuild.NewTruncateStage(&osbuild.TruncateStageOptions{Filename: filename, Size: fmt.Sprintf("%d", pt.Size)}))
+
+	for _, stage := range mkfsStages(&pt, loopback) {
+		p.AddStage(stage)
+	}
+
+	inputName := "root-tree"
+	copyInputs := copyPipelineTreeInputs(inputName, "efiboot-tree")
+	copyOptions, copyDevices, copyMounts := copyFSTreeOptions(inputName, "efiboot-tree", &pt, loopback)
+	p.AddStage(osbuild.NewCopyStage(copyOptions, copyInputs, copyDevices, copyMounts))
+
+	inputName = "coi"
+	copyInputs = copyPipelineTreeInputs(inputName, "coi-tree")
+	p.AddStage(osbuild.NewCopyStageSimple(
+		&osbuild.CopyStageOptions{
+			Paths: []osbuild.CopyStagePath{
+				{
+					From: fmt.Sprintf("input://%s/boot/vmlinuz-%s", inputName, kver),
+					To:   "tree:///images/pxeboot/vmlinuz",
+				},
+				{
+					From: fmt.Sprintf("input://%s/boot/initramfs-%s.img", inputName, kver),
+					To:   "tree:///images/pxeboot/initrd.img",
+				},
+			},
+		},
+		copyInputs,
+	))
+
+	inputName = "efi-tree"
+	copyInputs = copyPipelineTreeInputs(inputName, "efiboot-tree")
+	p.AddStage(osbuild.NewCopyStageSimple(
+		&osbuild.CopyStageOptions{
+			Paths: []osbuild.CopyStagePath{
+				{
+					From: fmt.Sprintf("input://%s/EFI", inputName),
+					To:   "tree:///",
+				},
+			},
+		},
+		copyInputs,
+	))
+
+	return p
+}
+
+func simplifiedInstallerEFIBootTreePipeline(installDevice, kernelVer, arch string) *osbuild.Pipeline {
+	p := new(osbuild.Pipeline)
+	p.Name = "efiboot-tree"
+	p.Build = "name:build"
+
+	isolabel := fmt.Sprintf("RHEL-8-5-0-BaseOS-%s", arch)
+
+	var architectures []string
+
+	if arch == "x86_64" {
+		architectures = []string{"IA32", "X64"}
+	} else if arch == "aarch64" {
+		architectures = []string{"AA64"}
+	} else {
+		panic("unsupported architecture")
+	}
+
+	p.AddStage(osbuild.NewGrubISOStage(
+		&osbuild.GrubISOStageOptions{
+			Product: osbuild.Product{
+				Name:    "Red Hat Enterprise Linux",
+				Version: osVersion,
+			},
+			ISOLabel: isolabel,
+			Kernel: osbuild.ISOKernel{
+				Dir: "/images/pxeboot",
+				Opts: []string{"rd.neednet=1",
+					"console=tty0",
+					"console=ttyS0",
+					"edge.liveiso=" + isolabel,
+					"coreos.inst.install_dev=" + installDevice,
+					"coreos.inst.image_file=/run/media/iso/disk.img.xz",
+					"coreos.inst.insecure"},
+			},
+			Architectures: architectures,
+			Vendor:        "redhat",
+		},
+	))
+
+	return p
+}
+
+func simplifiedInstallerTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, kernelVer string, arch string) *osbuild.Pipeline {
+	p := new(osbuild.Pipeline)
+	p.Name = "coi-tree"
+	p.Build = "name:build"
+	p.AddStage(osbuild.NewRPMStage(rpmStageOptions(repos), rpmStageInputs(packages)))
+	p.AddStage(osbuild.NewBuildstampStage(buildStampStageOptions(arch)))
+	p.AddStage(osbuild.NewLocaleStage(&osbuild.LocaleStageOptions{Language: "en_US.UTF-8"}))
+	p.AddStage(osbuild.NewSystemdStage(systemdStageOptions([]string{"coreos-installer"}, nil, nil, "")))
+	p.AddStage(osbuild.NewDracutStage(dracutStageOptions(kernelVer, arch, []string{
+		"rdcore",
+	})))
+
+	return p
+}
+
+func ostreeDeployPipeline(
+	t *imageType,
+	pt *disk.PartitionTable,
+	repoPath string,
+	kernel *blueprint.KernelCustomization,
+	kernelVer string,
+	rng *rand.Rand,
+	options distro.ImageOptions,
+) *osbuild.Pipeline {
+
+	p := new(osbuild.Pipeline)
+	p.Name = "image-tree"
+	p.Build = "name:build"
+	osname := "redhat"
+
+	p.AddStage(osbuild.OSTreeInitFsStage())
+	p.AddStage(osbuild.NewOSTreePullStage(
+		&osbuild.OSTreePullStageOptions{Repo: repoPath},
+		ostreePullStageInputs("org.osbuild.source", options.OSTree.Parent, options.OSTree.Ref),
+	))
+	p.AddStage(osbuild.NewOSTreeOsInitStage(
+		&osbuild.OSTreeOsInitStageOptions{
+			OSName: osname,
+		},
+	))
+	p.AddStage(osbuild.NewOSTreeConfigStage(ostreeConfigStageOptions(repoPath, true)))
+	p.AddStage(osbuild.NewMkdirStage(efiMkdirStageOptions()))
+	p.AddStage(osbuild.NewOSTreeDeployStage(
+		&osbuild.OSTreeDeployStageOptions{
+			OsName: osname,
+			Ref:    options.OSTree.Ref,
+			Mounts: []string{"/boot", "/boot/efi"},
+			Rootfs: osbuild.Rootfs{
+				Label: "root",
+			},
+			KernelOpts: []string{
+				"console=tty0",
+				"console=ttyS0",
+				"systemd.log_target=console",
+				"systemd.journald.forward_to_console=1",
+			},
+		},
+	))
+	p.AddStage(osbuild.NewOSTreeFillvarStage(
+		&osbuild.OSTreeFillvarStageOptions{
+			Deployment: osbuild.OSTreeDeployment{
+				OSName: osname,
+				Ref:    options.OSTree.Ref,
+			},
+		},
+	))
+
+	fstabOptions := pt.FSTabStageOptionsV2()
+	fstabOptions.OSTree = &osbuild.OSTreeFstab{
+		Deployment: osbuild.OSTreeDeployment{
+			OSName: osname,
+			Ref:    options.OSTree.Ref,
+		},
+	}
+	p.AddStage(osbuild2.NewFSTabStage(fstabOptions))
+
+	// TODO: Add users?
+
+	p.AddStage(bootloaderConfigStage(t, *pt, kernel, kernelVer, true, true))
+
+	p.AddStage(osbuild.NewOSTreeSelinuxStage(
+		&osbuild.OSTreeSelinuxStageOptions{
+			Deployment: osbuild.OSTreeDeployment{
+				OSName: osname,
+				Ref:    options.OSTree.Ref,
+			},
+		},
+	))
+	return p
+}
+
 func anacondaTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, kernelVer string, arch string, payloadStages []*osbuild.Stage) *osbuild.Pipeline {
 	p := new(osbuild.Pipeline)
 	p.Name = "anaconda-tree"
@@ -882,7 +1177,9 @@ func anacondaTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec
 	p.AddStage(osbuild.NewUsersStage(usersStageOptions))
 	p.AddStage(osbuild.NewAnacondaStage(anacondaStageOptions()))
 	p.AddStage(osbuild.NewLoraxScriptStage(loraxScriptStageOptions(arch)))
-	p.AddStage(osbuild.NewDracutStage(dracutStageOptions(kernelVer)))
+	p.AddStage(osbuild.NewDracutStage(dracutStageOptions(kernelVer, arch, []string{
+		"anaconda",
+	})))
 
 	return p
 }
@@ -898,12 +1195,12 @@ func bootISOTreePipeline(kernelVer string, arch string, ksOptions *osbuild.Kicks
 
 	return p
 }
-func bootISOPipeline(filename string, arch string) *osbuild.Pipeline {
+func bootISOPipeline(filename string, arch string, isolinux bool) *osbuild.Pipeline {
 	p := new(osbuild.Pipeline)
 	p.Name = "bootiso"
 	p.Build = "name:build"
 
-	p.AddStage(osbuild.NewXorrisofsStage(xorrisofsStageOptions(filename, arch), xorrisofsStageInputs()))
+	p.AddStage(osbuild.NewXorrisofsStage(xorrisofsStageOptions(filename, arch, isolinux), xorrisofsStageInputs("bootiso-tree")))
 	p.AddStage(osbuild.NewImplantisomd5Stage(&osbuild.Implantisomd5StageOptions{Filename: filename}))
 
 	return p
@@ -1011,7 +1308,7 @@ func qemuPipeline(inputPipelineName, inputFilename, outputFilename, format, qcow
 	return p
 }
 
-func bootloaderConfigStage(t *imageType, partitionTable disk.PartitionTable, kernel *blueprint.KernelCustomization, kernelVer string) *osbuild.Stage {
+func bootloaderConfigStage(t *imageType, partitionTable disk.PartitionTable, kernel *blueprint.KernelCustomization, kernelVer string, install, greenboot bool) *osbuild.Stage {
 	if t.arch.name == distro.S390xArchName {
 		return osbuild.NewZiplStage(new(osbuild.ZiplStageOptions))
 	}
@@ -1019,7 +1316,11 @@ func bootloaderConfigStage(t *imageType, partitionTable disk.PartitionTable, ker
 	kernelOptions := t.kernelOptions
 	uefi := t.supportsUEFI()
 	legacy := t.arch.legacy
-	return osbuild.NewGRUB2Stage(grub2StageOptions(partitionTable.RootPartition(), partitionTable.BootPartition(), kernelOptions, kernel, kernelVer, uefi, legacy))
+
+	options := grub2StageOptions(partitionTable.RootPartition(), partitionTable.BootPartition(), kernelOptions, kernel, kernelVer, uefi, legacy, install)
+	options.Greenboot = greenboot
+
+	return osbuild.NewGRUB2Stage(options)
 }
 
 func bootloaderInstStage(filename string, pt *disk.PartitionTable, arch *architecture, kernelVer string, devices *osbuild.Devices, mounts *osbuild.Mounts, disk *osbuild.Device) *osbuild.Stage {
diff --git a/internal/distro/rhel85/stage_inputs.go b/internal/distro/rhel85/stage_inputs.go
index e5cc310cb..80bc2690a 100644
--- a/internal/distro/rhel85/stage_inputs.go
+++ b/internal/distro/rhel85/stage_inputs.go
@@ -42,16 +42,16 @@ func ostreePullStageInputs(origin, source, commitRef string) *osbuild.OSTreePull
 	return &osbuild.OSTreePullStageInputs{Commits: pullStageInput}
 }
 
-func xorrisofsStageInputs() *osbuild.XorrisofsStageInputs {
+func xorrisofsStageInputs(pipeline string) *osbuild.XorrisofsStageInputs {
 	input := new(osbuild.XorrisofsStageInput)
 	input.Type = "org.osbuild.tree"
 	input.Origin = "org.osbuild.pipeline"
-	input.References = osbuild.XorrisofsStageReferences{"name:bootiso-tree"}
+	input.References = osbuild.XorrisofsStageReferences{"name:" + pipeline}
 	return &osbuild.XorrisofsStageInputs{Tree: input}
 }
 
 func copyPipelineTreeInputs(name, inputPipeline string) *osbuild.CopyStageInputs {
-	inputName := "root-tree"
+	inputName := name
 	treeInput := osbuild.CopyStageInput{}
 	treeInput.Type = "org.osbuild.tree"
 	treeInput.Origin = "org.osbuild.pipeline"
diff --git a/internal/distro/rhel85/stage_options.go b/internal/distro/rhel85/stage_options.go
index 74267d06c..17112d28d 100644
--- a/internal/distro/rhel85/stage_options.go
+++ b/internal/distro/rhel85/stage_options.go
@@ -2,6 +2,7 @@ package rhel85
 
 import (
 	"fmt"
+	"os"
 	"path/filepath"
 	"sort"
 
@@ -11,6 +12,7 @@ import (
 	"github.com/osbuild/osbuild-composer/internal/common"
 	"github.com/osbuild/osbuild-composer/internal/crypt"
 	"github.com/osbuild/osbuild-composer/internal/disk"
+	"github.com/osbuild/osbuild-composer/internal/distro"
 	osbuild "github.com/osbuild/osbuild-composer/internal/osbuild2"
 	"github.com/osbuild/osbuild-composer/internal/rpmmd"
 )
@@ -176,7 +178,7 @@ func loraxScriptStageOptions(arch string) *osbuild.LoraxScriptStageOptions {
 	}
 }
 
-func dracutStageOptions(kernelVer string) *osbuild.DracutStageOptions {
+func dracutStageOptions(kernelVer, arch string, additionalModules []string) *osbuild.DracutStageOptions {
 	kernel := []string{kernelVer}
 	modules := []string{
 		"bash",
@@ -197,7 +199,6 @@ func dracutStageOptions(kernelVer string) *osbuild.DracutStageOptions {
 		"plymouth",
 		"prefixdevname",
 		"prefixdevname-tools",
-		"anaconda",
 		"crypt",
 		"dm",
 		"dmsquash-live",
@@ -219,7 +220,6 @@ func dracutStageOptions(kernelVer string) *osbuild.DracutStageOptions {
 		"rootfs-block",
 		"terminfo",
 		"udev-rules",
-		"biosdevname",
 		"dracut-systemd",
 		"pollcdrom",
 		"usrmount",
@@ -229,6 +229,12 @@ func dracutStageOptions(kernelVer string) *osbuild.DracutStageOptions {
 		"shutdown",
 		"uefi-lib",
 	}
+
+	if arch == distro.X86_64ArchName {
+		modules = append(modules, "biosdevname")
+	}
+
+	modules = append(modules, additionalModules...)
 	return &osbuild.DracutStageOptions{
 		Kernel:  kernel,
 		Modules: modules,
@@ -263,6 +269,17 @@ func bootISOMonoStageOptions(kernelVer string, arch string) *osbuild.BootISOMono
 		comprOptions.BCJ = bcj
 	}
 	isolabel := fmt.Sprintf("RHEL-8-5-0-BaseOS-%s", arch)
+
+	var architectures []string
+
+	if arch == distro.X86_64ArchName {
+		architectures = []string{"IA32", "X64"}
+	} else if arch == distro.Aarch64ArchName {
+		architectures = []string{"AA64"}
+	} else {
+		panic("unsupported architecture")
+	}
+
 	return &osbuild.BootISOMonoStageOptions{
 		Product: osbuild.Product{
 			Name:    "Red Hat Enterprise Linux",
@@ -272,14 +289,11 @@ func bootISOMonoStageOptions(kernelVer string, arch string) *osbuild.BootISOMono
 		Kernel:     kernelVer,
 		KernelOpts: fmt.Sprintf("inst.ks=hd:LABEL=%s:%s", isolabel, kspath),
 		EFI: osbuild.EFI{
-			Architectures: []string{
-				"IA32",
-				"X64",
-			},
-			Vendor: "redhat",
+			Architectures: architectures,
+			Vendor:        "redhat",
 		},
 		ISOLinux: osbuild.ISOLinux{
-			Enabled: true,
+			Enabled: arch == distro.X86_64ArchName,
 			Debug:   false,
 		},
 		Templates: "80-rhel",
@@ -300,22 +314,28 @@ func discinfoStageOptions(arch string) *osbuild.DiscinfoStageOptions {
 	}
 }
 
-func xorrisofsStageOptions(filename string, arch string) *osbuild.XorrisofsStageOptions {
-	return &osbuild.XorrisofsStageOptions{
+func xorrisofsStageOptions(filename string, arch string, isolinux bool) *osbuild.XorrisofsStageOptions {
+	options := &osbuild.XorrisofsStageOptions{
 		Filename: filename,
 		VolID:    fmt.Sprintf("RHEL-8-5-0-BaseOS-%s", arch),
 		SysID:    "LINUX",
-		Boot: osbuild.XorrisofsBoot{
+		EFI:      "images/efiboot.img",
+	}
+
+	if isolinux {
+		options.Boot = &osbuild.XorrisofsBoot{
 			Image:   "isolinux/isolinux.bin",
 			Catalog: "isolinux/boot.cat",
-		},
-		EFI:          "images/efiboot.img",
-		IsohybridMBR: "/usr/share/syslinux/isohdpfx.bin",
+		}
+
+		options.IsohybridMBR = "/usr/share/syslinux/isohdpfx.bin"
 	}
+
+	return options
 }
 
 func grub2StageOptions(rootPartition *disk.Partition, bootPartition *disk.Partition, kernelOptions string,
-	kernel *blueprint.KernelCustomization, kernelVer string, uefi bool, legacy string) *osbuild.GRUB2StageOptions {
+	kernel *blueprint.KernelCustomization, kernelVer string, uefi bool, legacy string, install bool) *osbuild.GRUB2StageOptions {
 	if rootPartition == nil {
 		panic("root partition must be defined for grub2 stage, this is a programming error")
 	}
@@ -333,7 +353,8 @@ func grub2StageOptions(rootPartition *disk.Partition, bootPartition *disk.Partit
 
 	if uefi {
 		stageOptions.UEFI = &osbuild.GRUB2UEFI{
-			Vendor: "redhat",
+			Vendor:  "redhat",
+			Install: install,
 		}
 	}
 
@@ -450,6 +471,11 @@ func grub2InstStageOptions(filename string, pt *disk.PartitionTable, platform st
 	if bootPartIndex == -1 {
 		panic("failed to find boot or root partition for grub2.inst stage")
 	}
+	bootPart := pt.Partitions[bootPartIndex]
+	prefixPath := "/boot/grub2"
+	if bootPart.Filesystem.Mountpoint == "/boot" {
+		prefixPath = "/grub2"
+	}
 	core := osbuild.CoreMkImage{
 		Type:       "mkimage",
 		PartLabel:  pt.Type,
@@ -460,7 +486,7 @@ func grub2InstStageOptions(filename string, pt *disk.PartitionTable, platform st
 		Type:      "partition",
 		PartLabel: pt.Type,
 		Number:    uint(bootPartIndex),
-		Path:      "/boot/grub2",
+		Path:      prefixPath,
 	}
 
 	return &osbuild.Grub2InstStageOptions{
@@ -538,3 +564,25 @@ func chmodStageOptions(path, mode string, recursive bool) *osbuild.ChmodStageOpt
 		},
 	}
 }
+
+func ostreeConfigStageOptions(repo string, readOnly bool) *osbuild.OSTreeConfigStageOptions {
+	return &osbuild.OSTreeConfigStageOptions{
+		Repo: repo,
+		Config: &osbuild.OSTreeConfig{
+			Sysroot: &osbuild.SysrootOptions{
+				ReadOnly: common.BoolToPtr(readOnly),
+			},
+		},
+	}
+}
+
+func efiMkdirStageOptions() *osbuild.MkdirStageOptions {
+	return &osbuild.MkdirStageOptions{
+		Paths: []osbuild.Path{
+			{
+				Path: "/boot/efi",
+				Mode: os.FileMode(0700),
+			},
+		},
+	}
+}
diff --git a/internal/distro/rhel90/stage_options.go b/internal/distro/rhel90/stage_options.go
index 20e9047b7..3d08e997c 100644
--- a/internal/distro/rhel90/stage_options.go
+++ b/internal/distro/rhel90/stage_options.go
@@ -304,7 +304,7 @@ func xorrisofsStageOptions(filename string, arch string) *osbuild.XorrisofsStage
 		Filename: filename,
 		VolID:    fmt.Sprintf("RHEL-9-0-0-BaseOS-%s", arch),
 		SysID:    "LINUX",
-		Boot: osbuild.XorrisofsBoot{
+		Boot: &osbuild.XorrisofsBoot{
 			Image:   "isolinux/isolinux.bin",
 			Catalog: "isolinux/boot.cat",
 		},
diff --git a/internal/osbuild2/copy_stage.go b/internal/osbuild2/copy_stage.go
index 43a26ca10..510ea3a67 100644
--- a/internal/osbuild2/copy_stage.go
+++ b/internal/osbuild2/copy_stage.go
@@ -25,14 +25,36 @@ func (CopyStageInputs) isStageInputs() {}
 
 type CopyStageReferences []string
 
+type CopyStageInputsNew interface {
+	isCopyStageInputs()
+}
+
+func (CopyStageInputs) isCopyStageInputs() {}
+
 func (CopyStageReferences) isReferences() {}
 
-func NewCopyStage(options *CopyStageOptions, inputs *CopyStageInputs, devices *Devices, mounts *Mounts) *Stage {
+func NewCopyStage(options *CopyStageOptions, inputs CopyStageInputsNew, devices *Devices, mounts *Mounts) *Stage {
+	var stageInputs Inputs
+	if inputs != nil {
+		stageInputs = inputs.(Inputs)
+	}
 	return &Stage{
 		Type:    "org.osbuild.copy",
 		Options: options,
-		Inputs:  inputs,
+		Inputs:  stageInputs,
 		Devices: *devices,
 		Mounts:  *mounts,
 	}
 }
+
+func NewCopyStageSimple(options *CopyStageOptions, inputs CopyStageInputsNew) *Stage {
+	var stageInputs Inputs
+	if inputs != nil {
+		stageInputs = inputs.(Inputs)
+	}
+	return &Stage{
+		Type:    "org.osbuild.copy",
+		Options: options,
+		Inputs:  stageInputs,
+	}
+}
diff --git a/internal/osbuild2/files_input.go b/internal/osbuild2/files_input.go
index bb2e0e70b..93e545972 100644
--- a/internal/osbuild2/files_input.go
+++ b/internal/osbuild2/files_input.go
@@ -24,6 +24,9 @@ func NewFilesInputs(references FilesInputReferences) *FilesInputs {
 // inputs accepted by the XZ stage
 func (FilesInputs) isXzStageInputs() {}
 
+// inputs accepted by the Copy stage
+func (FilesInputs) isCopyStageInputs() {}
+
 // SPECIFIC INPUT STRUCTURE
 
 type FilesInput struct {
diff --git a/internal/osbuild2/fstab_stage.go b/internal/osbuild2/fstab_stage.go
index be02d4094..20ec46c44 100644
--- a/internal/osbuild2/fstab_stage.go
+++ b/internal/osbuild2/fstab_stage.go
@@ -7,10 +7,16 @@ package osbuild2
 // are set to their defaults (if possible).
 type FSTabStageOptions struct {
 	FileSystems []*FSTabEntry `json:"filesystems"`
+
+	OSTree *OSTreeFstab `json:"ostree,omitempty"`
 }
 
 func (FSTabStageOptions) isStageOptions() {}
 
+type OSTreeFstab struct {
+	Deployment OSTreeDeployment `json:"deployment"`
+}
+
 // NewFSTabStage creates a now FSTabStage object
 func NewFSTabStage(options *FSTabStageOptions) *Stage {
 	return &Stage{
diff --git a/internal/osbuild2/grub2_stage.go b/internal/osbuild2/grub2_stage.go
index 4f416a706..c2f9762b9 100644
--- a/internal/osbuild2/grub2_stage.go
+++ b/internal/osbuild2/grub2_stage.go
@@ -17,6 +17,7 @@ type GRUB2StageOptions struct {
 	Legacy             string     `json:"legacy,omitempty"`
 	UEFI               *GRUB2UEFI `json:"uefi,omitempty"`
 	SavedEntry         string     `json:"saved_entry,omitempty"`
+	Greenboot          bool       `json:"greenboot,omitempty"`
 }
 
 type GRUB2UEFI struct {
diff --git a/internal/osbuild2/grub_iso_stage.go b/internal/osbuild2/grub_iso_stage.go
new file mode 100644
index 000000000..0215a31b7
--- /dev/null
+++ b/internal/osbuild2/grub_iso_stage.go
@@ -0,0 +1,30 @@
+package osbuild2
+
+type GrubISOStageOptions struct {
+	Product Product `json:"product"`
+
+	Kernel ISOKernel `json:"kernel"`
+
+	ISOLabel string `json:"isolabel"`
+
+	Architectures []string `json:"architectures,omitempty"`
+
+	Vendor string `json:"vendor,omitempty"`
+}
+
+func (GrubISOStageOptions) isStageOptions() {}
+
+type ISOKernel struct {
+	Dir string `json:"dir"`
+
+	// Additional kernel boot options
+	Opts []string `json:"opts,omitempty"`
+}
+
+// Assemble a file system tree for a bootable ISO
+func NewGrubISOStage(options *GrubISOStageOptions) *Stage {
+	return &Stage{
+		Type:    "org.osbuild.grub2.iso",
+		Options: options,
+	}
+}
diff --git a/internal/osbuild2/lvm2_create_stage.go b/internal/osbuild2/lvm2_create_stage.go
new file mode 100644
index 000000000..f328c3349
--- /dev/null
+++ b/internal/osbuild2/lvm2_create_stage.go
@@ -0,0 +1,51 @@
+package osbuild2
+
+import (
+	"fmt"
+	"regexp"
+)
+
+const lvmVolNameRegex = "^[a-zA-Z0-9+_.][a-zA-Z0-9+_.-]*$"
+
+// Create LVM2 physical volumes, volume groups, and logical volumes
+
+type LVM2CreateStageOptions struct {
+	Volumes []LogicalVolume `json:"volumes"`
+}
+
+func (LVM2CreateStageOptions) isStageOptions() {}
+
+func (o LVM2CreateStageOptions) validate() error {
+	if len(o.Volumes) == 0 {
+		return fmt.Errorf("at least one volume is required")
+	}
+
+	nameRegex := regexp.MustCompile(lvmVolNameRegex)
+	for _, volume := range o.Volumes {
+		fmt.Printf("testing volume %q\n", volume.Name)
+		if !nameRegex.MatchString(volume.Name) {
+			return fmt.Errorf("volume name %q doesn't conform to schema (%s)", volume.Name, nameRegex.String())
+		} else {
+			fmt.Printf("volume.Name %q is ok\n", volume.Name)
+		}
+	}
+	return nil
+}
+
+type LogicalVolume struct {
+	Name string `json:"name"`
+
+	Size string `json:"size"`
+}
+
+func NewLVM2CreateStage(options *LVM2CreateStageOptions, device *Device) *Stage {
+	if err := options.validate(); err != nil {
+		panic(err)
+	}
+
+	return &Stage{
+		Type:    "org.osbuild.lvm2.create",
+		Options: options,
+		Devices: Devices{"device": *device},
+	}
+}
diff --git a/internal/osbuild2/lvm2_lv_device.go b/internal/osbuild2/lvm2_lv_device.go
new file mode 100644
index 000000000..ebddd17bc
--- /dev/null
+++ b/internal/osbuild2/lvm2_lv_device.go
@@ -0,0 +1,17 @@
+package osbuild2
+
+// Provide access to LVM2 Logical Volume (LV)
+
+type LVM2LVDeviceOptions struct {
+	// Logical volume to activate
+	Volume string `json:"volume"`
+}
+
+func (LVM2LVDeviceOptions) isDeviceOptions() {}
+
+func NewLVM2LVDevice(options *LoopbackDeviceOptions) *Device {
+	return &Device{
+		Type:    "org.osbuild.lvm2.lv",
+		Options: options,
+	}
+}
diff --git a/internal/osbuild2/lvm2_metadata_stage.go b/internal/osbuild2/lvm2_metadata_stage.go
new file mode 100644
index 000000000..b43fd8f9a
--- /dev/null
+++ b/internal/osbuild2/lvm2_metadata_stage.go
@@ -0,0 +1,46 @@
+package osbuild2
+
+import (
+	"fmt"
+	"regexp"
+	"strconv"
+)
+
+// Set LVM2 Volume Group metadata
+
+type LVM2MetadataStageOptions struct {
+	CreationHost string `json:"creation_host,omitempty"`
+
+	// Creation time (uint64 represented as string)
+	CreationTime string `json:"creation_time,omitempty"`
+
+	Description string `json:"description,omitempty"`
+
+	VGName string `json:"vg_name"`
+}
+
+func (LVM2MetadataStageOptions) isStageOptions() {}
+
+func (o LVM2MetadataStageOptions) validate() error {
+	nameRegex := regexp.MustCompile(lvmVolNameRegex)
+	if !nameRegex.MatchString(o.VGName) {
+		return fmt.Errorf("volume group name %q doesn't conform to schema (%s)", o.VGName, nameRegex.String())
+	}
+
+	if _, err := strconv.ParseUint(o.CreationTime, 10, 64); err != nil {
+		return fmt.Errorf("invalid volume creation time: %s", o.CreationTime)
+	}
+	return nil
+}
+
+func NewLVM2MetadataStage(options *LVM2MetadataStageOptions, device *Device) *Stage {
+	if err := options.validate(); err != nil {
+		panic(err)
+	}
+
+	return &Stage{
+		Type:    "org.osbuild.lvm2.metadata",
+		Options: options,
+		Devices: Devices{"device": *device},
+	}
+}
diff --git a/internal/osbuild2/mkdir_stage.go b/internal/osbuild2/mkdir_stage.go
new file mode 100644
index 000000000..6a386299f
--- /dev/null
+++ b/internal/osbuild2/mkdir_stage.go
@@ -0,0 +1,24 @@
+package osbuild2
+
+import "os"
+
+// Options for the org.osbuild.ostree.config stage.
+type MkdirStageOptions struct {
+	Paths []Path `json:"paths"`
+}
+
+type Path struct {
+	Path string `json:"path"`
+
+	Mode os.FileMode `json:"mode,omitempty"`
+}
+
+func (MkdirStageOptions) isStageOptions() {}
+
+// A new org.osbuild.ostree.init stage to create an OSTree repository
+func NewMkdirStage(options *MkdirStageOptions) *Stage {
+	return &Stage{
+		Type:    "org.osbuild.mkdir",
+		Options: options,
+	}
+}
diff --git a/internal/osbuild2/ostree_config_stage.go b/internal/osbuild2/ostree_config_stage.go
new file mode 100644
index 000000000..ead325685
--- /dev/null
+++ b/internal/osbuild2/ostree_config_stage.go
@@ -0,0 +1,28 @@
+package osbuild2
+
+// Options for the org.osbuild.ostree.config stage.
+type OSTreeConfigStageOptions struct {
+	// Location of the ostree repo
+	Repo string `json:"repo"`
+
+	Config *OSTreeConfig `json:"config,omitempty"`
+}
+
+func (OSTreeConfigStageOptions) isStageOptions() {}
+
+type OSTreeConfig struct {
+	// Options concerning the sysroot
+	Sysroot *SysrootOptions `json:"sysroot,omitempty"`
+}
+
+type SysrootOptions struct {
+	ReadOnly *bool `json:"readonly,omitempty"`
+}
+
+// A new org.osbuild.ostree.init stage to create an OSTree repository
+func NewOSTreeConfigStage(options *OSTreeConfigStageOptions) *Stage {
+	return &Stage{
+		Type:    "org.osbuild.ostree.config",
+		Options: options,
+	}
+}
diff --git a/internal/osbuild2/ostree_deploy_stage.go b/internal/osbuild2/ostree_deploy_stage.go
new file mode 100644
index 000000000..066f626d5
--- /dev/null
+++ b/internal/osbuild2/ostree_deploy_stage.go
@@ -0,0 +1,50 @@
+package osbuild2
+
+import (
+	"encoding/json"
+	"fmt"
+)
+
+// Options for the org.osbuild.ostree.deploy stage.
+type OSTreeDeployStageOptions struct {
+	OsName string `json:"osname"`
+
+	Ref string `json:"ref"`
+
+	Mounts []string `json:"mounts"`
+
+	Rootfs Rootfs `json:"rootfs"`
+
+	KernelOpts []string `json:"kernel_opts"`
+}
+
+type Rootfs struct {
+	// Identify the root file system by label
+	Label string `json:"label,omitempty"`
+
+	// Identify the root file system by UUID
+	UUID string `json:"uuid,omitempty"`
+}
+
+func (OSTreeDeployStageOptions) isStageOptions() {}
+
+// A new org.osbuild.ostree.init stage to create an OSTree repository
+func NewOSTreeDeployStage(options *OSTreeDeployStageOptions) *Stage {
+	return &Stage{
+		Type:    "org.osbuild.ostree.deploy",
+		Options: options,
+	}
+}
+
+// alias for custom marshaller
+type ostreeDeployStageOptions OSTreeDeployStageOptions
+
+func (options OSTreeDeployStageOptions) MarshalJSON() ([]byte, error) {
+	rootfs := options.Rootfs
+	if (len(rootfs.UUID) == 0 && len(rootfs.Label) == 0) || (len(rootfs.UUID) != 0 && len(rootfs.Label) != 0) {
+		return nil, fmt.Errorf("exactly one of UUID or Label must be specified")
+	}
+
+	aliasOptions := ostreeDeployStageOptions(options)
+	return json.Marshal(aliasOptions)
+}
diff --git a/internal/osbuild2/ostree_fillvar_stage.go b/internal/osbuild2/ostree_fillvar_stage.go
new file mode 100644
index 000000000..8f8d192c4
--- /dev/null
+++ b/internal/osbuild2/ostree_fillvar_stage.go
@@ -0,0 +1,24 @@
+package osbuild2
+
+// Options for the org.osbuild.ostree.fillvar stage.
+type OSTreeFillvarStageOptions struct {
+	Deployment OSTreeDeployment `json:"deployment"`
+}
+
+type OSTreeDeployment struct {
+	OSName string `json:"osname"`
+
+	Ref string `json:"ref"`
+
+	Serial *int `json:"serial,omitempty"`
+}
+
+func (OSTreeFillvarStageOptions) isStageOptions() {}
+
+// A new org.osbuild.ostree.init stage to create an OSTree repository
+func NewOSTreeFillvarStage(options *OSTreeFillvarStageOptions) *Stage {
+	return &Stage{
+		Type:    "org.osbuild.ostree.fillvar",
+		Options: options,
+	}
+}
diff --git a/internal/osbuild2/ostree_init_fs_stage.go b/internal/osbuild2/ostree_init_fs_stage.go
new file mode 100644
index 000000000..ae04467bd
--- /dev/null
+++ b/internal/osbuild2/ostree_init_fs_stage.go
@@ -0,0 +1,8 @@
+package osbuild2
+
+// A new org.osbuild.ostree.init stage to create an OSTree repository
+func OSTreeInitFsStage() *Stage {
+	return &Stage{
+		Type: "org.osbuild.ostree.init-fs",
+	}
+}
diff --git a/internal/osbuild2/ostree_os_init_stage.go b/internal/osbuild2/ostree_os_init_stage.go
new file mode 100644
index 000000000..72cb91341
--- /dev/null
+++ b/internal/osbuild2/ostree_os_init_stage.go
@@ -0,0 +1,17 @@
+package osbuild2
+
+// Options for the org.osbuild.ostree.os-init stage.
+type OSTreeOsInitStageOptions struct {
+	// Name of the OS
+	OSName string `json:"osname"`
+}
+
+func (OSTreeOsInitStageOptions) isStageOptions() {}
+
+// A new org.osbuild.ostree.init stage to create an OSTree repository
+func NewOSTreeOsInitStage(options *OSTreeOsInitStageOptions) *Stage {
+	return &Stage{
+		Type:    "org.osbuild.ostree.os-init",
+		Options: options,
+	}
+}
diff --git a/internal/osbuild2/ostree_preptree_stage.go b/internal/osbuild2/ostree_preptree_stage.go
index 6e0ba91d5..4ae592756 100644
--- a/internal/osbuild2/ostree_preptree_stage.go
+++ b/internal/osbuild2/ostree_preptree_stage.go
@@ -1,7 +1,16 @@
 package osbuild2
 
+// Transforms the tree to an ostree layout
+
 type OSTreePrepTreeStageOptions struct {
+	// Array of group names to still keep in /etc/group
 	EtcGroupMembers []string `json:"etc_group_members,omitempty"`
+
+	// Array of arguments passed to dracut
+	InitramfsArgs []string `json:"initramfs-args,omitempty"`
+
+	// Create a regular directory for /tmp
+	TmpIsDir *bool `json:"tmp-is-dir,omitempty"`
 }
 
 func (OSTreePrepTreeStageOptions) isStageOptions() {}
diff --git a/internal/osbuild2/ostree_remotes_stage.go b/internal/osbuild2/ostree_remotes_stage.go
new file mode 100644
index 000000000..f81de2add
--- /dev/null
+++ b/internal/osbuild2/ostree_remotes_stage.go
@@ -0,0 +1,36 @@
+package osbuild2
+
+// Configure OSTree remotes for a repository
+
+// Options for the org.osbuild.ostree.remotes stage.
+type OSTreeRemotesStageOptions struct {
+	// Location of the ostree repo
+	Repo string `json:"repo"`
+
+	// Configure remotes for the system repository
+	Remotes []OSTreeRemote `json:"remotes,omitempty"`
+}
+
+func (OSTreeRemotesStageOptions) isStageOptions() {}
+
+type OSTreeRemote struct {
+	// Identifier for the remote
+	Name string `json:"name"`
+
+	// URL of the repository.
+	URL string `json:"url"`
+
+	// Configured branches for the remote
+	Branches []string `json:"branches,omitempty"`
+
+	// GPG keys to verify the commits
+	GPGKeys []string `json:"secrets,omitempty"`
+}
+
+// A new org.osbuild.ostree.remotes stage to configure remotes
+func NewOSTreeRemotesStage(options *OSTreeRemotesStageOptions) *Stage {
+	return &Stage{
+		Type:    "org.osbuild.ostree.remotes",
+		Options: options,
+	}
+}
diff --git a/internal/osbuild2/ostree_selinux_stage.go b/internal/osbuild2/ostree_selinux_stage.go
new file mode 100644
index 000000000..e2a0b27ea
--- /dev/null
+++ b/internal/osbuild2/ostree_selinux_stage.go
@@ -0,0 +1,17 @@
+package osbuild2
+
+// Options for the org.osbuild.ostree.selinux stage.
+type OSTreeSelinuxStageOptions struct {
+	// shared with ostree.fillvar
+	Deployment OSTreeDeployment `json:"deployment"`
+}
+
+func (OSTreeSelinuxStageOptions) isStageOptions() {}
+
+// A new org.osbuild.ostree.init stage to create an OSTree repository
+func NewOSTreeSelinuxStage(options *OSTreeSelinuxStageOptions) *Stage {
+	return &Stage{
+		Type:    "org.osbuild.ostree.selinux",
+		Options: options,
+	}
+}
diff --git a/internal/osbuild2/ostree_source.go b/internal/osbuild2/ostree_source.go
index b64afaa41..6afacd886 100644
--- a/internal/osbuild2/ostree_source.go
+++ b/internal/osbuild2/ostree_source.go
@@ -8,10 +8,10 @@ type OSTreeSource struct {
 func (OSTreeSource) isSource() {}
 
 type OSTreeSourceItem struct {
-	Remote OSTreeRemote `json:"remote"`
+	Remote OSTreeSourceRemote `json:"remote"`
 }
 
-type OSTreeRemote struct {
+type OSTreeSourceRemote struct {
 	// URL of the repository.
 	URL string `json:"url"`
 	// GPG keys to verify the commits
diff --git a/internal/osbuild2/xorrisofs_stage.go b/internal/osbuild2/xorrisofs_stage.go
index 0a7698ca3..99724061f 100644
--- a/internal/osbuild2/xorrisofs_stage.go
+++ b/internal/osbuild2/xorrisofs_stage.go
@@ -10,7 +10,7 @@ type XorrisofsStageOptions struct {
 	// System ID to set
 	SysID string `json:"sysid,omitempty"`
 
-	Boot XorrisofsBoot `json:"boot,omitempty"`
+	Boot *XorrisofsBoot `json:"boot,omitempty"`
 
 	EFI string `json:"efi,omitempty"`
 
diff --git a/internal/store/json.go b/internal/store/json.go
index fb97bf213..7c84277ff 100644
--- a/internal/store/json.go
+++ b/internal/store/json.go
@@ -340,27 +340,32 @@ func (store *Store) toStoreV0() *storeV0 {
 }
 
 var imageTypeCompatMapping = map[string]string{
-	"vhd":                 "Azure",
-	"ami":                 "AWS",
-	"liveiso":             "LiveISO",
-	"openstack":           "OpenStack",
-	"qcow2":               "qcow2",
-	"vmdk":                "VMWare",
-	"ext4-filesystem":     "Raw-filesystem",
-	"partitioned-disk":    "Partitioned-disk",
-	"tar":                 "Tar",
-	"fedora-iot-commit":   "fedora-iot-commit",
-	"rhel-edge-commit":    "rhel-edge-commit",
-	"rhel-edge-container": "rhel-edge-container",
-	"rhel-edge-installer": "rhel-edge-installer",
-	"edge-commit":         "edge-commit",
-	"edge-container":      "edge-container",
-	"edge-installer":      "edge-installer",
-	"image-installer":     "image-installer",
-	"test_type":           "test_type",         // used only in json_test.go
-	"test_type_invalid":   "test_type_invalid", // used only in json_test.go
-	"ec2":                 "ec2",
-	"ec2-ha":              "ec2-ha",
+	"vhd":                            "Azure",
+	"ami":                            "AWS",
+	"liveiso":                        "LiveISO",
+	"openstack":                      "OpenStack",
+	"qcow2":                          "qcow2",
+	"vmdk":                           "VMWare",
+	"ext4-filesystem":                "Raw-filesystem",
+	"partitioned-disk":               "Partitioned-disk",
+	"tar":                            "Tar",
+	"fedora-iot-commit":              "fedora-iot-commit",
+	"rhel-edge-commit":               "rhel-edge-commit",
+	"rhel-edge-container":            "rhel-edge-container",
+	"rhel-edge-installer":            "rhel-edge-installer",
+	"rhel-raw-image":                 "rhel-raw-image",
+	"rhel-edge-raw-image":            "rhel-edge-raw-image",
+	"rhel-edge-simplified-installer": "rhel-edge-simplified-installer",
+	"edge-commit":                    "edge-commit",
+	"edge-container":                 "edge-container",
+	"edge-installer":                 "edge-installer",
+	"edge-raw-image":                 "edge-raw-image",
+	"edge-simplified-installer":      "edge-simplified-installer",
+	"image-installer":                "image-installer",
+	"test_type":                      "test_type",         // used only in json_test.go
+	"test_type_invalid":              "test_type_invalid", // used only in json_test.go
+	"ec2":                            "ec2",
+	"ec2-ha":                         "ec2-ha",
 }
 
 func imageTypeToCompatString(imgType distro.ImageType) string {
diff --git a/osbuild-composer.spec b/osbuild-composer.spec
index 92c9bc9ac..74c0e71b6 100644
--- a/osbuild-composer.spec
+++ b/osbuild-composer.spec
@@ -279,8 +279,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 >= 29
-Requires:   osbuild-ostree >= 29
+Requires:   osbuild >= 30
+Requires:   osbuild-ostree >= 30
 
 # 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 6bc3f8907..8ab7b91f1 100644
--- a/internal/blueprint/customizations_test.go
+++ b/internal/blueprint/customizations_test.go
@@ -6,6 +6,48 @@ import (
 	"github.com/stretchr/testify/assert"
 )
 
+func TestCheckAllowed(t *testing.T) {
+	Desc := "Test descritpion"
+	Pass := "testpass"
+	Key := "testkey"
+	Home := "Home"
+	Shell := "Shell"
+	Groups := []string{
+		"Group",
+	}
+	UID := 123
+	GID := 321
+
+	expectedUsers := []UserCustomization{
+		UserCustomization{
+			Name:        "John",
+			Description: &Desc,
+			Password:    &Pass,
+			Key:         &Key,
+			Home:        &Home,
+			Shell:       &Shell,
+			Groups:      Groups,
+			UID:         &UID,
+			GID:         &GID,
+		},
+	}
+
+	var expectedHostname = "Hostname"
+
+	x := Customizations{Hostname: &expectedHostname, User: expectedUsers}
+
+	err := x.CheckAllowed("Hostname", "User")
+	assert.NoError(t, err)
+
+	// "User" not allowed anymore
+	err = x.CheckAllowed("Hostname")
+	assert.Error(t, err)
+
+	// "Hostname" not allowed anymore
+	err = x.CheckAllowed("User")
+	assert.Error(t, err)
+}
+
 func TestGetHostname(t *testing.T) {
 
 	var expectedHostname = "Hostname"
diff --git a/internal/distro/rhel85/distro_test.go b/internal/distro/rhel85/distro_test.go
index eaa00b3df..cc03e6d69 100644
--- a/internal/distro/rhel85/distro_test.go
+++ b/internal/distro/rhel85/distro_test.go
@@ -417,8 +417,10 @@ func TestDistro_ManifestError(t *testing.T) {
 			_, err := imgType.Manifest(bp.Customizations, imgOpts, nil, nil, 0)
 			if imgTypeName == "edge-commit" || imgTypeName == "edge-container" {
 				assert.EqualError(t, err, "kernel boot parameter customizations are not supported for ostree types")
-			} else if imgTypeName == "edge-installer" {
-				assert.EqualError(t, err, "boot ISO image type \"edge-installer\" requires specifying a URL from which to retrieve the OSTree commit")
+			} else if imgTypeName == "edge-raw-image" {
+				assert.EqualError(t, err, "edge raw images require specifying a URL from which to retrieve the OSTree commit")
+			} else if imgTypeName == "edge-installer" || imgTypeName == "edge-simplified-installer" {
+				assert.EqualError(t, err, fmt.Sprintf("boot ISO image type \"%s\" requires specifying a URL from which to retrieve the OSTree commit", imgTypeName))
 			} else {
 				assert.NoError(t, err)
 			}
@@ -445,6 +447,8 @@ func TestArchitecture_ListImageTypes(t *testing.T) {
 				"edge-commit",
 				"edge-container",
 				"edge-installer",
+				"edge-raw-image",
+				"edge-simplified-installer",
 				"tar",
 				"image-installer",
 			},
@@ -458,6 +462,9 @@ func TestArchitecture_ListImageTypes(t *testing.T) {
 				"ec2",
 				"edge-commit",
 				"edge-container",
+				"edge-installer",
+				"edge-simplified-installer",
+				"edge-raw-image",
 				"tar",
 			},
 		},
@@ -574,7 +581,7 @@ func TestDistro_CustomFileSystemManifestError(t *testing.T) {
 			_, err := imgType.Manifest(bp.Customizations, distro.ImageOptions{}, nil, nil, 0)
 			if imgTypeName == "edge-commit" || imgTypeName == "edge-container" {
 				assert.EqualError(t, err, "Custom mountpoints are not supported for ostree types")
-			} else if imgTypeName == "edge-installer" {
+			} else if imgTypeName == "edge-installer" || imgTypeName == "edge-simplified-installer" || imgTypeName == "edge-raw-image" {
 				continue
 			} else {
 				assert.EqualError(t, err, "The following custom mountpoints are not supported [\"/boot\"]")
@@ -602,7 +609,7 @@ func TestDistro_TestRootMountPoint(t *testing.T) {
 			_, err := imgType.Manifest(bp.Customizations, distro.ImageOptions{}, nil, nil, 0)
 			if imgTypeName == "edge-commit" || imgTypeName == "edge-container" {
 				assert.EqualError(t, err, "Custom mountpoints are not supported for ostree types")
-			} else if imgTypeName == "edge-installer" {
+			} else if imgTypeName == "edge-installer" || imgTypeName == "edge-simplified-installer" || imgTypeName == "edge-raw-image" {
 				continue
 			} else {
 				assert.NoError(t, err)
@@ -630,7 +637,7 @@ func TestDistro_CustomFileSystemSubDirectories(t *testing.T) {
 			_, err := imgType.Manifest(bp.Customizations, distro.ImageOptions{}, nil, nil, 0)
 			if imgTypeName == "edge-commit" || imgTypeName == "edge-container" {
 				assert.EqualError(t, err, "Custom mountpoints are not supported for ostree types")
-			} else if imgTypeName == "edge-installer" {
+			} else if imgTypeName == "edge-installer" || imgTypeName == "edge-simplified-installer" || imgTypeName == "edge-raw-image" {
 				continue
 			} else {
 				assert.NoError(t, err)
@@ -658,7 +665,7 @@ func TestDistro_CustomFileSystemPatternMatching(t *testing.T) {
 			_, err := imgType.Manifest(bp.Customizations, distro.ImageOptions{}, nil, nil, 0)
 			if imgTypeName == "edge-commit" || imgTypeName == "edge-container" {
 				assert.EqualError(t, err, "Custom mountpoints are not supported for ostree types")
-			} else if imgTypeName == "edge-installer" {
+			} else if imgTypeName == "edge-installer" || imgTypeName == "edge-simplified-installer" || imgTypeName == "edge-raw-image" {
 				continue
 			} else {
 				assert.EqualError(t, err, "The following custom mountpoints are not supported [\"/variable\"]")
@@ -686,7 +693,7 @@ func TestDistro_CustomUsrPartitionNotLargeEnough(t *testing.T) {
 			_, err := imgType.Manifest(bp.Customizations, distro.ImageOptions{}, nil, nil, 0)
 			if imgTypeName == "edge-commit" || imgTypeName == "edge-container" {
 				assert.EqualError(t, err, "Custom mountpoints are not supported for ostree types")
-			} else if imgTypeName == "edge-installer" {
+			} else if imgTypeName == "edge-installer" || imgTypeName == "edge-simplified-installer" || imgTypeName == "edge-raw-image" {
 				continue
 			} else {
 				assert.NoError(t, err)
diff --git a/internal/osbuild2/lvm2_create_stage_test.go b/internal/osbuild2/lvm2_create_stage_test.go
new file mode 100644
index 000000000..0ede0f3c9
--- /dev/null
+++ b/internal/osbuild2/lvm2_create_stage_test.go
@@ -0,0 +1,60 @@
+package osbuild2
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestNewLVM2CreateStageValidation(t *testing.T) {
+	assert := assert.New(t)
+
+	okOptions := LVM2CreateStageOptions{
+		Volumes: []LogicalVolume{
+			{
+				Name: "a_volume_name",
+				Size: "",
+			},
+			{
+				Name: "good-volume.name",
+				Size: "10G",
+			},
+			{
+				Name: "99-luft+volumes",
+				Size: "10737418240",
+			},
+			{
+				Name: "++",
+				Size: "1337",
+			},
+			{
+				Name: "_",
+				Size: "0",
+			},
+		},
+	}
+	assert.NoError(okOptions.validate())
+
+	badVolumes := []LogicalVolume{
+		{
+			Name: "!bad-bad-volume-name",
+			Size: "1337",
+		},
+		{
+			Name: "even worse",
+		},
+		{
+			Name: "-",
+		},
+	}
+
+	for _, vol := range badVolumes {
+		options := LVM2CreateStageOptions{
+			Volumes: []LogicalVolume{vol},
+		}
+		assert.Error(options.validate(), vol.Name)
+	}
+
+	empty := LVM2CreateStageOptions{}
+	assert.Error(empty.validate())
+}
diff --git a/internal/osbuild2/lvm2_lv_device_test.go b/internal/osbuild2/lvm2_lv_device_test.go
new file mode 100644
index 000000000..d0a454639
--- /dev/null
+++ b/internal/osbuild2/lvm2_lv_device_test.go
@@ -0,0 +1,1 @@
+package osbuild2
diff --git a/internal/osbuild2/lvm2_metadata_stage_test.go b/internal/osbuild2/lvm2_metadata_stage_test.go
new file mode 100644
index 000000000..f83e55699
--- /dev/null
+++ b/internal/osbuild2/lvm2_metadata_stage_test.go
@@ -0,0 +1,55 @@
+package osbuild2
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestNewLVM2MetadataStageValidation(t *testing.T) {
+	assert := assert.New(t)
+
+	okOptions := []LVM2MetadataStageOptions{
+		{
+			VGName:       "a_volume_name",
+			CreationTime: "0",
+		},
+		{
+			VGName:       "good-volume.name",
+			CreationTime: "1629282647",
+		},
+		{
+			VGName:       "99-luft+volumes",
+			CreationTime: "2147483648",
+		},
+		{
+			VGName:       "++",
+			CreationTime: "42",
+		},
+		{
+			VGName:       "_",
+			CreationTime: "4294967297",
+		},
+	}
+	for _, o := range okOptions {
+		assert.NoError(o.validate(), o)
+	}
+
+	badOptions := []LVM2MetadataStageOptions{
+		{
+			VGName:       "ok-name-bad-time",
+			CreationTime: "-10",
+		},
+		{
+			VGName:       "!bad-name",
+			CreationTime: "1629282647",
+		},
+		{
+			VGName:       "worse.time",
+			CreationTime: "TIME",
+		},
+	}
+	for _, o := range badOptions {
+		assert.Error(o.validate(), o)
+	}
+}
diff --git a/test/cases/ostree-raw-image.sh b/test/cases/ostree-raw-image.sh
new file mode 100755
index 000000000..5c76dbef3
--- /dev/null
+++ b/test/cases/ostree-raw-image.sh
@@ -0,0 +1,582 @@
+#!/bin/bash
+set -euo pipefail
+
+# Provision the software under test.
+/usr/libexec/osbuild-composer-test/provision.sh
+
+# Get OS data.
+source /etc/os-release
+ARCH=$(uname -m)
+
+# Colorful output.
+function greenprint {
+    echo -e "\033[1;32m${1}\033[0m"
+}
+
+# Start libvirtd and test it.
+greenprint "🚀 Starting libvirt daemon"
+sudo systemctl start libvirtd
+sudo virsh list --all > /dev/null
+
+# Set a customized dnsmasq configuration for libvirt so we always get the
+# same address on bootup.
+sudo tee /tmp/integration.xml > /dev/null << EOF
+<network>
+  <name>integration</name>
+  <uuid>1c8fe98c-b53a-4ca4-bbdb-deb0f26b3579</uuid>
+  <forward mode='nat'>
+    <nat>
+      <port start='1024' end='65535'/>
+    </nat>
+  </forward>
+  <bridge name='integration' stp='on' delay='0'/>
+  <mac address='52:54:00:36:46:ef'/>
+  <ip address='192.168.100.1' netmask='255.255.255.0'>
+    <dhcp>
+      <range start='192.168.100.2' end='192.168.100.254'/>
+      <host mac='34:49:22:B0:83:30' name='vm-bios' ip='192.168.100.50'/>
+      <host mac='34:49:22:B0:83:31' name='vm-uefi' ip='192.168.100.51'/>
+    </dhcp>
+  </ip>
+</network>
+EOF
+if ! sudo virsh net-info integration > /dev/null 2>&1; then
+    sudo virsh net-define /tmp/integration.xml
+fi
+if [[ $(sudo virsh net-info integration | grep 'Active' | awk '{print $2}') == 'no' ]]; then
+    sudo virsh net-start integration
+fi
+
+# Allow anyone in the wheel group to talk to libvirt.
+greenprint "🚪 Allowing users in wheel group to talk to libvirt"
+sudo tee /etc/polkit-1/rules.d/50-libvirt.rules > /dev/null << EOF
+polkit.addRule(function(action, subject) {
+    if (action.id == "org.libvirt.unix.manage" &&
+        subject.isInGroup("adm")) {
+            return polkit.Result.YES;
+    }
+});
+EOF
+
+# Set up variables.
+OSTREE_REF="rhel/8/${ARCH}/edge"
+OS_VARIANT="rhel8-unknown"
+TEST_UUID=$(uuidgen)
+IMAGE_KEY="edge-${TEST_UUID}"
+UEFI_GUEST_ADDRESS=192.168.100.51
+PROD_REPO_URL=http://192.168.100.1/repo
+PROD_REPO=/var/www/html/repo
+STAGE_REPO_ADDRESS=192.168.200.1
+STAGE_REPO_URL="http://${STAGE_REPO_ADDRESS}:8080/repo/"
+ARTIFACTS="ci-artifacts"
+mkdir -p "${ARTIFACTS}"
+
+# Set up temporary files.
+TEMPDIR=$(mktemp -d)
+BLUEPRINT_FILE=${TEMPDIR}/blueprint.toml
+COMPOSE_START=${TEMPDIR}/compose-start-${IMAGE_KEY}.json
+COMPOSE_INFO=${TEMPDIR}/compose-info-${IMAGE_KEY}.json
+
+# SSH setup.
+SSH_OPTIONS=(-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=5)
+SSH_DATA_DIR=$(/usr/libexec/osbuild-composer-test/gen-ssh.sh)
+SSH_KEY=${SSH_DATA_DIR}/id_rsa
+SSH_KEY_PUB=$(cat "${SSH_KEY}".pub)
+
+case "${ID}-${VERSION_ID}" in
+    "rhel-8.5")
+        CONTAINER_TYPE=edge-container
+        CONTAINER_FILENAME=container.tar
+        INSTALLER_TYPE=edge-raw-image
+        INSTALLER_FILENAME=image.raw.xz
+        ;;
+    "rhel-9.0")
+        CONTAINER_TYPE=edge-container
+        CONTAINER_FILENAME=container.tar
+        INSTALLER_TYPE=edge-raw-image
+        INSTALLER_FILENAME=image.raw.xz
+        ;;
+    *)
+        echo "unsupported distro: ${ID}-${VERSION_ID}"
+        exit 1;;
+esac
+
+
+# Get the compose log.
+get_compose_log () {
+    COMPOSE_ID=$1
+    LOG_FILE=${ARTIFACTS}/osbuild-${ID}-${VERSION_ID}-${COMPOSE_ID}.log
+
+    # Download the logs.
+    sudo composer-cli compose log "$COMPOSE_ID" | tee "$LOG_FILE" > /dev/null
+}
+
+# Get the compose metadata.
+get_compose_metadata () {
+    COMPOSE_ID=$1
+    METADATA_FILE=${ARTIFACTS}/osbuild-${ID}-${VERSION_ID}-${COMPOSE_ID}.json
+
+    # Download the metadata.
+    sudo composer-cli compose metadata "$COMPOSE_ID" > /dev/null
+
+    # Find the tarball and extract it.
+    TARBALL=$(basename "$(find . -maxdepth 1 -type f -name "*-metadata.tar")")
+    tar -xf "$TARBALL" -C "${TEMPDIR}"
+    rm -f "$TARBALL"
+
+    # Move the JSON file into place.
+    cat "${TEMPDIR}"/"${COMPOSE_ID}".json | jq -M '.' | tee "$METADATA_FILE" > /dev/null
+}
+
+# Build ostree image.
+build_image() {
+    blueprint_name=$1
+    image_type=$2
+
+    # Get worker unit file so we can watch the journal.
+    WORKER_UNIT=$(sudo systemctl list-units | grep -o -E "osbuild.*worker.*\.service")
+    sudo journalctl -af -n 1 -u "${WORKER_UNIT}" &
+    WORKER_JOURNAL_PID=$!
+    # Stop watching the worker journal when exiting.
+    trap 'sudo pkill -P ${WORKER_JOURNAL_PID}' EXIT
+
+    # Start the compose.
+    greenprint "🚀 Starting compose"
+    if [ $# -eq 3 ]; then
+        repo_url=$3
+        sudo composer-cli --json compose start-ostree --ref "$OSTREE_REF" --url "$repo_url" "$blueprint_name" "$image_type" | tee "$COMPOSE_START"
+    else
+        sudo composer-cli --json compose start-ostree --ref "$OSTREE_REF" "$blueprint_name" "$image_type" | tee "$COMPOSE_START"
+    fi
+    COMPOSE_ID=$(jq -r '.build_id' "$COMPOSE_START")
+
+    # Wait for the compose to finish.
+    greenprint "⏱ Waiting for compose to finish: ${COMPOSE_ID}"
+    while true; do
+        sudo composer-cli --json compose info "${COMPOSE_ID}" | tee "$COMPOSE_INFO" > /dev/null
+        COMPOSE_STATUS=$(jq -r '.queue_status' "$COMPOSE_INFO")
+
+        # Is the compose finished?
+        if [[ $COMPOSE_STATUS != RUNNING ]] && [[ $COMPOSE_STATUS != WAITING ]]; then
+            break
+        fi
+
+        # Wait 30 seconds and try again.
+        sleep 5
+    done
+
+    # Capture the compose logs from osbuild.
+    greenprint "💬 Getting compose log and metadata"
+    get_compose_log "$COMPOSE_ID"
+    get_compose_metadata "$COMPOSE_ID"
+
+    # Kill the journal monitor immediately and remove the trap
+    sudo pkill -P ${WORKER_JOURNAL_PID}
+    trap - EXIT
+
+    # Did the compose finish with success?
+    if [[ $COMPOSE_STATUS != FINISHED ]]; then
+        echo "Something went wrong with the compose. 😢"
+        exit 1
+    fi
+}
+
+# Wait for the ssh server up to be.
+wait_for_ssh_up () {
+    SSH_STATUS=$(sudo ssh "${SSH_OPTIONS[@]}" -i "${SSH_KEY}" admin@"${1}" '/bin/bash -c "echo -n READY"')
+    if [[ $SSH_STATUS == READY ]]; then
+        echo 1
+    else
+        echo 0
+    fi
+}
+
+# Clean up our mess.
+clean_up () {
+    greenprint "🧼 Cleaning up"
+
+    # Clear vm
+    if [[ $(sudo virsh domstate "${IMAGE_KEY}-uefi") == "running" ]]; then
+        sudo virsh destroy "${IMAGE_KEY}-uefi"
+    fi
+    sudo virsh undefine "${IMAGE_KEY}-uefi" --nvram
+    # Remove qcow2 file.
+    sudo rm -f "$LIBVIRT_IMAGE_PATH"
+
+    # Remove any status containers if exist
+    sudo podman ps -a -q --format "{{.ID}}" | sudo xargs --no-run-if-empty podman rm -f
+    # Remove all images
+    sudo podman rmi -f -a
+
+    # Remove prod repo
+    sudo rm -rf "$PROD_REPO"
+
+    # Remomve tmp dir.
+    sudo rm -rf "$TEMPDIR"
+
+    # Stop prod repo http service
+    sudo systemctl disable --now httpd
+}
+
+# Test result checking
+check_result () {
+    greenprint "🎏 Checking for test result"
+    if [[ $RESULTS == 1 ]]; then
+        greenprint "💚 Success"
+    else
+        greenprint "❌ Failed"
+        clean_up
+        exit 1
+    fi
+}
+
+###########################################################
+##
+## Prepare edge prod and stage repo
+##
+###########################################################
+greenprint "🔧 Prepare edge prod repo"
+# Start prod repo web service
+# osbuild-composer-tests have mod_ssl as a dependency. The package installs
+# an example configuration which automatically enabled httpd on port 443, but
+# that one is already in use. Remove the default configuration as it is useless
+# anyway.
+sudo rm -f /etc/httpd/conf.d/ssl.conf
+sudo systemctl enable --now httpd.service
+
+# Have a clean prod repo
+sudo rm -rf "$PROD_REPO"
+sudo mkdir -p "$PROD_REPO"
+sudo ostree --repo="$PROD_REPO" init --mode=archive
+sudo ostree --repo="$PROD_REPO" remote add --no-gpg-verify edge-stage "$STAGE_REPO_URL"
+
+# Prepare stage repo network
+greenprint "🔧 Prepare stage repo network"
+sudo podman network inspect edge >/dev/null 2>&1 || sudo podman network create --driver=bridge --subnet=192.168.200.0/24 --ip-range=192.168.200.0/24 --gateway=192.168.200.254 edge
+
+##########################################################
+##
+## Build edge-container image and start it in podman
+##
+##########################################################
+
+# Write a blueprint for ostree image.
+tee "$BLUEPRINT_FILE" > /dev/null << EOF
+name = "container"
+description = "A base rhel-edge container image"
+version = "0.0.1"
+modules = []
+groups = []
+
+[[packages]]
+name = "python36"
+version = "*"
+
+[customizations.kernel]
+name = "kernel-rt"
+
+[[customizations.user]]
+name = "admin"
+description = "Administrator account"
+password = "\$6\$GRmb7S0p8vsYmXzH\$o0E020S.9JQGaHkszoog4ha4AQVs3sk8q0DvLjSMxoxHBKnB2FBXGQ/OkwZQfW/76ktHd0NX5nls2LPxPuUdl."
+key = "${SSH_KEY_PUB}"
+home = "/home/admin/"
+groups = ["wheel"]
+EOF
+
+greenprint "📄 container blueprint"
+cat "$BLUEPRINT_FILE"
+
+# Prepare the blueprint for the compose.
+greenprint "📋 Preparing container blueprint"
+sudo composer-cli blueprints push "$BLUEPRINT_FILE"
+sudo composer-cli blueprints depsolve container
+
+# Build container image.
+build_image container "${CONTAINER_TYPE}"
+
+# Download the image
+greenprint "📥 Downloading the container image"
+sudo composer-cli compose image "${COMPOSE_ID}" > /dev/null
+
+# Clear stage repo running env
+greenprint "🧹 Clearing stage repo running env"
+# Remove any status containers if exist
+sudo podman ps -a -q --format "{{.ID}}" | sudo xargs --no-run-if-empty podman rm -f
+# Remove all images
+sudo podman rmi -f -a
+
+# Deal with stage repo image
+greenprint "🗜 Starting container"
+IMAGE_FILENAME="${COMPOSE_ID}-${CONTAINER_FILENAME}"
+sudo podman pull "oci-archive:${IMAGE_FILENAME}"
+sudo podman images
+# Run edge stage repo
+greenprint "🛰 Running edge stage repo"
+# Get image id to run image
+EDGE_IMAGE_ID=$(sudo podman images --filter "dangling=true" --format "{{.ID}}")
+sudo podman run -d --name rhel-edge --network edge --ip "$STAGE_REPO_ADDRESS" "$EDGE_IMAGE_ID"
+# Clear image file
+sudo rm -f "$IMAGE_FILENAME"
+
+# Wait for container to be running
+until [ "$(sudo podman inspect -f '{{.State.Running}}' rhel-edge)" == "true" ]; do
+    sleep 1;
+done;
+
+# Sync installer edge content
+greenprint "📡 Sync installer content from stage repo"
+sudo ostree --repo="$PROD_REPO" pull --mirror edge-stage "$OSTREE_REF"
+
+# Clean compose and blueprints.
+greenprint "🧽 Clean up container blueprint and compose"
+sudo composer-cli compose delete "${COMPOSE_ID}" > /dev/null
+sudo composer-cli blueprints delete container > /dev/null
+
+############################################################
+##
+## Build edge-raw-image
+##
+############################################################
+
+# Write a blueprint for installer image.
+tee "$BLUEPRINT_FILE" > /dev/null << EOF
+name = "installer"
+description = "A rhel-edge raw image"
+version = "0.0.1"
+modules = []
+groups = []
+EOF
+
+greenprint "📄 raw image blueprint"
+cat "$BLUEPRINT_FILE"
+
+# Prepare the blueprint for the compose.
+greenprint "📋 Preparing raw image blueprint"
+sudo composer-cli blueprints push "$BLUEPRINT_FILE"
+sudo composer-cli blueprints depsolve installer
+
+# Build installer image.
+# Test --url arg following by URL with tailling slash for bz#1942029
+build_image installer "${INSTALLER_TYPE}" "${PROD_REPO_URL}/"
+
+# Download the image
+greenprint "📥 Downloading the raw image"
+sudo composer-cli compose image "${COMPOSE_ID}" > /dev/null
+ISO_FILENAME="${COMPOSE_ID}-${INSTALLER_FILENAME}"
+
+greenprint "Extracting and converting the raw image to a qcow2 file"
+sudo xz -d "${ISO_FILENAME}"
+sudo qemu-img convert -f raw "${COMPOSE_ID}-image.raw" -O qcow2 "${IMAGE_KEY}-uefi.qcow2"
+sudo mv "${IMAGE_KEY}-uefi.qcow2" /var/lib/libvirt/images/
+LIBVIRT_IMAGE_PATH=/var/lib/libvirt/images/${IMAGE_KEY}-uefi.qcow2
+
+# Clean compose and blueprints.
+greenprint "🧹 Clean up installer blueprint and compose"
+sudo composer-cli compose delete "${COMPOSE_ID}" > /dev/null
+sudo composer-cli blueprints delete installer > /dev/null
+
+##################################################################
+##
+## Install and test edge vm with edge-raw-image (UEFI)
+##
+##################################################################
+
+# Ensure SELinux is happy with our new images.
+greenprint "👿 Running restorecon on image directory"
+sudo restorecon -Rv /var/lib/libvirt/images/
+
+greenprint "💿 Installing raw image on UEFI VM"
+sudo virt-install  --name="${IMAGE_KEY}-uefi"\
+                   --disk path="${LIBVIRT_IMAGE_PATH}",format=qcow2 \
+                   --ram 3072 \
+                   --vcpus 2 \
+                   --network network=integration,mac=34:49:22:B0:83:31 \
+                   --os-type linux \
+                   --os-variant ${OS_VARIANT} \
+                   --boot uefi,loader_ro=yes,loader_type=pflash,nvram_template=/usr/share/edk2/ovmf/OVMF_VARS.fd,loader_secure=no \
+                   --nographics \
+                   --noautoconsole \
+                   --wait=-1 \
+                   --noreboot
+
+# Start VM.
+greenprint "💻 Start UEFI VM"
+sudo virsh start "${IMAGE_KEY}-uefi"
+
+# Check for ssh ready to go.
+greenprint "🛃 Checking for SSH is ready to go"
+for LOOP_COUNTER in $(seq 0 30); do
+    RESULTS="$(wait_for_ssh_up $UEFI_GUEST_ADDRESS)"
+    if [[ $RESULTS == 1 ]]; then
+        echo "SSH is ready now! 🥳"
+        break
+    fi
+    sleep 10
+done
+
+# Check image installation result
+check_result
+
+greenprint "🕹 Get ostree install commit value"
+INSTALL_HASH=$(curl "${PROD_REPO_URL}/refs/heads/${OSTREE_REF}")
+
+# Add instance IP address into /etc/ansible/hosts
+sudo tee "${TEMPDIR}"/inventory > /dev/null << EOF
+[ostree_guest]
+${UEFI_GUEST_ADDRESS}
+
+[ostree_guest:vars]
+ansible_python_interpreter=/usr/bin/python3
+ansible_user=admin
+ansible_private_key_file=${SSH_KEY}
+ansible_ssh_common_args="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
+ansible_become=yes 
+ansible_become_method=sudo
+ansible_become_pass=${EDGE_USER_PASSWORD}
+EOF
+
+# Test IoT/Edge OS
+sudo ANSIBLE_STDOUT_CALLBACK=debug ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type=redhat -e ostree_commit="${INSTALL_HASH}" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0
+check_result
+
+##################################################################
+##
+## Upgrade and test edge vm with edge-raw-image (UEFI)
+##
+##################################################################
+
+# Write a blueprint for ostree image.
+# NB: no ssh key in the upgrade commit because there is no home dir
+tee "$BLUEPRINT_FILE" > /dev/null << EOF
+name = "upgrade"
+description = "An upgrade rhel-edge container image"
+version = "0.0.2"
+modules = []
+groups = []
+
+[[packages]]
+name = "python36"
+version = "*"
+
+[[packages]]
+name = "wget"
+version = "*"
+
+[customizations.kernel]
+name = "kernel-rt"
+
+[[customizations.user]]
+name = "admin"
+description = "Administrator account"
+password = "\$6\$GRmb7S0p8vsYmXzH\$o0E020S.9JQGaHkszoog4ha4AQVs3sk8q0DvLjSMxoxHBKnB2FBXGQ/OkwZQfW/76ktHd0NX5nls2LPxPuUdl."
+home = "/home/admin/"
+groups = ["wheel"]
+EOF
+
+greenprint "📄 upgrade blueprint"
+cat "$BLUEPRINT_FILE"
+
+# Prepare the blueprint for the compose.
+greenprint "📋 Preparing upgrade blueprint"
+sudo composer-cli blueprints push "$BLUEPRINT_FILE"
+sudo composer-cli blueprints depsolve upgrade
+
+# Build upgrade image.
+build_image upgrade  "${CONTAINER_TYPE}" "$PROD_REPO_URL"
+
+# Download the image
+greenprint "📥 Downloading the upgrade image"
+sudo composer-cli compose image "${COMPOSE_ID}" > /dev/null
+
+# Clear stage repo running env
+greenprint "🧹 Clearing stage repo running env"
+# Remove any status containers if exist
+sudo podman ps -a -q --format "{{.ID}}" | sudo xargs --no-run-if-empty podman rm -f
+# Remove all images
+sudo podman rmi -f -a
+
+# Deal with stage repo container
+greenprint "🗜 Extracting image"
+IMAGE_FILENAME="${COMPOSE_ID}-${CONTAINER_FILENAME}"
+sudo podman pull "oci-archive:${IMAGE_FILENAME}"
+sudo podman images
+# Clear image file
+sudo rm -f "$IMAGE_FILENAME"
+
+# Run edge stage repo
+greenprint "🛰 Running edge stage repo"
+# Get image id to run image
+EDGE_IMAGE_ID=$(sudo podman images --filter "dangling=true" --format "{{.ID}}")
+sudo podman run -d --name rhel-edge --network edge --ip "$STAGE_REPO_ADDRESS" "$EDGE_IMAGE_ID"
+# Wait for container to be running
+until [ "$(sudo podman inspect -f '{{.State.Running}}' rhel-edge)" == "true" ]; do
+    sleep 1;
+done;
+
+# Workaround to https://github.com/osbuild/osbuild-composer/issues/1693
+greenprint "🗳 Add external prod edge repo"
+sudo ssh "${SSH_OPTIONS[@]}" -i "${SSH_KEY}" admin@${UEFI_GUEST_ADDRESS} "echo ${EDGE_USER_PASSWORD} |sudo -S ostree remote add --no-gpg-verify --no-sign-verify rhel-edge ${PROD_REPO_URL}"
+sudo ssh "${SSH_OPTIONS[@]}" -i "${SSH_KEY}" admin@${UEFI_GUEST_ADDRESS} "echo ${EDGE_USER_PASSWORD} |sudo -S ostree admin switch rhel-edge:${OSTREE_REF}"
+
+# Pull upgrade to prod mirror
+greenprint "⛓ Pull upgrade to prod mirror"
+sudo ostree --repo="$PROD_REPO" pull --mirror edge-stage "$OSTREE_REF"
+sudo ostree --repo="$PROD_REPO" static-delta generate "$OSTREE_REF"
+sudo ostree --repo="$PROD_REPO" summary -u
+
+# Get ostree commit value.
+greenprint "🕹 Get ostree upgrade commit value"
+UPGRADE_HASH=$(curl "${PROD_REPO_URL}/refs/heads/${OSTREE_REF}")
+
+# Clean compose and blueprints.
+greenprint "🧽 Clean up upgrade blueprint and compose"
+sudo composer-cli compose delete "${COMPOSE_ID}" > /dev/null
+sudo composer-cli blueprints delete upgrade > /dev/null
+
+# Upgrade image/commit.
+greenprint "🗳 Upgrade ostree image/commit"
+sudo ssh "${SSH_OPTIONS[@]}" -i "${SSH_KEY}" admin@${UEFI_GUEST_ADDRESS} "echo ${EDGE_USER_PASSWORD} |sudo -S rpm-ostree upgrade"
+sudo ssh "${SSH_OPTIONS[@]}" -i "${SSH_KEY}" admin@${UEFI_GUEST_ADDRESS} "echo ${EDGE_USER_PASSWORD} |nohup sudo -S systemctl reboot &>/dev/null & exit"
+
+# Sleep 10 seconds here to make sure vm restarted already
+sleep 10
+
+# Check for ssh ready to go.
+greenprint "🛃 Checking for SSH is ready to go"
+# shellcheck disable=SC2034  # Unused variables left for readability
+for LOOP_COUNTER in $(seq 0 30); do
+    RESULTS="$(wait_for_ssh_up $UEFI_GUEST_ADDRESS)"
+    if [[ $RESULTS == 1 ]]; then
+        echo "SSH is ready now! 🥳"
+        break
+    fi
+    sleep 10
+done
+
+# Check ostree upgrade result
+check_result
+
+# Add instance IP address into /etc/ansible/hosts
+sudo tee "${TEMPDIR}"/inventory > /dev/null << EOF
+[ostree_guest]
+${UEFI_GUEST_ADDRESS}
+
+[ostree_guest:vars]
+ansible_python_interpreter=/usr/bin/python3
+ansible_user=admin
+ansible_private_key_file=${SSH_KEY}
+ansible_ssh_common_args="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
+ansible_become=yes 
+ansible_become_method=sudo
+ansible_become_pass=${EDGE_USER_PASSWORD}
+EOF
+
+# Test IoT/Edge OS
+sudo ANSIBLE_STDOUT_CALLBACK=debug ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type=redhat -e ostree_commit="${UPGRADE_HASH}" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0
+check_result
+
+# Final success clean up
+clean_up
+
+exit 0
diff --git a/test/cases/ostree-simplified-installer.sh b/test/cases/ostree-simplified-installer.sh
new file mode 100755
index 000000000..c1daa58bb
--- /dev/null
+++ b/test/cases/ostree-simplified-installer.sh
@@ -0,0 +1,587 @@
+#!/bin/bash
+set -euo pipefail
+
+# Provision the software under test.
+/usr/libexec/osbuild-composer-test/provision.sh
+
+# Get OS data.
+source /etc/os-release
+ARCH=$(uname -m)
+
+# Colorful output.
+function greenprint {
+    echo -e "\033[1;32m${1}\033[0m"
+}
+
+# Start libvirtd and test it.
+greenprint "🚀 Starting libvirt daemon"
+sudo systemctl start libvirtd
+sudo virsh list --all > /dev/null
+
+# Set a customized dnsmasq configuration for libvirt so we always get the
+# same address on bootup.
+sudo tee /tmp/integration.xml > /dev/null << EOF
+<network>
+  <name>integration</name>
+  <uuid>1c8fe98c-b53a-4ca4-bbdb-deb0f26b3579</uuid>
+  <forward mode='nat'>
+    <nat>
+      <port start='1024' end='65535'/>
+    </nat>
+  </forward>
+  <bridge name='integration' stp='on' delay='0'/>
+  <mac address='52:54:00:36:46:ef'/>
+  <ip address='192.168.100.1' netmask='255.255.255.0'>
+    <dhcp>
+      <range start='192.168.100.2' end='192.168.100.254'/>
+      <host mac='34:49:22:B0:83:30' name='vm-bios' ip='192.168.100.50'/>
+      <host mac='34:49:22:B0:83:31' name='vm-uefi' ip='192.168.100.51'/>
+    </dhcp>
+  </ip>
+</network>
+EOF
+if ! sudo virsh net-info integration > /dev/null 2>&1; then
+    sudo virsh net-define /tmp/integration.xml
+fi
+if [[ $(sudo virsh net-info integration | grep 'Active' | awk '{print $2}') == 'no' ]]; then
+    sudo virsh net-start integration
+fi
+
+# Allow anyone in the wheel group to talk to libvirt.
+greenprint "🚪 Allowing users in wheel group to talk to libvirt"
+sudo tee /etc/polkit-1/rules.d/50-libvirt.rules > /dev/null << EOF
+polkit.addRule(function(action, subject) {
+    if (action.id == "org.libvirt.unix.manage" &&
+        subject.isInGroup("adm")) {
+            return polkit.Result.YES;
+    }
+});
+EOF
+
+# Set up variables.
+OSTREE_REF="rhel/8/${ARCH}/edge"
+OS_VARIANT="rhel8-unknown"
+TEST_UUID=$(uuidgen)
+IMAGE_KEY="edge-${TEST_UUID}"
+UEFI_GUEST_ADDRESS=192.168.100.51
+PROD_REPO_URL=http://192.168.100.1/repo
+PROD_REPO=/var/www/html/repo
+STAGE_REPO_ADDRESS=192.168.200.1
+STAGE_REPO_URL="http://${STAGE_REPO_ADDRESS}:8080/repo/"
+ARTIFACTS="ci-artifacts"
+mkdir -p "${ARTIFACTS}"
+
+# Set up temporary files.
+TEMPDIR=$(mktemp -d)
+BLUEPRINT_FILE=${TEMPDIR}/blueprint.toml
+COMPOSE_START=${TEMPDIR}/compose-start-${IMAGE_KEY}.json
+COMPOSE_INFO=${TEMPDIR}/compose-info-${IMAGE_KEY}.json
+
+# SSH setup.
+SSH_OPTIONS=(-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=5)
+SSH_DATA_DIR=$(/usr/libexec/osbuild-composer-test/gen-ssh.sh)
+SSH_KEY=${SSH_DATA_DIR}/id_rsa
+SSH_KEY_PUB=$(cat "${SSH_KEY}".pub)
+
+case "${ID}-${VERSION_ID}" in
+    "rhel-8.5")
+        CONTAINER_TYPE=edge-container
+        CONTAINER_FILENAME=container.tar
+        INSTALLER_TYPE=edge-simplified-installer
+        INSTALLER_FILENAME=simplified-installer.iso
+        ;;
+    "rhel-9.0")
+        CONTAINER_TYPE=edge-container
+        CONTAINER_FILENAME=container.tar
+        INSTALLER_TYPE=edge-simplified-installer
+        INSTALLER_FILENAME=simplified-installer.iso
+        ;;
+    *)
+        echo "unsupported distro: ${ID}-${VERSION_ID}"
+        exit 1;;
+esac
+
+
+# Get the compose log.
+get_compose_log () {
+    COMPOSE_ID=$1
+    LOG_FILE=${ARTIFACTS}/osbuild-${ID}-${VERSION_ID}-${COMPOSE_ID}.log
+
+    # Download the logs.
+    sudo composer-cli compose log "$COMPOSE_ID" | tee "$LOG_FILE" > /dev/null
+}
+
+# Get the compose metadata.
+get_compose_metadata () {
+    COMPOSE_ID=$1
+    METADATA_FILE=${ARTIFACTS}/osbuild-${ID}-${VERSION_ID}-${COMPOSE_ID}.json
+
+    # Download the metadata.
+    sudo composer-cli compose metadata "$COMPOSE_ID" > /dev/null
+
+    # Find the tarball and extract it.
+    TARBALL=$(basename "$(find . -maxdepth 1 -type f -name "*-metadata.tar")")
+    tar -xf "$TARBALL" -C "${TEMPDIR}"
+    rm -f "$TARBALL"
+
+    # Move the JSON file into place.
+    cat "${TEMPDIR}"/"${COMPOSE_ID}".json | jq -M '.' | tee "$METADATA_FILE" > /dev/null
+}
+
+# Build ostree image.
+build_image() {
+    blueprint_name=$1
+    image_type=$2
+
+    # Get worker unit file so we can watch the journal.
+    WORKER_UNIT=$(sudo systemctl list-units | grep -o -E "osbuild.*worker.*\.service")
+    sudo journalctl -af -n 1 -u "${WORKER_UNIT}" &
+    WORKER_JOURNAL_PID=$!
+    # Stop watching the worker journal when exiting.
+    trap 'sudo pkill -P ${WORKER_JOURNAL_PID}' EXIT
+
+    # Start the compose.
+    greenprint "🚀 Starting compose"
+    if [ $# -eq 3 ]; then
+        repo_url=$3
+        sudo composer-cli --json compose start-ostree --ref "$OSTREE_REF" --url "$repo_url" "$blueprint_name" "$image_type" | tee "$COMPOSE_START"
+    else
+        sudo composer-cli --json compose start-ostree --ref "$OSTREE_REF" "$blueprint_name" "$image_type" | tee "$COMPOSE_START"
+    fi
+    COMPOSE_ID=$(jq -r '.build_id' "$COMPOSE_START")
+
+    # Wait for the compose to finish.
+    greenprint "⏱ Waiting for compose to finish: ${COMPOSE_ID}"
+    while true; do
+        sudo composer-cli --json compose info "${COMPOSE_ID}" | tee "$COMPOSE_INFO" > /dev/null
+        COMPOSE_STATUS=$(jq -r '.queue_status' "$COMPOSE_INFO")
+
+        # Is the compose finished?
+        if [[ $COMPOSE_STATUS != RUNNING ]] && [[ $COMPOSE_STATUS != WAITING ]]; then
+            break
+        fi
+
+        # Wait 30 seconds and try again.
+        sleep 5
+    done
+
+    # Capture the compose logs from osbuild.
+    greenprint "💬 Getting compose log and metadata"
+    get_compose_log "$COMPOSE_ID"
+    get_compose_metadata "$COMPOSE_ID"
+
+    # Kill the journal monitor immediately and remove the trap
+    sudo pkill -P ${WORKER_JOURNAL_PID}
+    trap - EXIT
+
+    # Did the compose finish with success?
+    if [[ $COMPOSE_STATUS != FINISHED ]]; then
+        echo "Something went wrong with the compose. 😢"
+        exit 1
+    fi
+}
+
+# Wait for the ssh server up to be.
+wait_for_ssh_up () {
+    SSH_STATUS=$(sudo ssh "${SSH_OPTIONS[@]}" -i "${SSH_KEY}" admin@"${1}" '/bin/bash -c "echo -n READY"')
+    if [[ $SSH_STATUS == READY ]]; then
+        echo 1
+    else
+        echo 0
+    fi
+}
+
+# Clean up our mess.
+clean_up () {
+    greenprint "🧼 Cleaning up"
+
+    # Clear vm
+    if [[ $(sudo virsh domstate "${IMAGE_KEY}-uefi") == "running" ]]; then
+        sudo virsh destroy "${IMAGE_KEY}-uefi"
+    fi
+    sudo virsh undefine "${IMAGE_KEY}-uefi" --nvram
+    # Remove qcow2 file.
+    sudo rm -f "$LIBVIRT_IMAGE_PATH"
+
+    # Remove any status containers if exist
+    sudo podman ps -a -q --format "{{.ID}}" | sudo xargs --no-run-if-empty podman rm -f
+    # Remove all images
+    sudo podman rmi -f -a
+
+    # Remove prod repo
+    sudo rm -rf "$PROD_REPO"
+
+    # Remomve tmp dir.
+    sudo rm -rf "$TEMPDIR"
+
+    # Stop prod repo http service
+    sudo systemctl disable --now httpd
+}
+
+# Test result checking
+check_result () {
+    greenprint "🎏 Checking for test result"
+    if [[ $RESULTS == 1 ]]; then
+        greenprint "💚 Success"
+    else
+        greenprint "❌ Failed"
+        clean_up
+        exit 1
+    fi
+}
+
+###########################################################
+##
+## Prepare edge prod and stage repo
+##
+###########################################################
+greenprint "🔧 Prepare edge prod repo"
+# Start prod repo web service
+# osbuild-composer-tests have mod_ssl as a dependency. The package installs
+# an example configuration which automatically enabled httpd on port 443, but
+# that one is already in use. Remove the default configuration as it is useless
+# anyway.
+sudo rm -f /etc/httpd/conf.d/ssl.conf
+sudo systemctl enable --now httpd.service
+
+# Have a clean prod repo
+sudo rm -rf "$PROD_REPO"
+sudo mkdir -p "$PROD_REPO"
+sudo ostree --repo="$PROD_REPO" init --mode=archive
+sudo ostree --repo="$PROD_REPO" remote add --no-gpg-verify edge-stage "$STAGE_REPO_URL"
+
+# Prepare stage repo network
+greenprint "🔧 Prepare stage repo network"
+sudo podman network inspect edge >/dev/null 2>&1 || sudo podman network create --driver=bridge --subnet=192.168.200.0/24 --ip-range=192.168.200.0/24 --gateway=192.168.200.254 edge
+
+##########################################################
+##
+## Build edge-container image and start it in podman
+##
+##########################################################
+
+# Write a blueprint for ostree image.
+tee "$BLUEPRINT_FILE" > /dev/null << EOF
+name = "container"
+description = "A base rhel-edge container image"
+version = "0.0.1"
+modules = []
+groups = []
+
+[[packages]]
+name = "python36"
+version = "*"
+
+[customizations.kernel]
+name = "kernel-rt"
+
+[[customizations.user]]
+name = "admin"
+description = "Administrator account"
+password = "\$6\$GRmb7S0p8vsYmXzH\$o0E020S.9JQGaHkszoog4ha4AQVs3sk8q0DvLjSMxoxHBKnB2FBXGQ/OkwZQfW/76ktHd0NX5nls2LPxPuUdl."
+key = "${SSH_KEY_PUB}"
+home = "/home/admin/"
+groups = ["wheel"]
+EOF
+
+greenprint "📄 container blueprint"
+cat "$BLUEPRINT_FILE"
+
+# Prepare the blueprint for the compose.
+greenprint "📋 Preparing container blueprint"
+sudo composer-cli blueprints push "$BLUEPRINT_FILE"
+sudo composer-cli blueprints depsolve container
+
+# Build container image.
+build_image container "${CONTAINER_TYPE}"
+
+# Download the image
+greenprint "📥 Downloading the container image"
+sudo composer-cli compose image "${COMPOSE_ID}" > /dev/null
+
+# Clear stage repo running env
+greenprint "🧹 Clearing stage repo running env"
+# Remove any status containers if exist
+sudo podman ps -a -q --format "{{.ID}}" | sudo xargs --no-run-if-empty podman rm -f
+# Remove all images
+sudo podman rmi -f -a
+
+# Deal with stage repo image
+greenprint "🗜 Starting container"
+IMAGE_FILENAME="${COMPOSE_ID}-${CONTAINER_FILENAME}"
+sudo podman pull "oci-archive:${IMAGE_FILENAME}"
+sudo podman images
+# Run edge stage repo
+greenprint "🛰 Running edge stage repo"
+# Get image id to run image
+EDGE_IMAGE_ID=$(sudo podman images --filter "dangling=true" --format "{{.ID}}")
+sudo podman run -d --name rhel-edge --network edge --ip "$STAGE_REPO_ADDRESS" "$EDGE_IMAGE_ID"
+# Clear image file
+sudo rm -f "$IMAGE_FILENAME"
+
+# Wait for container to be running
+until [ "$(sudo podman inspect -f '{{.State.Running}}' rhel-edge)" == "true" ]; do
+    sleep 1;
+done;
+
+# Sync installer edge content
+greenprint "📡 Sync installer content from stage repo"
+sudo ostree --repo="$PROD_REPO" pull --mirror edge-stage "$OSTREE_REF"
+
+# Clean compose and blueprints.
+greenprint "🧽 Clean up container blueprint and compose"
+sudo composer-cli compose delete "${COMPOSE_ID}" > /dev/null
+sudo composer-cli blueprints delete container > /dev/null
+
+############################################################
+##
+## Build edge-simplified-installer image
+##
+############################################################
+
+# Write a blueprint for installer image.
+tee "$BLUEPRINT_FILE" > /dev/null << EOF
+name = "installer"
+description = "A rhel-edge simplified-installer image"
+version = "0.0.1"
+modules = []
+groups = []
+
+[customizations]
+installation_device = "/dev/vda"
+EOF
+
+greenprint "📄 installer blueprint"
+cat "$BLUEPRINT_FILE"
+
+# Prepare the blueprint for the compose.
+greenprint "📋 Preparing installer blueprint"
+sudo composer-cli blueprints push "$BLUEPRINT_FILE"
+sudo composer-cli blueprints depsolve installer
+
+# Build installer image.
+# Test --url arg following by URL with tailling slash for bz#1942029
+build_image installer "${INSTALLER_TYPE}" "${PROD_REPO_URL}/"
+
+# Download the image
+greenprint "📥 Downloading the installer image"
+sudo composer-cli compose image "${COMPOSE_ID}" > /dev/null
+ISO_FILENAME="${COMPOSE_ID}-${INSTALLER_FILENAME}"
+sudo mv "${ISO_FILENAME}" /var/lib/libvirt/images
+
+# Clean compose and blueprints.
+greenprint "🧹 Clean up installer blueprint and compose"
+sudo composer-cli compose delete "${COMPOSE_ID}" > /dev/null
+sudo composer-cli blueprints delete installer > /dev/null
+
+##################################################################
+##
+## Install and test edge vm with edge-simplified-installer (UEFI)
+##
+##################################################################
+
+# Ensure SELinux is happy with our new images.
+greenprint "👿 Running restorecon on image directory"
+sudo restorecon -Rv /var/lib/libvirt/images/
+
+# Create qcow2 file for virt install.
+greenprint "🖥 Create qcow2 file for virt install"
+LIBVIRT_IMAGE_PATH=/var/lib/libvirt/images/${IMAGE_KEY}-uefi.qcow2
+sudo qemu-img create -f qcow2 "${LIBVIRT_IMAGE_PATH}" 20G
+
+greenprint "💿 Install ostree image via installer(ISO) on UEFI VM"
+sudo virt-install  --name="${IMAGE_KEY}-uefi"\
+                   --disk path="${LIBVIRT_IMAGE_PATH}",format=qcow2 \
+                   --ram 3072 \
+                   --vcpus 2 \
+                   --network network=integration,mac=34:49:22:B0:83:31 \
+                   --os-type linux \
+                   --os-variant ${OS_VARIANT} \
+                   --cdrom "/var/lib/libvirt/images/${ISO_FILENAME}" \
+                   --boot uefi,loader_ro=yes,loader_type=pflash,nvram_template=/usr/share/edk2/ovmf/OVMF_VARS.fd,loader_secure=no \
+                   --nographics \
+                   --noautoconsole \
+                   --wait=-1 \
+                   --noreboot
+
+# Start VM.
+greenprint "💻 Start UEFI VM"
+sudo virsh start "${IMAGE_KEY}-uefi"
+
+# Check for ssh ready to go.
+greenprint "🛃 Checking for SSH is ready to go"
+for LOOP_COUNTER in $(seq 0 30); do
+    RESULTS="$(wait_for_ssh_up $UEFI_GUEST_ADDRESS)"
+    if [[ $RESULTS == 1 ]]; then
+        echo "SSH is ready now! 🥳"
+        break
+    fi
+    sleep 10
+done
+
+# Check image installation result
+check_result
+
+greenprint "🕹 Get ostree install commit value"
+INSTALL_HASH=$(curl "${PROD_REPO_URL}/refs/heads/${OSTREE_REF}")
+
+# Add instance IP address into /etc/ansible/hosts
+sudo tee "${TEMPDIR}"/inventory > /dev/null << EOF
+[ostree_guest]
+${UEFI_GUEST_ADDRESS}
+
+[ostree_guest:vars]
+ansible_python_interpreter=/usr/bin/python3
+ansible_user=admin
+ansible_private_key_file=${SSH_KEY}
+ansible_ssh_common_args="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
+ansible_become=yes 
+ansible_become_method=sudo
+ansible_become_pass=${EDGE_USER_PASSWORD}
+EOF
+
+# Test IoT/Edge OS
+sudo ANSIBLE_STDOUT_CALLBACK=debug ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type=redhat -e ostree_commit="${INSTALL_HASH}" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0
+check_result
+
+##################################################################
+##
+## Upgrade and test edge vm with edge-simplified-installer (UEFI)
+##
+##################################################################
+
+# Write a blueprint for ostree image.
+# NB: no ssh key in this blueprint for the admin user
+tee "$BLUEPRINT_FILE" > /dev/null << EOF
+name = "upgrade"
+description = "An upgrade rhel-edge container image"
+version = "0.0.2"
+modules = []
+groups = []
+
+[[packages]]
+name = "python36"
+version = "*"
+
+[[packages]]
+name = "wget"
+version = "*"
+
+[customizations.kernel]
+name = "kernel-rt"
+
+[[customizations.user]]
+name = "admin"
+description = "Administrator account"
+password = "\$6\$GRmb7S0p8vsYmXzH\$o0E020S.9JQGaHkszoog4ha4AQVs3sk8q0DvLjSMxoxHBKnB2FBXGQ/OkwZQfW/76ktHd0NX5nls2LPxPuUdl."
+home = "/home/admin/"
+groups = ["wheel"]
+EOF
+
+greenprint "📄 upgrade blueprint"
+cat "$BLUEPRINT_FILE"
+
+# Prepare the blueprint for the compose.
+greenprint "📋 Preparing upgrade blueprint"
+sudo composer-cli blueprints push "$BLUEPRINT_FILE"
+sudo composer-cli blueprints depsolve upgrade
+
+# Build upgrade image.
+build_image upgrade  "${CONTAINER_TYPE}" "$PROD_REPO_URL"
+
+# Download the image
+greenprint "📥 Downloading the upgrade image"
+sudo composer-cli compose image "${COMPOSE_ID}" > /dev/null
+
+# Clear stage repo running env
+greenprint "🧹 Clearing stage repo running env"
+# Remove any status containers if exist
+sudo podman ps -a -q --format "{{.ID}}" | sudo xargs --no-run-if-empty podman rm -f
+# Remove all images
+sudo podman rmi -f -a
+
+# Deal with stage repo container
+greenprint "🗜 Extracting image"
+IMAGE_FILENAME="${COMPOSE_ID}-${CONTAINER_FILENAME}"
+sudo podman pull "oci-archive:${IMAGE_FILENAME}"
+sudo podman images
+# Clear image file
+sudo rm -f "$IMAGE_FILENAME"
+
+# Run edge stage repo
+greenprint "🛰 Running edge stage repo"
+# Get image id to run image
+EDGE_IMAGE_ID=$(sudo podman images --filter "dangling=true" --format "{{.ID}}")
+sudo podman run -d --name rhel-edge --network edge --ip "$STAGE_REPO_ADDRESS" "$EDGE_IMAGE_ID"
+# Wait for container to be running
+until [ "$(sudo podman inspect -f '{{.State.Running}}' rhel-edge)" == "true" ]; do
+    sleep 1;
+done;
+
+# Workaround to https://github.com/osbuild/osbuild-composer/issues/1693
+greenprint "🗳 Add external prod edge repo"
+sudo ssh "${SSH_OPTIONS[@]}" -i "${SSH_KEY}" admin@${UEFI_GUEST_ADDRESS} "echo ${EDGE_USER_PASSWORD} |sudo -S ostree remote add --no-gpg-verify --no-sign-verify rhel-edge ${PROD_REPO_URL}"
+sudo ssh "${SSH_OPTIONS[@]}" -i "${SSH_KEY}" admin@${UEFI_GUEST_ADDRESS} "echo ${EDGE_USER_PASSWORD} |sudo -S ostree admin switch rhel-edge:${OSTREE_REF}"
+
+# Pull upgrade to prod mirror
+greenprint "⛓ Pull upgrade to prod mirror"
+sudo ostree --repo="$PROD_REPO" pull --mirror edge-stage "$OSTREE_REF"
+sudo ostree --repo="$PROD_REPO" static-delta generate "$OSTREE_REF"
+sudo ostree --repo="$PROD_REPO" summary -u
+
+# Get ostree commit value.
+greenprint "🕹 Get ostree upgrade commit value"
+UPGRADE_HASH=$(curl "${PROD_REPO_URL}/refs/heads/${OSTREE_REF}")
+
+# Clean compose and blueprints.
+greenprint "🧽 Clean up upgrade blueprint and compose"
+sudo composer-cli compose delete "${COMPOSE_ID}" > /dev/null
+sudo composer-cli blueprints delete upgrade > /dev/null
+
+greenprint "🗳 Upgrade ostree image/commit"
+sudo ssh "${SSH_OPTIONS[@]}" -i "${SSH_KEY}" admin@${UEFI_GUEST_ADDRESS} "echo ${EDGE_USER_PASSWORD} |sudo -S rpm-ostree upgrade"
+sudo ssh "${SSH_OPTIONS[@]}" -i "${SSH_KEY}" admin@${UEFI_GUEST_ADDRESS} "echo ${EDGE_USER_PASSWORD} |nohup sudo -S systemctl reboot &>/dev/null & exit"
+
+
+
+# Sleep 10 seconds here to make sure vm restarted already
+sleep 10
+
+# Check for ssh ready to go.
+greenprint "🛃 Checking for SSH is ready to go"
+# shellcheck disable=SC2034  # Unused variables left for readability
+for LOOP_COUNTER in $(seq 0 30); do
+    RESULTS="$(wait_for_ssh_up $UEFI_GUEST_ADDRESS)"
+    if [[ $RESULTS == 1 ]]; then
+        echo "SSH is ready now! 🥳"
+        break
+    fi
+    sleep 10
+done
+
+# Check ostree upgrade result
+check_result
+
+# Add instance IP address into /etc/ansible/hosts
+sudo tee "${TEMPDIR}"/inventory > /dev/null << EOF
+[ostree_guest]
+${UEFI_GUEST_ADDRESS}
+
+[ostree_guest:vars]
+ansible_python_interpreter=/usr/bin/python3
+ansible_user=admin
+ansible_private_key_file=${SSH_KEY}
+ansible_ssh_common_args="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
+ansible_become=yes 
+ansible_become_method=sudo
+ansible_become_pass=${EDGE_USER_PASSWORD}
+EOF
+
+# Test IoT/Edge OS
+sudo ANSIBLE_STDOUT_CALLBACK=debug ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type=redhat -e ostree_commit="${UPGRADE_HASH}" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0
+check_result
+
+# Final success clean up
+clean_up
+
+exit 0
diff --git a/test/data/ansible/check_ostree.yaml b/test/data/ansible/check_ostree.yaml
index 61dc51b43..be6620bb6 100644
--- a/test/data/ansible/check_ostree.yaml
+++ b/test/data/ansible/check_ostree.yaml
@@ -98,6 +98,16 @@
         device_name: /dev/vda3
       when: result_uefi.stat.exists
 
+    # for edge-simplified-installer and edge-raw-image, /sysroot is mounted at /dev/vda4, need to set device_name to /dev/vda4
+    - name: check if it is simplified-installer or raw-image
+      command: df -h
+      register: result_df
+    
+    - set_fact:
+        device_name: /dev/vda4
+        vda4_detected: yes
+      when: "'/dev/vda4' in result_df.stdout"
+
     # case: check /sysroot moutn point
     - name: check /sysroot mount point
       command: findmnt -r -o SOURCE -n /sysroot
@@ -393,6 +403,17 @@
               - "'greenboot MotD Generator' in result_greenboot_log.stdout"
             fail_msg: "Some errors happened in service boot"
             success_msg: "All greenboot services booted success"
+          when: vda4_detected is not defined
+
+        - assert:
+            that:
+              - "'Script \\'00_required_scripts_start.sh\\' SUCCESS' in result_greenboot_log.stdout"
+              - "'Script \\'00_wanted_scripts_start.sh\\' SUCCESS' in result_greenboot_log.stdout"
+              - "'Boot Status is GREEN - Health Check SUCCESS' in result_greenboot_log.stdout"
+            fail_msg: "Some errors happened in service boot"
+            success_msg: "All greenboot services booted success"
+          when: vda4_detected is defined
+
       always:
         - set_fact:
             total_counter: "{{ total_counter | int + 1 }}"
@@ -498,6 +519,18 @@
               - "'greenboot MotD Generator' in result_greenboot_log.stdout"
             fail_msg: "Fallback log not found"
             success_msg: "Found fallback log"
+          when: vda4_detected is not defined
+
+        - assert:
+            that:
+              - "'FALLBACK BOOT DETECTED! Default rpm-ostree deployment has been rolled back' in result_greenboot_log.stdout"
+              - "'Script \\'00_required_scripts_start.sh\\' SUCCESS' in result_greenboot_log.stdout"
+              - "'Script \\'00_wanted_scripts_start.sh\\' SUCCESS' in result_greenboot_log.stdout"
+              - "'Boot Status is GREEN - Health Check SUCCESS' in result_greenboot_log.stdout"
+            fail_msg: "Some errors happened in service boot"
+            success_msg: "All greenboot services booted success"
+          when: vda4_detected is defined
+
       always:
         - set_fact:
             total_counter: "{{ total_counter | int + 1 }}"
diff --git a/test/data/manifests/rhel_85-x86_64-image_installer-boot.json b/test/data/manifests/rhel_85-x86_64-image_installer-boot.json
index fdac064dd..b62bc4f64 100644
--- a/test/data/manifests/rhel_85-x86_64-image_installer-boot.json
+++ b/test/data/manifests/rhel_85-x86_64-image_installer-boot.json
@@ -1778,7 +1778,6 @@
                 "plymouth",
                 "prefixdevname",
                 "prefixdevname-tools",
-                "anaconda",
                 "crypt",
                 "dm",
                 "dmsquash-live",
@@ -1800,7 +1799,6 @@
                 "rootfs-block",
                 "terminfo",
                 "udev-rules",
-                "biosdevname",
                 "dracut-systemd",
                 "pollcdrom",
                 "usrmount",
@@ -1808,7 +1806,9 @@
                 "fs-lib",
                 "img-lib",
                 "shutdown",
-                "uefi-lib"
+                "uefi-lib",
+                "biosdevname",
+                "anaconda"
               ],
               "install": [
                 "/.buildstamp"
diff --git a/test/data/repositories/rhel-85.json b/test/data/repositories/rhel-85.json
index ed677b8a4..beb09990a 100644
--- a/test/data/repositories/rhel-85.json
+++ b/test/data/repositories/rhel-85.json
@@ -2,53 +2,53 @@
   "x86_64": [
     {
       "name": "baseos",
-      "baseurl": "https://rpmrepo.osbuild.org/v2/mirror/rhvpn/el8/el8-x86_64-baseos-n8.5-20210715/",
+      "baseurl": "https://rpmrepo.osbuild.org/v2/mirror/rhvpn/el8/el8-x86_64-baseos-n8.5-20210820/",
       "gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBErgSTsBEACh2A4b0O9t+vzC9VrVtL1AKvUWi9OPCjkvR7Xd8DtJxeeMZ5eF\n0HtzIG58qDRybwUe89FZprB1ffuUKzdE+HcL3FbNWSSOXVjZIersdXyH3NvnLLLF\n0DNRB2ix3bXG9Rh/RXpFsNxDp2CEMdUvbYCzE79K1EnUTVh1L0Of023FtPSZXX0c\nu7Pb5DI5lX5YeoXO6RoodrIGYJsVBQWnrWw4xNTconUfNPk0EGZtEnzvH2zyPoJh\nXGF+Ncu9XwbalnYde10OCvSWAZ5zTCpoLMTvQjWpbCdWXJzCm6G+/hx9upke546H\n5IjtYm4dTIVTnc3wvDiODgBKRzOl9rEOCIgOuGtDxRxcQkjrC+xvg5Vkqn7vBUyW\n9pHedOU+PoF3DGOM+dqv+eNKBvh9YF9ugFAQBkcG7viZgvGEMGGUpzNgN7XnS1gj\n/DPo9mZESOYnKceve2tIC87p2hqjrxOHuI7fkZYeNIcAoa83rBltFXaBDYhWAKS1\nPcXS1/7JzP0ky7d0L6Xbu/If5kqWQpKwUInXtySRkuraVfuK3Bpa+X1XecWi24JY\nHVtlNX025xx1ewVzGNCTlWn1skQN2OOoQTV4C8/qFpTW6DTWYurd4+fE0OJFJZQF\nbuhfXYwmRlVOgN5i77NTIJZJQfYFj38c/Iv5vZBPokO6mffrOTv3MHWVgQARAQAB\ntDNSZWQgSGF0LCBJbmMuIChyZWxlYXNlIGtleSAyKSA8c2VjdXJpdHlAcmVkaGF0\nLmNvbT6JAjYEEwECACAFAkrgSTsCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAK\nCRAZni+R/UMdUWzpD/9s5SFR/ZF3yjY5VLUFLMXIKUztNN3oc45fyLdTI3+UClKC\n2tEruzYjqNHhqAEXa2sN1fMrsuKec61Ll2NfvJjkLKDvgVIh7kM7aslNYVOP6BTf\nC/JJ7/ufz3UZmyViH/WDl+AYdgk3JqCIO5w5ryrC9IyBzYv2m0HqYbWfphY3uHw5\nun3ndLJcu8+BGP5F+ONQEGl+DRH58Il9Jp3HwbRa7dvkPgEhfFR+1hI+Btta2C7E\n0/2NKzCxZw7Lx3PBRcU92YKyaEihfy/aQKZCAuyfKiMvsmzs+4poIX7I9NQCJpyE\nIGfINoZ7VxqHwRn/d5mw2MZTJjbzSf+Um9YJyA0iEEyD6qjriWQRbuxpQXmlAJbh\n8okZ4gbVFv1F8MzK+4R8VvWJ0XxgtikSo72fHjwha7MAjqFnOq6eo6fEC/75g3NL\nGht5VdpGuHk0vbdENHMC8wS99e5qXGNDued3hlTavDMlEAHl34q2H9nakTGRF5Ki\nJUfNh3DVRGhg8cMIti21njiRh7gyFI2OccATY7bBSr79JhuNwelHuxLrCFpY7V25\nOFktl15jZJaMxuQBqYdBgSay2G0U6D1+7VsWufpzd/Abx1/c3oi9ZaJvW22kAggq\ndzdA27UUYjWvx42w9menJwh/0jeQcTecIUd0d0rFcw/c1pvgMMl/Q73yzKgKYw==\n=zbHE\n-----END PGP PUBLIC KEY BLOCK-----\n-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n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\nvt61kpkXoRGxjTlc6h+69aidSg==\n=ls8J\n-----END PGP PUBLIC KEY BLOCK-----\n"
     },
     {
       "name": "appstream",
-      "baseurl": "https://rpmrepo.osbuild.org/v2/mirror/rhvpn/el8/el8-x86_64-appstream-n8.5-20210715/",
+      "baseurl": "https://rpmrepo.osbuild.org/v2/mirror/rhvpn/el8/el8-x86_64-appstream-n8.5-20210820/",
       "gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBErgSTsBEACh2A4b0O9t+vzC9VrVtL1AKvUWi9OPCjkvR7Xd8DtJxeeMZ5eF\n0HtzIG58qDRybwUe89FZprB1ffuUKzdE+HcL3FbNWSSOXVjZIersdXyH3NvnLLLF\n0DNRB2ix3bXG9Rh/RXpFsNxDp2CEMdUvbYCzE79K1EnUTVh1L0Of023FtPSZXX0c\nu7Pb5DI5lX5YeoXO6RoodrIGYJsVBQWnrWw4xNTconUfNPk0EGZtEnzvH2zyPoJh\nXGF+Ncu9XwbalnYde10OCvSWAZ5zTCpoLMTvQjWpbCdWXJzCm6G+/hx9upke546H\n5IjtYm4dTIVTnc3wvDiODgBKRzOl9rEOCIgOuGtDxRxcQkjrC+xvg5Vkqn7vBUyW\n9pHedOU+PoF3DGOM+dqv+eNKBvh9YF9ugFAQBkcG7viZgvGEMGGUpzNgN7XnS1gj\n/DPo9mZESOYnKceve2tIC87p2hqjrxOHuI7fkZYeNIcAoa83rBltFXaBDYhWAKS1\nPcXS1/7JzP0ky7d0L6Xbu/If5kqWQpKwUInXtySRkuraVfuK3Bpa+X1XecWi24JY\nHVtlNX025xx1ewVzGNCTlWn1skQN2OOoQTV4C8/qFpTW6DTWYurd4+fE0OJFJZQF\nbuhfXYwmRlVOgN5i77NTIJZJQfYFj38c/Iv5vZBPokO6mffrOTv3MHWVgQARAQAB\ntDNSZWQgSGF0LCBJbmMuIChyZWxlYXNlIGtleSAyKSA8c2VjdXJpdHlAcmVkaGF0\nLmNvbT6JAjYEEwECACAFAkrgSTsCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAK\nCRAZni+R/UMdUWzpD/9s5SFR/ZF3yjY5VLUFLMXIKUztNN3oc45fyLdTI3+UClKC\n2tEruzYjqNHhqAEXa2sN1fMrsuKec61Ll2NfvJjkLKDvgVIh7kM7aslNYVOP6BTf\nC/JJ7/ufz3UZmyViH/WDl+AYdgk3JqCIO5w5ryrC9IyBzYv2m0HqYbWfphY3uHw5\nun3ndLJcu8+BGP5F+ONQEGl+DRH58Il9Jp3HwbRa7dvkPgEhfFR+1hI+Btta2C7E\n0/2NKzCxZw7Lx3PBRcU92YKyaEihfy/aQKZCAuyfKiMvsmzs+4poIX7I9NQCJpyE\nIGfINoZ7VxqHwRn/d5mw2MZTJjbzSf+Um9YJyA0iEEyD6qjriWQRbuxpQXmlAJbh\n8okZ4gbVFv1F8MzK+4R8VvWJ0XxgtikSo72fHjwha7MAjqFnOq6eo6fEC/75g3NL\nGht5VdpGuHk0vbdENHMC8wS99e5qXGNDued3hlTavDMlEAHl34q2H9nakTGRF5Ki\nJUfNh3DVRGhg8cMIti21njiRh7gyFI2OccATY7bBSr79JhuNwelHuxLrCFpY7V25\nOFktl15jZJaMxuQBqYdBgSay2G0U6D1+7VsWufpzd/Abx1/c3oi9ZaJvW22kAggq\ndzdA27UUYjWvx42w9menJwh/0jeQcTecIUd0d0rFcw/c1pvgMMl/Q73yzKgKYw==\n=zbHE\n-----END PGP PUBLIC KEY BLOCK-----\n-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n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\nvt61kpkXoRGxjTlc6h+69aidSg==\n=ls8J\n-----END PGP PUBLIC KEY BLOCK-----\n"
     },
     {
       "name": "rt",
-      "baseurl": "https://rpmrepo.osbuild.org/v2/mirror/rhvpn/el8/el8-x86_64-rt-n8.5-20210715/",
+      "baseurl": "https://rpmrepo.osbuild.org/v2/mirror/rhvpn/el8/el8-x86_64-rt-n8.5-20210820/",
       "gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBErgSTsBEACh2A4b0O9t+vzC9VrVtL1AKvUWi9OPCjkvR7Xd8DtJxeeMZ5eF\n0HtzIG58qDRybwUe89FZprB1ffuUKzdE+HcL3FbNWSSOXVjZIersdXyH3NvnLLLF\n0DNRB2ix3bXG9Rh/RXpFsNxDp2CEMdUvbYCzE79K1EnUTVh1L0Of023FtPSZXX0c\nu7Pb5DI5lX5YeoXO6RoodrIGYJsVBQWnrWw4xNTconUfNPk0EGZtEnzvH2zyPoJh\nXGF+Ncu9XwbalnYde10OCvSWAZ5zTCpoLMTvQjWpbCdWXJzCm6G+/hx9upke546H\n5IjtYm4dTIVTnc3wvDiODgBKRzOl9rEOCIgOuGtDxRxcQkjrC+xvg5Vkqn7vBUyW\n9pHedOU+PoF3DGOM+dqv+eNKBvh9YF9ugFAQBkcG7viZgvGEMGGUpzNgN7XnS1gj\n/DPo9mZESOYnKceve2tIC87p2hqjrxOHuI7fkZYeNIcAoa83rBltFXaBDYhWAKS1\nPcXS1/7JzP0ky7d0L6Xbu/If5kqWQpKwUInXtySRkuraVfuK3Bpa+X1XecWi24JY\nHVtlNX025xx1ewVzGNCTlWn1skQN2OOoQTV4C8/qFpTW6DTWYurd4+fE0OJFJZQF\nbuhfXYwmRlVOgN5i77NTIJZJQfYFj38c/Iv5vZBPokO6mffrOTv3MHWVgQARAQAB\ntDNSZWQgSGF0LCBJbmMuIChyZWxlYXNlIGtleSAyKSA8c2VjdXJpdHlAcmVkaGF0\nLmNvbT6JAjYEEwECACAFAkrgSTsCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAK\nCRAZni+R/UMdUWzpD/9s5SFR/ZF3yjY5VLUFLMXIKUztNN3oc45fyLdTI3+UClKC\n2tEruzYjqNHhqAEXa2sN1fMrsuKec61Ll2NfvJjkLKDvgVIh7kM7aslNYVOP6BTf\nC/JJ7/ufz3UZmyViH/WDl+AYdgk3JqCIO5w5ryrC9IyBzYv2m0HqYbWfphY3uHw5\nun3ndLJcu8+BGP5F+ONQEGl+DRH58Il9Jp3HwbRa7dvkPgEhfFR+1hI+Btta2C7E\n0/2NKzCxZw7Lx3PBRcU92YKyaEihfy/aQKZCAuyfKiMvsmzs+4poIX7I9NQCJpyE\nIGfINoZ7VxqHwRn/d5mw2MZTJjbzSf+Um9YJyA0iEEyD6qjriWQRbuxpQXmlAJbh\n8okZ4gbVFv1F8MzK+4R8VvWJ0XxgtikSo72fHjwha7MAjqFnOq6eo6fEC/75g3NL\nGht5VdpGuHk0vbdENHMC8wS99e5qXGNDued3hlTavDMlEAHl34q2H9nakTGRF5Ki\nJUfNh3DVRGhg8cMIti21njiRh7gyFI2OccATY7bBSr79JhuNwelHuxLrCFpY7V25\nOFktl15jZJaMxuQBqYdBgSay2G0U6D1+7VsWufpzd/Abx1/c3oi9ZaJvW22kAggq\ndzdA27UUYjWvx42w9menJwh/0jeQcTecIUd0d0rFcw/c1pvgMMl/Q73yzKgKYw==\n=zbHE\n-----END PGP PUBLIC KEY BLOCK-----\n-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n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\nvt61kpkXoRGxjTlc6h+69aidSg==\n=ls8J\n-----END PGP PUBLIC KEY BLOCK-----\n"
     }
   ],
   "aarch64": [
     {
       "name": "baseos",
-      "baseurl": "https://rpmrepo.osbuild.org/v2/mirror/rhvpn/el8/el8-aarch64-baseos-n8.5-20210715/",
+      "baseurl": "https://rpmrepo.osbuild.org/v2/mirror/rhvpn/el8/el8-aarch64-baseos-n8.5-20210820/",
       "gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBErgSTsBEACh2A4b0O9t+vzC9VrVtL1AKvUWi9OPCjkvR7Xd8DtJxeeMZ5eF\n0HtzIG58qDRybwUe89FZprB1ffuUKzdE+HcL3FbNWSSOXVjZIersdXyH3NvnLLLF\n0DNRB2ix3bXG9Rh/RXpFsNxDp2CEMdUvbYCzE79K1EnUTVh1L0Of023FtPSZXX0c\nu7Pb5DI5lX5YeoXO6RoodrIGYJsVBQWnrWw4xNTconUfNPk0EGZtEnzvH2zyPoJh\nXGF+Ncu9XwbalnYde10OCvSWAZ5zTCpoLMTvQjWpbCdWXJzCm6G+/hx9upke546H\n5IjtYm4dTIVTnc3wvDiODgBKRzOl9rEOCIgOuGtDxRxcQkjrC+xvg5Vkqn7vBUyW\n9pHedOU+PoF3DGOM+dqv+eNKBvh9YF9ugFAQBkcG7viZgvGEMGGUpzNgN7XnS1gj\n/DPo9mZESOYnKceve2tIC87p2hqjrxOHuI7fkZYeNIcAoa83rBltFXaBDYhWAKS1\nPcXS1/7JzP0ky7d0L6Xbu/If5kqWQpKwUInXtySRkuraVfuK3Bpa+X1XecWi24JY\nHVtlNX025xx1ewVzGNCTlWn1skQN2OOoQTV4C8/qFpTW6DTWYurd4+fE0OJFJZQF\nbuhfXYwmRlVOgN5i77NTIJZJQfYFj38c/Iv5vZBPokO6mffrOTv3MHWVgQARAQAB\ntDNSZWQgSGF0LCBJbmMuIChyZWxlYXNlIGtleSAyKSA8c2VjdXJpdHlAcmVkaGF0\nLmNvbT6JAjYEEwECACAFAkrgSTsCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAK\nCRAZni+R/UMdUWzpD/9s5SFR/ZF3yjY5VLUFLMXIKUztNN3oc45fyLdTI3+UClKC\n2tEruzYjqNHhqAEXa2sN1fMrsuKec61Ll2NfvJjkLKDvgVIh7kM7aslNYVOP6BTf\nC/JJ7/ufz3UZmyViH/WDl+AYdgk3JqCIO5w5ryrC9IyBzYv2m0HqYbWfphY3uHw5\nun3ndLJcu8+BGP5F+ONQEGl+DRH58Il9Jp3HwbRa7dvkPgEhfFR+1hI+Btta2C7E\n0/2NKzCxZw7Lx3PBRcU92YKyaEihfy/aQKZCAuyfKiMvsmzs+4poIX7I9NQCJpyE\nIGfINoZ7VxqHwRn/d5mw2MZTJjbzSf+Um9YJyA0iEEyD6qjriWQRbuxpQXmlAJbh\n8okZ4gbVFv1F8MzK+4R8VvWJ0XxgtikSo72fHjwha7MAjqFnOq6eo6fEC/75g3NL\nGht5VdpGuHk0vbdENHMC8wS99e5qXGNDued3hlTavDMlEAHl34q2H9nakTGRF5Ki\nJUfNh3DVRGhg8cMIti21njiRh7gyFI2OccATY7bBSr79JhuNwelHuxLrCFpY7V25\nOFktl15jZJaMxuQBqYdBgSay2G0U6D1+7VsWufpzd/Abx1/c3oi9ZaJvW22kAggq\ndzdA27UUYjWvx42w9menJwh/0jeQcTecIUd0d0rFcw/c1pvgMMl/Q73yzKgKYw==\n=zbHE\n-----END PGP PUBLIC KEY BLOCK-----\n-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n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\nvt61kpkXoRGxjTlc6h+69aidSg==\n=ls8J\n-----END PGP PUBLIC KEY BLOCK-----\n"
     },
     {
       "name": "appstream",
-      "baseurl": "https://rpmrepo.osbuild.org/v2/mirror/rhvpn/el8/el8-aarch64-appstream-n8.5-20210715/",
+      "baseurl": "https://rpmrepo.osbuild.org/v2/mirror/rhvpn/el8/el8-aarch64-appstream-n8.5-20210820/",
       "gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBErgSTsBEACh2A4b0O9t+vzC9VrVtL1AKvUWi9OPCjkvR7Xd8DtJxeeMZ5eF\n0HtzIG58qDRybwUe89FZprB1ffuUKzdE+HcL3FbNWSSOXVjZIersdXyH3NvnLLLF\n0DNRB2ix3bXG9Rh/RXpFsNxDp2CEMdUvbYCzE79K1EnUTVh1L0Of023FtPSZXX0c\nu7Pb5DI5lX5YeoXO6RoodrIGYJsVBQWnrWw4xNTconUfNPk0EGZtEnzvH2zyPoJh\nXGF+Ncu9XwbalnYde10OCvSWAZ5zTCpoLMTvQjWpbCdWXJzCm6G+/hx9upke546H\n5IjtYm4dTIVTnc3wvDiODgBKRzOl9rEOCIgOuGtDxRxcQkjrC+xvg5Vkqn7vBUyW\n9pHedOU+PoF3DGOM+dqv+eNKBvh9YF9ugFAQBkcG7viZgvGEMGGUpzNgN7XnS1gj\n/DPo9mZESOYnKceve2tIC87p2hqjrxOHuI7fkZYeNIcAoa83rBltFXaBDYhWAKS1\nPcXS1/7JzP0ky7d0L6Xbu/If5kqWQpKwUInXtySRkuraVfuK3Bpa+X1XecWi24JY\nHVtlNX025xx1ewVzGNCTlWn1skQN2OOoQTV4C8/qFpTW6DTWYurd4+fE0OJFJZQF\nbuhfXYwmRlVOgN5i77NTIJZJQfYFj38c/Iv5vZBPokO6mffrOTv3MHWVgQARAQAB\ntDNSZWQgSGF0LCBJbmMuIChyZWxlYXNlIGtleSAyKSA8c2VjdXJpdHlAcmVkaGF0\nLmNvbT6JAjYEEwECACAFAkrgSTsCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAK\nCRAZni+R/UMdUWzpD/9s5SFR/ZF3yjY5VLUFLMXIKUztNN3oc45fyLdTI3+UClKC\n2tEruzYjqNHhqAEXa2sN1fMrsuKec61Ll2NfvJjkLKDvgVIh7kM7aslNYVOP6BTf\nC/JJ7/ufz3UZmyViH/WDl+AYdgk3JqCIO5w5ryrC9IyBzYv2m0HqYbWfphY3uHw5\nun3ndLJcu8+BGP5F+ONQEGl+DRH58Il9Jp3HwbRa7dvkPgEhfFR+1hI+Btta2C7E\n0/2NKzCxZw7Lx3PBRcU92YKyaEihfy/aQKZCAuyfKiMvsmzs+4poIX7I9NQCJpyE\nIGfINoZ7VxqHwRn/d5mw2MZTJjbzSf+Um9YJyA0iEEyD6qjriWQRbuxpQXmlAJbh\n8okZ4gbVFv1F8MzK+4R8VvWJ0XxgtikSo72fHjwha7MAjqFnOq6eo6fEC/75g3NL\nGht5VdpGuHk0vbdENHMC8wS99e5qXGNDued3hlTavDMlEAHl34q2H9nakTGRF5Ki\nJUfNh3DVRGhg8cMIti21njiRh7gyFI2OccATY7bBSr79JhuNwelHuxLrCFpY7V25\nOFktl15jZJaMxuQBqYdBgSay2G0U6D1+7VsWufpzd/Abx1/c3oi9ZaJvW22kAggq\ndzdA27UUYjWvx42w9menJwh/0jeQcTecIUd0d0rFcw/c1pvgMMl/Q73yzKgKYw==\n=zbHE\n-----END PGP PUBLIC KEY BLOCK-----\n-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n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\nvt61kpkXoRGxjTlc6h+69aidSg==\n=ls8J\n-----END PGP PUBLIC KEY BLOCK-----\n"
     }
   ],
   "s390x": [
     {
       "name": "baseos",
-      "baseurl": "https://rpmrepo.osbuild.org/v2/mirror/rhvpn/el8/el8-s390x-baseos-n8.5-20210715/",
+      "baseurl": "https://rpmrepo.osbuild.org/v2/mirror/rhvpn/el8/el8-s390x-baseos-n8.5-20210820/",
       "gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBErgSTsBEACh2A4b0O9t+vzC9VrVtL1AKvUWi9OPCjkvR7Xd8DtJxeeMZ5eF\n0HtzIG58qDRybwUe89FZprB1ffuUKzdE+HcL3FbNWSSOXVjZIersdXyH3NvnLLLF\n0DNRB2ix3bXG9Rh/RXpFsNxDp2CEMdUvbYCzE79K1EnUTVh1L0Of023FtPSZXX0c\nu7Pb5DI5lX5YeoXO6RoodrIGYJsVBQWnrWw4xNTconUfNPk0EGZtEnzvH2zyPoJh\nXGF+Ncu9XwbalnYde10OCvSWAZ5zTCpoLMTvQjWpbCdWXJzCm6G+/hx9upke546H\n5IjtYm4dTIVTnc3wvDiODgBKRzOl9rEOCIgOuGtDxRxcQkjrC+xvg5Vkqn7vBUyW\n9pHedOU+PoF3DGOM+dqv+eNKBvh9YF9ugFAQBkcG7viZgvGEMGGUpzNgN7XnS1gj\n/DPo9mZESOYnKceve2tIC87p2hqjrxOHuI7fkZYeNIcAoa83rBltFXaBDYhWAKS1\nPcXS1/7JzP0ky7d0L6Xbu/If5kqWQpKwUInXtySRkuraVfuK3Bpa+X1XecWi24JY\nHVtlNX025xx1ewVzGNCTlWn1skQN2OOoQTV4C8/qFpTW6DTWYurd4+fE0OJFJZQF\nbuhfXYwmRlVOgN5i77NTIJZJQfYFj38c/Iv5vZBPokO6mffrOTv3MHWVgQARAQAB\ntDNSZWQgSGF0LCBJbmMuIChyZWxlYXNlIGtleSAyKSA8c2VjdXJpdHlAcmVkaGF0\nLmNvbT6JAjYEEwECACAFAkrgSTsCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAK\nCRAZni+R/UMdUWzpD/9s5SFR/ZF3yjY5VLUFLMXIKUztNN3oc45fyLdTI3+UClKC\n2tEruzYjqNHhqAEXa2sN1fMrsuKec61Ll2NfvJjkLKDvgVIh7kM7aslNYVOP6BTf\nC/JJ7/ufz3UZmyViH/WDl+AYdgk3JqCIO5w5ryrC9IyBzYv2m0HqYbWfphY3uHw5\nun3ndLJcu8+BGP5F+ONQEGl+DRH58Il9Jp3HwbRa7dvkPgEhfFR+1hI+Btta2C7E\n0/2NKzCxZw7Lx3PBRcU92YKyaEihfy/aQKZCAuyfKiMvsmzs+4poIX7I9NQCJpyE\nIGfINoZ7VxqHwRn/d5mw2MZTJjbzSf+Um9YJyA0iEEyD6qjriWQRbuxpQXmlAJbh\n8okZ4gbVFv1F8MzK+4R8VvWJ0XxgtikSo72fHjwha7MAjqFnOq6eo6fEC/75g3NL\nGht5VdpGuHk0vbdENHMC8wS99e5qXGNDued3hlTavDMlEAHl34q2H9nakTGRF5Ki\nJUfNh3DVRGhg8cMIti21njiRh7gyFI2OccATY7bBSr79JhuNwelHuxLrCFpY7V25\nOFktl15jZJaMxuQBqYdBgSay2G0U6D1+7VsWufpzd/Abx1/c3oi9ZaJvW22kAggq\ndzdA27UUYjWvx42w9menJwh/0jeQcTecIUd0d0rFcw/c1pvgMMl/Q73yzKgKYw==\n=zbHE\n-----END PGP PUBLIC KEY BLOCK-----\n-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n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\nvt61kpkXoRGxjTlc6h+69aidSg==\n=ls8J\n-----END PGP PUBLIC KEY BLOCK-----\n"
     },
     {
       "name": "appstream",
-      "baseurl": "https://rpmrepo.osbuild.org/v2/mirror/rhvpn/el8/el8-s390x-appstream-n8.5-20210715/",
+      "baseurl": "https://rpmrepo.osbuild.org/v2/mirror/rhvpn/el8/el8-s390x-appstream-n8.5-20210820/",
       "gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBErgSTsBEACh2A4b0O9t+vzC9VrVtL1AKvUWi9OPCjkvR7Xd8DtJxeeMZ5eF\n0HtzIG58qDRybwUe89FZprB1ffuUKzdE+HcL3FbNWSSOXVjZIersdXyH3NvnLLLF\n0DNRB2ix3bXG9Rh/RXpFsNxDp2CEMdUvbYCzE79K1EnUTVh1L0Of023FtPSZXX0c\nu7Pb5DI5lX5YeoXO6RoodrIGYJsVBQWnrWw4xNTconUfNPk0EGZtEnzvH2zyPoJh\nXGF+Ncu9XwbalnYde10OCvSWAZ5zTCpoLMTvQjWpbCdWXJzCm6G+/hx9upke546H\n5IjtYm4dTIVTnc3wvDiODgBKRzOl9rEOCIgOuGtDxRxcQkjrC+xvg5Vkqn7vBUyW\n9pHedOU+PoF3DGOM+dqv+eNKBvh9YF9ugFAQBkcG7viZgvGEMGGUpzNgN7XnS1gj\n/DPo9mZESOYnKceve2tIC87p2hqjrxOHuI7fkZYeNIcAoa83rBltFXaBDYhWAKS1\nPcXS1/7JzP0ky7d0L6Xbu/If5kqWQpKwUInXtySRkuraVfuK3Bpa+X1XecWi24JY\nHVtlNX025xx1ewVzGNCTlWn1skQN2OOoQTV4C8/qFpTW6DTWYurd4+fE0OJFJZQF\nbuhfXYwmRlVOgN5i77NTIJZJQfYFj38c/Iv5vZBPokO6mffrOTv3MHWVgQARAQAB\ntDNSZWQgSGF0LCBJbmMuIChyZWxlYXNlIGtleSAyKSA8c2VjdXJpdHlAcmVkaGF0\nLmNvbT6JAjYEEwECACAFAkrgSTsCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAK\nCRAZni+R/UMdUWzpD/9s5SFR/ZF3yjY5VLUFLMXIKUztNN3oc45fyLdTI3+UClKC\n2tEruzYjqNHhqAEXa2sN1fMrsuKec61Ll2NfvJjkLKDvgVIh7kM7aslNYVOP6BTf\nC/JJ7/ufz3UZmyViH/WDl+AYdgk3JqCIO5w5ryrC9IyBzYv2m0HqYbWfphY3uHw5\nun3ndLJcu8+BGP5F+ONQEGl+DRH58Il9Jp3HwbRa7dvkPgEhfFR+1hI+Btta2C7E\n0/2NKzCxZw7Lx3PBRcU92YKyaEihfy/aQKZCAuyfKiMvsmzs+4poIX7I9NQCJpyE\nIGfINoZ7VxqHwRn/d5mw2MZTJjbzSf+Um9YJyA0iEEyD6qjriWQRbuxpQXmlAJbh\n8okZ4gbVFv1F8MzK+4R8VvWJ0XxgtikSo72fHjwha7MAjqFnOq6eo6fEC/75g3NL\nGht5VdpGuHk0vbdENHMC8wS99e5qXGNDued3hlTavDMlEAHl34q2H9nakTGRF5Ki\nJUfNh3DVRGhg8cMIti21njiRh7gyFI2OccATY7bBSr79JhuNwelHuxLrCFpY7V25\nOFktl15jZJaMxuQBqYdBgSay2G0U6D1+7VsWufpzd/Abx1/c3oi9ZaJvW22kAggq\ndzdA27UUYjWvx42w9menJwh/0jeQcTecIUd0d0rFcw/c1pvgMMl/Q73yzKgKYw==\n=zbHE\n-----END PGP PUBLIC KEY BLOCK-----\n-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n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\nvt61kpkXoRGxjTlc6h+69aidSg==\n=ls8J\n-----END PGP PUBLIC KEY BLOCK-----\n"
     }
   ],
   "ppc64le": [
     {
       "name": "baseos",
-      "baseurl": "https://rpmrepo.osbuild.org/v2/mirror/rhvpn/el8/el8-ppc64le-baseos-n8.5-20210715/",
+      "baseurl": "https://rpmrepo.osbuild.org/v2/mirror/rhvpn/el8/el8-ppc64le-baseos-n8.5-20210820/",
       "gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBErgSTsBEACh2A4b0O9t+vzC9VrVtL1AKvUWi9OPCjkvR7Xd8DtJxeeMZ5eF\n0HtzIG58qDRybwUe89FZprB1ffuUKzdE+HcL3FbNWSSOXVjZIersdXyH3NvnLLLF\n0DNRB2ix3bXG9Rh/RXpFsNxDp2CEMdUvbYCzE79K1EnUTVh1L0Of023FtPSZXX0c\nu7Pb5DI5lX5YeoXO6RoodrIGYJsVBQWnrWw4xNTconUfNPk0EGZtEnzvH2zyPoJh\nXGF+Ncu9XwbalnYde10OCvSWAZ5zTCpoLMTvQjWpbCdWXJzCm6G+/hx9upke546H\n5IjtYm4dTIVTnc3wvDiODgBKRzOl9rEOCIgOuGtDxRxcQkjrC+xvg5Vkqn7vBUyW\n9pHedOU+PoF3DGOM+dqv+eNKBvh9YF9ugFAQBkcG7viZgvGEMGGUpzNgN7XnS1gj\n/DPo9mZESOYnKceve2tIC87p2hqjrxOHuI7fkZYeNIcAoa83rBltFXaBDYhWAKS1\nPcXS1/7JzP0ky7d0L6Xbu/If5kqWQpKwUInXtySRkuraVfuK3Bpa+X1XecWi24JY\nHVtlNX025xx1ewVzGNCTlWn1skQN2OOoQTV4C8/qFpTW6DTWYurd4+fE0OJFJZQF\nbuhfXYwmRlVOgN5i77NTIJZJQfYFj38c/Iv5vZBPokO6mffrOTv3MHWVgQARAQAB\ntDNSZWQgSGF0LCBJbmMuIChyZWxlYXNlIGtleSAyKSA8c2VjdXJpdHlAcmVkaGF0\nLmNvbT6JAjYEEwECACAFAkrgSTsCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAK\nCRAZni+R/UMdUWzpD/9s5SFR/ZF3yjY5VLUFLMXIKUztNN3oc45fyLdTI3+UClKC\n2tEruzYjqNHhqAEXa2sN1fMrsuKec61Ll2NfvJjkLKDvgVIh7kM7aslNYVOP6BTf\nC/JJ7/ufz3UZmyViH/WDl+AYdgk3JqCIO5w5ryrC9IyBzYv2m0HqYbWfphY3uHw5\nun3ndLJcu8+BGP5F+ONQEGl+DRH58Il9Jp3HwbRa7dvkPgEhfFR+1hI+Btta2C7E\n0/2NKzCxZw7Lx3PBRcU92YKyaEihfy/aQKZCAuyfKiMvsmzs+4poIX7I9NQCJpyE\nIGfINoZ7VxqHwRn/d5mw2MZTJjbzSf+Um9YJyA0iEEyD6qjriWQRbuxpQXmlAJbh\n8okZ4gbVFv1F8MzK+4R8VvWJ0XxgtikSo72fHjwha7MAjqFnOq6eo6fEC/75g3NL\nGht5VdpGuHk0vbdENHMC8wS99e5qXGNDued3hlTavDMlEAHl34q2H9nakTGRF5Ki\nJUfNh3DVRGhg8cMIti21njiRh7gyFI2OccATY7bBSr79JhuNwelHuxLrCFpY7V25\nOFktl15jZJaMxuQBqYdBgSay2G0U6D1+7VsWufpzd/Abx1/c3oi9ZaJvW22kAggq\ndzdA27UUYjWvx42w9menJwh/0jeQcTecIUd0d0rFcw/c1pvgMMl/Q73yzKgKYw==\n=zbHE\n-----END PGP PUBLIC KEY BLOCK-----\n-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n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\nvt61kpkXoRGxjTlc6h+69aidSg==\n=ls8J\n-----END PGP PUBLIC KEY BLOCK-----\n"
     },
     {
       "name": "appstream",
-      "baseurl": "https://rpmrepo.osbuild.org/v2/mirror/rhvpn/el8/el8-ppc64le-appstream-n8.5-20210715/",
+      "baseurl": "https://rpmrepo.osbuild.org/v2/mirror/rhvpn/el8/el8-ppc64le-appstream-n8.5-20210820/",
       "gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBErgSTsBEACh2A4b0O9t+vzC9VrVtL1AKvUWi9OPCjkvR7Xd8DtJxeeMZ5eF\n0HtzIG58qDRybwUe89FZprB1ffuUKzdE+HcL3FbNWSSOXVjZIersdXyH3NvnLLLF\n0DNRB2ix3bXG9Rh/RXpFsNxDp2CEMdUvbYCzE79K1EnUTVh1L0Of023FtPSZXX0c\nu7Pb5DI5lX5YeoXO6RoodrIGYJsVBQWnrWw4xNTconUfNPk0EGZtEnzvH2zyPoJh\nXGF+Ncu9XwbalnYde10OCvSWAZ5zTCpoLMTvQjWpbCdWXJzCm6G+/hx9upke546H\n5IjtYm4dTIVTnc3wvDiODgBKRzOl9rEOCIgOuGtDxRxcQkjrC+xvg5Vkqn7vBUyW\n9pHedOU+PoF3DGOM+dqv+eNKBvh9YF9ugFAQBkcG7viZgvGEMGGUpzNgN7XnS1gj\n/DPo9mZESOYnKceve2tIC87p2hqjrxOHuI7fkZYeNIcAoa83rBltFXaBDYhWAKS1\nPcXS1/7JzP0ky7d0L6Xbu/If5kqWQpKwUInXtySRkuraVfuK3Bpa+X1XecWi24JY\nHVtlNX025xx1ewVzGNCTlWn1skQN2OOoQTV4C8/qFpTW6DTWYurd4+fE0OJFJZQF\nbuhfXYwmRlVOgN5i77NTIJZJQfYFj38c/Iv5vZBPokO6mffrOTv3MHWVgQARAQAB\ntDNSZWQgSGF0LCBJbmMuIChyZWxlYXNlIGtleSAyKSA8c2VjdXJpdHlAcmVkaGF0\nLmNvbT6JAjYEEwECACAFAkrgSTsCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAK\nCRAZni+R/UMdUWzpD/9s5SFR/ZF3yjY5VLUFLMXIKUztNN3oc45fyLdTI3+UClKC\n2tEruzYjqNHhqAEXa2sN1fMrsuKec61Ll2NfvJjkLKDvgVIh7kM7aslNYVOP6BTf\nC/JJ7/ufz3UZmyViH/WDl+AYdgk3JqCIO5w5ryrC9IyBzYv2m0HqYbWfphY3uHw5\nun3ndLJcu8+BGP5F+ONQEGl+DRH58Il9Jp3HwbRa7dvkPgEhfFR+1hI+Btta2C7E\n0/2NKzCxZw7Lx3PBRcU92YKyaEihfy/aQKZCAuyfKiMvsmzs+4poIX7I9NQCJpyE\nIGfINoZ7VxqHwRn/d5mw2MZTJjbzSf+Um9YJyA0iEEyD6qjriWQRbuxpQXmlAJbh\n8okZ4gbVFv1F8MzK+4R8VvWJ0XxgtikSo72fHjwha7MAjqFnOq6eo6fEC/75g3NL\nGht5VdpGuHk0vbdENHMC8wS99e5qXGNDued3hlTavDMlEAHl34q2H9nakTGRF5Ki\nJUfNh3DVRGhg8cMIti21njiRh7gyFI2OccATY7bBSr79JhuNwelHuxLrCFpY7V25\nOFktl15jZJaMxuQBqYdBgSay2G0U6D1+7VsWufpzd/Abx1/c3oi9ZaJvW22kAggq\ndzdA27UUYjWvx42w9menJwh/0jeQcTecIUd0d0rFcw/c1pvgMMl/Q73yzKgKYw==\n=zbHE\n-----END PGP PUBLIC KEY BLOCK-----\n-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n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\nvt61kpkXoRGxjTlc6h+69aidSg==\n=ls8J\n-----END PGP PUBLIC KEY BLOCK-----\n"
     }
   ]