Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finalise interface between composer and image definitions #3444

Merged
merged 40 commits into from
May 31, 2023
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
1914131
distro: inline initializeManifest
achilleas-k Apr 5, 2023
abd68dc
distro/fedora: move imageType implementation to separate file
achilleas-k Apr 11, 2023
730840c
distro/rhel7: move imageType implementation to separate file
achilleas-k Apr 11, 2023
c3a9654
distro: simplify checkOptions() arguments
achilleas-k Apr 11, 2023
54ec501
subscription: new package for subscription options
achilleas-k Apr 12, 2023
2850288
distro: remove architecture names and use platform enum
achilleas-k Apr 27, 2023
b624d36
manifest: serialize to OSBuildManifest instead of distro.Manifest
achilleas-k Apr 27, 2023
034a7bb
distro: delete distro.Manifest type
achilleas-k Apr 27, 2023
3038403
manifest: expand the manifest package doc
achilleas-k May 5, 2023
4af3641
container: create a SourceSpec for the resolve parameters
achilleas-k Apr 27, 2023
d7e6ad2
ostree: rename RequestParams to SourceSpec
achilleas-k May 5, 2023
f6839f9
ostree: rename ResolveParams to Resolve
achilleas-k May 5, 2023
53e2512
pipeline: expand interface to return source specs
achilleas-k May 5, 2023
2b2e10e
rhsm: move FactsImageOptions to the rhsm/facts package
achilleas-k May 5, 2023
658c62f
ostree: move OSTreeImageOptions to the ostree package
achilleas-k May 5, 2023
f3da509
Make Manifest() return manifest.Manifest
achilleas-k Apr 12, 2023
3fc6a11
manifest: attach unresolved Content to Manifest struct
achilleas-k Apr 27, 2023
388f866
manifest: document Pipeline interface
achilleas-k May 9, 2023
cfd0c85
distro: pass entire Blueprint to Manifest()
achilleas-k May 9, 2023
b2178f8
distro: copy PackageSets() functionality into Manifest()
achilleas-k May 9, 2023
c0c9d27
cmd: remove usage of ImageType.PackageSets()
achilleas-k May 9, 2023
51a6d44
weldr: remove usage of ImageType.PackageSets()
achilleas-k May 9, 2023
1a4618a
distro: attach payload repositories to workload package sets
achilleas-k May 11, 2023
30860c5
manifest: fix repository collection in the os pipeline
achilleas-k May 11, 2023
2a55e34
distro: move the checkOptions() call to the top of Manifest()
achilleas-k May 11, 2023
b8b8d5b
distro: remove usage of ImageType.PackageSets() from tests
achilleas-k May 9, 2023
92d9c7e
distro/fedora: remove test for empty ostree ref
achilleas-k May 11, 2023
a8afe6f
manifest: collect container and ostree source specs
achilleas-k May 15, 2023
052082c
manifest: use container SourceSpec instead of Spec
achilleas-k May 15, 2023
19a5ee3
manifest: container specs added during serialization
achilleas-k May 15, 2023
e81aca0
gen-manifests: resolve containers after Manifest()
achilleas-k May 15, 2023
81b30dd
osbuild-pipeline: resolve containers after Manifest()
achilleas-k May 15, 2023
3b4d51e
weldr: resolve containers after Manifest()
achilleas-k May 15, 2023
7176ec8
distro: pass containers to Serialize() in test
achilleas-k May 15, 2023
aba9ba0
distro: remove packageSpecSets and containers from Manifest() args
achilleas-k May 15, 2023
1f04220
cloudapi: remove redundant type from composite literal
achilleas-k May 15, 2023
e6b7df0
cloudapi: remove usage of ImageType.PackageSets()
achilleas-k May 16, 2023
ee7a2cd
cloudapi: add container specs to Serialize()
achilleas-k May 26, 2023
f321275
distro: remove PackageSets() from the ImageType interface
achilleas-k May 17, 2023
ce10100
cloudapi: set the default ostree ref for package selection
achilleas-k May 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 48 additions & 23 deletions cmd/gen-manifests/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import (
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/distroregistry"
"github.com/osbuild/osbuild-composer/internal/dnfjson"
"github.com/osbuild/osbuild-composer/internal/manifest"
"github.com/osbuild/osbuild-composer/internal/ostree"
"github.com/osbuild/osbuild-composer/internal/rhsm/facts"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
)

