manifest: support for container embedding
Adding support for container embedding. The containers need to be specified in the image function (imageFunc) arguments and when specified, propagate down to the OS pipeline generator to add the necessary stages. Support is added for RHEL 9.x and Fedora. Requires a temporary container spec array with the info from the blueprint for the first initialization of the manifest that's needed when collecting required packages. This should be simplified in the future.
This commit is contained in:
parent
c4b5c229fb
commit
09903bd0db
9 changed files with 118 additions and 22 deletions
|
|
@ -464,7 +464,7 @@ func (a *architecture) Distro() distro.Distro {
|
|||
return a.distro
|
||||
}
|
||||
|
||||
type imageFunc func(workload workload.Workload, t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, packageSets map[string]rpmmd.PackageSet, rng *rand.Rand) (image.ImageKind, error)
|
||||
type imageFunc func(workload workload.Workload, t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, packageSets map[string]rpmmd.PackageSet, containers []container.Spec, rng *rand.Rand) (image.ImageKind, error)
|
||||
|
||||
type packageSetFunc func(t *imageType) rpmmd.PackageSet
|
||||
|
||||
|
|
@ -574,8 +574,19 @@ func (t *imageType) PackageSets(bp blueprint.Blueprint, options distro.ImageOpti
|
|||
logrus.Warn("FIXME: Requesting package sets for iot-installer without a resolved ostree ref. Faking one.")
|
||||
}
|
||||
|
||||
// create a temporary container spec array with the info from the blueprint
|
||||
// to initialize the manifest
|
||||
containers := make([]container.Spec, len(bp.Containers))
|
||||
for idx := range bp.Containers {
|
||||
containers[idx] = container.Spec{
|
||||
Source: bp.Containers[idx].Source,
|
||||
TLSVerify: bp.Containers[idx].TLSVerify,
|
||||
LocalName: bp.Containers[idx].Name,
|
||||
}
|
||||
}
|
||||
|
||||
// create a manifest object and instantiate it with the computed packageSetChains
|
||||
manifest, err := t.initializeManifest(&bp, options, globalRepos, packageSets, nil, 0)
|
||||
manifest, err := t.initializeManifest(&bp, options, globalRepos, packageSets, containers, 0)
|
||||
if err != nil {
|
||||
// TODO: handle manifest initialization errors more gracefully, we
|
||||
// refuse to initialize manifests with invalid config.
|
||||
|
|
@ -674,7 +685,7 @@ func (t *imageType) initializeManifest(bp *blueprint.Blueprint,
|
|||
/* #nosec G404 */
|
||||
rng := rand.New(source)
|
||||
|
||||
img, err := t.image(w, t, bp.Customizations, options, packageSets, rng)
|
||||
img, err := t.image(w, t, bp.Customizations, options, packageSets, containers, rng)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -711,7 +722,8 @@ func (t *imageType) Manifest(customizations *blueprint.Customizations,
|
|||
// checkOptions checks the validity and compatibility of options and customizations for the image type.
|
||||
func (t *imageType) checkOptions(customizations *blueprint.Customizations, options distro.ImageOptions, containers []container.Spec) error {
|
||||
|
||||
if len(containers) > 0 {
|
||||
// we do not support embedding containers on ostree-derived images, only on commits themselves
|
||||
if len(containers) > 0 && t.rpmOstree && (t.name != "iot-commit" && t.name != "iot-container") {
|
||||
return fmt.Errorf("embedding containers is not supported for %s on %s", t.name, t.arch.distro.name)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"github.com/osbuild/osbuild-composer/internal/blueprint"
|
||||
"github.com/osbuild/osbuild-composer/internal/common"
|
||||
"github.com/osbuild/osbuild-composer/internal/container"
|
||||
"github.com/osbuild/osbuild-composer/internal/distro"
|
||||
"github.com/osbuild/osbuild-composer/internal/image"
|
||||
"github.com/osbuild/osbuild-composer/internal/manifest"
|
||||
|
|
@ -22,6 +23,7 @@ import (
|
|||
func osCustomizations(
|
||||
t *imageType,
|
||||
osPackageSet rpmmd.PackageSet,
|
||||
containers []container.Spec,
|
||||
c *blueprint.Customizations) manifest.OSCustomizations {
|
||||
|
||||
imageConfig := t.getDefaultImageConfig()
|
||||
|
|
@ -45,6 +47,8 @@ func osCustomizations(
|
|||
osc.ExcludeBasePackages = osPackageSet.Exclude
|
||||
osc.ExtraBaseRepos = osPackageSet.Repositories
|
||||
|
||||
osc.Containers = containers
|
||||
|
||||
osc.GPGKeyFiles = imageConfig.GPGKeyFiles
|
||||
if imageConfig.ExcludeDocs != nil {
|
||||
osc.ExcludeDocs = *imageConfig.ExcludeDocs
|
||||
|
|
@ -153,11 +157,12 @@ func liveImage(workload workload.Workload,
|
|||
customizations *blueprint.Customizations,
|
||||
options distro.ImageOptions,
|
||||
packageSets map[string]rpmmd.PackageSet,
|
||||
containers []container.Spec,
|
||||
rng *rand.Rand) (image.ImageKind, error) {
|
||||
|
||||
img := image.NewLiveImage()
|
||||
img.Platform = t.platform
|
||||
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], customizations)
|
||||
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], containers, customizations)
|
||||
img.Environment = t.environment
|
||||
img.Workload = workload
|
||||
// TODO: move generation into LiveImage
|
||||
|
|
@ -177,11 +182,12 @@ func containerImage(workload workload.Workload,
|
|||
c *blueprint.Customizations,
|
||||
options distro.ImageOptions,
|
||||
packageSets map[string]rpmmd.PackageSet,
|
||||
containers []container.Spec,
|
||||
rng *rand.Rand) (image.ImageKind, error) {
|
||||
img := image.NewBaseContainer()
|
||||
|
||||
img.Platform = t.platform
|
||||
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], c)
|
||||
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], containers, c)
|
||||
img.Environment = t.environment
|
||||
img.Workload = workload
|
||||
|
||||
|
|
@ -195,6 +201,7 @@ func imageInstallerImage(workload workload.Workload,
|
|||
customizations *blueprint.Customizations,
|
||||
options distro.ImageOptions,
|
||||
packageSets map[string]rpmmd.PackageSet,
|
||||
containers []container.Spec,
|
||||
rng *rand.Rand) (image.ImageKind, error) {
|
||||
|
||||
img := image.NewImageInstaller()
|
||||
|
|
@ -212,7 +219,7 @@ func imageInstallerImage(workload workload.Workload,
|
|||
}
|
||||
|
||||
img.Platform = t.platform
|
||||
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], customizations)
|
||||
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], containers, customizations)
|
||||
img.ExtraBasePackages = packageSets[installerPkgsKey]
|
||||
img.Users = users.UsersFromBP(customizations.GetUsers())
|
||||
img.Groups = users.GroupsFromBP(customizations.GetGroups())
|
||||
|
|
@ -235,12 +242,13 @@ func iotCommitImage(workload workload.Workload,
|
|||
customizations *blueprint.Customizations,
|
||||
options distro.ImageOptions,
|
||||
packageSets map[string]rpmmd.PackageSet,
|
||||
containers []container.Spec,
|
||||
rng *rand.Rand) (image.ImageKind, error) {
|
||||
|
||||
img := image.NewOSTreeArchive(options.OSTree.ImageRef)
|
||||
|
||||
img.Platform = t.platform
|
||||
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], customizations)
|
||||
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], containers, customizations)
|
||||
img.Environment = t.environment
|
||||
img.Workload = workload
|
||||
|
||||
|
|
@ -264,12 +272,13 @@ func iotContainerImage(workload workload.Workload,
|
|||
customizations *blueprint.Customizations,
|
||||
options distro.ImageOptions,
|
||||
packageSets map[string]rpmmd.PackageSet,
|
||||
containers []container.Spec,
|
||||
rng *rand.Rand) (image.ImageKind, error) {
|
||||
|
||||
img := image.NewOSTreeContainer(options.OSTree.ImageRef)
|
||||
|
||||
img.Platform = t.platform
|
||||
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], customizations)
|
||||
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], containers, customizations)
|
||||
img.ContainerLanguage = img.OSCustomizations.Language
|
||||
img.Environment = t.environment
|
||||
img.Workload = workload
|
||||
|
|
@ -296,6 +305,7 @@ func iotInstallerImage(workload workload.Workload,
|
|||
customizations *blueprint.Customizations,
|
||||
options distro.ImageOptions,
|
||||
packageSets map[string]rpmmd.PackageSet,
|
||||
containers []container.Spec,
|
||||
rng *rand.Rand) (image.ImageKind, error) {
|
||||
|
||||
d := t.arch.distro
|
||||
|
|
@ -330,6 +340,7 @@ func iotRawImage(workload workload.Workload,
|
|||
customizations *blueprint.Customizations,
|
||||
options distro.ImageOptions,
|
||||
packageSets map[string]rpmmd.PackageSet,
|
||||
containers []container.Spec,
|
||||
rng *rand.Rand) (image.ImageKind, error) {
|
||||
|
||||
commit := ostree.CommitSpec{
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"math/rand"
|
||||
|
||||
"github.com/osbuild/osbuild-composer/internal/blueprint"
|
||||
"github.com/osbuild/osbuild-composer/internal/container"
|
||||
"github.com/osbuild/osbuild-composer/internal/distro"
|
||||
"github.com/osbuild/osbuild-composer/internal/image"
|
||||
"github.com/osbuild/osbuild-composer/internal/manifest"
|
||||
|
|
@ -19,6 +20,7 @@ func osCustomizations(
|
|||
t *imageType,
|
||||
osPackageSet rpmmd.PackageSet,
|
||||
options distro.ImageOptions,
|
||||
containers []container.Spec,
|
||||
c *blueprint.Customizations,
|
||||
) manifest.OSCustomizations {
|
||||
|
||||
|
|
@ -43,6 +45,8 @@ func osCustomizations(
|
|||
osc.ExcludeBasePackages = osPackageSet.Exclude
|
||||
osc.ExtraBaseRepos = osPackageSet.Repositories
|
||||
|
||||
osc.Containers = containers
|
||||
|
||||
osc.GPGKeyFiles = imageConfig.GPGKeyFiles
|
||||
if imageConfig.ExcludeDocs != nil {
|
||||
osc.ExcludeDocs = *imageConfig.ExcludeDocs
|
||||
|
|
@ -159,11 +163,12 @@ func liveImage(workload workload.Workload,
|
|||
customizations *blueprint.Customizations,
|
||||
options distro.ImageOptions,
|
||||
packageSets map[string]rpmmd.PackageSet,
|
||||
containers []container.Spec,
|
||||
rng *rand.Rand) (image.ImageKind, error) {
|
||||
|
||||
img := image.NewLiveImage()
|
||||
img.Platform = t.platform
|
||||
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], options, customizations)
|
||||
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], options, containers, customizations)
|
||||
img.Environment = t.environment
|
||||
img.Workload = workload
|
||||
img.Compression = t.compression
|
||||
|
|
@ -184,12 +189,13 @@ func edgeCommitImage(workload workload.Workload,
|
|||
customizations *blueprint.Customizations,
|
||||
options distro.ImageOptions,
|
||||
packageSets map[string]rpmmd.PackageSet,
|
||||
containers []container.Spec,
|
||||
rng *rand.Rand) (image.ImageKind, error) {
|
||||
|
||||
img := image.NewOSTreeArchive(options.OSTree.ImageRef)
|
||||
|
||||
img.Platform = t.platform
|
||||
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], options, customizations)
|
||||
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], options, containers, customizations)
|
||||
img.Environment = t.environment
|
||||
img.Workload = workload
|
||||
|
||||
|
|
@ -213,12 +219,13 @@ func edgeContainerImage(workload workload.Workload,
|
|||
customizations *blueprint.Customizations,
|
||||
options distro.ImageOptions,
|
||||
packageSets map[string]rpmmd.PackageSet,
|
||||
containers []container.Spec,
|
||||
rng *rand.Rand) (image.ImageKind, error) {
|
||||
|
||||
img := image.NewOSTreeContainer(options.OSTree.ImageRef)
|
||||
|
||||
img.Platform = t.platform
|
||||
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], options, customizations)
|
||||
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], options, containers, customizations)
|
||||
img.ContainerLanguage = img.OSCustomizations.Language
|
||||
img.Environment = t.environment
|
||||
img.Workload = workload
|
||||
|
|
@ -245,6 +252,7 @@ func edgeInstallerImage(workload workload.Workload,
|
|||
customizations *blueprint.Customizations,
|
||||
options distro.ImageOptions,
|
||||
packageSets map[string]rpmmd.PackageSet,
|
||||
containers []container.Spec,
|
||||
rng *rand.Rand) (image.ImageKind, error) {
|
||||
|
||||
d := t.arch.distro
|
||||
|
|
@ -279,6 +287,7 @@ func edgeRawImage(workload workload.Workload,
|
|||
customizations *blueprint.Customizations,
|
||||
options distro.ImageOptions,
|
||||
packageSets map[string]rpmmd.PackageSet,
|
||||
containers []container.Spec,
|
||||
rng *rand.Rand) (image.ImageKind, error) {
|
||||
|
||||
commit := ostree.CommitSpec{
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ const (
|
|||
blueprintPkgsKey = "blueprint"
|
||||
)
|
||||
|
||||
type imageFunc func(workload workload.Workload, t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, packageSets map[string]rpmmd.PackageSet, rng *rand.Rand) (image.ImageKind, error)
|
||||
type imageFunc func(workload workload.Workload, t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, packageSets map[string]rpmmd.PackageSet, containers []container.Spec, rng *rand.Rand) (image.ImageKind, error)
|
||||
|
||||
type pipelinesFunc func(t *imageType, customizations *blueprint.Customizations, options distro.ImageOptions, repos []rpmmd.RepoConfig, packageSetSpecs map[string][]rpmmd.PackageSpec, containers []container.Spec, rng *rand.Rand) ([]osbuild.Pipeline, error)
|
||||
|
||||
|
|
@ -320,7 +320,7 @@ func (t *imageType) initializeManifest(bp *blueprint.Blueprint,
|
|||
/* #nosec G404 */
|
||||
rng := rand.New(source)
|
||||
|
||||
img, err := t.image(w, t, bp.Customizations, options, packageSets, rng)
|
||||
img, err := t.image(w, t, bp.Customizations, options, packageSets, containers, rng)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -460,8 +460,19 @@ func (t *imageType) PackageSetsNew(bp blueprint.Blueprint, options distro.ImageO
|
|||
logrus.Warn("FIXME: Requesting package sets for iot-installer without a resolved ostree ref. Faking one.")
|
||||
}
|
||||
|
||||
// create a temporary container spec array with the info from the blueprint
|
||||
// to initialize the manifest
|
||||
containers := make([]container.Spec, len(bp.Containers))
|
||||
for idx := range bp.Containers {
|
||||
containers[idx] = container.Spec{
|
||||
Source: bp.Containers[idx].Source,
|
||||
TLSVerify: bp.Containers[idx].TLSVerify,
|
||||
LocalName: bp.Containers[idx].Name,
|
||||
}
|
||||
}
|
||||
|
||||
// create a manifest object and instantiate it with the computed packageSetChains
|
||||
manifest, err := t.initializeManifest(&bp, options, globalRepos, packageSets, nil, 0)
|
||||
manifest, err := t.initializeManifest(&bp, options, globalRepos, packageSets, containers, 0)
|
||||
if err != nil {
|
||||
// TODO: handle manifest initialization errors more gracefully, we
|
||||
// refuse to initialize manifests with invalid config.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue