Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 80 additions & 40 deletions data/distrodefs/fedora/imagetypes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1752,45 +1752,84 @@ image_types:
- <<: *aarch64_platform
image_format: "raw"
boot_files:
- ["/usr/lib/ostree-boot/efi/bcm2710-rpi-2-b.dtb", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/bcm2710-rpi-3-b-plus.dtb", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/bcm2710-rpi-3-b.dtb", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/bcm2710-rpi-cm0.dtb", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/bcm2710-rpi-cm3.dtb", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/bcm2710-rpi-zero-2-w.dtb", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/bcm2710-rpi-zero-2.dtb", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/bcm2711-rpi-4-b.dtb", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/bcm2711-rpi-400.dtb", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/bcm2711-rpi-cm4.dtb", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/bcm2711-rpi-cm4s.dtb", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/bcm2712-rpi-5-b.dtb", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/bcm2712-rpi-500.dtb", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/bcm2712-d-rpi-5-b.dtb", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/bcm2712d0-rpi-5-b.dtb", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/bcm2712-rpi-cm5-cm4io.dtb", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/bcm2712-rpi-cm5-cm5io.dtb", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/bcm2712-rpi-cm5l-cm4io.dtb", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/bcm2712-rpi-cm5l-cm5io.dtb", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/bootcode.bin", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/config.txt", "/boot/efi/config.txt"]
- ["/usr/lib/ostree-boot/efi/fixup.dat", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/fixup4.dat", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/fixup4cd.dat", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/fixup4db.dat", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/fixup4x.dat", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/fixup_cd.dat", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/fixup_db.dat", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/fixup_x.dat", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/overlays", "/boot/efi/"]
- ["/usr/share/uboot/rpi_arm64/u-boot.bin", "/boot/efi/rpi-u-boot.bin"]
- ["/usr/lib/ostree-boot/efi/start.elf", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/start4.elf", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/start4cd.elf", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/start4db.elf", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/start4x.elf", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/start_cd.elf", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/start_db.elf", "/boot/efi/"]
- ["/usr/lib/ostree-boot/efi/start_x.elf", "/boot/efi/"]
- src: "/usr/lib/ostree-boot/efi/bcm2710-rpi-2-b.dtb"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/bcm2710-rpi-3-b-plus.dtb"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/bcm2710-rpi-3-b.dtb"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/bcm2710-rpi-cm0.dtb"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/bcm2710-rpi-cm3.dtb"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/bcm2710-rpi-zero-2-w.dtb"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/bcm2710-rpi-zero-2.dtb"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/bcm2711-rpi-4-b.dtb"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/bcm2711-rpi-400.dtb"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/bcm2711-rpi-cm4.dtb"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/bcm2711-rpi-cm4s.dtb"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/bcm2712-rpi-5-b.dtb"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/bcm2712-rpi-500.dtb"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/bcm2712-d-rpi-5-b.dtb"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/bcm2712d0-rpi-5-b.dtb"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/bcm2712-rpi-cm5-cm4io.dtb"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/bcm2712-rpi-cm5-cm5io.dtb"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/bcm2712-rpi-cm5l-cm4io.dtb"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/bcm2712-rpi-cm5l-cm5io.dtb"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/bootcode.bin"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/config.txt"
dst: "/boot/efi/config.txt"
- src: "/usr/lib/ostree-boot/efi/fixup.dat"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/fixup4.dat"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/fixup4cd.dat"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/fixup4db.dat"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/fixup4x.dat"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/fixup_cd.dat"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/fixup_db.dat"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/fixup_x.dat"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/overlays"
dst: "/boot/efi/"
- src: "/usr/share/uboot/rpi_arm64/u-boot.bin"
dst: "/boot/efi/rpi-u-boot.bin"
- src: "/usr/lib/ostree-boot/efi/start.elf"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/start4.elf"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/start4cd.elf"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/start4db.elf"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/start4x.elf"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/start_cd.elf"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/start_db.elf"
dst: "/boot/efi/"
- src: "/usr/lib/ostree-boot/efi/start_x.elf"
dst: "/boot/efi/"
partition_table:
<<: *iot_base_partition_tables
blueprint:
Expand Down Expand Up @@ -1996,7 +2035,8 @@ image_types:
- "bcm283x-firmware"
- "uboot-images-armv8"
boot_files:
- ["/usr/share/uboot/rpi_arm64/u-boot.bin", "/boot/efi/rpi-u-boot.bin"]
- src: "/usr/share/uboot/rpi_arm64/u-boot.bin"
dst: "/boot/efi/rpi-u-boot.bin"
bootloader: "grub2"
- *riscv64_uefi_platform
disk_config:
Expand Down
86 changes: 58 additions & 28 deletions pkg/manifest/raw.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/artifact"
"github.com/osbuild/images/pkg/disk"
"github.com/osbuild/images/pkg/osbuild"
"github.com/osbuild/images/pkg/platform"
)
Expand Down Expand Up @@ -68,36 +69,24 @@ func (p *RawImage) serialize() (osbuild.Pipeline, error) {
copyInputs := osbuild.NewPipelineTreeInputs(inputName, p.treePipeline.Name())
pipeline.AddStage(osbuild.NewCopyStage(copyOptions, copyInputs, copyDevices, copyMounts))

bootFiles := p.treePipeline.platform.GetBootFiles()
if len(bootFiles) > 0 {
// we ignore the bootcopyoptions as they contain a full tree copy instead we make our own, we *do* still want all the other
// information such as mountpoints and devices
_, bootCopyDevices, bootCopyMounts := osbuild.GenCopyFSTreeOptions(inputName, p.treePipeline.Name(), p.Filename(), pt)
bootCopyOptions := &osbuild.CopyStageOptions{}
bootCopyInputs := osbuild.NewPipelineTreeInputs(inputName, p.treePipeline.Name())

// Find the FS root mount name to use as the destination root
// for the target when copying the boot files.
var fsRootMntName string
for _, mnt := range bootCopyMounts {
if mnt.Target == "/" {
fsRootMntName = mnt.Name
break
}
}

if fsRootMntName == "" {
return osbuild.Pipeline{}, fmt.Errorf("no mount found for the filesystem root")
treeBootFiles, buildBootFiles := splitBootFiles(p.treePipeline.platform.GetBootFiles())
if len(treeBootFiles) > 0 {
treeInputName := "root-tree"
bootCopyInputs := osbuild.NewPipelineTreeInputs(treeInputName, p.treePipeline.Name())
stage, err := bootFilesCopyStage(treeBootFiles, bootCopyInputs, treeInputName, p.Filename(), pt)
if err != nil {
return osbuild.Pipeline{}, err
Comment on lines +72 to +78

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In order to make the serialize() function not huge, could we create a function similar to this

func (p *RawImage) addBootFilesStage(
	pipeline *osbuild.Pipeline,
	bootFiles []platform.BootFile,
	inputName string,
	sourcePipelineName string,
	pt *disk.PartitionTable,
) error {
	if len(bootFiles) == 0 {
		return nil
	}

	bootCopyInputs := osbuild.NewPipelineTreeInputs(inputName, sourcePipelineName)
	stage, err := bootFilesCopyStage(bootFiles, bootCopyInputs, inputName, p.Filename(), pt)
	if err != nil {
		return err
	}

	pipeline.AddStage(stage)
	return nil
}

And then you could call something like

	if err := p.addBootFilesStage(&pipeline, treeBootFiles, "root-tree", p.treePipeline.Name(), pt); err != nil {
		return osbuild.Pipeline{}, err
	}

and later the same for buildTree?

@supakeen supakeen Jun 12, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I had something similar initially but if I recall it doesn't generalize over the setup of filtering and the copy inputs so it doesn't save that much space?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yea, looking at the drellabot PR it's +13/-13 and +1/-3 not a huge saving so unless you or someone else insists that it makes things more clear I probably won't address this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, it was not as much about saving space, but rather about making the code a tiny bit more readable. I don't quite like what drellabot did anyway. I like those tests that it generated, but I am not sure if we even need such coverage:) So, especially if you are saying that you already tried to implement this before, I am good with the current solution.

}

for _, paths := range bootFiles {
bootCopyOptions.Paths = append(bootCopyOptions.Paths, osbuild.CopyStagePath{
From: fmt.Sprintf("input://root-tree%s", paths[0]),
To: fmt.Sprintf("mount://%s%s", fsRootMntName, paths[1]),
})
pipeline.AddStage(stage)
}
if len(buildBootFiles) > 0 {
buildInputName := "build-tree"
buildCopyInputs := osbuild.NewPipelineTreeInputs(buildInputName, p.build.Name())
stage, err := bootFilesCopyStage(buildBootFiles, buildCopyInputs, buildInputName, p.Filename(), pt)
if err != nil {
return osbuild.Pipeline{}, err
}

pipeline.AddStage(osbuild.NewCopyStage(bootCopyOptions, bootCopyInputs, bootCopyDevices, bootCopyMounts))
pipeline.AddStage(stage)
}

for _, stage := range osbuild.GenImageFinishStages(pt, p.Filename()) {
Expand Down Expand Up @@ -138,6 +127,47 @@ func (p *RawImage) serialize() (osbuild.Pipeline, error) {
return pipeline, nil
}

func splitBootFiles(bootFiles []platform.BootFile) (tree, build []platform.BootFile) {
for _, bf := range bootFiles {
if bf.FromBuild {
build = append(build, bf)
} else {
tree = append(tree, bf)
}
}
return tree, build
}

func bootFilesCopyStage(
bootFiles []platform.BootFile,
inputs osbuild.Inputs,
srcPrefix, filename string,
pt *disk.PartitionTable,
) (*osbuild.Stage, error) {
_, devices, mounts := osbuild.GenCopyFSTreeOptions("", "", filename, pt)

var fsRootMntName string
for _, mnt := range mounts {
if mnt.Target == "/" {
fsRootMntName = mnt.Name
break
}
}
if fsRootMntName == "" {
return nil, fmt.Errorf("no mount found for the filesystem root")
}

options := &osbuild.CopyStageOptions{}
for _, bf := range bootFiles {
options.Paths = append(options.Paths, osbuild.CopyStagePath{
From: fmt.Sprintf("input://%s%s", srcPrefix, bf.Src),
To: fmt.Sprintf("mount://%s%s", fsRootMntName, bf.Dst),
})
}

return osbuild.NewCopyStage(options, inputs, devices, mounts), nil
}

func (p *RawImage) Export() *artifact.Artifact {
p.Base.export = true
return artifact.New(p.Name(), p.Filename(), nil)
Expand Down
44 changes: 15 additions & 29 deletions pkg/manifest/raw_ostree.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,42 +71,28 @@ func (p *RawOSTreeImage) serialize() (osbuild.Pipeline, error) {

pipeline.AddStage(osbuild.NewCopyStage(treeCopyOptions, treeCopyInputs, treeCopyDevices, treeCopyMounts))

bootFiles := p.platform.GetBootFiles()
if len(bootFiles) > 0 {
// we ignore the bootcopyoptions as they contain a full tree copy instead we make our own, we *do* still want all the other
// information such as mountpoints and devices
_, bootCopyDevices, bootCopyMounts := osbuild.GenCopyFSTreeOptions(inputName, p.treePipeline.Name(), p.Filename(), pt)
bootCopyOptions := &osbuild.CopyStageOptions{}

treeBootFiles, buildBootFiles := splitBootFiles(p.platform.GetBootFiles())
if len(treeBootFiles) > 0 {
commit := p.treePipeline.ostreeSpec
commitChecksum := commit.Checksum

bootCopyInputs := osbuild.OSTreeCheckoutInputs{
"ostree-tree": *osbuild.NewOSTreeCheckoutInput("org.osbuild.source", commitChecksum),
}

// Find the FS root mount name to use as the destination root
// for the target when copying the boot files.
var fsRootMntName string
for _, mnt := range bootCopyMounts {
if mnt.Target == "/" {
fsRootMntName = mnt.Name
break
}
}

if fsRootMntName == "" {
return osbuild.Pipeline{}, fmt.Errorf("no mount found for the filesystem root")
srcPrefix := fmt.Sprintf("ostree-tree/%s", commitChecksum)
stage, err := bootFilesCopyStage(treeBootFiles, bootCopyInputs, srcPrefix, p.Filename(), pt)
if err != nil {
return osbuild.Pipeline{}, err
}

for _, paths := range bootFiles {
bootCopyOptions.Paths = append(bootCopyOptions.Paths, osbuild.CopyStagePath{
From: fmt.Sprintf("input://ostree-tree/%s%s", commitChecksum, paths[0]),
To: fmt.Sprintf("mount://%s%s", fsRootMntName, paths[1]),
})
pipeline.AddStage(stage)
}
if len(buildBootFiles) > 0 {
buildInputName := "build-tree"
buildCopyInputs := osbuild.NewPipelineTreeInputs(buildInputName, p.build.Name())
stage, err := bootFilesCopyStage(buildBootFiles, buildCopyInputs, buildInputName, p.Filename(), pt)
if err != nil {
return osbuild.Pipeline{}, err
}

pipeline.AddStage(osbuild.NewCopyStage(bootCopyOptions, bootCopyInputs, bootCopyDevices, bootCopyMounts))
pipeline.AddStage(stage)
}

for _, stage := range osbuild.GenImageFinishStages(pt, p.Filename()) {
Expand Down
8 changes: 7 additions & 1 deletion pkg/platform/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,12 @@ func (f *ImageFormat) UnmarshalYAML(unmarshal func(any) error) error {
return common.UnmarshalYAMLviaJSON(f, unmarshal)
}

type BootFile struct {
Src string `yaml:"src" json:"src"`
Dst string `yaml:"dst" json:"dst"`
FromBuild bool `yaml:"from_build,omitempty" json:"from_build,omitempty"`
}

type Platform interface {
GetArch() arch.Arch
GetImageFormat() ImageFormat
Expand All @@ -159,7 +165,7 @@ type Platform interface {
GetZiplSupport() bool
GetPackages() []string
GetBuildPackages() []string
GetBootFiles() [][2]string
GetBootFiles() []BootFile
GetBootloader() Bootloader
GetFIPSMenu() bool
}
4 changes: 2 additions & 2 deletions pkg/platform/yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type Data struct {
// bios support
Packages map[string][]string `yaml:"packages"`
BuildPackages map[string][]string `yaml:"build_packages"`
BootFiles [][2]string `yaml:"boot_files"`
BootFiles []BootFile `yaml:"boot_files"`

Bootloader Bootloader `yaml:"bootloader"`
FIPSMenu bool `yaml:"fips_menu"` // Add FIPS entry to iso bootloader menu
Expand Down Expand Up @@ -64,7 +64,7 @@ func (d *Data) GetBuildPackages() []string {
}
return merged
}
func (d *Data) GetBootFiles() [][2]string {
func (d *Data) GetBootFiles() []BootFile {
return d.BootFiles
}

Expand Down
7 changes: 4 additions & 3 deletions pkg/platform/yaml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ func TestPlatformYamlSmoke(t *testing.T) {
bios:
- grub2-pc-as-bp
boot_files:
- ["/usr/share/uboot/rpi_arm64/u-boot.bin", "/boot/efi/rpi-u-boot.bin"]
- src: "/usr/share/uboot/rpi_arm64/u-boot.bin"
dst: "/boot/efi/rpi-u-boot.bin"
extra_uefi_architectures:
- "ia32"
`)
Expand All @@ -45,8 +46,8 @@ func TestPlatformYamlSmoke(t *testing.T) {
BuildPackages: map[string][]string{
"bios": []string{"grub2-pc-as-bp"},
},
BootFiles: [][2]string{
{"/usr/share/uboot/rpi_arm64/u-boot.bin", "/boot/efi/rpi-u-boot.bin"},
BootFiles: []platform.BootFile{
{Src: "/usr/share/uboot/rpi_arm64/u-boot.bin", Dst: "/boot/efi/rpi-u-boot.bin"},
},
FIPSMenu: false,
ExtraUEFIArchitectures: []string{"ia32"},
Expand Down
Loading