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.
This commit is contained in:
Tom Gundersen 2022-06-29 20:53:02 +01:00
parent 28b8a790b5
commit 4961a17ba8
17 changed files with 181 additions and 101 deletions

View file

@ -490,7 +490,7 @@ func (a *architecture) Distro() distro.Distro {
return a.distro return a.distro
} }
type pipelinesFunc func(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet, rng *rand.Rand) ([]manifest.Pipeline, error) type pipelinesFunc func(m *manifest.Manifest, t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet, rng *rand.Rand) ([]manifest.Pipeline, error)
type packageSetFunc func(t *imageType) rpmmd.PackageSet type packageSetFunc func(t *imageType) rpmmd.PackageSet
@ -750,17 +750,12 @@ func (t *imageType) initializeManifest(customizations *blueprint.Customizations,
/* #nosec G404 */ /* #nosec G404 */
rng := rand.New(source) rng := rand.New(source)
pipelines, err := t.pipelines(t, customizations, options, repos, packageSetChains, rng) manifest := manifest.New()
_, err := t.pipelines(&manifest, t, customizations, options, repos, packageSetChains, rng)
if err != nil { if err != nil {
return nil, err return nil, err
} }
manifest := manifest.New()
for _, pipeline := range pipelines {
// TODO: make this implicit on pipeline creation to enforce manifest validitiy
manifest.AddPipeline(pipeline)
}
return &manifest, nil return &manifest, nil
} }

View file

