diff --git a/internal/distro/rhel85/pipelines.go b/internal/distro/rhel85/pipelines.go index 285d308ea..f87e17e7c 100644 --- a/internal/distro/rhel85/pipelines.go +++ b/internal/distro/rhel85/pipelines.go @@ -1291,7 +1291,7 @@ func bootloaderInstStage(filename string, pt *disk.PartitionTable, arch *archite } if arch.name == distro.S390xArchName { - return osbuild.NewZiplInstStage(ziplInstStageOptions(kernelVer, pt), disk, devices, mounts) + return osbuild.NewZiplInstStage(osbuild.NewZiplInstStageOptions(kernelVer, pt), disk, devices, mounts) } return nil diff --git a/internal/distro/rhel85/stage_options.go b/internal/distro/rhel85/stage_options.go index 29e3ba7a1..4c299db36 100644 --- a/internal/distro/rhel85/stage_options.go +++ b/internal/distro/rhel85/stage_options.go @@ -349,18 +349,6 @@ func sfdiskStageOptions(pt *disk.PartitionTable) *osbuild.SfdiskStageOptions { return stageOptions } -func ziplInstStageOptions(kernel string, pt *disk.PartitionTable) *osbuild.ZiplInstStageOptions { - bootPartIndex := pt.BootPartitionIndex() - if bootPartIndex == -1 { - panic("failed to find boot or root partition for zipl.inst stage") - } - - return &osbuild.ZiplInstStageOptions{ - Kernel: kernel, - Location: pt.BytesToSectors(pt.Partitions[bootPartIndex].Start), - } -} - func qemuStageOptions(filename, format, compat string) *osbuild.QEMUStageOptions { var options osbuild.QEMUFormatOptions switch format { diff --git a/internal/distro/rhel86/pipelines.go b/internal/distro/rhel86/pipelines.go index f44237ecf..0b2e954d9 100644 --- a/internal/distro/rhel86/pipelines.go +++ b/internal/distro/rhel86/pipelines.go @@ -1015,7 +1015,7 @@ func bootloaderInstStage(filename string, pt *disk.PartitionTable, arch *archite } if arch.name == distro.S390xArchName { - return osbuild.NewZiplInstStage(ziplInstStageOptions(kernelVer, pt), disk, devices, mounts) + return osbuild.NewZiplInstStage(osbuild.NewZiplInstStageOptions(kernelVer, pt), disk, devices, mounts) } return nil diff --git a/internal/distro/rhel86/stage_options.go b/internal/distro/rhel86/stage_options.go index 9779b1184..86ed91868 100644 --- a/internal/distro/rhel86/stage_options.go +++ b/internal/distro/rhel86/stage_options.go @@ -383,18 +383,6 @@ func sfdiskStageOptions(pt *disk.PartitionTable) *osbuild.SfdiskStageOptions { return stageOptions } -func ziplInstStageOptions(kernel string, pt *disk.PartitionTable) *osbuild.ZiplInstStageOptions { - bootPartIndex := pt.BootPartitionIndex() - if bootPartIndex == -1 { - panic("failed to find boot or root partition for zipl.inst stage") - } - - return &osbuild.ZiplInstStageOptions{ - Kernel: kernel, - Location: pt.BytesToSectors(pt.Partitions[bootPartIndex].Start), - } -} - func qemuStageOptions(filename, format, compat string) *osbuild.QEMUStageOptions { var options osbuild.QEMUFormatOptions switch format { diff --git a/internal/distro/rhel90/pipelines.go b/internal/distro/rhel90/pipelines.go index 975e70994..b740d6916 100644 --- a/internal/distro/rhel90/pipelines.go +++ b/internal/distro/rhel90/pipelines.go @@ -1004,7 +1004,7 @@ func bootloaderInstStage(filename string, pt *disk.PartitionTable, arch *archite } if arch.name == distro.S390xArchName { - return osbuild.NewZiplInstStage(ziplInstStageOptions(kernelVer, pt), disk, devices, mounts) + return osbuild.NewZiplInstStage(osbuild.NewZiplInstStageOptions(kernelVer, pt), disk, devices, mounts) } return nil diff --git a/internal/distro/rhel90/stage_options.go b/internal/distro/rhel90/stage_options.go index d67874a56..447f1d14e 100644 --- a/internal/distro/rhel90/stage_options.go +++ b/internal/distro/rhel90/stage_options.go @@ -383,18 +383,6 @@ func sfdiskStageOptions(pt *disk.PartitionTable) *osbuild.SfdiskStageOptions { return stageOptions } -func ziplInstStageOptions(kernel string, pt *disk.PartitionTable) *osbuild.ZiplInstStageOptions { - bootPartIndex := pt.BootPartitionIndex() - if bootPartIndex == -1 { - panic("failed to find boot or root partition for zipl.inst stage") - } - - return &osbuild.ZiplInstStageOptions{ - Kernel: kernel, - Location: pt.BytesToSectors(pt.Partitions[bootPartIndex].Start), - } -} - func qemuStageOptions(filename, format, compat string) *osbuild.QEMUStageOptions { var options osbuild.QEMUFormatOptions switch format { diff --git a/internal/distro/rhel90beta/pipelines.go b/internal/distro/rhel90beta/pipelines.go index b007d8c08..e7b7b549f 100644 --- a/internal/distro/rhel90beta/pipelines.go +++ b/internal/distro/rhel90beta/pipelines.go @@ -1091,7 +1091,7 @@ func bootloaderInstStage(filename string, pt *disk.PartitionTable, arch *archite } if arch.name == distro.S390xArchName { - return osbuild.NewZiplInstStage(ziplInstStageOptions(kernelVer, pt), disk, devices, mounts) + return osbuild.NewZiplInstStage(osbuild.NewZiplInstStageOptions(kernelVer, pt), disk, devices, mounts) } return nil diff --git a/internal/distro/rhel90beta/stage_options.go b/internal/distro/rhel90beta/stage_options.go index a573cc5b9..63c201064 100644 --- a/internal/distro/rhel90beta/stage_options.go +++ b/internal/distro/rhel90beta/stage_options.go @@ -328,18 +328,6 @@ func sfdiskStageOptions(pt *disk.PartitionTable) *osbuild.SfdiskStageOptions { return stageOptions } -func ziplInstStageOptions(kernel string, pt *disk.PartitionTable) *osbuild.ZiplInstStageOptions { - bootPartIndex := pt.BootPartitionIndex() - if bootPartIndex == -1 { - panic("failed to find boot or root partition for zipl.inst stage") - } - - return &osbuild.ZiplInstStageOptions{ - Kernel: kernel, - Location: pt.BytesToSectors(pt.Partitions[bootPartIndex].Start), - } -} - func qemuStageOptions(filename, format, compat string) *osbuild.QEMUStageOptions { var options osbuild.QEMUFormatOptions switch format { diff --git a/internal/osbuild2/zipl_inst_stage.go b/internal/osbuild2/zipl_inst_stage.go index 8f2eb4ebc..40e68cec3 100644 --- a/internal/osbuild2/zipl_inst_stage.go +++ b/internal/osbuild2/zipl_inst_stage.go @@ -1,5 +1,7 @@ package osbuild2 +import "github.com/osbuild/osbuild-composer/internal/disk" + // Install the Z Initial Program Loader type ZiplInstStageOptions struct { @@ -27,3 +29,37 @@ func NewZiplInstStage(options *ZiplInstStageOptions, disk *Device, devices *Devi Mounts: *mounts, } } + +func NewZiplInstStageOptions(kernel string, pt *disk.PartitionTable) *ZiplInstStageOptions { + bootIdx := -1 + rootIdx := -1 + for idx := range pt.Partitions { + // NOTE: we only support having /boot at the top level of the partition + // table (e.g., not in LUKS or LVM), so we don't need to descend into + // VolumeContainer types. If /boot is on the root partition, then the + // root partition needs to be at the top level. + partition := &pt.Partitions[idx] + if partition.Payload == nil { + continue + } + if partition.Payload.GetMountpoint() == "/boot" { + bootIdx = idx + } else if partition.Payload.GetMountpoint() == "/" { + rootIdx = idx + } + } + if bootIdx == -1 { + // if there's no boot partition, fall back to root + if rootIdx == -1 { + // no root either!? + panic("failed to find boot or root partition for zipl.inst stage") + } + bootIdx = rootIdx + } + + bootPart := pt.Partitions[bootIdx] + return &ZiplInstStageOptions{ + Kernel: kernel, + Location: pt.BytesToSectors(bootPart.Start), + } +}