Blame internal/rpmmd/repository.go

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