@ -10,13 +10,13 @@ import (
"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, packageSetChains map[string][]rpmmd.PackageSet, rng *rand.Rand) ([]manifest.Pipeline, error) { func qcow2Pipelines(m *manifest.Manifest, t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet, rng *rand.Rand) ([]manifest.Pipeline, error) {
pipelines := make([]manifest.Pipeline, 0) pipelines := make([]manifest.Pipeline, 0)
buildPipeline := manifest.NewBuildPipeline(t.arch.distro.runner, repos) buildPipeline := manifest.NewBuildPipeline(m, t.arch.distro.runner, repos)
pipelines = append(pipelines, buildPipeline) pipelines = append(pipelines, buildPipeline)
treePipeline, err := osPipeline(buildPipeline, t, repos, customizations, options, rng) treePipeline, err := osPipeline(m, buildPipeline, t, repos, customizations, options, rng)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -34,23 +34,23 @@ func qcow2Pipelines(t *imageType, customizations *blueprint.Customizations, opti
} }
pipelines = append(pipelines, treePipeline) pipelines = append(pipelines, treePipeline)
imagePipeline := manifest.NewLiveImgPipeline(buildPipeline, treePipeline, "disk.img") imagePipeline := manifest.NewLiveImgPipeline(m, buildPipeline, treePipeline, "disk.img")
pipelines = append(pipelines, imagePipeline) pipelines = append(pipelines, imagePipeline)
qcow2Pipeline := manifest.NewQCOW2Pipeline(buildPipeline, imagePipeline, t.filename) qcow2Pipeline := manifest.NewQCOW2Pipeline(m, buildPipeline, imagePipeline, t.filename)
qcow2Pipeline.Compat = "1.1" qcow2Pipeline.Compat = "1.1"
pipelines = append(pipelines, qcow2Pipeline) pipelines = append(pipelines, qcow2Pipeline)
return pipelines, nil return pipelines, nil
} }
func vhdPipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet, rng *rand.Rand) ([]manifest.Pipeline, error) { func vhdPipelines(m *manifest.Manifest, t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet, rng *rand.Rand) ([]manifest.Pipeline, error) {
pipelines := make([]manifest.Pipeline, 0) pipelines := make([]manifest.Pipeline, 0)
buildPipeline := manifest.NewBuildPipeline(t.arch.distro.runner, repos) buildPipeline := manifest.NewBuildPipeline(m, t.arch.distro.runner, repos)
pipelines = append(pipelines, buildPipeline) pipelines = append(pipelines, buildPipeline)
treePipeline, err := osPipeline(buildPipeline, t, repos, customizations, options, rng) treePipeline, err := osPipeline(m, buildPipeline, t, repos, customizations, options, rng)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -68,21 +68,21 @@ func vhdPipelines(t *imageType, customizations *blueprint.Customizations, option
} }
pipelines = append(pipelines, treePipeline) pipelines = append(pipelines, treePipeline)
imagePipeline := manifest.NewLiveImgPipeline(buildPipeline, treePipeline, "disk.img") imagePipeline := manifest.NewLiveImgPipeline(m, buildPipeline, treePipeline, "disk.img")
pipelines = append(pipelines, imagePipeline) pipelines = append(pipelines, imagePipeline)
vpcPipeline := manifest.NewVPCPipeline(buildPipeline, imagePipeline, t.filename) vpcPipeline := manifest.NewVPCPipeline(m, buildPipeline, imagePipeline, t.filename)
pipelines = append(pipelines, vpcPipeline) pipelines = append(pipelines, vpcPipeline)
return pipelines, nil return pipelines, nil
} }
func vmdkPipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet, rng *rand.Rand) ([]manifest.Pipeline, error) { func vmdkPipelines(m *manifest.Manifest, t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet, rng *rand.Rand) ([]manifest.Pipeline, error) {
pipelines := make([]manifest.Pipeline, 0) pipelines := make([]manifest.Pipeline, 0)
buildPipeline := manifest.NewBuildPipeline(t.arch.distro.runner, repos) buildPipeline := manifest.NewBuildPipeline(m, t.arch.distro.runner, repos)
pipelines = append(pipelines, buildPipeline) pipelines = append(pipelines, buildPipeline)
treePipeline, err := osPipeline(buildPipeline, t, repos, customizations, options, rng) treePipeline, err := osPipeline(m, buildPipeline, t, repos, customizations, options, rng)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -100,21 +100,21 @@ func vmdkPipelines(t *imageType, customizations *blueprint.Customizations, optio
} }
pipelines = append(pipelines, treePipeline) pipelines = append(pipelines, treePipeline)
imagePipeline := manifest.NewLiveImgPipeline(buildPipeline, treePipeline, "disk.img") imagePipeline := manifest.NewLiveImgPipeline(m, buildPipeline, treePipeline, "disk.img")
pipelines = append(pipelines, imagePipeline) pipelines = append(pipelines, imagePipeline)
vmdkPipeline := manifest.NewVMDKPipeline(buildPipeline, imagePipeline, t.filename) vmdkPipeline := manifest.NewVMDKPipeline(m, buildPipeline, imagePipeline, t.filename)
pipelines = append(pipelines, vmdkPipeline) pipelines = append(pipelines, vmdkPipeline)
return pipelines, nil return pipelines, nil
} }
func openstackPipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet, rng *rand.Rand) ([]manifest.Pipeline, error) { func openstackPipelines(m *manifest.Manifest, t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet, rng *rand.Rand) ([]manifest.Pipeline, error) {
pipelines := make([]manifest.Pipeline, 0) pipelines := make([]manifest.Pipeline, 0)
buildPipeline := manifest.NewBuildPipeline(t.arch.distro.runner, repos) buildPipeline := manifest.NewBuildPipeline(m, t.arch.distro.runner, repos)
pipelines = append(pipelines, buildPipeline) pipelines = append(pipelines, buildPipeline)
treePipeline, err := osPipeline(buildPipeline, t, repos, customizations, options, rng) treePipeline, err := osPipeline(m, buildPipeline, t, repos, customizations, options, rng)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -132,23 +132,23 @@ func openstackPipelines(t *imageType, customizations *blueprint.Customizations,
} }
pipelines = append(pipelines, treePipeline) pipelines = append(pipelines, treePipeline)
imagePipeline := manifest.NewLiveImgPipeline(buildPipeline, treePipeline, "disk.img") imagePipeline := manifest.NewLiveImgPipeline(m, buildPipeline, treePipeline, "disk.img")
pipelines = append(pipelines, imagePipeline) pipelines = append(pipelines, imagePipeline)
qcow2Pipeline := manifest.NewQCOW2Pipeline(buildPipeline, imagePipeline, t.filename) qcow2Pipeline := manifest.NewQCOW2Pipeline(m, buildPipeline, imagePipeline, t.filename)
pipelines = append(pipelines, qcow2Pipeline) pipelines = append(pipelines, qcow2Pipeline)
return pipelines, nil return pipelines, nil
} }
func ec2CommonPipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, func ec2CommonPipelines(m *manifest.Manifest, t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions,
repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet, repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet,
rng *rand.Rand, diskfile string) ([]manifest.Pipeline, error) { rng *rand.Rand, diskfile string) ([]manifest.Pipeline, error) {
pipelines := make([]manifest.Pipeline, 0) pipelines := make([]manifest.Pipeline, 0)
buildPipeline := manifest.NewBuildPipeline(t.arch.distro.runner, repos) buildPipeline := manifest.NewBuildPipeline(m, t.arch.distro.runner, repos)
pipelines = append(pipelines, buildPipeline) pipelines = append(pipelines, buildPipeline)
treePipeline, err := osPipeline(buildPipeline, t, repos, customizations, options, rng) treePipeline, err := osPipeline(m, buildPipeline, t, repos, customizations, options, rng)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -166,30 +166,30 @@ func ec2CommonPipelines(t *imageType, customizations *blueprint.Customizations,
} }
pipelines = append(pipelines, treePipeline) pipelines = append(pipelines, treePipeline)
imagePipeline := manifest.NewLiveImgPipeline(buildPipeline, treePipeline, diskfile) imagePipeline := manifest.NewLiveImgPipeline(m, buildPipeline, treePipeline, diskfile)
pipelines = append(pipelines, imagePipeline) pipelines = append(pipelines, imagePipeline)
return pipelines, nil return pipelines, nil
} }
// ec2Pipelines returns pipelines which produce uncompressed EC2 images which are expected to use RHSM for content // ec2Pipelines returns pipelines which produce uncompressed EC2 images which are expected to use RHSM for content
func ec2Pipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, func ec2Pipelines(m *manifest.Manifest, t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions,
repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet, repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet,
rng *rand.Rand) ([]manifest.Pipeline, error) { rng *rand.Rand) ([]manifest.Pipeline, error) {
return ec2CommonPipelines(t, customizations, options, repos, packageSetChains, rng, t.Filename()) return ec2CommonPipelines(m, t, customizations, options, repos, packageSetChains, rng, t.Filename())
} }
func iotInstallerPipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, func iotInstallerPipelines(m *manifest.Manifest, t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions,
repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet, repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet,
rng *rand.Rand) ([]manifest.Pipeline, error) { rng *rand.Rand) ([]manifest.Pipeline, error) {
pipelines := make([]manifest.Pipeline, 0) pipelines := make([]manifest.Pipeline, 0)
buildPipeline := manifest.NewBuildPipeline(t.arch.distro.runner, repos) buildPipeline := manifest.NewBuildPipeline(m, t.arch.distro.runner, repos)
pipelines = append(pipelines, buildPipeline) pipelines = append(pipelines, buildPipeline)
d := t.arch.distro d := t.arch.distro
ksUsers := len(customizations.GetUsers())+len(customizations.GetGroups()) > 0 ksUsers := len(customizations.GetUsers())+len(customizations.GetGroups()) > 0
anacondaTreePipeline := anacondaTreePipeline(buildPipeline, repos, t.Arch().Name(), d.product, d.osVersion, "IoT", ksUsers) anacondaTreePipeline := anacondaTreePipeline(m, buildPipeline, repos, t.Arch().Name(), d.product, d.osVersion, "IoT", ksUsers)
installerChain := packageSetChains[installerPkgsKey] installerChain := packageSetChains[installerPkgsKey]
if len(installerChain) >= 1 { if len(installerChain) >= 1 {
anacondaTreePipeline.ExtraPackages = installerChain[0].Include anacondaTreePipeline.ExtraPackages = installerChain[0].Include
@ -197,16 +197,16 @@ func iotInstallerPipelines(t *imageType, customizations *blueprint.Customization
if len(installerChain) > 1 { if len(installerChain) > 1 {
panic("unexpected number of package sets in installer chain") panic("unexpected number of package sets in installer chain")
} }
isoTreePipeline := bootISOTreePipeline(buildPipeline, anacondaTreePipeline, options, d.vendor, d.isolabelTmpl, customizations.GetUsers(), customizations.GetGroups()) isoTreePipeline := bootISOTreePipeline(m, buildPipeline, anacondaTreePipeline, options, d.vendor, d.isolabelTmpl, customizations.GetUsers(), customizations.GetGroups())
isoPipeline := bootISOPipeline(buildPipeline, isoTreePipeline, t.Filename(), false) isoPipeline := bootISOPipeline(m, buildPipeline, isoTreePipeline, t.Filename(), false)
return append(pipelines, anacondaTreePipeline, isoTreePipeline, isoPipeline), nil return append(pipelines, anacondaTreePipeline, isoTreePipeline, isoPipeline), nil
} }
func iotCorePipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, func iotCorePipelines(m *manifest.Manifest, t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions,
repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet) (*manifest.BuildPipeline, *manifest.OSPipeline, *manifest.OSTreeCommitPipeline, error) { repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet) (*manifest.BuildPipeline, *manifest.OSPipeline, *manifest.OSTreeCommitPipeline, error) {
buildPipeline := manifest.NewBuildPipeline(t.arch.distro.runner, repos) buildPipeline := manifest.NewBuildPipeline(m, t.arch.distro.runner, repos)
treePipeline, err := osPipeline(buildPipeline, t, repos, customizations, options, nil) treePipeline, err := osPipeline(m, buildPipeline, t, repos, customizations, options, nil)
if err != nil { if err != nil {
return nil, nil, nil, err return nil, nil, nil, err
} }
@ -222,38 +222,38 @@ func iotCorePipelines(t *imageType, customizations *blueprint.Customizations, op
if len(osChain) > 2 { if len(osChain) > 2 {
panic("unexpected number of package sets in os chain") panic("unexpected number of package sets in os chain")
} }
commitPipeline := ostreeCommitPipeline(buildPipeline, treePipeline, options, t.arch.distro.osVersion) commitPipeline := ostreeCommitPipeline(m, buildPipeline, treePipeline, options, t.arch.distro.osVersion)
return buildPipeline, treePipeline, commitPipeline, nil return buildPipeline, treePipeline, commitPipeline, nil
} }
func iotCommitPipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, func iotCommitPipelines(m *manifest.Manifest, t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions,
repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet, repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet,
rng *rand.Rand) ([]manifest.Pipeline, error) { rng *rand.Rand) ([]manifest.Pipeline, error) {
pipelines := make([]manifest.Pipeline, 0) pipelines := make([]manifest.Pipeline, 0)
buildPipeline, treePipeline, commitPipeline, err := iotCorePipelines(t, customizations, options, repos, packageSetChains) buildPipeline, treePipeline, commitPipeline, err := iotCorePipelines(m, t, customizations, options, repos, packageSetChains)
if err != nil { if err != nil {
return nil, err return nil, err
} }
tarPipeline := manifest.NewTarPipeline(buildPipeline, &commitPipeline.BasePipeline, "commit-archive", t.Filename()) tarPipeline := manifest.NewTarPipeline(m, buildPipeline, &commitPipeline.BasePipeline, "commit-archive", t.Filename())
pipelines = append(pipelines, buildPipeline, treePipeline, commitPipeline, tarPipeline) pipelines = append(pipelines, buildPipeline, treePipeline, commitPipeline, tarPipeline)
return pipelines, nil return pipelines, nil
} }
func iotContainerPipelines(t *imageType, customizations *blueprint.Customizations, func iotContainerPipelines(m *manifest.Manifest, t *imageType, customizations *blueprint.Customizations,
options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet,
rng *rand.Rand) ([]manifest.Pipeline, error) { rng *rand.Rand) ([]manifest.Pipeline, error) {
pipelines := make([]manifest.Pipeline, 0) pipelines := make([]manifest.Pipeline, 0)
buildPipeline, treePipeline, commitPipeline, err := iotCorePipelines(t, customizations, options, repos, packageSetChains) buildPipeline, treePipeline, commitPipeline, err := iotCorePipelines(m, t, customizations, options, repos, packageSetChains)
if err != nil { if err != nil {
return nil, err return nil, err
} }
nginxConfigPath := "/etc/nginx.conf" nginxConfigPath := "/etc/nginx.conf"
httpPort := "8080" httpPort := "8080"
containerTreePipeline := containerTreePipeline(buildPipeline, commitPipeline, repos, options, customizations, nginxConfigPath, httpPort) containerTreePipeline := containerTreePipeline(m, buildPipeline, commitPipeline, repos, options, customizations, nginxConfigPath, httpPort)
containerChain := packageSetChains[osPkgsKey] containerChain := packageSetChains[osPkgsKey]
if len(containerChain) >= 1 { if len(containerChain) >= 1 {
containerTreePipeline.ExtraPackages = containerChain[0].Include containerTreePipeline.ExtraPackages = containerChain[0].Include
@ -261,13 +261,14 @@ func iotContainerPipelines(t *imageType, customizations *blueprint.Customization
if len(containerChain) > 2 { if len(containerChain) > 2 {
panic("unexpected number of package sets in os chain") panic("unexpected number of package sets in os chain")
} }
containerPipeline := containerPipeline(buildPipeline, &containerTreePipeline.BasePipeline, t, nginxConfigPath, httpPort) containerPipeline := containerPipeline(m, buildPipeline, &containerTreePipeline.BasePipeline, t, nginxConfigPath, httpPort)
pipelines = append(pipelines, buildPipeline, treePipeline, commitPipeline, containerTreePipeline, containerPipeline) pipelines = append(pipelines, buildPipeline, treePipeline, commitPipeline, containerTreePipeline, containerPipeline)
return pipelines, nil return pipelines, nil
} }
func osPipeline(buildPipeline *manifest.BuildPipeline, func osPipeline(m *manifest.Manifest,
buildPipeline *manifest.BuildPipeline,
t *imageType, t *imageType,
repos []rpmmd.RepoConfig, repos []rpmmd.RepoConfig,
c *blueprint.Customizations, c *blueprint.Customizations,
@ -298,7 +299,7 @@ func osPipeline(buildPipeline *manifest.BuildPipeline,
kernelName = c.GetKernel().Name kernelName = c.GetKernel().Name
} }
pl := manifest.NewOSPipeline(buildPipeline, t.rpmOstree, options.OSTree.Parent, options.OSTree.URL, repos, pt, bootLoader, t.arch.legacy, kernelName) pl := manifest.NewOSPipeline(m, buildPipeline, t.rpmOstree, options.OSTree.Parent, options.OSTree.URL, repos, pt, bootLoader, t.arch.legacy, kernelName)
if t.supportsUEFI() { if t.supportsUEFI() {
pl.UEFIVendor = t.arch.distro.vendor pl.UEFIVendor = t.arch.distro.vendor
@ -392,14 +393,14 @@ func osPipeline(buildPipeline *manifest.BuildPipeline,
return pl, nil return pl, nil
} }
func ostreeCommitPipeline(buildPipeline *manifest.BuildPipeline, treePipeline *manifest.OSPipeline, options distro.ImageOptions, osVersion string) *manifest.OSTreeCommitPipeline { func ostreeCommitPipeline(m *manifest.Manifest, buildPipeline *manifest.BuildPipeline, treePipeline *manifest.OSPipeline, options distro.ImageOptions, osVersion string) *manifest.OSTreeCommitPipeline {
p := manifest.NewOSTreeCommitPipeline(buildPipeline, treePipeline, options.OSTree.Ref) p := manifest.NewOSTreeCommitPipeline(m, buildPipeline, treePipeline, options.OSTree.Ref)
p.OSVersion = osVersion p.OSVersion = osVersion
return p return p
} }
func containerTreePipeline(buildPipeline *manifest.BuildPipeline, commitPipeline *manifest.OSTreeCommitPipeline, repos []rpmmd.RepoConfig, options distro.ImageOptions, c *blueprint.Customizations, nginxConfigPath, listenPort string) *manifest.OSTreeCommitServerTreePipeline { func containerTreePipeline(m *manifest.Manifest, buildPipeline *manifest.BuildPipeline, commitPipeline *manifest.OSTreeCommitPipeline, repos []rpmmd.RepoConfig, options distro.ImageOptions, c *blueprint.Customizations, nginxConfigPath, listenPort string) *manifest.OSTreeCommitServerTreePipeline {
p := manifest.NewOSTreeCommitServerTreePipeline(buildPipeline, repos, commitPipeline, nginxConfigPath, listenPort) p := manifest.NewOSTreeCommitServerTreePipeline(m, buildPipeline, repos, commitPipeline, nginxConfigPath, listenPort)
language, _ := c.GetPrimaryLocale() language, _ := c.GetPrimaryLocale()
if language != nil { if language != nil {
p.Language = *language p.Language = *language
@ -407,23 +408,23 @@ func containerTreePipeline(buildPipeline *manifest.BuildPipeline, commitPipeline
return p return p
} }
func containerPipeline(buildPipeline *manifest.BuildPipeline, treePipeline *manifest.BasePipeline, t *imageType, nginxConfigPath, listenPort string) *manifest.OCIContainerPipeline { func containerPipeline(m *manifest.Manifest, buildPipeline *manifest.BuildPipeline, treePipeline *manifest.BasePipeline, t *imageType, nginxConfigPath, listenPort string) *manifest.OCIContainerPipeline {
p := manifest.NewOCIContainerPipeline(buildPipeline, treePipeline, t.Arch().Name(), t.Filename()) p := manifest.NewOCIContainerPipeline(m, buildPipeline, treePipeline, t.Arch().Name(), t.Filename())
p.Cmd = []string{"nginx", "-c", nginxConfigPath} p.Cmd = []string{"nginx", "-c", nginxConfigPath}
p.ExposedPorts = []string{listenPort} p.ExposedPorts = []string{listenPort}
return p return p
} }
func anacondaTreePipeline(buildPipeline *manifest.BuildPipeline, repos []rpmmd.RepoConfig, arch, product, osVersion, variant string, users bool) *manifest.AnacondaPipeline { func anacondaTreePipeline(m *manifest.Manifest, buildPipeline *manifest.BuildPipeline, repos []rpmmd.RepoConfig, arch, product, osVersion, variant string, users bool) *manifest.AnacondaPipeline {
p := manifest.NewAnacondaPipeline(buildPipeline, repos, "kernel", arch, product, osVersion) p := manifest.NewAnacondaPipeline(m, buildPipeline, repos, "kernel", arch, product, osVersion)
p.Users = users p.Users = users
p.Variant = variant p.Variant = variant
p.Biosdevname = (arch == distro.X86_64ArchName) p.Biosdevname = (arch == distro.X86_64ArchName)
return p return p
} }
func bootISOTreePipeline(buildPipeline *manifest.BuildPipeline, anacondaPipeline *manifest.AnacondaPipeline, options distro.ImageOptions, vendor, isoLabelTempl string, users []blueprint.UserCustomization, groups []blueprint.GroupCustomization) *manifest.ISOTreePipeline { func bootISOTreePipeline(m *manifest.Manifest, buildPipeline *manifest.BuildPipeline, anacondaPipeline *manifest.AnacondaPipeline, options distro.ImageOptions, vendor, isoLabelTempl string, users []blueprint.UserCustomization, groups []blueprint.GroupCustomization) *manifest.ISOTreePipeline {
p := manifest.NewISOTreePipeline(buildPipeline, anacondaPipeline, options.OSTree.Parent, options.OSTree.URL, options.OSTree.Ref, isoLabelTempl) p := manifest.NewISOTreePipeline(m, buildPipeline, anacondaPipeline, options.OSTree.Parent, options.OSTree.URL, options.OSTree.Ref, isoLabelTempl)
p.Release = "202010217.n.0" p.Release = "202010217.n.0"
p.OSName = "fedora" p.OSName = "fedora"
p.UEFIVendor = vendor p.UEFIVendor = vendor
@ -433,19 +434,19 @@ func bootISOTreePipeline(buildPipeline *manifest.BuildPipeline, anacondaPipeline
return p return p
} }
func bootISOPipeline(buildPipeline *manifest.BuildPipeline, treePipeline *manifest.ISOTreePipeline, filename string, isolinux bool) *manifest.ISOPipeline { func bootISOPipeline(m *manifest.Manifest, buildPipeline *manifest.BuildPipeline, treePipeline *manifest.ISOTreePipeline, filename string, isolinux bool) *manifest.ISOPipeline {
p := manifest.NewISOPipeline(buildPipeline, treePipeline, filename) p := manifest.NewISOPipeline(m, buildPipeline, treePipeline, filename)
p.ISOLinux = isolinux p.ISOLinux = isolinux
return p return p
} }
func containerPipelines(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet, rng *rand.Rand) ([]manifest.Pipeline, error) { func containerPipelines(m *manifest.Manifest, t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetChains map[string][]rpmmd.PackageSet, rng *rand.Rand) ([]manifest.Pipeline, error) {
pipelines := make([]manifest.Pipeline, 0) pipelines := make([]manifest.Pipeline, 0)
buildPipeline := manifest.NewBuildPipeline(t.arch.distro.runner, repos) buildPipeline := manifest.NewBuildPipeline(m, t.arch.distro.runner, repos)
pipelines = append(pipelines, buildPipeline) pipelines = append(pipelines, buildPipeline)
treePipeline, err := osPipeline(buildPipeline, t, repos, customizations, options, rng) treePipeline, err := osPipeline(m, buildPipeline, t, repos, customizations, options, rng)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -463,7 +464,7 @@ func containerPipelines(t *imageType, customizations *blueprint.Customizations,
} }
pipelines = append(pipelines, treePipeline) pipelines = append(pipelines, treePipeline)
ociPipeline := manifest.NewOCIContainerPipeline(buildPipeline, &treePipeline.BasePipeline, t.Arch().Name(), t.Filename()) ociPipeline := manifest.NewOCIContainerPipeline(m, buildPipeline, &treePipeline.BasePipeline, t.Arch().Name(), t.Filename())
pipelines = append(pipelines, ociPipeline) pipelines = append(pipelines, ociPipeline)
return pipelines, nil return pipelines, nil

View file

@ -40,14 +40,15 @@ type AnacondaPipeline struct {
// name of the kernel package the intsaller will use. arch is the supported // 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 // architecture. Product and version refers to the product the installer is the
// installer for. // installer for.
func NewAnacondaPipeline(buildPipeline *BuildPipeline, func NewAnacondaPipeline(m *Manifest,
buildPipeline *BuildPipeline,
repos []rpmmd.RepoConfig, repos []rpmmd.RepoConfig,
kernelName, kernelName,
arch, arch,
product, product,
version string) *AnacondaPipeline { version string) *AnacondaPipeline {
p := &AnacondaPipeline{ p := &AnacondaPipeline{
BasePipeline: NewBasePipeline("anaconda-tree", buildPipeline, nil), BasePipeline: NewBasePipeline(m, "anaconda-tree", buildPipeline, nil),
repos: repos, repos: repos,
kernelName: kernelName, kernelName: kernelName,
arch: arch, arch: arch,
@ -55,6 +56,7 @@ func NewAnacondaPipeline(buildPipeline *BuildPipeline,
version: version, version: version,
} }
buildPipeline.addDependent(p) buildPipeline.addDependent(p)
m.addPipeline(p)
return p return p
} }

View file

@ -25,12 +25,13 @@ type BuildPipeline struct {
// NewBuildPipeline creates a new build pipeline from the repositories in repos // NewBuildPipeline creates a new build pipeline from the repositories in repos
// and the specified packages. // and the specified packages.
func NewBuildPipeline(runner string, repos []rpmmd.RepoConfig) *BuildPipeline { func NewBuildPipeline(m *Manifest, runner string, repos []rpmmd.RepoConfig) *BuildPipeline {
pipeline := &BuildPipeline{ pipeline := &BuildPipeline{
BasePipeline: NewBasePipeline("build", nil, &runner), BasePipeline: NewBasePipeline(m, "build", nil, &runner),
dependents: make([]Pipeline, 0), dependents: make([]Pipeline, 0),
repos: repos, repos: repos,
} }
m.addPipeline(pipeline)
return pipeline return pipeline
} }

View file

@ -16,13 +16,20 @@ type OSTreeCommitPipeline struct {
// NewOSTreeCommitPipeline creates a new OSTree commit pipeline. The // NewOSTreeCommitPipeline creates a new OSTree commit pipeline. The
// treePipeline is the tree representing the content of the commit. // treePipeline is the tree representing the content of the commit.
// ref is the ref to create the commit under. // ref is the ref to create the commit under.
func NewOSTreeCommitPipeline(buildPipeline *BuildPipeline, treePipeline *OSPipeline, ref string) *OSTreeCommitPipeline { func NewOSTreeCommitPipeline(m *Manifest,
buildPipeline *BuildPipeline,
treePipeline *OSPipeline,
ref string) *OSTreeCommitPipeline {
p := &OSTreeCommitPipeline{ p := &OSTreeCommitPipeline{
BasePipeline: NewBasePipeline("ostree-commit", buildPipeline, nil), BasePipeline: NewBasePipeline(m, "ostree-commit", buildPipeline, nil),
treePipeline: treePipeline, treePipeline: treePipeline,
ref: ref, ref: ref,
} }
if treePipeline.BasePipeline.manifest != m {
panic("tree pipeline from different manifest")
}
buildPipeline.addDependent(p) buildPipeline.addDependent(p)
m.addPipeline(p)
return p return p
} }

View file

@ -30,20 +30,25 @@ type OSTreeCommitServerTreePipeline struct {
// is a pipeline producing an ostree commit to be served. nginxConfigPath // is a pipeline producing an ostree commit to be served. nginxConfigPath
// is the path to the main nginx config file and listenPort is the port // is the path to the main nginx config file and listenPort is the port
// nginx will be listening on. // nginx will be listening on.
func NewOSTreeCommitServerTreePipeline(buildPipeline *BuildPipeline, func NewOSTreeCommitServerTreePipeline(m *Manifest,
buildPipeline *BuildPipeline,
repos []rpmmd.RepoConfig, repos []rpmmd.RepoConfig,
commitPipeline *OSTreeCommitPipeline, commitPipeline *OSTreeCommitPipeline,
nginxConfigPath, nginxConfigPath,
listenPort string) *OSTreeCommitServerTreePipeline { listenPort string) *OSTreeCommitServerTreePipeline {
p := &OSTreeCommitServerTreePipeline{ p := &OSTreeCommitServerTreePipeline{
BasePipeline: NewBasePipeline("container-tree", buildPipeline, nil), BasePipeline: NewBasePipeline(m, "container-tree", buildPipeline, nil),
repos: repos, repos: repos,
commitPipeline: commitPipeline, commitPipeline: commitPipeline,
nginxConfigPath: nginxConfigPath, nginxConfigPath: nginxConfigPath,
listenPort: listenPort, listenPort: listenPort,
Language: "en_US", Language: "en_US",
} }
if commitPipeline.BasePipeline.manifest != m {
panic("commit pipeline from different manifest")
}
buildPipeline.addDependent(p) buildPipeline.addDependent(p)
m.addPipeline(p)
return p return p
} }

View file

@ -14,13 +14,20 @@ type ISOPipeline struct {
filename string filename string
} }
func NewISOPipeline(buildPipeline *BuildPipeline, treePipeline *ISOTreePipeline, filename string) *ISOPipeline { func NewISOPipeline(m *Manifest,
buildPipeline *BuildPipeline,
treePipeline *ISOTreePipeline,
filename string) *ISOPipeline {
p := &ISOPipeline{ p := &ISOPipeline{
BasePipeline: NewBasePipeline("bootiso", buildPipeline, nil), BasePipeline: NewBasePipeline(m, "bootiso", buildPipeline, nil),
treePipeline: treePipeline, treePipeline: treePipeline,
filename: filename, filename: filename,
} }
buildPipeline.addDependent(p) buildPipeline.addDependent(p)
if treePipeline.BasePipeline.manifest != m {
panic("tree pipeline from different manifest")
}
m.addPipeline(p)
return p return p
} }

View file

@ -28,12 +28,18 @@ type ISOTreePipeline struct {
osTreeRef string osTreeRef string
} }
func NewISOTreePipeline(buildPipeline *BuildPipeline, anacondaPipeline *AnacondaPipeline, osTreeCommit, osTreeURL, osTreeRef, isoLabelTmpl string) *ISOTreePipeline { func NewISOTreePipeline(m *Manifest,
buildPipeline *BuildPipeline,
anacondaPipeline *AnacondaPipeline,
osTreeCommit,
osTreeURL,
osTreeRef,
isoLabelTmpl string) *ISOTreePipeline {
// TODO: replace isoLabelTmpl with more high-level properties // TODO: replace isoLabelTmpl with more high-level properties
isoLabel := fmt.Sprintf(isoLabelTmpl, anacondaPipeline.arch) isoLabel := fmt.Sprintf(isoLabelTmpl, anacondaPipeline.arch)
p := &ISOTreePipeline{ p := &ISOTreePipeline{
BasePipeline: NewBasePipeline("bootiso-tree", buildPipeline, nil), BasePipeline: NewBasePipeline(m, "bootiso-tree", buildPipeline, nil),
anacondaPipeline: anacondaPipeline, anacondaPipeline: anacondaPipeline,
isoLabel: isoLabel, isoLabel: isoLabel,
osTreeCommit: osTreeCommit, osTreeCommit: osTreeCommit,
@ -41,6 +47,10 @@ func NewISOTreePipeline(buildPipeline *BuildPipeline, anacondaPipeline *Anaconda
osTreeRef: osTreeRef, osTreeRef: osTreeRef,
} }
buildPipeline.addDependent(p) buildPipeline.addDependent(p)
if anacondaPipeline.BasePipeline.manifest != m {
panic("anaconda pipeline from different manifest")
}
m.addPipeline(p)
return p return p
} }

View file

@ -13,13 +13,20 @@ type LiveImgPipeline struct {
filename string filename string
} }
func NewLiveImgPipeline(buildPipeline *BuildPipeline, treePipeline *OSPipeline, filename string) *LiveImgPipeline { func NewLiveImgPipeline(m *Manifest,
buildPipeline *BuildPipeline,
treePipeline *OSPipeline,
filename string) *LiveImgPipeline {
p := &LiveImgPipeline{ p := &LiveImgPipeline{
BasePipeline: NewBasePipeline("image", buildPipeline, nil), BasePipeline: NewBasePipeline(m, "image", buildPipeline, nil),
treePipeline: treePipeline, treePipeline: treePipeline,
filename: filename, filename: filename,
} }
buildPipeline.addDependent(p) buildPipeline.addDependent(p)
if treePipeline.BasePipeline.manifest != m {
panic("tree pipeline from different manifest")
}
m.addPipeline(p)
return p return p
} }

View file

@ -28,7 +28,7 @@ func New() Manifest {
} }
} }
func (m *Manifest) AddPipeline(p Pipeline) { func (m *Manifest) addPipeline(p Pipeline) {
for _, pipeline := range m.pipelines { for _, pipeline := range m.pipelines {
if pipeline.Name() == p.Name() { if pipeline.Name() == p.Name() {
panic("duplicate pipeline name in manifest") panic("duplicate pipeline name in manifest")

View file

@ -16,14 +16,22 @@ type OCIContainerPipeline struct {
filename string filename string
} }
func NewOCIContainerPipeline(buildPipeline *BuildPipeline, treePipeline *BasePipeline, architecture, filename string) *OCIContainerPipeline { func NewOCIContainerPipeline(m *Manifest,
buildPipeline *BuildPipeline,
treePipeline *BasePipeline,
architecture,
filename string) *OCIContainerPipeline {
p := &OCIContainerPipeline{ p := &OCIContainerPipeline{
BasePipeline: NewBasePipeline("container", buildPipeline, nil), BasePipeline: NewBasePipeline(m, "container", buildPipeline, nil),
treePipeline: treePipeline, treePipeline: treePipeline,
architecture: architecture, architecture: architecture,
filename: filename, filename: filename,
} }
if treePipeline.build.BasePipeline.manifest != m {
panic("tree pipeline from different manifest")
}
buildPipeline.addDependent(p) buildPipeline.addDependent(p)
m.addPipeline(p)
return p return p
} }

View file

@ -102,7 +102,8 @@ type OSPipeline struct {
// are the depsolved pacakges to be installed into the tree. partitionTable // are the depsolved pacakges to be installed into the tree. partitionTable
// represents the disk layout of the target system. kernelName is the name of the // represents the disk layout of the target system. kernelName is the name of the
// kernel package that will be used on the target system. // kernel package that will be used on the target system.
func NewOSPipeline(buildPipeline *BuildPipeline, func NewOSPipeline(m *Manifest,
buildPipeline *BuildPipeline,
osTree bool, osTree bool,
osTreeParent string, osTreeParent string,
osTreeURL string, osTreeURL string,
@ -116,7 +117,7 @@ func NewOSPipeline(buildPipeline *BuildPipeline,
name = "ostree-tree" name = "ostree-tree"
} }
p := &OSPipeline{ p := &OSPipeline{
BasePipeline: NewBasePipeline(name, buildPipeline, nil), BasePipeline: NewBasePipeline(m, name, buildPipeline, nil),
osTree: osTree, osTree: osTree,
osTreeParent: osTreeParent, osTreeParent: osTreeParent,
osTreeURL: osTreeURL, osTreeURL: osTreeURL,
@ -131,6 +132,7 @@ func NewOSPipeline(buildPipeline *BuildPipeline,
SElinux: "targeted", SElinux: "targeted",
} }
buildPipeline.addDependent(p) buildPipeline.addDependent(p)
m.addPipeline(p)
return p return p
} }

View file

@ -26,9 +26,10 @@ type Pipeline interface {
// A BasePipeline represents the core functionality shared between each of the pipeline // A BasePipeline represents the core functionality shared between each of the pipeline
// implementations, and the BasePipeline struct must be embedded in each of them. // implementations, and the BasePipeline struct must be embedded in each of them.
type BasePipeline struct { type BasePipeline struct {
name string manifest *Manifest
runner string name string
build *BuildPipeline runner string
build *BuildPipeline
} }
// Name returns the name of the pipeline. The name must be unique for a given manifest. // Name returns the name of the pipeline. The name must be unique for a given manifest.
@ -65,10 +66,11 @@ func (p BasePipeline) getInline() []string {
// provided, except for int he build pipeline itself. When a build pipeline is not provided // 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 // 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. // specified which knows how to interpret the host filesystem as a build root.
func NewBasePipeline(name string, build *BuildPipeline, runner *string) BasePipeline { func NewBasePipeline(m *Manifest, name string, build *BuildPipeline, runner *string) BasePipeline {
p := BasePipeline{ p := BasePipeline{
name: name, manifest: m,
build: build, name: name,
build: build,
} }
if runner != nil { if runner != nil {
if build != nil { if build != nil {
@ -77,6 +79,10 @@ func NewBasePipeline(name string, build *BuildPipeline, runner *string) BasePipe
p.runner = *runner p.runner = *runner
} else if build == nil { } else if build == nil {
panic("neither build pipeline nor runner specified") panic("neither build pipeline nor runner specified")
} else {
if build.BasePipeline.manifest != m {
panic("build pipeline from a different manifest")
}
} }
return p return p
} }

View file

@ -16,13 +16,20 @@ type QCOW2Pipeline struct {
// NewQCOW2Pipeline createsa new QCOW2 pipeline. imgPipeline is the pipeline producing the // NewQCOW2Pipeline createsa new QCOW2 pipeline. imgPipeline is the pipeline producing the
// raw image. The pipeline name is the name of the new pipeline. Filename is the name // raw image. The pipeline name is the name of the new pipeline. Filename is the name
// of the produced qcow2 image. // of the produced qcow2 image.
func NewQCOW2Pipeline(buildPipeline *BuildPipeline, imgPipeline *LiveImgPipeline, filename string) *QCOW2Pipeline { func NewQCOW2Pipeline(m *Manifest,
buildPipeline *BuildPipeline,
imgPipeline *LiveImgPipeline,
filename string) *QCOW2Pipeline {
p := &QCOW2Pipeline{ p := &QCOW2Pipeline{
BasePipeline: NewBasePipeline("qcow2", buildPipeline, nil), BasePipeline: NewBasePipeline(m, "qcow2", buildPipeline, nil),
imgPipeline: imgPipeline, imgPipeline: imgPipeline,
filename: filename, filename: filename,
} }
if imgPipeline.BasePipeline.manifest != m {
panic("live image pipeline from different manifest")
}
buildPipeline.addDependent(p) buildPipeline.addDependent(p)
m.addPipeline(p)
return p return p
} }

View file

@ -14,13 +14,21 @@ type TarPipeline struct {
// NewTarPipeline creates a new TarPipeline. The inputPipeline represents the // NewTarPipeline creates a new TarPipeline. The inputPipeline represents the
// filesystem tree which will be the contents of the tar file. The pipelinename // filesystem tree which will be the contents of the tar file. The pipelinename
// is the name of the pipeline. The filename is the name of the output tar file. // is the name of the pipeline. The filename is the name of the output tar file.
func NewTarPipeline(buildPipeline *BuildPipeline, inputPipeline *BasePipeline, pipelinename, filename string) *TarPipeline { func NewTarPipeline(m *Manifest,
buildPipeline *BuildPipeline,
inputPipeline *BasePipeline,
pipelinename,
filename string) *TarPipeline {
p := &TarPipeline{ p := &TarPipeline{
BasePipeline: NewBasePipeline(pipelinename, buildPipeline, nil), BasePipeline: NewBasePipeline(m, pipelinename, buildPipeline, nil),
inputPipeline: inputPipeline, inputPipeline: inputPipeline,
filename: filename, filename: filename,
} }
if inputPipeline.manifest != m {
panic("tree pipeline from different manifest")
}
buildPipeline.addDependent(p) buildPipeline.addDependent(p)
m.addPipeline(p)
return p return p
} }

View file

@ -14,13 +14,20 @@ type VMDKPipeline struct {
// NewVMDKPipeline creates a new VMDK pipeline. imgPipeline is the pipeline producing the // NewVMDKPipeline creates a new VMDK pipeline. imgPipeline is the pipeline producing the
// raw image. Filename is the name of the produced image. // raw image. Filename is the name of the produced image.
func NewVMDKPipeline(buildPipeline *BuildPipeline, imgPipeline *LiveImgPipeline, filename string) *VMDKPipeline { func NewVMDKPipeline(m *Manifest,
buildPipeline *BuildPipeline,
imgPipeline *LiveImgPipeline,
filename string) *VMDKPipeline {
p := &VMDKPipeline{ p := &VMDKPipeline{
BasePipeline: NewBasePipeline("vmdk", buildPipeline, nil), BasePipeline: NewBasePipeline(m, "vmdk", buildPipeline, nil),
imgPipeline: imgPipeline, imgPipeline: imgPipeline,
filename: filename, filename: filename,
} }
if imgPipeline.BasePipeline.manifest != m {
panic("live image pipeline from different manifest")
}
buildPipeline.addDependent(p) buildPipeline.addDependent(p)
m.addPipeline(p)
return p return p
} }

View file

@ -15,13 +15,20 @@ type VPCPipeline struct {
// NewVPCPipeline createsa new Qemu pipeline. imgPipeline is the pipeline producing the // NewVPCPipeline createsa new Qemu pipeline. imgPipeline is the pipeline producing the
// raw image. The pipeline name is the name of the new pipeline. Filename is the name // raw image. The pipeline name is the name of the new pipeline. Filename is the name
// of the produced image. // of the produced image.
func NewVPCPipeline(buildPipeline *BuildPipeline, imgPipeline *LiveImgPipeline, filename string) *VPCPipeline { func NewVPCPipeline(m *Manifest,
buildPipeline *BuildPipeline,
imgPipeline *LiveImgPipeline,
filename string) *VPCPipeline {
p := &VPCPipeline{ p := &VPCPipeline{
BasePipeline: NewBasePipeline("vpc", buildPipeline, nil), BasePipeline: NewBasePipeline(m, "vpc", buildPipeline, nil),
imgPipeline: imgPipeline, imgPipeline: imgPipeline,
filename: filename, filename: filename,
} }
if imgPipeline.BasePipeline.manifest != m {
panic("live image pipeline from different manifest")
}
buildPipeline.addDependent(p) buildPipeline.addDependent(p)
m.addPipeline(p)
return p return p
} }