api: add support for /projects/depsolve

This commit is contained in:
Ondřej Budai 2019-11-12 20:26:25 +01:00 committed by Tom Gundersen
parent 9076f68f7b
commit 36ccb110b3
4 changed files with 92 additions and 13 deletions

View file

@ -71,14 +71,11 @@ if command == "dump":
elif command == "depsolve":
base = create_base(arguments.get("repos", {}))
errors = []
for pkgspec in arguments["package-specs"]:
try:
base.install_specs([pkgspec])
except dnf.exceptions.MarkingError as e:
errors.append((pkgspec, str(e)))
if errors:
formatted_errors = ", ".join((f"{package} ({err})" for package, err in errors))
exit_with_dnf_error("MarkingError", f"The following package(s) had problems: {formatted_errors}")
try:
base.install_specs(arguments["package-specs"])
except dnf.exceptions.MarkingErrors as e:
exit_with_dnf_error("MarkingErrors", f"Error occurred when marking packages for installation: {e}")
try:
base.resolve()

View file

@ -4,16 +4,55 @@ import (
"github.com/osbuild/osbuild-composer/internal/rpmmd"
)
var basePackageList = fetchPackageList{
rpmmd.PackageList{
{Name: "package1"},
{Name: "package2"},
},
nil,
}
var BaseFixture = Fixture{
fetchPackageList{
rpmmd.PackageList{
{Name: "package1"},
{Name: "package2"},
basePackageList,
depsolve{
[]rpmmd.PackageSpec{
{
Name: "libgpg-error",
Epoch: 0,
Version: "1.33",
Release: "2.fc30",
Arch: "x86_64",
},
{
Name: "libsemanage",
Epoch: 0,
Version: "2.9",
Release: "1.fc30",
Arch: "x86_64",
},
},
nil,
},
}
var NonExistingPackage = Fixture{
basePackageList,
depsolve{
nil,
nil,
&rpmmd.DNFError{
Kind: "MarkingErrors",
Reason: "Error occurred when marking packages for installation: Problems in request:\nmissing packages: fash",
},
},
}
var BadDepsolve = Fixture{
basePackageList,
depsolve{
nil,
&rpmmd.DNFError{
Kind: "DepsolveError",
Reason: "There was a problem depsolving ['go2rpm']: \n Problem: conflicting requests\n - nothing provides askalono-cli needed by go2rpm-1-4.fc31.noarch",
},
},
}

View file

@ -55,6 +55,8 @@ func New(rpmmd rpmmd.RPMMD, repo rpmmd.RepoConfig, packages rpmmd.PackageList, l
api.router.POST("/api/v0/projects/source/new", api.sourceNewHandler)
api.router.DELETE("/api/v0/projects/source/delete/*source", api.sourceDeleteHandler)
api.router.GET("/api/v0/projects/depsolve/:projects", api.projectsDepsolveHandler)
api.router.GET("/api/v0/modules/list", api.modulesListAllHandler)
api.router.GET("/api/v0/modules/list/:modules", api.modulesListHandler)
@ -482,6 +484,29 @@ func (api *API) modulesInfoHandler(writer http.ResponseWriter, request *http.Req
}
}
func (api *API) projectsDepsolveHandler(writer http.ResponseWriter, request *http.Request, params httprouter.Params) {
type reply struct {
Projects []rpmmd.PackageSpec `json:"projects"`
}
names := strings.Split(params.ByName("projects"), ",")
packages, err := api.rpmmd.Depsolve(names, []rpmmd.RepoConfig{api.repo})
if err != nil {
errors := responseError{
ID: "PROJECTS_ERROR",
Msg: fmt.Sprintf("BadRequest: %s", err.Error()),
}
statusResponseError(writer, http.StatusBadRequest, errors)
return
}
json.NewEncoder(writer).Encode(reply{
Projects: packages,
})
}
func (api *API) blueprintsListHandler(writer http.ResponseWriter, request *http.Request, _ httprouter.Params) {
type reply struct {
Total uint `json:"total"`

View file

@ -422,3 +422,21 @@ func TestSourcesDelete(t *testing.T) {
sendHTTP(api, true, "DELETE", "/api/v0/projects/source/delete/fish", ``)
}
}
func TestProjectsDepsolve(t *testing.T) {
var cases = []struct {
Fixture rpmmd_mock.Fixture
Path string
ExpectedStatus int
ExpectedJSON string
}{
{rpmmd_mock.NonExistingPackage, "/api/v0/projects/depsolve/fash", http.StatusBadRequest, `{"status":false,"errors":[{"id":"PROJECTS_ERROR","msg":"BadRequest: DNF error occured: MarkingErrors: Error occurred when marking packages for installation: Problems in request:\nmissing packages: fash"}]}`},
{rpmmd_mock.BaseFixture, "/api/v0/projects/depsolve/fish", http.StatusOK, `{"projects":[{"name":"libgpg-error","epoch":0,"version":"1.33","release":"2.fc30","arch":"x86_64"},{"name":"libsemanage","epoch":0,"version":"2.9","release":"1.fc30","arch":"x86_64"}]}`},
{rpmmd_mock.BadDepsolve, "/api/v0/projects/depsolve/go2rpm", http.StatusBadRequest, `{"status":false,"errors":[{"id":"PROJECTS_ERROR","msg":"BadRequest: 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"}]}`},
}
for _, c := range cases {
api, _ := createWeldrAPI(c.Fixture)
testRoute(t, api, true, "GET", c.Path, ``, c.ExpectedStatus, c.ExpectedJSON)
}
}