distro/rhel90: update to match 8.6 and add centos-9 alias

- Copied distro and image definitions from RHEL 8.6
    - New package set handling
    - Distribution-specific strings
    - New image types: edge-raw and edge-simplified-installer
    - Edge container with nginx
    - Removed greenboot services from edge enabled services (enabled
      automatically)
- Adapted to required changes from RHEL 9.0 Beta
- Added CentOS 9 (centos-9) alias

Signed-off-by: Achilleas Koutsou <achilleas@koutsou.net>
This commit is contained in:
Achilleas Koutsou 2021-10-21 21:35:32 +02:00 committed by Ondřej Budai
parent ba4a4541d9
commit 6b73dc5a92
7 changed files with 1273 additions and 454 deletions

View file

@ -16,33 +16,15 @@ import (
"github.com/osbuild/osbuild-composer/internal/rpmmd"
)
const defaultName = "rhel-90-ga"
const osVersion = "9.0"
const releaseVersion = "9"
const modulePlatformID = "platform:el9"
const ostreeRef = "rhel/9/%s/edge"
const (
// package set names
// 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"
@ -59,10 +41,41 @@ var mountpointAllowList = []string{
type distribution struct {
name string
product string
osVersion string
releaseVersion string
modulePlatformID string
ostreeRef string
vendor string
ostreeRefTmpl string
isolabelTmpl string
runner string
arches map[string]distro.Arch
packageSets map[string]rpmmd.PackageSet
}
// distribution objects without the arches > image types
var distroMap = map[string]distribution{
"rhel-90-ga": {
name: "rhel-90-ga",
product: "Red Hat Enterprise Linux",
osVersion: "9.0",
releaseVersion: "9",
modulePlatformID: "platform:el9",
vendor: "redhat",
ostreeRefTmpl: "rhel/9/%s/edge",
isolabelTmpl: "RHEL-9-0-0-BaseOS-%s",
runner: "org.osbuild.rhel90",
},
"centos-9": {
name: "centos-9",
product: "CentOS Stream",
osVersion: "9-stream",
releaseVersion: "9",
modulePlatformID: "platform:el9",
vendor: "centos",
ostreeRefTmpl: "centos/9/%s/edge",
isolabelTmpl: "CentOS-Stream-9-%s-dvd",
runner: "org.osbuild.centos9",
},
}
func (d *distribution) Name() string {
@ -70,7 +83,7 @@ func (d *distribution) Name() string {
}
func (d *distribution) Releasever() string {
return releaseVersion
return d.releaseVersion
}
func (d *distribution) ModulePlatformID() string {
@ -78,7 +91,7 @@ func (d *distribution) ModulePlatformID() string {
}
func (d *distribution) OSTreeRef() string {
return d.ostreeRef
return d.ostreeRefTmpl
}
func (d *distribution) ListArches() []string {
@ -111,12 +124,15 @@ func (d *distribution) addArches(arches ...architecture) {
}
}
func (d *distribution) isRHEL() bool {
return strings.HasPrefix(d.name, "rhel")
}
type architecture struct {
distro *distribution
name string
imageTypes map[string]distro.ImageType
imageTypeAliases map[string]string
packageSets map[string]rpmmd.PackageSet
legacy string
bootType distro.BootType
}
@ -175,13 +191,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
@ -219,8 +237,9 @@ func (t *imageType) MIMEType() string {
}
func (t *imageType) OSTreeRef() string {
d := t.arch.distro
if t.rpmOstree {
return fmt.Sprintf(ostreeRef, t.arch.name)
return fmt.Sprintf(d.ostreeRefTmpl, t.arch.name)
}
return ""
}
@ -237,16 +256,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 {
@ -254,40 +281,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
@ -380,7 +376,7 @@ func (t *imageType) Manifest(customizations *blueprint.Customizations,
}
var commits []ostreeCommit
if t.bootISO && options.OSTree.Parent != "" && options.OSTree.URL != "" {
if options.OSTree.Parent != "" && options.OSTree.URL != "" {
commits = []ostreeCommit{{Checksum: options.OSTree.Parent, URL: options.OSTree.URL}}
}
return json.Marshal(
@ -450,11 +446,20 @@ 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 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 {
return fmt.Errorf("kernel boot parameter customizations are not supported for ostree types")
}
@ -484,75 +489,55 @@ func (t *imageType) checkOptions(customizations *blueprint.Customizations, optio
// New creates a new distro object, defining the supported architectures and image types
func New() distro.Distro {
return newDistro(defaultName, modulePlatformID, ostreeRef)
return newDistro("rhel-90-ga")
}
func NewHostDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
return newDistro(name, modulePlatformID, ostreeRef)
return newDistro("rhel-90-ga")
}
func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
func NewCentos() distro.Distro {
return newDistro("centos-9")
}
func NewCentosHostDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
return newDistro("centos-9")
}
func newDistro(distroName string) distro.Distro {
const GigaByte = 1024 * 1024 * 1024
rd := &distribution{
name: name,
modulePlatformID: modulePlatformID,
ostreeRef: ostreeRef,
packageSets: map[string]rpmmd.PackageSet{
buildPkgsKey: distroBuildPackageSet(),
edgeBuildPkgsKey: edgeBuildPackageSet(),
},
}
rd := distroMap[distroName]
// 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,
}
// Shared Services
edgeServices := []string{
"NetworkManager.service", "firewalld.service", "sshd.service",
"greenboot-grub2-set-counter", "greenboot-grub2-set-success", "greenboot-healthcheck",
"greenboot-rpm-ostree-grub2-check-fallback", "greenboot-status", "greenboot-task-runner",
"redboot-auto-reboot", "redboot-task-runner",
}
// Image Definitions
@ -561,24 +546,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{"httpd"}},
packageSets: map[string]packageSetFunc{
buildPkgsKey: edgeBuildPackageSet,
osPkgsKey: edgeCommitPackageSet,
containerPkgsKey: func(t *imageType) rpmmd.PackageSet {
return rpmmd.PackageSet{
Include: []string{"nginx"},
}
},
},
enabledServices: edgeServices,
rpmOstree: true,
@ -586,12 +576,30 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
pipelines: edgeContainerPipelines,
exports: []string{containerPkgsKey},
}
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
@ -599,9 +607,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,
@ -610,14 +618,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,
@ -630,8 +665,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",
@ -650,8 +686,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,
@ -665,8 +702,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,
@ -693,9 +731,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,
@ -712,9 +750,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,
@ -730,9 +768,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,
@ -749,9 +787,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,
@ -767,9 +805,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,
@ -786,9 +824,9 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
name: "ec2-sap",
filename: "image.raw.xz",
mimeType: "application/xz",
packageSets: map[string]rpmmd.PackageSet{
buildPkgsKey: ec2BuildPackageSet(),
osPkgsKey: rhelEc2SapPackageSet(),
packageSets: map[string]packageSetFunc{
buildPkgsKey: ec2BuildPackageSet,
osPkgsKey: rhelEc2SapPackageSet,
},
defaultTarget: "multi-user.target",
enabledServices: ec2EnabledServices,
@ -805,10 +843,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,
@ -818,10 +859,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,
@ -830,11 +871,19 @@ func newDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
exports: []string{"bootiso"},
}
x86_64.addImageTypes(qcow2ImgType, vhdImgType, vmdkImgType, openstackImgType, amiImgTypeX86_64, ec2ImgTypeX86_64, ec2HaImgTypeX86_64, ec2SapImgTypeX86_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, tarImgType, tarInstallerImgTypeX86_64, edgeCommitImgType, edgeInstallerImgType, edgeOCIImgType, edgeRawImgType, edgeSimplifiedInstallerImgType)
aarch64.addImageTypes(qcow2ImgType, openstackImgType, amiImgTypeAarch64, tarImgType, edgeCommitImgType, edgeInstallerImgType, edgeOCIImgType, edgeRawImgType, edgeSimplifiedInstallerImgType)
ppc64le.addImageTypes(qcow2ImgType, tarImgType)
s390x.addImageTypes(qcow2ImgType, tarImgType)
rd.addArches(x86_64, aarch64, ppc64le, s390x)
return rd
if rd.isRHEL() {
// add ec2 image types to RHEL distro only
x86_64.addImageTypes(ec2ImgTypeX86_64, ec2HaImgTypeX86_64, ec2SapImgTypeX86_64)
aarch64.addImageTypes(ec2ImgTypeAarch64)
// add s390x to RHEL distro only
rd.addArches(s390x)
}
rd.addArches(x86_64, aarch64, ppc64le)
return &rd
}

View file

@ -2,13 +2,18 @@ package rhel90
// 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",
@ -16,70 +21,210 @@ 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,
})
}
// x86_64 installer ISO build package set
// TODO: separate into common installer and arch specific sets
func x8664InstallerBuildPackageSet() rpmmd.PackageSet {
return rpmmd.PackageSet{
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{
"efibootmgr", "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",
"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
}
func installerBuildPackageSet(t *imageType) rpmmd.PackageSet {
return distroBuildPackageSet(t).Append(
rpmmd.PackageSet{
Include: []string{
"isomd5sum",
"xorriso",
},
})
}
func anacondaBuildPackageSet(t *imageType) rpmmd.PackageSet {
ps := rpmmd.PackageSet{
Include: []string{
"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 +234,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 +244,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,14 +252,14 @@ 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",
"cloud-utils-growpart", "cockpit-system", "cockpit-ws",
"dnf", "dnf-utils", "dosfstools",
"insights-client", "NetworkManager", "nfs-utils",
"oddjob", "oddjob-mkhomedir", "psmisc", "python3-jsonschema",
"NetworkManager", "nfs-utils", "oddjob",
"oddjob-mkhomedir", "psmisc", "python3-jsonschema",
"qemu-guest-agent", "redhat-release", "redhat-release-eula",
"rsync", "subscription-manager-cockpit", "tar", "tcpdump", "yum",
},
@ -126,17 +271,17 @@ func qcow2CommonPackageSet() rpmmd.PackageSet {
"iwl100-firmware", "iwl1000-firmware", "iwl105-firmware",
"iwl135-firmware", "iwl2000-firmware", "iwl2030-firmware",
"iwl3160-firmware", "iwl3945-firmware", "iwl4965-firmware",
"iwl5000-firmware", "iwl5150-firmware", "iwl6000-firmware",
"iwl5000-firmware", "iwl5150-firmware",
"iwl6000g2a-firmware", "iwl6000g2b-firmware", "iwl6050-firmware",
"iwl7260-firmware", "langpacks-*", "langpacks-en", "langpacks-en",
"libertas-sd8686-firmware", "libertas-sd8787-firmware",
"libertas-usb8388-firmware", "nss", "plymouth", "rng-tools",
"udisks2",
},
}
}.Append(bootPackageSet(t)).Append(distroSpecificPackageSet(t))
}
func vhdCommonPackageSet() rpmmd.PackageSet {
func vhdCommonPackageSet(t *imageType) rpmmd.PackageSet {
return rpmmd.PackageSet{
Include: []string{
// Defaults
@ -152,10 +297,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 +309,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,18 +326,19 @@ 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",
"dhcp-client", "yum-utils", "dracut-config-generic", "gdisk",
"grub2", "insights-client", "langpacks-en", "NetworkManager",
"NetworkManager-cloud-setup", "redhat-release",
"redhat-release-eula", "rsync", "tar", "qemu-guest-agent",
"@core", "authselect-compat", "chrony", "cloud-init",
"cloud-utils-growpart", "dhcp-client", "yum-utils",
"dracut-config-generic", "gdisk", "grub2",
"langpacks-en", "NetworkManager", "NetworkManager-cloud-setup",
"redhat-release", "redhat-release-eula", "rsync", "tar",
"qemu-guest-agent",
},
Exclude: []string{
"aic94xx-firmware", "alsa-firmware",
@ -200,26 +346,26 @@ func ec2CommonPackageSet() rpmmd.PackageSet {
"iwl1000-firmware", "iwl100-firmware", "iwl105-firmware",
"iwl135-firmware", "iwl2000-firmware", "iwl2030-firmware",
"iwl3160-firmware", "iwl3945-firmware", "iwl4965-firmware",
"iwl5000-firmware", "iwl5150-firmware", "iwl6000-firmware",
"iwl5000-firmware", "iwl5150-firmware",
"iwl6000g2a-firmware", "iwl6000g2b-firmware", "iwl6050-firmware",
"iwl7260-firmware", "libertas-sd8686-firmware",
"libertas-sd8787-firmware", "libertas-usb8388-firmware",
"plymouth",
},
}
}.Append(bootPackageSet(t)).Append(distroSpecificPackageSet(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")
ec2PackageSet.Exclude = append(ec2PackageSet.Exclude, "alsa-lib")
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",
@ -231,8 +377,8 @@ func rhelEc2HaPackageSet() rpmmd.PackageSet {
}
// rhel-sap-ec2 image package set
func rhelEc2SapPackageSet() rpmmd.PackageSet {
ec2SapPackageSet := ec2CommonPackageSet()
func rhelEc2SapPackageSet(t *imageType) rpmmd.PackageSet {
ec2SapPackageSet := ec2CommonPackageSet(t)
ec2SapPackageSet.Include = append(ec2SapPackageSet.Include,
// SAP System Roles
// https://access.redhat.com/sites/default/files/attachments/rhel_system_roles_for_sap_1.pdf
@ -240,7 +386,7 @@ func rhelEc2SapPackageSet() rpmmd.PackageSet {
"rhel-system-roles-sap",
// RHBZ#1959813
"bind-utils",
//"compat-sap-c++-9", // not needed on RHEL-9
"compat-sap-c++-9",
"nfs-utils",
"tcsh",
// RHBZ#1959955
@ -256,7 +402,6 @@ func rhelEc2SapPackageSet() rpmmd.PackageSet {
"libatomic",
"libcanberra-gtk2",
"libicu",
//"libpng12", // not needed on RHEL-9
"libtool-ltdl",
"lm_sensors",
"net-tools",
@ -274,8 +419,8 @@ func rhelEc2SapPackageSet() 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",
@ -289,7 +434,7 @@ func edgeCommitPackageSet() rpmmd.PackageSet {
"hostname", "iproute", "iputils", "openssh-clients", "procps-ng",
"rootfiles", "openssh-server", "passwd", "policycoreutils",
"policycoreutils-python-utils", "selinux-policy-targeted",
"setools-console", "less", "tar", "rsync", "fwupd", "usbguard",
"setools-console", "less", "tar", "rsync", "usbguard",
"bash-completion", "tmux", "ima-evm-utils", "audit", "podman",
"container-selinux", "skopeo", "criu", "slirp4netns",
"fuse-overlayfs", "clevis", "clevis-dracut", "clevis-luks",
@ -298,9 +443,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",
@ -314,138 +472,227 @@ 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,
}
}
// INSTALLER PACKAGE SET
func installerPackageSet() rpmmd.PackageSet {
// TODO: simplify
return 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", "gnome-kiosk",
"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",
},
}
}
func edgeInstallerPackageSet() rpmmd.PackageSet {
return 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", "gnome-kiosk",
"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",
"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",
},
Exclude: nil,
}
}
func bareMetalPackageSet() rpmmd.PackageSet {
func bareMetalPackageSet(t *imageType) rpmmd.PackageSet {
return rpmmd.PackageSet{
Include: []string{
"authselect-compat", "chrony", "cockpit-system", "cockpit-ws",
"@core", "dhcp-client", "dnf", "dnf-utils", "dosfstools",
"insights-client", "iwl1000-firmware", "iwl100-firmware",
"iwl1000-firmware", "iwl100-firmware", "iwl105-firmware",
"iwl135-firmware", "iwl2000-firmware", "iwl2030-firmware",
"iwl3160-firmware", "iwl3945-firmware", "iwl4965-firmware",
"iwl5000-firmware", "iwl5150-firmware",
"iwl6000g2a-firmware", "iwl6000g2b-firmware", "iwl6050-firmware",
"iwl7260-firmware", "lvm2", "net-tools", "NetworkManager",
"nfs-utils", "oddjob", "oddjob-mkhomedir", "policycoreutils",
"psmisc", "python3-jsonschema", "qemu-guest-agent",
"redhat-release", "redhat-release-eula", "rsync",
"selinux-policy-targeted", "subscription-manager-cockpit", "tar",
"tcpdump", "yum",
},
Exclude: nil,
}.Append(bootPackageSet(t)).Append(distroBuildPackageSet(t))
}
// packages that are only in some (sub)-distributions
func distroSpecificPackageSet(t *imageType) rpmmd.PackageSet {
if t.arch.distro.isRHEL() {
return rpmmd.PackageSet{
Include: []string{"insights-client"},
}
}
return rpmmd.PackageSet{}
}
// INSTALLER PACKAGE SET
func installerPackageSet(t *imageType) rpmmd.PackageSet {
ps := rpmmd.PackageSet{
Include: []string{
"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",
"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 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",
"efibootmgr", "ethtool", "ftp", "gdb-gdbserver", "gdisk",
"glibc-all-langpacks", "gnome-kiosk",
"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", "iwl5000-firmware",
"iwl5150-firmware", "iwl6000g2a-firmware", "iwl6000g2b-firmware",
"iwl6050-firmware", "iwl7260-firmware", "lvm2", "net-tools",
"NetworkManager", "nfs-utils", "oddjob", "oddjob-mkhomedir",
"policycoreutils", "psmisc", "python3-jsonschema",
"qemu-guest-agent", "redhat-release", "redhat-release-eula",
"rsync", "selinux-policy-targeted", "subscription-manager-cockpit",
"tar", "tcpdump", "yum",
"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", "libibverbs", "libreport-plugin-bugzilla",
"libreport-plugin-reportuploader", "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+", "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",
"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",
},
})
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
}

View file

@ -181,3 +181,101 @@ 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,
},
},
},
},
}

