image: add ostree commit source when initialising manifest

When initialising a manifest, use the ostree commit source spec only.
Then, when serialising, use the resolved ostree commit.
This is the same process we use for the other content types, packages
and containers.

Two new functions are defined in the distros to handle resolving the
ostree options: one for creating the parent commit source spec and image
ref for image types that have an optional parent commit (ostree commits
and containers) and one for creating the payload commit source spec for
image types that require an ostree payload (ostree raw images and
installers).
This commit is contained in:
Achilleas Koutsou 2023-05-31 20:15:10 +02:00 committed by Ondřej Budai
parent 8a0f3ce4a3
commit 966aec464a
8 changed files with 252 additions and 146 deletions

View file

@ -290,23 +290,15 @@ func iotCommitImage(workload workload.Workload,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
img := image.NewOSTreeArchive(options.OSTree.ImageRef)
parentCommit, commitRef := makeOSTreeParentCommit(options.OSTree, t.OSTreeRef())
img := image.NewOSTreeArchive(commitRef)
img.Platform = t.platform
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], containers, customizations)
img.Environment = t.environment
img.Workload = workload
if options.OSTree.ParentRef != "" && options.OSTree.URL != "" {
img.OSTreeParent = &ostree.CommitSpec{
Checksum: options.OSTree.ParentRef,
URL: options.OSTree.URL,
ContentURL: options.OSTree.ContentURL,
}
}
img.OSTreeParent = parentCommit
img.OSVersion = t.arch.distro.osVersion
img.Filename = t.Filename()
return img, nil
@ -320,26 +312,17 @@ func iotContainerImage(workload workload.Workload,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
img := image.NewOSTreeContainer(options.OSTree.ImageRef)
parentCommit, commitRef := makeOSTreeParentCommit(options.OSTree, t.OSTreeRef())
img := image.NewOSTreeContainer(commitRef)
img.Platform = t.platform
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], containers, customizations)
img.ContainerLanguage = img.OSCustomizations.Language
img.Environment = t.environment
img.Workload = workload
if options.OSTree.ParentRef != "" && options.OSTree.URL != "" {
img.OSTreeParent = &ostree.CommitSpec{
Checksum: options.OSTree.ParentRef,
URL: options.OSTree.URL,
ContentURL: options.OSTree.ContentURL,
}
}
img.OSTreeParent = parentCommit
img.OSVersion = t.arch.distro.osVersion
img.ExtraContainerPackages = packageSets[containerPkgsKey]
img.Filename = t.Filename()
return img, nil
@ -355,12 +338,11 @@ func iotInstallerImage(workload workload.Workload,
d := t.arch.distro
commit := ostree.CommitSpec{
Ref: options.OSTree.ImageRef,
URL: options.OSTree.URL,
ContentURL: options.OSTree.ContentURL,
Checksum: options.OSTree.ParentRef,
commit, err := makeOSTreePayloadCommit(options.OSTree, t.OSTreeRef())
if err != nil {
return nil, fmt.Errorf("%s: %s", t.Name(), err.Error())
}
img := image.NewOSTreeInstaller(commit)
img.Platform = t.platform
@ -395,12 +377,11 @@ func iotRawImage(workload workload.Workload,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
commit := ostree.CommitSpec{
Ref: options.OSTree.ImageRef,
URL: options.OSTree.URL,
ContentURL: options.OSTree.ContentURL,
Checksum: options.OSTree.ParentRef,
commit, err := makeOSTreePayloadCommit(options.OSTree, t.OSTreeRef())
if err != nil {
return nil, fmt.Errorf("%s: %s", t.Name(), err.Error())
}
img := image.NewOSTreeRawImage(commit)
// Set sysroot read-only only for Fedora 37+
@ -412,7 +393,6 @@ func iotRawImage(workload workload.Workload,
img.Users = users.UsersFromBP(customizations.GetUsers())
img.Groups = users.GroupsFromBP(customizations.GetGroups())
var err error
img.Directories, err = blueprint.DirectoryCustomizationsToFsNodeDirectories(customizations.GetDirectories())
if err != nil {
return nil, err
@ -451,3 +431,59 @@ func iotRawImage(workload workload.Workload,
return img, nil
}
// Create an ostree SourceSpec to define an ostree parent commit using the user
// options and the default ref for the image type. Additionally returns the
// ref to be used for the new commit to be created.
func makeOSTreeParentCommit(options *ostree.ImageOptions, defaultRef string) (*ostree.SourceSpec, string) {
commitRef := defaultRef
if options == nil {
// nothing to do
return nil, commitRef
}
if options.ImageRef != "" {
// user option overrides default commit ref
commitRef = options.ImageRef
}
var parentCommit *ostree.SourceSpec
if options.URL == "" {
// no parent
return nil, commitRef
}
// ostree URL specified: set source spec for parent commit
parentRef := options.ParentRef
if parentRef == "" {
// parent ref not set: use image ref
parentRef = commitRef
}
parentCommit = &ostree.SourceSpec{
URL: options.URL,
Ref: parentRef,
RHSM: options.RHSM,
}
return parentCommit, commitRef
}
// Create an ostree SourceSpec to define an ostree payload using the user options and the default ref for the image type.
func makeOSTreePayloadCommit(options *ostree.ImageOptions, defaultRef string) (ostree.SourceSpec, error) {
if options == nil || options.URL == "" {
// this should be caught by checkOptions() in distro, but it's good
// to guard against it here as well
return ostree.SourceSpec{}, fmt.Errorf("ostree commit URL required")
}
commitRef := defaultRef
if options.ImageRef != "" {
// user option overrides default commit ref
commitRef = options.ImageRef
}
return ostree.SourceSpec{
URL: options.URL,
Ref: commitRef,
RHSM: options.RHSM,
}, nil
}

View file

@ -313,26 +313,15 @@ func edgeCommitImage(workload workload.Workload,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
img := image.NewOSTreeArchive(options.OSTree.ImageRef)
parentCommit, commitRef := makeOSTreeParentCommit(options.OSTree, t.OSTreeRef())
img := image.NewOSTreeArchive(commitRef)
img.Platform = t.platform
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], options, containers, customizations)
img.Environment = t.environment
img.Workload = workload
if options.OSTree.ParentRef != "" && options.OSTree.URL != "" {
img.OSTreeParent = &ostree.CommitSpec{
Checksum: options.OSTree.ParentRef,
URL: options.OSTree.URL,
ContentURL: options.OSTree.ContentURL,
}
if options.OSTree.RHSM {
img.OSTreeParent.Secrets = "org.osbuild.rhsm.consumer"
}
}
img.OSTreeParent = parentCommit
img.OSVersion = t.arch.distro.osVersion
img.Filename = t.Filename()
return img, nil
@ -346,29 +335,17 @@ func edgeContainerImage(workload workload.Workload,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
img := image.NewOSTreeContainer(options.OSTree.ImageRef)
parentCommit, commitRef := makeOSTreeParentCommit(options.OSTree, t.OSTreeRef())
img := image.NewOSTreeContainer(commitRef)
img.Platform = t.platform
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], options, containers, customizations)
img.ContainerLanguage = img.OSCustomizations.Language
img.Environment = t.environment
img.Workload = workload
if options.OSTree.ParentRef != "" && options.OSTree.URL != "" {
img.OSTreeParent = &ostree.CommitSpec{
Checksum: options.OSTree.ParentRef,
URL: options.OSTree.URL,
ContentURL: options.OSTree.ContentURL,
}
if options.OSTree.RHSM {
img.OSTreeParent.Secrets = "org.osbuild.rhsm.consumer"
}
}
img.OSTreeParent = parentCommit
img.OSVersion = t.arch.distro.osVersion
img.ExtraContainerPackages = packageSets[containerPkgsKey]
img.Filename = t.Filename()
return img, nil
@ -384,15 +361,11 @@ func edgeInstallerImage(workload workload.Workload,
d := t.arch.distro
commit := ostree.CommitSpec{
Ref: options.OSTree.ImageRef,
URL: options.OSTree.URL,
ContentURL: options.OSTree.ContentURL,
Checksum: options.OSTree.ParentRef,
}
if options.OSTree.RHSM {
commit.Secrets = "org.osbuild.rhsm.consumer"
commit, err := makeOSTreePayloadCommit(options.OSTree, t.OSTreeRef())
if err != nil {
return nil, fmt.Errorf("%s: %s", t.Name(), err.Error())
}
img := image.NewOSTreeInstaller(commit)
img.Platform = t.platform
@ -428,12 +401,11 @@ func edgeRawImage(workload workload.Workload,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
commit := ostree.CommitSpec{
Ref: options.OSTree.ImageRef,
URL: options.OSTree.URL,
ContentURL: options.OSTree.ContentURL,
Checksum: options.OSTree.ParentRef,
commit, err := makeOSTreePayloadCommit(options.OSTree, t.OSTreeRef())
if err != nil {
return nil, fmt.Errorf("%s: %s", t.Name(), err.Error())
}
img := image.NewOSTreeRawImage(commit)
img.Users = users.UsersFromBP(customizations.GetUsers())
@ -474,12 +446,11 @@ func edgeSimplifiedInstallerImage(workload workload.Workload,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
commit := ostree.CommitSpec{
Ref: options.OSTree.ImageRef,
URL: options.OSTree.URL,
ContentURL: options.OSTree.ContentURL,
Checksum: options.OSTree.ParentRef,
commit, err := makeOSTreePayloadCommit(options.OSTree, t.OSTreeRef())
if err != nil {
return nil, fmt.Errorf("%s: %s", t.Name(), err.Error())
}
rawImg := image.NewOSTreeRawImage(commit)
rawImg.Users = users.UsersFromBP(customizations.GetUsers())
@ -539,3 +510,59 @@ func edgeSimplifiedInstallerImage(workload workload.Workload,
return img, nil
}
// Create an ostree SourceSpec to define an ostree parent commit using the user
// options and the default ref for the image type. Additionally returns the
// ref to be used for the new commit to be created.
func makeOSTreeParentCommit(options *ostree.ImageOptions, defaultRef string) (*ostree.SourceSpec, string) {
commitRef := defaultRef
if options == nil {
// nothing to do
return nil, commitRef
}
if options.ImageRef != "" {
// user option overrides default commit ref
commitRef = options.ImageRef
}
var parentCommit *ostree.SourceSpec
if options.URL == "" {
// no parent
return nil, commitRef
}
// ostree URL specified: set source spec for parent commit
parentRef := options.ParentRef
if parentRef == "" {
// parent ref not set: use image ref
parentRef = commitRef
}
parentCommit = &ostree.SourceSpec{
URL: options.URL,
Ref: parentRef,
RHSM: options.RHSM,
}
return parentCommit, commitRef
}
// Create an ostree SourceSpec to define an ostree payload using the user options and the default ref for the image type.
func makeOSTreePayloadCommit(options *ostree.ImageOptions, defaultRef string) (ostree.SourceSpec, error) {
if options == nil || options.URL == "" {
// this should be caught by checkOptions() in distro, but it's good
// to guard against it here as well
return ostree.SourceSpec{}, fmt.Errorf("ostree commit URL required")
}
commitRef := defaultRef
if options.ImageRef != "" {
// user option overrides default commit ref
commitRef = options.ImageRef
}
return ostree.SourceSpec{
URL: options.URL,
Ref: commitRef,
RHSM: options.RHSM,
}, nil
}

View file

@ -252,27 +252,23 @@ func edgeCommitImage(workload workload.Workload,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
img := image.NewOSTreeArchive(options.OSTree.ImageRef)
parentCommit, commitRef := makeOSTreeParentCommit(options.OSTree, t.OSTreeRef())
img := image.NewOSTreeArchive(commitRef)
img.Platform = t.platform
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], options, containers, customizations)
img.Environment = t.environment
img.Workload = workload
img.OSTreeParent = parentCommit
img.OSVersion = t.arch.distro.osVersion
img.Filename = t.Filename()
if !common.VersionLessThan(t.arch.distro.osVersion, "9.2") || t.arch.distro.osVersion == "9-stream" {
img.OSCustomizations.EnabledServices = append(img.OSCustomizations.EnabledServices, "ignition-firstboot-complete.service", "coreos-ignition-write-issues.service")
}
img.Environment = t.environment
img.Workload = workload
if options.OSTree.ParentRef != "" && options.OSTree.URL != "" {
img.OSTreeParent = &ostree.CommitSpec{
Checksum: options.OSTree.ParentRef,
URL: options.OSTree.URL,
ContentURL: options.OSTree.ContentURL,
}
if options.OSTree.RHSM {
img.OSTreeParent.Secrets = "org.osbuild.rhsm.consumer"
}
}
img.OSVersion = t.arch.distro.osVersion
img.Filename = t.Filename()
@ -288,34 +284,23 @@ func edgeContainerImage(workload workload.Workload,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
img := image.NewOSTreeContainer(options.OSTree.ImageRef)
parentCommit, commitRef := makeOSTreeParentCommit(options.OSTree, t.OSTreeRef())
img := image.NewOSTreeContainer(commitRef)
img.Platform = t.platform
img.OSCustomizations = osCustomizations(t, packageSets[osPkgsKey], options, containers, customizations)
if !common.VersionLessThan(t.arch.distro.osVersion, "9.2") || t.arch.distro.osVersion == "9-stream" {
img.OSCustomizations.EnabledServices = append(img.OSCustomizations.EnabledServices, "ignition-firstboot-complete.service", "coreos-ignition-write-issues.service")
}
img.ContainerLanguage = img.OSCustomizations.Language
img.Environment = t.environment
img.Workload = workload
if options.OSTree.ParentRef != "" && options.OSTree.URL != "" {
img.OSTreeParent = &ostree.CommitSpec{
Checksum: options.OSTree.ParentRef,
URL: options.OSTree.URL,
ContentURL: options.OSTree.ContentURL,
}
if options.OSTree.RHSM {
img.OSTreeParent.Secrets = "org.osbuild.rhsm.consumer"
}
}
img.OSTreeParent = parentCommit
img.OSVersion = t.arch.distro.osVersion
img.ExtraContainerPackages = packageSets[containerPkgsKey]
img.Filename = t.Filename()
if !common.VersionLessThan(t.arch.distro.osVersion, "9.2") || t.arch.distro.osVersion == "9-stream" {
img.OSCustomizations.EnabledServices = append(img.OSCustomizations.EnabledServices, "ignition-firstboot-complete.service", "coreos-ignition-write-issues.service")
}
return img, nil
}
@ -329,15 +314,11 @@ func edgeInstallerImage(workload workload.Workload,
d := t.arch.distro
commit := ostree.CommitSpec{
Ref: options.OSTree.ImageRef,
URL: options.OSTree.URL,
ContentURL: options.OSTree.ContentURL,
Checksum: options.OSTree.ParentRef,
}
if options.OSTree.RHSM {
commit.Secrets = "org.osbuild.rhsm.consumer"
commit, err := makeOSTreePayloadCommit(options.OSTree, t.OSTreeRef())
if err != nil {
return nil, fmt.Errorf("%s: %s", t.Name(), err.Error())
}
img := image.NewOSTreeInstaller(commit)
img.Platform = t.platform
@ -378,13 +359,13 @@ func edgeRawImage(workload workload.Workload,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
commit := ostree.CommitSpec{
Ref: options.OSTree.ImageRef,
URL: options.OSTree.URL,
ContentURL: options.OSTree.ContentURL,
Checksum: options.OSTree.ParentRef,
commit, err := makeOSTreePayloadCommit(options.OSTree, t.OSTreeRef())
if err != nil {
return nil, fmt.Errorf("%s: %s", t.Name(), err.Error())
}
img := image.NewOSTreeRawImage(commit)
if !common.VersionLessThan(t.arch.distro.osVersion, "9.2") || t.arch.distro.osVersion == "9-stream" {
img.Ignition = true
}
@ -441,12 +422,11 @@ func edgeSimplifiedInstallerImage(workload workload.Workload,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
commit := ostree.CommitSpec{
Ref: options.OSTree.ImageRef,
URL: options.OSTree.URL,
ContentURL: options.OSTree.ContentURL,
Checksum: options.OSTree.ParentRef,
commit, err := makeOSTreePayloadCommit(options.OSTree, t.OSTreeRef())
if err != nil {
return nil, fmt.Errorf("%s: %s", t.Name(), err.Error())
}
rawImg := image.NewOSTreeRawImage(commit)
if !common.VersionLessThan(t.arch.distro.osVersion, "9.2") || t.arch.distro.osVersion == "9-stream" {
rawImg.Ignition = true
@ -584,3 +564,59 @@ func tarImage(workload workload.Workload,
return img, nil
}
// Create an ostree SourceSpec to define an ostree parent commit using the user
// options and the default ref for the image type. Additionally returns the
// ref to be used for the new commit to be created.
func makeOSTreeParentCommit(options *ostree.ImageOptions, defaultRef string) (*ostree.SourceSpec, string) {
commitRef := defaultRef
if options == nil {
// nothing to do
return nil, commitRef
}
if options.ImageRef != "" {
// user option overrides default commit ref
commitRef = options.ImageRef
}
var parentCommit *ostree.SourceSpec
if options.URL == "" {
// no parent
return nil, commitRef
}
// ostree URL specified: set source spec for parent commit
parentRef := options.ParentRef
if parentRef == "" {
// parent ref not set: use image ref
parentRef = commitRef
}
parentCommit = &ostree.SourceSpec{
URL: options.URL,
Ref: parentRef,
RHSM: options.RHSM,
}
return parentCommit, commitRef
}
// Create an ostree SourceSpec to define an ostree payload using the user options and the default ref for the image type.
func makeOSTreePayloadCommit(options *ostree.ImageOptions, defaultRef string) (ostree.SourceSpec, error) {
if options == nil || options.URL == "" {
// this should be caught by checkOptions() in distro, but it's good
// to guard against it here as well
return ostree.SourceSpec{}, fmt.Errorf("ostree commit URL required")
}
commitRef := defaultRef
if options.ImageRef != "" {
// user option overrides default commit ref
commitRef = options.ImageRef
}
return ostree.SourceSpec{
URL: options.URL,
Ref: commitRef,
RHSM: options.RHSM,
}, nil
}

View file

@ -20,9 +20,9 @@ type OSTreeArchive struct {
Environment environment.Environment
Workload workload.Workload
// OSTreeParent specifies an optional parent commit for the new commit
// being built.
OSTreeParent *ostree.CommitSpec
// OSTreeParent specifies the source for an optional parent commit for the
// new commit being built.
OSTreeParent *ostree.SourceSpec
// OSTreeRef is the ref of the commit that will be built.
OSTreeRef string

View file

@ -15,12 +15,18 @@ import (
type OSTreeContainer struct {
Base
Platform platform.Platform
OSCustomizations manifest.OSCustomizations
Environment environment.Environment
Workload workload.Workload
OSTreeRef string
OSTreeParent *ostree.CommitSpec
Platform platform.Platform
OSCustomizations manifest.OSCustomizations
Environment environment.Environment
Workload workload.Workload
// OSTreeParent specifies the source for an optional parent commit for the
// new commit being built.
OSTreeParent *ostree.SourceSpec
// OSTreeRef is the ref of the commit that will be built.
OSTreeRef string
OSVersion string
ExtraContainerPackages rpmmd.PackageSet // FIXME: this is never read
ContainerLanguage string

View file

@ -31,7 +31,7 @@ type OSTreeInstaller struct {
OSVersion string
Release string
Commit ostree.CommitSpec
Commit ostree.SourceSpec
Filename string
@ -40,7 +40,7 @@ type OSTreeInstaller struct {
AdditionalDrivers []string
}
func NewOSTreeInstaller(commit ostree.CommitSpec) *OSTreeInstaller {
func NewOSTreeInstaller(commit ostree.SourceSpec) *OSTreeInstaller {
return &OSTreeInstaller{
Base: NewBase("ostree-installer"),
Commit: commit,
@ -120,7 +120,7 @@ func (img *OSTreeInstaller) InstantiateManifest(m *manifest.Manifest,
isoTreePipeline.KSPath = kspath
isoTreePipeline.PayloadPath = "/ostree/repo"
isoTreePipeline.OSTree = &img.Commit
isoTreePipeline.OSTreeCommitSource = &img.Commit
isoTreePipeline.ISOLinux = isoLinuxEnabled
isoPipeline := manifest.NewISO(m, buildPipeline, isoTreePipeline, isoLabel)

View file

@ -26,7 +26,7 @@ type OSTreeRawImage struct {
Users []users.User
Groups []users.Group
Commit ostree.CommitSpec
CommitSource ostree.SourceSpec
SysrootReadOnly bool
@ -47,10 +47,10 @@ type OSTreeRawImage struct {
Files []*fsnode.File
}
func NewOSTreeRawImage(commit ostree.CommitSpec) *OSTreeRawImage {
func NewOSTreeRawImage(commit ostree.SourceSpec) *OSTreeRawImage {
return &OSTreeRawImage{
Base: NewBase("ostree-raw-image"),
Commit: commit,
Base: NewBase("ostree-raw-image"),
CommitSource: commit,
}
}
@ -64,7 +64,7 @@ func ostreeCompressedImagePipelines(img *OSTreeRawImage, m *manifest.Manifest, b
}
func baseRawOstreeImage(img *OSTreeRawImage, m *manifest.Manifest, buildPipeline *manifest.Build) *manifest.RawOSTreeImage {
osPipeline := manifest.NewOSTreeDeployment(m, buildPipeline, img.Commit, img.OSName, img.Ignition, img.Platform)
osPipeline := manifest.NewOSTreeDeployment(m, buildPipeline, img.CommitSource, img.OSName, img.Ignition, img.Platform)
osPipeline.PartitionTable = img.PartitionTable
osPipeline.Remote = img.Remote
osPipeline.KernelOptionsAppend = img.KernelOptionsAppend

View file

@ -173,6 +173,7 @@ func ResolveRef(location, ref string, consumerCerts bool, subs *rhsm.Subscriptio
//
// If any ref (Ref or Parent) is malformed, the function returns with a RefError.
func Resolve(source SourceSpec) (ref, checksum string, err error) {
// TODO: return CommitSpec instead and add RHSM option
ref = source.Ref
// Determine value of ref