cloudapi: Add support for depsolving a blueprint + image type

This uses the blueprint and the image type's manifest with a minimal
imageRequest to get the package sets to use for depsolving, instead of
just using the packages in the blueprint.

This does not work with iot image types that require an ostree url.
Depsolving iot commits doesn't make sense anyway, since the blueprint
packages have no effect on it.

Includes simple tests for depsolving with image type, and returning an
error if the image type isn't recognized.

Related: RHEL-60125
This commit is contained in:
Brian C. Lane 2025-08-04 16:39:26 -07:00 committed by Brian C. Lane
parent c2f982e6cc
commit 78e983b69a
2 changed files with 112 additions and 23 deletions

View file

@ -4,9 +4,13 @@ package v2
import (
"context"
"crypto/rand"
"fmt"
"math"
"math/big"
"time"
"github.com/osbuild/blueprint/pkg/blueprint"
"github.com/osbuild/images/pkg/distrofactory"
"github.com/osbuild/images/pkg/reporegistry"
"github.com/osbuild/images/pkg/rpmmd"
@ -56,14 +60,44 @@ func (request *DepsolveRequest) Depsolve(df *distrofactory.Factory, rr *reporegi
}
}
// Send the depsolve request to the worker
packageSet := make(map[string][]rpmmd.PackageSet, 1)
packageSet["depsolve"] = []rpmmd.PackageSet{
{
Include: bp.GetPackages(),
EnabledModules: bp.GetEnabledModules(),
Repositories: repos,
},
// If there is an optional image_type we use manifest to setup the package/repo list
if request.ImageType != nil {
imageType, err := distroArch.GetImageType(imageTypeFromApiImageType(*request.ImageType, distroArch))
if err != nil {
return nil, HTTPError(ErrorUnsupportedImageType)
}
// use the same seed for all images so we get the same IDs
bigSeed, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt64))
if err != nil {
return nil, HTTPError(ErrorFailedToGenerateManifestSeed)
}
manifestSeed := bigSeed.Int64()
ir := imageRequest{
imageType: imageType,
repositories: repos,
manifestSeed: manifestSeed,
}
ibp := blueprint.Convert(bp)
manifestSource, _, err := ir.imageType.Manifest(&ibp, ir.imageOptions, ir.repositories, &ir.manifestSeed)
if err != nil {
return nil, HTTPErrorWithInternal(ErrorFailedToDepsolve, err)
}
packageSet = manifestSource.GetPackageSetChains()
} else {
// Send the depsolve request to the worker
packageSet["os"] = []rpmmd.PackageSet{
{
Include: bp.GetPackages(),
EnabledModules: bp.GetEnabledModules(),
Repositories: repos,
},
}
}
depsolveJobID, err := workers.EnqueueDepsolve(&worker.DepsolveJob{
@ -109,5 +143,5 @@ func (request *DepsolveRequest) Depsolve(df *distrofactory.Factory, rr *reporegi
}
}
return result.PackageSpecs["depsolve"], nil
return result.PackageSpecs["os"], nil
}