pipelines: cleanups

This is a collection of minor cleanups:
 - Start documenting the API
 - Enforce dependent pipelines have the correct type where necessary
 - Use data from dependent pipelines where possible
 - Start enforcing required fields
 - Move logic into the pipeline implementation where we can
This commit is contained in:
Tom Gundersen 2022-06-26 18:30:29 +01:00
parent 040a4ef6a1
commit e024ceb138
13 changed files with 203 additions and 146 deletions

View file

@ -1,23 +1,20 @@
package fedora package fedora
import ( import (
"fmt"
"math/rand" "math/rand"
"github.com/osbuild/osbuild-composer/internal/blueprint" "github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/disk" "github.com/osbuild/osbuild-composer/internal/disk"
"github.com/osbuild/osbuild-composer/internal/distro" "github.com/osbuild/osbuild-composer/internal/distro"
pipeline "github.com/osbuild/osbuild-composer/internal/distro/pipelines"
osbuild "github.com/osbuild/osbuild-composer/internal/osbuild2" osbuild "github.com/osbuild/osbuild-composer/internal/osbuild2"
"github.com/osbuild/osbuild-composer/internal/pipeline"
"github.com/osbuild/osbuild-composer/internal/rpmmd" "github.com/osbuild/osbuild-composer/internal/rpmmd"
) )
func qcow2Pipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec, rng *rand.Rand) ([]osbuild.Pipeline, error) { func qcow2Pipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec, rng *rand.Rand) ([]osbuild.Pipeline, error) {
pipelines := make([]osbuild.Pipeline, 0) pipelines := make([]osbuild.Pipeline, 0)
buildPipeline := pipeline.NewBuildPipeline(t.arch.distro.runner) buildPipeline := pipeline.NewBuildPipeline(t.arch.distro.runner, repos, packageSetSpecs[buildPkgsKey])
buildPipeline.Repos = repos
buildPipeline.PackageSpecs = packageSetSpecs[buildPkgsKey]
pipelines = append(pipelines, buildPipeline.Serialize()) pipelines = append(pipelines, buildPipeline.Serialize())
partitionTable, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng) partitionTable, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng)
@ -32,8 +29,7 @@ func qcow2Pipelines(t *imageType, customizations *blueprint.Customizations, opti
pipelines = append(pipelines, treePipeline.Serialize()) pipelines = append(pipelines, treePipeline.Serialize())
diskfile := "disk.img" diskfile := "disk.img"
kernelVer := rpmmd.GetVerStrFromPackageSpecListPanic(packageSetSpecs[osPkgsKey], customizations.GetKernel().Name) imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, partitionTable, t.arch)
imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, partitionTable, t.arch, kernelVer)
pipelines = append(pipelines, imagePipeline.Serialize()) pipelines = append(pipelines, imagePipeline.Serialize())
qemuPipeline := qemuPipeline(&buildPipeline, &imagePipeline, diskfile, t.filename, osbuild.QEMUFormatQCOW2, osbuild.QCOW2Options{Compat: "1.1"}) qemuPipeline := qemuPipeline(&buildPipeline, &imagePipeline, diskfile, t.filename, osbuild.QEMUFormatQCOW2, osbuild.QCOW2Options{Compat: "1.1"})
@ -45,9 +41,7 @@ func qcow2Pipelines(t *imageType, customizations *blueprint.Customizations, opti
func vhdPipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec, rng *rand.Rand) ([]osbuild.Pipeline, error) { func vhdPipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec, rng *rand.Rand) ([]osbuild.Pipeline, error) {
pipelines := make([]osbuild.Pipeline, 0) pipelines := make([]osbuild.Pipeline, 0)
buildPipeline := pipeline.NewBuildPipeline(t.arch.distro.runner) buildPipeline := pipeline.NewBuildPipeline(t.arch.distro.runner, repos, packageSetSpecs[buildPkgsKey])
buildPipeline.Repos = repos
buildPipeline.PackageSpecs = packageSetSpecs[buildPkgsKey]
pipelines = append(pipelines, buildPipeline.Serialize()) pipelines = append(pipelines, buildPipeline.Serialize())
partitionTable, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng) partitionTable, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng)
@ -62,8 +56,7 @@ func vhdPipelines(t *imageType, customizations *blueprint.Customizations, option
pipelines = append(pipelines, treePipeline.Serialize()) pipelines = append(pipelines, treePipeline.Serialize())
diskfile := "disk.img" diskfile := "disk.img"
kernelVer := rpmmd.GetVerStrFromPackageSpecListPanic(packageSetSpecs[osPkgsKey], customizations.GetKernel().Name) imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, partitionTable, t.arch)
imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, partitionTable, t.arch, kernelVer)
pipelines = append(pipelines, imagePipeline.Serialize()) pipelines = append(pipelines, imagePipeline.Serialize())
qemuPipeline := qemuPipeline(&buildPipeline, &imagePipeline, diskfile, t.filename, osbuild.QEMUFormatVPC, nil) qemuPipeline := qemuPipeline(&buildPipeline, &imagePipeline, diskfile, t.filename, osbuild.QEMUFormatVPC, nil)
@ -74,9 +67,7 @@ func vhdPipelines(t *imageType, customizations *blueprint.Customizations, option
func vmdkPipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec, rng *rand.Rand) ([]osbuild.Pipeline, error) { func vmdkPipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec, rng *rand.Rand) ([]osbuild.Pipeline, error) {
pipelines := make([]osbuild.Pipeline, 0) pipelines := make([]osbuild.Pipeline, 0)
buildPipeline := pipeline.NewBuildPipeline(t.arch.distro.runner) buildPipeline := pipeline.NewBuildPipeline(t.arch.distro.runner, repos, packageSetSpecs[buildPkgsKey])
buildPipeline.Repos = repos
buildPipeline.PackageSpecs = packageSetSpecs[buildPkgsKey]
pipelines = append(pipelines, buildPipeline.Serialize()) pipelines = append(pipelines, buildPipeline.Serialize())
partitionTable, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng) partitionTable, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng)
@ -91,8 +82,7 @@ func vmdkPipelines(t *imageType, customizations *blueprint.Customizations, optio
pipelines = append(pipelines, treePipeline.Serialize()) pipelines = append(pipelines, treePipeline.Serialize())
diskfile := "disk.img" diskfile := "disk.img"
kernelVer := rpmmd.GetVerStrFromPackageSpecListPanic(packageSetSpecs[osPkgsKey], customizations.GetKernel().Name) imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, partitionTable, t.arch)
imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, partitionTable, t.arch, kernelVer)
pipelines = append(pipelines, imagePipeline.Serialize()) pipelines = append(pipelines, imagePipeline.Serialize())
qemuPipeline := qemuPipeline(&buildPipeline, &imagePipeline, diskfile, t.filename, osbuild.QEMUFormatVMDK, osbuild.VMDKOptions{Subformat: osbuild.VMDKSubformatStreamOptimized}) qemuPipeline := qemuPipeline(&buildPipeline, &imagePipeline, diskfile, t.filename, osbuild.QEMUFormatVMDK, osbuild.VMDKOptions{Subformat: osbuild.VMDKSubformatStreamOptimized})
@ -103,9 +93,7 @@ func vmdkPipelines(t *imageType, customizations *blueprint.Customizations, optio
func openstackPipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec, rng *rand.Rand) ([]osbuild.Pipeline, error) { func openstackPipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec, rng *rand.Rand) ([]osbuild.Pipeline, error) {
pipelines := make([]osbuild.Pipeline, 0) pipelines := make([]osbuild.Pipeline, 0)
buildPipeline := pipeline.NewBuildPipeline(t.arch.distro.runner) buildPipeline := pipeline.NewBuildPipeline(t.arch.distro.runner, repos, packageSetSpecs[buildPkgsKey])
buildPipeline.Repos = repos
buildPipeline.PackageSpecs = packageSetSpecs[buildPkgsKey]
pipelines = append(pipelines, buildPipeline.Serialize()) pipelines = append(pipelines, buildPipeline.Serialize())
partitionTable, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng) partitionTable, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng)
@ -120,8 +108,7 @@ func openstackPipelines(t *imageType, customizations *blueprint.Customizations,
pipelines = append(pipelines, treePipeline.Serialize()) pipelines = append(pipelines, treePipeline.Serialize())
diskfile := "disk.img" diskfile := "disk.img"
kernelVer := rpmmd.GetVerStrFromPackageSpecListPanic(packageSetSpecs[osPkgsKey], customizations.GetKernel().Name) imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, partitionTable, t.arch)
imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, partitionTable, t.arch, kernelVer)
pipelines = append(pipelines, imagePipeline.Serialize()) pipelines = append(pipelines, imagePipeline.Serialize())
qemuPipeline := qemuPipeline(&buildPipeline, &imagePipeline, diskfile, t.filename, osbuild.QEMUFormatQCOW2, nil) qemuPipeline := qemuPipeline(&buildPipeline, &imagePipeline, diskfile, t.filename, osbuild.QEMUFormatQCOW2, nil)
@ -134,9 +121,7 @@ func ec2CommonPipelines(t *imageType, customizations *blueprint.Customizations,
rng *rand.Rand, diskfile string) ([]osbuild.Pipeline, error) { rng *rand.Rand, diskfile string) ([]osbuild.Pipeline, error) {
pipelines := make([]osbuild.Pipeline, 0) pipelines := make([]osbuild.Pipeline, 0)
buildPipeline := pipeline.NewBuildPipeline(t.arch.distro.runner) buildPipeline := pipeline.NewBuildPipeline(t.arch.distro.runner, repos, packageSetSpecs[buildPkgsKey])
buildPipeline.Repos = repos
buildPipeline.PackageSpecs = packageSetSpecs[buildPkgsKey]
pipelines = append(pipelines, buildPipeline.Serialize()) pipelines = append(pipelines, buildPipeline.Serialize())
partitionTable, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng) partitionTable, err := t.getPartitionTable(customizations.GetFilesystems(), options, rng)
@ -150,8 +135,7 @@ func ec2CommonPipelines(t *imageType, customizations *blueprint.Customizations,
} }
pipelines = append(pipelines, treePipeline.Serialize()) pipelines = append(pipelines, treePipeline.Serialize())
kernelVer := rpmmd.GetVerStrFromPackageSpecListPanic(packageSetSpecs[osPkgsKey], customizations.GetKernel().Name) imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, partitionTable, t.arch)
imagePipeline := liveImagePipeline(&buildPipeline, &treePipeline, diskfile, partitionTable, t.arch, kernelVer)
pipelines = append(pipelines, imagePipeline.Serialize()) pipelines = append(pipelines, imagePipeline.Serialize())
return pipelines, nil return pipelines, nil
} }
@ -164,29 +148,22 @@ func ec2Pipelines(t *imageType, customizations *blueprint.Customizations, option
func iotInstallerPipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec, rng *rand.Rand) ([]osbuild.Pipeline, error) { func iotInstallerPipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec, rng *rand.Rand) ([]osbuild.Pipeline, error) {
pipelines := make([]osbuild.Pipeline, 0) pipelines := make([]osbuild.Pipeline, 0)
buildPipeline := pipeline.NewBuildPipeline(t.arch.distro.runner) buildPipeline := pipeline.NewBuildPipeline(t.arch.distro.runner, repos, packageSetSpecs[buildPkgsKey])
buildPipeline.Repos = repos
buildPipeline.PackageSpecs = packageSetSpecs[buildPkgsKey]
pipelines = append(pipelines, buildPipeline.Serialize()) pipelines = append(pipelines, buildPipeline.Serialize())
installerPackages := packageSetSpecs[installerPkgsKey] installerPackages := packageSetSpecs[installerPkgsKey]
d := t.arch.distro d := t.arch.distro
archName := t.Arch().Name()
kernelVer := rpmmd.GetVerStrFromPackageSpecListPanic(installerPackages, "kernel")
ksUsers := len(customizations.GetUsers())+len(customizations.GetGroups()) > 0 ksUsers := len(customizations.GetUsers())+len(customizations.GetGroups()) > 0
isolabel := fmt.Sprintf(d.isolabelTmpl, archName)
anacondaTreePipeline := anacondaTreePipeline(&buildPipeline, repos, installerPackages, kernelVer, archName, d.product, d.osVersion, "IoT", ksUsers) anacondaTreePipeline := anacondaTreePipeline(&buildPipeline, repos, installerPackages, t.Arch().Name(), d.product, d.osVersion, "IoT", ksUsers)
isoTreePipeline := bootISOTreePipeline(&buildPipeline, &anacondaTreePipeline.Pipeline, options, kernelVer, archName, d.vendor, d.product, d.osVersion, isolabel, customizations.GetUsers(), customizations.GetGroups()) isoTreePipeline := bootISOTreePipeline(&buildPipeline, &anacondaTreePipeline, options, d.vendor, d.isolabelTmpl, customizations.GetUsers(), customizations.GetGroups())
isoPipeline := bootISOPipeline(&buildPipeline, &isoTreePipeline, t.Filename(), isolabel, false) isoPipeline := bootISOPipeline(&buildPipeline, &isoTreePipeline, t.Filename(), false)
return append(pipelines, anacondaTreePipeline.Serialize(), isoTreePipeline.Serialize(), isoPipeline.Serialize()), nil return append(pipelines, anacondaTreePipeline.Serialize(), isoTreePipeline.Serialize(), isoPipeline.Serialize()), nil
} }
func iotCorePipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec) (*pipeline.BuildPipeline, *pipeline.OSPipeline, *pipeline.OSTreeCommitPipeline, error) { func iotCorePipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec) (*pipeline.BuildPipeline, *pipeline.OSPipeline, *pipeline.OSTreeCommitPipeline, error) {
buildPipeline := pipeline.NewBuildPipeline(t.arch.distro.runner) buildPipeline := pipeline.NewBuildPipeline(t.arch.distro.runner, repos, packageSetSpecs[buildPkgsKey])
buildPipeline.Repos = repos
buildPipeline.PackageSpecs = packageSetSpecs[buildPkgsKey]
treePipeline, err := osPipeline(&buildPipeline, t, repos, packageSetSpecs[osPkgsKey], customizations, options, nil) treePipeline, err := osPipeline(&buildPipeline, t, repos, packageSetSpecs[osPkgsKey], customizations, options, nil)
if err != nil { if err != nil {
return nil, nil, nil, err return nil, nil, nil, err
@ -236,7 +213,7 @@ func osPipeline(buildPipeline *pipeline.BuildPipeline,
imageConfig := t.getDefaultImageConfig() imageConfig := t.getDefaultImageConfig()
pl := pipeline.NewOSPipeline(buildPipeline, t.rpmOstree) pl := pipeline.NewOSPipeline(buildPipeline, t.rpmOstree, repos, packages, c.GetKernel().Name)
pl.PartitionTable = pt pl.PartitionTable = pt
@ -258,13 +235,9 @@ func osPipeline(buildPipeline *pipeline.BuildPipeline,
kernelOptions = append(kernelOptions, bpKernel.Append) kernelOptions = append(kernelOptions, bpKernel.Append)
} }
pl.KernelOptionsAppend = kernelOptions pl.KernelOptionsAppend = kernelOptions
pl.KernelName = c.GetKernel().Name
pl.OSTreeParent = options.OSTree.Parent pl.OSTreeParent = options.OSTree.Parent
pl.OSTreeURL = options.OSTree.URL pl.OSTreeURL = options.OSTree.URL
pl.Repos = repos
pl.PackageSpecs = packages
pl.GPGKeyFiles = imageConfig.GPGKeyFiles pl.GPGKeyFiles = imageConfig.GPGKeyFiles
if !t.bootISO { if !t.bootISO {
@ -340,8 +313,7 @@ func osPipeline(buildPipeline *pipeline.BuildPipeline,
} }
func ostreeCommitPipeline(buildPipeline *pipeline.BuildPipeline, treePipeline *pipeline.OSPipeline, options distro.ImageOptions, osVersion string) pipeline.OSTreeCommitPipeline { func ostreeCommitPipeline(buildPipeline *pipeline.BuildPipeline, treePipeline *pipeline.OSPipeline, options distro.ImageOptions, osVersion string) pipeline.OSTreeCommitPipeline {
p := pipeline.NewOSTreeCommitPipeline(buildPipeline, treePipeline) p := pipeline.NewOSTreeCommitPipeline(buildPipeline, treePipeline, options.OSTree.Ref)
p.Ref = options.OSTree.Ref
p.OSVersion = osVersion p.OSVersion = osVersion
p.Parent = options.OSTree.Parent p.Parent = options.OSTree.Parent
return p return p
@ -369,30 +341,19 @@ func containerPipeline(buildPipeline *pipeline.BuildPipeline, treePipeline *pipe
return p return p
} }
func anacondaTreePipeline(buildPipeline *pipeline.BuildPipeline, repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, kernelVer, arch, product, osVersion, variant string, users bool) pipeline.AnacondaPipeline { func anacondaTreePipeline(buildPipeline *pipeline.BuildPipeline, repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, arch, product, osVersion, variant string, users bool) pipeline.AnacondaPipeline {
p := pipeline.NewAnacondaPipeline(buildPipeline) p := pipeline.NewAnacondaPipeline(buildPipeline, repos, packages, "kernel", arch, product, osVersion)
p.Repos = repos
p.PackageSpecs = packages
p.Users = users p.Users = users
p.KernelVer = kernelVer
p.Arch = arch
p.Product = product
p.OSVersion = osVersion
p.Variant = variant p.Variant = variant
p.Biosdevname = (p.Arch == distro.X86_64ArchName) p.Biosdevname = (arch == distro.X86_64ArchName)
return p return p
} }
func bootISOTreePipeline(buildPipeline *pipeline.BuildPipeline, treePipeline *pipeline.Pipeline, options distro.ImageOptions, kernelVer, arch, vendor, product, osVersion, isolabel string, users []blueprint.UserCustomization, groups []blueprint.GroupCustomization) pipeline.ISOTreePipeline { func bootISOTreePipeline(buildPipeline *pipeline.BuildPipeline, anacondaPipeline *pipeline.AnacondaPipeline, options distro.ImageOptions, vendor, isoLabelTempl string, users []blueprint.UserCustomization, groups []blueprint.GroupCustomization) pipeline.ISOTreePipeline {
p := pipeline.NewISOTreePipeline(buildPipeline, treePipeline) p := pipeline.NewISOTreePipeline(buildPipeline, anacondaPipeline, isoLabelTempl)
p.KernelVer = kernelVer
p.Arch = arch
p.Release = "202010217.n.0" p.Release = "202010217.n.0"
p.Vendor = vendor
p.Product = product
p.OSName = "fedora" p.OSName = "fedora"
p.OSVersion = osVersion p.Vendor = vendor
p.ISOLabel = isolabel
p.Users = users p.Users = users
p.Groups = groups p.Groups = groups
p.OSTreeRef = options.OSTree.Ref p.OSTreeRef = options.OSTree.Ref
@ -401,15 +362,14 @@ func bootISOTreePipeline(buildPipeline *pipeline.BuildPipeline, treePipeline *pi
return p return p
} }
func bootISOPipeline(buildPipeline *pipeline.BuildPipeline, treePipeline *pipeline.ISOTreePipeline, filename, isolabel string, isolinux bool) pipeline.ISOPipeline { func bootISOPipeline(buildPipeline *pipeline.BuildPipeline, treePipeline *pipeline.ISOTreePipeline, filename string, isolinux bool) pipeline.ISOPipeline {
p := pipeline.NewISOPipeline(buildPipeline, treePipeline) p := pipeline.NewISOPipeline(buildPipeline, treePipeline)
p.Filename = filename p.Filename = filename
p.ISOLabel = isolabel
p.ISOLinux = isolinux p.ISOLinux = isolinux
return p return p
} }
func liveImagePipeline(buildPipeline *pipeline.BuildPipeline, treePipeline *pipeline.OSPipeline, outputFilename string, pt *disk.PartitionTable, arch *architecture, kernelVer string) pipeline.LiveImgPipeline { func liveImagePipeline(buildPipeline *pipeline.BuildPipeline, treePipeline *pipeline.OSPipeline, outputFilename string, pt *disk.PartitionTable, arch *architecture) pipeline.LiveImgPipeline {
p := pipeline.NewLiveImgPipeline(buildPipeline, treePipeline) p := pipeline.NewLiveImgPipeline(buildPipeline, treePipeline)
p.Filename = outputFilename p.Filename = outputFilename
@ -421,7 +381,6 @@ func liveImagePipeline(buildPipeline *pipeline.BuildPipeline, treePipeline *pipe
p.GRUBLegacy = arch.legacy p.GRUBLegacy = arch.legacy
} }
p.KernelVer = kernelVer
p.PartitionTable = *pt p.PartitionTable = *pt
return p return p

View file

@ -5,34 +5,87 @@ import (
"github.com/osbuild/osbuild-composer/internal/rpmmd" "github.com/osbuild/osbuild-composer/internal/rpmmd"
) )
// An AnacondaPipeline represents the installer tree as found on an ISO.
type AnacondaPipeline struct { type AnacondaPipeline struct {
Pipeline Pipeline
Repos []rpmmd.RepoConfig // Users indicate whether or not the user spoke should be enabled in
PackageSpecs []rpmmd.PackageSpec // anaconda. If it is, users specified in a kickstart will be configured,
Users bool // and in case no users are provided in a kickstart the user will be
KernelVer string // prompted to configure them at install time. If this is set to false
Arch string // any kickstart provided users are ignored and the user is never
Product string // prompted to configure users during installation.
OSVersion string Users bool
Variant string // Biosdevname indicates whether or not biosdevname should be used to
Biosdevname bool // name network devices when booting the installer. This may affect
// the naming of network devices on the target system.
Biosdevname bool
// Variant is the variant of the product being installed.
// TODO: what should be the default value?
Variant string
repos []rpmmd.RepoConfig
packageSpecs []rpmmd.PackageSpec
kernelVer string
arch string
product string
version string
} }
func NewAnacondaPipeline(buildPipeline *BuildPipeline) AnacondaPipeline { // NewAnacondaPipeline creates an anaconda pipeline object. repos and packages
// indicate the content to build the installer from, which is distinct from the
// packages the installer will install on the target system. kernelName is the
// name of the kernel package the intsaller will use. arch is the supported
// architecture. Product and version refers to the product the installer is the
// installer for.
func NewAnacondaPipeline(buildPipeline *BuildPipeline,
repos []rpmmd.RepoConfig,
packages []rpmmd.PackageSpec,
kernelName,
arch,
product,
version string) AnacondaPipeline {
kernelVer := rpmmd.GetVerStrFromPackageSpecListPanic(packages, kernelName)
return AnacondaPipeline{ return AnacondaPipeline{
Pipeline: New("anaconda-tree", &buildPipeline.Pipeline), Pipeline: New("anaconda-tree", buildPipeline, nil),
repos: repos,
packageSpecs: packages,
kernelVer: kernelVer,
arch: arch,
product: product,
version: version,
} }
} }
// KernelVer returns the NEVRA of the kernel package the installer will use at
// install time.
func (p AnacondaPipeline) KernelVer() string {
return p.kernelVer
}
// Arch returns the supported architecture.
func (p AnacondaPipeline) Arch() string {
return p.arch
}
// Product returns the product being installed.
func (p AnacondaPipeline) Product() string {
return p.product
}
// Version returns the version of the product being installed.
func (p AnacondaPipeline) Version() string {
return p.version
}
func (p AnacondaPipeline) Serialize() osbuild2.Pipeline { func (p AnacondaPipeline) Serialize() osbuild2.Pipeline {
pipeline := p.Pipeline.Serialize() pipeline := p.Pipeline.Serialize()
pipeline.AddStage(osbuild2.NewRPMStage(osbuild2.NewRPMStageOptions(p.Repos), osbuild2.NewRpmStageSourceFilesInputs(p.PackageSpecs))) pipeline.AddStage(osbuild2.NewRPMStage(osbuild2.NewRPMStageOptions(p.repos), osbuild2.NewRpmStageSourceFilesInputs(p.packageSpecs)))
pipeline.AddStage(osbuild2.NewBuildstampStage(&osbuild2.BuildstampStageOptions{ pipeline.AddStage(osbuild2.NewBuildstampStage(&osbuild2.BuildstampStageOptions{
Arch: p.Arch, Arch: p.Arch(),
Product: p.Product, Product: p.Product(),
Version: p.OSVersion,
Variant: p.Variant, Variant: p.Variant,
Version: p.Version(),
Final: true, Final: true,
})) }))
pipeline.AddStage(osbuild2.NewLocaleStage(&osbuild2.LocaleStageOptions{Language: "en_US.UTF-8"})) pipeline.AddStage(osbuild2.NewLocaleStage(&osbuild2.LocaleStageOptions{Language: "en_US.UTF-8"}))
@ -65,9 +118,9 @@ func (p AnacondaPipeline) Serialize() osbuild2.Pipeline {
pipeline.AddStage(osbuild2.NewAnacondaStage(osbuild2.NewAnacondaStageOptions(p.Users))) pipeline.AddStage(osbuild2.NewAnacondaStage(osbuild2.NewAnacondaStageOptions(p.Users)))
pipeline.AddStage(osbuild2.NewLoraxScriptStage(&osbuild2.LoraxScriptStageOptions{ pipeline.AddStage(osbuild2.NewLoraxScriptStage(&osbuild2.LoraxScriptStageOptions{
Path: "99-generic/runtime-postinstall.tmpl", Path: "99-generic/runtime-postinstall.tmpl",
BaseArch: p.Arch, BaseArch: p.Arch(),
})) }))
pipeline.AddStage(osbuild2.NewDracutStage(dracutStageOptions(p.KernelVer, p.Biosdevname, []string{ pipeline.AddStage(osbuild2.NewDracutStage(dracutStageOptions(p.KernelVer(), p.Biosdevname, []string{
"anaconda", "anaconda",
"rdma", "rdma",
"rngd", "rngd",

View file

@ -7,22 +7,24 @@ import (
type BuildPipeline struct { type BuildPipeline struct {
Pipeline Pipeline
Repos []rpmmd.RepoConfig
PackageSpecs []rpmmd.PackageSpec repos []rpmmd.RepoConfig
packageSpecs []rpmmd.PackageSpec
} }
func NewBuildPipeline(runner string) BuildPipeline { func NewBuildPipeline(runner string, repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec) BuildPipeline {
pipeline := BuildPipeline{ pipeline := BuildPipeline{
Pipeline: New("build", nil), Pipeline: New("build", nil, &runner),
repos: repos,
packageSpecs: packages,
} }
pipeline.runner = &runner
return pipeline return pipeline
} }
func (p BuildPipeline) Serialize() osbuild2.Pipeline { func (p BuildPipeline) Serialize() osbuild2.Pipeline {
pipeline := p.Pipeline.Serialize() pipeline := p.Pipeline.Serialize()
pipeline.AddStage(osbuild2.NewRPMStage(osbuild2.NewRPMStageOptions(p.Repos), osbuild2.NewRpmStageSourceFilesInputs(p.PackageSpecs))) pipeline.AddStage(osbuild2.NewRPMStage(osbuild2.NewRPMStageOptions(p.repos), osbuild2.NewRpmStageSourceFilesInputs(p.packageSpecs)))
pipeline.AddStage(osbuild2.NewSELinuxStage(selinuxStageOptions(true))) pipeline.AddStage(osbuild2.NewSELinuxStage(selinuxStageOptions(true)))
return pipeline return pipeline

View file

@ -7,18 +7,24 @@ import (
type OSTreeCommitPipeline struct { type OSTreeCommitPipeline struct {
Pipeline Pipeline
treePipeline *OSPipeline treePipeline *OSPipeline
Ref string
OSVersion string OSVersion string
Parent string Parent string
ref string
} }
func NewOSTreeCommitPipeline(buildPipeline *BuildPipeline, treePipeline *OSPipeline) OSTreeCommitPipeline { func NewOSTreeCommitPipeline(buildPipeline *BuildPipeline, treePipeline *OSPipeline, ref string) OSTreeCommitPipeline {
return OSTreeCommitPipeline{ return OSTreeCommitPipeline{
Pipeline: New("ostree-commit", &buildPipeline.Pipeline), Pipeline: New("ostree-commit", buildPipeline, nil),
treePipeline: treePipeline, treePipeline: treePipeline,
ref: ref,
} }
} }
func (p OSTreeCommitPipeline) Ref() string {
return p.ref
}
func (p OSTreeCommitPipeline) Serialize() osbuild2.Pipeline { func (p OSTreeCommitPipeline) Serialize() osbuild2.Pipeline {
pipeline := p.Pipeline.Serialize() pipeline := p.Pipeline.Serialize()
@ -31,7 +37,7 @@ func (p OSTreeCommitPipeline) Serialize() osbuild2.Pipeline {
pipeline.AddStage(osbuild2.NewOSTreeCommitStage( pipeline.AddStage(osbuild2.NewOSTreeCommitStage(
&osbuild2.OSTreeCommitStageOptions{ &osbuild2.OSTreeCommitStageOptions{
Ref: p.Ref, Ref: p.Ref(),
OSVersion: p.OSVersion, OSVersion: p.OSVersion,
Parent: p.Parent, Parent: p.Parent,
}, },

View file

@ -20,7 +20,7 @@ type OSTreeCommitServerTreePipeline struct {
func NewOSTreeCommitServerTreePipeline(buildPipeline *BuildPipeline, commitPipeline *OSTreeCommitPipeline) OSTreeCommitServerTreePipeline { func NewOSTreeCommitServerTreePipeline(buildPipeline *BuildPipeline, commitPipeline *OSTreeCommitPipeline) OSTreeCommitServerTreePipeline {
return OSTreeCommitServerTreePipeline{ return OSTreeCommitServerTreePipeline{
Pipeline: New("container-tree", &buildPipeline.Pipeline), Pipeline: New("container-tree", buildPipeline, nil),
commitPipeline: commitPipeline, commitPipeline: commitPipeline,
Language: "en_US", Language: "en_US",
} }
@ -38,7 +38,7 @@ func (p OSTreeCommitServerTreePipeline) Serialize() osbuild2.Pipeline {
pipeline.AddStage(osbuild2.NewOSTreePullStage( pipeline.AddStage(osbuild2.NewOSTreePullStage(
&osbuild2.OSTreePullStageOptions{Repo: repoPath}, &osbuild2.OSTreePullStageOptions{Repo: repoPath},
osbuild2.NewOstreePullStageInputs("org.osbuild.pipeline", "name:"+p.commitPipeline.Name(), p.commitPipeline.Ref), osbuild2.NewOstreePullStageInputs("org.osbuild.pipeline", "name:"+p.commitPipeline.Name(), p.commitPipeline.Ref()),
)) ))
// make nginx log and lib directories world writeable, otherwise nginx can't start in // make nginx log and lib directories world writeable, otherwise nginx can't start in

View file

@ -8,13 +8,12 @@ type ISOPipeline struct {
Pipeline Pipeline
treePipeline *ISOTreePipeline treePipeline *ISOTreePipeline
Filename string Filename string
ISOLabel string
ISOLinux bool ISOLinux bool
} }
func NewISOPipeline(buildPipeline *BuildPipeline, treePipeline *ISOTreePipeline) ISOPipeline { func NewISOPipeline(buildPipeline *BuildPipeline, treePipeline *ISOTreePipeline) ISOPipeline {
return ISOPipeline{ return ISOPipeline{
Pipeline: New("bootiso", &buildPipeline.Pipeline), Pipeline: New("bootiso", buildPipeline, nil),
treePipeline: treePipeline, treePipeline: treePipeline,
} }
} }
@ -22,7 +21,7 @@ func NewISOPipeline(buildPipeline *BuildPipeline, treePipeline *ISOTreePipeline)
func (p ISOPipeline) Serialize() osbuild2.Pipeline { func (p ISOPipeline) Serialize() osbuild2.Pipeline {
pipeline := p.Pipeline.Serialize() pipeline := p.Pipeline.Serialize()
pipeline.AddStage(osbuild2.NewXorrisofsStage(xorrisofsStageOptions(p.Filename, p.ISOLabel, p.ISOLinux), osbuild2.NewXorrisofsStagePipelineTreeInputs(p.treePipeline.Name()))) pipeline.AddStage(osbuild2.NewXorrisofsStage(xorrisofsStageOptions(p.Filename, p.treePipeline.ISOLabel(), p.ISOLinux), osbuild2.NewXorrisofsStagePipelineTreeInputs(p.treePipeline.Name())))
pipeline.AddStage(osbuild2.NewImplantisomd5Stage(&osbuild2.Implantisomd5StageOptions{Filename: p.Filename})) pipeline.AddStage(osbuild2.NewImplantisomd5Stage(&osbuild2.Implantisomd5StageOptions{Filename: p.Filename}))
return pipeline return pipeline

View file

@ -11,35 +11,40 @@ import (
type ISOTreePipeline struct { type ISOTreePipeline struct {
Pipeline Pipeline
treePipeline *Pipeline anacondaPipeline *AnacondaPipeline
KernelVer string Vendor string
Arch string OSName string
Release string Release string
Vendor string Users []blueprint.UserCustomization
Product string Groups []blueprint.GroupCustomization
OSName string OSTreeParent string
OSVersion string OSTreeRef string
ISOLabel string
Users []blueprint.UserCustomization isoLabel string
Groups []blueprint.GroupCustomization
OSTreeParent string
OSTreeRef string
} }
func NewISOTreePipeline(buildPipeline *BuildPipeline, treePipeline *Pipeline) ISOTreePipeline { func NewISOTreePipeline(buildPipeline *BuildPipeline, anacondaPipeline *AnacondaPipeline, isoLabelTmpl string) ISOTreePipeline {
// TODO: replace isoLabelTmpl with more high-level properties
isoLabel := fmt.Sprintf(isoLabelTmpl, anacondaPipeline.Arch())
return ISOTreePipeline{ return ISOTreePipeline{
Pipeline: New("bootiso-tree", &buildPipeline.Pipeline), Pipeline: New("bootiso-tree", buildPipeline, nil),
treePipeline: treePipeline, anacondaPipeline: anacondaPipeline,
isoLabel: isoLabel,
} }
} }
func (p ISOTreePipeline) ISOLabel() string {
return p.isoLabel
}
func (p ISOTreePipeline) Serialize() osbuild2.Pipeline { func (p ISOTreePipeline) Serialize() osbuild2.Pipeline {
pipeline := p.Pipeline.Serialize() pipeline := p.Pipeline.Serialize()
kspath := "/osbuild.ks" kspath := "/osbuild.ks"
ostreeRepoPath := "/ostree/repo" ostreeRepoPath := "/ostree/repo"
pipeline.AddStage(osbuild2.NewBootISOMonoStage(bootISOMonoStageOptions(p.KernelVer, p.Arch, p.Vendor, p.Product, p.OSVersion, p.ISOLabel, kspath), osbuild2.NewBootISOMonoStagePipelineTreeInputs(p.treePipeline.Name()))) pipeline.AddStage(osbuild2.NewBootISOMonoStage(bootISOMonoStageOptions(p.anacondaPipeline.KernelVer(), p.anacondaPipeline.Arch(), p.Vendor, 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) kickstartOptions, err := osbuild2.NewKickstartStageOptions(kspath, "", p.Users, p.Groups, makeISORootPath(ostreeRepoPath), p.OSTreeRef, p.OSName)
if err != nil { if err != nil {
@ -48,7 +53,7 @@ func (p ISOTreePipeline) Serialize() osbuild2.Pipeline {
pipeline.AddStage(osbuild2.NewKickstartStage(kickstartOptions)) pipeline.AddStage(osbuild2.NewKickstartStage(kickstartOptions))
pipeline.AddStage(osbuild2.NewDiscinfoStage(&osbuild2.DiscinfoStageOptions{ pipeline.AddStage(osbuild2.NewDiscinfoStage(&osbuild2.DiscinfoStageOptions{
BaseArch: p.Arch, BaseArch: p.anacondaPipeline.Arch(),
Release: p.Release, Release: p.Release,
})) }))

View file

@ -10,15 +10,14 @@ type LiveImgPipeline struct {
PartitionTable disk.PartitionTable PartitionTable disk.PartitionTable
BootLoader BootLoader BootLoader BootLoader
GRUBLegacy string GRUBLegacy string
KernelVer string treePipeline *OSPipeline
treePipeline *Pipeline
Filename string Filename string
} }
func NewLiveImgPipeline(buildPipeline *BuildPipeline, treePipeline *OSPipeline) LiveImgPipeline { func NewLiveImgPipeline(buildPipeline *BuildPipeline, treePipeline *OSPipeline) LiveImgPipeline {
return LiveImgPipeline{ return LiveImgPipeline{
Pipeline: New("image", &buildPipeline.Pipeline), Pipeline: New("image", buildPipeline, nil),
treePipeline: &treePipeline.Pipeline, treePipeline: treePipeline,
} }
} }
@ -45,7 +44,7 @@ func (p LiveImgPipeline) Serialize() osbuild2.Pipeline {
} }
case BOOTLOADER_ZIPL: case BOOTLOADER_ZIPL:
loopback := osbuild2.NewLoopbackDevice(&osbuild2.LoopbackDeviceOptions{Filename: p.Filename}) loopback := osbuild2.NewLoopbackDevice(&osbuild2.LoopbackDeviceOptions{Filename: p.Filename})
pipeline.AddStage(osbuild2.NewZiplInstStage(osbuild2.NewZiplInstStageOptions(p.KernelVer, &p.PartitionTable), loopback, copyDevices, copyMounts)) pipeline.AddStage(osbuild2.NewZiplInstStage(osbuild2.NewZiplInstStageOptions(p.treePipeline.KernelVer(), &p.PartitionTable), loopback, copyDevices, copyMounts))
} }
return pipeline return pipeline

View file

@ -15,7 +15,7 @@ type OCIContainerPipeline struct {
func NewOCIContainerPipeline(buildPipeline *BuildPipeline, treePipeline *Pipeline) OCIContainerPipeline { func NewOCIContainerPipeline(buildPipeline *BuildPipeline, treePipeline *Pipeline) OCIContainerPipeline {
return OCIContainerPipeline{ return OCIContainerPipeline{
Pipeline: New("container", &buildPipeline.Pipeline), Pipeline: New("container", buildPipeline, nil),
treePipeline: treePipeline, treePipeline: treePipeline,
} }
} }

View file

@ -14,17 +14,13 @@ import (
type OSPipeline struct { type OSPipeline struct {
Pipeline Pipeline
osTree bool
OSTreeParent string OSTreeParent string
OSTreeURL string OSTreeURL string
KernelName string
KernelOptionsAppend []string KernelOptionsAppend []string
BootLoader BootLoader BootLoader BootLoader
UEFI bool UEFI bool
GRUBLegacy string GRUBLegacy string
Vendor string Vendor string
Repos []rpmmd.RepoConfig
PackageSpecs []rpmmd.PackageSpec
GPGKeyFiles []string GPGKeyFiles []string
PartitionTable *disk.PartitionTable PartitionTable *disk.PartitionTable
Language string Language string
@ -58,20 +54,33 @@ type OSPipeline struct {
AuthConfig *osbuild2.AuthconfigStageOptions AuthConfig *osbuild2.AuthconfigStageOptions
PwQuality *osbuild2.PwqualityConfStageOptions PwQuality *osbuild2.PwqualityConfStageOptions
WAAgentConfig *osbuild2.WAAgentConfStageOptions WAAgentConfig *osbuild2.WAAgentConfStageOptions
osTree bool
repos []rpmmd.RepoConfig
packageSpecs []rpmmd.PackageSpec
kernelVer string
} }
func NewOSPipeline(buildPipeline *BuildPipeline, osTree bool) OSPipeline { func NewOSPipeline(buildPipeline *BuildPipeline, osTree bool, repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, kernelName string) OSPipeline {
name := "os" name := "os"
if osTree { if osTree {
name = "ostree-tree" name = "ostree-tree"
} }
kernelVer := rpmmd.GetVerStrFromPackageSpecListPanic(packages, kernelName)
return OSPipeline{ return OSPipeline{
Pipeline: New(name, &buildPipeline.Pipeline), Pipeline: New(name, buildPipeline, nil),
osTree: osTree, osTree: osTree,
Hostname: "localhost.localdomain", repos: repos,
packageSpecs: packages,
kernelVer: kernelVer,
Hostname: "localhost.localdomain",
} }
} }
func (p OSPipeline) KernelVer() string {
return p.kernelVer
}
func (p OSPipeline) Serialize() osbuild2.Pipeline { func (p OSPipeline) Serialize() osbuild2.Pipeline {
pipeline := p.Pipeline.Serialize() pipeline := p.Pipeline.Serialize()
@ -79,9 +88,9 @@ func (p OSPipeline) Serialize() osbuild2.Pipeline {
pipeline.AddStage(osbuild2.NewOSTreePasswdStage("org.osbuild.source", p.OSTreeParent)) pipeline.AddStage(osbuild2.NewOSTreePasswdStage("org.osbuild.source", p.OSTreeParent))
} }
rpmOptions := osbuild2.NewRPMStageOptions(p.Repos) rpmOptions := osbuild2.NewRPMStageOptions(p.repos)
rpmOptions.GPGKeysFromTree = p.GPGKeyFiles rpmOptions.GPGKeysFromTree = p.GPGKeyFiles
pipeline.AddStage(osbuild2.NewRPMStage(rpmOptions, osbuild2.NewRpmStageSourceFilesInputs(p.PackageSpecs))) 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 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 {
@ -229,8 +238,7 @@ func (p OSPipeline) Serialize() osbuild2.Pipeline {
var bootloader *osbuild2.Stage var bootloader *osbuild2.Stage
switch p.BootLoader { switch p.BootLoader {
case BOOTLOADER_GRUB: case BOOTLOADER_GRUB:
kernelVer := rpmmd.GetVerStrFromPackageSpecListPanic(p.PackageSpecs, p.KernelName) options := osbuild2.NewGrub2StageOptionsUnified(p.PartitionTable, p.kernelVer, p.UEFI, p.GRUBLegacy, p.Vendor, false)
options := osbuild2.NewGrub2StageOptionsUnified(p.PartitionTable, kernelVer, p.UEFI, p.GRUBLegacy, p.Vendor, false)
if cfg := p.Grub2Config; cfg != nil { if cfg := p.Grub2Config; cfg != nil {
// TODO: don't store Grub2Config in OSPipeline, making the overrides unnecessary // TODO: don't store Grub2Config in OSPipeline, making the overrides unnecessary
// grub2.Config.Default is owned and set by `NewGrub2StageOptionsUnified` // grub2.Config.Default is owned and set by `NewGrub2StageOptionsUnified`

View file

@ -1,3 +1,9 @@
// Package pipeline implements a standard set of osbuild pipelines. A pipeline
// conceptually represents a named filesystem tree, optionally generated
// in a provided build root (represented by another pipeline). All inputs
// to a pipeline must be explicitly specified, either in terms of other
// pipeline, in terms of content addressable inputs or in terms of static
// parameters to the inherited Pipeline structs.
package pipeline package pipeline
import ( import (
@ -11,35 +17,55 @@ const (
BOOTLOADER_ZIPL BOOTLOADER_ZIPL
) )
// A Pipeline represents the core functionality shared between each of the pipeline
// implementations, and the Pipeline struct must be embedded in each of them.
type Pipeline struct { type Pipeline struct {
name string name string
runner *string runner string
build *Pipeline build *BuildPipeline
} }
// Name returns the name of the pipeline. The name must be unique for a given manifest.
// Pipeline names are used to refer to pipelines either as dependencies between pipelines
// or for exporting them.
func (p Pipeline) Name() string { func (p Pipeline) Name() string {
return p.name return p.name
} }
func New(name string, build *Pipeline) Pipeline { // New returns a generic Pipeline object. The name is mandatory, immutable and must
return Pipeline{ // be unique among all the pipelines used in a manifest, which is currently not enforced.
// The build argument is a pipeline representing a build root in which the rest of the
// pipeline is built. In order to ensure reproducibility a build pipeline must always be
// provided, except for int he build pipeline itself. When a build pipeline is not provided
// the build host's filesystem is used as the build root, and in this case a runner must be
// specified which knows how to interpret the host filesystem as a build root.
func New(name string, build *BuildPipeline, runner *string) Pipeline {
p := Pipeline{
name: name, name: name,
build: build, build: build,
} }
if runner != nil {
if build != nil {
panic("both runner and build pipeline specified")
}
p.runner = *runner
} else if build == nil {
panic("neither build pipeline nor runner specified")
}
return p
} }
// Serialize turns a given pipeline into an osbuild2.Pipeline object. This object is
// meant to be treated as opaque and not to be modified further outside of the pipeline
// package.
func (p Pipeline) Serialize() osbuild2.Pipeline { func (p Pipeline) Serialize() osbuild2.Pipeline {
var buildName string var buildName string
if p.build != nil { if p.build != nil {
buildName = "name:" + p.build.Name() buildName = "name:" + p.build.Name()
} }
var runner string
if p.runner != nil {
runner = *p.runner
}
return osbuild2.Pipeline{ return osbuild2.Pipeline{
Name: p.name, Name: p.name,
Runner: runner, Runner: p.runner,
Build: buildName, Build: buildName,
} }
} }

View file

@ -16,7 +16,7 @@ type QemuPipeline struct {
func NewQemuPipeline(buildPipeline *BuildPipeline, imgPipeline *LiveImgPipeline, name string) QemuPipeline { func NewQemuPipeline(buildPipeline *BuildPipeline, imgPipeline *LiveImgPipeline, name string) QemuPipeline {
return QemuPipeline{ return QemuPipeline{
Pipeline: New(name, &buildPipeline.Pipeline), Pipeline: New(name, buildPipeline, nil),
imgPipeline: &imgPipeline.Pipeline, imgPipeline: &imgPipeline.Pipeline,
} }
} }

View file

@ -12,7 +12,7 @@ type TarPipeline struct {
func NewTarPipeline(buildPipeline *BuildPipeline, inputPipeline *Pipeline, name string) TarPipeline { func NewTarPipeline(buildPipeline *BuildPipeline, inputPipeline *Pipeline, name string) TarPipeline {
return TarPipeline{ return TarPipeline{
Pipeline: New(name, &buildPipeline.Pipeline), Pipeline: New(name, buildPipeline, nil),
inputPipeline: inputPipeline, inputPipeline: inputPipeline,
} }
} }