debian-forge-composer/internal/manifest/iso_tree.go
Tom Gundersen 4961a17ba8 manifest: implicitly track pipelines in manifest
Pipelines are now added to their manifest on creation, and we
ensure that dependants are associated with the same manifest.
2022-07-04 23:04:29 +01:00

141 lines
4.1 KiB
Go

package manifest
import (
"fmt"
"path"
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/osbuild2"
)
// An ISOTreePipeline represents a tree containing the anaconda installer,
// configuration in terms of a kickstart file, as well as an embedded
// payload to be installed.
type ISOTreePipeline struct {
BasePipeline
// TODO: review optional and mandatory fields and their meaning
UEFIVendor string
OSName string
Release string
Users []blueprint.UserCustomization
Groups []blueprint.GroupCustomization
anacondaPipeline *AnacondaPipeline
isoLabel string
osTreeCommit string
osTreeURL string
osTreeRef string
}
func NewISOTreePipeline(m *Manifest,
buildPipeline *BuildPipeline,
anacondaPipeline *AnacondaPipeline,
osTreeCommit,
osTreeURL,
osTreeRef,
isoLabelTmpl string) *ISOTreePipeline {
// TODO: replace isoLabelTmpl with more high-level properties
isoLabel := fmt.Sprintf(isoLabelTmpl, anacondaPipeline.arch)
p := &ISOTreePipeline{
BasePipeline: NewBasePipeline(m, "bootiso-tree", buildPipeline, nil),
anacondaPipeline: anacondaPipeline,
isoLabel: isoLabel,
osTreeCommit: osTreeCommit,
osTreeURL: osTreeURL,
osTreeRef: osTreeRef,
}
buildPipeline.addDependent(p)
if anacondaPipeline.BasePipeline.manifest != m {
panic("anaconda pipeline from different manifest")
}
m.addPipeline(p)
return p
}
func (p *ISOTreePipeline) getOSTreeCommits() []osTreeCommit {
return []osTreeCommit{
{
checksum: p.osTreeCommit,
url: p.osTreeURL,
},
}
}
func (p *ISOTreePipeline) serialize() osbuild2.Pipeline {
pipeline := p.BasePipeline.serialize()
kspath := "/osbuild.ks"
ostreeRepoPath := "/ostree/repo"
pipeline.AddStage(osbuild2.NewBootISOMonoStage(bootISOMonoStageOptions(p.anacondaPipeline.kernelVer, p.anacondaPipeline.arch, p.UEFIVendor, p.anacondaPipeline.product, p.anacondaPipeline.version, p.isoLabel, kspath), osbuild2.NewBootISOMonoStagePipelineTreeInputs(p.anacondaPipeline.Name())))
kickstartOptions, err := osbuild2.NewKickstartStageOptions(kspath, "", p.Users, p.Groups, makeISORootPath(ostreeRepoPath), p.osTreeRef, p.OSName)
if err != nil {
panic("password encryption failed")
}
pipeline.AddStage(osbuild2.NewKickstartStage(kickstartOptions))
pipeline.AddStage(osbuild2.NewDiscinfoStage(&osbuild2.DiscinfoStageOptions{
BaseArch: p.anacondaPipeline.arch,
Release: p.Release,
}))
pipeline.AddStage(osbuild2.NewOSTreeInitStage(&osbuild2.OSTreeInitStageOptions{Path: ostreeRepoPath}))
pipeline.AddStage(osbuild2.NewOSTreePullStage(
&osbuild2.OSTreePullStageOptions{Repo: ostreeRepoPath},
osbuild2.NewOstreePullStageInputs("org.osbuild.source", p.osTreeCommit, p.osTreeRef),
))
return pipeline
}
func bootISOMonoStageOptions(kernelVer, arch, vendor, product, osVersion, isolabel, kspath string) *osbuild2.BootISOMonoStageOptions {
comprOptions := new(osbuild2.FSCompressionOptions)
if bcj := osbuild2.BCJOption(arch); bcj != "" {
comprOptions.BCJ = bcj
}
var architectures []string
if arch == distro.X86_64ArchName {
architectures = []string{"X64"}
} else if arch == distro.Aarch64ArchName {
architectures = []string{"AA64"}
} else {
panic("unsupported architecture")
}
return &osbuild2.BootISOMonoStageOptions{
Product: osbuild2.Product{
Name: product,
Version: osVersion,
},
ISOLabel: isolabel,
Kernel: kernelVer,
KernelOpts: fmt.Sprintf("inst.ks=hd:LABEL=%s:%s", isolabel, kspath),
EFI: osbuild2.EFI{
Architectures: architectures,
Vendor: vendor,
},
ISOLinux: osbuild2.ISOLinux{
Enabled: arch == distro.X86_64ArchName,
Debug: false,
},
Templates: "99-generic",
RootFS: osbuild2.RootFS{
Size: 9216,
Compression: osbuild2.FSCompression{
Method: "xz",
Options: comprOptions,
},
},
}
}
//makeISORootPath return a path that can be used to address files and folders in
//the root of the iso
func makeISORootPath(p string) string {
fullpath := path.Join("/run/install/repo", p)
return fmt.Sprintf("file://%s", fullpath)
}