From e1bcbc29028a367ce2aa753d988190c253b49bd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20V=C3=ADtov=C3=A1?= Date: Fri, 6 Mar 2026 11:35:00 +0100 Subject: [PATCH 1/5] pkg/distro: search for image types in all files Update LoadImageTypes to search for all relevant files in the folder, add image type from each of those. The function allows for each image type to appear in only one file. --- pkg/distro/defs/loader.go | 49 ++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/pkg/distro/defs/loader.go b/pkg/distro/defs/loader.go index c150faae7c..b746be3255 100644 --- a/pkg/distro/defs/loader.go +++ b/pkg/distro/defs/loader.go @@ -267,22 +267,36 @@ func LoadDistroWithoutImageTypes(nameVer string) (*DistroYAML, error) { } func (d *DistroYAML) LoadImageTypes() error { - f, err := dataFS().Open(filepath.Join(d.DefsPath, "imagetypes.yaml")) + files, err := fs.Glob(dataFS(), filepath.Join(d.DefsPath, "*.yaml")) if err != nil { return err } - defer f.Close() - var toplevel imageTypesYAML - decoder := yaml.NewDecoder(f) - decoder.KnownFields(true) - if err := decoder.Decode(&toplevel); err != nil { - return err + var configs []imageTypesYAML + for _, fileName := range files { + f, err := dataFS().Open(fileName) + if err != nil { + return err + } + + var toplevel imageTypesYAML + decoder := yaml.NewDecoder(f) + decoder.KnownFields(true) + decodeErr := decoder.Decode(&toplevel) + if decodeErr != nil { + return err + } + f.Close() + + configs = append(configs, toplevel) } - if len(toplevel.ImageTypes) > 0 { - d.imageTypes = make(map[string]ImageTypeYAML, len(toplevel.ImageTypes)) - for name := range toplevel.ImageTypes { - v := toplevel.ImageTypes[name] + + imageTypes := make(map[string]ImageTypeYAML) + for _, cfg := range configs { + for name, v := range cfg.ImageTypes { + if _, exists := d.imageTypes[name]; exists { + return fmt.Errorf("duplicate image type %s found", name) + } v.name = name if err := v.runTemplates(d); err != nil { return err @@ -291,10 +305,19 @@ func (d *DistroYAML) LoadImageTypes() error { return err } - d.imageTypes[name] = v + imageTypes[name] = v + } + + if d.imageConfig == nil && (cfg.ImageConfig.Default != nil) { + d.imageConfig = cfg.ImageConfig.For(d.ID) } + + } + + if len(imageTypes) > 0 { + d.imageTypes = imageTypes } - d.imageConfig = toplevel.ImageConfig.For(d.ID) + return nil } From d28eae24243ea6ed146406152cbbd133a9ed4035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20V=C3=ADtov=C3=A1?= Date: Thu, 12 Mar 2026 11:03:08 +0100 Subject: [PATCH 2/5] distrodefs: move image_config to distro YAML Move the image config field from the image types yaml into distro definitions. Allow image types to contain only definitions of image types. --- data/distrodefs/fedora.yaml | 11 ++++ data/distrodefs/fedora/imagetypes.yaml | 11 ---- data/distrodefs/rhel-10/imagetypes.yaml | 19 ------- data/distrodefs/rhel-7/imagetypes.yaml | 17 ------ data/distrodefs/rhel-8/imagetypes.yaml | 20 ------- data/distrodefs/rhel-9/imagetypes.yaml | 19 ------- data/distrodefs/rhel.yaml | 73 +++++++++++++++++++++++++ pkg/distro/defs/loader.go | 20 +++---- pkg/distro/defs/loader_test.go | 35 +++++++----- 9 files changed, 115 insertions(+), 110 deletions(-) diff --git a/data/distrodefs/fedora.yaml b/data/distrodefs/fedora.yaml index 2838174319..d98050f8c3 100644 --- a/data/distrodefs/fedora.yaml +++ b/data/distrodefs/fedora.yaml @@ -42,6 +42,17 @@ distros: # we will need to update two places which is clearly a regression from # before. + image_config: + default: + default_oscap_datastream: "/usr/share/xml/scap/ssg/content/ssg-fedora-ds.xml" + hostname: "localhost.localdomain" + install_weak_deps: true + locale: "C.UTF-8" + machine_id_uninitialized: true + timezone: "UTC" + default_kernel: "kernel-core" + update_default_kernel: true + - &fedora_stable <<: *fedora_rawhide name: "fedora-{{.MajorVersion}}" diff --git a/data/distrodefs/fedora/imagetypes.yaml b/data/distrodefs/fedora/imagetypes.yaml index e14ca52682..24cecc219a 100644 --- a/data/distrodefs/fedora/imagetypes.yaml +++ b/data/distrodefs/fedora/imagetypes.yaml @@ -1260,17 +1260,6 @@ blueprint: supported_options: *supported_options_ostree_disk -image_config: - default: - default_oscap_datastream: "/usr/share/xml/scap/ssg/content/ssg-fedora-ds.xml" - hostname: "localhost.localdomain" - install_weak_deps: true - locale: "C.UTF-8" - machine_id_uninitialized: true - timezone: "UTC" - default_kernel: "kernel-core" - update_default_kernel: true - image_types: "generic-vagrant-libvirt": &generic_vagrant_libvirt filename: "vagrant-libvirt.box" diff --git a/data/distrodefs/rhel-10/imagetypes.yaml b/data/distrodefs/rhel-10/imagetypes.yaml index 7fcfe947f4..ed8b277cc2 100644 --- a/data/distrodefs/rhel-10/imagetypes.yaml +++ b/data/distrodefs/rhel-10/imagetypes.yaml @@ -869,25 +869,6 @@ - "customizations.timezone" -image_config: - default: - default_kernel: "kernel" - default_oscap_datastream: "/usr/share/xml/scap/ssg/content/ssg-rhel10-ds.xml" - install_weak_deps: true - locale: "C.UTF-8" - permissive_rhc: true - sysconfig: - networking: true - no_zero_conf: true - timezone: "UTC" - update_default_kernel: true - conditions: - "centos oscap datastream path": - when: - distro_name: "centos" - shallow_merge: - default_oscap_datastream: "/usr/share/xml/scap/ssg/content/ssg-cs10-ds.xml" - image_types: # XXX: not a real pkgset but the "os" pipeline pkgset for image-installer # find a nicer way to represent this diff --git a/data/distrodefs/rhel-7/imagetypes.yaml b/data/distrodefs/rhel-7/imagetypes.yaml index 59f07c4972..4ef6a20f2b 100644 --- a/data/distrodefs/rhel-7/imagetypes.yaml +++ b/data/distrodefs/rhel-7/imagetypes.yaml @@ -236,23 +236,6 @@ - "customizations.timezone" - "customizations.sshd" -image_config: - default: - timezone: "America/New_York" - locale: "en_US.UTF-8" - gpgkey_files: - - "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release" - sysconfig: - networking: true - no_zero_conf: true - create_default_network_scripts: true - default_kernel: "kernel" - update_default_kernel: true - kernel_options_bootloader: true - # RHEL 7 grub does not support BLS - no_bls: true - install_weak_deps: true - image_types: "azure-rhui": filename: "disk.vhd.xz" diff --git a/data/distrodefs/rhel-8/imagetypes.yaml b/data/distrodefs/rhel-8/imagetypes.yaml index 41738b4988..db2da955c5 100644 --- a/data/distrodefs/rhel-8/imagetypes.yaml +++ b/data/distrodefs/rhel-8/imagetypes.yaml @@ -1331,26 +1331,6 @@ ref: &ostree_edge_ref "{{.Distro.Name}}/{{.Distro.MajorVersion}}/{{.Arch}}/edge" -image_config: - default: - default_kernel: "kernel" - default_oscap_datastream: "/usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml" - install_weak_deps: true - kernel_options_bootloader: true - locale: "en_US.UTF-8" - permissive_rhc: false - sysconfig: - networking: true - no_zero_conf: true - timezone: "America/New_York" - update_default_kernel: true - conditions: - "centos has a different oscap path": - when: - distro_name: "centos" - shallow_merge: - default_oscap_datastream: "/usr/share/xml/scap/ssg/content/ssg-centos8-ds.xml" - image_types: # XXX: not a real pkgset but the "os" pipeline pkgset for image-installer # find a nicer way to represent this diff --git a/data/distrodefs/rhel-9/imagetypes.yaml b/data/distrodefs/rhel-9/imagetypes.yaml index c526aef84b..57d8b4cd7d 100644 --- a/data/distrodefs/rhel-9/imagetypes.yaml +++ b/data/distrodefs/rhel-9/imagetypes.yaml @@ -1344,25 +1344,6 @@ remote_name: "rhel-edge" ref: &ostree_edge_ref "{{.Distro.Name}}/{{.Distro.MajorVersion}}/{{.Arch}}/edge" -image_config: - default: - default_kernel: "kernel" - default_oscap_datastream: "/usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml" - install_weak_deps: true - locale: "C.UTF-8" - permissive_rhc: true - sysconfig: - networking: true - no_zero_conf: true - timezone: "America/New_York" - update_default_kernel: true - conditions: - "oscap needs a differnt path on centos": - when: - distro_name: "centos" - shallow_merge: - default_oscap_datastream: "/usr/share/xml/scap/ssg/content/ssg-cs9-ds.xml" - image_types: # XXX: not a real pkgset but the "os" pipeline pkgset for image-installer # find a nicer way to represent this diff --git a/data/distrodefs/rhel.yaml b/data/distrodefs/rhel.yaml index 7369310756..0aeca60c9b 100644 --- a/data/distrodefs/rhel.yaml +++ b/data/distrodefs/rhel.yaml @@ -70,6 +70,24 @@ distros: aarch64: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest" ppc64le: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest" s390x: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest" + image_config: + default: + default_kernel: "kernel" + default_oscap_datastream: "/usr/share/xml/scap/ssg/content/ssg-rhel10-ds.xml" + install_weak_deps: true + locale: "C.UTF-8" + permissive_rhc: true + sysconfig: + networking: true + no_zero_conf: true + timezone: "UTC" + update_default_kernel: true + conditions: + "centos oscap datastream path": + when: + distro_name: "centos" + shallow_merge: + default_oscap_datastream: "/usr/share/xml/scap/ssg/content/ssg-cs10-ds.xml" - <<: *rhel10 name: "almalinux-{{.MajorVersion}}.{{.MinorVersion}}" @@ -199,6 +217,25 @@ distros: ppc64le: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest" s390x: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest" + image_config: + default: + default_kernel: "kernel" + default_oscap_datastream: "/usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml" + install_weak_deps: true + locale: "C.UTF-8" + permissive_rhc: true + sysconfig: + networking: true + no_zero_conf: true + timezone: "America/New_York" + update_default_kernel: true + conditions: + "oscap needs a differnt path on centos": + when: + distro_name: "centos" + shallow_merge: + default_oscap_datastream: "/usr/share/xml/scap/ssg/content/ssg-cs9-ds.xml" + - <<: *rhel9 name: "almalinux-{{.MajorVersion}}.{{.MinorVersion}}" match: 'almalinux-9\.[0-9]{1,2}' @@ -314,6 +351,26 @@ distros: ppc64le: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest" s390x: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest" + image_config: + default: + default_kernel: "kernel" + default_oscap_datastream: "/usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml" + install_weak_deps: true + kernel_options_bootloader: true + locale: "en_US.UTF-8" + permissive_rhc: false + sysconfig: + networking: true + no_zero_conf: true + timezone: "America/New_York" + update_default_kernel: true + conditions: + "centos has a different oscap path": + when: + distro_name: "centos" + shallow_merge: + default_oscap_datastream: "/usr/share/xml/scap/ssg/content/ssg-centos8-ds.xml" + - <<: *rhel8 name: "almalinux-{{.MajorVersion}}.{{.MinorVersion}}" match: 'almalinux-8\.[0-9]{1,2}' @@ -373,6 +430,22 @@ distros: x86_64: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest" ppc64le: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest" s390x: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest" + image_config: + default: + timezone: "America/New_York" + locale: "en_US.UTF-8" + gpgkey_files: + - "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release" + sysconfig: + networking: true + no_zero_conf: true + create_default_network_scripts: true + default_kernel: "kernel" + update_default_kernel: true + kernel_options_bootloader: true + # RHEL 7 grub does not support BLS + no_bls: true + install_weak_deps: true # Note that this will not be visible by default because we do not # ship with a reporegistry that contains repositories for it. It diff --git a/pkg/distro/defs/loader.go b/pkg/distro/defs/loader.go index b746be3255..085c635fb6 100644 --- a/pkg/distro/defs/loader.go +++ b/pkg/distro/defs/loader.go @@ -94,7 +94,7 @@ type DistroYAML struct { imageTypes map[string]ImageTypeYAML // distro wide default image config - imageConfig *distro.ImageConfig `yaml:"default"` + DistroImageConfig *distroImageConfig `yaml:"image_config,omitempty"` // ignore the given image types & override tweaks Conditions map[string]distroConditions `yaml:"conditions"` @@ -119,7 +119,10 @@ func (d *DistroYAML) ImageTypes() map[string]ImageTypeYAML { // // Each ImageType gets this as their default ImageConfig. func (d *DistroYAML) ImageConfig() *distro.ImageConfig { - return d.imageConfig + if d.DistroImageConfig != nil { + return d.DistroImageConfig.For(d.ID) + } + return nil } func (d *DistroYAML) SkipImageType(imgTypeName, archName string) bool { @@ -284,7 +287,8 @@ func (d *DistroYAML) LoadImageTypes() error { decoder.KnownFields(true) decodeErr := decoder.Decode(&toplevel) if decodeErr != nil { - return err + f.Close() + return decodeErr } f.Close() @@ -307,11 +311,6 @@ func (d *DistroYAML) LoadImageTypes() error { imageTypes[name] = v } - - if d.imageConfig == nil && (cfg.ImageConfig.Default != nil) { - d.imageConfig = cfg.ImageConfig.For(d.ID) - } - } if len(imageTypes) > 0 { @@ -325,9 +324,8 @@ func (d *DistroYAML) LoadImageTypes() error { // family. Note that multiple distros may use the same image types, // e.g. centos/rhel type imageTypesYAML struct { - ImageConfig distroImageConfig `yaml:"image_config,omitempty"` - ImageTypes map[string]ImageTypeYAML `yaml:"image_types"` - Common map[string]any `yaml:".common,omitempty"` + ImageTypes map[string]ImageTypeYAML `yaml:"image_types"` + Common map[string]any `yaml:".common,omitempty"` } type distroImageConfig struct { diff --git a/pkg/distro/defs/loader_test.go b/pkg/distro/defs/loader_test.go index ecc7d72f49..78ae0bc185 100644 --- a/pkg/distro/defs/loader_test.go +++ b/pkg/distro/defs/loader_test.go @@ -627,25 +627,32 @@ image_types: func TestDefsDistroImageConfig(t *testing.T) { fakeDistroYaml := ` -image_config: - default: - locale: "C.UTF-8" - timezone: "DefaultTZ" - users: - - name: testuser - conditions: - "some description": - when: - distro_name: "test-distro" - shallow_merge: +distros: + - name: test-distro-1 + vendor: test-vendor + defs_path: test-distro-1/ + image_config: + default: + locale: "C.UTF-8" timezone: "OverrideTZ" + users: + - name: testuser + conditions: + "centos oscap datastream path": + when: + distro_name: "centos" + shallow_merge: + timezone: "OverrideTZ" +` + fakeImageTypeYaml := ` image_types: test_type: filename: foo ` - makeTestImageType(t, fakeDistroYaml) - + baseDir := makeFakeDistrosYAML(t, fakeDistroYaml, fakeImageTypeYaml) + restore := defs.MockDataFS(baseDir) + defer restore() dist, err := defs.NewDistroYAML("test-distro-1") assert.NoError(t, err) assert.Equal(t, dist.ImageConfig(), &distro.ImageConfig{ @@ -1284,6 +1291,7 @@ distros: os_version: "{{.MajorVersion}}.{{.MinorVersion}}" release_version: "{{.MajorVersion}}" module_platform_id: "platform:el{{.MajorVersion}}" + defs_path: rhel-8 ` baseDir := makeFakeDistrosYAML(t, fakeDistrosYAML, "") restore := defs.MockDataFS(baseDir) @@ -1309,6 +1317,7 @@ distros: OsVersion: tc.expectedOsVersion, ReleaseVersion: "8", ModulePlatformID: "platform:el8", + DefsPath: "rhel-8", ID: *common.Must(distro.ParseID(tc.expectedDistroNameVer)), }) } From fbe5553d0a695bb2192a52e33e01fdfd26ab1c3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20V=C3=ADtov=C3=A1?= Date: Mon, 9 Mar 2026 10:46:47 +0100 Subject: [PATCH 3/5] data/distrodefs: remove unused anchor blocks Remove anchors defined in imagetypes.yaml that were not used anywhere in the yaml. --- data/distrodefs/fedora/imagetypes.yaml | 39 -------------------------- 1 file changed, 39 deletions(-) diff --git a/data/distrodefs/fedora/imagetypes.yaml b/data/distrodefs/fedora/imagetypes.yaml index 24cecc219a..0f0692eb0d 100644 --- a/data/distrodefs/fedora/imagetypes.yaml +++ b/data/distrodefs/fedora/imagetypes.yaml @@ -21,14 +21,6 @@ - "smartmontools" - "smartmontools-selinux" - server_host_pkgset: &server_host_pkgset - include: - - "@container-management" - - "@server-hardware-support" - - "dracut-config-rescue" - - "kernel" - - "linux-firmware" - cloud_core_pkgset: &cloud_core_pkgset include: - "@cloud-server-environment" @@ -470,36 +462,6 @@ - "grub2-ppc64le" - "grub2-ppc64le-modules" bootloader: "grub2" - ppc64le_installer_platform: &ppc64le_installer_platform - <<: *ppc64le_bios_platform - image_format: "qcow2" - packages: - <<: *ppc64le_bios_platform_packages - booting: - - "lsvpd" - - "ppc64-diag" - - "grub2-tools" - - "grub2-tools-minimal" - - "grub2-tools-extra" - firmware: - - "amd-gpu-firmware" - - "atheros-firmware" - - "atmel-firmware" - - "b43-openfwwf" - - "brcmfmac-firmware" - - "intel-gpu-firmware" - - "iwlegacy-firmware" - - "iwlwifi-dvm-firmware" - - "iwlwifi-mvm-firmware" - - "libertas-firmware" - - "linux-firmware" - - "mt7xxx-firmware" - - "nvidia-gpu-firmware" - - "nxpwireless-firmware" - - "qed-firmware" - - "realtek-firmware" - - "tiwilink-firmware" - - "zd1211-firmware" s390x_zipl_platform: &s390x_zipl_platform arch: "s390x" zipl_support: true @@ -637,7 +599,6 @@ - &root_partition_guid_x86_64 "4f68bce3-e8cd-4db1-96e7-fbcaf984b709" - &root_partition_guid_aarch64 "b921b045-1df0-41c3-af44-4c6f280d3fae" - &root_partition_guid_ppc64le "c31c45e6-3f39-412e-80fb-4809c4980599" - - &root_partition_guid_s390x "5eead9a9-fe09-4a1e-a1d7-520d00531306" # the invidual partitions for easier composibility partitions: From 5b6377356e66a46aa2bab99721f1ca4467b08765 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20V=C3=ADtov=C3=A1?= Date: Mon, 9 Mar 2026 11:42:49 +0100 Subject: [PATCH 4/5] distrodefs: remove unused default_kernel_options Remove the default_kernel_options which was unused for fedora, and had also a typo. --- data/distrodefs/fedora/imagetypes.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/data/distrodefs/fedora/imagetypes.yaml b/data/distrodefs/fedora/imagetypes.yaml index 0f0692eb0d..9745289bf3 100644 --- a/data/distrodefs/fedora/imagetypes.yaml +++ b/data/distrodefs/fedora/imagetypes.yaml @@ -296,8 +296,6 @@ - "cloud-init-local.service" kernel_options: - default_kernel_optons: - - "ro" generic_kernel_options: &generic_kernel_options - "no_timer_check" - "console=tty1" From d30485ed24479f526b9624ff99169c7b37af5eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20V=C3=ADtov=C3=A1?= Date: Fri, 13 Mar 2026 19:00:19 +0100 Subject: [PATCH 5/5] distrodefs: prepend a common file to all img types Add a logic for prepending a file _common.yaml in front of other yaml image types. Allow splitting yaml files while keeping common anchors. --- pkg/distro/defs/loader.go | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/pkg/distro/defs/loader.go b/pkg/distro/defs/loader.go index 085c635fb6..d297c70371 100644 --- a/pkg/distro/defs/loader.go +++ b/pkg/distro/defs/loader.go @@ -5,6 +5,7 @@ import ( "bytes" "errors" "fmt" + "io" "io/fs" "os" "path/filepath" @@ -270,31 +271,50 @@ func LoadDistroWithoutImageTypes(nameVer string) (*DistroYAML, error) { } func (d *DistroYAML) LoadImageTypes() error { - files, err := fs.Glob(dataFS(), filepath.Join(d.DefsPath, "*.yaml")) + configs, err := loadImageTypeConfigs(d) if err != nil { return err } + return mergeImageTypeConfigs(d, configs) +} + +func loadImageTypeConfigs(d *DistroYAML) ([]imageTypesYAML, error) { + files, err := fs.Glob(dataFS(), filepath.Join(d.DefsPath, "[^_]*.yaml")) + if err != nil { + return nil, err + } + + commonPath := filepath.Join(d.DefsPath, "_common.yaml") + commonContent, _ := fs.ReadFile(dataFS(), commonPath) - var configs []imageTypesYAML + configs := make([]imageTypesYAML, 0, len(files)) for _, fileName := range files { f, err := dataFS().Open(fileName) if err != nil { - return err + return nil, err + } + defer f.Close() + + var reader io.Reader = f + if len(commonContent) > 0 { + reader = io.MultiReader(bytes.NewReader(commonContent), f) } var toplevel imageTypesYAML - decoder := yaml.NewDecoder(f) + decoder := yaml.NewDecoder(reader) decoder.KnownFields(true) decodeErr := decoder.Decode(&toplevel) if decodeErr != nil { - f.Close() - return decodeErr + return nil, err } - f.Close() configs = append(configs, toplevel) } + return configs, nil +} + +func mergeImageTypeConfigs(d *DistroYAML, configs []imageTypesYAML) error { imageTypes := make(map[string]ImageTypeYAML) for _, cfg := range configs { for name, v := range cfg.ImageTypes {