From 1abdd9a1f7a26567dd193e56fad83dea7bbb09fc Mon Sep 17 00:00:00 2001 From: "Brian C. Lane" Date: Fri, 16 Apr 2021 13:49:52 -0700 Subject: [PATCH] weldr: Add distro field to blueprints An optional distribution name can be included with the blueprint. If is is not then the blueprint will be depsolved/built using the current host distribution. depsolveBlueprint and depsolveBlueprintForImageType check for the empty Distro name and set it to the host distro before using it. The function signatures have also been changed to use the value instead of a pointer so that changes don't effect anything outside the depsolve function. --- internal/blueprint/blueprint.go | 1 + internal/weldr/api.go | 22 ++++++++++++++++------ internal/weldr/api_test.go | 19 ++++++++++--------- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/internal/blueprint/blueprint.go b/internal/blueprint/blueprint.go index c30a16a46..6248bb961 100644 --- a/internal/blueprint/blueprint.go +++ b/internal/blueprint/blueprint.go @@ -17,6 +17,7 @@ type Blueprint struct { Modules []Package `json:"modules" toml:"modules"` Groups []Group `json:"groups" toml:"groups"` Customizations *Customizations `json:"customizations,omitempty" toml:"customizations,omitempty"` + Distro string `json:"distro" toml:"distro"` } type Change struct { diff --git a/internal/weldr/api.go b/internal/weldr/api.go index d2edd1765..374264323 100644 --- a/internal/weldr/api.go +++ b/internal/weldr/api.go @@ -1323,7 +1323,7 @@ func (api *API) blueprintsDepsolveHandler(writer http.ResponseWriter, request *h continue } - dependencies, err := api.depsolveBlueprint(blueprint) + dependencies, err := api.depsolveBlueprint(*blueprint) if err != nil { blueprintsErrors = append(blueprintsErrors, responseError{ @@ -1412,7 +1412,7 @@ func (api *API) blueprintsFreezeHandler(writer http.ResponseWriter, request *htt } // Make a copy of the blueprint since we will be replacing the version globs blueprint := bp.DeepCopy() - dependencies, err := api.depsolveBlueprint(&blueprint) + dependencies, err := api.depsolveBlueprint(blueprint) if err != nil { rerr := responseError{ ID: "BlueprintsError", @@ -1889,8 +1889,13 @@ func (api *API) blueprintsTagHandler(writer http.ResponseWriter, request *http.R statusResponseOK(writer) } -func (api *API) depsolveBlueprintForImageType(bp *blueprint.Blueprint, imageType distro.ImageType) (map[string][]rpmmd.PackageSpec, error) { - packageSets := imageType.PackageSets(*bp) +func (api *API) depsolveBlueprintForImageType(bp blueprint.Blueprint, imageType distro.ImageType) (map[string][]rpmmd.PackageSpec, error) { + // Depsolve using the host distro if none has been specified + if bp.Distro == "" { + bp.Distro = api.hostDistroName + } + + packageSets := imageType.PackageSets(bp) packageSpecSets := make(map[string][]rpmmd.PackageSpec) imageTypeRepos, err := api.allRepositoriesByImageType(imageType) @@ -2039,7 +2044,7 @@ func (api *API) composeHandler(writer http.ResponseWriter, request *http.Request cr.OSTree.Parent = parent } - packageSets, err := api.depsolveBlueprintForImageType(bp, imageType) + packageSets, err := api.depsolveBlueprintForImageType(*bp, imageType) if err != nil { errors := responseError{ ID: "DepsolveError", @@ -2862,12 +2867,17 @@ func (api *API) allRepositories() ([]rpmmd.RepoConfig, error) { return repos, nil } -func (api *API) depsolveBlueprint(bp *blueprint.Blueprint) ([]rpmmd.PackageSpec, error) { +func (api *API) depsolveBlueprint(bp blueprint.Blueprint) ([]rpmmd.PackageSpec, error) { repos, err := api.allRepositories() if err != nil { return nil, err } + // Depsolve using the host distro if none has been specified + if bp.Distro == "" { + bp.Distro = api.hostDistroName + } + packages, _, err := api.rpmmd.Depsolve(rpmmd.PackageSet{Include: bp.GetPackages()}, repos, api.distro.ModulePlatformID(), api.arch.Name()) if err != nil { return nil, err diff --git a/internal/weldr/api_test.go b/internal/weldr/api_test.go index 56aef9fdd..3171fa3b5 100644 --- a/internal/weldr/api_test.go +++ b/internal/weldr/api_test.go @@ -272,9 +272,9 @@ func TestBlueprintsInfo(t *testing.T) { ExpectedStatus int ExpectedJSON string }{ - {"GET", "/api/v0/blueprints/info/test1", ``, http.StatusOK, `{"blueprints":[{"name":"test1","description":"Test","modules":[],"packages":[{"name":"httpd","version":"2.4.*"}],"groups":[],"version":"0.0.0"}], + {"GET", "/api/v0/blueprints/info/test1", ``, http.StatusOK, `{"blueprints":[{"name":"test1","description":"Test","distro":"","modules":[],"packages":[{"name":"httpd","version":"2.4.*"}],"groups":[],"version":"0.0.0"}], "changes":[{"name":"test1","changed":false}], "errors":[]}`}, - {"GET", "/api/v0/blueprints/info/test2", ``, http.StatusOK, `{"blueprints":[{"name":"test2","description":"Test","modules":[],"packages":[{"name":"systemd","version":"123"}],"groups":[],"version":"0.0.0"}], + {"GET", "/api/v0/blueprints/info/test2", ``, http.StatusOK, `{"blueprints":[{"name":"test2","description":"Test","distro":"","modules":[],"packages":[{"name":"systemd","version":"123"}],"groups":[],"version":"0.0.0"}], "changes":[{"name":"test2","changed":true}], "errors":[]}`}, {"GET", "/api/v0/blueprints/info/test3-non", ``, http.StatusOK, `{"blueprints":[],"changes":[],"errors":[{"id":"UnknownBlueprint","msg":"test3-non: "}]}`}, } @@ -317,6 +317,7 @@ func TestBlueprintsInfoToml(t *testing.T) { Name: "test1", Description: "Test", Version: "0.0.0", + Distro: "", Packages: []blueprint.Package{ { Name: "httpd", @@ -395,7 +396,7 @@ func TestBlueprintsFreeze(t *testing.T) { ExpectedStatus int ExpectedJSON string }{ - {rpmmd_mock.BaseFixture, "/api/v0/blueprints/freeze/test,test2", http.StatusOK, `{"blueprints":[{"blueprint":{"name":"test","description":"Test","version":"0.0.1","packages":[{"name":"dep-package1","version":"1.33-2.fc30.x86_64"},{"name":"dep-package3","version":"7:3.0.3-1.fc30.x86_64"}],"modules":[{"name":"dep-package2","version":"2.9-1.fc30.x86_64"}],"groups":[]}},{"blueprint":{"name":"test2","description":"Test","version":"0.0.0","packages":[{"name":"dep-package1","version":"1.33-2.fc30.x86_64"},{"name":"dep-package3","version":"7:3.0.3-1.fc30.x86_64"}],"modules":[{"name":"dep-package2","version":"2.9-1.fc30.x86_64"}],"groups":[]}}],"errors":[]}`}, + {rpmmd_mock.BaseFixture, "/api/v0/blueprints/freeze/test,test2", http.StatusOK, `{"blueprints":[{"blueprint":{"name":"test","description":"Test","distro":"","version":"0.0.1","packages":[{"name":"dep-package1","version":"1.33-2.fc30.x86_64"},{"name":"dep-package3","version":"7:3.0.3-1.fc30.x86_64"}],"modules":[{"name":"dep-package2","version":"2.9-1.fc30.x86_64"}],"groups":[]}},{"blueprint":{"name":"test2","description":"Test","distro":"","version":"0.0.0","packages":[{"name":"dep-package1","version":"1.33-2.fc30.x86_64"},{"name":"dep-package3","version":"7:3.0.3-1.fc30.x86_64"}],"modules":[{"name":"dep-package2","version":"2.9-1.fc30.x86_64"}],"groups":[]}}],"errors":[]}`}, } tempdir, err := ioutil.TempDir("", "weldr-tests-") @@ -417,7 +418,7 @@ func TestBlueprintsFreeze(t *testing.T) { ExpectedStatus int ExpectedTOML string }{ - {rpmmd_mock.BaseFixture, "/api/v0/blueprints/freeze/test?format=toml", http.StatusOK, "name=\"test\"\n description=\"Test\"\n version=\"0.0.1\"\n groups = []\n [[packages]]\n name=\"dep-package1\"\n version=\"1.33-2.fc30.x86_64\"\n [[packages]]\n name=\"dep-package3\"\n version=\"7:3.0.3-1.fc30.x86_64\"\n [[modules]]\n name=\"dep-package2\"\n version=\"2.9-1.fc30.x86_64\""}, + {rpmmd_mock.BaseFixture, "/api/v0/blueprints/freeze/test?format=toml", http.StatusOK, "name=\"test\"\n description=\"Test\"\n distro=\"\"\n version=\"0.0.1\"\n groups = []\n [[packages]]\n name=\"dep-package1\"\n version=\"1.33-2.fc30.x86_64\"\n [[packages]]\n name=\"dep-package3\"\n version=\"7:3.0.3-1.fc30.x86_64\"\n [[modules]]\n name=\"dep-package2\"\n version=\"2.9-1.fc30.x86_64\""}, {rpmmd_mock.BaseFixture, "/api/v0/blueprints/freeze/missing?format=toml", http.StatusOK, ""}, } @@ -528,9 +529,9 @@ func TestBlueprintsDepsolve(t *testing.T) { ExpectedStatus int ExpectedJSON string }{ - {rpmmd_mock.BaseFixture, http.StatusOK, `{"blueprints":[{"blueprint":{"name":"test","description":"Test","version":"0.0.1","packages":[{"name":"dep-package1","version":"*"}],"groups":[],"modules":[{"name":"dep-package3","version":"*"}]},"dependencies":[{"name":"dep-package3","epoch":7,"version":"3.0.3","release":"1.fc30","arch":"x86_64"},{"name":"dep-package1","epoch":0,"version":"1.33","release":"2.fc30","arch":"x86_64"},{"name":"dep-package2","epoch":0,"version":"2.9","release":"1.fc30","arch":"x86_64"}]}],"errors":[]}`}, - {rpmmd_mock.NonExistingPackage, http.StatusOK, `{"blueprints":[{"blueprint":{"name":"test","description":"Test","version":"0.0.1","packages":[{"name":"dep-package1","version":"*"}],"groups":[],"modules":[{"name":"dep-package3","version":"*"}]},"dependencies":[]}],"errors":[{"id":"BlueprintsError","msg":"test: DNF error occured: MarkingErrors: Error occurred when marking packages for installation: Problems in request:\nmissing packages: fash"}]}`}, - {rpmmd_mock.BadDepsolve, http.StatusOK, `{"blueprints":[{"blueprint":{"name":"test","description":"Test","version":"0.0.1","packages":[{"name":"dep-package1","version":"*"}],"groups":[],"modules":[{"name":"dep-package3","version":"*"}]},"dependencies":[]}],"errors":[{"id":"BlueprintsError","msg":"test: DNF error occured: DepsolveError: There was a problem depsolving ['go2rpm']: \n Problem: conflicting requests\n - nothing provides askalono-cli needed by go2rpm-1-4.fc31.noarch"}]}`}, + {rpmmd_mock.BaseFixture, http.StatusOK, `{"blueprints":[{"blueprint":{"name":"test","description":"Test","distro":"","version":"0.0.1","packages":[{"name":"dep-package1","version":"*"}],"groups":[],"modules":[{"name":"dep-package3","version":"*"}]},"dependencies":[{"name":"dep-package3","epoch":7,"version":"3.0.3","release":"1.fc30","arch":"x86_64"},{"name":"dep-package1","epoch":0,"version":"1.33","release":"2.fc30","arch":"x86_64"},{"name":"dep-package2","epoch":0,"version":"2.9","release":"1.fc30","arch":"x86_64"}]}],"errors":[]}`}, + {rpmmd_mock.NonExistingPackage, http.StatusOK, `{"blueprints":[{"blueprint":{"name":"test","description":"Test","distro":"","version":"0.0.1","packages":[{"name":"dep-package1","version":"*"}],"groups":[],"modules":[{"name":"dep-package3","version":"*"}]},"dependencies":[]}],"errors":[{"id":"BlueprintsError","msg":"test: DNF error occured: MarkingErrors: Error occurred when marking packages for installation: Problems in request:\nmissing packages: fash"}]}`}, + {rpmmd_mock.BadDepsolve, http.StatusOK, `{"blueprints":[{"blueprint":{"name":"test","description":"Test","distro":"","version":"0.0.1","packages":[{"name":"dep-package1","version":"*"}],"groups":[],"modules":[{"name":"dep-package3","version":"*"}]},"dependencies":[]}],"errors":[{"id":"BlueprintsError","msg":"test: DNF error occured: DepsolveError: There was a problem depsolving ['go2rpm']: \n Problem: conflicting requests\n - nothing provides askalono-cli needed by go2rpm-1-4.fc31.noarch"}]}`}, } tempdir, err := ioutil.TempDir("", "weldr-tests-") @@ -797,8 +798,8 @@ func TestComposeInfo(t *testing.T) { ExpectedStatus int ExpectedJSON string }{ - {rpmmd_mock.BaseFixture, "GET", "/api/v0/compose/info/30000000-0000-0000-0000-000000000000", ``, http.StatusOK, fmt.Sprintf(`{"id":"30000000-0000-0000-0000-000000000000","config":"","blueprint":{"name":"test","description":"","version":"0.0.0","packages":[],"modules":[],"groups":[]},"commit":"","deps":{"packages":[]},"compose_type":"%s","queue_status":"WAITING","image_size":0}`, test_distro.TestImageTypeName)}, - {rpmmd_mock.BaseFixture, "GET", "/api/v1/compose/info/30000000-0000-0000-0000-000000000000", ``, http.StatusOK, fmt.Sprintf(`{"id":"30000000-0000-0000-0000-000000000000","config":"","blueprint":{"name":"test","description":"","version":"0.0.0","packages":[],"modules":[],"groups":[]},"commit":"","deps":{"packages":[]},"compose_type":"%s","queue_status":"WAITING","image_size":0,"uploads":[{"uuid":"10000000-0000-0000-0000-000000000000","status":"WAITING","provider_name":"aws","image_name":"awsimage","creation_time":1574857140,"settings":{"region":"frankfurt","bucket":"clay","key":"imagekey"}}]}`, test_distro.TestImageTypeName)}, + {rpmmd_mock.BaseFixture, "GET", "/api/v0/compose/info/30000000-0000-0000-0000-000000000000", ``, http.StatusOK, fmt.Sprintf(`{"id":"30000000-0000-0000-0000-000000000000","config":"","blueprint":{"name":"test","description":"","distro":"","version":"0.0.0","packages":[],"modules":[],"groups":[]},"commit":"","deps":{"packages":[]},"compose_type":"%s","queue_status":"WAITING","image_size":0}`, test_distro.TestImageTypeName)}, + {rpmmd_mock.BaseFixture, "GET", "/api/v1/compose/info/30000000-0000-0000-0000-000000000000", ``, http.StatusOK, fmt.Sprintf(`{"id":"30000000-0000-0000-0000-000000000000","config":"","blueprint":{"name":"test","description":"","distro":"","version":"0.0.0","packages":[],"modules":[],"groups":[]},"commit":"","deps":{"packages":[]},"compose_type":"%s","queue_status":"WAITING","image_size":0,"uploads":[{"uuid":"10000000-0000-0000-0000-000000000000","status":"WAITING","provider_name":"aws","image_name":"awsimage","creation_time":1574857140,"settings":{"region":"frankfurt","bucket":"clay","key":"imagekey"}}]}`, test_distro.TestImageTypeName)}, {rpmmd_mock.BaseFixture, "GET", "/api/v1/compose/info/30000000-0000-0000-0000", ``, http.StatusBadRequest, `{"status":false,"errors":[{"id":"UnknownUUID","msg":"30000000-0000-0000-0000 is not a valid build uuid"}]}`}, {rpmmd_mock.BaseFixture, "GET", "/api/v1/compose/info/42000000-0000-0000-0000-000000000000", ``, http.StatusBadRequest, `{"status":false,"errors":[{"id":"UnknownUUID","msg":"42000000-0000-0000-0000-000000000000 is not a valid build uuid"}]}`}, }