View file

@ -3,20 +3,21 @@ package rhel90
import (
"fmt"
"math/rand"
"path"
"path/filepath"
"strings"
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/common"
"github.com/osbuild/osbuild-composer/internal/disk"
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/osbuild2"
osbuild "github.com/osbuild/osbuild-composer/internal/osbuild2"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
)
func qcow2Pipelines(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]))
pipelines = append(pipelines, *buildPipeline(repos, packageSetSpecs[buildPkgsKey], t.arch.distro.runner))
treePipeline, err := osPipeline(repos, packageSetSpecs[osPkgsKey], packageSetSpecs[blueprintPkgsKey], customizations, options, t.enabledServices, t.disabledServices, t.defaultTarget)
if err != nil {
@ -43,9 +44,10 @@ 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)
@ -68,7 +70,7 @@ func prependKernelCmdlineStage(pipeline *osbuild.Pipeline, t *imageType, pt *dis
func vhdPipelines(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]))
pipelines = append(pipelines, *buildPipeline(repos, packageSetSpecs[buildPkgsKey], t.arch.distro.runner))
treePipeline, err := osPipeline(repos, packageSetSpecs[osPkgsKey], packageSetSpecs[blueprintPkgsKey], customizations, options, t.enabledServices, t.disabledServices, t.defaultTarget)
if err != nil {
return nil, err
@ -82,7 +84,7 @@ func vhdPipelines(t *imageType, customizations *blueprint.Customizations, option
treePipeline = prependKernelCmdlineStage(treePipeline, t, &partitionTable)
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)
@ -100,7 +102,7 @@ func vhdPipelines(t *imageType, customizations *blueprint.Customizations, option
func vmdkPipelines(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]))
pipelines = append(pipelines, *buildPipeline(repos, packageSetSpecs[buildPkgsKey], t.arch.distro.runner))
treePipeline, err := osPipeline(repos, packageSetSpecs[osPkgsKey], packageSetSpecs[blueprintPkgsKey], customizations, options, t.enabledServices, t.disabledServices, t.defaultTarget)
if err != nil {
return nil, err
@ -114,7 +116,7 @@ func vmdkPipelines(t *imageType, customizations *blueprint.Customizations, optio
treePipeline = prependKernelCmdlineStage(treePipeline, t, &partitionTable)
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)
@ -132,7 +134,7 @@ func vmdkPipelines(t *imageType, customizations *blueprint.Customizations, optio
func openstackPipelines(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]))
pipelines = append(pipelines, *buildPipeline(repos, packageSetSpecs[buildPkgsKey], t.arch.distro.runner))
treePipeline, err := osPipeline(repos, packageSetSpecs[osPkgsKey], packageSetSpecs[blueprintPkgsKey], customizations, options, t.enabledServices, t.disabledServices, t.defaultTarget)
if err != nil {
return nil, err
@ -142,10 +144,11 @@ func openstackPipelines(t *imageType, customizations *blueprint.Customizations,
if err != nil {
return nil, err
}
treePipeline = prependKernelCmdlineStage(treePipeline, t, &partitionTable)
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)
@ -171,9 +174,17 @@ func openstackPipelines(t *imageType, customizations *blueprint.Customizations,
// Note: the caller of this function has to append the `osbuild.NewSELinuxStage(selinuxStageOptions(false))` stage
// as the last one to the returned pipeline. The stage is not appended on purpose, to allow caller to append
// any additional stages to the pipeline, but before the SELinuxStage, which must be always the last one.
func ec2BaseTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, bpPackages []rpmmd.PackageSpec,
c *blueprint.Customizations, options distro.ImageOptions, enabledServices, disabledServices []string,
defaultTarget string, withRHUI bool, pt *disk.PartitionTable) (*osbuild.Pipeline, error) {
func ec2BaseTreePipeline(
repos []rpmmd.RepoConfig,
packages []rpmmd.PackageSpec,
bpPackages []rpmmd.PackageSpec,
c *blueprint.Customizations,
options distro.ImageOptions,
enabledServices, disabledServices []string,
defaultTarget string,
withRHUI, isRHEL bool,
pt *disk.PartitionTable) (*osbuild.Pipeline, error) {
p := new(osbuild.Pipeline)
p.Name = "os"
p.Build = "name:build"
@ -312,7 +323,7 @@ func ec2BaseTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec,
},
}))
// RHBZ#1822853
// RHBZ#1822863
p.AddStage(osbuild.NewSystemdUnitStage(&osbuild.SystemdUnitStageOptions{
Unit: "nm-cloud-setup.service",
Dropin: "10-rh-enable-for-ec2.conf",
@ -327,42 +338,44 @@ func ec2BaseTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec,
Profile: "sssd",
}))
if options.Subscription != nil {
commands := []string{
fmt.Sprintf("/usr/sbin/subscription-manager register --org=%s --activationkey=%s --serverurl %s --baseurl %s", options.Subscription.Organization, options.Subscription.ActivationKey, options.Subscription.ServerUrl, options.Subscription.BaseUrl),
}
if options.Subscription.Insights {
commands = append(commands, "/usr/bin/insights-client --register")
}
p.AddStage(osbuild.NewFirstBootStage(&osbuild.FirstBootStageOptions{
Commands: commands,
WaitForNetwork: true,
}))
} else {
// The EC2 images should keep the RHSM DNF plugins enabled (RHBZ#1996670)
rhsmStageOptions := &osbuild.RHSMStageOptions{
// RHBZ#1932802
SubMan: &osbuild.RHSMStageOptionsSubMan{
Rhsmcertd: &osbuild.SubManConfigRHSMCERTDSection{
AutoRegistration: common.BoolToPtr(true),
},
},
}
// Disable RHSM redhat.repo management only if the image uses RHUI
// for content. Otherwise subscribing the system manually after booting
// it would result in empty redhat.repo. Without RHUI, such system
// would have no way to get Red Hat content, but enable the repo
// management manually, which would be very confusing.
// RHBZ#1932802
if withRHUI {
rhsmStageOptions.SubMan.Rhsm = &osbuild.SubManConfigRHSMSection{
ManageRepos: common.BoolToPtr(false),
if isRHEL {
if options.Subscription != nil {
commands := []string{
fmt.Sprintf("/usr/sbin/subscription-manager register --org=%s --activationkey=%s --serverurl %s --baseurl %s", options.Subscription.Organization, options.Subscription.ActivationKey, options.Subscription.ServerUrl, options.Subscription.BaseUrl),
}
if options.Subscription.Insights {
commands = append(commands, "/usr/bin/insights-client --register")
}
}
p.AddStage(osbuild.NewRHSMStage(rhsmStageOptions))
p.AddStage(osbuild.NewFirstBootStage(&osbuild.FirstBootStageOptions{
Commands: commands,
WaitForNetwork: true,
}))
} else {
// The EC2 images should keep the RHSM DNF plugins enabled (RHBZ#1996670)
rhsmStageOptions := &osbuild.RHSMStageOptions{
// RHBZ#1932802
SubMan: &osbuild.RHSMStageOptionsSubMan{
Rhsmcertd: &osbuild.SubManConfigRHSMCERTDSection{
AutoRegistration: common.BoolToPtr(true),
},
},
}
// Disable RHSM redhat.repo management only if the image uses RHUI
// for content. Otherwise subscribing the system manually after booting
// it would result in empty redhat.repo. Without RHUI, such system
// would have no way to get Red Hat content, but enable the repo
// management manually, which would be very confusing.
// RHBZ#1932802
if withRHUI {
rhsmStageOptions.SubMan.Rhsm = &osbuild.SubManConfigRHSMSection{
ManageRepos: common.BoolToPtr(false),
}
}
p.AddStage(osbuild.NewRHSMStage(rhsmStageOptions))
}
}
return p, nil
@ -370,9 +383,9 @@ func ec2BaseTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec,
func ec2X86_64BaseTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, bpPackages []rpmmd.PackageSpec,
c *blueprint.Customizations, options distro.ImageOptions, enabledServices, disabledServices []string,
defaultTarget string, withRHUI bool, pt *disk.PartitionTable) (*osbuild.Pipeline, error) {
defaultTarget string, withRHUI, isRHEL bool, pt *disk.PartitionTable) (*osbuild.Pipeline, error) {
treePipeline, err := ec2BaseTreePipeline(repos, packages, bpPackages, c, options, enabledServices, disabledServices, defaultTarget, withRHUI, pt)
treePipeline, err := ec2BaseTreePipeline(repos, packages, bpPackages, c, options, enabledServices, disabledServices, defaultTarget, withRHUI, isRHEL, pt)
if err != nil {
return nil, err
}
@ -397,7 +410,7 @@ func ec2CommonPipelines(t *imageType, customizations *blueprint.Customizations,
repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec,
rng *rand.Rand, withRHUI bool, diskfile string) ([]osbuild.Pipeline, error) {
pipelines := make([]osbuild.Pipeline, 0)
pipelines = append(pipelines, *buildPipeline(repos, packageSetSpecs[buildPkgsKey]))
pipelines = append(pipelines, *buildPipeline(repos, packageSetSpecs[buildPkgsKey], t.arch.distro.runner))
partitionTable, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng)
if err != nil {
@ -408,10 +421,10 @@ func ec2CommonPipelines(t *imageType, customizations *blueprint.Customizations,
switch arch := t.arch.Name(); arch {
// rhel-ec2-x86_64, rhel-ha-ec2
case distro.X86_64ArchName:
treePipeline, err = ec2X86_64BaseTreePipeline(repos, packageSetSpecs[osPkgsKey], packageSetSpecs[blueprintPkgsKey], customizations, options, t.enabledServices, t.disabledServices, t.defaultTarget, withRHUI, &partitionTable)
treePipeline, err = ec2X86_64BaseTreePipeline(repos, packageSetSpecs[osPkgsKey], packageSetSpecs[blueprintPkgsKey], customizations, options, t.enabledServices, t.disabledServices, t.defaultTarget, withRHUI, t.arch.distro.isRHEL(), &partitionTable)
// rhel-ec2-aarch64
case distro.Aarch64ArchName:
treePipeline, err = ec2BaseTreePipeline(repos, packageSetSpecs[osPkgsKey], packageSetSpecs[blueprintPkgsKey], customizations, options, t.enabledServices, t.disabledServices, t.defaultTarget, withRHUI, &partitionTable)
treePipeline, err = ec2BaseTreePipeline(repos, packageSetSpecs[osPkgsKey], packageSetSpecs[blueprintPkgsKey], customizations, options, t.enabledServices, t.disabledServices, t.defaultTarget, withRHUI, t.arch.distro.isRHEL(), &partitionTable)
default:
return nil, fmt.Errorf("ec2CommonPipelines: unsupported image architecture: %q", arch)
}
@ -422,7 +435,7 @@ func ec2CommonPipelines(t *imageType, customizations *blueprint.Customizations,
treePipeline = prependKernelCmdlineStage(treePipeline, t, &partitionTable)
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)
@ -436,7 +449,7 @@ func ec2SapPipelines(t *imageType, customizations *blueprint.Customizations, opt
repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec,
rng *rand.Rand, withRHUI bool, diskfile string) ([]osbuild.Pipeline, error) {
pipelines := make([]osbuild.Pipeline, 0)
pipelines = append(pipelines, *buildPipeline(repos, packageSetSpecs[buildPkgsKey]))
pipelines = append(pipelines, *buildPipeline(repos, packageSetSpecs[buildPkgsKey], t.arch.distro.runner))
partitionTable, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng)
if err != nil {
@ -447,7 +460,7 @@ func ec2SapPipelines(t *imageType, customizations *blueprint.Customizations, opt
switch arch := t.arch.Name(); arch {
// rhel-sap-ec2
case distro.X86_64ArchName:
treePipeline, err = ec2X86_64BaseTreePipeline(repos, packageSetSpecs[osPkgsKey], packageSetSpecs[blueprintPkgsKey], customizations, options, t.enabledServices, t.disabledServices, t.defaultTarget, withRHUI, &partitionTable)
treePipeline, err = ec2X86_64BaseTreePipeline(repos, packageSetSpecs[osPkgsKey], packageSetSpecs[blueprintPkgsKey], customizations, options, t.enabledServices, t.disabledServices, t.defaultTarget, withRHUI, t.arch.distro.isRHEL(), &partitionTable)
default:
return nil, fmt.Errorf("ec2SapPipelines: unsupported image architecture: %q", arch)
}
@ -554,7 +567,7 @@ func ec2SapPipelines(t *imageType, customizations *blueprint.Customizations, opt
[]osbuild.DNFVariable{
{
Name: "releasever",
Value: "9.0",
Value: t.arch.distro.osVersion,
},
},
)))
@ -562,7 +575,7 @@ func ec2SapPipelines(t *imageType, customizations *blueprint.Customizations, opt
treePipeline = prependKernelCmdlineStage(treePipeline, t, &partitionTable)
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)
@ -609,7 +622,7 @@ func rhelEc2SapPipelines(t *imageType, customizations *blueprint.Customizations,
func tarPipelines(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]))
pipelines = append(pipelines, *buildPipeline(repos, packageSetSpecs[buildPkgsKey], t.arch.distro.runner))
treePipeline, err := osPipeline(repos, packageSetSpecs[osPkgsKey], packageSetSpecs[blueprintPkgsKey], customizations, options, t.enabledServices, t.disabledServices, t.defaultTarget)
if err != nil {
@ -626,21 +639,33 @@ func tarPipelines(t *imageType, customizations *blueprint.Customizations, option
return pipelines, nil
}
//makeISORootPath return a path that can be used to address files and folders in
//the root of the iso
func makeISORootPath(p string) string {
fullpath := path.Join("/run/install/repo", p)
return fmt.Sprintf("file://%s", fullpath)
}
func edgeInstallerPipelines(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]))
pipelines = append(pipelines, *buildPipeline(repos, packageSetSpecs[buildPkgsKey], t.arch.distro.runner))
installerPackages := packageSetSpecs[installerPkgsKey]
kernelVer := kernelVerStr(installerPackages, "kernel", t.Arch().Name())
d := t.arch.distro
archName := t.arch.name
kernelVer := kernelVerStr(installerPackages, "kernel", archName)
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()))
payloadStages := ostreePayloadStages(options, ostreeRepoPath)
kickstartOptions := ostreeKickstartStageOptions(makeISORootPath(ostreeRepoPath), options.OSTree.Ref)
pipelines = append(pipelines, *anacondaTreePipeline(repos, installerPackages, kernelVer, archName, d.product, d.osVersion, "edge"))
isolabel := fmt.Sprintf(d.isolabelTmpl, archName)
pipelines = append(pipelines, *bootISOTreePipeline(kernelVer, archName, d.vendor, d.product, d.osVersion, isolabel, kickstartOptions, payloadStages))
pipelines = append(pipelines, *bootISOPipeline(t.Filename(), d.isolabelTmpl, archName, false))
return pipelines, nil
}
func tarInstallerPipelines(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]))
pipelines = append(pipelines, *buildPipeline(repos, packageSetSpecs[buildPkgsKey], t.arch.distro.runner))
treePipeline, err := osPipeline(repos, packageSetSpecs[osPkgsKey], packageSetSpecs[blueprintPkgsKey], customizations, options, t.enabledServices, t.disabledServices, t.defaultTarget)
if err != nil {
@ -664,15 +689,19 @@ func tarInstallerPipelines(t *imageType, customizations *blueprint.Customization
tarPath := "/liveimg.tar"
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()))
kickstartOptions := tarKickstartStageOptions(makeISORootPath(tarPath))
archName := t.arch.name
d := t.arch.distro
pipelines = append(pipelines, *anacondaTreePipeline(repos, installerPackages, kernelVer, archName, d.product, d.osVersion, "BaseOS"))
isolabel := fmt.Sprintf(d.isolabelTmpl, archName)
pipelines = append(pipelines, *bootISOTreePipeline(kernelVer, archName, d.vendor, d.product, d.osVersion, isolabel, kickstartOptions, tarPayloadStages))
pipelines = append(pipelines, *bootISOPipeline(t.Filename(), d.isolabelTmpl, t.Arch().Name(), true))
return pipelines, nil
}
func edgeCorePipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec) ([]osbuild.Pipeline, error) {
pipelines := make([]osbuild.Pipeline, 0)
pipelines = append(pipelines, *buildPipeline(repos, packageSetSpecs[buildPkgsKey]))
pipelines = append(pipelines, *buildPipeline(repos, packageSetSpecs[buildPkgsKey], t.arch.distro.runner))
treePipeline, err := ostreeTreePipeline(repos, packageSetSpecs[osPkgsKey], packageSetSpecs[blueprintPkgsKey], customizations, options, t.enabledServices, t.disabledServices, t.defaultTarget)
if err != nil {
@ -680,7 +709,7 @@ func edgeCorePipelines(t *imageType, customizations *blueprint.Customizations, o
}
pipelines = append(pipelines, *treePipeline)
pipelines = append(pipelines, *ostreeCommitPipeline(options))
pipelines = append(pipelines, *ostreeCommitPipeline(options, t.arch.distro.osVersion))
return pipelines, nil
}
@ -704,15 +733,60 @@ func edgeContainerPipelines(t *imageType, customizations *blueprint.Customizatio
if err != nil {
return nil, err
}
pipelines = append(pipelines, *containerTreePipeline(repos, packageSetSpecs[containerPkgsKey], options, customizations))
pipelines = append(pipelines, *containerPipeline(t))
nginxConfigPath := "/etc/nginx.conf"
httpPort := "8080"
pipelines = append(pipelines, *containerTreePipeline(repos, packageSetSpecs[containerPkgsKey], options, customizations, nginxConfigPath, httpPort))
pipelines = append(pipelines, *containerPipeline(t, nginxConfigPath, httpPort))
return pipelines, nil
}
func buildPipeline(repos []rpmmd.RepoConfig, buildPackageSpecs []rpmmd.PackageSpec) *osbuild.Pipeline {
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], t.arch.distro.runner))
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, runner string) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = "build"
p.Runner = "org.osbuild.rhel90"
p.Runner = runner
p.AddStage(osbuild.NewRPMStage(rpmStageOptions(repos), rpmStageInputs(buildPackageSpecs)))
p.AddStage(osbuild.NewSELinuxStage(selinuxStageOptions(true)))
return p
@ -804,6 +878,11 @@ func ostreeTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec,
p.Build = "name:build"
packages = append(packages, bpPackages...)
if options.OSTree.Parent != "" && options.OSTree.URL != "" {
p.AddStage(osbuild.NewOSTreePasswdStage("org.osbuild.source", options.OSTree.Parent))
}
p.AddStage(osbuild.NewRPMStage(rpmStageOptions(repos), rpmStageInputs(packages)))
p.AddStage(osbuild.NewFixBLSStage(&osbuild.FixBLSStageOptions{}))
language, keyboard := c.GetPrimaryLocale()
@ -887,7 +966,7 @@ func ostreeTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec,
}))
return p, nil
}
func ostreeCommitPipeline(options distro.ImageOptions) *osbuild.Pipeline {
func ostreeCommitPipeline(options distro.ImageOptions, osVersion string) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = "ostree-commit"
p.Build = "name:build"
@ -917,7 +996,7 @@ func tarStage(source, filename string) *osbuild.Stage {
return osbuild.NewTarStage(&osbuild.TarStageOptions{Filename: filename}, &osbuild.TarStageInputs{Tree: tree})
}
func containerTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, options distro.ImageOptions, c *blueprint.Customizations) *osbuild.Pipeline {
func containerTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, options distro.ImageOptions, c *blueprint.Customizations, nginxConfigPath, listenPort string) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = "container-tree"
p.Build = "name:build"
@ -928,16 +1007,25 @@ func containerTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpe
} else {
p.AddStage(osbuild.NewLocaleStage(&osbuild.LocaleStageOptions{Language: "en_US"}))
}
p.AddStage(osbuild.NewOSTreeInitStage(&osbuild.OSTreeInitStageOptions{Path: "/var/www/html/repo"}))
htmlRoot := "/usr/share/nginx/html"
repoPath := filepath.Join(htmlRoot, "repo")
p.AddStage(osbuild.NewOSTreeInitStage(&osbuild.OSTreeInitStageOptions{Path: repoPath}))
p.AddStage(osbuild.NewOSTreePullStage(
&osbuild.OSTreePullStageOptions{Repo: "/var/www/html/repo"},
&osbuild.OSTreePullStageOptions{Repo: repoPath},
ostreePullStageInputs("org.osbuild.pipeline", "name:ostree-commit", options.OSTree.Ref),
))
// make nginx log directory world writeable, otherwise nginx can't start in
// an unprivileged container
p.AddStage(osbuild.NewChmodStage(chmodStageOptions("/var/log/nginx", "o+w", true)))
p.AddStage(osbuild.NewNginxConfigStage(nginxConfigStageOptions(nginxConfigPath, htmlRoot, listenPort)))
return p
}
func containerPipeline(t *imageType) *osbuild.Pipeline {
func containerPipeline(t *imageType, nginxConfigPath, listenPort string) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = "container"
p.Build = "name:build"
@ -945,8 +1033,8 @@ func containerPipeline(t *imageType) *osbuild.Pipeline {
Architecture: t.arch.Name(),
Filename: t.Filename(),
Config: &osbuild.OCIArchiveConfig{
Cmd: []string{"httpd", "-D", "FOREGROUND"},
ExposedPorts: []string{"80"},
Cmd: []string{"nginx", "-c", nginxConfigPath},
ExposedPorts: []string{listenPort},
},
}
baseInput := new(osbuild.OCIArchiveStageInput)
@ -971,15 +1059,230 @@ func ostreePayloadStages(options distro.ImageOptions, ostreeRepoPath string) []*
return stages
}
func anacondaTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, kernelVer string, arch string, payloadStages []*osbuild.Stage) *osbuild.Pipeline {
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], t.arch.distro.runner))
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
d := t.arch.distro
archName := t.arch.name
installerTreePipeline := simplifiedInstallerTreePipeline(repos, installerPackages, kernelVer, archName, d.product, d.osVersion, "edge")
isolabel := fmt.Sprintf(d.isolabelTmpl, archName)
efibootTreePipeline := simplifiedInstallerEFIBootTreePipeline(installDevice, kernelVer, archName, d.vendor, d.product, d.osVersion, isolabel)
bootISOTreePipeline := simplifiedInstallerBootISOTreePipeline(imgPipelineName, kernelVer)
pipelines = append(pipelines, *installerTreePipeline, *efibootTreePipeline, *bootISOTreePipeline)
pipelines = append(pipelines, *bootISOPipeline(t.Filename(), d.isolabelTmpl, 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, vendor, product, osVersion, isolabel string) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = "efiboot-tree"
p.Build = "name:build"
p.AddStage(osbuild.NewGrubISOStage(grubISOStageOptions(installDevice, kernelVer, arch, vendor, product, osVersion, isolabel)))
return p
}
func simplifiedInstallerTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, kernelVer, arch, product, osVersion, variant 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, product, osVersion, variant)))
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",
},
},
))
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(osbuild.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, arch, product, osVersion, variant string) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = "anaconda-tree"
p.Build = "name:build"
p.AddStage(osbuild.NewRPMStage(rpmStageOptions(repos), rpmStageInputs(packages)))
for _, stage := range payloadStages {
p.AddStage(stage)
}
p.AddStage(osbuild.NewBuildstampStage(buildStampStageOptions(arch)))
p.AddStage(osbuild.NewBuildstampStage(buildStampStageOptions(arch, product, osVersion, variant)))
p.AddStage(osbuild.NewLocaleStage(&osbuild.LocaleStageOptions{Language: "en_US.UTF-8"}))
rootPassword := ""
@ -1009,28 +1312,34 @@ 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
}
func bootISOTreePipeline(kernelVer string, arch string, ksOptions *osbuild.KickstartStageOptions) *osbuild.Pipeline {
func bootISOTreePipeline(kernelVer, arch, vendor, product, osVersion, isolabel string, ksOptions *osbuild.KickstartStageOptions, payloadStages []*osbuild.Stage) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = "bootiso-tree"
p.Build = "name:build"
p.AddStage(osbuild.NewBootISOMonoStage(bootISOMonoStageOptions(kernelVer, arch), bootISOMonoStageInputs()))
p.AddStage(osbuild.NewBootISOMonoStage(bootISOMonoStageOptions(kernelVer, arch, vendor, product, osVersion, isolabel), bootISOMonoStageInputs()))
p.AddStage(osbuild.NewKickstartStage(ksOptions))
p.AddStage(osbuild.NewDiscinfoStage(discinfoStageOptions(arch)))
for _, stage := range payloadStages {
p.AddStage(stage)
}
return p
}
func bootISOPipeline(filename string, arch string) *osbuild.Pipeline {
func bootISOPipeline(filename, isolabel, 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, isolabel, arch, isolinux), xorrisofsStageInputs("bootiso-tree")))
p.AddStage(osbuild.NewImplantisomd5Stage(&osbuild.Implantisomd5StageOptions{Filename: filename}))
return p
@ -1073,8 +1382,8 @@ func xzArchivePipeline(inputPipelineName, inputFilename, outputFilename string)
// mkfsStages generates a list of org.osbuild.mkfs.* stages based on a
// partition table description for a single device node
func mkfsStages(pt *disk.PartitionTable, device *osbuild.Device) []*osbuild2.Stage {
stages := make([]*osbuild2.Stage, 0, len(pt.Partitions))
func mkfsStages(pt *disk.PartitionTable, device *osbuild.Device) []*osbuild.Stage {
stages := make([]*osbuild.Stage, 0, len(pt.Partitions))
// assume loopback device for simplicity since it's the only one currently supported
// panic if the conversion fails
@ -1138,7 +1447,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))
}
@ -1146,7 +1455,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, t.arch.distro.vendor, 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 {

View file

@ -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"

View file

@ -2,14 +2,17 @@ package rhel90
import (
"fmt"
"os"
"path/filepath"
"sort"
"github.com/google/uuid"
"github.com/osbuild/osbuild-composer/internal/blueprint"
"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"
)
@ -144,12 +147,12 @@ func systemdStageOptions(enabledServices, disabledServices []string, s *blueprin
}
}
func buildStampStageOptions(arch string) *osbuild.BuildstampStageOptions {
func buildStampStageOptions(arch, product, osVersion, variant string) *osbuild.BuildstampStageOptions {
return &osbuild.BuildstampStageOptions{
Arch: arch,
Product: "Red Hat Enterprise Linux",
Product: product,
Version: osVersion,
Variant: "edge",
Variant: variant,
Final: true,
}
}
@ -171,7 +174,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",
@ -192,7 +195,6 @@ func dracutStageOptions(kernelVer string) *osbuild.DracutStageOptions {
"plymouth",
"prefixdevname",
"prefixdevname-tools",
"anaconda",
"crypt",
"dm",
"dmsquash-live",
@ -214,7 +216,6 @@ func dracutStageOptions(kernelVer string) *osbuild.DracutStageOptions {
"rootfs-block",
"terminfo",
"udev-rules",
"biosdevname",
"dracut-systemd",
"pollcdrom",
"usrmount",
@ -224,6 +225,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,
@ -252,29 +259,35 @@ func ostreeKickstartStageOptions(ostreeURL, ostreeRef string) *osbuild.Kickstart
}
}
func bootISOMonoStageOptions(kernelVer string, arch string) *osbuild.BootISOMonoStageOptions {
func bootISOMonoStageOptions(kernelVer, arch, vendor, product, osVersion, isolabel string) *osbuild.BootISOMonoStageOptions {
comprOptions := new(osbuild.FSCompressionOptions)
if bcj := osbuild.BCJOption(arch); bcj != "" {
comprOptions.BCJ = bcj
}
isolabel := fmt.Sprintf("RHEL-9-0-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",
Name: product,
Version: osVersion,
},
ISOLabel: isolabel,
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: vendor,
},
ISOLinux: osbuild.ISOLinux{
Enabled: true,
Enabled: arch == distro.X86_64ArchName,
Debug: false,
},
Templates: "80-rhel",
@ -288,6 +301,40 @@ func bootISOMonoStageOptions(kernelVer string, arch string) *osbuild.BootISOMono
}
}
func grubISOStageOptions(installDevice, kernelVer, arch, vendor, product, osVersion, isolabel string) *osbuild.GrubISOStageOptions {
var architectures []string
if arch == "x86_64" {
architectures = []string{"IA32", "X64"}
} else if arch == "aarch64" {
architectures = []string{"AA64"}
} else {
panic("unsupported architecture")
}
return &osbuild.GrubISOStageOptions{
Product: osbuild.Product{
Name: product,
Version: osVersion,
},
ISOLabel: isolabel,
Kernel: osbuild.ISOKernel{
Dir: "/images/pxeboot",
Opts: []string{"rd.neednet=1",
"console=tty0",
"console=ttyS0",
"systemd.log_target=console",
"systemd.journald.forward_to_console=1",
"edge.liveiso=" + isolabel,
"coreos.inst.install_dev=" + installDevice,
"coreos.inst.image_file=/run/media/iso/disk.img.xz",
"coreos.inst.insecure"},
},
Architectures: architectures,
Vendor: vendor,
}
}
func discinfoStageOptions(arch string) *osbuild.DiscinfoStageOptions {
return &osbuild.DiscinfoStageOptions{
BaseArch: arch,
@ -295,22 +342,35 @@ func discinfoStageOptions(arch string) *osbuild.DiscinfoStageOptions {
}
}
func xorrisofsStageOptions(filename string, arch string) *osbuild.XorrisofsStageOptions {
return &osbuild.XorrisofsStageOptions{
func xorrisofsStageOptions(filename, isolabel, arch string, isolinux bool) *osbuild.XorrisofsStageOptions {
options := &osbuild.XorrisofsStageOptions{
Filename: filename,
VolID: fmt.Sprintf("RHEL-9-0-0-BaseOS-%s", arch),
VolID: fmt.Sprintf(isolabel, 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 {
func grub2StageOptions(rootPartition *disk.Partition,
bootPartition *disk.Partition,
kernelOptions string,
kernel *blueprint.KernelCustomization,
kernelVer string,
uefi bool,
legacy string,
vendor string,
install bool) *osbuild.GRUB2StageOptions {
if rootPartition == nil {
panic("root partition must be defined for grub2 stage, this is a programming error")
}
@ -328,7 +388,8 @@ func grub2StageOptions(rootPartition *disk.Partition, bootPartition *disk.Partit
if uefi {
stageOptions.UEFI = &osbuild.GRUB2UEFI{
Vendor: "redhat",
Vendor: vendor,
Install: install,
Unified: legacy == "", // force unified grub scheme for pure efi systems
}
}
@ -446,6 +507,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,
@ -456,7 +522,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{
@ -512,3 +578,48 @@ func kernelCmdlineStageOptions(rootUUID string, kernelOptions string) *osbuild.K
KernelOpts: kernelOptions,
}
}
func nginxConfigStageOptions(path, htmlRoot, listen string) *osbuild.NginxConfigStageOptions {
// configure nginx to work in an unprivileged container
cfg := &osbuild.NginxConfig{
Listen: listen,
Root: htmlRoot,
Daemon: common.BoolToPtr(false),
PID: "/tmp/nginx.pid",
}
return &osbuild.NginxConfigStageOptions{
Path: path,
Config: cfg,
}
}
func chmodStageOptions(path, mode string, recursive bool) *osbuild.ChmodStageOptions {
return &osbuild.ChmodStageOptions{
Items: map[string]osbuild.ChmodStagePathOptions{
path: {Mode: mode, Recursive: recursive},
},
}
}
func ostreeConfigStageOptions(repo string, readOnly bool) *osbuild.OSTreeConfigStageOptions {
return &osbuild.OSTreeConfigStageOptions{
Repo: repo,
Config: &osbuild.OSTreeConfig{
Sysroot: &osbuild.SysrootOptions{
ReadOnly: common.BoolToPtr(readOnly),
Bootloader: "none",
},
},
}
}
func efiMkdirStageOptions() *osbuild.MkdirStageOptions {
return &osbuild.MkdirStageOptions{
Paths: []osbuild.Path{
{
Path: "/boot/efi",
Mode: os.FileMode(0700),
},
},
}
}

View file

@ -30,6 +30,7 @@ var supportedDistros = []supportedDistro{
{rhel90beta.New, rhel90beta.NewHostDistro},
{rhel90beta.NewRHEL90, rhel90beta.NewHostDistro},
{rhel90.New, rhel90.NewHostDistro},
{rhel90.NewCentos, rhel90.NewCentosHostDistro},
}
type supportedDistro struct {