156 lines
4.2 KiB
Go
156 lines
4.2 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/osbuild"
|
|
)
|
|
|
|
// An ISOTree represents a tree containing the anaconda installer,
|
|
// configuration in terms of a kickstart file, as well as an embedded
|
|
// payload to be installed.
|
|
type ISOTree struct {
|
|
Base
|
|
// TODO: review optional and mandatory fields and their meaning
|
|
UEFIVendor string
|
|
OSName string
|
|
Release string
|
|
Users []blueprint.UserCustomization
|
|
Groups []blueprint.GroupCustomization
|
|
|
|
anacondaPipeline *Anaconda
|
|
isoLabel string
|
|
osTreeCommit string
|
|
osTreeURL string
|
|
osTreeRef string
|
|
}
|
|
|
|
func NewISOTree(m *Manifest,
|
|
buildPipeline *Build,
|
|
anacondaPipeline *Anaconda,
|
|
osTreeCommit,
|
|
osTreeURL,
|
|
osTreeRef,
|
|
isoLabelTmpl string) *ISOTree {
|
|
// TODO: replace isoLabelTmpl with more high-level properties
|
|
isoLabel := fmt.Sprintf(isoLabelTmpl, anacondaPipeline.platform.GetArch())
|
|
|
|
p := &ISOTree{
|
|
Base: NewBase(m, "bootiso-tree", buildPipeline),
|
|
anacondaPipeline: anacondaPipeline,
|
|
isoLabel: isoLabel,
|
|
osTreeCommit: osTreeCommit,
|
|
osTreeURL: osTreeURL,
|
|
osTreeRef: osTreeRef,
|
|
}
|
|
buildPipeline.addDependent(p)
|
|
if anacondaPipeline.Base.manifest != m {
|
|
panic("anaconda pipeline from different manifest")
|
|
}
|
|
m.addPipeline(p)
|
|
return p
|
|
}
|
|
|
|
func (p *ISOTree) getOSTreeCommits() []osTreeCommit {
|
|
return []osTreeCommit{
|
|
{
|
|
checksum: p.osTreeCommit,
|
|
url: p.osTreeURL,
|
|
},
|
|
}
|
|
}
|
|
|
|
func (p *ISOTree) getBuildPackages() []string {
|
|
packages := []string{
|
|
"rpm-ostree",
|
|
"squashfs-tools",
|
|
}
|
|
return packages
|
|
}
|
|
|
|
func (p *ISOTree) serialize() osbuild.Pipeline {
|
|
pipeline := p.Base.serialize()
|
|
|
|
kspath := "/osbuild.ks"
|
|
ostreeRepoPath := "/ostree/repo"
|
|
|
|
pipeline.AddStage(osbuild.NewBootISOMonoStage(bootISOMonoStageOptions(p.anacondaPipeline.kernelVer,
|
|
p.anacondaPipeline.platform.GetArch().String(),
|
|
p.UEFIVendor,
|
|
p.anacondaPipeline.product,
|
|
p.anacondaPipeline.version,
|
|
p.isoLabel,
|
|
kspath),
|
|
osbuild.NewBootISOMonoStagePipelineTreeInputs(p.anacondaPipeline.Name())))
|
|
|
|
kickstartOptions, err := osbuild.NewKickstartStageOptions(kspath, "", p.Users, p.Groups, makeISORootPath(ostreeRepoPath), p.osTreeRef, p.OSName)
|
|
if err != nil {
|
|
panic("password encryption failed")
|
|
}
|
|
|
|
pipeline.AddStage(osbuild.NewKickstartStage(kickstartOptions))
|
|
pipeline.AddStage(osbuild.NewDiscinfoStage(&osbuild.DiscinfoStageOptions{
|
|
BaseArch: p.anacondaPipeline.platform.GetArch().String(),
|
|
Release: p.Release,
|
|
}))
|
|
|
|
pipeline.AddStage(osbuild.NewOSTreeInitStage(&osbuild.OSTreeInitStageOptions{Path: ostreeRepoPath}))
|
|
pipeline.AddStage(osbuild.NewOSTreePullStage(
|
|
&osbuild.OSTreePullStageOptions{Repo: ostreeRepoPath},
|
|
osbuild.NewOstreePullStageInputs("org.osbuild.source", p.osTreeCommit, p.osTreeRef),
|
|
))
|
|
|
|
return pipeline
|
|
}
|
|
|
|
func bootISOMonoStageOptions(kernelVer, arch, vendor, product, osVersion, isolabel, kspath string) *osbuild.BootISOMonoStageOptions {
|
|
comprOptions := new(osbuild.FSCompressionOptions)
|
|
if bcj := osbuild.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 &osbuild.BootISOMonoStageOptions{
|
|
Product: osbuild.Product{
|
|
Name: product,
|
|
Version: osVersion,
|
|
},
|
|
ISOLabel: isolabel,
|
|
Kernel: kernelVer,
|
|
KernelOpts: fmt.Sprintf("inst.ks=hd:LABEL=%s:%s", isolabel, kspath),
|
|
EFI: osbuild.EFI{
|
|
Architectures: architectures,
|
|
Vendor: vendor,
|
|
},
|
|
ISOLinux: osbuild.ISOLinux{
|
|
Enabled: arch == distro.X86_64ArchName,
|
|
Debug: false,
|
|
},
|
|
Templates: "99-generic",
|
|
RootFS: osbuild.RootFS{
|
|
Size: 9216,
|
|
Compression: osbuild.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)
|
|
}
|