debian-forge-composer/cmd/osbuild-worker/jobimpl-depsolve.go
Achilleas Koutsou 6fbddeea35 composer+worker: make dnf-json path externally configurable
The default value is the installation path.
2022-06-01 11:36:52 +01:00

93 lines
3.3 KiB
Go

package main
import (
"fmt"
"github.com/sirupsen/logrus"
"github.com/osbuild/osbuild-composer/internal/dnfjson"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
"github.com/osbuild/osbuild-composer/internal/worker"
"github.com/osbuild/osbuild-composer/internal/worker/clienterrors"
)
type DepsolveJobImpl struct {
Solver *dnfjson.BaseSolver
}
// depsolve each package set in the pacakgeSets map. The repositories defined
// in repos are used for all package sets, whereas the repositories in
// packageSetsRepos are only used for the package set with the same name
// (matching map keys).
func (impl *DepsolveJobImpl) depsolve(packageSetsChains map[string][]string, packageSets map[string]rpmmd.PackageSet, repos []rpmmd.RepoConfig, packageSetsRepos map[string][]rpmmd.RepoConfig, modulePlatformID, arch, releasever string) (map[string][]rpmmd.PackageSpec, error) {
solver := impl.Solver.NewWithConfig(modulePlatformID, releasever, arch)
depsolvedSets := make(map[string][]rpmmd.PackageSpec)
// first depsolve package sets that are part of a chain
for specName, setNames := range packageSetsChains {
pkgSets := make([]rpmmd.PackageSet, len(setNames))
for idx, pkgSetName := range setNames {
pkgSets[idx] = packageSets[pkgSetName]
pkgSets[idx].Repositories = packageSetsRepos[pkgSetName]
delete(packageSets, pkgSetName) // will be depsolved here: remove from map
}
res, err := solver.Depsolve(pkgSets, repos)
if err != nil {
return nil, err
}
depsolvedSets[specName] = res.Dependencies
}
// depsolve the rest of the package sets
for name, pkgSet := range packageSets {
pkgSet.Repositories = packageSetsRepos[name]
res, err := solver.Depsolve([]rpmmd.PackageSet{pkgSet}, repos)
if err != nil {
return nil, err
}
depsolvedSets[name] = res.Dependencies
}
return depsolvedSets, nil
}
func (impl *DepsolveJobImpl) Run(job worker.Job) error {
logWithId := logrus.WithField("jobId", job.Id())
var args worker.DepsolveJob
err := job.Args(&args)
if err != nil {
return err
}
var result worker.DepsolveJobResult
result.PackageSpecs, err = impl.depsolve(args.PackageSetsChains, args.PackageSets, args.Repos, args.PackageSetsRepos, args.ModulePlatformID, args.Arch, args.Releasever)
if err != nil {
switch e := err.(type) {
case *dnfjson.Error:
// Error originates from dnf-json
switch e.Kind {
case "DepsolveError":
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorDNFDepsolveError, err.Error())
case "MarkingErrors":
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorDNFMarkingErrors, err.Error())
case "RepoError":
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorDNFRepoError, err.Error())
default:
// This still has the kind/reason format but a kind that's returned
// by dnf-json and not explicitly handled here.
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorDNFOtherError, err.Error())
logWithId.Errorf("Unhandled dnf-json error in depsolve job: %v", err)
}
case error:
// Error originates from internal/rpmmd, not from dnf-json
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorRPMMDError, err.Error())
logWithId.Errorf("rpmmd error in depsolve job: %v", err)
}
}
err = job.Update(&result)
if err != nil {
return fmt.Errorf("Error reporting job result: %v", err)
}
return nil
}