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:
parent
c2f982e6cc
commit
78e983b69a
2 changed files with 112 additions and 23 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,17 +92,6 @@ func mockDepsolve(t *testing.T, workerServer *worker.Server, wg *sync.WaitGroup,
|
|||
}
|
||||
dJR := &worker.DepsolveJobResult{
|
||||
PackageSpecs: map[string][]rpmmd.PackageSpec{
|
||||
// Used when depsolving a list of packages outside the manifest
|
||||
// Including it in other responses currently doesn't cause a problem
|
||||
"depsolve": {
|
||||
{
|
||||
Name: "dep-package1",
|
||||
Version: "1.33",
|
||||
Release: "2.fc30",
|
||||
Arch: "x86_64",
|
||||
Checksum: "sha256:fe3951d112c3b1c84dc8eac57afe0830df72df1ca0096b842f4db5d781189893",
|
||||
},
|
||||
},
|
||||
// Used when depsolving a manifest
|
||||
"build": {
|
||||
{
|
||||
|
|
@ -113,6 +102,9 @@ func mockDepsolve(t *testing.T, workerServer *worker.Server, wg *sync.WaitGroup,
|
|||
"os": {
|
||||
{
|
||||
Name: "pkg1",
|
||||
Version: "1.33",
|
||||
Release: "2.fc30",
|
||||
Arch: "x86_64",
|
||||
Checksum: "sha256:e50ddb78a37f5851d1a5c37a4c77d59123153c156e628e064b9daa378f45a2fe",
|
||||
},
|
||||
},
|
||||
|
|
@ -1694,7 +1686,7 @@ func TestDepsolveBlueprint(t *testing.T) {
|
|||
"distro": "%[1]s",
|
||||
"enabled_modules": [{ "name": "deps", "stream": "1" }],
|
||||
"packages": [
|
||||
{ "name": "dep-package", "version": "*" }
|
||||
{ "name": "pkg1", "version": "*" }
|
||||
]},
|
||||
"distribution": "%[1]s",
|
||||
"architecture": "%[2]s"
|
||||
|
|
@ -1703,17 +1695,80 @@ func TestDepsolveBlueprint(t *testing.T) {
|
|||
`{
|
||||
"packages": [
|
||||
{
|
||||
"name": "dep-package1",
|
||||
"type": "rpm",
|
||||
"name": "pkg1",
|
||||
"type": "rpm",
|
||||
"version": "1.33",
|
||||
"release": "2.fc30",
|
||||
"arch": "x86_64",
|
||||
"checksum": "sha256:fe3951d112c3b1c84dc8eac57afe0830df72df1ca0096b842f4db5d781189893"
|
||||
"checksum": "sha256:e50ddb78a37f5851d1a5c37a4c77d59123153c156e628e064b9daa378f45a2fe"
|
||||
}
|
||||
]
|
||||
}`)
|
||||
}
|
||||
|
||||
func TestDepsolveImageType(t *testing.T) {
|
||||
srv, _, _, cancel := newV2Server(t, t.TempDir(), false, false)
|
||||
defer cancel()
|
||||
|
||||
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST",
|
||||
"/api/image-builder-composer/v2/depsolve/blueprint", fmt.Sprintf(`
|
||||
{
|
||||
"blueprint": {
|
||||
"name": "deptest1",
|
||||
"version": "0.0.1",
|
||||
"distro": "%[1]s",
|
||||
"enabled_modules": [{ "name": "deps", "stream": "1" }],
|
||||
"packages": [
|
||||
{ "name": "pkg1", "version": "*" }
|
||||
]},
|
||||
"distribution": "%[1]s",
|
||||
"architecture": "%[2]s",
|
||||
"image_type": "%[3]s"
|
||||
}`, test_distro.TestDistro1Name, test_distro.TestArch3Name, test_distro.TestImageTypeImageInstaller),
|
||||
http.StatusOK,
|
||||
`{
|
||||
"packages": [
|
||||
{
|
||||
"name": "pkg1",
|
||||
"type": "rpm",
|
||||
"version": "1.33",
|
||||
"release": "2.fc30",
|
||||
"arch": "x86_64",
|
||||
"checksum": "sha256:e50ddb78a37f5851d1a5c37a4c77d59123153c156e628e064b9daa378f45a2fe"
|
||||
}
|
||||
]
|
||||
}`)
|
||||
}
|
||||
|
||||
func TestDepsolveImageTypeError(t *testing.T) {
|
||||
srv, _, _, cancel := newV2Server(t, t.TempDir(), false, false)
|
||||
defer cancel()
|
||||
|
||||
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST",
|
||||
"/api/image-builder-composer/v2/depsolve/blueprint", fmt.Sprintf(`
|
||||
{
|
||||
"blueprint": {
|
||||
"name": "deptest1",
|
||||
"version": "0.0.1",
|
||||
"distro": "%[1]s",
|
||||
"enabled_modules": [{ "name": "deps", "stream": "1" }],
|
||||
"packages": [
|
||||
{ "name": "pkg1", "version": "*" }
|
||||
]},
|
||||
"distribution": "%[1]s",
|
||||
"architecture": "%[2]s",
|
||||
"image_type": "bad-image-type"
|
||||
}`, test_distro.TestDistro1Name, test_distro.TestArchName),
|
||||
http.StatusBadRequest, `
|
||||
{
|
||||
"href": "/api/image-builder-composer/v2/errors/30",
|
||||
"id": "30",
|
||||
"kind": "Error",
|
||||
"code": "IMAGE-BUILDER-COMPOSER-30",
|
||||
"reason":"Request could not be validated"
|
||||
}`, "operation_id", "details")
|
||||
}
|
||||
|
||||
func TestDepsolveDistroErrors(t *testing.T) {
|
||||
srv, _, _, cancel := newV2Server(t, t.TempDir(), false, false)
|
||||
defer cancel()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue