debian-forge-composer/internal/distro/rhel9/distro.go
Achilleas Koutsou 390ae15eaa distro: replace ostree.RequestParams with new OSTreeImageOptions
Instead of using the ostree.RequestParams in the OSTReeImageOptions,
define a new struct specific to ImageOptions for the ostree parameters.
This is almost identical to the new ostree.CommitSpec but the meaning of
the parameters changes based on image type and it would not be clear if
the CommitSpec was used in all cases.  For example, the parameters of
the new OSTreeImageOptions do not always refer to the same commit.  The
URL and Checksum may point to a parent commit to be pulled in to base
the new commit on, while the Ref refers to the new commit that will be
built (which may have a different ref from the parent).

The ostree.ResolveParams() function now returns two strings, the
resolved ref, which is replaced by the defaultRef if it's not specified
in the request, and the resolved parent checksum if a URL is specified.
The URL does not need to be returned since it's always the same as the
one specified in the request.
The function has been rewritten to make the logic more clear.
The docstring for the function has been rewritten to cover all use cases
and error conditions.
2022-10-11 10:00:22 +02:00

1601 lines
49 KiB
Go

package rhel9
import (
"encoding/json"
"errors"
"fmt"
"math/rand"
"sort"
"strings"
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/common"
"github.com/osbuild/osbuild-composer/internal/container"
"github.com/osbuild/osbuild-composer/internal/disk"
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/osbuild"
"github.com/osbuild/osbuild-composer/internal/oscap"
"github.com/osbuild/osbuild-composer/internal/ostree"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
)
const (
// package set names
// build package set name
buildPkgsKey = "build"
// main/common os image package set name
osPkgsKey = "packages"
// container package set name
containerPkgsKey = "container"
// installer package set name
installerPkgsKey = "installer"
// blueprint package set name
blueprintPkgsKey = "blueprint"
)
var (
// rhel9 & cs9 share the same list
// of allowed profiles so a single
// allow list can be used
oscapProfileAllowList = []oscap.Profile{
oscap.AnssiBp28Enhanced,
oscap.AnssiBp28High,
oscap.AnssiBp28Intermediary,
oscap.AnssiBp28Minimal,
oscap.Cis,
oscap.CisServerL1,
oscap.CisWorkstationL1,
oscap.CisWorkstationL2,
oscap.Cui,
oscap.E8,
oscap.Hippa,
oscap.IsmO,
oscap.Ospp,
oscap.PciDss,
oscap.Stig,
oscap.StigGui,
}
)
type distribution struct {
name string
product string
osVersion string
releaseVersion string
modulePlatformID string
vendor string
ostreeRefTmpl string
isolabelTmpl string
runner string
arches map[string]distro.Arch
defaultImageConfig *distro.ImageConfig
}
// RHEL-based OS image configuration defaults
var defaultDistroImageConfig = &distro.ImageConfig{
Timezone: common.StringToPtr("America/New_York"),
Locale: common.StringToPtr("C.UTF-8"),
Sysconfig: []*osbuild.SysconfigStageOptions{
{
Kernel: &osbuild.SysconfigKernelOptions{
UpdateDefault: true,
DefaultKernel: "kernel",
},
Network: &osbuild.SysconfigNetworkOptions{
Networking: true,
NoZeroConf: true,
},
},
},
}
// distribution objects without the arches > image types
var distroMap = map[string]distribution{
"rhel-90": {
name: "rhel-90",
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",
defaultImageConfig: defaultDistroImageConfig,
},
"rhel-91": {
name: "rhel-91",
product: "Red Hat Enterprise Linux",
osVersion: "9.1",
releaseVersion: "9",
modulePlatformID: "platform:el9",
vendor: "redhat",
ostreeRefTmpl: "rhel/9/%s/edge",
isolabelTmpl: "RHEL-9-1-0-BaseOS-%s",
runner: "org.osbuild.rhel91",
defaultImageConfig: defaultDistroImageConfig,
},
"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-BaseOS-%s",
runner: "org.osbuild.centos9",
defaultImageConfig: defaultDistroImageConfig,
},
}
func (d *distribution) Name() string {
return d.name
}
func (d *distribution) Releasever() string {
return d.releaseVersion
}
func (d *distribution) ModulePlatformID() string {
return d.modulePlatformID
}
func (d *distribution) OSTreeRef() string {
return d.ostreeRefTmpl
}
func (d *distribution) ListArches() []string {
archNames := make([]string, 0, len(d.arches))
for name := range d.arches {
archNames = append(archNames, name)
}
sort.Strings(archNames)
return archNames
}
func (d *distribution) GetArch(name string) (distro.Arch, error) {
arch, exists := d.arches[name]
if !exists {
return nil, errors.New("invalid architecture: " + name)
}
return arch, nil
}
func (d *distribution) addArches(arches ...architecture) {
if d.arches == nil {
d.arches = map[string]distro.Arch{}
}
// Do not make copies of architectures, as opposed to image types,
// because architecture definitions are not used by more than a single
// distro definition.
for idx := range arches {
d.arches[arches[idx].name] = &arches[idx]
}
}
func (d *distribution) isRHEL() bool {
return strings.HasPrefix(d.name, "rhel")
}
func (d *distribution) getDefaultImageConfig() *distro.ImageConfig {
return d.defaultImageConfig
}
type architecture struct {
distro *distribution
name string
imageTypes map[string]distro.ImageType
imageTypeAliases map[string]string
legacy string
bootType distro.BootType
}
func (a *architecture) Name() string {
return a.name
}
func (a *architecture) ListImageTypes() []string {
itNames := make([]string, 0, len(a.imageTypes))
for name := range a.imageTypes {
itNames = append(itNames, name)
}
sort.Strings(itNames)
return itNames
}
func (a *architecture) GetImageType(name string) (distro.ImageType, error) {
t, exists := a.imageTypes[name]
if !exists {
aliasForName, exists := a.imageTypeAliases[name]
if !exists {
return nil, errors.New("invalid image type: " + name)
}
t, exists = a.imageTypes[aliasForName]
if !exists {
panic(fmt.Sprintf("image type '%s' is an alias to a non-existing image type '%s'", name, aliasForName))
}
}
return t, nil
}
func (a *architecture) addImageTypes(imageTypes ...imageType) {
if a.imageTypes == nil {
a.imageTypes = map[string]distro.ImageType{}
}
for idx := range imageTypes {
it := imageTypes[idx]
it.arch = a
a.imageTypes[it.name] = &it
for _, alias := range it.nameAliases {
if a.imageTypeAliases == nil {
a.imageTypeAliases = map[string]string{}
}
if existingAliasFor, exists := a.imageTypeAliases[alias]; exists {
panic(fmt.Sprintf("image type alias '%s' for '%s' is already defined for another image type '%s'", alias, it.name, existingAliasFor))
}
a.imageTypeAliases[alias] = it.name
}
}
}
func (a *architecture) Distro() distro.Distro {
return a.distro
}
type pipelinesFunc func(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec, containers []container.Spec, 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]packageSetFunc
packageSetChains map[string][]string
defaultImageConfig *distro.ImageConfig
kernelOptions string
defaultSize uint64
buildPipelines []string
payloadPipelines []string
exports []string
pipelines pipelinesFunc
// bootISO: installable ISO
bootISO bool
// rpmOstree: edge/ostree
rpmOstree bool
// bootable image
bootable bool
// If set to a value, it is preferred over the architecture value
bootType distro.BootType
// List of valid arches for the image type
basePartitionTables distro.BasePartitionTableMap
}
func (t *imageType) Name() string {
return t.name
}
func (t *imageType) Arch() distro.Arch {
return t.arch
}
func (t *imageType) Filename() string {
return t.filename
}
func (t *imageType) MIMEType() string {
return t.mimeType
}
func (t *imageType) OSTreeRef() string {
d := t.arch.distro
if t.rpmOstree {
return fmt.Sprintf(d.ostreeRefTmpl, t.Arch().Name())
}
return ""
}
func (t *imageType) Size(size uint64) uint64 {
// Microsoft Azure requires vhd images to be rounded up to the nearest MB
if t.name == "vhd" && size%common.MebiByte != 0 {
size = (size/common.MebiByte + 1) * common.MebiByte
}
if size == 0 {
size = t.defaultSize
}
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, options distro.ImageOptions, repos []rpmmd.RepoConfig) 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
for name := range imageSets {
mergedSets[name] = t.getPackages(name)
}
if _, hasPackages := imageSets[osPkgsKey]; !hasPackages {
// should this be possible??
mergedSets[osPkgsKey] = rpmmd.PackageSet{}
}
// every image type must define a 'build' package set
if _, hasBuild := imageSets[buildPkgsKey]; !hasBuild {
panic(fmt.Sprintf("'%s' image type has no '%s' package set defined", t.name, buildPkgsKey))
}
// blueprint packages
bpPackages := bp.GetPackages()
timezone, _ := bp.Customizations.GetTimezoneSettings()
if timezone != nil {
bpPackages = append(bpPackages, "chrony")
}
// if we have file system customization that will need to a new mount point
// the layout is converted to LVM so we need to corresponding packages
if !t.rpmOstree {
archName := t.arch.Name()
pt := t.basePartitionTables[archName]
haveNewMountpoint := false
if fs := bp.Customizations.GetFilesystems(); fs != nil {
for i := 0; !haveNewMountpoint && i < len(fs); i++ {
haveNewMountpoint = !pt.ContainsMountpoint(fs[i].Mountpoint)
}
}
if haveNewMountpoint {
bpPackages = append(bpPackages, "lvm2")
}
}
// if we are embedding containers we need to have `skopeo` in the build root
if len(bp.Containers) > 0 {
extraPkgs := rpmmd.PackageSet{Include: []string{"skopeo"}}
if t.rpmOstree {
// for OSTree based images we need to configure the containers-storage.conf(5)
// via the org.osbuild.containers.storage.conf stage, which needs python3-toml
extraPkgs = extraPkgs.Append(rpmmd.PackageSet{Include: []string{"python3-toml"}})
}
mergedSets[buildPkgsKey] = mergedSets[buildPkgsKey].Append(extraPkgs)
}
// if oscap customizations are enabled we need to add
// `openscap-scanner` & `scap-security-guide` packages
// to build root
if bp.Customizations.GetOpenSCAP() != nil {
bpPackages = append(bpPackages, "openscap-scanner", "scap-security-guide")
}
// depsolve bp packages separately
// bp packages aren't restricted by exclude lists
mergedSets[blueprintPkgsKey] = rpmmd.PackageSet{Include: bpPackages}
kernel := bp.Customizations.GetKernel().Name
// add bp kernel to main OS package set to avoid duplicate kernels
mergedSets[osPkgsKey] = mergedSets[osPkgsKey].Append(rpmmd.PackageSet{Include: []string{kernel}})
return distro.MakePackageSetChains(t, mergedSets, repos)
}
func (t *imageType) BuildPipelines() []string {
return t.buildPipelines
}
func (t *imageType) PayloadPipelines() []string {
return t.payloadPipelines
}
func (t *imageType) PayloadPackageSets() []string {
return []string{blueprintPkgsKey}
}
func (t *imageType) PackageSetsChains() map[string][]string {
return t.packageSetChains
}
func (t *imageType) Exports() []string {
if len(t.exports) > 0 {
return t.exports
}
return []string{"assembler"}
}
// getBootType returns the BootType which should be used for this particular
// combination of architecture and image type.
func (t *imageType) getBootType() distro.BootType {
bootType := t.arch.bootType
if t.bootType != distro.UnsetBootType {
bootType = t.bootType
}
return bootType
}
func (t *imageType) supportsUEFI() bool {
bootType := t.getBootType()
if bootType == distro.HybridBootType || bootType == distro.UEFIBootType {
return true
}
return false
}
func (t *imageType) getPartitionTable(
mountpoints []blueprint.FilesystemCustomization,
options distro.ImageOptions,
rng *rand.Rand,
) (*disk.PartitionTable, error) {
archName := t.arch.Name()
basePartitionTable, exists := t.basePartitionTables[archName]
if !exists {
return nil, fmt.Errorf("unknown arch: " + archName)
}
imageSize := t.Size(options.Size)
lvmify := !t.rpmOstree
return disk.NewPartitionTable(&basePartitionTable, mountpoints, imageSize, lvmify, rng)
}
func (t *imageType) getDefaultImageConfig() *distro.ImageConfig {
// ensure that image always returns non-nil default config
imageConfig := t.defaultImageConfig
if imageConfig == nil {
imageConfig = &distro.ImageConfig{}
}
return imageConfig.InheritFrom(t.arch.distro.getDefaultImageConfig())
}
func (t *imageType) PartitionType() string {
archName := t.arch.Name()
basePartitionTable, exists := t.basePartitionTables[archName]
if !exists {
return ""
}
return basePartitionTable.Type
}
func (t *imageType) Manifest(customizations *blueprint.Customizations,
options distro.ImageOptions,
repos []rpmmd.RepoConfig,
packageSpecSets map[string][]rpmmd.PackageSpec,
containers []container.Spec,
seed int64) (distro.Manifest, error) {
if err := t.checkOptions(customizations, options, containers); err != nil {
return distro.Manifest{}, err
}
source := rand.NewSource(seed)
// math/rand is good enough in this case
/* #nosec G404 */
rng := rand.New(source)
pipelines, err := t.pipelines(t, customizations, options, repos, packageSpecSets, containers, rng)
if err != nil {
return distro.Manifest{}, err
}
// flatten spec sets for sources
allPackageSpecs := make([]rpmmd.PackageSpec, 0)
for _, specs := range packageSpecSets {
allPackageSpecs = append(allPackageSpecs, specs...)
}
// handle OSTree commit inputs
var commits []ostree.CommitSpec
if options.OSTree.FetchChecksum != "" && options.OSTree.URL != "" {
commits = []ostree.CommitSpec{{Checksum: options.OSTree.FetchChecksum, URL: options.OSTree.URL}}
}
// handle inline sources
inlineData := []string{}
// FDO root certs, if any, are transmitted via an inline source
if fdo := customizations.GetFDO(); fdo != nil && fdo.DiunPubKeyRootCerts != "" {
inlineData = append(inlineData, fdo.DiunPubKeyRootCerts)
}
return json.Marshal(
osbuild.Manifest{
Version: "2",
Pipelines: pipelines,
Sources: osbuild.GenSources(allPackageSpecs, commits, inlineData, containers),
},
)
}
// checkOptions checks the validity and compatibility of options and customizations for the image type.
func (t *imageType) checkOptions(customizations *blueprint.Customizations, options distro.ImageOptions, containers []container.Spec) error {
// we do not support embedding containers on ostree-derived images, only on commits themselves
if len(containers) > 0 && t.rpmOstree && (t.name != "edge-commit" && t.name != "edge-container") {
return fmt.Errorf("embedding containers is not supported for %s on %s", t.name, t.arch.distro.name)
}
if t.bootISO && t.rpmOstree {
// check the checksum instead of the URL, because the URL should have been used to resolve the checksum and we need both
if options.OSTree.FetchChecksum == "" {
return fmt.Errorf("boot ISO image type %q requires specifying a URL from which to retrieve the OSTree commit", t.name)
}
if t.name == "edge-simplified-installer" {
allowed := []string{"InstallationDevice", "FDO"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return fmt.Errorf("unsupported blueprint customizations found for boot ISO image type %q: (allowed: %s)", t.name, strings.Join(allowed, ", "))
}
if customizations.GetInstallationDevice() == "" {
return fmt.Errorf("boot ISO image type %q requires specifying an installation device to install to", t.name)
}
if customizations.GetFDO() == nil {
return fmt.Errorf("boot ISO image type %q requires specifying FDO configuration to install to", t.name)
}
if customizations.GetFDO().ManufacturingServerURL == "" {
return fmt.Errorf("boot ISO image type %q requires specifying FDO.ManufacturingServerURL configuration to install to", t.name)
}
var diunSet int
if customizations.GetFDO().DiunPubKeyHash != "" {
diunSet++
}
if customizations.GetFDO().DiunPubKeyInsecure != "" {
diunSet++
}
if customizations.GetFDO().DiunPubKeyRootCerts != "" {
diunSet++
}
if diunSet != 1 {
return fmt.Errorf("boot ISO image type %q requires specifying one of [FDO.DiunPubKeyHash,FDO.DiunPubKeyInsecure,FDO.DiunPubKeyRootCerts] configuration to install to", t.name)
}
} else if t.name == "edge-installer" {
allowed := []string{"User", "Group"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return fmt.Errorf("unsupported blueprint customizations found for boot ISO image type %q: (allowed: %s)", t.name, strings.Join(allowed, ", "))
}
}
}
// check the checksum instead of the URL, because the URL should have been used to resolve the checksum and we need both
if t.name == "edge-raw-image" && options.OSTree.FetchChecksum == "" {
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")
}
mountpoints := customizations.GetFilesystems()
if mountpoints != nil && t.rpmOstree {
return fmt.Errorf("Custom mountpoints are not supported for ostree types")
}
err := disk.CheckMountpoints(mountpoints, disk.MountpointPolicies)
if err != nil {
return err
}
if osc := customizations.GetOpenSCAP(); osc != nil {
if t.arch.distro.osVersion == "9.0" {
return fmt.Errorf(fmt.Sprintf("OpenSCAP unsupported os version: %s", t.arch.distro.osVersion))
}
if !oscap.IsProfileAllowed(osc.ProfileID, oscapProfileAllowList) {
return fmt.Errorf(fmt.Sprintf("OpenSCAP unsupported profile: %s", osc.ProfileID))
}
if t.rpmOstree {
return fmt.Errorf("OpenSCAP customizations are not supported for ostree types")
}
if osc.DataStream == "" {
return fmt.Errorf("OpenSCAP datastream cannot be empty")
}
if osc.ProfileID == "" {
return fmt.Errorf("OpenSCAP profile cannot be empty")
}
}
return nil
}
// New creates a new distro object, defining the supported architectures and image types
func New() distro.Distro {
return newDistro("rhel-90")
}
func NewHostDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
return newDistro("rhel-90")
}
func NewRHEL91() distro.Distro {
return newDistro("rhel-91")
}
func NewRHEL91HostDistro(name, modulePlatformID, ostreeRef string) distro.Distro {
return newDistro("rhel-91")
}
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 {
rd := distroMap[distroName]
// Architecture definitions
x86_64 := architecture{
name: distro.X86_64ArchName,
distro: &rd,
legacy: "i386-pc",
bootType: distro.HybridBootType,
}
aarch64 := architecture{
name: distro.Aarch64ArchName,
distro: &rd,
bootType: distro.UEFIBootType,
}
ppc64le := architecture{
distro: &rd,
name: distro.Ppc64leArchName,
legacy: "powerpc-ieee1275",
bootType: distro.LegacyBootType,
}
s390x := architecture{
distro: &rd,
name: distro.S390xArchName,
bootType: distro.LegacyBootType,
}
// Shared Services
edgeServices := []string{
// TODO(runcom): move fdo-client-linuxapp.service to presets?
"NetworkManager.service", "firewalld.service", "sshd.service", "fdo-client-linuxapp.service",
}
// Image Definitions
edgeCommitImgType := imageType{
name: "edge-commit",
nameAliases: []string{"rhel-edge-commit"},
filename: "commit.tar",
mimeType: "application/x-tar",
packageSets: map[string]packageSetFunc{
buildPkgsKey: edgeBuildPackageSet,
osPkgsKey: edgeCommitPackageSet,
},
packageSetChains: map[string][]string{
osPkgsKey: {osPkgsKey, blueprintPkgsKey},
},
defaultImageConfig: &distro.ImageConfig{
EnabledServices: edgeServices,
},
rpmOstree: true,
pipelines: edgeCommitPipelines,
buildPipelines: []string{"build"},
payloadPipelines: []string{"ostree-tree", "ostree-commit", "commit-archive"},
exports: []string{"commit-archive"},
}
edgeOCIImgType := imageType{
name: "edge-container",
nameAliases: []string{"rhel-edge-container"},
filename: "container.tar",
mimeType: "application/x-tar",
packageSets: map[string]packageSetFunc{
buildPkgsKey: edgeBuildPackageSet,
osPkgsKey: edgeCommitPackageSet,
containerPkgsKey: func(t *imageType) rpmmd.PackageSet {
return rpmmd.PackageSet{
Include: []string{"nginx"},
}
},
},
packageSetChains: map[string][]string{
osPkgsKey: {osPkgsKey, blueprintPkgsKey},
},
defaultImageConfig: &distro.ImageConfig{
EnabledServices: edgeServices,
},
rpmOstree: true,
bootISO: false,
pipelines: edgeContainerPipelines,
buildPipelines: []string{"build"},
payloadPipelines: []string{"ostree-tree", "ostree-commit", "container-tree", "container"},
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,
},
defaultImageConfig: &distro.ImageConfig{
Locale: common.StringToPtr("en_US.UTF-8"),
},
defaultSize: 10 * common.GibiByte,
rpmOstree: true,
bootable: true,
bootISO: false,
pipelines: edgeRawImagePipelines,
buildPipelines: []string{"build"},
payloadPipelines: []string{"image-tree", "image", "archive"},
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]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,
osPkgsKey: edgeCommitPackageSet,
installerPkgsKey: edgeInstallerPackageSet,
},
packageSetChains: map[string][]string{
osPkgsKey: {osPkgsKey, blueprintPkgsKey},
},
defaultImageConfig: &distro.ImageConfig{
Locale: common.StringToPtr("en_US.UTF-8"),
EnabledServices: edgeServices,
},
rpmOstree: true,
bootISO: true,
pipelines: edgeInstallerPipelines,
buildPipelines: []string{"build"},
payloadPipelines: []string{"anaconda-tree", "bootiso-tree", "bootiso"},
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: edgeSimplifiedInstallerBuildPackageSet,
installerPkgsKey: edgeSimplifiedInstallerPackageSet,
},
defaultImageConfig: &distro.ImageConfig{
EnabledServices: edgeServices,
},
defaultSize: 10 * common.GibiByte,
rpmOstree: true,
bootable: true,
bootISO: true,
pipelines: edgeSimplifiedInstallerPipelines,
buildPipelines: []string{"build"},
payloadPipelines: []string{"image-tree", "image", "archive", "coi-tree", "efiboot-tree", "bootiso-tree", "bootiso"},
exports: []string{"bootiso"},
basePartitionTables: edgeBasePartitionTables,
}
qcow2ImgType := imageType{
name: "qcow2",
filename: "disk.qcow2",
mimeType: "application/x-qemu-disk",
kernelOptions: "console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0",
packageSets: map[string]packageSetFunc{
buildPkgsKey: distroBuildPackageSet,
osPkgsKey: qcow2CommonPackageSet,
},
packageSetChains: map[string][]string{
osPkgsKey: {osPkgsKey, blueprintPkgsKey},
},
defaultImageConfig: &distro.ImageConfig{
DefaultTarget: common.StringToPtr("multi-user.target"),
RHSMConfig: map[distro.RHSMSubscriptionStatus]*osbuild.RHSMStageOptions{
distro.RHSMConfigNoSubscription: {
DnfPlugins: &osbuild.RHSMStageOptionsDnfPlugins{
ProductID: &osbuild.RHSMStageOptionsDnfPlugin{
Enabled: false,
},
SubscriptionManager: &osbuild.RHSMStageOptionsDnfPlugin{
Enabled: false,
},
},
},
},
},
bootable: true,
defaultSize: 10 * common.GibiByte,
pipelines: qcow2Pipelines,
buildPipelines: []string{"build"},
payloadPipelines: []string{"os", "image", "qcow2"},
exports: []string{"qcow2"},
basePartitionTables: defaultBasePartitionTables,
}
vmdkImgType := imageType{
name: "vmdk",
filename: "disk.vmdk",
mimeType: "application/x-vmdk",
packageSets: map[string]packageSetFunc{
buildPkgsKey: distroBuildPackageSet,
osPkgsKey: vmdkCommonPackageSet,
},
packageSetChains: map[string][]string{
osPkgsKey: {osPkgsKey, blueprintPkgsKey},
},
defaultImageConfig: &distro.ImageConfig{
Locale: common.StringToPtr("en_US.UTF-8"),
},
kernelOptions: "ro net.ifnames=0",
bootable: true,
defaultSize: 4 * common.GibiByte,
pipelines: vmdkPipelines,
buildPipelines: []string{"build"},
payloadPipelines: []string{"os", "image", "vmdk"},
exports: []string{"vmdk"},
basePartitionTables: defaultBasePartitionTables,
}
openstackImgType := imageType{
name: "openstack",
filename: "disk.qcow2",
mimeType: "application/x-qemu-disk",
packageSets: map[string]packageSetFunc{
buildPkgsKey: distroBuildPackageSet,
osPkgsKey: openstackCommonPackageSet,
},
packageSetChains: map[string][]string{
osPkgsKey: {osPkgsKey, blueprintPkgsKey},
},
defaultImageConfig: &distro.ImageConfig{
Locale: common.StringToPtr("en_US.UTF-8"),
},
kernelOptions: "ro net.ifnames=0",
bootable: true,
defaultSize: 4 * common.GibiByte,
pipelines: openstackPipelines,
buildPipelines: []string{"build"},
payloadPipelines: []string{"os", "image", "qcow2"},
exports: []string{"qcow2"},
basePartitionTables: defaultBasePartitionTables,
}
// default EC2 images config (common for all architectures)
defaultEc2ImageConfig := &distro.ImageConfig{
Locale: common.StringToPtr("en_US.UTF-8"),
Timezone: common.StringToPtr("UTC"),
TimeSynchronization: &osbuild.ChronyStageOptions{
Servers: []osbuild.ChronyConfigServer{
{
Hostname: "169.254.169.123",
Prefer: common.BoolToPtr(true),
Iburst: common.BoolToPtr(true),
Minpoll: common.IntToPtr(4),
Maxpoll: common.IntToPtr(4),
},
},
// empty string will remove any occurrences of the option from the configuration
LeapsecTz: common.StringToPtr(""),
},
Keyboard: &osbuild.KeymapStageOptions{
Keymap: "us",
X11Keymap: &osbuild.X11KeymapOptions{
Layouts: []string{"us"},
},
},
EnabledServices: []string{
"sshd",
"NetworkManager",
"nm-cloud-setup.service",
"nm-cloud-setup.timer",
"cloud-init",
"cloud-init-local",
"cloud-config",
"cloud-final",
"reboot.target",
"tuned",
},
DefaultTarget: common.StringToPtr("multi-user.target"),
Sysconfig: []*osbuild.SysconfigStageOptions{
{
Kernel: &osbuild.SysconfigKernelOptions{
UpdateDefault: true,
DefaultKernel: "kernel",
},
Network: &osbuild.SysconfigNetworkOptions{
Networking: true,
NoZeroConf: true,
},
NetworkScripts: &osbuild.NetworkScriptsOptions{
IfcfgFiles: map[string]osbuild.IfcfgFile{
"eth0": {
Device: "eth0",
Bootproto: osbuild.IfcfgBootprotoDHCP,
OnBoot: common.BoolToPtr(true),
Type: osbuild.IfcfgTypeEthernet,
UserCtl: common.BoolToPtr(true),
PeerDNS: common.BoolToPtr(true),
IPv6Init: common.BoolToPtr(false),
},
},
},
},
},
RHSMConfig: map[distro.RHSMSubscriptionStatus]*osbuild.RHSMStageOptions{
distro.RHSMConfigNoSubscription: {
// RHBZ#1932802
SubMan: &osbuild.RHSMStageOptionsSubMan{
Rhsmcertd: &osbuild.SubManConfigRHSMCERTDSection{
AutoRegistration: common.BoolToPtr(true),
},
Rhsm: &osbuild.SubManConfigRHSMSection{
ManageRepos: common.BoolToPtr(false),
},
},
},
distro.RHSMConfigWithSubscription: {
// RHBZ#1932802
SubMan: &osbuild.RHSMStageOptionsSubMan{
Rhsmcertd: &osbuild.SubManConfigRHSMCERTDSection{
AutoRegistration: common.BoolToPtr(true),
},
// do not disable the redhat.repo management if the user
// explicitly request the system to be subscribed
},
},
},
SystemdLogind: []*osbuild.SystemdLogindStageOptions{
{
Filename: "00-getty-fixes.conf",
Config: osbuild.SystemdLogindConfigDropin{
Login: osbuild.SystemdLogindConfigLoginSection{
NAutoVTs: common.IntToPtr(0),
},
},
},
},
CloudInit: []*osbuild.CloudInitStageOptions{
{
Filename: "00-rhel-default-user.cfg",
Config: osbuild.CloudInitConfigFile{
SystemInfo: &osbuild.CloudInitConfigSystemInfo{
DefaultUser: &osbuild.CloudInitConfigDefaultUser{
Name: "ec2-user",
},
},
},
},
},
Modprobe: []*osbuild.ModprobeStageOptions{
{
Filename: "blacklist-nouveau.conf",
Commands: osbuild.ModprobeConfigCmdList{
osbuild.NewModprobeConfigCmdBlacklist("nouveau"),
},
},
},
DracutConf: []*osbuild.DracutConfStageOptions{
{
Filename: "sgdisk.conf",
Config: osbuild.DracutConfigFile{
Install: []string{"sgdisk"},
},
},
},
SystemdUnit: []*osbuild.SystemdUnitStageOptions{
// RHBZ#1822863
{
Unit: "nm-cloud-setup.service",
Dropin: "10-rh-enable-for-ec2.conf",
Config: osbuild.SystemdServiceUnitDropin{
Service: &osbuild.SystemdUnitServiceSection{
Environment: "NM_CLOUD_SETUP_EC2=yes",
},
},
},
},
Authselect: &osbuild.AuthselectStageOptions{
Profile: "sssd",
},
SshdConfig: &osbuild.SshdConfigStageOptions{
Config: osbuild.SshdConfigConfig{
PasswordAuthentication: common.BoolToPtr(false),
},
},
}
// default EC2 images config (x86_64)
defaultEc2ImageConfigX86_64 := &distro.ImageConfig{
DracutConf: append(defaultEc2ImageConfig.DracutConf,
&osbuild.DracutConfStageOptions{
Filename: "ec2.conf",
Config: osbuild.DracutConfigFile{
AddDrivers: []string{
"nvme",
"xen-blkfront",
},
},
}),
}
defaultEc2ImageConfigX86_64 = defaultEc2ImageConfigX86_64.InheritFrom(defaultEc2ImageConfig)
// default AMI (EC2 BYOS) images config
defaultAMIImageConfig := &distro.ImageConfig{
RHSMConfig: map[distro.RHSMSubscriptionStatus]*osbuild.RHSMStageOptions{
distro.RHSMConfigNoSubscription: {
// RHBZ#1932802
SubMan: &osbuild.RHSMStageOptionsSubMan{
Rhsmcertd: &osbuild.SubManConfigRHSMCERTDSection{
AutoRegistration: common.BoolToPtr(true),
},
// Don't disable RHSM redhat.repo management on the AMI
// image, which is BYOS and does not use 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.
},
},
distro.RHSMConfigWithSubscription: {
// RHBZ#1932802
SubMan: &osbuild.RHSMStageOptionsSubMan{
Rhsmcertd: &osbuild.SubManConfigRHSMCERTDSection{
AutoRegistration: common.BoolToPtr(true),
},
// do not disable the redhat.repo management if the user
// explicitly request the system to be subscribed
},
},
},
}
defaultAMIImageConfigX86_64 := defaultAMIImageConfig.InheritFrom(defaultEc2ImageConfigX86_64)
defaultAMIImageConfig = defaultAMIImageConfig.InheritFrom(defaultEc2ImageConfig)
amiImgTypeX86_64 := imageType{
name: "ami",
filename: "image.raw",
mimeType: "application/octet-stream",
packageSets: map[string]packageSetFunc{
buildPkgsKey: ec2BuildPackageSet,
osPkgsKey: ec2CommonPackageSet,
},
packageSetChains: map[string][]string{
osPkgsKey: {osPkgsKey, blueprintPkgsKey},
},
defaultImageConfig: defaultAMIImageConfigX86_64,
kernelOptions: "console=ttyS0,115200n8 console=tty0 net.ifnames=0 rd.blacklist=nouveau nvme_core.io_timeout=4294967295",
bootable: true,
bootType: distro.LegacyBootType,
defaultSize: 10 * common.GibiByte,
pipelines: ec2Pipelines,
buildPipelines: []string{"build"},
payloadPipelines: []string{"os", "image"},
exports: []string{"image"},
basePartitionTables: defaultBasePartitionTables,
}
amiImgTypeAarch64 := imageType{
name: "ami",
filename: "image.raw",
mimeType: "application/octet-stream",
packageSets: map[string]packageSetFunc{
buildPkgsKey: ec2BuildPackageSet,
osPkgsKey: ec2CommonPackageSet,
},
packageSetChains: map[string][]string{
osPkgsKey: {osPkgsKey, blueprintPkgsKey},
},
defaultImageConfig: defaultAMIImageConfig,
kernelOptions: "console=ttyS0,115200n8 console=tty0 net.ifnames=0 rd.blacklist=nouveau nvme_core.io_timeout=4294967295 iommu.strict=0",
bootable: true,
defaultSize: 10 * common.GibiByte,
pipelines: ec2Pipelines,
buildPipelines: []string{"build"},
payloadPipelines: []string{"os", "image"},
exports: []string{"image"},
basePartitionTables: defaultBasePartitionTables,
}
ec2ImgTypeX86_64 := imageType{
name: "ec2",
filename: "image.raw.xz",
mimeType: "application/xz",
packageSets: map[string]packageSetFunc{
buildPkgsKey: ec2BuildPackageSet,
osPkgsKey: rhelEc2PackageSet,
},
packageSetChains: map[string][]string{
osPkgsKey: {osPkgsKey, blueprintPkgsKey},
},
defaultImageConfig: defaultEc2ImageConfigX86_64,
kernelOptions: "console=ttyS0,115200n8 console=tty0 net.ifnames=0 rd.blacklist=nouveau nvme_core.io_timeout=4294967295",
bootable: true,
bootType: distro.LegacyBootType,
defaultSize: 10 * common.GibiByte,
pipelines: rhelEc2Pipelines,
buildPipelines: []string{"build"},
payloadPipelines: []string{"os", "image", "archive"},
exports: []string{"archive"},
basePartitionTables: defaultBasePartitionTables,
}
ec2ImgTypeAarch64 := imageType{
name: "ec2",
filename: "image.raw.xz",
mimeType: "application/xz",
packageSets: map[string]packageSetFunc{
buildPkgsKey: ec2BuildPackageSet,
osPkgsKey: rhelEc2PackageSet,
},
packageSetChains: map[string][]string{
osPkgsKey: {osPkgsKey, blueprintPkgsKey},
},
defaultImageConfig: defaultEc2ImageConfig,
kernelOptions: "console=ttyS0,115200n8 console=tty0 net.ifnames=0 rd.blacklist=nouveau nvme_core.io_timeout=4294967295 iommu.strict=0",
bootable: true,
defaultSize: 10 * common.GibiByte,
pipelines: rhelEc2Pipelines,
buildPipelines: []string{"build"},
payloadPipelines: []string{"os", "image", "archive"},
exports: []string{"archive"},
basePartitionTables: defaultBasePartitionTables,
}
ec2HaImgTypeX86_64 := imageType{
name: "ec2-ha",
filename: "image.raw.xz",
mimeType: "application/xz",
packageSets: map[string]packageSetFunc{
buildPkgsKey: ec2BuildPackageSet,
osPkgsKey: rhelEc2HaPackageSet,
},
packageSetChains: map[string][]string{
osPkgsKey: {osPkgsKey, blueprintPkgsKey},
},
defaultImageConfig: defaultEc2ImageConfigX86_64,
kernelOptions: "console=ttyS0,115200n8 console=tty0 net.ifnames=0 rd.blacklist=nouveau nvme_core.io_timeout=4294967295",
bootable: true,
bootType: distro.LegacyBootType,
defaultSize: 10 * common.GibiByte,
pipelines: rhelEc2Pipelines,
buildPipelines: []string{"build"},
payloadPipelines: []string{"os", "image", "archive"},
exports: []string{"archive"},
basePartitionTables: defaultBasePartitionTables,
}
// default EC2-SAP image config (x86_64)
defaultEc2SapImageConfigX86_64 := &distro.ImageConfig{
SELinuxConfig: &osbuild.SELinuxConfigStageOptions{
State: osbuild.SELinuxStatePermissive,
},
// RHBZ#1960617
Tuned: osbuild.NewTunedStageOptions("sap-hana"),
// RHBZ#1959979
Tmpfilesd: []*osbuild.TmpfilesdStageOptions{
osbuild.NewTmpfilesdStageOptions("sap.conf",
[]osbuild.TmpfilesdConfigLine{
{
Type: "x",
Path: "/tmp/.sap*",
},
{
Type: "x",
Path: "/tmp/.hdb*lock",
},
{
Type: "x",
Path: "/tmp/.trex*lock",
},
},
),
},
// RHBZ#1959963
PamLimitsConf: []*osbuild.PamLimitsConfStageOptions{
osbuild.NewPamLimitsConfStageOptions("99-sap.conf",
[]osbuild.PamLimitsConfigLine{
{
Domain: "@sapsys",
Type: osbuild.PamLimitsTypeHard,
Item: osbuild.PamLimitsItemNofile,
Value: osbuild.PamLimitsValueInt(1048576),
},
{
Domain: "@sapsys",
Type: osbuild.PamLimitsTypeSoft,
Item: osbuild.PamLimitsItemNofile,
Value: osbuild.PamLimitsValueInt(1048576),
},
{
Domain: "@dba",
Type: osbuild.PamLimitsTypeHard,
Item: osbuild.PamLimitsItemNofile,
Value: osbuild.PamLimitsValueInt(1048576),
},
{
Domain: "@dba",
Type: osbuild.PamLimitsTypeSoft,
Item: osbuild.PamLimitsItemNofile,
Value: osbuild.PamLimitsValueInt(1048576),
},
{
Domain: "@sapsys",
Type: osbuild.PamLimitsTypeHard,
Item: osbuild.PamLimitsItemNproc,
Value: osbuild.PamLimitsValueUnlimited,
},
{
Domain: "@sapsys",
Type: osbuild.PamLimitsTypeSoft,
Item: osbuild.PamLimitsItemNproc,
Value: osbuild.PamLimitsValueUnlimited,
},
{
Domain: "@dba",
Type: osbuild.PamLimitsTypeHard,
Item: osbuild.PamLimitsItemNproc,
Value: osbuild.PamLimitsValueUnlimited,
},
{
Domain: "@dba",
Type: osbuild.PamLimitsTypeSoft,
Item: osbuild.PamLimitsItemNproc,
Value: osbuild.PamLimitsValueUnlimited,
},
},
),
},
// RHBZ#1959962
Sysctld: []*osbuild.SysctldStageOptions{
osbuild.NewSysctldStageOptions("sap.conf",
[]osbuild.SysctldConfigLine{
{
Key: "kernel.pid_max",
Value: "4194304",
},
{
Key: "vm.max_map_count",
Value: "2147483647",
},
},
),
},
// E4S/EUS
DNFConfig: []*osbuild.DNFConfigStageOptions{
osbuild.NewDNFConfigStageOptions(
[]osbuild.DNFVariable{
{
Name: "releasever",
Value: rd.osVersion,
},
},
nil,
),
},
}
defaultEc2SapImageConfigX86_64 = defaultEc2SapImageConfigX86_64.InheritFrom(defaultEc2ImageConfigX86_64)
ec2SapImgTypeX86_64 := imageType{
name: "ec2-sap",
filename: "image.raw.xz",
mimeType: "application/xz",
packageSets: map[string]packageSetFunc{
buildPkgsKey: ec2BuildPackageSet,
osPkgsKey: rhelEc2SapPackageSet,
},
packageSetChains: map[string][]string{
osPkgsKey: {osPkgsKey, blueprintPkgsKey},
},
defaultImageConfig: defaultEc2SapImageConfigX86_64,
kernelOptions: "console=ttyS0,115200n8 console=tty0 net.ifnames=0 rd.blacklist=nouveau nvme_core.io_timeout=4294967295 processor.max_cstate=1 intel_idle.max_cstate=1",
bootable: true,
bootType: distro.LegacyBootType,
defaultSize: 10 * common.GibiByte,
pipelines: rhelEc2Pipelines,
buildPipelines: []string{"build"},
payloadPipelines: []string{"os", "image", "archive"},
exports: []string{"archive"},
basePartitionTables: defaultBasePartitionTables,
}
defaultGceImageConfig := &distro.ImageConfig{
Timezone: common.StringToPtr("UTC"),
TimeSynchronization: &osbuild.ChronyStageOptions{
Timeservers: []string{"metadata.google.internal"},
},
Firewall: &osbuild.FirewallStageOptions{
DefaultZone: "trusted",
},
EnabledServices: []string{
"sshd",
"rngd",
"dnf-automatic.timer",
},
DisabledServices: []string{
"sshd-keygen@",
"reboot.target",
},
DefaultTarget: common.StringToPtr("multi-user.target"),
Locale: common.StringToPtr("en_US.UTF-8"),
Keyboard: &osbuild.KeymapStageOptions{
Keymap: "us",
},
DNFConfig: []*osbuild.DNFConfigStageOptions{
{
Config: &osbuild.DNFConfig{
Main: &osbuild.DNFConfigMain{
IPResolve: "4",
},
},
},
},
DNFAutomaticConfig: &osbuild.DNFAutomaticConfigStageOptions{
Config: &osbuild.DNFAutomaticConfig{
Commands: &osbuild.DNFAutomaticConfigCommands{
ApplyUpdates: common.BoolToPtr(true),
UpgradeType: osbuild.DNFAutomaticUpgradeTypeSecurity,
},
},
},
YUMRepos: []*osbuild.YumReposStageOptions{
{
Filename: "google-cloud.repo",
Repos: []osbuild.YumRepository{
{
Id: "google-compute-engine",
Name: "Google Compute Engine",
BaseURL: []string{"https://packages.cloud.google.com/yum/repos/google-compute-engine-el9-x86_64-stable"},
Enabled: common.BoolToPtr(true),
// TODO: enable GPG check once Google stops using SHA-1 in their keys
// https://issuetracker.google.com/issues/223626963
GPGCheck: common.BoolToPtr(false),
RepoGPGCheck: common.BoolToPtr(false),
GPGKey: []string{
"https://packages.cloud.google.com/yum/doc/yum-key.gpg",
"https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg",
},
},
},
},
},
RHSMConfig: map[distro.RHSMSubscriptionStatus]*osbuild.RHSMStageOptions{
distro.RHSMConfigNoSubscription: {
SubMan: &osbuild.RHSMStageOptionsSubMan{
Rhsmcertd: &osbuild.SubManConfigRHSMCERTDSection{
AutoRegistration: common.BoolToPtr(true),
},
// Don't disable RHSM redhat.repo management on the GCE
// image, which is BYOS and does not use 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.
},
},
distro.RHSMConfigWithSubscription: {
SubMan: &osbuild.RHSMStageOptionsSubMan{
Rhsmcertd: &osbuild.SubManConfigRHSMCERTDSection{
AutoRegistration: common.BoolToPtr(true),
},
// do not disable the redhat.repo management if the user
// explicitly request the system to be subscribed
},
},
},
SshdConfig: &osbuild.SshdConfigStageOptions{
Config: osbuild.SshdConfigConfig{
PasswordAuthentication: common.BoolToPtr(false),
ClientAliveInterval: common.IntToPtr(420),
PermitRootLogin: osbuild.PermitRootLoginValueNo,
},
},
Sysconfig: []*osbuild.SysconfigStageOptions{
{
Kernel: &osbuild.SysconfigKernelOptions{
DefaultKernel: "kernel-core",
UpdateDefault: true,
},
},
},
Modprobe: []*osbuild.ModprobeStageOptions{
{
Filename: "blacklist-floppy.conf",
Commands: osbuild.ModprobeConfigCmdList{
osbuild.NewModprobeConfigCmdBlacklist("floppy"),
},
},
},
GCPGuestAgentConfig: &osbuild.GcpGuestAgentConfigOptions{
ConfigScope: osbuild.GcpGuestAgentConfigScopeDistro,
Config: &osbuild.GcpGuestAgentConfig{
InstanceSetup: &osbuild.GcpGuestAgentConfigInstanceSetup{
SetBotoConfig: common.BoolToPtr(false),
},
},
},
}
gceImgType := imageType{
name: "gce",
filename: "image.tar.gz",
mimeType: "application/gzip",
packageSets: map[string]packageSetFunc{
buildPkgsKey: distroBuildPackageSet,
osPkgsKey: gcePackageSet,
},
packageSetChains: map[string][]string{
osPkgsKey: {osPkgsKey, blueprintPkgsKey},
},
defaultImageConfig: defaultGceImageConfig,
kernelOptions: "net.ifnames=0 biosdevname=0 scsi_mod.use_blk_mq=Y console=ttyS0,38400n8d",
bootable: true,
bootType: distro.UEFIBootType,
defaultSize: 20 * common.GibiByte,
pipelines: gcePipelines,
buildPipelines: []string{"build"},
payloadPipelines: []string{"os", "image", "archive"},
exports: []string{"archive"},
basePartitionTables: defaultBasePartitionTables,
}
defaultGceRhuiImageConfig := &distro.ImageConfig{
RHSMConfig: map[distro.RHSMSubscriptionStatus]*osbuild.RHSMStageOptions{
distro.RHSMConfigNoSubscription: {
SubMan: &osbuild.RHSMStageOptionsSubMan{
Rhsmcertd: &osbuild.SubManConfigRHSMCERTDSection{
AutoRegistration: common.BoolToPtr(true),
},
Rhsm: &osbuild.SubManConfigRHSMSection{
ManageRepos: common.BoolToPtr(false),
},
},
},
distro.RHSMConfigWithSubscription: {
SubMan: &osbuild.RHSMStageOptionsSubMan{
Rhsmcertd: &osbuild.SubManConfigRHSMCERTDSection{
AutoRegistration: common.BoolToPtr(true),
},
// do not disable the redhat.repo management if the user
// explicitly request the system to be subscribed
},
},
},
}
defaultGceRhuiImageConfig = defaultGceRhuiImageConfig.InheritFrom(defaultGceImageConfig)
gceRhuiImgType := imageType{
name: "gce-rhui",
filename: "image.tar.gz",
mimeType: "application/gzip",
packageSets: map[string]packageSetFunc{
buildPkgsKey: distroBuildPackageSet,
osPkgsKey: gceRhuiPackageSet,
},
packageSetChains: map[string][]string{
osPkgsKey: {osPkgsKey, blueprintPkgsKey},
},
defaultImageConfig: defaultGceRhuiImageConfig,
kernelOptions: "net.ifnames=0 biosdevname=0 scsi_mod.use_blk_mq=Y console=ttyS0,38400n8d",
bootable: true,
bootType: distro.UEFIBootType,
defaultSize: 20 * common.GibiByte,
pipelines: gcePipelines,
buildPipelines: []string{"build"},
payloadPipelines: []string{"os", "image", "archive"},
exports: []string{"archive"},
basePartitionTables: defaultBasePartitionTables,
}
tarImgType := imageType{
name: "tar",
filename: "root.tar.xz",
mimeType: "application/x-tar",
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"},
}
},
},
packageSetChains: map[string][]string{
osPkgsKey: {osPkgsKey, blueprintPkgsKey},
},
pipelines: tarPipelines,
buildPipelines: []string{"build"},
payloadPipelines: []string{"os", "root-tar"},
exports: []string{"root-tar"},
}
imageInstaller := imageType{
name: "image-installer",
filename: "installer.iso",
mimeType: "application/x-iso9660-image",
packageSets: map[string]packageSetFunc{
buildPkgsKey: anacondaBuildPackageSet,
osPkgsKey: bareMetalPackageSet,
installerPkgsKey: anacondaPackageSet,
},
packageSetChains: map[string][]string{
osPkgsKey: {osPkgsKey, blueprintPkgsKey},
},
rpmOstree: false,
bootISO: true,
bootable: true,
pipelines: imageInstallerPipelines,
buildPipelines: []string{"build"},
payloadPipelines: []string{"os", "anaconda-tree", "bootiso-tree", "bootiso"},
exports: []string{"bootiso"},
}
ociImgType := qcow2ImgType
ociImgType.name = "oci"
x86_64.addImageTypes(qcow2ImgType, vmdkImgType, openstackImgType, amiImgTypeX86_64, tarImgType, imageInstaller, edgeCommitImgType, edgeInstallerImgType, edgeOCIImgType, edgeRawImgType, edgeSimplifiedInstallerImgType, ociImgType, gceImgType)
aarch64.addImageTypes(qcow2ImgType, openstackImgType, amiImgTypeAarch64, tarImgType, imageInstaller, edgeCommitImgType, edgeInstallerImgType, edgeOCIImgType, edgeRawImgType, edgeSimplifiedInstallerImgType)
ppc64le.addImageTypes(qcow2ImgType, tarImgType)
s390x.addImageTypes(qcow2ImgType, tarImgType)
if rd.isRHEL() {
// add azure to RHEL distro only
x86_64.addImageTypes(azureRhuiImgType)
x86_64.addImageTypes(azureByosImgType)
// add ec2 image types to RHEL distro only
x86_64.addImageTypes(ec2ImgTypeX86_64, ec2HaImgTypeX86_64, ec2SapImgTypeX86_64)
aarch64.addImageTypes(ec2ImgTypeAarch64)
// add GCE RHUI image to RHEL only
x86_64.addImageTypes(gceRhuiImgType)
} else {
x86_64.addImageTypes(azureImgType)
}
rd.addArches(x86_64, aarch64, ppc64le, s390x)
return &rd
}