runner: introduce runner abstraction

For now all it does is represent the name of the runner and what requirements
it has of the build pipeline.

Move some package definitions from the runner package set to where it belongs.
This commit is contained in:
Tom Gundersen 2022-07-08 01:34:38 +01:00
parent 33fe2da25c
commit 529bc803db
22 changed files with 101 additions and 40 deletions

View file

@ -14,13 +14,14 @@ import (
"github.com/osbuild/osbuild-composer/internal/distroregistry"
"github.com/osbuild/osbuild-composer/internal/manifest"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
"github.com/osbuild/osbuild-composer/internal/runner"
)
var ImageTypes = make(map[string]ImageType)
type ImageType interface {
Name() string
InstantiateManifest(m *manifest.Manifest, repos []rpmmd.RepoConfig, runner string) error
InstantiateManifest(m *manifest.Manifest, repos []rpmmd.RepoConfig, runner runner.Runner) error
GetExports() []string
GetCheckpoints() []string
}

View file

@ -4,6 +4,7 @@ import (
"github.com/osbuild/osbuild-composer/internal/manifest"
"github.com/osbuild/osbuild-composer/internal/platform"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
"github.com/osbuild/osbuild-composer/internal/runner"
)
func init() {
@ -35,7 +36,7 @@ func (img *MyImage) Name() string {
// Return nil when you are done, or an error if something
// went wrong. Your manifest will be streamed to osbuild
// for building.
func (img *MyImage) InstantiateManifest(m *manifest.Manifest, repos []rpmmd.RepoConfig, runner string) error {
func (img *MyImage) InstantiateManifest(m *manifest.Manifest, repos []rpmmd.RepoConfig, runner runner.Runner) error {
// Let's create a simple OCI container!
// configure a build pipeline

View file

@ -10,6 +10,7 @@ import (
"github.com/osbuild/osbuild-composer/internal/manifest"
"github.com/osbuild/osbuild-composer/internal/osbuild2"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
"github.com/osbuild/osbuild-composer/internal/runner"
)
func RunPlayground(img ImageType, d distro.Distro, arch distro.Arch, repos map[string][]rpmmd.RepoConfig, state_dir string) {
@ -22,8 +23,8 @@ func RunPlayground(img ImageType, d distro.Distro, arch distro.Arch, repos map[s
manifest := manifest.New()
// TODO: figure out the runner situation
err := img.InstantiateManifest(&manifest, repos[arch.Name()], "org.osbuild.fedora36")
// TODO: query distro for runner
err := img.InstantiateManifest(&manifest, repos[arch.Name()], &runner.Fedora{Version: 36})
if err != nil {
panic("InstantiateManifest() failed: " + err.Error())
}

View file

@ -14,6 +14,7 @@ import (
"github.com/osbuild/osbuild-composer/internal/manifest"
"github.com/osbuild/osbuild-composer/internal/platform"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
"github.com/osbuild/osbuild-composer/internal/runner"
"github.com/osbuild/osbuild-composer/internal/workload"
)
@ -289,7 +290,7 @@ type distribution struct {
vendor string
ostreeRefTmpl string
isolabelTmpl string
runner string
runner runner.Runner
arches map[string]distro.Arch
defaultImageConfig *distro.ImageConfig
}
@ -311,7 +312,7 @@ var distroMap = map[string]distribution{
vendor: "fedora",
ostreeRefTmpl: "fedora/34/%s/iot",
isolabelTmpl: "Fedora-34-BaseOS-%s",
runner: "org.osbuild.fedora34",
runner: &runner.Fedora{Version: 34},
defaultImageConfig: defaultDistroImageConfig,
},
fedora35Distribution: {
@ -323,7 +324,7 @@ var distroMap = map[string]distribution{
vendor: "fedora",
ostreeRefTmpl: "fedora/35/%s/iot",
isolabelTmpl: "Fedora-35-BaseOS-%s",
runner: "org.osbuild.fedora35",
runner: &runner.Fedora{Version: 35},
defaultImageConfig: defaultDistroImageConfig,
},
fedora36Distribution: {
@ -335,7 +336,7 @@ var distroMap = map[string]distribution{
vendor: "fedora",
ostreeRefTmpl: "fedora/36/%s/iot",
isolabelTmpl: "Fedora-36-BaseOS-%s",
runner: "org.osbuild.fedora36",
runner: &runner.Fedora{Version: 36},
defaultImageConfig: defaultDistroImageConfig,
},
}

View file

@ -52,7 +52,7 @@ func NewAnacondaPipeline(m *Manifest,
product,
version string) *AnacondaPipeline {
p := &AnacondaPipeline{
BasePipeline: NewBasePipeline(m, "anaconda-tree", buildPipeline, nil),
BasePipeline: NewBasePipeline(m, "anaconda-tree", buildPipeline),
repos: repos,
kernelName: kernelName,
arch: arch,

View file

@ -3,6 +3,7 @@ package manifest
import (
"github.com/osbuild/osbuild-composer/internal/osbuild2"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
"github.com/osbuild/osbuild-composer/internal/runner"
)
// A BuildPipeline represents the build environment for other pipelines. As a
@ -15,6 +16,7 @@ import (
type BuildPipeline struct {
BasePipeline
runner runner.Runner
dependents []Pipeline
repos []rpmmd.RepoConfig
packageSpecs []rpmmd.PackageSpec
@ -22,9 +24,10 @@ type BuildPipeline struct {
// NewBuildPipeline creates a new build pipeline from the repositories in repos
// and the specified packages.
func NewBuildPipeline(m *Manifest, runner string, repos []rpmmd.RepoConfig) *BuildPipeline {
func NewBuildPipeline(m *Manifest, runner runner.Runner, repos []rpmmd.RepoConfig) *BuildPipeline {
pipeline := &BuildPipeline{
BasePipeline: NewBasePipeline(m, "build", nil, &runner),
BasePipeline: NewBasePipeline(m, "build", nil),
runner: runner,
dependents: make([]Pipeline, 0),
repos: repos,
}
@ -37,17 +40,16 @@ func (p *BuildPipeline) addDependent(dep Pipeline) {
}
func (p *BuildPipeline) getPackageSetChain() []rpmmd.PackageSet {
// TODO: have a runner abstraction that provides the necessary packages
// TODO: make the /usr/bin/cp dependency conditional
// TODO: make the /usr/bin/xz dependency conditional
packages := []string{
"selinux-policy-targeted", // needed to build the build pipeline
"coreutils", // /usr/bin/cp - used all over
"glibc", // ldconfig - used in the runner
"systemd", // systemd-tmpfiles and systemd-sysusers - used in the runner
"xz", // usage unclear
}
packages = append(packages, p.runner.GetBuildPackages()...)
for _, pipeline := range p.dependents {
packages = append(packages, pipeline.getBuildPackages()...)
}
@ -83,6 +85,7 @@ func (p *BuildPipeline) serialize() osbuild2.Pipeline {
panic("serialization not started")
}
pipeline := p.BasePipeline.serialize()
pipeline.Runner = p.runner.String()
pipeline.AddStage(osbuild2.NewRPMStage(osbuild2.NewRPMStageOptions(p.repos), osbuild2.NewRpmStageSourceFilesInputs(p.packageSpecs)))
pipeline.AddStage(osbuild2.NewSELinuxStage(&osbuild2.SELinuxStageOptions{

View file

@ -21,7 +21,7 @@ func NewOSTreeCommitPipeline(m *Manifest,
treePipeline *OSPipeline,
ref string) *OSTreeCommitPipeline {
p := &OSTreeCommitPipeline{
BasePipeline: NewBasePipeline(m, "ostree-commit", buildPipeline, nil),
BasePipeline: NewBasePipeline(m, "ostree-commit", buildPipeline),
treePipeline: treePipeline,
ref: ref,
}

View file

@ -39,7 +39,7 @@ func NewOSTreeCommitServerTreePipeline(m *Manifest,
nginxConfigPath,
listenPort string) *OSTreeCommitServerTreePipeline {
p := &OSTreeCommitServerTreePipeline{
BasePipeline: NewBasePipeline(m, "container-tree", buildPipeline, nil),
BasePipeline: NewBasePipeline(m, "container-tree", buildPipeline),
repos: repos,
commitPipeline: commitPipeline,
nginxConfigPath: nginxConfigPath,

View file

@ -19,7 +19,7 @@ func NewISOPipeline(m *Manifest,
treePipeline *ISOTreePipeline,
filename string) *ISOPipeline {
p := &ISOPipeline{
BasePipeline: NewBasePipeline(m, "bootiso", buildPipeline, nil),
BasePipeline: NewBasePipeline(m, "bootiso", buildPipeline),
treePipeline: treePipeline,
filename: filename,
}

View file

@ -39,7 +39,7 @@ func NewISOTreePipeline(m *Manifest,
isoLabel := fmt.Sprintf(isoLabelTmpl, anacondaPipeline.arch)
p := &ISOTreePipeline{
BasePipeline: NewBasePipeline(m, "bootiso-tree", buildPipeline, nil),
BasePipeline: NewBasePipeline(m, "bootiso-tree", buildPipeline),
anacondaPipeline: anacondaPipeline,
isoLabel: isoLabel,
osTreeCommit: osTreeCommit,

View file

@ -19,7 +19,7 @@ func NewLiveImgPipeline(m *Manifest,
treePipeline *OSPipeline,
filename string) *LiveImgPipeline {
p := &LiveImgPipeline{
BasePipeline: NewBasePipeline(m, "image", buildPipeline, nil),
BasePipeline: NewBasePipeline(m, "image", buildPipeline),
treePipeline: treePipeline,
filename: filename,
}

View file

@ -22,7 +22,7 @@ func NewOCIContainerPipeline(m *Manifest,
architecture,
filename string) *OCIContainerPipeline {
p := &OCIContainerPipeline{
BasePipeline: NewBasePipeline(m, "container", buildPipeline, nil),
BasePipeline: NewBasePipeline(m, "container", buildPipeline),
treePipeline: treePipeline,
architecture: architecture,
filename: filename,

View file

@ -110,7 +110,7 @@ func NewOSPipeline(m *Manifest,
platform platform.Platform,
repos []rpmmd.RepoConfig) *OSPipeline {
p := &OSPipeline{
BasePipeline: NewBasePipeline(m, "os", buildPipeline, nil),
BasePipeline: NewBasePipeline(m, "os", buildPipeline),
repos: repos,
platform: platform,
Language: "C.UTF-8",

View file

@ -28,7 +28,6 @@ type Pipeline interface {
type BasePipeline struct {
manifest *Manifest
name string
runner string
build *BuildPipeline
}
@ -67,7 +66,7 @@ func (p BasePipeline) getInline() []string {
// the build host's filesystem is used as the build root. The runner specifies how to use this
// pipeline as a build pipeline, by naming the distro it contains. When the host system is used
// as a build root, then the necessary runner is autodetected.
func NewBasePipeline(m *Manifest, name string, build *BuildPipeline, runner *string) BasePipeline {
func NewBasePipeline(m *Manifest, name string, build *BuildPipeline) BasePipeline {
p := BasePipeline{
manifest: m,
name: name,
@ -77,12 +76,6 @@ func NewBasePipeline(m *Manifest, name string, build *BuildPipeline, runner *str
if build.BasePipeline.manifest != m {
panic("build pipeline from a different manifest")
}
if build.BasePipeline.runner == "" {
panic("build pipeline does not have runner")
}
}
if runner != nil {
p.runner = *runner
}
return p
}
@ -101,13 +94,11 @@ func (p BasePipeline) serializeEnd() {
// meant to be treated as opaque and not to be modified further outside of the pipeline
// package.
func (p BasePipeline) serialize() osbuild2.Pipeline {
var buildName string
pipeline := osbuild2.Pipeline{
Name: p.name,
}
if p.build != nil {
buildName = "name:" + p.build.Name()
}
return osbuild2.Pipeline{
Name: p.name,
Runner: p.runner,
Build: buildName,
pipeline.Build = "name:" + p.build.Name()
}
return pipeline
}

View file

@ -21,7 +21,7 @@ func NewQCOW2Pipeline(m *Manifest,
imgPipeline *LiveImgPipeline,
filename string) *QCOW2Pipeline {
p := &QCOW2Pipeline{
BasePipeline: NewBasePipeline(m, "qcow2", buildPipeline, nil),
BasePipeline: NewBasePipeline(m, "qcow2", buildPipeline),
imgPipeline: imgPipeline,
filename: filename,
}

View file

@ -20,7 +20,7 @@ func NewTarPipeline(m *Manifest,
pipelinename,
filename string) *TarPipeline {
p := &TarPipeline{
BasePipeline: NewBasePipeline(m, pipelinename, buildPipeline, nil),
BasePipeline: NewBasePipeline(m, pipelinename, buildPipeline),
inputPipeline: inputPipeline,
filename: filename,
}

View file

@ -19,7 +19,7 @@ func NewVMDKPipeline(m *Manifest,
imgPipeline *LiveImgPipeline,
filename string) *VMDKPipeline {
p := &VMDKPipeline{
BasePipeline: NewBasePipeline(m, "vmdk", buildPipeline, nil),
BasePipeline: NewBasePipeline(m, "vmdk", buildPipeline),
imgPipeline: imgPipeline,
filename: filename,
}

View file

@ -20,7 +20,7 @@ func NewVPCPipeline(m *Manifest,
imgPipeline *LiveImgPipeline,
filename string) *VPCPipeline {
p := &VPCPipeline{
BasePipeline: NewBasePipeline(m, "vpc", buildPipeline, nil),
BasePipeline: NewBasePipeline(m, "vpc", buildPipeline),
imgPipeline: imgPipeline,
filename: filename,
}

18
internal/runner/fedora.go Normal file
View file

@ -0,0 +1,18 @@
package runner
import "fmt"
type Fedora struct {
Version uint64
}
func (r *Fedora) String() string {
return fmt.Sprintf("org.osbuild.fedora%d", r.Version)
}
func (p *Fedora) GetBuildPackages() []string {
return []string{
"glibc", // ldconfig
"systemd", // systemd-tmpfiles and systemd-sysusers
}
}

15
internal/runner/linux.go Normal file
View file

@ -0,0 +1,15 @@
package runner
type Linux struct {
}
func (r *Linux) String() string {
return "org.osbuild.linux"
}
func (p *Linux) GetBuildPackages() []string {
return []string{
"glibc", // ldconfig
"systemd", // systemd-tmpfiles and systemd-sysusers
}
}

24
internal/runner/rhel.go Normal file
View file

@ -0,0 +1,24 @@
package runner
import "fmt"
type RHEL struct {
Major uint64
Minor uint64
}
func (r *RHEL) String() string {
return fmt.Sprintf("org.osbuild.fedora%d%d", r.Major, r.Minor)
}
func (p *RHEL) GetBuildPackages() []string {
packages := []string{
"glibc", // ldconfig
}
if p.Major >= 8 {
packages = append(packages,
"systemd", // systemd-tmpfiles and systemd-sysusers
)
}
return packages
}

View file

@ -0,0 +1,6 @@
package runner
type Runner interface {
String() string
GetBuildPackages() []string
}