116 lines
3.5 KiB
Go
116 lines
3.5 KiB
Go
package manifest
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/osbuild/images/pkg/arch"
|
|
"github.com/osbuild/images/pkg/artifact"
|
|
"github.com/osbuild/images/pkg/osbuild"
|
|
)
|
|
|
|
// A RawImage represents a raw image file which can be booted in a
|
|
// hypervisor. It is created from an existing OSPipeline.
|
|
type RawImage struct {
|
|
Base
|
|
treePipeline *OS
|
|
filename string
|
|
PartTool osbuild.PartTool
|
|
}
|
|
|
|
func (p RawImage) Filename() string {
|
|
return p.filename
|
|
}
|
|
|
|
func (p *RawImage) SetFilename(filename string) {
|
|
p.filename = filename
|
|
}
|
|
|
|
func NewRawImage(buildPipeline Build, treePipeline *OS) *RawImage {
|
|
p := &RawImage{
|
|
Base: NewBase("image", buildPipeline),
|
|
treePipeline: treePipeline,
|
|
filename: "disk.img",
|
|
}
|
|
buildPipeline.addDependent(p)
|
|
p.PartTool = osbuild.PTSfdisk // default; can be changed after initialisation
|
|
return p
|
|
}
|
|
|
|
func (p *RawImage) getBuildPackages(d Distro) []string {
|
|
pkgs := p.treePipeline.getBuildPackages(d)
|
|
if p.PartTool == osbuild.PTSgdisk {
|
|
pkgs = append(pkgs, "gdisk")
|
|
}
|
|
return pkgs
|
|
}
|
|
|
|
func (p *RawImage) serialize() osbuild.Pipeline {
|
|
pipeline := p.Base.serialize()
|
|
|
|
pt := p.treePipeline.PartitionTable
|
|
if pt == nil {
|
|
panic("no partition table in live image")
|
|
}
|
|
|
|
for _, stage := range osbuild.GenImagePrepareStages(pt, p.Filename(), p.PartTool) {
|
|
pipeline.AddStage(stage)
|
|
}
|
|
|
|
inputName := "root-tree"
|
|
copyOptions, copyDevices, copyMounts := osbuild.GenCopyFSTreeOptions(inputName, p.treePipeline.Name(), p.Filename(), pt)
|
|
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 == "" {
|
|
panic("no mount found for the filesystem root")
|
|
}
|
|
|
|
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(osbuild.NewCopyStage(bootCopyOptions, bootCopyInputs, bootCopyDevices, bootCopyMounts))
|
|
}
|
|
|
|
for _, stage := range osbuild.GenImageFinishStages(pt, p.Filename()) {
|
|
pipeline.AddStage(stage)
|
|
}
|
|
|
|
switch p.treePipeline.platform.GetArch() {
|
|
case arch.ARCH_S390X:
|
|
loopback := osbuild.NewLoopbackDevice(&osbuild.LoopbackDeviceOptions{Filename: p.Filename()})
|
|
pipeline.AddStage(osbuild.NewZiplInstStage(osbuild.NewZiplInstStageOptions(p.treePipeline.kernelVer, pt), loopback, copyDevices, copyMounts))
|
|
default:
|
|
if grubLegacy := p.treePipeline.platform.GetBIOSPlatform(); grubLegacy != "" {
|
|
pipeline.AddStage(osbuild.NewGrub2InstStage(osbuild.NewGrub2InstStageOption(p.Filename(), pt, grubLegacy)))
|
|
}
|
|
}
|
|
|
|
return pipeline
|
|
}
|
|
|
|
func (p *RawImage) Export() *artifact.Artifact {
|
|
p.Base.export = true
|
|
return artifact.New(p.Name(), p.Filename(), nil)
|
|
}
|