Skip to content
Merged
2 changes: 2 additions & 0 deletions data/distrodefs/fedora/imagetypes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1658,6 +1658,8 @@ image_types:
image_config:
<<: *image_config_iot_enabled_services
locale: "en_US.UTF-8"
# iot-installer is not using the default ostree kernel options
kernel_options:
package_sets:
installer:
- *anaconda_pkgset
Expand Down
41 changes: 14 additions & 27 deletions pkg/distro/generic/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ import (
"github.com/osbuild/images/pkg/rpmmd"
)

func kernelOptions(t *imageType, c *blueprint.Customizations) []string {
imageConfig := t.getDefaultImageConfig()

kernelOptions := imageConfig.KernelOptions
if bpKernel := c.GetKernel(); bpKernel.Append != "" {
kernelOptions = append(kernelOptions, bpKernel.Append)
}
return kernelOptions
}

func osCustomizations(t *imageType, osPackageSet rpmmd.PackageSet, options distro.ImageOptions, containers []container.SourceSpec, bp *blueprint.Blueprint) (manifest.OSCustomizations, error) {
c := bp.Customizations
osc := manifest.OSCustomizations{}
Expand All @@ -40,13 +50,7 @@ func osCustomizations(t *imageType, osPackageSet rpmmd.PackageSet, options distr
if imageConfig.DefaultKernelName != nil {
osc.KernelName = *imageConfig.DefaultKernelName
}

// XXX: keep in sync with the identical copy in rhel/images.go
kernelOptions := imageConfig.KernelOptions
if bpKernel := c.GetKernel(); bpKernel.Append != "" {
kernelOptions = append(kernelOptions, bpKernel.Append)
}
osc.KernelOptionsAppend = kernelOptions
osc.KernelOptionsAppend = kernelOptions(t, c)
if imageConfig.KernelOptionsBootloader != nil {
osc.KernelOptionsBootloader = *imageConfig.KernelOptionsBootloader
}
Expand Down Expand Up @@ -390,6 +394,7 @@ func installerCustomizations(t *imageType, c *blueprint.Customizations) (manifes
isc.EnabledAnacondaModules = append(isc.EnabledAnacondaModules, installerCust.Modules.Enable...)
isc.DisabledAnacondaModules = append(isc.DisabledAnacondaModules, installerCust.Modules.Disable...)
}
isc.KernelOptionsAppend = kernelOptions(t, c)

return isc, nil
}
Expand Down Expand Up @@ -625,7 +630,7 @@ func imageInstallerImage(t *imageType,
img.InstallerCustomizations.EnabledAnacondaModules = append(img.InstallerCustomizations.EnabledAnacondaModules, anaconda.ModuleUsers)

if img.Kickstart.Unattended {
img.InstallerCustomizations.AdditionalKernelOpts = append(img.InstallerCustomizations.AdditionalKernelOpts, installerConfig.KickstartUnattendedExtraKernelOpts...)
img.InstallerCustomizations.KernelOptionsAppend = append(installerConfig.KickstartUnattendedExtraKernelOpts, img.InstallerCustomizations.KernelOptionsAppend...)
}

img.RootfsCompression = "xz" // This also triggers using the bcj filter
Expand Down Expand Up @@ -769,7 +774,6 @@ func iotInstallerImage(t *imageType,
img.Kickstart.Timezone, _ = customizations.GetTimezoneSettings()

img.InstallerCustomizations, err = installerCustomizations(t, bp.Customizations)

if err != nil {
return nil, err
}
Expand Down Expand Up @@ -889,28 +893,11 @@ func iotSimplifiedInstallerImage(t *imageType,
}
}
}

installerConfig, err := t.getDefaultInstallerConfig()
img.InstallerCustomizations, err = installerCustomizations(t, bp.Customizations)
if err != nil {
return nil, err
}

if installerConfig != nil {
img.AdditionalDracutModules = append(img.AdditionalDracutModules, installerConfig.AdditionalDracutModules...)
img.AdditionalDrivers = append(img.AdditionalDrivers, installerConfig.AdditionalDrivers...)
}

// XXX: move to use InstallerCustomizations too
d := t.arch.distro
img.Product = d.Product()
img.Variant = t.ImageTypeYAML.Variant
img.OSName = t.OSTree.Name
img.OSVersion = d.OsVersion()

img.ISOLabel, err = t.ISOLabel()
if err != nil {
return nil, err
}

return img, nil
}
Expand Down
70 changes: 70 additions & 0 deletions pkg/distro/generic/images_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package generic

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/osbuild/blueprint/pkg/blueprint"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/distro/defs"
)