Expand Down Expand Up @@ -120,17 +123,22 @@ func makeManifestJob(name string, imgType distro.ImageType, cr composeRequest, d

options := distro.ImageOptions{Size: 0}
if cr.OSTree != nil {
options.OSTree = distro.OSTreeImageOptions{
options.OSTree = &ostree.ImageOptions{
URL: cr.OSTree.URL,
ImageRef: cr.OSTree.Ref,
FetchChecksum: cr.OSTree.Parent,
RHSM: cr.OSTree.RHSM,
}
} else {
// use default OSTreeRef for image type
options.OSTree = &ostree.ImageOptions{
ImageRef: imgType.OSTreeRef(),
}
}

// add RHSM fact to detect changes
options.Facts = &distro.FactsImageOptions{
ApiType: "test-manifest",
options.Facts = &facts.ImageOptions{
APIType: facts.TEST_APITYPE,
}

job := func(msgq chan string) (err error) {
Expand All @@ -148,17 +156,13 @@ func makeManifestJob(name string, imgType distro.ImageType, cr composeRequest, d
bp = blueprint.Blueprint(*cr.Blueprint)
}

containerSpecs, err := resolveContainers(bp.Containers, archName)
manifest, _, err := imgType.Manifest(&bp, options, repos, seedArg)
if err != nil {
return fmt.Errorf("[%s] container resolution failed: %s", filename, err.Error())
}

if options.OSTree.ImageRef == "" {
// use default OSTreeRef for image type
options.OSTree.ImageRef = imgType.OSTreeRef()
err = fmt.Errorf("[%s] failed: %s", filename, err)
return
}

packageSpecs, err := depsolve(cacheDir, imgType, bp, options, repos, distribution, archName)
packageSpecs, err := depsolve(cacheDir, manifest.Content.PackageSets, distribution, archName)
thozza marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
err = fmt.Errorf("[%s] depsolve failed: %s", filename, err.Error())
return
Expand All @@ -167,11 +171,21 @@ func makeManifestJob(name string, imgType distro.ImageType, cr composeRequest, d
err = fmt.Errorf("[%s] nil package specs", filename)
return
}
manifest, _, err := imgType.Manifest(cr.Blueprint.Customizations, options, repos, packageSpecs, containerSpecs, seedArg)

if cr.Blueprint != nil {
bp = blueprint.Blueprint(*cr.Blueprint)
}

containerSpecs, err := resolvePipelineContainers(manifest.Content.Containers, archName)
if err != nil {
err = fmt.Errorf("[%s] failed: %s", filename, err)
return
return fmt.Errorf("[%s] container resolution failed: %s", filename, err.Error())
}

mf, err := manifest.Serialize(packageSpecs, containerSpecs)
if err != nil {
return fmt.Errorf("[%s] manifest serialization failed: %s", filename, err.Error())
}

request := composeRequest{
Distro: distribution.Name(),
Arch: archName,
Expand All @@ -181,7 +195,7 @@ func makeManifestJob(name string, imgType distro.ImageType, cr composeRequest, d
Blueprint: cr.Blueprint,
OSTree: cr.OSTree,
}
err = save(manifest, packageSpecs, containerSpecs, request, path, filename)
err = save(mf, packageSpecs, containerSpecs, request, path, filename)
return
}
return job
Expand Down Expand Up @@ -243,20 +257,31 @@ func readRepos() DistroArchRepoMap {
return darm
}

func resolveContainers(containers []blueprint.Container, archName string) ([]container.Spec, error) {
func resolveContainers(containers []container.SourceSpec, archName string) ([]container.Spec, error) {
resolver := container.NewResolver(archName)

for _, c := range containers {
resolver.Add(c.Source, c.Name, c.TLSVerify)
resolver.Add(c)
}

return resolver.Finish()
}

func depsolve(cacheDir string, imageType distro.ImageType, bp blueprint.Blueprint, options distro.ImageOptions, repos []rpmmd.RepoConfig, d distro.Distro, arch string) (map[string][]rpmmd.PackageSpec, error) {
func resolvePipelineContainers(containerSources map[string][]container.SourceSpec, archName string) (map[string][]container.Spec, error) {
containerSpecs := make(map[string][]container.Spec, len(containerSources))
for plName, sourceSpecs := range containerSources {
specs, err := resolveContainers(sourceSpecs, archName)
if err != nil {
return nil, err
}
containerSpecs[plName] = specs
}
return containerSpecs, nil
}

func depsolve(cacheDir string, packageSets map[string][]rpmmd.PackageSet, d distro.Distro, arch string) (map[string][]rpmmd.PackageSpec, error) {
solver := dnfjson.NewSolver(d.ModulePlatformID(), d.Releasever(), arch, d.Name(), cacheDir)
solver.SetDNFJSONPath("./dnf-json")
packageSets := imageType.PackageSets(bp, options, repos)
depsolvedSets := make(map[string][]rpmmd.PackageSpec)
for name, pkgSet := range packageSets {
res, err := solver.Depsolve(pkgSet)
Expand All @@ -268,15 +293,15 @@ func depsolve(cacheDir string, imageType distro.ImageType, bp blueprint.Blueprin
return depsolvedSets, nil
}

func save(manifest distro.Manifest, pkgs map[string][]rpmmd.PackageSpec, containers []container.Spec, cr composeRequest, path, filename string) error {
func save(ms manifest.OSBuildManifest, pkgs map[string][]rpmmd.PackageSpec, containers map[string][]container.Spec, cr composeRequest, path, filename string) error {
data := struct {
ComposeRequest composeRequest `json:"compose-request"`
Manifest distro.Manifest `json:"manifest"`
Manifest manifest.OSBuildManifest `json:"manifest"`
RPMMD map[string][]rpmmd.PackageSpec `json:"rpmmd"`
Containers []container.Spec `json:"containers,omitempty"`
Containers map[string][]container.Spec `json:"containers,omitempty"`
NoImageInfo bool `json:"no-image-info"`
}{
cr, manifest, pkgs, containers, true,
cr, ms, pkgs, containers, true,
}
b, err := json.MarshalIndent(data, "", " ")
if err != nil {
Expand Down
38 changes: 26 additions & 12 deletions cmd/osbuild-dnf-json-tests/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"github.com/osbuild/osbuild-composer/internal/distro"
rhel "github.com/osbuild/osbuild-composer/internal/distro/rhel8"
"github.com/osbuild/osbuild-composer/internal/dnfjson"
"github.com/osbuild/osbuild-composer/internal/ostree"
"github.com/osbuild/osbuild-composer/internal/platform"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
)

Expand Down Expand Up @@ -43,18 +45,28 @@ func TestCrossArchDepsolve(t *testing.T) {
t.Run(imgTypeStr, func(t *testing.T) {
imgType, err := arch.GetImageType(imgTypeStr)
require.NoError(t, err)

packages := imgType.PackageSets(blueprint.Blueprint{},
// set up bare minimum args for image type
var customizations *blueprint.Customizations
if imgTypeStr == "edge-simplified-installer" {
customizations = &blueprint.Customizations{
InstallationDevice: "/dev/null",
}
}
manifest, _, err := imgType.Manifest(
&blueprint.Blueprint{
Customizations: customizations,
},
distro.ImageOptions{
OSTree: distro.OSTreeImageOptions{
OSTree: &ostree.ImageOptions{
URL: "foo",
ImageRef: "bar",
FetchChecksum: "baz",
},
},
repos[archStr])
repos[archStr], 0)
assert.NoError(t, err)

for _, set := range packages {
for _, set := range manifest.Content.PackageSets {
_, err = solver.Depsolve(set)
assert.NoError(t, err)
}
Expand All @@ -75,21 +87,23 @@ func TestDepsolvePackageSets(t *testing.T) {

// Set up temporary directory for rpm/dnf cache
dir := t.TempDir()
solver := dnfjson.NewSolver(cs9.ModulePlatformID(), cs9.Releasever(), distro.X86_64ArchName, cs9.Name(), dir)
solver := dnfjson.NewSolver(cs9.ModulePlatformID(), cs9.Releasever(), platform.ARCH_X86_64.String(), cs9.Name(), dir)

repos, err := rpmmd.LoadRepositories([]string{repoDir}, cs9.Name())
require.NoErrorf(t, err, "Failed to LoadRepositories %v", cs9.Name())
x86Repos, ok := repos[distro.X86_64ArchName]
require.Truef(t, ok, "failed to get %q repos for %q", distro.X86_64ArchName, cs9.Name())
x86Repos, ok := repos[platform.ARCH_X86_64.String()]
require.Truef(t, ok, "failed to get %q repos for %q", platform.ARCH_X86_64.String(), cs9.Name())

x86Arch, err := cs9.GetArch(distro.X86_64ArchName)
require.Nilf(t, err, "failed to get %q arch of %q distro", distro.X86_64ArchName, cs9.Name())
x86Arch, err := cs9.GetArch(platform.ARCH_X86_64.String())
require.Nilf(t, err, "failed to get %q arch of %q distro", platform.ARCH_X86_64.String(), cs9.Name())

qcow2ImageTypeName := "qcow2"
qcow2Image, err := x86Arch.GetImageType(qcow2ImageTypeName)
require.Nilf(t, err, "failed to get %q image type of %q/%q distro/arch", qcow2ImageTypeName, cs9.Name(), distro.X86_64ArchName)
require.Nilf(t, err, "failed to get %q image type of %q/%q distro/arch", qcow2ImageTypeName, cs9.Name(), platform.ARCH_X86_64.String())

imagePkgSets := qcow2Image.PackageSets(blueprint.Blueprint{Packages: []blueprint.Package{{Name: "bind"}}}, distro.ImageOptions{}, x86Repos)
manifestSource, _, err := qcow2Image.Manifest(&blueprint.Blueprint{Packages: []blueprint.Package{{Name: "bind"}}}, distro.ImageOptions{}, x86Repos, 0)
require.Nilf(t, err, "failed to initialise manifest for %q image type of %q/%q distro/arch", qcow2ImageTypeName, cs9.Name(), platform.ARCH_X86_64.String())
imagePkgSets := manifestSource.Content.PackageSets

gotPackageSpecsSets := make(map[string][]rpmmd.PackageSpec, len(imagePkgSets))
for name, pkgSet := range imagePkgSets {
Expand Down
4 changes: 2 additions & 2 deletions cmd/osbuild-image-tests/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
"github.com/osbuild/osbuild-composer/internal/boot/openstacktest"
"github.com/osbuild/osbuild-composer/internal/boot/vmwaretest"
"github.com/osbuild/osbuild-composer/internal/common"
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/platform"
"github.com/osbuild/osbuild-composer/internal/test"
)

Expand Down Expand Up @@ -410,7 +410,7 @@ func testBootUsingOpenStack(t *testing.T, imagePath string) {
currentArch := common.CurrentArch()

// skip on aarch64 because we don't have aarch64 openstack or kvm machines
if currentArch == distro.Aarch64ArchName {
if currentArch == platform.ARCH_AARCH64.String() {
t.Skip("Openstack boot test is skipped on aarch64.")
// if no credentials are given, fall back to qemu
} else if (creds == gophercloud.AuthOptions{}) {
Expand Down
13 changes: 9 additions & 4 deletions cmd/osbuild-package-sets/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/distroregistry"
"github.com/osbuild/osbuild-composer/internal/ostree"
)

func main() {
Expand Down Expand Up @@ -47,12 +48,16 @@ func main() {

encoder := json.NewEncoder(os.Stdout)
encoder.SetIndent("", " ")
pkgset := image.PackageSets(blueprint.Blueprint{}, distro.ImageOptions{
OSTree: distro.OSTreeImageOptions{
options := distro.ImageOptions{
OSTree: &ostree.ImageOptions{
URL: "foo",
ImageRef: "bar",
FetchChecksum: "baz",
},
}, nil)
_ = encoder.Encode(pkgset)
}
manifest, _, err := image.Manifest(&blueprint.Blueprint{}, options, nil, 0)
if err != nil {
panic(err)
}
_ = encoder.Encode(manifest.Content.PackageSets)
}
44 changes: 23 additions & 21 deletions cmd/osbuild-pipeline/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/distroregistry"
"github.com/osbuild/osbuild-composer/internal/dnfjson"
"github.com/osbuild/osbuild-composer/internal/ostree"

"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
Expand Down Expand Up @@ -64,15 +65,15 @@ func findDnfJsonBin() string {
panic(fmt.Sprintf("could not find 'dnf-json' in any of the known paths: %+v", locations))
}

func resolveContainers(bp blueprint.Blueprint, archName string) ([]container.Spec, error) {
if len(bp.Containers) == 0 {
func resolveContainers(sourceSpecs []container.SourceSpec, archName string) ([]container.Spec, error) {
if len(sourceSpecs) == 0 {
return nil, nil
}

resolver := container.NewResolver(archName)

for _, c := range bp.Containers {
resolver.Add(c.Source, c.Name, c.TLSVerify)
for _, c := range sourceSpecs {
resolver.Add(c)
}

return resolver.Finish()
Expand Down Expand Up @@ -179,7 +180,7 @@ func main() {

options := distro.ImageOptions{
Size: imageType.Size(0),
OSTree: distro.OSTreeImageOptions{
OSTree: &ostree.ImageOptions{
ImageRef: composeRequest.OSTree.Ref,
FetchChecksum: composeRequest.OSTree.Parent,
URL: composeRequest.OSTree.URL,
Expand All @@ -199,46 +200,47 @@ func main() {
// let the cache grow to fit much more repository metadata than we usually allow
solver.SetMaxCacheSize(3 * 1024 * 1024 * 1024)

packageSets := imageType.PackageSets(composeRequest.Blueprint, options, repos)
depsolvedSets := make(map[string][]rpmmd.PackageSpec)
manifest, _, err := imageType.Manifest(&composeRequest.Blueprint, options, repos, seedArg)
if err != nil {
panic(err.Error())
}

for name, pkgSet := range packageSets {
depsolvedSets := make(map[string][]rpmmd.PackageSpec)
for name, pkgSet := range manifest.Content.PackageSets {
res, err := solver.Depsolve(pkgSet)
if err != nil {
panic("Could not depsolve: " + err.Error())
}
depsolvedSets[name] = res
}

containers := make(map[string][]container.Spec, len(manifest.Content.Containers))
for name, sourceSpecs := range manifest.Content.Containers {
containerSpecs, err := resolveContainers(sourceSpecs, arch.Name())
if err != nil {
panic("Could not resolve containers: " + err.Error())
}
containers[name] = containerSpecs
}

var bytes []byte
if rpmmdArg {
bytes, err = json.Marshal(depsolvedSets)
if err != nil {
panic(err)
}
} else {

containerSpecs, err := resolveContainers(composeRequest.Blueprint, arch.Name())
if err != nil {
panic("Could not resolve containers: " + err.Error())
}

if composeRequest.OSTree.Ref == "" {
// use default OSTreeRef for image type
composeRequest.OSTree.Ref = imageType.OSTreeRef()
}

manifest, _, err := imageType.Manifest(composeRequest.Blueprint.Customizations,
options,
repos,
depsolvedSets,
containerSpecs,
seedArg)
ms, err := manifest.Serialize(depsolvedSets, containers)
if err != nil {
panic(err.Error())
}

bytes, err = json.Marshal(manifest)
bytes, err = json.Marshal(ms)
if err != nil {
panic(err)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/osbuild-playground/playground.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func RunPlayground(img image.ImageKind, d distro.Distro, arch distro.Arch, repos
fmt.Fprintf(os.Stderr, "could not clean dnf cache: %s", err.Error())
}

bytes, err := manifest.Serialize(packageSpecs)
bytes, err := manifest.Serialize(packageSpecs, nil)
if err != nil {
panic("failed to serialize manifest: " + err.Error())
}
Expand Down
Loading