diff --git a/cmd/mock-dnf-json/dnf-json.go b/cmd/mock-dnf-json/dnf-json.go index 9a6d06182..5b0152154 100644 --- a/cmd/mock-dnf-json/dnf-json.go +++ b/cmd/mock-dnf-json/dnf-json.go @@ -53,10 +53,6 @@ func parseResponse(resp []byte, command string) json.RawMessage { parsedResponse := make(map[string]json.RawMessage) err := json.Unmarshal(resp, &parsedResponse) maybeFail(err) - if command == "chain-depsolve" { - // treat chain-depsolve and depsolve the same - command = "depsolve" - } return parsedResponse[command] } diff --git a/cmd/osbuild-dnf-json-tests/main_test.go b/cmd/osbuild-dnf-json-tests/main_test.go index 1695eb922..b0e0d90f0 100644 --- a/cmd/osbuild-dnf-json-tests/main_test.go +++ b/cmd/osbuild-dnf-json-tests/main_test.go @@ -83,10 +83,10 @@ func TestCrossArchDepsolve(t *testing.T) { packages := imgType.PackageSets(blueprint.Blueprint{}) - _, err = solver.Depsolve(packages["build"], repos[archStr]) + _, err = solver.Depsolve([]rpmmd.PackageSet{packages["build"]}, repos[archStr], nil) assert.NoError(t, err) - _, err = solver.Depsolve(packages["packages"], repos[archStr]) + _, err = solver.Depsolve([]rpmmd.PackageSet{packages["packages"]}, repos[archStr], nil) assert.NoError(t, err) }) } @@ -155,7 +155,7 @@ func TestDepsolvePackageSets(t *testing.T) { pkgSets[idx] = imagePkgSets[pkgSetName] delete(imagePkgSets, pkgSetName) // will be depsolved here: remove from map } - res, err := solver.ChainDepsolve(pkgSets, x86Repos, nil) + res, err := solver.Depsolve(pkgSets, x86Repos, nil) if err != nil { require.Nil(t, err) } @@ -164,7 +164,7 @@ func TestDepsolvePackageSets(t *testing.T) { // depsolve the rest of the package sets for name, pkgSet := range imagePkgSets { - res, err := solver.ChainDepsolve([]rpmmd.PackageSet{pkgSet}, x86Repos, nil) + res, err := solver.Depsolve([]rpmmd.PackageSet{pkgSet}, x86Repos, nil) if err != nil { require.Nil(t, err) } diff --git a/cmd/osbuild-pipeline/main.go b/cmd/osbuild-pipeline/main.go index de668a8cc..61633d0ed 100644 --- a/cmd/osbuild-pipeline/main.go +++ b/cmd/osbuild-pipeline/main.go @@ -152,7 +152,7 @@ func main() { pkgSets[idx] = packageSets[pkgSetName] delete(packageSets, pkgSetName) // will be depsolved here: remove from map } - res, err := solver.ChainDepsolve(pkgSets, repos, nil) + res, err := solver.Depsolve(pkgSets, repos, nil) if err != nil { panic("Could not depsolve: " + err.Error()) } @@ -161,7 +161,7 @@ func main() { // depsolve the rest of the package sets for name, pkgSet := range packageSets { - res, err := solver.ChainDepsolve([]rpmmd.PackageSet{pkgSet}, repos, nil) + res, err := solver.Depsolve([]rpmmd.PackageSet{pkgSet}, repos, nil) if err != nil { panic("Could not depsolve: " + err.Error()) } diff --git a/cmd/osbuild-store-dump/main.go b/cmd/osbuild-store-dump/main.go index 8bbb3b1f9..67832fc0d 100644 --- a/cmd/osbuild-store-dump/main.go +++ b/cmd/osbuild-store-dump/main.go @@ -23,7 +23,7 @@ func getManifest(bp blueprint.Blueprint, t distro.ImageType, a distro.Arch, d di pkgSpecSets := make(map[string][]rpmmd.PackageSpec) solver := dnfjson.NewSolver(d.ModulePlatformID(), d.Releasever(), a.Name(), cacheDir) for name, packages := range packageSets { - res, err := solver.Depsolve(packages, repos) + res, err := solver.Depsolve([]rpmmd.PackageSet{packages}, repos, nil) if err != nil { panic(err) } diff --git a/cmd/osbuild-worker/jobimpl-depsolve.go b/cmd/osbuild-worker/jobimpl-depsolve.go index 835017056..b2eeede23 100644 --- a/cmd/osbuild-worker/jobimpl-depsolve.go +++ b/cmd/osbuild-worker/jobimpl-depsolve.go @@ -32,7 +32,7 @@ func (impl *DepsolveJobImpl) depsolve(packageSetsChains map[string][]string, pac psRepos = append(psRepos, packageSetsRepos[pkgSetName]) // will be nil if it doesn't exist delete(packageSets, pkgSetName) // will be depsolved here: remove from map } - res, err := solver.ChainDepsolve(pkgSets, repos, psRepos) + res, err := solver.Depsolve(pkgSets, repos, psRepos) if err != nil { return nil, err } @@ -41,7 +41,7 @@ func (impl *DepsolveJobImpl) depsolve(packageSetsChains map[string][]string, pac // depsolve the rest of the package sets for name, pkgSet := range packageSets { - res, err := solver.ChainDepsolve([]rpmmd.PackageSet{pkgSet}, repos, [][]rpmmd.RepoConfig{packageSetsRepos[name]}) + res, err := solver.Depsolve([]rpmmd.PackageSet{pkgSet}, repos, [][]rpmmd.RepoConfig{packageSetsRepos[name]}) if err != nil { return nil, err } diff --git a/dnf-json b/dnf-json index 36b5c294a..3192dea31 100755 --- a/dnf-json +++ b/dnf-json @@ -147,37 +147,7 @@ class Solver(): "packages": packages } - def depsolve(self, package_spec, exclude_spec): - self.base.install_specs(package_spec, exclude_spec) - self.base.resolve() - dependencies = [] - for tsi in self.base.transaction: - # Avoid using the install_set() helper, as it does not guarantee - # a stable order - if tsi.action not in dnf.transaction.FORWARD_ACTIONS: - continue - package = tsi.pkg - - dependencies.append({ - "name": package.name, - "epoch": package.epoch, - "version": package.version, - "release": package.release, - "arch": package.arch, - "repo_id": package.repoid, - "path": package.relativepath, - "remote_location": package.remote_location(), - "checksum": ( - f"{hawkey.chksum_name(package.chksum[0])}:" - f"{package.chksum[1].hex()}" - ) - }) - return { - "checksums": self._repo_checksums(), - "dependencies": dependencies - } - - def chain_depsolve(self, transactions): + def depsolve(self, transactions): last_transaction = [] for idx, transaction in enumerate(transactions): @@ -266,15 +236,8 @@ def solve(request, cache_dir): result = solver.dump() printe("dump success") elif command == "depsolve": - job = transactions[0] - result = solver.depsolve( - job["package-specs"], - job.get("exclude-specs", []) - ) + result = solver.depsolve(transactions) printe("depsolve success") - elif command == "chain-depsolve": - result = solver.chain_depsolve(transactions) - printe("chain-depsolve success") except dnf.exceptions.MarkingErrors as e: printe("error install_specs") @@ -318,7 +281,7 @@ def respond(result): def validate_request(request): command = request.get("command") - valid_cmds = ("depsolve", "dump", "chain-depsolve") + valid_cmds = ("depsolve", "dump") if command not in valid_cmds: return { "kind": "InvalidRequest", diff --git a/internal/distro/distro_test_common/distro_test_common.go b/internal/distro/distro_test_common/distro_test_common.go index 1fe1d24c5..5e41ab052 100644 --- a/internal/distro/distro_test_common/distro_test_common.go +++ b/internal/distro/distro_test_common/distro_test_common.go @@ -143,7 +143,7 @@ func getImageTypePkgSpecSets(imageType distro.ImageType, bp blueprint.Blueprint, solver := dnfjson.NewSolver(imageType.Arch().Distro().ModulePlatformID(), imageType.Arch().Distro().Releasever(), imageType.Arch().Name(), cacheDir) imgPackageSpecSets := make(map[string][]rpmmd.PackageSpec) for name, packages := range imgPackageSets { - res, err := solver.Depsolve(packages, repos) + res, err := solver.Depsolve([]rpmmd.PackageSet{packages}, repos, nil) if err != nil { panic("Could not depsolve: " + err.Error()) } diff --git a/internal/dnfjson/dnfjson.go b/internal/dnfjson/dnfjson.go index bce59fe97..c0a77c0a7 100644 --- a/internal/dnfjson/dnfjson.go +++ b/internal/dnfjson/dnfjson.go @@ -88,41 +88,17 @@ func NewSolver(modulePlatformID string, releaseVer string, arch string, cacheDir return s.NewWithConfig(modulePlatformID, releaseVer, arch) } -// ChainDepsolve the given packages with explicit excludes using the given configuration and repos -func ChainDepsolve(pkgSets []rpmmd.PackageSet, repos []rpmmd.RepoConfig, psRepos [][]rpmmd.RepoConfig, modulePlatformID string, releaseVer string, arch string, cacheDir string) (*DepsolveResult, error) { - return NewSolver(modulePlatformID, releaseVer, arch, cacheDir).ChainDepsolve(pkgSets, repos, psRepos) +// Depsolve the given packages with explicit excludes using the given configuration and repos +func Depsolve(pkgSets []rpmmd.PackageSet, repos []rpmmd.RepoConfig, psRepos [][]rpmmd.RepoConfig, modulePlatformID string, releaseVer string, arch string, cacheDir string) (*DepsolveResult, error) { + return NewSolver(modulePlatformID, releaseVer, arch, cacheDir).Depsolve(pkgSets, repos, psRepos) } -// ChainDepsolve the list of required package sets with explicit excludes using +// Depsolve the list of required package sets with explicit excludes using // the given repositories. Each package set is depsolved as a separate // transactions in a chain. It returns a list of all packages (with solved // dependencies) that will be installed into the system. -func (s *Solver) ChainDepsolve(pkgSets []rpmmd.PackageSet, repos []rpmmd.RepoConfig, psRepos [][]rpmmd.RepoConfig) (*DepsolveResult, error) { - req, err := s.makeChainDepsolveRequest(pkgSets, repos, psRepos) - if err != nil { - return nil, err - } - - output, err := run(s.dnfJsonCmd, req) - if err != nil { - return nil, err - } - var result *depsolveResult - if err := json.Unmarshal(output, &result); err != nil { - return nil, err - } - - return resultToPublic(result, repos), nil -} - -// Depsolve the given packages with explicit excludes using the given configuration and repos -func Depsolve(pkgSets rpmmd.PackageSet, repos []rpmmd.RepoConfig, modulePlatformID string, releaseVer string, arch string, cacheDir string) (*DepsolveResult, error) { - return NewSolver(modulePlatformID, releaseVer, arch, cacheDir).Depsolve(pkgSets, repos) -} - -// Depsolve the given packages with explicit excludes using the solver configuration and provided repos -func (s *Solver) Depsolve(pkgSets rpmmd.PackageSet, repos []rpmmd.RepoConfig) (*DepsolveResult, error) { - req, err := s.makeDepsolveRequest(pkgSets, repos) +func (s *Solver) Depsolve(pkgSets []rpmmd.PackageSet, repos []rpmmd.RepoConfig, psRepos [][]rpmmd.RepoConfig) (*DepsolveResult, error) { + req, err := s.makeDepsolveRequest(pkgSets, repos, psRepos) if err != nil { return nil, err } @@ -228,7 +204,7 @@ func (r *repoConfig) hash() string { return fmt.Sprintf("%x", sha1.Sum([]byte(r.BaseURL+r.Metalink+r.MirrorList+r.GPGKey+fmt.Sprintf("%T", r.IgnoreSSL)+r.SSLCACert+r.SSLClientKey+r.SSLClientCert+r.MetadataExpire))) } -// makeChainDepsolveRequest constructs an Request for a chain-depsolve job. +// Helper function for creating a depsolve request payload. // The request defines a sequence of transactions, each depsolving one of the // elements of `pkgSets` in the order they appear. The `repoConfigs` are used // as the base repositories for all transactions. The extra repository configs @@ -239,8 +215,7 @@ func (r *repoConfig) hash() string { // NOTE: Due to implementation limitations of DNF and dnf-json, each package set // in the chain must use all of the repositories used by its predecessor. // An error is returned if this requirement is not met. -func (s *Solver) makeChainDepsolveRequest(pkgSets []rpmmd.PackageSet, repoConfigs []rpmmd.RepoConfig, pkgsetsRepos [][]rpmmd.RepoConfig) (*Request, error) { - +func (s *Solver) makeDepsolveRequest(pkgSets []rpmmd.PackageSet, repoConfigs []rpmmd.RepoConfig, pkgsetsRepos [][]rpmmd.RepoConfig) (*Request, error) { // pkgsetsRepos must either be nil (empty) or the same length as the pkgSets array if len(pkgsetsRepos) > 0 && len(pkgSets) != len(pkgsetsRepos) { return nil, fmt.Errorf("depsolve: the number of package set repository configurations (%d) does not match the number of package sets (%d)", len(pkgsetsRepos), len(pkgSets)) @@ -324,37 +299,6 @@ func (s *Solver) makeChainDepsolveRequest(pkgSets []rpmmd.PackageSet, repoConfig Transactions: transactions, } - req := Request{ - Command: "chain-depsolve", - ModulePlatformID: s.modulePlatformID, - Arch: s.arch, - CacheDir: s.cacheDir, - Arguments: args, - } - - return &req, nil -} - -// Helper function for creating a depsolve request payload -func (s *Solver) makeDepsolveRequest(pkgSets rpmmd.PackageSet, repoConfigs []rpmmd.RepoConfig) (*Request, error) { - repos, err := s.reposFromRPMMD(repoConfigs) - if err != nil { - return nil, err - } - allRepoIDs := make([]int, len(repoConfigs)) - for idx := range allRepoIDs { - allRepoIDs[idx] = idx - } - args := arguments{ - Repos: repos, - Transactions: []transactionArgs{ - { - PackageSpecs: pkgSets.Include, - ExcludeSpecs: pkgSets.Exclude, - RepoIDs: allRepoIDs, - }, - }, - } req := Request{ Command: "depsolve", ModulePlatformID: s.modulePlatformID, @@ -362,6 +306,7 @@ func (s *Solver) makeDepsolveRequest(pkgSets rpmmd.PackageSet, repoConfigs []rpm CacheDir: s.cacheDir, Arguments: args, } + return &req, nil } diff --git a/internal/dnfjson/dnfjson_test.go b/internal/dnfjson/dnfjson_test.go index 8ea86fe26..7f820ea7c 100644 --- a/internal/dnfjson/dnfjson_test.go +++ b/internal/dnfjson/dnfjson_test.go @@ -19,29 +19,10 @@ func TestDepsolver(t *testing.T) { solver := NewSolver("platform:el9", "9", "x86_64", tmpdir) solver.SetDNFJSONPath("../../dnf-json") - pkgset := rpmmd.PackageSet{Include: []string{"kernel", "vim-minimal", "tmux", "zsh"}} // everything you'll ever need - deps, err := solver.Depsolve(pkgset, []rpmmd.RepoConfig{s.RepoConfig}) - if err != nil { - t.Fatal(err) - } - exp := expectedResult(s.Server.URL) - assert.Equal(deps, exp) -} - -func TestChainDepsolver(t *testing.T) { - s := rpmrepo.NewTestServer() - defer s.Close() - - assert := assert.New(t) - - tmpdir := t.TempDir() - solver := NewSolver("platform:el9", "9", "x86_64", tmpdir) - solver.SetDNFJSONPath("../../dnf-json") - - { // single depsolve, but using chain function, should behave the same way as plain Depsolve + { // single depsolve pkgsets := []rpmmd.PackageSet{{Include: []string{"kernel", "vim-minimal", "tmux", "zsh"}}} // everything you'll ever need - deps, err := solver.ChainDepsolve(pkgsets, []rpmmd.RepoConfig{s.RepoConfig}, nil) + deps, err := solver.Depsolve(pkgsets, []rpmmd.RepoConfig{s.RepoConfig}, nil) if err != nil { t.Fatal(err) } @@ -54,7 +35,7 @@ func TestChainDepsolver(t *testing.T) { {Include: []string{"kernel"}}, {Include: []string{"vim-minimal", "tmux", "zsh"}}, } - deps, err := solver.ChainDepsolve(pkgsets, []rpmmd.RepoConfig{s.RepoConfig}, nil) + deps, err := solver.Depsolve(pkgsets, []rpmmd.RepoConfig{s.RepoConfig}, nil) if err != nil { t.Fatal(err) } @@ -67,7 +48,7 @@ func TestChainDepsolver(t *testing.T) { {Include: []string{"kernel"}}, {Include: []string{"vim-minimal", "tmux", "zsh"}}, } - deps, err := solver.ChainDepsolve(pkgsets, []rpmmd.RepoConfig{s.RepoConfig}, [][]rpmmd.RepoConfig{nil, {s.RepoConfig}}) + deps, err := solver.Depsolve(pkgsets, []rpmmd.RepoConfig{s.RepoConfig}, [][]rpmmd.RepoConfig{nil, {s.RepoConfig}}) if err != nil { t.Fatal(err) } @@ -76,7 +57,7 @@ func TestChainDepsolver(t *testing.T) { } } -func TestMakeChainDepsolveRequest(t *testing.T) { +func TestMakeDepsolveRequest(t *testing.T) { tests := []struct { packageSets []rpmmd.PackageSet repos []rpmmd.RepoConfig @@ -464,7 +445,7 @@ func TestMakeChainDepsolveRequest(t *testing.T) { solver := NewSolver("", "", "", "") for idx, tt := range tests { t.Run(fmt.Sprintf("%d", idx), func(t *testing.T) { - req, err := solver.makeChainDepsolveRequest(tt.packageSets, tt.repos, tt.packageSetsRepos) + req, err := solver.makeDepsolveRequest(tt.packageSets, tt.repos, tt.packageSetsRepos) if tt.err { assert.NotNilf(t, err, "expected an error, but got 'nil' instead") assert.Nilf(t, req, "got non-nill request, but expected an error") diff --git a/internal/kojiapi/server.go b/internal/kojiapi/server.go index 4a999b1c4..35e809adc 100644 --- a/internal/kojiapi/server.go +++ b/internal/kojiapi/server.go @@ -131,7 +131,7 @@ func (h *apiHandlers) PostCompose(ctx echo.Context) error { for idx, pkgSetName := range setNames { chain[idx] = packageSets[pkgSetName] } - res, err := solver.ChainDepsolve(chain, repositories, nil) + res, err := solver.Depsolve(chain, repositories, nil) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Failed to depsolve base packages for %s/%s/%s: %s", ir.ImageType, ir.Architecture, request.Distribution, err)) } diff --git a/internal/weldr/api.go b/internal/weldr/api.go index 9b2380fc0..b3a340bd9 100644 --- a/internal/weldr/api.go +++ b/internal/weldr/api.go @@ -1261,7 +1261,7 @@ func (api *API) modulesInfoHandler(writer http.ResponseWriter, request *http.Req solver := api.solver.NewWithConfig(d.ModulePlatformID(), d.Releasever(), api.archName) for i := range packageInfos { pkgName := packageInfos[i].Name - solved, err := solver.Depsolve(rpmmd.PackageSet{Include: []string{pkgName}}, repos) + solved, err := solver.Depsolve([]rpmmd.PackageSet{{Include: []string{pkgName}}}, repos, nil) if err != nil { errors := responseError{ ID: errorId, @@ -1340,8 +1340,9 @@ func (api *API) projectsDepsolveHandler(writer http.ResponseWriter, request *htt solver := api.solver.NewWithConfig(d.ModulePlatformID(), d.Releasever(), api.archName) deps, err := solver.Depsolve( - rpmmd.PackageSet{Include: names}, + []rpmmd.PackageSet{{Include: names}}, repos, + nil, ) if err != nil { errors := responseError{ @@ -2160,7 +2161,7 @@ func (api *API) depsolveBlueprintForImageType(bp blueprint.Blueprint, imageType psRepos = append(psRepos, packageSetsRepos[pkgSetName]) // will be nil if it doesn't exist delete(packageSets, pkgSetName) // will be depsolved here: remove from map } - res, err := solver.ChainDepsolve(pkgSets, imageTypeRepos, psRepos) + res, err := solver.Depsolve(pkgSets, imageTypeRepos, psRepos) if err != nil { return nil, err } @@ -2169,7 +2170,7 @@ func (api *API) depsolveBlueprintForImageType(bp blueprint.Blueprint, imageType // depsolve the rest of the package sets for name, pkgSet := range packageSets { - res, err := solver.ChainDepsolve([]rpmmd.PackageSet{pkgSet}, imageTypeRepos, [][]rpmmd.RepoConfig{packageSetsRepos[name]}) + res, err := solver.Depsolve([]rpmmd.PackageSet{pkgSet}, imageTypeRepos, [][]rpmmd.RepoConfig{packageSetsRepos[name]}) if err != nil { return nil, err } @@ -3208,7 +3209,7 @@ func (api *API) depsolveBlueprint(bp blueprint.Blueprint) ([]rpmmd.PackageSpec, } solver := api.solver.NewWithConfig(d.ModulePlatformID(), d.Releasever(), api.archName) - solved, err := solver.Depsolve(rpmmd.PackageSet{Include: bp.GetPackages()}, repos) + solved, err := solver.Depsolve([]rpmmd.PackageSet{{Include: bp.GetPackages()}}, repos, nil) if err != nil { return nil, err }