func isoTestImageType() *imageType {
return &imageType{
arch: &architecture{
distro: &distribution{},
},
ImageTypeYAML: defs.ImageTypeYAML{
BootISO: true,
},
isoLabel: func(*imageType) string { return "iso-label" },
}
}

func TestInstallerCustomizationsHonorKernelOptions(t *testing.T) {

for _, tc := range []struct {
imageConfig *distro.ImageConfig
kernelCustomizations *blueprint.KernelCustomization
expected []string
}{
{
nil,
nil,
nil,
},
{
nil,
&blueprint.KernelCustomization{
Append: "debug",
},
[]string{"debug"},
},
{
&distro.ImageConfig{
KernelOptions: []string{"default"},
},
nil,
[]string{"default"},
},
{
&distro.ImageConfig{
KernelOptions: []string{"default"},
},
&blueprint.KernelCustomization{
Append: "debug",
},
[]string{"default", "debug"},
},
} {
it := isoTestImageType()
it.ImageConfigYAML.ImageConfig = tc.imageConfig
c := &blueprint.Customizations{Kernel: tc.kernelCustomizations}

isc, err := installerCustomizations(it, c)
require.NoError(t, err)
assert.Equal(t, tc.expected, isc.KernelOptionsAppend)
}
}
3 changes: 2 additions & 1 deletion pkg/distro/generic/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package generic_test
import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/osbuild/blueprint/pkg/blueprint"
"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/pkg/disk/partition"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/distro/generic"
"github.com/osbuild/images/pkg/ostree"
"github.com/stretchr/testify/assert"
)

