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:
parent
ce40e1d810
commit
5a15608c89
5 changed files with 63 additions and 51 deletions
|
|
@ -12,21 +12,13 @@ import (
|
||||||
"github.com/osbuild/osbuild-composer/internal/common"
|
"github.com/osbuild/osbuild-composer/internal/common"
|
||||||
"github.com/osbuild/osbuild-composer/internal/distro"
|
"github.com/osbuild/osbuild-composer/internal/distro"
|
||||||
"github.com/osbuild/osbuild-composer/internal/distroregistry"
|
"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/rpmmd"
|
||||||
"github.com/osbuild/osbuild-composer/internal/runner"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var ImageTypes = make(map[string]ImageType)
|
var ImageTypes = make(map[string]image.ImageKind)
|
||||||
|
|
||||||
type ImageType interface {
|
func AddImageType(img image.ImageKind) {
|
||||||
Name() string
|
|
||||||
InstantiateManifest(m *manifest.Manifest, repos []rpmmd.RepoConfig, runner runner.Runner) error
|
|
||||||
GetExports() []string
|
|
||||||
GetCheckpoints() []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func AddImageType(img ImageType) {
|
|
||||||
ImageTypes[img.Name()] = img
|
ImageTypes[img.Name()] = img
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/rand"
|
||||||
|
|
||||||
|
"github.com/osbuild/osbuild-composer/internal/artifact"
|
||||||
"github.com/osbuild/osbuild-composer/internal/manifest"
|
"github.com/osbuild/osbuild-composer/internal/manifest"
|
||||||
"github.com/osbuild/osbuild-composer/internal/platform"
|
"github.com/osbuild/osbuild-composer/internal/platform"
|
||||||
"github.com/osbuild/osbuild-composer/internal/rpmmd"
|
"github.com/osbuild/osbuild-composer/internal/rpmmd"
|
||||||
|
|
@ -36,11 +39,15 @@ func init() {
|
||||||
// Return nil when you are done, or an error if something
|
// Return nil when you are done, or an error if something
|
||||||
// went wrong. Your manifest will be streamed to osbuild
|
// went wrong. Your manifest will be streamed to osbuild
|
||||||
// for building.
|
// 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!
|
// Let's create a simple OCI container!
|
||||||
|
|
||||||
// configure a build pipeline
|
// configure a build pipeline
|
||||||
build := manifest.NewBuild(m, runner, repos)
|
build := manifest.NewBuild(m, runner, repos)
|
||||||
|
build.Checkpoint()
|
||||||
|
|
||||||
// create a minimal non-bootable OS tree
|
// create a minimal non-bootable OS tree
|
||||||
os := manifest.NewOS(m, build, &platform.X86{}, repos)
|
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"
|
os.OSCustomizations.Timezone = "UTC"
|
||||||
|
|
||||||
// create an OCI container containing the OS tree created above
|
// 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
|
return artifact, 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"}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
|
||||||
|
"github.com/osbuild/osbuild-composer/internal/artifact"
|
||||||
"github.com/osbuild/osbuild-composer/internal/disk"
|
"github.com/osbuild/osbuild-composer/internal/disk"
|
||||||
"github.com/osbuild/osbuild-composer/internal/manifest"
|
"github.com/osbuild/osbuild-composer/internal/manifest"
|
||||||
"github.com/osbuild/osbuild-composer/internal/platform"
|
"github.com/osbuild/osbuild-composer/internal/platform"
|
||||||
|
|
@ -22,11 +23,15 @@ func init() {
|
||||||
AddImageType(&MyImage{})
|
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!
|
// Let's create a simple raw image!
|
||||||
|
|
||||||
// configure a build pipeline
|
// configure a build pipeline
|
||||||
build := manifest.NewBuild(m, runner, repos)
|
build := manifest.NewBuild(m, runner, repos)
|
||||||
|
build.Checkpoint()
|
||||||
|
|
||||||
// create an x86_64 platform with bios boot
|
// create an x86_64 platform with bios boot
|
||||||
platform := &platform.X86{
|
platform := &platform.X86{
|
||||||
|
|
@ -34,9 +39,7 @@ func (img *MyImage) InstantiateManifest(m *manifest.Manifest, repos []rpmmd.Repo
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add helper
|
// TODO: add helper
|
||||||
// math/rand is good enough in this case
|
pt, err := disk.NewPartitionTable(&basePT, nil, 0, false, rng)
|
||||||
/* #nosec G404 */
|
|
||||||
pt, err := disk.NewPartitionTable(&basePT, nil, 0, false, rand.New(rand.NewSource(0)))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
@ -47,16 +50,8 @@ func (img *MyImage) InstantiateManifest(m *manifest.Manifest, repos []rpmmd.Repo
|
||||||
os.KernelName = "kernel" // use the default fedora kernel
|
os.KernelName = "kernel" // use the default fedora kernel
|
||||||
|
|
||||||
// create a raw image containing the OS tree created above
|
// 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
|
return artifact, nil
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: make internal
|
|
||||||
func (img *MyImage) GetExports() []string {
|
|
||||||
return []string{"image"}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (img *MyImage) GetCheckpoints() []string {
|
|
||||||
return []string{"build"}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,18 +2,20 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
"github.com/osbuild/osbuild-composer/internal/distro"
|
"github.com/osbuild/osbuild-composer/internal/distro"
|
||||||
"github.com/osbuild/osbuild-composer/internal/dnfjson"
|
"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/manifest"
|
||||||
"github.com/osbuild/osbuild-composer/internal/osbuild"
|
"github.com/osbuild/osbuild-composer/internal/osbuild"
|
||||||
"github.com/osbuild/osbuild-composer/internal/rpmmd"
|
"github.com/osbuild/osbuild-composer/internal/rpmmd"
|
||||||
"github.com/osbuild/osbuild-composer/internal/runner"
|
"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 := dnfjson.NewSolver(d.ModulePlatformID(), d.Releasever(), arch.Name(), path.Join(state_dir, "rpmmd"))
|
||||||
solver.SetDNFJSONPath(findDnfJsonBin())
|
solver.SetDNFJSONPath(findDnfJsonBin())
|
||||||
|
|
@ -23,8 +25,11 @@ func RunPlayground(img ImageType, d distro.Distro, arch distro.Arch, repos map[s
|
||||||
|
|
||||||
manifest := manifest.New()
|
manifest := manifest.New()
|
||||||
|
|
||||||
|
/* #nosec G404 */
|
||||||
|
rnd := rand.New(rand.NewSource(0))
|
||||||
|
|
||||||
// TODO: query distro for runner
|
// 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 {
|
if err != nil {
|
||||||
panic("InstantiateManifest() failed: " + err.Error())
|
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")
|
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 {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "could not run osbuild: %s", err.Error())
|
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())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
29
internal/image/image.go
Normal file
29
internal/image/image.go
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
package image
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
|
||||||
|
"github.com/osbuild/osbuild-composer/internal/artifact"
|
||||||
|
"github.com/osbuild/osbuild-composer/internal/manifest"
|
||||||
|
"github.com/osbuild/osbuild-composer/internal/rpmmd"
|
||||||
|
"github.com/osbuild/osbuild-composer/internal/runner"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ImageKind interface {
|
||||||
|
Name() string
|
||||||
|
InstantiateManifest(m *manifest.Manifest, repos []rpmmd.RepoConfig, runner runner.Runner, rng *rand.Rand) (*artifact.Artifact, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Base struct {
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (img Base) Name() string {
|
||||||
|
return img.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBase(name string) Base {
|
||||||
|
return Base{
|
||||||
|
name: name,
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue