diff --git a/pkg/distro/rhel/rhel10/ami.go b/pkg/distro/rhel/rhel10/ami.go index 61b0c7613d..2358791e9c 100644 --- a/pkg/distro/rhel/rhel10/ami.go +++ b/pkg/distro/rhel/rhel10/ami.go @@ -9,11 +9,162 @@ import ( "github.com/osbuild/images/pkg/rpmmd" ) +func mkAMIImgTypeX86_64() *rhel.ImageType { + it := rhel.NewImageType( + "ami", + "image.raw", + "application/octet-stream", + map[string]rhel.PackageSetFunc{ + rhel.OSPkgsKey: ec2PackageSet, + }, + rhel.DiskImage, + []string{"build"}, + []string{"os", "image"}, + []string{"image"}, + ) + + it.KernelOptions = amiKernelOptions + it.Bootable = true + it.DefaultSize = 10 * datasizes.GibiByte + it.DefaultImageConfig = defaultEc2ImageConfigX86_64() + it.BasePartitionTables = defaultBasePartitionTables + + return it +} + +func mkAMIImgTypeAarch64() *rhel.ImageType { + it := rhel.NewImageType( + "ami", + "image.raw", + "application/octet-stream", + map[string]rhel.PackageSetFunc{ + rhel.OSPkgsKey: ec2PackageSet, + }, + rhel.DiskImage, + []string{"build"}, + []string{"os", "image"}, + []string{"image"}, + ) + + it.KernelOptions = amiAarch64KernelOptions + it.Bootable = true + it.DefaultSize = 10 * datasizes.GibiByte + it.DefaultImageConfig = defaultEc2ImageConfig() + it.BasePartitionTables = defaultBasePartitionTables + + return it +} + +// RHEL internal-only x86_64 EC2 image type +func mkEc2ImgTypeX86_64() *rhel.ImageType { + it := rhel.NewImageType( + "ec2", + "image.raw.xz", + "application/xz", + map[string]rhel.PackageSetFunc{ + rhel.OSPkgsKey: ec2PackageSet, + }, + rhel.DiskImage, + []string{"build"}, + []string{"os", "image", "xz"}, + []string{"xz"}, + ) + + it.Compression = "xz" + it.KernelOptions = amiKernelOptions + it.Bootable = true + it.DefaultSize = 10 * datasizes.GibiByte + it.DefaultImageConfig = defaultEc2ImageConfigX86_64() + it.BasePartitionTables = defaultBasePartitionTables + + return it +} + +// RHEL internal-only aarch64 EC2 image type +func mkEC2ImgTypeAarch64() *rhel.ImageType { + it := rhel.NewImageType( + "ec2", + "image.raw.xz", + "application/xz", + map[string]rhel.PackageSetFunc{ + rhel.OSPkgsKey: ec2PackageSet, + }, + rhel.DiskImage, + []string{"build"}, + []string{"os", "image", "xz"}, + []string{"xz"}, + ) + + it.Compression = "xz" + it.KernelOptions = amiAarch64KernelOptions + it.Bootable = true + it.DefaultSize = 10 * datasizes.GibiByte + it.DefaultImageConfig = defaultEc2ImageConfig() + it.BasePartitionTables = defaultBasePartitionTables + + return it +} + +// RHEL internal-only x86_64 EC2 HA image type +func mkEc2HaImgTypeX86_64() *rhel.ImageType { + it := rhel.NewImageType( + "ec2-ha", + "image.raw.xz", + "application/xz", + map[string]rhel.PackageSetFunc{ + rhel.OSPkgsKey: rhelEc2HaPackageSet, + }, + rhel.DiskImage, + []string{"build"}, + []string{"os", "image", "xz"}, + []string{"xz"}, + ) + + it.Compression = "xz" + it.KernelOptions = amiKernelOptions + it.Bootable = true + it.DefaultSize = 10 * datasizes.GibiByte + it.DefaultImageConfig = defaultEc2ImageConfigX86_64() + it.BasePartitionTables = defaultBasePartitionTables + + return it +} + +func mkEC2SapImgTypeX86_64(osVersion string) *rhel.ImageType { + it := rhel.NewImageType( + "ec2-sap", + "image.raw.xz", + "application/xz", + map[string]rhel.PackageSetFunc{ + rhel.OSPkgsKey: rhelEc2SapPackageSet, + }, + rhel.DiskImage, + []string{"build"}, + []string{"os", "image", "xz"}, + []string{"xz"}, + ) + + it.Compression = "xz" + it.KernelOptions = amiSapKernelOptions + it.Bootable = true + it.DefaultSize = 10 * datasizes.GibiByte + it.DefaultImageConfig = sapImageConfig(osVersion).InheritFrom(defaultEc2ImageConfigX86_64()) + it.BasePartitionTables = defaultBasePartitionTables + + return it +} + +// IMAGE CONFIG + // TODO: move these to the EC2 environment -const amiKernelOptions = "console=tty0 console=ttyS0,115200n8 nvme_core.io_timeout=4294967295" +const ( + amiKernelOptions = "console=tty0 console=ttyS0,115200n8 nvme_core.io_timeout=4294967295" + amiAarch64KernelOptions = amiKernelOptions + " iommu.strict=0" + amiSapKernelOptions = amiKernelOptions + " processor.max_cstate=1 intel_idle.max_cstate=1" +) // default EC2 images config (common for all architectures) -func baseEc2ImageConfig() *distro.ImageConfig { +func defaultEc2ImageConfig() *distro.ImageConfig { return &distro.ImageConfig{ Locale: common.ToPtr("en_US.UTF-8"), Timezone: common.ToPtr("UTC"), @@ -120,32 +271,28 @@ func baseEc2ImageConfig() *distro.ImageConfig { } } -// Default AMI (custom image built by users) images config. -// The configuration does not touch the RHSM configuration at all. -// https://issues.redhat.com/browse/COMPOSER-2157 -func defaultAMIImageConfig() *distro.ImageConfig { - return baseEc2ImageConfig() +func appendEC2DracutX86_64(ic *distro.ImageConfig) *distro.ImageConfig { + ic.DracutConf = append(ic.DracutConf, + &osbuild.DracutConfStageOptions{ + Filename: "ec2.conf", + Config: osbuild.DracutConfigFile{ + AddDrivers: []string{ + "nvme", + "xen-blkfront", + }, + }, + }) + return ic } -// Default AMI x86_64 (custom image built by users) images config. -// The configuration does not touch the RHSM configuration at all. -// https://issues.redhat.com/browse/COMPOSER-2157 -func defaultAMIImageConfigX86_64() *distro.ImageConfig { - ic := defaultAMIImageConfig() +func defaultEc2ImageConfigX86_64() *distro.ImageConfig { + ic := defaultEc2ImageConfig() return appendEC2DracutX86_64(ic) } -// common ec2 image build package set -func ec2BuildPackageSet(t *rhel.ImageType) rpmmd.PackageSet { - return distroBuildPackageSet(t).Append( - rpmmd.PackageSet{ - Include: []string{ - "python3-pyyaml", - }, - }) -} +// PACKAGE SETS -func ec2CommonPackageSet(t *rhel.ImageType) rpmmd.PackageSet { +func ec2PackageSet(t *rhel.ImageType) rpmmd.PackageSet { ps := rpmmd.PackageSet{ Include: []string{ "@core", @@ -202,63 +349,24 @@ func ec2CommonPackageSet(t *rhel.ImageType) rpmmd.PackageSet { return ps } -func mkAMIImgTypeX86_64() *rhel.ImageType { - it := rhel.NewImageType( - "ami", - "image.raw", - "application/octet-stream", - map[string]rhel.PackageSetFunc{ - rhel.OSPkgsKey: ec2CommonPackageSet, +// rhel-ha-ec2 image package set +func rhelEc2HaPackageSet(t *rhel.ImageType) rpmmd.PackageSet { + ec2HaPackageSet := ec2PackageSet(t) + ec2HaPackageSet = ec2HaPackageSet.Append(rpmmd.PackageSet{ + Include: []string{ + "fence-agents-all", + "pacemaker", + "pcs", }, - rhel.DiskImage, - []string{"build"}, - []string{"os", "image"}, - []string{"image"}, - ) - - it.KernelOptions = amiKernelOptions - it.Bootable = true - it.DefaultSize = 10 * datasizes.GibiByte - it.DefaultImageConfig = defaultAMIImageConfigX86_64() - it.BasePartitionTables = defaultBasePartitionTables - - return it + }) + return ec2HaPackageSet } -func mkAMIImgTypeAarch64() *rhel.ImageType { - it := rhel.NewImageType( - "ami", - "image.raw", - "application/octet-stream", - map[string]rhel.PackageSetFunc{ - rhel.BuildPkgsKey: ec2BuildPackageSet, - rhel.OSPkgsKey: ec2CommonPackageSet, +// rhel-sap-ec2 image package set +func rhelEc2SapPackageSet(t *rhel.ImageType) rpmmd.PackageSet { + return rpmmd.PackageSet{ + Include: []string{ + //"libcanberra-gtk2", // libcanberra-gtk2 is not available in RHEL-10 }, - rhel.DiskImage, - []string{"build"}, - []string{"os", "image"}, - []string{"image"}, - ) - - it.KernelOptions = "console=ttyS0,115200n8 console=tty0 nvme_core.io_timeout=4294967295 iommu.strict=0" - it.Bootable = true - it.DefaultSize = 10 * datasizes.GibiByte - it.DefaultImageConfig = defaultAMIImageConfig() - it.BasePartitionTables = defaultBasePartitionTables - - return it -} - -func appendEC2DracutX86_64(ic *distro.ImageConfig) *distro.ImageConfig { - ic.DracutConf = append(ic.DracutConf, - &osbuild.DracutConfStageOptions{ - Filename: "ec2.conf", - Config: osbuild.DracutConfigFile{ - AddDrivers: []string{ - "nvme", - "xen-blkfront", - }, - }, - }) - return ic + }.Append(ec2PackageSet(t)).Append(SapPackageSet(t)) } diff --git a/pkg/distro/rhel/rhel10/azure.go b/pkg/distro/rhel/rhel10/azure.go index 610b1c5c22..7f10832881 100644 --- a/pkg/distro/rhel/rhel10/azure.go +++ b/pkg/distro/rhel/rhel10/azure.go @@ -2,15 +2,17 @@ package rhel10 import ( "github.com/osbuild/images/internal/common" + "github.com/osbuild/images/pkg/arch" "github.com/osbuild/images/pkg/datasizes" + "github.com/osbuild/images/pkg/disk" "github.com/osbuild/images/pkg/distro" "github.com/osbuild/images/pkg/distro/rhel" "github.com/osbuild/images/pkg/osbuild" "github.com/osbuild/images/pkg/rpmmd" ) -// Azure non-RHEL image type -func mkAzureImgType() *rhel.ImageType { +// Azure image type +func mkAzureImgType(rd *rhel.Distribution) *rhel.ImageType { it := rhel.NewImageType( "vhd", "disk.vhd", @@ -27,32 +29,57 @@ func mkAzureImgType() *rhel.ImageType { it.KernelOptions = defaultAzureKernelOptions it.Bootable = true it.DefaultSize = 4 * datasizes.GibiByte - it.DefaultImageConfig = defaultAzureImageConfig + it.DefaultImageConfig = defaultAzureImageConfig(rd) it.BasePartitionTables = defaultBasePartitionTables return it } -// Azure BYOS image type -func mkAzureByosImgType(rd distro.Distro) *rhel.ImageType { +// Azure RHEL-internal image type +func mkAzureInternalImgType(rd *rhel.Distribution) *rhel.ImageType { it := rhel.NewImageType( - "vhd", - "disk.vhd", - "application/x-vhd", + "azure-rhui", + "disk.vhd.xz", + "application/xz", map[string]rhel.PackageSetFunc{ rhel.OSPkgsKey: azurePackageSet, }, rhel.DiskImage, []string{"build"}, - []string{"os", "image", "vpc"}, - []string{"vpc"}, + []string{"os", "image", "vpc", "xz"}, + []string{"xz"}, ) + it.Compression = "xz" it.KernelOptions = defaultAzureKernelOptions it.Bootable = true - it.DefaultSize = 4 * datasizes.GibiByte - it.DefaultImageConfig = defaultAzureImageConfig - it.BasePartitionTables = defaultBasePartitionTables + it.DefaultSize = 64 * datasizes.GibiByte + it.DefaultImageConfig = defaultAzureImageConfig(rd) + it.BasePartitionTables = azureInternalBasePartitionTables + + return it +} + +func mkAzureSapInternalImgType(rd *rhel.Distribution) *rhel.ImageType { + it := rhel.NewImageType( + "azure-sap-rhui", + "disk.vhd.xz", + "application/xz", + map[string]rhel.PackageSetFunc{ + rhel.OSPkgsKey: azureSapPackageSet, + }, + rhel.DiskImage, + []string{"build"}, + []string{"os", "image", "vpc", "xz"}, + []string{"xz"}, + ) + + it.Compression = "xz" + it.KernelOptions = defaultAzureKernelOptions + it.Bootable = true + it.DefaultSize = 64 * datasizes.GibiByte + it.DefaultImageConfig = sapAzureImageConfig(rd) + it.BasePartitionTables = azureInternalBasePartitionTables return it } @@ -143,161 +170,401 @@ func azurePackageSet(t *rhel.ImageType) rpmmd.PackageSet { return azureCommonPackageSet(t) } +// Azure SAP image package set +// Includes the common azure package set, the common SAP packages +func azureSapPackageSet(t *rhel.ImageType) rpmmd.PackageSet { + return azureCommonPackageSet(t).Append(SapPackageSet(t)) +} + +// PARTITION TABLES +func azureInternalBasePartitionTables(t *rhel.ImageType) (disk.PartitionTable, bool) { + switch t.Arch().Name() { + case arch.ARCH_X86_64.String(): + return disk.PartitionTable{ + UUID: "D209C89E-EA5E-4FBD-B161-B461CCE297E0", + Type: disk.PT_GPT, + Size: 64 * datasizes.GibiByte, + Partitions: []disk.Partition{ + { + Size: 500 * datasizes.MebiByte, + Type: disk.EFISystemPartitionGUID, + UUID: disk.EFISystemPartitionUUID, + Payload: &disk.Filesystem{ + Type: "vfat", + UUID: disk.EFIFilesystemUUID, + Mountpoint: "/boot/efi", + FSTabOptions: "defaults,uid=0,gid=0,umask=077,shortname=winnt", + FSTabFreq: 0, + FSTabPassNo: 2, + }, + }, + // NB: we currently don't support /boot on LVM + { + Size: 1 * datasizes.GibiByte, + Type: disk.FilesystemDataGUID, + UUID: disk.FilesystemDataUUID, + Payload: &disk.Filesystem{ + Type: "xfs", + Mountpoint: "/boot", + FSTabOptions: "defaults", + FSTabFreq: 0, + FSTabPassNo: 0, + }, + }, + { + Size: 2 * datasizes.MebiByte, + Bootable: true, + Type: disk.BIOSBootPartitionGUID, + UUID: disk.BIOSBootPartitionUUID, + }, + { + Type: disk.LVMPartitionGUID, + UUID: disk.RootPartitionUUID, + Payload: &disk.LVMVolumeGroup{ + Name: "rootvg", + Description: "built with lvm2 and osbuild", + LogicalVolumes: []disk.LVMLogicalVolume{ + { + Size: 1 * datasizes.GibiByte, + Name: "homelv", + Payload: &disk.Filesystem{ + Type: "xfs", + Label: "home", + Mountpoint: "/home", + FSTabOptions: "defaults", + FSTabFreq: 0, + FSTabPassNo: 0, + }, + }, + { + Size: 2 * datasizes.GibiByte, + Name: "rootlv", + Payload: &disk.Filesystem{ + Type: "xfs", + Label: "root", + Mountpoint: "/", + FSTabOptions: "defaults", + FSTabFreq: 0, + FSTabPassNo: 0, + }, + }, + { + Size: 2 * datasizes.GibiByte, + Name: "tmplv", + Payload: &disk.Filesystem{ + Type: "xfs", + Label: "tmp", + Mountpoint: "/tmp", + FSTabOptions: "defaults", + FSTabFreq: 0, + FSTabPassNo: 0, + }, + }, + { + Size: 10 * datasizes.GibiByte, + Name: "usrlv", + Payload: &disk.Filesystem{ + Type: "xfs", + Label: "usr", + Mountpoint: "/usr", + FSTabOptions: "defaults", + FSTabFreq: 0, + FSTabPassNo: 0, + }, + }, + { + Size: 10 * datasizes.GibiByte, + Name: "varlv", + Payload: &disk.Filesystem{ + Type: "xfs", + Label: "var", + Mountpoint: "/var", + FSTabOptions: "defaults", + FSTabFreq: 0, + FSTabPassNo: 0, + }, + }, + }, + }, + }, + }, + }, true + case arch.ARCH_AARCH64.String(): + return disk.PartitionTable{ + UUID: "D209C89E-EA5E-4FBD-B161-B461CCE297E0", + Type: disk.PT_GPT, + Size: 64 * datasizes.GibiByte, + Partitions: []disk.Partition{ + { + Size: 500 * datasizes.MebiByte, + Type: disk.EFISystemPartitionGUID, + UUID: disk.EFISystemPartitionUUID, + Payload: &disk.Filesystem{ + Type: "vfat", + UUID: disk.EFIFilesystemUUID, + Mountpoint: "/boot/efi", + FSTabOptions: "defaults,uid=0,gid=0,umask=077,shortname=winnt", + FSTabFreq: 0, + FSTabPassNo: 2, + }, + }, + // NB: we currently don't support /boot on LVM + { + Size: 1 * datasizes.GibiByte, + Type: disk.FilesystemDataGUID, + UUID: disk.FilesystemDataUUID, + Payload: &disk.Filesystem{ + Type: "xfs", + Mountpoint: "/boot", + FSTabOptions: "defaults", + FSTabFreq: 0, + FSTabPassNo: 0, + }, + }, + { + Type: disk.LVMPartitionGUID, + UUID: disk.RootPartitionUUID, + Payload: &disk.LVMVolumeGroup{ + Name: "rootvg", + Description: "built with lvm2 and osbuild", + LogicalVolumes: []disk.LVMLogicalVolume{ + { + Size: 1 * datasizes.GibiByte, + Name: "homelv", + Payload: &disk.Filesystem{ + Type: "xfs", + Label: "home", + Mountpoint: "/home", + FSTabOptions: "defaults", + FSTabFreq: 0, + FSTabPassNo: 0, + }, + }, + { + Size: 2 * datasizes.GibiByte, + Name: "rootlv", + Payload: &disk.Filesystem{ + Type: "xfs", + Label: "root", + Mountpoint: "/", + FSTabOptions: "defaults", + FSTabFreq: 0, + FSTabPassNo: 0, + }, + }, + { + Size: 2 * datasizes.GibiByte, + Name: "tmplv", + Payload: &disk.Filesystem{ + Type: "xfs", + Label: "tmp", + Mountpoint: "/tmp", + FSTabOptions: "defaults", + FSTabFreq: 0, + FSTabPassNo: 0, + }, + }, + { + Size: 10 * datasizes.GibiByte, + Name: "usrlv", + Payload: &disk.Filesystem{ + Type: "xfs", + Label: "usr", + Mountpoint: "/usr", + FSTabOptions: "defaults", + FSTabFreq: 0, + FSTabPassNo: 0, + }, + }, + { + Size: 10 * datasizes.GibiByte, + Name: "varlv", + Payload: &disk.Filesystem{ + Type: "xfs", + Label: "var", + Mountpoint: "/var", + FSTabOptions: "defaults", + FSTabFreq: 0, + FSTabPassNo: 0, + }, + }, + }, + }, + }, + }, + }, true + default: + return disk.PartitionTable{}, false + } +} + // IMAGE CONFIG // use loglevel=3 as described in the RHEL documentation and used in existing RHEL images built by MSFT const defaultAzureKernelOptions = "ro loglevel=3 console=tty1 console=ttyS0 earlyprintk=ttyS0 rootdelay=300" // based on https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/deploying_rhel_9_on_microsoft_azure/assembly_deploying-a-rhel-image-as-a-virtual-machine-on-microsoft-azure_cloud-content-azure#making-configuration-changes_configure-the-image-azure -var defaultAzureImageConfig = &distro.ImageConfig{ - Timezone: common.ToPtr("Etc/UTC"), - Locale: common.ToPtr("en_US.UTF-8"), - Keyboard: &osbuild.KeymapStageOptions{ - Keymap: "us", - X11Keymap: &osbuild.X11KeymapOptions{ - Layouts: []string{"us"}, - }, - }, - Sysconfig: []*osbuild.SysconfigStageOptions{ - { - Kernel: &osbuild.SysconfigKernelOptions{ - UpdateDefault: true, - DefaultKernel: "kernel-core", +func defaultAzureImageConfig(rd *rhel.Distribution) *distro.ImageConfig { + ic := &distro.ImageConfig{ + Timezone: common.ToPtr("Etc/UTC"), + Locale: common.ToPtr("en_US.UTF-8"), + Keyboard: &osbuild.KeymapStageOptions{ + Keymap: "us", + X11Keymap: &osbuild.X11KeymapOptions{ + Layouts: []string{"us"}, }, - Network: &osbuild.SysconfigNetworkOptions{ - Networking: true, - NoZeroConf: true, + }, + Sysconfig: []*osbuild.SysconfigStageOptions{ + { + Kernel: &osbuild.SysconfigKernelOptions{ + UpdateDefault: true, + DefaultKernel: "kernel-core", + }, + Network: &osbuild.SysconfigNetworkOptions{ + Networking: true, + NoZeroConf: true, + }, }, }, - }, - EnabledServices: []string{ - "firewalld", - "nm-cloud-setup.service", - "nm-cloud-setup.timer", - "sshd", - "waagent", - }, - SshdConfig: &osbuild.SshdConfigStageOptions{ - Config: osbuild.SshdConfigConfig{ - ClientAliveInterval: common.ToPtr(180), + EnabledServices: []string{ + "firewalld", + "nm-cloud-setup.service", + "nm-cloud-setup.timer", + "sshd", + "waagent", }, - }, - Modprobe: []*osbuild.ModprobeStageOptions{ - { - Filename: "blacklist-amdgpu.conf", - Commands: osbuild.ModprobeConfigCmdList{ - osbuild.NewModprobeConfigCmdBlacklist("amdgpu"), + SshdConfig: &osbuild.SshdConfigStageOptions{ + Config: osbuild.SshdConfigConfig{ + ClientAliveInterval: common.ToPtr(180), }, }, - { - Filename: "blacklist-intel-cstate.conf", - Commands: osbuild.ModprobeConfigCmdList{ - osbuild.NewModprobeConfigCmdBlacklist("intel_cstate"), + Modprobe: []*osbuild.ModprobeStageOptions{ + { + Filename: "blacklist-amdgpu.conf", + Commands: osbuild.ModprobeConfigCmdList{ + osbuild.NewModprobeConfigCmdBlacklist("amdgpu"), + }, }, - }, - { - Filename: "blacklist-floppy.conf", - Commands: osbuild.ModprobeConfigCmdList{ - osbuild.NewModprobeConfigCmdBlacklist("floppy"), + { + Filename: "blacklist-intel-cstate.conf", + Commands: osbuild.ModprobeConfigCmdList{ + osbuild.NewModprobeConfigCmdBlacklist("intel_cstate"), + }, }, - }, - { - Filename: "blacklist-nouveau.conf", - Commands: osbuild.ModprobeConfigCmdList{ - osbuild.NewModprobeConfigCmdBlacklist("nouveau"), - osbuild.NewModprobeConfigCmdBlacklist("lbm-nouveau"), + { + Filename: "blacklist-floppy.conf", + Commands: osbuild.ModprobeConfigCmdList{ + osbuild.NewModprobeConfigCmdBlacklist("floppy"), + }, }, - }, - { - Filename: "blacklist-skylake-edac.conf", - Commands: osbuild.ModprobeConfigCmdList{ - osbuild.NewModprobeConfigCmdBlacklist("skx_edac"), + { + Filename: "blacklist-nouveau.conf", + Commands: osbuild.ModprobeConfigCmdList{ + osbuild.NewModprobeConfigCmdBlacklist("nouveau"), + osbuild.NewModprobeConfigCmdBlacklist("lbm-nouveau"), + }, }, - }, - }, - CloudInit: []*osbuild.CloudInitStageOptions{ - { - Filename: "10-azure-kvp.cfg", - Config: osbuild.CloudInitConfigFile{ - Reporting: &osbuild.CloudInitConfigReporting{ - Logging: &osbuild.CloudInitConfigReportingHandlers{ - Type: "log", - }, - Telemetry: &osbuild.CloudInitConfigReportingHandlers{ - Type: "hyperv", - }, + { + Filename: "blacklist-skylake-edac.conf", + Commands: osbuild.ModprobeConfigCmdList{ + osbuild.NewModprobeConfigCmdBlacklist("skx_edac"), }, }, }, - { - Filename: "91-azure_datasource.cfg", - Config: osbuild.CloudInitConfigFile{ - Datasource: &osbuild.CloudInitConfigDatasource{ - Azure: &osbuild.CloudInitConfigDatasourceAzure{ - ApplyNetworkConfig: false, + CloudInit: []*osbuild.CloudInitStageOptions{ + { + Filename: "10-azure-kvp.cfg", + Config: osbuild.CloudInitConfigFile{ + Reporting: &osbuild.CloudInitConfigReporting{ + Logging: &osbuild.CloudInitConfigReportingHandlers{ + Type: "log", + }, + Telemetry: &osbuild.CloudInitConfigReportingHandlers{ + Type: "hyperv", + }, }, }, - DatasourceList: []string{ - "Azure", + }, + { + Filename: "91-azure_datasource.cfg", + Config: osbuild.CloudInitConfigFile{ + Datasource: &osbuild.CloudInitConfigDatasource{ + Azure: &osbuild.CloudInitConfigDatasourceAzure{ + ApplyNetworkConfig: false, + }, + }, + DatasourceList: []string{ + "Azure", + }, }, }, }, - }, - PwQuality: &osbuild.PwqualityConfStageOptions{ - Config: osbuild.PwqualityConfConfig{ - Minlen: common.ToPtr(6), - Minclass: common.ToPtr(3), - Dcredit: common.ToPtr(0), - Ucredit: common.ToPtr(0), - Lcredit: common.ToPtr(0), - Ocredit: common.ToPtr(0), + PwQuality: &osbuild.PwqualityConfStageOptions{ + Config: osbuild.PwqualityConfConfig{ + Minlen: common.ToPtr(6), + Minclass: common.ToPtr(3), + Dcredit: common.ToPtr(0), + Ucredit: common.ToPtr(0), + Lcredit: common.ToPtr(0), + Ocredit: common.ToPtr(0), + }, + }, + WAAgentConfig: &osbuild.WAAgentConfStageOptions{ + Config: osbuild.WAAgentConfig{ + RDFormat: common.ToPtr(false), + RDEnableSwap: common.ToPtr(false), + }, }, - }, - WAAgentConfig: &osbuild.WAAgentConfStageOptions{ - Config: osbuild.WAAgentConfig{ - RDFormat: common.ToPtr(false), - RDEnableSwap: common.ToPtr(false), + Grub2Config: &osbuild.GRUB2Config{ + DisableRecovery: common.ToPtr(true), + DisableSubmenu: common.ToPtr(true), + Distributor: "$(sed 's, release .*$,,g' /etc/system-release)", + Terminal: []string{"serial", "console"}, + Serial: "serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1", + Timeout: 10, + TimeoutStyle: osbuild.GRUB2ConfigTimeoutStyleCountdown, }, - }, - Grub2Config: &osbuild.GRUB2Config{ - DisableRecovery: common.ToPtr(true), - DisableSubmenu: common.ToPtr(true), - Distributor: "$(sed 's, release .*$,,g' /etc/system-release)", - Terminal: []string{"serial", "console"}, - Serial: "serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1", - Timeout: 10, - TimeoutStyle: osbuild.GRUB2ConfigTimeoutStyleCountdown, - }, - UdevRules: &osbuild.UdevRulesStageOptions{ - Filename: "/etc/udev/rules.d/68-azure-sriov-nm-unmanaged.rules", - Rules: osbuild.UdevRules{ - osbuild.UdevRuleComment{ - Comment: []string{ - "Accelerated Networking on Azure exposes a new SRIOV interface to the VM.", - "This interface is transparently bonded to the synthetic interface,", - "so NetworkManager should just ignore any SRIOV interfaces.", + UdevRules: &osbuild.UdevRulesStageOptions{ + Filename: "/etc/udev/rules.d/68-azure-sriov-nm-unmanaged.rules", + Rules: osbuild.UdevRules{ + osbuild.UdevRuleComment{ + Comment: []string{ + "Accelerated Networking on Azure exposes a new SRIOV interface to the VM.", + "This interface is transparently bonded to the synthetic interface,", + "so NetworkManager should just ignore any SRIOV interfaces.", + }, }, + osbuild.NewUdevRule( + []osbuild.UdevKV{ + {K: "SUBSYSTEM", O: "==", V: "net"}, + {K: "DRIVERS", O: "==", V: "hv_pci"}, + {K: "ACTION", O: "==", V: "add"}, + {K: "ENV", A: "NM_UNMANAGED", O: "=", V: "1"}, + }, + ), }, - osbuild.NewUdevRule( - []osbuild.UdevKV{ - {K: "SUBSYSTEM", O: "==", V: "net"}, - {K: "DRIVERS", O: "==", V: "hv_pci"}, - {K: "ACTION", O: "==", V: "add"}, - {K: "ENV", A: "NM_UNMANAGED", O: "=", V: "1"}, - }, - ), }, - }, - SystemdUnit: []*osbuild.SystemdUnitStageOptions{ - { - Unit: "nm-cloud-setup.service", - Dropin: "10-rh-enable-for-azure.conf", - Config: osbuild.SystemdServiceUnitDropin{ - Service: &osbuild.SystemdUnitServiceSection{ - Environment: []osbuild.EnvironmentVariable{{Key: "NM_CLOUD_SETUP_AZURE", Value: "yes"}}, + SystemdUnit: []*osbuild.SystemdUnitStageOptions{ + { + Unit: "nm-cloud-setup.service", + Dropin: "10-rh-enable-for-azure.conf", + Config: osbuild.SystemdServiceUnitDropin{ + Service: &osbuild.SystemdUnitServiceSection{ + Environment: []osbuild.EnvironmentVariable{{Key: "NM_CLOUD_SETUP_AZURE", Value: "yes"}}, + }, }, }, }, - }, - DefaultTarget: common.ToPtr("multi-user.target"), + DefaultTarget: common.ToPtr("multi-user.target"), + } + + if rd.IsRHEL() { + ic.GPGKeyFiles = append(ic.GPGKeyFiles, "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release") + } + + return ic +} + +func sapAzureImageConfig(rd *rhel.Distribution) *distro.ImageConfig { + return sapImageConfig(rd.OsVersion()).InheritFrom(defaultAzureImageConfig(rd)) } diff --git a/pkg/distro/rhel/rhel10/distro.go b/pkg/distro/rhel/rhel10/distro.go index 3d4c243e35..a5cd9b909d 100644 --- a/pkg/distro/rhel/rhel10/distro.go +++ b/pkg/distro/rhel/rhel10/distro.go @@ -183,13 +183,14 @@ func newDistro(name string, major, minor int) *rhel.Distribution { mkAMIImgTypeX86_64(), ) - aarch64.AddImageTypes( - &platform.Aarch64{ - UEFIVendor: rd.Vendor(), - BasePlatform: platform.BasePlatform{ - ImageFormat: platform.FORMAT_RAW, - }, + ec2Aarch64Platform := &platform.Aarch64{ + UEFIVendor: rd.Vendor(), + BasePlatform: platform.BasePlatform{ + ImageFormat: platform.FORMAT_RAW, }, + } + aarch64.AddImageTypes( + ec2Aarch64Platform, mkAMIImgTypeAarch64(), ) @@ -208,13 +209,8 @@ func newDistro(name string, major, minor int) *rhel.Distribution { }, } - if rd.IsRHEL() { // RHEL-only (non-CentOS) image types - x86_64.AddImageTypes(azureX64Platform, mkAzureByosImgType(rd)) - aarch64.AddImageTypes(azureAarch64Platform, mkAzureByosImgType(rd)) - } else { - x86_64.AddImageTypes(azureX64Platform, mkAzureImgType()) - aarch64.AddImageTypes(azureAarch64Platform, mkAzureImgType()) - } + x86_64.AddImageTypes(azureX64Platform, mkAzureImgType(rd)) + aarch64.AddImageTypes(azureAarch64Platform, mkAzureImgType(rd)) gceX86Platform := &platform.X86{ UEFIVendor: rd.Vendor(), @@ -258,6 +254,16 @@ func newDistro(name string, major, minor int) *rhel.Distribution { mkImageInstallerImgType(), ) + if rd.IsRHEL() { // RHEL-only (non-CentOS) image types + x86_64.AddImageTypes(azureX64Platform, mkAzureInternalImgType(rd)) + aarch64.AddImageTypes(azureAarch64Platform, mkAzureInternalImgType(rd)) + + x86_64.AddImageTypes(azureX64Platform, mkAzureSapInternalImgType(rd)) + + x86_64.AddImageTypes(ec2X86Platform, mkEc2ImgTypeX86_64(), mkEc2HaImgTypeX86_64(), mkEC2SapImgTypeX86_64(rd.OsVersion())) + aarch64.AddImageTypes(ec2Aarch64Platform, mkEC2ImgTypeAarch64()) + } + rd.AddArches(x86_64, aarch64, ppc64le, s390x) return rd } diff --git a/pkg/distro/rhel/rhel10/distro_internal_test.go b/pkg/distro/rhel/rhel10/distro_internal_test.go index 5ac98502d3..4315939822 100644 --- a/pkg/distro/rhel/rhel10/distro_internal_test.go +++ b/pkg/distro/rhel/rhel10/distro_internal_test.go @@ -176,6 +176,11 @@ func TestRhel10_NoBootPartition(t *testing.T) { if it.BasePartitionTables == nil { continue } + if it.Name() == "azure-rhui" || it.Name() == "azure-sap-rhui" { + // Azure RHEL internal image type PT is by default LVM-based + // and we do not support /boot on LVM, so it must be on a separate partition. + continue + } pt, err := it.GetPartitionTable([]blueprint.FilesystemCustomization{}, distro.ImageOptions{}, rng) assert.NoError(t, err) _, err = pt.GetMountpointSize("/boot") diff --git a/pkg/distro/rhel/rhel10/distro_test.go b/pkg/distro/rhel/rhel10/distro_test.go index 2b9ff75d9c..ccbe2f73a6 100644 --- a/pkg/distro/rhel/rhel10/distro_test.go +++ b/pkg/distro/rhel/rhel10/distro_test.go @@ -282,6 +282,11 @@ func TestArchitecture_ListImageTypes(t *testing.T) { "wsl", "gce", "image-installer", + "azure-rhui", + "azure-sap-rhui", + "ec2", + "ec2-ha", + "ec2-sap", }, }, { @@ -293,6 +298,8 @@ func TestArchitecture_ListImageTypes(t *testing.T) { "vhd", "wsl", "image-installer", + "azure-rhui", + "ec2", }, }, { diff --git a/pkg/distro/rhel/rhel10/sap.go b/pkg/distro/rhel/rhel10/sap.go new file mode 100644 index 0000000000..1290bb2d63 --- /dev/null +++ b/pkg/distro/rhel/rhel10/sap.go @@ -0,0 +1,174 @@ +package rhel10 + +import ( + "github.com/osbuild/images/pkg/distro" + "github.com/osbuild/images/pkg/distro/rhel" + "github.com/osbuild/images/pkg/osbuild" + "github.com/osbuild/images/pkg/rpmmd" +) + +// sapImageConfig returns the SAP specific ImageConfig data +func sapImageConfig(osVersion string) *distro.ImageConfig { + return &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: osVersion, + }, + }, + nil, + ), + }, + } +} + +func SapPackageSet(t *rhel.ImageType) rpmmd.PackageSet { + return rpmmd.PackageSet{ + Include: []string{ + // RHBZ#2076763 + "@Server", + // SAP System Roles + // https://access.redhat.com/sites/default/files/attachments/rhel_system_roles_for_sap_1.pdf + "ansible-core", + "rhel-system-roles-sap", + // RHBZ#1959813 + "bind-utils", + "nfs-utils", + "tcsh", + // RHBZ#1959955 + "uuidd", + // RHBZ#1959923 + "cairo", + "expect", + "graphviz", + //"gtk2", // gtk2 is not available in RHEL-10 + "iptraf-ng", + "krb5-workstation", + "libaio", + "libatomic", + "libicu", + "libtool-ltdl", + "lm_sensors", + "net-tools", + "numactl", + "PackageKit-gtk3-module", + "xorg-x11-xauth", + // RHBZ#1960617 + "tuned-profiles-sap-hana", + // RHBZ#1961168 + "libnsl", + }, + Exclude: []string{ + "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", + }, + } +} diff --git a/test/config-map.json b/test/config-map.json index fa828e32d8..9c246ef87a 100644 --- a/test/config-map.json +++ b/test/config-map.json @@ -40,7 +40,8 @@ "rhel-8.7", "rhel-8.8", "rhel-8.9", - "rhel-9.*" + "rhel-9.*", + "rhel-10.*" ], "image-types": [ "ec2-sap"