func TestCheckOptions(t *testing.T) {
Expand Down
6 changes: 4 additions & 2 deletions pkg/image/anaconda_container_installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,12 @@ func (img *AnacondaContainerInstaller) InstantiateManifest(m *manifest.Manifest,
img.Kickstart.Path = osbuild.KickstartPathOSBuild
}

bootTreePipeline.KernelOpts = []string{fmt.Sprintf("inst.stage2=hd:LABEL=%s", img.InstallerCustomizations.ISOLabel), fmt.Sprintf("inst.ks=hd:LABEL=%s:%s", img.InstallerCustomizations.ISOLabel, img.Kickstart.Path)}
kernelOpts := []string{fmt.Sprintf("inst.stage2=hd:LABEL=%s", img.InstallerCustomizations.ISOLabel), fmt.Sprintf("inst.ks=hd:LABEL=%s:%s", img.InstallerCustomizations.ISOLabel, img.Kickstart.Path)}
if anacondaPipeline.InstallerCustomizations.FIPS {
bootTreePipeline.KernelOpts = append(bootTreePipeline.KernelOpts, "fips=1")
kernelOpts = append(kernelOpts, "fips=1")
}
kernelOpts = append(kernelOpts, img.InstallerCustomizations.KernelOptionsAppend...)
bootTreePipeline.KernelOpts = kernelOpts

isoTreePipeline := manifest.NewAnacondaInstallerISOTree(buildPipeline, anacondaPipeline, rootfsImagePipeline, bootTreePipeline)
isoTreePipeline.PartitionTable = efiBootPartitionTable(rng)
Expand Down
2 changes: 1 addition & 1 deletion pkg/image/anaconda_live_installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (img *AnacondaLiveInstaller) InstantiateManifest(m *manifest.Manifest,
"rhgb",
}

kernelOpts = append(kernelOpts, img.InstallerCustomizations.AdditionalKernelOpts...)
kernelOpts = append(kernelOpts, img.InstallerCustomizations.KernelOptionsAppend...)

bootTreePipeline.KernelOpts = kernelOpts

Expand Down
4 changes: 2 additions & 2 deletions pkg/image/anaconda_net_installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func (img *AnacondaNetInstaller) InstantiateManifest(m *manifest.Manifest,
if anacondaPipeline.InstallerCustomizations.FIPS {
kernelOpts = append(kernelOpts, "fips=1")
}
kernelOpts = append(kernelOpts, img.InstallerCustomizations.AdditionalKernelOpts...)
kernelOpts = append(kernelOpts, img.InstallerCustomizations.KernelOptionsAppend...)
bootTreePipeline.KernelOpts = kernelOpts

isoTreePipeline := manifest.NewAnacondaInstallerISOTree(buildPipeline, anacondaPipeline, rootfsImagePipeline, bootTreePipeline)
Expand All @@ -95,7 +95,7 @@ func (img *AnacondaNetInstaller) InstantiateManifest(m *manifest.Manifest,
isoTreePipeline.RootfsCompression = img.RootfsCompression
isoTreePipeline.RootfsType = img.InstallerCustomizations.ISORootfsType

isoTreePipeline.KernelOpts = img.InstallerCustomizations.AdditionalKernelOpts
isoTreePipeline.KernelOpts = img.InstallerCustomizations.KernelOptionsAppend
if anacondaPipeline.InstallerCustomizations.FIPS {
isoTreePipeline.KernelOpts = append(isoTreePipeline.KernelOpts, "fips=1")
}
Expand Down
6 changes: 4 additions & 2 deletions pkg/image/anaconda_ostree_installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,12 @@ func (img *AnacondaOSTreeInstaller) InstantiateManifest(m *manifest.Manifest,
if img.Kickstart.Path == "" {
img.Kickstart.Path = osbuild.KickstartPathOSBuild
}
bootTreePipeline.KernelOpts = []string{fmt.Sprintf("inst.stage2=hd:LABEL=%s", img.InstallerCustomizations.ISOLabel), fmt.Sprintf("inst.ks=hd:LABEL=%s:%s", img.InstallerCustomizations.ISOLabel, img.Kickstart.Path)}
kernelOpts := []string{fmt.Sprintf("inst.stage2=hd:LABEL=%s", img.InstallerCustomizations.ISOLabel), fmt.Sprintf("inst.ks=hd:LABEL=%s:%s", img.InstallerCustomizations.ISOLabel, img.Kickstart.Path)}
if anacondaPipeline.InstallerCustomizations.FIPS {
bootTreePipeline.KernelOpts = append(bootTreePipeline.KernelOpts, "fips=1")
kernelOpts = append(kernelOpts, "fips=1")
}
kernelOpts = append(kernelOpts, img.InstallerCustomizations.KernelOptionsAppend...)
bootTreePipeline.KernelOpts = kernelOpts

var subscriptionPipeline *manifest.Subscription
if img.Subscription != nil {
Expand Down
6 changes: 2 additions & 4 deletions pkg/image/anaconda_tar_installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,7 @@ func (img *AnacondaTarInstaller) InstantiateManifest(m *manifest.Manifest,
if img.OSCustomizations.FIPS {
kernelOpts = append(kernelOpts, "fips=1")
}
kernelOpts = append(kernelOpts, img.InstallerCustomizations.AdditionalKernelOpts...)
kernelOpts = append(kernelOpts, img.OSCustomizations.KernelOptionsAppend...)
kernelOpts = append(kernelOpts, img.InstallerCustomizations.KernelOptionsAppend...)
bootTreePipeline.KernelOpts = kernelOpts

osPipeline := manifest.NewOS(buildPipeline, img.platform, repos)
Expand All @@ -145,8 +144,7 @@ func (img *AnacondaTarInstaller) InstantiateManifest(m *manifest.Manifest,
isoTreePipeline.RootfsType = img.InstallerCustomizations.ISORootfsType

isoTreePipeline.OSPipeline = osPipeline
isoTreePipeline.KernelOpts = img.InstallerCustomizations.AdditionalKernelOpts
isoTreePipeline.KernelOpts = append(isoTreePipeline.KernelOpts, img.OSCustomizations.KernelOptionsAppend...)
isoTreePipeline.KernelOpts = img.InstallerCustomizations.KernelOptionsAppend
if img.OSCustomizations.FIPS {
isoTreePipeline.KernelOpts = append(isoTreePipeline.KernelOpts, "fips=1")
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/image/installer_image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@ func TestTarInstallerKernelOpts(t *testing.T) {

testOpts := []string{"foo=1", "bar=2"}

img.InstallerCustomizations.AdditionalKernelOpts = testOpts
img.InstallerCustomizations.KernelOptionsAppend = testOpts

assert.NotNil(t, img)
mfs := instantiateAndSerialize(t, img, mockPackageSets(), nil, nil)
Expand Down
46 changes: 21 additions & 25 deletions pkg/image/ostree_simplified_installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,15 @@ type OSTreeSimplifiedInstaller struct {
// Raw image that will be created and embedded
rawImage *OSTreeDiskImage

OSCustomizations manifest.OSCustomizations
Environment environment.Environment
OSCustomizations manifest.OSCustomizations
Environment environment.Environment
InstallerCustomizations manifest.InstallerCustomizations

ExtraBasePackages rpmmd.PackageSet

ISOLabel string

// ISO label template (architecture-free)
ISOLabelTmpl string

// Product string for ISO buildstamp
Product string

// OSVersion string for ISO buildstamp
OSVersion string

// Variant string for ISO buildstamp
Variant string

// OSName for ostree deployment
OSName string

Expand All @@ -52,9 +42,6 @@ type OSTreeSimplifiedInstaller struct {

// Ignition embedded configuration options
IgnitionEmbedded *ignition.EmbeddedOptions

AdditionalDracutModules []string
AdditionalDrivers []string
}

func NewOSTreeSimplifiedInstaller(platform platform.Platform, filename string, rawImage *OSTreeDiskImage, installDevice string) *OSTreeSimplifiedInstaller {
Expand Down Expand Up @@ -83,29 +70,29 @@ func (img *OSTreeSimplifiedInstaller) InstantiateManifest(m *manifest.Manifest,
img.platform,
repos,
"kernel",
img.Product,
img.OSVersion,
img.InstallerCustomizations.Product,
img.InstallerCustomizations.OSVersion,
)
coiPipeline.ExtraPackages = img.ExtraBasePackages.Include
coiPipeline.ExcludePackages = img.ExtraBasePackages.Exclude
coiPipeline.ExtraRepos = img.ExtraBasePackages.Repositories
coiPipeline.FDO = img.FDO
coiPipeline.Ignition = img.IgnitionEmbedded
coiPipeline.Biosdevname = (img.platform.GetArch() == arch.ARCH_X86_64)
coiPipeline.Variant = img.Variant
coiPipeline.AdditionalDracutModules = img.AdditionalDracutModules
coiPipeline.AdditionalDrivers = img.AdditionalDrivers
coiPipeline.Variant = img.InstallerCustomizations.Variant
coiPipeline.AdditionalDracutModules = img.InstallerCustomizations.AdditionalDracutModules
coiPipeline.AdditionalDrivers = img.InstallerCustomizations.AdditionalDrivers

var isoLabel string

if len(img.ISOLabel) > 0 {
isoLabel = img.ISOLabel
if len(img.InstallerCustomizations.ISOLabel) > 0 {
isoLabel = img.InstallerCustomizations.ISOLabel
} else {
// TODO: replace isoLabelTmpl with more high-level properties
isoLabel = fmt.Sprintf(img.ISOLabelTmpl, img.platform.GetArch())
}

bootTreePipeline := manifest.NewEFIBootTree(buildPipeline, img.Product, img.OSVersion)
bootTreePipeline := manifest.NewEFIBootTree(buildPipeline, img.InstallerCustomizations.Product, img.InstallerCustomizations.OSVersion)
bootTreePipeline.Platform = img.platform
bootTreePipeline.UEFIVendor = img.platform.GetUEFIVendor()
bootTreePipeline.ISOLabel = isoLabel
Expand Down Expand Up @@ -136,7 +123,16 @@ func (img *OSTreeSimplifiedInstaller) InstantiateManifest(m *manifest.Manifest,
kernelOpts = append(kernelOpts, "fdo.di_mfg_string_type_mac_iface="+img.FDO.DiMfgStringTypeMacIface)
}
}

// Note that we do not use the
// InstallerCustomizations.KernelOptionsAppend here because
// InstallerCustomizations.KernelOptionsAppend also picks up
// the kernel options from the imageConfig but we only set
// those in the rawImage.OSTreeDeploymentCustomizations and
// not in the bootTreePipeline. Its unclear if we should change
// this or not. Its inconsistent with the other installers but

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is actually (even more) interesting - we allow customizations.kernel for the iot-simplified-installer image type but afaict setting it has no effect(?)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, that's funky. Maybe this is from the time that we wanted blueprints to be able to apply to multiple image types even though silently discarding stuff is bad (in my opinion).

We can probably drop this from the allowed customizations as it has no effect?

@achilleas-k achilleas-k Sep 18, 2025

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a Muppet (again) - I was confused by gen-manifests-diff not showing anything when doing #1880 but its just a silly bug in gen-manifests-diff (I opened #1881 to address that)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for this blunder - I think the comment itself is (largely) correct though or do you want me to clarify further and/or fix this (could be a followup) it would change existing manifest checksums iirc.

// then simplifiedInstaler is special.
//
// kernelOpts = append(kernelOpts, img.InstallerCustomizations.KernelOptionsAppend...)
bootTreePipeline.KernelOpts = kernelOpts

// enable ISOLinux on x86_64 only
Expand Down
10 changes: 5 additions & 5 deletions pkg/image/ostree_simplified_installer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ func TestSimplifiedInstallerDracut(t *testing.T) {
ostreeDiskImage := image.NewOSTreeDiskImageFromCommit(platform, "filename", commit)
ostreeDiskImage.PartitionTable = testdisk.MakeFakePartitionTable("/")
img := image.NewOSTreeSimplifiedInstaller(testPlatform, "filename", ostreeDiskImage, "")
img.Product = product
img.OSVersion = osversion
img.ISOLabel = isolabel
img.InstallerCustomizations.Product = product
img.InstallerCustomizations.OSVersion = osversion
img.InstallerCustomizations.ISOLabel = isolabel

testModules := []string{"test-module"}
testDrivers := []string{"test-driver"}

img.AdditionalDracutModules = testModules
img.AdditionalDrivers = testDrivers
img.InstallerCustomizations.AdditionalDracutModules = testModules
img.InstallerCustomizations.AdditionalDrivers = testDrivers

commitSpec := map[string][]ostree.CommitSpec{
"ostree-deployment": {
Expand Down
2 changes: 1 addition & 1 deletion pkg/manifest/installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ package manifest
type InstallerCustomizations struct {
FIPS bool

AdditionalKernelOpts []string
KernelOptionsAppend []string

EnabledAnacondaModules []string
DisabledAnacondaModules []string
Expand Down
Loading