debian-forge-composer/cmd/osbuild-worker/jobimpl-depsolve.go
Achilleas Koutsou c092783a70 simplify package set chain handling
Move package set chain collation to the distro package and add
repositories to the package sets while returning the package sets from
their source, i.e., the ImageType.PackageSets() method.

This also removes the concept of "base repositories".  There are no
longer repositories that are added implicitly to all package sets but
instead each package set needs to specify *all* the repositories it will
be depsolved against.

This paves the way for the requirement we have for building RHEL 7
images with a RHEL 8 build root.  The build root package set has to be
depsolved against RHEL 8 repositories without any "base repos" included.
This is now possible since package sets and repositories are explicitly
associated from the start and there is no implicit global repository
set.

The change requires adding a list of PackageSet names to the core
rpmmd.RepoConfig.  In the cloud API, repositories that are limited to
specific package sets already contain the correct package set names and
these are now copied to the internal RepoConfig when converting types in
genRepoConfig().
The user-specified repositories are only associated with the payload
package sets like before.
2022-06-01 11:36:52 +01:00

76 lines
2.5 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(packageSets map[string][]rpmmd.PackageSet, modulePlatformID, arch, releasever string) (map[string][]rpmmd.PackageSpec, error) {
solver := impl.Solver.NewWithConfig(modulePlatformID, releasever, arch)
depsolvedSets := make(map[string][]rpmmd.PackageSpec)
for name, pkgSet := range packageSets {
res, err := solver.Depsolve(pkgSet)
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.PackageSets, 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
}