diff --git a/cmd/osbuild-pipeline/main.go b/cmd/osbuild-pipeline/main.go index cf291696b..506b37b02 100644 --- a/cmd/osbuild-pipeline/main.go +++ b/cmd/osbuild-pipeline/main.go @@ -81,7 +81,7 @@ func main() { } rpmmd := rpmmd.NewRPMMD() - _, checksums, err := rpmmd.Depsolve(packages, nil, d.Repositories(archArg), true) + _, checksums, err := rpmmd.Depsolve(packages, nil, d.Repositories(archArg), d.ModulePlatformID(), true) if err != nil { panic(err.Error()) } diff --git a/dnf-json b/dnf-json index db123502f..4731675c4 100644 --- a/dnf-json +++ b/dnf-json @@ -7,6 +7,7 @@ import hawkey import json import shutil import sys +import tempfile DNF_ERROR_EXIT_CODE = 10 @@ -37,8 +38,13 @@ def dnfrepo(desc, parent_conf=None): return repo -def create_base(repos, clean=False): +def create_base(repos, module_platform_id, persistdir, cachedir, clean=False): base = dnf.Base() + base.conf.module_platform_id = module_platform_id + base.conf.config_file_path = "/dev/null" + base.conf.persistdir = persistdir + if cachedir: + base.conf.cachedir = cachedir if clean: shutil.rmtree(base.conf.cachedir, ignore_errors=True) @@ -81,55 +87,60 @@ def repo_checksums(base): call = json.load(sys.stdin) command = call["command"] -arguments = call.get("arguments", {}) +arguments = call["arguments"] +repos = arguments.get("repos", {}) +clean = arguments.get("clean", False) +cachedir = arguments.get("cachedir", None) +module_platform_id = arguments["module_platform_id"] -if command == "dump": - base = create_base(arguments.get("repos", {}), arguments.get("clean", False)) - packages = [] - for package in base.sack.query().available(): - packages.append({ - "name": package.name, - "summary": package.summary, - "description": package.description, - "url": package.url, - "epoch": package.epoch, - "version": package.version, - "release": package.release, - "arch": package.arch, - "buildtime": timestamp_to_rfc3339(package.buildtime), - "license": package.license - }) - json.dump({ - "checksums": repo_checksums(base), - "packages": packages - }, sys.stdout) +with tempfile.TemporaryDirectory() as persistdir: + base = create_base(repos, module_platform_id, persistdir, cachedir, clean) -elif command == "depsolve": - base = create_base(arguments.get("repos", {}), arguments.get("clean", False)) - errors = [] + if command == "dump": + packages = [] + for package in base.sack.query().available(): + packages.append({ + "name": package.name, + "summary": package.summary, + "description": package.description, + "url": package.url, + "epoch": package.epoch, + "version": package.version, + "release": package.release, + "arch": package.arch, + "buildtime": timestamp_to_rfc3339(package.buildtime), + "license": package.license + }) + json.dump({ + "checksums": repo_checksums(base), + "packages": packages + }, sys.stdout) - try: - base.install_specs(arguments["package-specs"], exclude=arguments.get("exclude-specs", [])) - except dnf.exceptions.MarkingErrors as e: - exit_with_dnf_error("MarkingErrors", f"Error occurred when marking packages for installation: {e}") + elif command == "depsolve": + errors = [] - try: - base.resolve() - except dnf.exceptions.DepsolveError as e: - exit_with_dnf_error("DepsolveError", f"There was a problem depsolving {arguments['package-specs']}: {e}") + try: + base.install_specs(arguments["package-specs"], exclude=arguments.get("exclude-specs", [])) + except dnf.exceptions.MarkingErrors as e: + exit_with_dnf_error("MarkingErrors", f"Error occurred when marking packages for installation: {e}") - dependencies = [] - for package in base.transaction.install_set: - dependencies.append({ - "name": package.name, - "epoch": package.epoch, - "version": package.version, - "release": package.release, - "arch": package.arch, - "remote_location": package.remote_location(), - "checksum": f"{hawkey.chksum_name(package.chksum[0])}:{package.chksum[1].hex()}", - }) - json.dump({ - "checksums": repo_checksums(base), - "dependencies": dependencies - }, sys.stdout) + try: + base.resolve() + except dnf.exceptions.DepsolveError as e: + exit_with_dnf_error("DepsolveError", f"There was a problem depsolving {arguments['package-specs']}: {e}") + + dependencies = [] + for package in base.transaction.install_set: + dependencies.append({ + "name": package.name, + "epoch": package.epoch, + "version": package.version, + "release": package.release, + "arch": package.arch, + "remote_location": package.remote_location(), + "checksum": f"{hawkey.chksum_name(package.chksum[0])}:{package.chksum[1].hex()}", + }) + json.dump({ + "checksums": repo_checksums(base), + "dependencies": dependencies + }, sys.stdout) diff --git a/internal/mocks/rpmmd/rpmmd_mock.go b/internal/mocks/rpmmd/rpmmd_mock.go index d958a95da..3bc8fe40e 100644 --- a/internal/mocks/rpmmd/rpmmd_mock.go +++ b/internal/mocks/rpmmd/rpmmd_mock.go @@ -30,10 +30,10 @@ func NewRPMMDMock(fixture Fixture) rpmmd.RPMMD { return &rpmmdMock{Fixture: fixture} } -func (r *rpmmdMock) FetchPackageList(repos []rpmmd.RepoConfig) (rpmmd.PackageList, map[string]string, error) { +func (r *rpmmdMock) FetchPackageList(repos []rpmmd.RepoConfig, modulePlatformID string) (rpmmd.PackageList, map[string]string, error) { return r.Fixture.fetchPackageList.ret, r.Fixture.fetchPackageList.checksums, r.Fixture.fetchPackageList.err } -func (r *rpmmdMock) Depsolve(specs, excludeSpecs []string, repos []rpmmd.RepoConfig, clean bool) ([]rpmmd.PackageSpec, map[string]string, error) { +func (r *rpmmdMock) Depsolve(specs, excludeSpecs []string, repos []rpmmd.RepoConfig, modulePlatformID string, clean bool) ([]rpmmd.PackageSpec, map[string]string, error) { return r.Fixture.depsolve.ret, r.Fixture.fetchPackageList.checksums, r.Fixture.depsolve.err } diff --git a/internal/rpmmd/repository.go b/internal/rpmmd/repository.go index 0f3506dc5..5227a8ee9 100644 --- a/internal/rpmmd/repository.go +++ b/internal/rpmmd/repository.go @@ -95,8 +95,8 @@ type PackageInfo struct { } type RPMMD interface { - FetchPackageList(repos []RepoConfig) (PackageList, map[string]string, error) - Depsolve(specs, excludeSpecs []string, repos []RepoConfig, clean bool) ([]PackageSpec, map[string]string, error) + FetchPackageList(repos []RepoConfig, modulePlatformID string) (PackageList, map[string]string, error) + Depsolve(specs, excludeSpecs []string, repos []RepoConfig, modulePlatformID string, clean bool) ([]PackageSpec, map[string]string, error) } type DNFError struct { @@ -199,10 +199,11 @@ func NewRPMMD() RPMMD { return &rpmmdImpl{} } -func (*rpmmdImpl) FetchPackageList(repos []RepoConfig) (PackageList, map[string]string, error) { +func (*rpmmdImpl) FetchPackageList(repos []RepoConfig, modulePlatformID string) (PackageList, map[string]string, error) { var arguments = struct { - Repos []RepoConfig `json:"repos"` - }{repos} + Repos []RepoConfig `json:"repos"` + ModulePlatformID string `json:"module_platform_id"` + }{repos, modulePlatformID} var reply struct { Checksums map[string]string `json:"checksums"` Packages PackageList `json:"packages"` @@ -214,13 +215,14 @@ func (*rpmmdImpl) FetchPackageList(repos []RepoConfig) (PackageList, map[string] return reply.Packages, reply.Checksums, err } -func (*rpmmdImpl) Depsolve(specs, excludeSpecs []string, repos []RepoConfig, clean bool) ([]PackageSpec, map[string]string, error) { +func (*rpmmdImpl) Depsolve(specs, excludeSpecs []string, repos []RepoConfig, modulePlatformID string, clean bool) ([]PackageSpec, map[string]string, error) { var arguments = struct { - PackageSpecs []string `json:"package-specs"` - ExcludSpecs []string `json:"exclude-specs"` - Repos []RepoConfig `json:"repos"` - Clean bool `json:"clean,omitempty"` - }{specs, excludeSpecs, repos, clean} + PackageSpecs []string `json:"package-specs"` + ExcludSpecs []string `json:"exclude-specs"` + Repos []RepoConfig `json:"repos"` + ModulePlatformID string `json:"module_platform_id"` + Clean bool `json:"clean,omitempty"` + }{specs, excludeSpecs, repos, modulePlatformID, clean} var reply struct { Checksums map[string]string `json:"checksums"` Dependencies []PackageSpec `json:"dependencies"` @@ -281,7 +283,7 @@ func (packages PackageList) ToPackageInfos() []PackageInfo { return results } -func (pkg *PackageInfo) FillDependencies(rpmmd RPMMD, repos []RepoConfig) (err error) { - pkg.Dependencies, _, err = rpmmd.Depsolve([]string{pkg.Name}, nil, repos, false) +func (pkg *PackageInfo) FillDependencies(rpmmd RPMMD, repos []RepoConfig, modulePlatformID string) (err error) { + pkg.Dependencies, _, err = rpmmd.Depsolve([]string{pkg.Name}, nil, repos, modulePlatformID, false) return } diff --git a/internal/weldr/api.go b/internal/weldr/api.go index 31ec1518f..ea9d6771e 100644 --- a/internal/weldr/api.go +++ b/internal/weldr/api.go @@ -615,7 +615,7 @@ func (api *API) modulesInfoHandler(writer http.ResponseWriter, request *http.Req if modulesRequested { for i, _ := range packageInfos { - err := packageInfos[i].FillDependencies(api.rpmmd, api.distro.Repositories(api.arch)) + err := packageInfos[i].FillDependencies(api.rpmmd, api.distro.Repositories(api.arch), api.distro.ModulePlatformID()) if err != nil { errors := responseError{ ID: errorId, @@ -645,7 +645,7 @@ func (api *API) projectsDepsolveHandler(writer http.ResponseWriter, request *htt names := strings.Split(params.ByName("projects"), ",") - packages, _, err := api.rpmmd.Depsolve(names, nil, api.distro.Repositories(api.arch), false) + packages, _, err := api.rpmmd.Depsolve(names, nil, api.distro.Repositories(api.arch), api.distro.ModulePlatformID(), false) if err != nil { errors := responseError{ @@ -1792,7 +1792,7 @@ func (api *API) fetchPackageList() (rpmmd.PackageList, error) { repos = append(repos, source.RepoConfig()) } - packages, _, err := api.rpmmd.FetchPackageList(repos) + packages, _, err := api.rpmmd.FetchPackageList(repos, api.distro.ModulePlatformID()) return packages, err } @@ -1817,7 +1817,7 @@ func (api *API) depsolveBlueprint(bp *blueprint.Blueprint, clean bool) ([]rpmmd. repos = append(repos, source.RepoConfig()) } - return api.rpmmd.Depsolve(specs, nil, repos, clean) + return api.rpmmd.Depsolve(specs, nil, repos, api.distro.ModulePlatformID(), clean) } func (api *API) uploadsScheduleHandler(writer http.ResponseWriter, request *http.Request, params httprouter.Params) {