-
Notifications
You must be signed in to change notification settings - Fork 43
/
reporegistry.go
126 lines (105 loc) · 4.24 KB
/
reporegistry.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package reporegistry
import (
"fmt"
"github.com/osbuild/images/pkg/distroidparser"
"github.com/osbuild/images/pkg/rpmmd"
)
// RepoRegistry represents a database of distro and architecture
// specific RPM repositories. Image types are considered only
// if the loaded repository definition contains any ImageTypeTags.
type RepoRegistry struct {
repos rpmmd.DistrosRepoConfigs
}
// New returns a new RepoRegistry instance with the data
// loaded from the given repoConfigPaths
func New(repoConfigPaths []string) (*RepoRegistry, error) {
repositories, err := LoadAllRepositories(repoConfigPaths)
if err != nil {
return nil, err
}
return &RepoRegistry{repositories}, nil
}
// NewTestedDefault returns a new RepoRegistry instance with the data
// loaded from the default test repositories
func NewTestedDefault() (*RepoRegistry, error) {
testReposPath := []string{"./test/data"}
return New(testReposPath)
}
func NewFromDistrosRepoConfigs(distrosRepoConfigs rpmmd.DistrosRepoConfigs) *RepoRegistry {
return &RepoRegistry{distrosRepoConfigs}
}
// ReposByImageTypeName returns a slice of rpmmd.RepoConfig instances, which should be used for building the specific
// image type name (of a given distribution and architecture). The method does not verify
// if the given image type name is actually part of the architecture definition of the provided name.
// Therefore in general, all common distro-arch-specific repositories are returned for any image type name,
// even for non-existing ones.
func (r *RepoRegistry) ReposByImageTypeName(distro, arch, imageType string) ([]rpmmd.RepoConfig, error) {
repositories := []rpmmd.RepoConfig{}
archRepos, err := r.ReposByArchName(distro, arch, true)
if err != nil {
return nil, err
}
for _, repo := range archRepos {
// Add all repositories without image_type tags
if len(repo.ImageTypeTags) == 0 {
repositories = append(repositories, repo)
continue
}
// Add all repositories tagged with the image type
for _, imageNameTag := range repo.ImageTypeTags {
if imageNameTag == imageType {
repositories = append(repositories, repo)
break
}
}
}
return repositories, nil
}
// reposByArchName returns a slice of rpmmd.RepoConfig instances, which should be used for building image types for the
// specific architecture and distribution. This includes by default all repositories without any image type tags specified.
// Depending on the `includeTagged` argument value, repositories with image type tags set will be added to the returned
// slice or not.
//
// The method does not verify if the given architecture name is actually part of the specific distribution definition.
func (r *RepoRegistry) ReposByArchName(distro, arch string, includeTagged bool) ([]rpmmd.RepoConfig, error) {
repositories := []rpmmd.RepoConfig{}
archRepos, err := r.DistroHasRepos(distro, arch)
if err != nil {
return nil, fmt.Errorf("Failed to get repositories for distribution '%s' and architecture '%s': %v", distro, arch, err)
}
for _, repo := range archRepos {
// skip repos with image type tags if specified to do so
if !includeTagged && len(repo.ImageTypeTags) != 0 {
continue
}
repositories = append(repositories, repo)
}
return repositories, nil
}
// DistroHasRepos returns the repositories for the distro+arch, and a found flag
func (r *RepoRegistry) DistroHasRepos(distro, arch string) ([]rpmmd.RepoConfig, error) {
// compatibility layer to support old repository definition filenames
// without a dot to separate major and minor release versions
stdDistroName, err := distroidparser.DefaultParser.Standardize(distro)
if err != nil {
return nil, fmt.Errorf("failed to parse distro ID string: %v", err)
}
distroRepos, found := r.repos[stdDistroName]
if !found {
return nil, fmt.Errorf("there are no repositories for distribution '%s'", stdDistroName)
}
repos, found := distroRepos[arch]
if !found {
return nil, fmt.Errorf("there are no repositories for distribution '%s' and architecture '%s'", stdDistroName, arch)
}
return repos, nil
}
// ListDistros returns a list of all distros which have a repository defined
// in the registry.
func (r *RepoRegistry) ListDistros() []string {
distros := make([]string, 0, len(r.repos))
for name := range r.repos {
distros = append(distros, name)
}
return distros
}