From 1fafdbfaab955a164eb7b1fb1aa2f500c2a718f1 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 2 Sep 2025 13:56:47 +0200 Subject: [PATCH 1/7] bib: add bibcontainer.Arch helper We always have a local and running container with bib so we can figure out the architecture for it. This is useful for the bootc distro because with that we can create the correct distro/arch/imagetypes combination. Note that some images (like ubi9) do not show the architecture when inspecting the image. So we need a `podman exec uname -m` fallback for those. Note also that it would be nice in the future to inspect for multi arch images and actually populate the bootc distro with the correct architectures. But that is tricky as we currently introspect (run) each container so we would have to download/run all the distros just to do the inspection. This is generally not possible (without qemu-user) and certainly not practical. --- pkg/bib/container/container.go | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/pkg/bib/container/container.go b/pkg/bib/container/container.go index 634738ee02..59a7aaae77 100644 --- a/pkg/bib/container/container.go +++ b/pkg/bib/container/container.go @@ -2,6 +2,7 @@ package container import ( "encoding/json" + "errors" "fmt" "os" "os/exec" @@ -16,6 +17,7 @@ import ( type Container struct { id string root string + arch string } // New creates a new running container from the given image reference. @@ -62,6 +64,15 @@ func New(ref string) (*Container, error) { c = nil } }() + // not all containers set {{.Architecture}} so fallback + c.arch, err = findContainerArchInspect(c.id, ref) + if err != nil { + var err2 error + c.arch, err2 = findContainerArchUname(c.id, ref) + if err2 != nil { + return nil, errors.Join(err, err2) + } + } /* #nosec G204 */ output, err = exec.Command("podman", "mount", c.id).Output() @@ -98,6 +109,11 @@ func (c *Container) Root() string { return c.root } +// Arch returns the architecture of the container +func (c *Container) Arch() string { + return c.arch +} + // Reads a file from the container func (c *Container) ReadFile(path string) ([]byte, error) { /* #nosec G204 */ @@ -168,3 +184,27 @@ func (c *Container) DefaultRootfsType() (string, error) { return fsType, nil } + +func findContainerArchInspect(cntId, ref string) (string, error) { + /* #nosec G204 */ + output, err := exec.Command("podman", "inspect", "-f", "{{.Architecture}}", cntId).Output() + if err != nil { + if err, ok := err.(*exec.ExitError); ok { + return "", fmt.Errorf("inspecting container %q failed: %w\nstderr:\n%s", ref, err, err.Stderr) + } + return "", fmt.Errorf("inspecting %s container failed with generic error: %w", ref, err) + } + return strings.TrimSpace(string(output)), nil +} + +func findContainerArchUname(cntId, ref string) (string, error) { + /* #nosec G204 */ + output, err := exec.Command("podman", "exec", cntId, "uname", "-m").Output() + if err != nil { + if err, ok := err.(*exec.ExitError); ok { + return "", fmt.Errorf("running 'uname -m' from container %q failed: %w\nstderr:\n%s", cntId, err, err.Stderr) + } + return "", fmt.Errorf("running 'uname -m' from container %q failed with generic error: %w", cntId, err) + } + return strings.TrimSpace(string(output)), nil +} From a3527bb87464c2c8b709b6a0a4113fe99a8f8dfd Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 2 Sep 2025 10:45:35 +0200 Subject: [PATCH 2/7] gen-manifests: add panic() handler The current gen-manifest behavior is to not catch panics. In part this is nice as it gives the full backtrace. But it also lacks lots of content as the panic happens without knowing for what image type. So instead just handle a panic like an error and how the image type that paniced and the error. --- cmd/gen-manifests/main.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cmd/gen-manifests/main.go b/cmd/gen-manifests/main.go index 1b48196097..f9f0b1d64e 100644 --- a/cmd/gen-manifests/main.go +++ b/cmd/gen-manifests/main.go @@ -258,6 +258,11 @@ func makeManifestJob( } msgq <- msg }() + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("[%s] failed with panic: %s", filename, r) + } + }() msgq <- fmt.Sprintf("Starting job %s", filename) manifest, _, err := imgType.Manifest(&bp, options, repos, &seedArg) From 7fd80f63fc695d1d618fda9b533f02e5c57c5e7d Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 1 Sep 2025 10:14:34 +0200 Subject: [PATCH 3/7] gen-manifests: use json.NewDecoder() instead of io.ReadAll Tiny cleanup to use the json.NewDecoder() instead of getting all the data first and then passing it to json.Unmarshal(). This is a bit more efficient and also slightly shorter (and more idiomatic). --- cmd/gen-manifests/main.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/cmd/gen-manifests/main.go b/cmd/gen-manifests/main.go index f9f0b1d64e..dc56a574c2 100644 --- a/cmd/gen-manifests/main.go +++ b/cmd/gen-manifests/main.go @@ -10,7 +10,6 @@ import ( "encoding/json" "flag" "fmt" - "io" "os" "path/filepath" "strings" @@ -141,12 +140,9 @@ func loadConfigMap(configPath string, opts *buildconfig.Options) *BuildConfigs { panic(fmt.Sprintf("failed to open config map %q: %s", configPath, err.Error())) } defer fp.Close() - data, err := io.ReadAll(fp) - if err != nil { - panic(fmt.Sprintf("failed to read config map %q: %s", configPath, err.Error())) - } + var cfgMap configMap - if err := json.Unmarshal(data, &cfgMap); err != nil { + if err := json.NewDecoder(fp).Decode(&cfgMap); err != nil { panic(fmt.Sprintf("failed to unmarshal config map %q: %s", configPath, err.Error())) } From 45301646559d16990eefd361e55c0556c861991b Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 16 Jul 2025 09:32:05 +0200 Subject: [PATCH 4/7] many: add support to generate bootc fake manifests This commit adds support to generate fake manifests for bootc. This a bit different from how this work for rpm based distros. There the distro/arch/imgtype/blueprint is enough to fully describe an image. However in the bootc world the container is inspected for various inputs as well so we need a (fast) way to provide the inputs from the inspection. We could build fake containers but it would still be a bit on the slow side. So instead we define a new `test/bootc-fake-containers.yaml` that can be used to create a bunch of fake bootc inputs as if those are read from the image itself. With that we can (re)use the normal `config-map.json` mechanism to get all the "bootc-*" distros and apply the customizations. Note that this adds some (f)ugly: ``` bootc.NewBootcForTesting() bootc.BootcDistro.SetBuildContainerForTesting() ``` this is unavoidable if we want to use this approach for testing. We could move to this testing to the `booctest` fake containers approach from https://github.com/osbuild/images/pull/1828 The downside is slightly slower fake image generation and that we need to run this all as root because we need "podman container mount" for the introspection to work (this is a big downside as it will generate root owned manifest checksums). --- cmd/gen-manifests/main.go | 68 ++++++++++++++++++++- pkg/bib/osinfo/osinfo.go | 6 +- pkg/distro/bootc/bootc.go | 101 +++++++++++++++++--------------- test/bootc-fake-containers.yaml | 25 ++++++++ test/config-map.json | 5 ++ tools/gen-manifests-diff | 2 +- 6 files changed, 156 insertions(+), 51 deletions(-) create mode 100644 test/bootc-fake-containers.yaml diff --git a/cmd/gen-manifests/main.go b/cmd/gen-manifests/main.go index dc56a574c2..2f793234d8 100644 --- a/cmd/gen-manifests/main.go +++ b/cmd/gen-manifests/main.go @@ -16,10 +16,13 @@ import ( "time" "github.com/gobwas/glob" + "gopkg.in/yaml.v3" "github.com/osbuild/blueprint/pkg/blueprint" "github.com/osbuild/images/internal/buildconfig" "github.com/osbuild/images/internal/cmdutil" + "github.com/osbuild/images/pkg/arch" + "github.com/osbuild/images/pkg/bib/osinfo" "github.com/osbuild/images/pkg/container" "github.com/osbuild/images/pkg/depsolvednf" "github.com/osbuild/images/pkg/distro" @@ -396,10 +399,11 @@ func main() { flag.BoolVar(&buildconfigAllowUnknown, "buildconfig-allow-unknown", false, "allow unknown keys in buildconfig") // content args - var packages, containers, commits bool + var packages, containers, commits, fakeBootc bool flag.BoolVar(&packages, "packages", true, "depsolve package sets") flag.BoolVar(&containers, "containers", true, "resolve container checksums") flag.BoolVar(&commits, "commits", false, "resolve ostree commit IDs") + flag.BoolVar(&fakeBootc, "fake-bootc", false, "create fake bootc containers based on test/bootc-fake-containers.yaml") // manifest selection args var arches, distros, imgTypes, bootcRefs cmdutil.MultiValue @@ -569,6 +573,68 @@ func main() { } } } + if fakeBootc { + p := "test/bootc-fake-containers.yaml" + f, err := os.Open(p) + if err != nil { + panic(fmt.Errorf("cannot find %q", p)) + } + defer f.Close() + type fakeBootcContainerYAML struct { + Arch arch.Arch `yaml:"arch"` + Info osinfo.Info `yaml:"info"` + DefaultFs string `yaml:"default_fs"` + ContainerSize uint64 `yaml:"container_size"` + ImageRef string `yaml:"image_ref"` + } + type fakeContainersYAML struct { + Containers []fakeBootcContainerYAML + } + var fakeContainers fakeContainersYAML + dec := yaml.NewDecoder(f) + dec.KnownFields(true) + if err := dec.Decode(&fakeContainers); err != nil { + panic(err) + } + for _, fakeBootcCnt := range fakeContainers.Containers { + distribution, err := bootc.NewBootcDistroForTesting(fakeBootcCnt.Arch.String(), &fakeBootcCnt.Info, fakeBootcCnt.ImageRef, fakeBootcCnt.DefaultFs, fakeBootcCnt.ContainerSize) + if err != nil { + panic(err) + } + arches, _ := arches.ResolveArgValues(distribution.ListArches()) + for _, archName := range arches { + archi, err := distribution.GetArch(archName) + if err != nil { + panic(err) + } + imgTypes, _ := imgTypes.ResolveArgValues(archi.ListImageTypes()) + for _, imgTypeName := range imgTypes { + imgType, err := archi.GetImageType(imgTypeName) + if err != nil { + panic(err) + } + // XXX: copied from loop above + imgTypeConfigs := configs.Get(distribution.Name(), archName, imgTypeName) + if len(imgTypeConfigs) == 0 { + if skipNoconfig { + continue + } + panic(fmt.Sprintf("no configs defined for image type %q for %s/%s", imgTypeName, distribution.Name(), archi.Name())) + } + for _, itConfig := range imgTypeConfigs { + if needsSkipping, reason := configs.needsSkipping(distribution.Name(), itConfig); needsSkipping { + fmt.Printf("Skipping %s for %s/%s (reason: %v)\n", itConfig.Name, imgTypeName, distribution.Name(), reason) + continue + } + + var repos []rpmmd.RepoConfig + job := makeManifestJob(itConfig, imgType, distribution, repos, archName, cacheRoot, outputDir, contentResolve, metadata, tmpdirRoot) + jobs = append(jobs, job) + } + } + } + } + } nJobs := len(jobs) fmt.Printf("Collected %d jobs\n", nJobs) diff --git a/pkg/bib/osinfo/osinfo.go b/pkg/bib/osinfo/osinfo.go index 3fabf5bfff..046192be1b 100644 --- a/pkg/bib/osinfo/osinfo.go +++ b/pkg/bib/osinfo/osinfo.go @@ -35,9 +35,9 @@ type KernelInfo struct { } type Info struct { - OSRelease OSRelease - UEFIVendor string - SELinuxPolicy string + OSRelease OSRelease `yaml:"os_release"` + UEFIVendor string `yaml:"uefi_vendor"` + SELinuxPolicy string `yaml:"selinux_policy"` ImageCustomization *blueprint.Customizations KernelInfo *KernelInfo diff --git a/pkg/distro/bootc/bootc.go b/pkg/distro/bootc/bootc.go index 8888c10be2..341c450739 100644 --- a/pkg/distro/bootc/bootc.go +++ b/pkg/distro/bootc/bootc.go @@ -368,7 +368,7 @@ func (t *BootcImageType) Manifest(bp *blueprint.Blueprint, options distro.ImageO // newBootcDistro returns a new instance of BootcDistro // from the given url -func NewBootcDistro(imgref string) (bd *BootcDistro, err error) { +func NewBootcDistro(imgref string) (*BootcDistro, error) { cnt, err := bibcontainer.New(imgref) if err != nil { return nil, err @@ -381,7 +381,6 @@ func NewBootcDistro(imgref string) (bd *BootcDistro, err error) { if err != nil { return nil, err } - // XXX: provide a way to set defaultfs (needed for bib) defaultFs, err := cnt.DefaultRootfsType() if err != nil { @@ -391,9 +390,12 @@ func NewBootcDistro(imgref string) (bd *BootcDistro, err error) { if err != nil { return nil, fmt.Errorf("cannot get container size: %w", err) } + return newBootcDistroAfterIntrospect(cnt.Arch(), info, imgref, defaultFs, cntSize) +} +func newBootcDistroAfterIntrospect(archStr string, info *osinfo.Info, imgref, defaultFs string, cntSize uint64) (*BootcDistro, error) { nameVer := fmt.Sprintf("bootc-%s-%s", info.OSRelease.ID, info.OSRelease.VersionID) - bd = &BootcDistro{ + bd := &BootcDistro{ name: nameVer, releasever: info.OSRelease.VersionID, defaultFs: defaultFs, @@ -407,54 +409,61 @@ func NewBootcDistro(imgref string) (bd *BootcDistro, err error) { buildSourceInfo: info, } - for _, archStr := range []string{"x86_64", "aarch64", "ppc64le", "s390x", "riscv64"} { - ba := &BootcArch{ - arch: common.Must(arch.FromString(archStr)), - } - // TODO: add iso image types, see bootc-image-builder - // - // Note that the file extension is hardcoded in - // pkg/image/bootc_disk.go, we have no way to access - // it here so we need to duplicate it - // XXX: find a way to avoid this duplication - ba.addImageTypes( - BootcImageType{ - name: "ami", - export: "image", - ext: "raw", - }, - BootcImageType{ - name: "qcow2", - export: "qcow2", - ext: "qcow2", - }, - BootcImageType{ - name: "raw", - export: "image", - ext: "raw", - }, - BootcImageType{ - name: "vmdk", - export: "vmdk", - ext: "vmdk", - }, - BootcImageType{ - name: "vhd", - export: "bpc", - ext: "vhd", - }, - BootcImageType{ - name: "gce", - export: "gce", - ext: "tar.gz", - }, - ) - bd.addArches(ba) + archi, err := arch.FromString(archStr) + if err != nil { + return nil, err } + ba := &BootcArch{ + arch: archi, + } + // TODO: add iso image types, see bootc-image-builder + // + // Note that the file extension is hardcoded in + // pkg/image/bootc_disk.go, we have no way to access + // it here so we need to duplicate it + // XXX: find a way to avoid this duplication + ba.addImageTypes( + BootcImageType{ + name: "ami", + export: "image", + ext: "raw", + }, + BootcImageType{ + name: "qcow2", + export: "qcow2", + ext: "qcow2", + }, + BootcImageType{ + name: "raw", + export: "image", + ext: "raw", + }, + BootcImageType{ + name: "vmdk", + export: "vmdk", + ext: "vmdk", + }, + BootcImageType{ + name: "vhd", + export: "bpc", + ext: "vhd", + }, + BootcImageType{ + name: "gce", + export: "gce", + ext: "tar.gz", + }, + ) + bd.addArches(ba) return bd, nil } +// NewBootcDistroForTesting can be used to generate test manifests. +// The container introspection is skipped. Do not use this for +// anything but tests. +var NewBootcDistroForTesting = newBootcDistroAfterIntrospect + func DistroFactory(idStr string) distro.Distro { l := strings.SplitN(idStr, ":", 2) if l[0] != "bootc" { diff --git a/test/bootc-fake-containers.yaml b/test/bootc-fake-containers.yaml new file mode 100644 index 0000000000..c9dc1fd5b7 --- /dev/null +++ b/test/bootc-fake-containers.yaml @@ -0,0 +1,25 @@ +--- +containers: + - &default_fake_container + arch: riscv64 + info: &default_info + os_release: + id: "test-os" + versionid: "1" + image_ref: "bootc-fake-imgref" + default_fs: "ext4" + container_size: 10_000_000_000 + - <<: *default_fake_container + arch: s390x + - <<: *default_fake_container + arch: ppc64le + - <<: *default_fake_container + arch: x86_64 + info: + <<: *default_info + uefi_vendor: "uefi-vendor-x86_64" + - <<: *default_fake_container + arch: aarch64 + info: + <<: *default_info + uefi_vendor: "uefi-vendor-aarch64" diff --git a/test/config-map.json b/test/config-map.json index 8be18b5880..db8fa47120 100644 --- a/test/config-map.json +++ b/test/config-map.json @@ -526,5 +526,10 @@ "image-types": [ "vhd" ] + }, + "./configs/empty.json": { + "distros": [ + "bootc-*" + ] } } diff --git a/tools/gen-manifests-diff b/tools/gen-manifests-diff index 4d9f86d7d0..839796d79f 100755 --- a/tools/gen-manifests-diff +++ b/tools/gen-manifests-diff @@ -65,7 +65,7 @@ def manifests_diff(tmp_path, rev): cmd_new = ["go", "run", f"github.com/osbuild/images/cmd/gen-manifests@{rev}"] run_gen_manifests(cmd_new, manifests_old) - cmd_new = ["go", "run", os.fspath(top_srcdir() / "cmd/gen-manifests")] + cmd_new = ["go", "run", os.fspath(top_srcdir() / "cmd/gen-manifests"), "-bootc-refs=fake"] run_gen_manifests(cmd_new, manifests_new) ret = subprocess.run([ From 7153c127dcebda79b2d36b0cbed40fc3962c5f44 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 2 Sep 2025 14:10:19 +0200 Subject: [PATCH 5/7] test: add bootc manifest checksums Now that have the ability to generate bootc checksums, include them. --- internal/cmdutil/rand.go | 4 +++- pkg/distro/bootc/bootc.go | 11 +++++++++-- pkg/distro/bootc/export_test.go | 1 - pkg/distro/bootc/image_test.go | 13 +++++++++---- pkg/distro/bootc/util.go | 15 --------------- .../bootc_test_os_1-aarch64-ami-empty | 1 + .../bootc_test_os_1-aarch64-gce-empty | 1 + .../bootc_test_os_1-aarch64-qcow2-empty | 1 + .../bootc_test_os_1-aarch64-raw-empty | 1 + .../bootc_test_os_1-aarch64-vhd-empty | 1 + .../bootc_test_os_1-aarch64-vmdk-empty | 1 + .../bootc_test_os_1-ppc64le-ami-empty | 1 + .../bootc_test_os_1-ppc64le-gce-empty | 1 + .../bootc_test_os_1-ppc64le-qcow2-empty | 1 + .../bootc_test_os_1-ppc64le-raw-empty | 1 + .../bootc_test_os_1-ppc64le-vhd-empty | 1 + .../bootc_test_os_1-ppc64le-vmdk-empty | 1 + .../bootc_test_os_1-s390x-ami-empty | 1 + .../bootc_test_os_1-s390x-gce-empty | 1 + .../bootc_test_os_1-s390x-qcow2-empty | 1 + .../bootc_test_os_1-s390x-raw-empty | 1 + .../bootc_test_os_1-s390x-vhd-empty | 1 + .../bootc_test_os_1-s390x-vmdk-empty | 1 + .../bootc_test_os_1-x86_64-ami-empty | 1 + .../bootc_test_os_1-x86_64-gce-empty | 1 + .../bootc_test_os_1-x86_64-qcow2-empty | 1 + .../bootc_test_os_1-x86_64-raw-empty | 1 + .../bootc_test_os_1-x86_64-vhd-empty | 1 + .../bootc_test_os_1-x86_64-vmdk-empty | 1 + tools/gen-manifest-checksums.sh | 1 + tools/gen-manifests-diff | 2 +- 31 files changed, 47 insertions(+), 24 deletions(-) create mode 100644 test/data/manifest-checksums/bootc_test_os_1-aarch64-ami-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-aarch64-gce-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-aarch64-qcow2-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-aarch64-raw-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-aarch64-vhd-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-aarch64-vmdk-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-ppc64le-ami-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-ppc64le-gce-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-ppc64le-qcow2-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-ppc64le-raw-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-ppc64le-vhd-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-ppc64le-vmdk-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-s390x-ami-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-s390x-gce-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-s390x-qcow2-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-s390x-raw-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-s390x-vhd-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-s390x-vmdk-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-x86_64-ami-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-x86_64-gce-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-x86_64-qcow2-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-x86_64-raw-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-x86_64-vhd-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_1-x86_64-vmdk-empty diff --git a/internal/cmdutil/rand.go b/internal/cmdutil/rand.go index b4ea8c13bd..ee5a5e36b0 100644 --- a/internal/cmdutil/rand.go +++ b/internal/cmdutil/rand.go @@ -42,7 +42,9 @@ func SeedArgFor(bc *buildconfig.BuildConfig, imgTypeName, distributionName, arch h.Write([]byte(distributionName)) h.Write([]byte(archName)) h.Write([]byte(imgTypeName)) - h.Write([]byte(bc.Name)) + if bc != nil { + h.Write([]byte(bc.Name)) + } // nolint:gosec return rngSeed + int64(h.Sum64()), nil diff --git a/pkg/distro/bootc/bootc.go b/pkg/distro/bootc/bootc.go index 341c450739..84eec59f48 100644 --- a/pkg/distro/bootc/bootc.go +++ b/pkg/distro/bootc/bootc.go @@ -3,11 +3,13 @@ package bootc import ( "errors" "fmt" + "math/rand" "sort" "strings" "github.com/osbuild/blueprint/pkg/blueprint" + "github.com/osbuild/images/internal/cmdutil" "github.com/osbuild/images/internal/common" "github.com/osbuild/images/pkg/arch" bibcontainer "github.com/osbuild/images/pkg/bib/container" @@ -270,7 +272,6 @@ func (t *BootcImageType) Manifest(bp *blueprint.Blueprint, options distro.ImageO if t.arch.distro.imgref == "" { return nil, nil, fmt.Errorf("internal error: no base image defined") } - containerSource := container.SourceSpec{ Source: t.arch.distro.imgref, Name: t.arch.distro.imgref, @@ -286,6 +287,12 @@ func (t *BootcImageType) Manifest(bp *blueprint.Blueprint, options distro.ImageO if bp != nil { customizations = bp.Customizations } + seed, err := cmdutil.SeedArgFor(nil, t.Name(), t.arch.Name(), t.arch.distro.Name()) + if err != nil { + return nil, nil, err + } + //nolint:gosec + rng := rand.New(rand.NewSource(seed)) archi := common.Must(arch.FromString(t.arch.Name())) platform := &platform.Data{ @@ -327,7 +334,7 @@ func (t *BootcImageType) Manifest(bp *blueprint.Blueprint, options distro.ImageO } rootfsMinSize := max(t.arch.distro.rootfsMinSize, options.Size) - rng := createRand() + pt, err := t.genPartitionTable(customizations, rootfsMinSize, rng) if err != nil { return nil, nil, err diff --git a/pkg/distro/bootc/export_test.go b/pkg/distro/bootc/export_test.go index 39d35e581a..0e88c52c97 100644 --- a/pkg/distro/bootc/export_test.go +++ b/pkg/distro/bootc/export_test.go @@ -14,7 +14,6 @@ var ( CheckFilesystemCustomizations = checkFilesystemCustomizations PartitionTables = partitionTables UpdateFilesystemSizes = updateFilesystemSizes - CreateRand = createRand CalcRequiredDirectorySizes = calcRequiredDirectorySizes TestDiskContainers = diskContainers diff --git a/pkg/distro/bootc/image_test.go b/pkg/distro/bootc/image_test.go index 1cc6913c13..3d5b44493b 100644 --- a/pkg/distro/bootc/image_test.go +++ b/pkg/distro/bootc/image_test.go @@ -1,6 +1,7 @@ package bootc_test import ( + "math/rand" "testing" "github.com/stretchr/testify/assert" @@ -16,6 +17,10 @@ import ( "github.com/osbuild/images/pkg/distro/bootc" ) +func createRand() *rand.Rand { + return rand.New(rand.NewSource(0)) +} + func TestCheckFilesystemCustomizationsValidates(t *testing.T) { for _, tc := range []struct { fsCust []blueprint.FilesystemCustomization @@ -326,7 +331,7 @@ func findMountableSizeableFor(pt *disk.PartitionTable, needle string) (disk.Moun } func TestGenPartitionTableSetsRootfsForAllFilesystemsXFS(t *testing.T) { - rng := bootc.CreateRand() + rng := createRand() imgType := bootc.NewTestBootcImageType() @@ -356,7 +361,7 @@ func TestGenPartitionTableSetsRootfsForAllFilesystemsXFS(t *testing.T) { } func TestGenPartitionTableSetsRootfsForAllFilesystemsBtrfs(t *testing.T) { - rng := bootc.CreateRand() + rng := createRand() imgType := bootc.NewTestBootcImageType() err := imgType.Arch().Distro().(*bootc.BootcDistro).SetDefaultFs("btrfs") @@ -378,7 +383,7 @@ func TestGenPartitionTableSetsRootfsForAllFilesystemsBtrfs(t *testing.T) { assert.Equal(t, "vfat", mnt.GetFSType()) } func TestGenPartitionTableDiskCustomizationRunsValidateLayoutConstraints(t *testing.T) { - rng := bootc.CreateRand() + rng := createRand() imgType := bootc.NewTestBootcImageType() @@ -415,7 +420,7 @@ func TestGenPartitionTableDiskCustomizationUnknownTypesError(t *testing.T) { } func TestGenPartitionTableDiskCustomizationSizes(t *testing.T) { - rng := bootc.CreateRand() + rng := createRand() for _, tc := range []struct { name string diff --git a/pkg/distro/bootc/util.go b/pkg/distro/bootc/util.go index 1049550dcb..097d44c3ed 100644 --- a/pkg/distro/bootc/util.go +++ b/pkg/distro/bootc/util.go @@ -1,27 +1,12 @@ package bootc import ( - cryptorand "crypto/rand" "fmt" - "math" - "math/big" - "math/rand" "os/exec" "strconv" "strings" ) -func createRand() *rand.Rand { - seed, err := cryptorand.Int(cryptorand.Reader, big.NewInt(math.MaxInt64)) - if err != nil { - panic("Cannot generate an RNG seed.") - } - - // math/rand is good enough in this case - /* #nosec G404 */ - return rand.New(rand.NewSource(seed.Int64())) -} - // getContainerSize returns the size of an already pulled container image in bytes func getContainerSize(imgref string) (uint64, error) { output, err := exec.Command("podman", "image", "inspect", imgref, "--format", "{{.Size}}").Output() diff --git a/test/data/manifest-checksums/bootc_test_os_1-aarch64-ami-empty b/test/data/manifest-checksums/bootc_test_os_1-aarch64-ami-empty new file mode 100644 index 0000000000..1e7782a15e --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-aarch64-ami-empty @@ -0,0 +1 @@ +b8a2e3722b12d0327672c2ff1765c0e6cbd355df diff --git a/test/data/manifest-checksums/bootc_test_os_1-aarch64-gce-empty b/test/data/manifest-checksums/bootc_test_os_1-aarch64-gce-empty new file mode 100644 index 0000000000..28f876cae2 --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-aarch64-gce-empty @@ -0,0 +1 @@ +3c444830b05ee7e9bbf7a44494701130087e0ed0 diff --git a/test/data/manifest-checksums/bootc_test_os_1-aarch64-qcow2-empty b/test/data/manifest-checksums/bootc_test_os_1-aarch64-qcow2-empty new file mode 100644 index 0000000000..ecd163f15e --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-aarch64-qcow2-empty @@ -0,0 +1 @@ +22d208e39a11ba5feb8f586be9b3b9f8257f8263 diff --git a/test/data/manifest-checksums/bootc_test_os_1-aarch64-raw-empty b/test/data/manifest-checksums/bootc_test_os_1-aarch64-raw-empty new file mode 100644 index 0000000000..2b6dd7f2bf --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-aarch64-raw-empty @@ -0,0 +1 @@ +f4f2f3508999911db0befd41b6429ae0c0a525ab diff --git a/test/data/manifest-checksums/bootc_test_os_1-aarch64-vhd-empty b/test/data/manifest-checksums/bootc_test_os_1-aarch64-vhd-empty new file mode 100644 index 0000000000..0cc8a80962 --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-aarch64-vhd-empty @@ -0,0 +1 @@ +5b3da86b3a2abfafe5cb2d3de4acfa01ab4beebb diff --git a/test/data/manifest-checksums/bootc_test_os_1-aarch64-vmdk-empty b/test/data/manifest-checksums/bootc_test_os_1-aarch64-vmdk-empty new file mode 100644 index 0000000000..061110863a --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-aarch64-vmdk-empty @@ -0,0 +1 @@ +6a70959d7e673cde56b11b89785a2ac9dec7106c diff --git a/test/data/manifest-checksums/bootc_test_os_1-ppc64le-ami-empty b/test/data/manifest-checksums/bootc_test_os_1-ppc64le-ami-empty new file mode 100644 index 0000000000..d41569ed12 --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-ppc64le-ami-empty @@ -0,0 +1 @@ +b7ddbad816724cb66eec36cf7ca2b643d15f4c9d diff --git a/test/data/manifest-checksums/bootc_test_os_1-ppc64le-gce-empty b/test/data/manifest-checksums/bootc_test_os_1-ppc64le-gce-empty new file mode 100644 index 0000000000..97fe326f10 --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-ppc64le-gce-empty @@ -0,0 +1 @@ +ad12dee18e7f6e33b076b9377c1fd1879dcead7e diff --git a/test/data/manifest-checksums/bootc_test_os_1-ppc64le-qcow2-empty b/test/data/manifest-checksums/bootc_test_os_1-ppc64le-qcow2-empty new file mode 100644 index 0000000000..aa8944a57d --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-ppc64le-qcow2-empty @@ -0,0 +1 @@ +14d6cffd05250e0b6ac1113aa2a5cb1ccb3b33d2 diff --git a/test/data/manifest-checksums/bootc_test_os_1-ppc64le-raw-empty b/test/data/manifest-checksums/bootc_test_os_1-ppc64le-raw-empty new file mode 100644 index 0000000000..0d5facc72a --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-ppc64le-raw-empty @@ -0,0 +1 @@ +49ad8d143bbbf96bce01a029745e7bfba4d7b900 diff --git a/test/data/manifest-checksums/bootc_test_os_1-ppc64le-vhd-empty b/test/data/manifest-checksums/bootc_test_os_1-ppc64le-vhd-empty new file mode 100644 index 0000000000..ac5e7717e5 --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-ppc64le-vhd-empty @@ -0,0 +1 @@ +2d31fe3c4c747c4b5ae3094bf4182ecc8dc7caeb diff --git a/test/data/manifest-checksums/bootc_test_os_1-ppc64le-vmdk-empty b/test/data/manifest-checksums/bootc_test_os_1-ppc64le-vmdk-empty new file mode 100644 index 0000000000..24d09f7f74 --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-ppc64le-vmdk-empty @@ -0,0 +1 @@ +498f8bde1ec3ce0f704fe98ec4f8050d850d73f4 diff --git a/test/data/manifest-checksums/bootc_test_os_1-s390x-ami-empty b/test/data/manifest-checksums/bootc_test_os_1-s390x-ami-empty new file mode 100644 index 0000000000..53a7186598 --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-s390x-ami-empty @@ -0,0 +1 @@ +54bf9201635e54806ddea4cda2947fd99d7c276c diff --git a/test/data/manifest-checksums/bootc_test_os_1-s390x-gce-empty b/test/data/manifest-checksums/bootc_test_os_1-s390x-gce-empty new file mode 100644 index 0000000000..f0ac6650cb --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-s390x-gce-empty @@ -0,0 +1 @@ +c1ef1aac4823032a85371c75a111638c37e31ffe diff --git a/test/data/manifest-checksums/bootc_test_os_1-s390x-qcow2-empty b/test/data/manifest-checksums/bootc_test_os_1-s390x-qcow2-empty new file mode 100644 index 0000000000..39a1975b50 --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-s390x-qcow2-empty @@ -0,0 +1 @@ +554badbf13db66e073446315b25c8dd8ac974a9e diff --git a/test/data/manifest-checksums/bootc_test_os_1-s390x-raw-empty b/test/data/manifest-checksums/bootc_test_os_1-s390x-raw-empty new file mode 100644 index 0000000000..b7f3e6fb25 --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-s390x-raw-empty @@ -0,0 +1 @@ +465de5127abee6828a1b60a280b8630f9ac5457a diff --git a/test/data/manifest-checksums/bootc_test_os_1-s390x-vhd-empty b/test/data/manifest-checksums/bootc_test_os_1-s390x-vhd-empty new file mode 100644 index 0000000000..25adf7524d --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-s390x-vhd-empty @@ -0,0 +1 @@ +ff19bdec8c095f3d146e84498877932249aded4a diff --git a/test/data/manifest-checksums/bootc_test_os_1-s390x-vmdk-empty b/test/data/manifest-checksums/bootc_test_os_1-s390x-vmdk-empty new file mode 100644 index 0000000000..e6f371a8a3 --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-s390x-vmdk-empty @@ -0,0 +1 @@ +d634826c27a2993ef59e6bfa5a764219b2a83325 diff --git a/test/data/manifest-checksums/bootc_test_os_1-x86_64-ami-empty b/test/data/manifest-checksums/bootc_test_os_1-x86_64-ami-empty new file mode 100644 index 0000000000..26280c4641 --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-x86_64-ami-empty @@ -0,0 +1 @@ +eece2136444b81ffec6edcfb4f14f69ab7218ed4 diff --git a/test/data/manifest-checksums/bootc_test_os_1-x86_64-gce-empty b/test/data/manifest-checksums/bootc_test_os_1-x86_64-gce-empty new file mode 100644 index 0000000000..6bd85a08cc --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-x86_64-gce-empty @@ -0,0 +1 @@ +a6df8aa5feae6b9f7c35dc805baadcf292258896 diff --git a/test/data/manifest-checksums/bootc_test_os_1-x86_64-qcow2-empty b/test/data/manifest-checksums/bootc_test_os_1-x86_64-qcow2-empty new file mode 100644 index 0000000000..71790681ef --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-x86_64-qcow2-empty @@ -0,0 +1 @@ +6dc585a8846922b1d1486af70f124fb3026f20db diff --git a/test/data/manifest-checksums/bootc_test_os_1-x86_64-raw-empty b/test/data/manifest-checksums/bootc_test_os_1-x86_64-raw-empty new file mode 100644 index 0000000000..3a808d6356 --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-x86_64-raw-empty @@ -0,0 +1 @@ +6f73b578193e4b8f3fca9a7c9d408791237cadb9 diff --git a/test/data/manifest-checksums/bootc_test_os_1-x86_64-vhd-empty b/test/data/manifest-checksums/bootc_test_os_1-x86_64-vhd-empty new file mode 100644 index 0000000000..bbfe83c13c --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-x86_64-vhd-empty @@ -0,0 +1 @@ +31b7b9f7874a1d94d656028ed06a7fbcf04b9a90 diff --git a/test/data/manifest-checksums/bootc_test_os_1-x86_64-vmdk-empty b/test/data/manifest-checksums/bootc_test_os_1-x86_64-vmdk-empty new file mode 100644 index 0000000000..17e2ec0606 --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_1-x86_64-vmdk-empty @@ -0,0 +1 @@ +c2ffb4e140c7927fc51af604abd42e58e407e536 diff --git a/tools/gen-manifest-checksums.sh b/tools/gen-manifest-checksums.sh index 6e6d325ed2..8bf9882678 100755 --- a/tools/gen-manifest-checksums.sh +++ b/tools/gen-manifest-checksums.sh @@ -35,6 +35,7 @@ echo "Generating mock manifests" if ! "${tmpdir}/bin/gen-manifests" \ --packages=false --containers=false --commits=false \ --metadata=false \ + --fake-bootc=true \ --arches "x86_64,aarch64,ppc64le,s390x" \ --output "${tmpdir}/manifests" \ > /dev/null 2> "${tmpdir}/stderr"; then diff --git a/tools/gen-manifests-diff b/tools/gen-manifests-diff index 839796d79f..7d5898f79c 100755 --- a/tools/gen-manifests-diff +++ b/tools/gen-manifests-diff @@ -65,7 +65,7 @@ def manifests_diff(tmp_path, rev): cmd_new = ["go", "run", f"github.com/osbuild/images/cmd/gen-manifests@{rev}"] run_gen_manifests(cmd_new, manifests_old) - cmd_new = ["go", "run", os.fspath(top_srcdir() / "cmd/gen-manifests"), "-bootc-refs=fake"] + cmd_new = ["go", "run", os.fspath(top_srcdir() / "cmd/gen-manifests"), "-fake-bootc=true"] run_gen_manifests(cmd_new, manifests_new) ret = subprocess.run([ From f382aeed887cf6e3b63db22938c9bc58b4582dcb Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 4 Sep 2025 16:44:24 +0200 Subject: [PATCH 6/7] test: add bootc manifest tests with build containers This commit adds support for build containers in the manifest tests. --- cmd/gen-manifests/main.go | 9 +++++++++ pkg/distro/bootc/bootc.go | 10 ++++++++++ test/bootc-fake-containers.yaml | 13 ++++++++++++- ..._test_os_with_build_container_1-x86_64-ami-empty | 1 + ..._test_os_with_build_container_1-x86_64-gce-empty | 1 + ...est_os_with_build_container_1-x86_64-qcow2-empty | 1 + ..._test_os_with_build_container_1-x86_64-raw-empty | 1 + ..._test_os_with_build_container_1-x86_64-vhd-empty | 1 + ...test_os_with_build_container_1-x86_64-vmdk-empty | 1 + 9 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-ami-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-gce-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-qcow2-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-raw-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-vhd-empty create mode 100644 test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-vmdk-empty diff --git a/cmd/gen-manifests/main.go b/cmd/gen-manifests/main.go index 2f793234d8..c06f7fc44c 100644 --- a/cmd/gen-manifests/main.go +++ b/cmd/gen-manifests/main.go @@ -586,6 +586,9 @@ func main() { DefaultFs string `yaml:"default_fs"` ContainerSize uint64 `yaml:"container_size"` ImageRef string `yaml:"image_ref"` + + BuildContainerRef string `yaml:"build_container_ref"` + BuildContainerInfo osinfo.Info `yaml:"build_container_info"` } type fakeContainersYAML struct { Containers []fakeBootcContainerYAML @@ -601,6 +604,12 @@ func main() { if err != nil { panic(err) } + if fakeBootcCnt.BuildContainerRef != "" { + if err := distribution.SetBuildContainerForTesting(fakeBootcCnt.BuildContainerRef, &fakeBootcCnt.BuildContainerInfo); err != nil { + panic(err) + } + } + arches, _ := arches.ResolveArgValues(distribution.ListArches()) for _, archName := range arches { archi, err := distribution.GetArch(archName) diff --git a/pkg/distro/bootc/bootc.go b/pkg/distro/bootc/bootc.go index 84eec59f48..eddc7e2316 100644 --- a/pkg/distro/bootc/bootc.go +++ b/pkg/distro/bootc/bootc.go @@ -79,11 +79,21 @@ func (d *BootcDistro) SetBuildContainer(imgref string) (err error) { if err != nil { return err } + return d.setBuildContainer(imgref, info) +} + +func (d *BootcDistro) setBuildContainer(imgref string, info *osinfo.Info) error { d.buildImgref = imgref d.buildSourceInfo = info return nil } +// SetBuildContainerForTesting should only be used for in tests +// please use "SetBuildContainer" instead +func (d *BootcDistro) SetBuildContainerForTesting(imgref string, info *osinfo.Info) error { + return d.setBuildContainer(imgref, info) +} + func (d *BootcDistro) SetDefaultFs(defaultFs string) error { if defaultFs == "" { return nil diff --git a/test/bootc-fake-containers.yaml b/test/bootc-fake-containers.yaml index c9dc1fd5b7..bc211668dc 100644 --- a/test/bootc-fake-containers.yaml +++ b/test/bootc-fake-containers.yaml @@ -1,12 +1,12 @@ --- containers: - &default_fake_container + image_ref: "bootc-fake-imgref" arch: riscv64 info: &default_info os_release: id: "test-os" versionid: "1" - image_ref: "bootc-fake-imgref" default_fs: "ext4" container_size: 10_000_000_000 - <<: *default_fake_container @@ -23,3 +23,14 @@ containers: info: <<: *default_info uefi_vendor: "uefi-vendor-aarch64" + + - <<: *default_fake_container + arch: x86_64 + info: + os_release: + id: "test-os-with-build-container" + versionid: "1" + build_container_ref: "build-container-fake-ref" + build_container_info: + os_release: + id: "build-test-os" diff --git a/test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-ami-empty b/test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-ami-empty new file mode 100644 index 0000000000..4d003eff16 --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-ami-empty @@ -0,0 +1 @@ +3acf7e43d917fba754c7dddc6ad793616ff54cce diff --git a/test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-gce-empty b/test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-gce-empty new file mode 100644 index 0000000000..2e5f0e347b --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-gce-empty @@ -0,0 +1 @@ +46ec6c72dc9942552f2fdab02ae0a1b3950954a8 diff --git a/test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-qcow2-empty b/test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-qcow2-empty new file mode 100644 index 0000000000..82bf2db417 --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-qcow2-empty @@ -0,0 +1 @@ +e2d3eca009d3276d5cc286df48f2c2d9b99aaecc diff --git a/test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-raw-empty b/test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-raw-empty new file mode 100644 index 0000000000..87e0a7b572 --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-raw-empty @@ -0,0 +1 @@ +7f6896bf5f7437f01a08b417077c7f647eea22a3 diff --git a/test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-vhd-empty b/test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-vhd-empty new file mode 100644 index 0000000000..1358259e01 --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-vhd-empty @@ -0,0 +1 @@ +ed2b094ebe4646ad8a305173251128c251de9bf9 diff --git a/test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-vmdk-empty b/test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-vmdk-empty new file mode 100644 index 0000000000..1c7bc879d3 --- /dev/null +++ b/test/data/manifest-checksums/bootc_test_os_with_build_container_1-x86_64-vmdk-empty @@ -0,0 +1 @@ +a8365d782f5261d21d8e17a947d20faca2422ffe From be4fd485da0a72b574238b27628ebf4c1ac3d381 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 5 Sep 2025 11:47:10 +0200 Subject: [PATCH 7/7] test: filter bootc-* distros when validate_build_config() We need to filter out all bootc-* distros, they are "virtual" and will not show up in "list-images" which is used to validate known distros. Without this the validation will fail with: ``` Validating config file paths OK: All config files found Validating build configurations (distros, arches, image types) 1 ./configs/empty.json: distros: bootc-* arches: * image types: * ``` --- test/scripts/validate-config-map | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/test/scripts/validate-config-map b/test/scripts/validate-config-map index cd2c1aee6e..82035e16ed 100755 --- a/test/scripts/validate-config-map +++ b/test/scripts/validate-config-map @@ -6,6 +6,7 @@ image-types produces at least one valid build configuration for each config file The config map is read as test/config-map.json relative to the repository root. """ import argparse +import copy import json import pathlib import sys @@ -59,6 +60,17 @@ def validate_build_config(config_map): return no_matches +def filter_bootc(orig_config_map): + """ returns a copy of the config_map without booc distros """ + config_map = copy.deepcopy(orig_config_map) + for build_config in config_map.values(): + if distros := build_config.get("distros"): + build_config["distros"] = [ + d for d in distros if not d.startswith("bootc-")] + + return config_map + + def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("path", default=".", nargs="?", help="path to repository root") @@ -78,7 +90,9 @@ def main(): print("OK: All config files found") print("Validating build configurations (distros, arches, image types)") - no_matches = validate_build_config(config_map) + # filter out all bootc-* distros, they are "virtual" and will not + # show up in "list-images" which is used to validate known distros + no_matches = validate_build_config(filter_bootc(config_map)) if no_matches: print("failed: the following configs do not match any known build configurations", file=sys.stderr) for idx, (config, build_config) in enumerate(no_matches, start=1):