diff --git a/internal/distro/fedora/pipelines.go b/internal/distro/fedora/pipelines.go index 6ad92ae4c..5ae9ea788 100644 --- a/internal/distro/fedora/pipelines.go +++ b/internal/distro/fedora/pipelines.go @@ -17,19 +17,14 @@ func qcow2Pipelines(t *imageType, customizations *blueprint.Customizations, opti buildPipeline := pipeline.NewBuildPipeline(t.arch.distro.runner, repos, packageSetSpecs[buildPkgsKey]) pipelines = append(pipelines, buildPipeline.Serialize()) - partitionTable, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng) - if err != nil { - return nil, err - } - - treePipeline, err := osPipeline(&buildPipeline, t, repos, packageSetSpecs[osPkgsKey], customizations, options, partitionTable) + treePipeline, err := osPipeline(&buildPipeline, t, repos, packageSetSpecs[osPkgsKey], customizations, options, rng) if err != nil { return nil, err } pipelines = append(pipelines, treePipeline.Serialize()) diskfile := "disk.img" - imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, partitionTable, t.arch) + imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, t.arch) pipelines = append(pipelines, imagePipeline.Serialize()) qemuPipeline := qemuPipeline(&buildPipeline, &imagePipeline, diskfile, t.filename, osbuild.QEMUFormatQCOW2, osbuild.QCOW2Options{Compat: "1.1"}) @@ -44,19 +39,14 @@ func vhdPipelines(t *imageType, customizations *blueprint.Customizations, option buildPipeline := pipeline.NewBuildPipeline(t.arch.distro.runner, repos, packageSetSpecs[buildPkgsKey]) pipelines = append(pipelines, buildPipeline.Serialize()) - partitionTable, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng) - if err != nil { - return nil, err - } - - treePipeline, err := osPipeline(&buildPipeline, t, repos, packageSetSpecs[osPkgsKey], customizations, options, partitionTable) + treePipeline, err := osPipeline(&buildPipeline, t, repos, packageSetSpecs[osPkgsKey], customizations, options, rng) if err != nil { return nil, err } pipelines = append(pipelines, treePipeline.Serialize()) diskfile := "disk.img" - imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, partitionTable, t.arch) + imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, t.arch) pipelines = append(pipelines, imagePipeline.Serialize()) qemuPipeline := qemuPipeline(&buildPipeline, &imagePipeline, diskfile, t.filename, osbuild.QEMUFormatVPC, nil) @@ -70,19 +60,14 @@ func vmdkPipelines(t *imageType, customizations *blueprint.Customizations, optio buildPipeline := pipeline.NewBuildPipeline(t.arch.distro.runner, repos, packageSetSpecs[buildPkgsKey]) pipelines = append(pipelines, buildPipeline.Serialize()) - partitionTable, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng) - if err != nil { - return nil, err - } - - treePipeline, err := osPipeline(&buildPipeline, t, repos, packageSetSpecs[osPkgsKey], customizations, options, partitionTable) + treePipeline, err := osPipeline(&buildPipeline, t, repos, packageSetSpecs[osPkgsKey], customizations, options, rng) if err != nil { return nil, err } pipelines = append(pipelines, treePipeline.Serialize()) diskfile := "disk.img" - imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, partitionTable, t.arch) + imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, t.arch) pipelines = append(pipelines, imagePipeline.Serialize()) qemuPipeline := qemuPipeline(&buildPipeline, &imagePipeline, diskfile, t.filename, osbuild.QEMUFormatVMDK, osbuild.VMDKOptions{Subformat: osbuild.VMDKSubformatStreamOptimized}) @@ -96,19 +81,14 @@ func openstackPipelines(t *imageType, customizations *blueprint.Customizations, buildPipeline := pipeline.NewBuildPipeline(t.arch.distro.runner, repos, packageSetSpecs[buildPkgsKey]) pipelines = append(pipelines, buildPipeline.Serialize()) - partitionTable, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng) - if err != nil { - return nil, err - } - - treePipeline, err := osPipeline(&buildPipeline, t, repos, packageSetSpecs[osPkgsKey], customizations, options, partitionTable) + treePipeline, err := osPipeline(&buildPipeline, t, repos, packageSetSpecs[osPkgsKey], customizations, options, rng) if err != nil { return nil, err } pipelines = append(pipelines, treePipeline.Serialize()) diskfile := "disk.img" - imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, partitionTable, t.arch) + imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, t.arch) pipelines = append(pipelines, imagePipeline.Serialize()) qemuPipeline := qemuPipeline(&buildPipeline, &imagePipeline, diskfile, t.filename, osbuild.QEMUFormatQCOW2, nil) @@ -124,18 +104,13 @@ func ec2CommonPipelines(t *imageType, customizations *blueprint.Customizations, buildPipeline := pipeline.NewBuildPipeline(t.arch.distro.runner, repos, packageSetSpecs[buildPkgsKey]) pipelines = append(pipelines, buildPipeline.Serialize()) - partitionTable, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng) - if err != nil { - return nil, err - } - - treePipeline, err := osPipeline(&buildPipeline, t, repos, packageSetSpecs[osPkgsKey], customizations, options, partitionTable) + treePipeline, err := osPipeline(&buildPipeline, t, repos, packageSetSpecs[osPkgsKey], customizations, options, rng) if err != nil { return nil, err } pipelines = append(pipelines, treePipeline.Serialize()) - imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, partitionTable, t.arch) + imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, t.arch) pipelines = append(pipelines, imagePipeline.Serialize()) return pipelines, nil } @@ -209,13 +184,21 @@ func osPipeline(buildPipeline *pipeline.BuildPipeline, packages []rpmmd.PackageSpec, c *blueprint.Customizations, options distro.ImageOptions, - pt *disk.PartitionTable) (pipeline.OSPipeline, error) { + rng *rand.Rand) (pipeline.OSPipeline, error) { imageConfig := t.getDefaultImageConfig() - pl := pipeline.NewOSPipeline(buildPipeline, t.rpmOstree, repos, packages, c.GetKernel().Name) + var pt *disk.PartitionTable + if t.bootable { + // TODO: should there always be a partition table? + var err error + pt, err = t.getPartitionTable(c.GetFilesystems(), options, rng) + if err != nil { + return pipeline.OSPipeline{}, err + } + } - pl.PartitionTable = pt + pl := pipeline.NewOSPipeline(buildPipeline, t.rpmOstree, repos, packages, pt, c.GetKernel().Name) if t.Arch().Name() == distro.S390xArchName { pl.BootLoader = pipeline.BOOTLOADER_ZIPL @@ -369,7 +352,7 @@ func bootISOPipeline(buildPipeline *pipeline.BuildPipeline, treePipeline *pipeli return p } -func liveImagePipeline(buildPipeline *pipeline.BuildPipeline, treePipeline *pipeline.OSPipeline, outputFilename string, pt *disk.PartitionTable, arch *architecture) pipeline.LiveImgPipeline { +func liveImagePipeline(buildPipeline *pipeline.BuildPipeline, treePipeline *pipeline.OSPipeline, outputFilename string, arch *architecture) pipeline.LiveImgPipeline { p := pipeline.NewLiveImgPipeline(buildPipeline, treePipeline) p.Filename = outputFilename @@ -381,8 +364,6 @@ func liveImagePipeline(buildPipeline *pipeline.BuildPipeline, treePipeline *pipe p.GRUBLegacy = arch.legacy } - p.PartitionTable = *pt - return p } diff --git a/internal/pipeline/live.go b/internal/pipeline/live.go index 5f0b39703..b86d0ef8f 100644 --- a/internal/pipeline/live.go +++ b/internal/pipeline/live.go @@ -1,17 +1,15 @@ package pipeline import ( - "github.com/osbuild/osbuild-composer/internal/disk" "github.com/osbuild/osbuild-composer/internal/osbuild2" ) type LiveImgPipeline struct { Pipeline - PartitionTable disk.PartitionTable - BootLoader BootLoader - GRUBLegacy string - treePipeline *OSPipeline - Filename string + BootLoader BootLoader + GRUBLegacy string + treePipeline *OSPipeline + Filename string } func NewLiveImgPipeline(buildPipeline *BuildPipeline, treePipeline *OSPipeline) LiveImgPipeline { @@ -24,27 +22,32 @@ func NewLiveImgPipeline(buildPipeline *BuildPipeline, treePipeline *OSPipeline) func (p LiveImgPipeline) Serialize() osbuild2.Pipeline { pipeline := p.Pipeline.Serialize() - for _, stage := range osbuild2.GenImagePrepareStages(&p.PartitionTable, p.Filename, osbuild2.PTSfdisk) { + pt := p.treePipeline.PartitionTable() + if pt == nil { + panic("no partition table in live image") + } + + for _, stage := range osbuild2.GenImagePrepareStages(pt, p.Filename, osbuild2.PTSfdisk) { pipeline.AddStage(stage) } inputName := "root-tree" - copyOptions, copyDevices, copyMounts := osbuild2.GenCopyFSTreeOptions(inputName, p.treePipeline.Name(), p.Filename, &p.PartitionTable) + copyOptions, copyDevices, copyMounts := osbuild2.GenCopyFSTreeOptions(inputName, p.treePipeline.Name(), p.Filename, pt) copyInputs := osbuild2.NewCopyStagePipelineTreeInputs(inputName, p.treePipeline.Name()) pipeline.AddStage(osbuild2.NewCopyStage(copyOptions, copyInputs, copyDevices, copyMounts)) - for _, stage := range osbuild2.GenImageFinishStages(&p.PartitionTable, p.Filename) { + for _, stage := range osbuild2.GenImageFinishStages(pt, p.Filename) { pipeline.AddStage(stage) } switch p.BootLoader { case BOOTLOADER_GRUB: if p.GRUBLegacy != "" { - pipeline.AddStage(osbuild2.NewGrub2InstStage(osbuild2.NewGrub2InstStageOption(p.Filename, &p.PartitionTable, p.GRUBLegacy))) + pipeline.AddStage(osbuild2.NewGrub2InstStage(osbuild2.NewGrub2InstStageOption(p.Filename, pt, p.GRUBLegacy))) } case BOOTLOADER_ZIPL: loopback := osbuild2.NewLoopbackDevice(&osbuild2.LoopbackDeviceOptions{Filename: p.Filename}) - pipeline.AddStage(osbuild2.NewZiplInstStage(osbuild2.NewZiplInstStageOptions(p.treePipeline.KernelVer(), &p.PartitionTable), loopback, copyDevices, copyMounts)) + pipeline.AddStage(osbuild2.NewZiplInstStage(osbuild2.NewZiplInstStageOptions(p.treePipeline.KernelVer(), pt), loopback, copyDevices, copyMounts)) } return pipeline diff --git a/internal/pipeline/os.go b/internal/pipeline/os.go index 0387ffde8..02d600b42 100644 --- a/internal/pipeline/os.go +++ b/internal/pipeline/os.go @@ -22,7 +22,6 @@ type OSPipeline struct { GRUBLegacy string Vendor string GPGKeyFiles []string - PartitionTable *disk.PartitionTable Language string Keyboard *string Hostname string @@ -55,25 +54,27 @@ type OSPipeline struct { PwQuality *osbuild2.PwqualityConfStageOptions WAAgentConfig *osbuild2.WAAgentConfStageOptions - osTree bool - repos []rpmmd.RepoConfig - packageSpecs []rpmmd.PackageSpec - kernelVer string + osTree bool + repos []rpmmd.RepoConfig + packageSpecs []rpmmd.PackageSpec + partitionTable *disk.PartitionTable + kernelVer string } -func NewOSPipeline(buildPipeline *BuildPipeline, osTree bool, repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, kernelName string) OSPipeline { +func NewOSPipeline(buildPipeline *BuildPipeline, osTree bool, repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, pt *disk.PartitionTable, kernelName string) OSPipeline { name := "os" if osTree { name = "ostree-tree" } kernelVer := rpmmd.GetVerStrFromPackageSpecListPanic(packages, kernelName) return OSPipeline{ - Pipeline: New(name, buildPipeline, nil), - osTree: osTree, - repos: repos, - packageSpecs: packages, - kernelVer: kernelVer, - Hostname: "localhost.localdomain", + Pipeline: New(name, buildPipeline, nil), + osTree: osTree, + repos: repos, + packageSpecs: packages, + partitionTable: pt, + kernelVer: kernelVer, + Hostname: "localhost.localdomain", } } @@ -81,6 +82,10 @@ func (p OSPipeline) KernelVer() string { return p.kernelVer } +func (p OSPipeline) PartitionTable() *disk.PartitionTable { + return p.partitionTable +} + func (p OSPipeline) Serialize() osbuild2.Pipeline { pipeline := p.Pipeline.Serialize() @@ -93,7 +98,7 @@ func (p OSPipeline) Serialize() osbuild2.Pipeline { pipeline.AddStage(osbuild2.NewRPMStage(rpmOptions, osbuild2.NewRpmStageSourceFilesInputs(p.packageSpecs))) // If the /boot is on a separate partition, the prefix for the BLS stage must be "" - if p.PartitionTable == nil || p.PartitionTable.FindMountable("/boot") == nil { + if p.PartitionTable() == nil || p.PartitionTable().FindMountable("/boot") == nil { pipeline.AddStage(osbuild2.NewFixBLSStage(&osbuild2.FixBLSStageOptions{})) } else { pipeline.AddStage(osbuild2.NewFixBLSStage(&osbuild2.FixBLSStageOptions{Prefix: common.StringToPtr("")})) @@ -228,17 +233,17 @@ func (p OSPipeline) Serialize() osbuild2.Pipeline { pipeline.AddStage(osbuild2.NewWAAgentConfStage(p.WAAgentConfig)) } - if p.PartitionTable != nil { - kernelOptions := osbuild2.GenImageKernelOptions(p.PartitionTable) + if pt := p.PartitionTable(); pt != nil { + kernelOptions := osbuild2.GenImageKernelOptions(p.PartitionTable()) kernelOptions = append(kernelOptions, p.KernelOptionsAppend...) - pipeline = prependKernelCmdlineStage(pipeline, strings.Join(kernelOptions, " "), p.PartitionTable) + pipeline = prependKernelCmdlineStage(pipeline, strings.Join(kernelOptions, " "), pt) - pipeline.AddStage(osbuild2.NewFSTabStage(osbuild2.NewFSTabStageOptions(p.PartitionTable))) + pipeline.AddStage(osbuild2.NewFSTabStage(osbuild2.NewFSTabStageOptions(pt))) var bootloader *osbuild2.Stage switch p.BootLoader { case BOOTLOADER_GRUB: - options := osbuild2.NewGrub2StageOptionsUnified(p.PartitionTable, p.kernelVer, p.UEFI, p.GRUBLegacy, p.Vendor, false) + options := osbuild2.NewGrub2StageOptionsUnified(pt, p.kernelVer, p.UEFI, p.GRUBLegacy, p.Vendor, false) if cfg := p.Grub2Config; cfg != nil { // TODO: don't store Grub2Config in OSPipeline, making the overrides unnecessary // grub2.Config.Default is owned and set by `NewGrub2StageOptionsUnified`