image: add image kind abstraction

This abstracts away the manifest instantiation. The idea is that we define one
of these image kind types to represent a group of image types that are
sufficiently similar. Each image kind will have a struct with with all the
properties that can be customised for the image and a function to turn that into
an actual manifest. This is similar to how distro/fedora/manifest.go and
cmd/osbuild-playground works today, and aspires to move these closer together
and to eventually make the distro definitions simpler.

For now cmd/osbuild-playground is moved over to using the new abstraction.
This commit is contained in:
Tom Gundersen 2022-07-10 13:45:24 +01:00 committed by Christian Kellner
parent ce40e1d810
commit 5a15608c89
5 changed files with 63 additions and 51 deletions

View file

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

View file

@ -1,6 +1,9 @@
package main
import (
"math/rand"
"github.com/osbuild/osbuild-composer/internal/artifact"
"github.com/osbuild/osbuild-composer/internal/manifest"
"github.com/osbuild/osbuild-composer/internal/platform"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
@ -36,11 +39,15 @@ func init() {
// Return nil when you are done, or an error if something
// went wrong. Your manifest will be streamed to osbuild
// for building.
func (img *MyContainer) InstantiateManifest(m *manifest.Manifest, repos []rpmmd.RepoConfig, runner runner.Runner) error {
func (img *MyContainer) InstantiateManifest(m *manifest.Manifest,
repos []rpmmd.RepoConfig,
runner runner.Runner,
rng *rand.Rand) (*artifact.Artifact, error) {
// Let's create a simple OCI container!
// configure a build pipeline
build := manifest.NewBuild(m, runner, repos)
build.Checkpoint()
// create a minimal non-bootable OS tree
os := manifest.NewOS(m, build, &platform.X86{}, repos)
@ -50,26 +57,8 @@ func (img *MyContainer) InstantiateManifest(m *manifest.Manifest, repos []rpmmd.
os.OSCustomizations.Timezone = "UTC"
// create an OCI container containing the OS tree created above
manifest.NewOCIContainer(m, build, os)
container := manifest.NewOCIContainer(m, build, os)
artifact := container.Export()
return nil
}
// GetExports returns a list of the pipelines osbuild should export.
// These are the pipelines containing the artefact you want returned.
//
// TODO: Move this to be implemented in terms ofthe Manifest package.
// We should not need to know the pipeline names.
func (img *MyContainer) GetExports() []string {
return []string{"container"}
}
// GetCheckpoints returns a list of the pipelines osbuild should
// checkpoint. These are the pipelines likely to be reusable in
// future runs.
//
// TODO: Move this to be implemented in terms ofthe Manifest package.
// We should not need to know the pipeline names.
func (img *MyContainer) GetCheckpoints() []string {
return []string{"build"}
return artifact, nil
}

View file

@ -3,6 +3,7 @@ package main
import (
"math/rand"
"github.com/osbuild/osbuild-composer/internal/artifact"
"github.com/osbuild/osbuild-composer/internal/disk"
"github.com/osbuild/osbuild-composer/internal/manifest"
"github.com/osbuild/osbuild-composer/internal/platform"
@ -22,11 +23,15 @@ func init() {
AddImageType(&MyImage{})
}
func (img *MyImage) InstantiateManifest(m *manifest.Manifest, repos []rpmmd.RepoConfig, runner runner.Runner) error {
func (img *MyImage) InstantiateManifest(m *manifest.Manifest,
repos []rpmmd.RepoConfig,
runner runner.Runner,
rng *rand.Rand) (*artifact.Artifact, error) {
// Let's create a simple raw image!
// configure a build pipeline
build := manifest.NewBuild(m, runner, repos)
build.Checkpoint()
// create an x86_64 platform with bios boot
platform := &platform.X86{
@ -34,9 +39,7 @@ func (img *MyImage) InstantiateManifest(m *manifest.Manifest, repos []rpmmd.Repo
}
// TODO: add helper
// math/rand is good enough in this case
/* #nosec G404 */
pt, err := disk.NewPartitionTable(&basePT, nil, 0, false, rand.New(rand.NewSource(0)))
pt, err := disk.NewPartitionTable(&basePT, nil, 0, false, rng)
if err != nil {
panic(err)
}
@ -47,16 +50,8 @@ func (img *MyImage) InstantiateManifest(m *manifest.Manifest, repos []rpmmd.Repo
os.KernelName = "kernel" // use the default fedora kernel
// create a raw image containing the OS tree created above
manifest.NewRawImage(m, build, os)
raw := manifest.NewRawImage(m, build, os)
artifact := raw.Export()
return nil
}
// TODO: make internal
func (img *MyImage) GetExports() []string {
return []string{"image"}
}
func (img *MyImage) GetCheckpoints() []string {
return []string{"build"}
return artifact, nil
}

View file

@ -2,18 +2,20 @@ package main
import (
"fmt"
"math/rand"
"os"
"path"
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/dnfjson"
"github.com/osbuild/osbuild-composer/internal/image"
"github.com/osbuild/osbuild-composer/internal/manifest"
"github.com/osbuild/osbuild-composer/internal/osbuild"
"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) {
func RunPlayground(img image.ImageKind, d distro.Distro, arch distro.Arch, repos map[string][]rpmmd.RepoConfig, state_dir string) {
solver := dnfjson.NewSolver(d.ModulePlatformID(), d.Releasever(), arch.Name(), path.Join(state_dir, "rpmmd"))
solver.SetDNFJSONPath(findDnfJsonBin())
@ -23,8 +25,11 @@ func RunPlayground(img ImageType, d distro.Distro, arch distro.Arch, repos map[s
manifest := manifest.New()
/* #nosec G404 */
rnd := rand.New(rand.NewSource(0))
// TODO: query distro for runner
err := img.InstantiateManifest(&manifest, repos[arch.Name()], &runner.Fedora{Version: 36})
artifact, err := img.InstantiateManifest(&manifest, repos[arch.Name()], &runner.Fedora{Version: 36}, rnd)
if err != nil {
panic("InstantiateManifest() failed: " + err.Error())
}
@ -50,8 +55,10 @@ func RunPlayground(img ImageType, d distro.Distro, arch distro.Arch, repos map[s
store := path.Join(state_dir, "osbuild-store")
_, err = osbuild.RunOSBuild(bytes, store, "./", img.GetExports(), []string{"build"}, false, os.Stdout)
_, err = osbuild.RunOSBuild(bytes, store, "./", manifest.GetExports(), manifest.GetCheckpoints(), false, os.Stdout)
if err != nil {
fmt.Fprintf(os.Stderr, "could not run osbuild: %s", err.Error())
}
fmt.Fprintf(os.Stderr, "built ./%s/%s (%s)\n", artifact.Export(), artifact.Filename(), artifact.MIMEType())
}