|
Packit |
63bb0d |
package rpmmd
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
import (
|
|
Packit |
63bb0d |
"encoding/json"
|
|
Packit |
63bb0d |
"fmt"
|
|
Packit |
63bb0d |
"io/ioutil"
|
|
Packit |
63bb0d |
"os"
|
|
Packit |
63bb0d |
"os/exec"
|
|
Packit |
63bb0d |
"path/filepath"
|
|
Packit |
63bb0d |
"sort"
|
|
Packit |
63bb0d |
"strconv"
|
|
Packit |
63bb0d |
"strings"
|
|
Packit |
63bb0d |
"time"
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
"github.com/gobwas/glob"
|
|
Packit |
63bb0d |
)
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
type repository struct {
|
|
Packit |
63bb0d |
Name string `json:"name"`
|
|
Packit |
63bb0d |
BaseURL string `json:"baseurl,omitempty"`
|
|
Packit |
63bb0d |
Metalink string `json:"metalink,omitempty"`
|
|
Packit |
63bb0d |
MirrorList string `json:"mirrorlist,omitempty"`
|
|
Packit |
63bb0d |
GPGKey string `json:"gpgkey,omitempty"`
|
|
Packit |
63bb0d |
CheckGPG bool `json:"check_gpg,omitempty"`
|
|
Packit |
63bb0d |
RHSM bool `json:"rhsm,omitempty"`
|
|
Packit |
63bb0d |
MetadataExpire string `json:"metadata_expire,omitempty"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
type dnfRepoConfig struct {
|
|
Packit |
63bb0d |
ID string `json:"id"`
|
|
Packit |
63bb0d |
BaseURL string `json:"baseurl,omitempty"`
|
|
Packit |
63bb0d |
Metalink string `json:"metalink,omitempty"`
|
|
Packit |
63bb0d |
MirrorList string `json:"mirrorlist,omitempty"`
|
|
Packit |
63bb0d |
GPGKey string `json:"gpgkey,omitempty"`
|
|
Packit |
63bb0d |
IgnoreSSL bool `json:"ignoressl"`
|
|
Packit |
63bb0d |
SSLCACert string `json:"sslcacert,omitempty"`
|
|
Packit |
63bb0d |
SSLClientKey string `json:"sslclientkey,omitempty"`
|
|
Packit |
63bb0d |
SSLClientCert string `json:"sslclientcert,omitempty"`
|
|
Packit |
63bb0d |
MetadataExpire string `json:"metadata_expire,omitempty"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
type RepoConfig struct {
|
|
Packit |
63bb0d |
Name string
|
|
Packit |
63bb0d |
BaseURL string
|
|
Packit |
63bb0d |
Metalink string
|
|
Packit |
63bb0d |
MirrorList string
|
|
Packit |
63bb0d |
GPGKey string
|
|
Packit |
63bb0d |
CheckGPG bool
|
|
Packit |
63bb0d |
IgnoreSSL bool
|
|
Packit |
63bb0d |
MetadataExpire string
|
|
Packit |
63bb0d |
RHSM bool
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
type PackageList []Package
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
type Package struct {
|
|
Packit |
63bb0d |
Name string
|
|
Packit |
63bb0d |
Summary string
|
|
Packit |
63bb0d |
Description string
|
|
Packit |
63bb0d |
URL string
|
|
Packit |
63bb0d |
Epoch uint
|
|
Packit |
63bb0d |
Version string
|
|
Packit |
63bb0d |
Release string
|
|
Packit |
63bb0d |
Arch string
|
|
Packit |
63bb0d |
BuildTime time.Time
|
|
Packit |
63bb0d |
License string
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func (pkg Package) ToPackageBuild() PackageBuild {
|
|
Packit |
63bb0d |
// Convert the time to the API time format
|
|
Packit |
63bb0d |
return PackageBuild{
|
|
Packit |
63bb0d |
Arch: pkg.Arch,
|
|
Packit |
63bb0d |
BuildTime: pkg.BuildTime.Format("2006-01-02T15:04:05"),
|
|
Packit |
63bb0d |
Epoch: pkg.Epoch,
|
|
Packit |
63bb0d |
Release: pkg.Release,
|
|
Packit |
63bb0d |
Changelog: "CHANGELOG_NEEDED", // the same value as lorax-composer puts here
|
|
Packit |
63bb0d |
BuildConfigRef: "BUILD_CONFIG_REF", // the same value as lorax-composer puts here
|
|
Packit |
63bb0d |
BuildEnvRef: "BUILD_ENV_REF", // the same value as lorax-composer puts here
|
|
Packit |
63bb0d |
Source: PackageSource{
|
|
Packit |
63bb0d |
License: pkg.License,
|
|
Packit |
63bb0d |
Version: pkg.Version,
|
|
Packit |
63bb0d |
SourceRef: "SOURCE_REF", // the same value as lorax-composer puts here
|
|
Packit |
63bb0d |
},
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func (pkg Package) ToPackageInfo() PackageInfo {
|
|
Packit |
63bb0d |
return PackageInfo{
|
|
Packit |
63bb0d |
Name: pkg.Name,
|
|
Packit |
63bb0d |
Summary: pkg.Summary,
|
|
Packit |
63bb0d |
Description: pkg.Description,
|
|
Packit |
63bb0d |
Homepage: pkg.URL,
|
|
Packit |
63bb0d |
UpstreamVCS: "UPSTREAM_VCS", // the same value as lorax-composer puts here
|
|
Packit |
63bb0d |
Builds: []PackageBuild{pkg.ToPackageBuild()},
|
|
Packit |
63bb0d |
Dependencies: nil,
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit Service |
15f37d |
// The inputs to depsolve, a set of packages to include and a set of
|
|
Packit Service |
15f37d |
// packages to exclude.
|
|
Packit Service |
15f37d |
type PackageSet struct {
|
|
Packit Service |
15f37d |
Include []string
|
|
Packit Service |
15f37d |
Exclude []string
|
|
Packit Service |
15f37d |
}
|
|
Packit Service |
15f37d |
|
|
Packit |
63bb0d |
// TODO: the public API of this package should not be reused for serialization.
|
|
Packit |
63bb0d |
type PackageSpec struct {
|
|
Packit |
63bb0d |
Name string `json:"name"`
|
|
Packit |
63bb0d |
Epoch uint `json:"epoch"`
|
|
Packit |
63bb0d |
Version string `json:"version,omitempty"`
|
|
Packit |
63bb0d |
Release string `json:"release,omitempty"`
|
|
Packit |
63bb0d |
Arch string `json:"arch,omitempty"`
|
|
Packit |
63bb0d |
RemoteLocation string `json:"remote_location,omitempty"`
|
|
Packit |
63bb0d |
Checksum string `json:"checksum,omitempty"`
|
|
Packit |
63bb0d |
Secrets string `json:"secrets,omitempty"`
|
|
Packit |
63bb0d |
CheckGPG bool `json:"check_gpg,omitempty"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
type dnfPackageSpec struct {
|
|
Packit |
63bb0d |
Name string `json:"name"`
|
|
Packit |
63bb0d |
Epoch uint `json:"epoch"`
|
|
Packit |
63bb0d |
Version string `json:"version,omitempty"`
|
|
Packit |
63bb0d |
Release string `json:"release,omitempty"`
|
|
Packit |
63bb0d |
Arch string `json:"arch,omitempty"`
|
|
Packit |
63bb0d |
RepoID string `json:"repo_id,omitempty"`
|
|
Packit |
63bb0d |
Path string `json:"path,omitempty"`
|
|
Packit |
63bb0d |
RemoteLocation string `json:"remote_location,omitempty"`
|
|
Packit |
63bb0d |
Checksum string `json:"checksum,omitempty"`
|
|
Packit |
63bb0d |
Secrets string `json:"secrets,omitempty"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
type PackageSource struct {
|
|
Packit |
63bb0d |
License string `json:"license"`
|
|
Packit |
63bb0d |
Version string `json:"version"`
|
|
Packit |
63bb0d |
SourceRef string `json:"source_ref"`
|
|
Packit |
63bb0d |
Metadata struct{} `json:"metadata"` // it's just an empty struct in lorax-composer
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
type PackageBuild struct {
|
|
Packit |
63bb0d |
Arch string `json:"arch"`
|
|
Packit |
63bb0d |
BuildTime string `json:"build_time"`
|
|
Packit |
63bb0d |
Epoch uint `json:"epoch"`
|
|
Packit |
63bb0d |
Release string `json:"release"`
|
|
Packit |
63bb0d |
Source PackageSource `json:"source"`
|
|
Packit |
63bb0d |
Changelog string `json:"changelog"`
|
|
Packit |
63bb0d |
BuildConfigRef string `json:"build_config_ref"`
|
|
Packit |
63bb0d |
BuildEnvRef string `json:"build_env_ref"`
|
|
Packit |
63bb0d |
Metadata struct{} `json:"metadata"` // it's just an empty struct in lorax-composer
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
type PackageInfo struct {
|
|
Packit |
63bb0d |
Name string `json:"name"`
|
|
Packit |
63bb0d |
Summary string `json:"summary"`
|
|
Packit |
63bb0d |
Description string `json:"description"`
|
|
Packit |
63bb0d |
Homepage string `json:"homepage"`
|
|
Packit |
63bb0d |
UpstreamVCS string `json:"upstream_vcs"`
|
|
Packit |
63bb0d |
Builds []PackageBuild `json:"builds"`
|
|
Packit |
63bb0d |
Dependencies []PackageSpec `json:"dependencies,omitempty"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
type RPMMD interface {
|
|
Packit |
63bb0d |
// FetchMetadata returns all metadata about the repositories we use in the code. Specifically it is a
|
|
Packit |
63bb0d |
// list of packages and dictionary of checksums of the repositories.
|
|
Packit |
63bb0d |
FetchMetadata(repos []RepoConfig, modulePlatformID string, arch string) (PackageList, map[string]string, error)
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Depsolve takes a list of required content (specs), explicitly unwanted content (excludeSpecs), list
|
|
Packit |
63bb0d |
// or repositories, and platform ID for modularity. It returns a list of all packages (with solved
|
|
Packit |
63bb0d |
// dependencies) that will be installed into the system.
|
|
Packit Service |
15f37d |
Depsolve(packageSet PackageSet, repos []RepoConfig, modulePlatformID, arch string) ([]PackageSpec, map[string]string, error)
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
type DNFError struct {
|
|
Packit |
63bb0d |
Kind string `json:"kind"`
|
|
Packit |
63bb0d |
Reason string `json:"reason"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func (err *DNFError) Error() string {
|
|
Packit |
63bb0d |
return fmt.Sprintf("DNF error occured: %s: %s", err.Kind, err.Reason)
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
type RepositoryError struct {
|
|
Packit |
63bb0d |
msg string
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func (re *RepositoryError) Error() string {
|
|
Packit |
63bb0d |
return re.msg
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
type RHSMSecrets struct {
|
|
Packit |
63bb0d |
SSLCACert string `json:"sslcacert,omitempty"`
|
|
Packit |
63bb0d |
SSLClientKey string `json:"sslclientkey,omitempty"`
|
|
Packit |
63bb0d |
SSLClientCert string `json:"sslclientcert,omitempty"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func getRHSMSecrets() *RHSMSecrets {
|
|
Packit |
63bb0d |
keys, err := filepath.Glob("/etc/pki/entitlement/*-key.pem")
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
return nil
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
for _, key := range keys {
|
|
Packit |
63bb0d |
cert := strings.TrimSuffix(key, "-key.pem") + ".pem"
|
|
Packit |
63bb0d |
if _, err := os.Stat(cert); err == nil {
|
|
Packit |
63bb0d |
return &RHSMSecrets{
|
|
Packit |
63bb0d |
SSLCACert: "/etc/rhsm/ca/redhat-uep.pem",
|
|
Packit |
63bb0d |
SSLClientKey: key,
|
|
Packit |
63bb0d |
SSLClientCert: cert,
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
return nil
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func LoadRepositories(confPaths []string, distro string) (map[string][]RepoConfig, error) {
|
|
Packit |
63bb0d |
var f *os.File
|
|
Packit |
63bb0d |
var err error
|
|
Packit |
63bb0d |
path := "/repositories/" + distro + ".json"
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
for _, confPath := range confPaths {
|
|
Packit |
63bb0d |
f, err = os.Open(confPath + path)
|
|
Packit |
63bb0d |
if err == nil {
|
|
Packit |
63bb0d |
break
|
|
Packit |
63bb0d |
} else if !os.IsNotExist(err) {
|
|
Packit |
63bb0d |
return nil, err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
return nil, &RepositoryError{"LoadRepositories failed: none of the provided paths contain distro configuration"}
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
defer f.Close()
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
var reposMap map[string][]repository
|
|
Packit |
63bb0d |
repoConfigs := make(map[string][]RepoConfig)
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
err = json.NewDecoder(f).Decode(&reposMap)
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
return nil, err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
for arch, repos := range reposMap {
|
|
Packit |
63bb0d |
for _, repo := range repos {
|
|
Packit |
63bb0d |
config := RepoConfig{
|
|
Packit |
63bb0d |
Name: repo.Name,
|
|
Packit |
63bb0d |
BaseURL: repo.BaseURL,
|
|
Packit |
63bb0d |
Metalink: repo.Metalink,
|
|
Packit |
63bb0d |
MirrorList: repo.MirrorList,
|
|
Packit |
63bb0d |
GPGKey: repo.GPGKey,
|
|
Packit |
63bb0d |
CheckGPG: repo.CheckGPG,
|
|
Packit |
63bb0d |
RHSM: repo.RHSM,
|
|
Packit |
63bb0d |
MetadataExpire: repo.MetadataExpire,
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
repoConfigs[arch] = append(repoConfigs[arch], config)
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
return repoConfigs, nil
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func runDNF(dnfJsonPath string, command string, arguments interface{}, result interface{}) error {
|
|
Packit |
63bb0d |
var call = struct {
|
|
Packit |
63bb0d |
Command string `json:"command"`
|
|
Packit |
63bb0d |
Arguments interface{} `json:"arguments,omitempty"`
|
|
Packit |
63bb0d |
}{
|
|
Packit |
63bb0d |
command,
|
|
Packit |
63bb0d |
arguments,
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
cmd := exec.Command(dnfJsonPath)
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
stdin, err := cmd.StdinPipe()
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
return err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
cmd.Stderr = os.Stderr
|
|
Packit |
63bb0d |
stdout, err := cmd.StdoutPipe()
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
return err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
err = cmd.Start()
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
return err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
err = json.NewEncoder(stdin).Encode(call)
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
return err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
stdin.Close()
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
output, err := ioutil.ReadAll(stdout)
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
return err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
err = cmd.Wait()
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
const DnfErrorExitCode = 10
|
|
Packit |
63bb0d |
if runError, ok := err.(*exec.ExitError); ok && runError.ExitCode() == DnfErrorExitCode {
|
|
Packit |
63bb0d |
var dnfError DNFError
|
|
Packit |
63bb0d |
err = json.Unmarshal(output, &dnfError)
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
return err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
return &dnfError
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
err = json.Unmarshal(output, result)
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
return err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
return nil
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
type rpmmdImpl struct {
|
|
Packit |
63bb0d |
CacheDir string
|
|
Packit |
63bb0d |
RHSM *RHSMSecrets
|
|
Packit |
63bb0d |
dnfJsonPath string
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func NewRPMMD(cacheDir, dnfJsonPath string) RPMMD {
|
|
Packit |
63bb0d |
return &rpmmdImpl{
|
|
Packit |
63bb0d |
CacheDir: cacheDir,
|
|
Packit |
63bb0d |
RHSM: getRHSMSecrets(),
|
|
Packit |
63bb0d |
dnfJsonPath: dnfJsonPath,
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func (repo RepoConfig) toDNFRepoConfig(rpmmd *rpmmdImpl, i int) (dnfRepoConfig, error) {
|
|
Packit |
63bb0d |
id := strconv.Itoa(i)
|
|
Packit |
63bb0d |
dnfRepo := dnfRepoConfig{
|
|
Packit |
63bb0d |
ID: id,
|
|
Packit |
63bb0d |
BaseURL: repo.BaseURL,
|
|
Packit |
63bb0d |
Metalink: repo.Metalink,
|
|
Packit |
63bb0d |
MirrorList: repo.MirrorList,
|
|
Packit |
63bb0d |
GPGKey: repo.GPGKey,
|
|
Packit |
63bb0d |
IgnoreSSL: repo.IgnoreSSL,
|
|
Packit |
63bb0d |
MetadataExpire: repo.MetadataExpire,
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
if repo.RHSM {
|
|
Packit |
63bb0d |
if rpmmd.RHSM == nil {
|
|
Packit |
63bb0d |
return dnfRepoConfig{}, fmt.Errorf("RHSM secrets not found on host")
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
dnfRepo.SSLCACert = rpmmd.RHSM.SSLCACert
|
|
Packit |
63bb0d |
dnfRepo.SSLClientKey = rpmmd.RHSM.SSLClientKey
|
|
Packit |
63bb0d |
dnfRepo.SSLClientCert = rpmmd.RHSM.SSLClientCert
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
return dnfRepo, nil
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func (r *rpmmdImpl) FetchMetadata(repos []RepoConfig, modulePlatformID string, arch string) (PackageList, map[string]string, error) {
|
|
Packit |
63bb0d |
var dnfRepoConfigs []dnfRepoConfig
|
|
Packit |
63bb0d |
for i, repo := range repos {
|
|
Packit |
63bb0d |
dnfRepo, err := repo.toDNFRepoConfig(r, i)
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
return nil, nil, err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
dnfRepoConfigs = append(dnfRepoConfigs, dnfRepo)
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
var arguments = struct {
|
|
Packit |
63bb0d |
Repos []dnfRepoConfig `json:"repos"`
|
|
Packit |
63bb0d |
CacheDir string `json:"cachedir"`
|
|
Packit |
63bb0d |
ModulePlatformID string `json:"module_platform_id"`
|
|
Packit |
63bb0d |
Arch string `json:"arch"`
|
|
Packit |
63bb0d |
}{dnfRepoConfigs, r.CacheDir, modulePlatformID, arch}
|
|
Packit |
63bb0d |
var reply struct {
|
|
Packit |
63bb0d |
Checksums map[string]string `json:"checksums"`
|
|
Packit |
63bb0d |
Packages PackageList `json:"packages"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
err := runDNF(r.dnfJsonPath, "dump", arguments, &reply)
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
sort.Slice(reply.Packages, func(i, j int) bool {
|
|
Packit |
63bb0d |
return reply.Packages[i].Name < reply.Packages[j].Name
|
|
Packit |
63bb0d |
})
|
|
Packit |
63bb0d |
checksums := make(map[string]string)
|
|
Packit |
63bb0d |
for i, repo := range repos {
|
|
Packit |
63bb0d |
checksums[repo.Name] = reply.Checksums[strconv.Itoa(i)]
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
return reply.Packages, checksums, err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit Service |
15f37d |
func (r *rpmmdImpl) Depsolve(packageSet PackageSet, repos []RepoConfig, modulePlatformID, arch string) ([]PackageSpec, map[string]string, error) {
|
|
Packit |
63bb0d |
var dnfRepoConfigs []dnfRepoConfig
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
for i, repo := range repos {
|
|
Packit |
63bb0d |
dnfRepo, err := repo.toDNFRepoConfig(r, i)
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
return nil, nil, err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
dnfRepoConfigs = append(dnfRepoConfigs, dnfRepo)
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
var arguments = struct {
|
|
Packit |
63bb0d |
PackageSpecs []string `json:"package-specs"`
|
|
Packit |
63bb0d |
ExcludSpecs []string `json:"exclude-specs"`
|
|
Packit |
63bb0d |
Repos []dnfRepoConfig `json:"repos"`
|
|
Packit |
63bb0d |
CacheDir string `json:"cachedir"`
|
|
Packit |
63bb0d |
ModulePlatformID string `json:"module_platform_id"`
|
|
Packit |
63bb0d |
Arch string `json:"arch"`
|
|
Packit Service |
15f37d |
}{packageSet.Include, packageSet.Exclude, dnfRepoConfigs, r.CacheDir, modulePlatformID, arch}
|
|
Packit |
63bb0d |
var reply struct {
|
|
Packit |
63bb0d |
Checksums map[string]string `json:"checksums"`
|
|
Packit |
63bb0d |
Dependencies []dnfPackageSpec `json:"dependencies"`
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
err := runDNF(r.dnfJsonPath, "depsolve", arguments, &reply)
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
dependencies := make([]PackageSpec, len(reply.Dependencies))
|
|
Packit |
63bb0d |
for i, pack := range reply.Dependencies {
|
|
Packit |
63bb0d |
id, err := strconv.Atoi(pack.RepoID)
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
panic(err)
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
repo := repos[id]
|
|
Packit |
63bb0d |
dep := reply.Dependencies[i]
|
|
Packit |
63bb0d |
dependencies[i].Name = dep.Name
|
|
Packit |
63bb0d |
dependencies[i].Epoch = dep.Epoch
|
|
Packit |
63bb0d |
dependencies[i].Version = dep.Version
|
|
Packit |
63bb0d |
dependencies[i].Release = dep.Release
|
|
Packit |
63bb0d |
dependencies[i].Arch = dep.Arch
|
|
Packit |
63bb0d |
dependencies[i].RemoteLocation = dep.RemoteLocation
|
|
Packit |
63bb0d |
dependencies[i].Checksum = dep.Checksum
|
|
Packit |
63bb0d |
dependencies[i].CheckGPG = repo.CheckGPG
|
|
Packit |
63bb0d |
if repo.RHSM {
|
|
Packit |
63bb0d |
dependencies[i].Secrets = "org.osbuild.rhsm"
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
return dependencies, reply.Checksums, err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func (packages PackageList) Search(globPatterns ...string) (PackageList, error) {
|
|
Packit |
63bb0d |
var globs []glob.Glob
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
for _, globPattern := range globPatterns {
|
|
Packit |
63bb0d |
g, err := glob.Compile(globPattern)
|
|
Packit |
63bb0d |
if err != nil {
|
|
Packit |
63bb0d |
return nil, err
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
globs = append(globs, g)
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
var foundPackages PackageList
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
for _, pkg := range packages {
|
|
Packit |
63bb0d |
for _, g := range globs {
|
|
Packit |
63bb0d |
if g.Match(pkg.Name) {
|
|
Packit |
63bb0d |
foundPackages = append(foundPackages, pkg)
|
|
Packit |
63bb0d |
break
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
sort.Slice(packages, func(i, j int) bool {
|
|
Packit |
63bb0d |
return packages[i].Name < packages[j].Name
|
|
Packit |
63bb0d |
})
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
return foundPackages, nil
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func (packages PackageList) ToPackageInfos() []PackageInfo {
|
|
Packit |
63bb0d |
resultsNames := make(map[string]int)
|
|
Packit |
63bb0d |
var results []PackageInfo
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
for _, pkg := range packages {
|
|
Packit |
63bb0d |
if index, ok := resultsNames[pkg.Name]; ok {
|
|
Packit |
63bb0d |
foundPkg := &results[index]
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
foundPkg.Builds = append(foundPkg.Builds, pkg.ToPackageBuild())
|
|
Packit |
63bb0d |
} else {
|
|
Packit |
63bb0d |
newIndex := len(results)
|
|
Packit |
63bb0d |
resultsNames[pkg.Name] = newIndex
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
packageInfo := pkg.ToPackageInfo()
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
results = append(results, packageInfo)
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
return results
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func (pkg *PackageInfo) FillDependencies(rpmmd RPMMD, repos []RepoConfig, modulePlatformID string, arch string) (err error) {
|
|
Packit Service |
15f37d |
pkg.Dependencies, _, err = rpmmd.Depsolve(PackageSet{Include: []string{pkg.Name}}, repos, modulePlatformID, arch)
|
|
Packit |
63bb0d |
return
|
|
Packit |
63bb0d |
}
|