diff --git a/internal/distro/fedora/images.go b/internal/distro/fedora/images.go index 352b7a396..25a92fadc 100644 --- a/internal/distro/fedora/images.go +++ b/internal/distro/fedora/images.go @@ -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 +} diff --git a/internal/distro/rhel8/images.go b/internal/distro/rhel8/images.go index ad7e49916..ce5434f83 100644 --- a/internal/distro/rhel8/images.go +++ b/internal/distro/rhel8/images.go @@ -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 +} diff --git a/internal/distro/rhel9/images.go b/internal/distro/rhel9/images.go index cf70ac0b0..ccef5bb3d 100644 --- a/internal/distro/rhel9/images.go +++ b/internal/distro/rhel9/images.go @@ -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 +} diff --git a/internal/image/ostree_archive.go b/internal/image/ostree_archive.go index 39d367117..d8ccb3615 100644 --- a/internal/image/ostree_archive.go +++ b/internal/image/ostree_archive.go @@ -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 diff --git a/internal/image/ostree_container.go b/internal/image/ostree_container.go index 449d8c4f9..d9365e6f1 100644 --- a/internal/image/ostree_container.go +++ b/internal/image/ostree_container.go @@ -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 diff --git a/internal/image/ostree_installer.go b/internal/image/ostree_installer.go index 409b3c717..9866cbd6b 100644 --- a/internal/image/ostree_installer.go +++ b/internal/image/ostree_installer.go @@ -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) diff --git a/internal/image/ostree_raw.go b/internal/image/ostree_raw.go index f6f79ebcd..1b7bc6503 100644 --- a/internal/image/ostree_raw.go +++ b/internal/image/ostree_raw.go @@ -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 diff --git a/internal/ostree/ostree.go b/internal/ostree/ostree.go index d3ed10474..1a8f750c4 100644 --- a/internal/ostree/ostree.go +++ b/internal/ostree/ostree.go @@ -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