Blame internal/rpmmd/repository.go

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
}