Skip to content

Commit 41f843b

Browse files
authored
image-mapper: fix bad aliases in the data (#253)
There are images where the alias data is known to be incorrect and it is non-trivial to fix on our side at the moment. For now, let's correct those aliases in the mapper to improve the results. Add an integration test that tests against the actual data returned by GraphQL so we have a baseline for identifying regressions and codifying known-good output.
1 parent d6c9f3e commit 41f843b

4 files changed

Lines changed: 642 additions & 43 deletions

File tree

image-mapper/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,15 @@ docker run -it --rm image-mapper ghcr.io/stakater/reloader:v1.4.1
7878
# Or, pass a list of images from a text file
7979
docker run -i --rm image-mapper -- - < images.txt
8080
```
81+
82+
## Development
83+
84+
You can run integration tests against the actual catalog endpoint by setting
85+
`IMAGE_MAPPER_RUN_INTEGRATION_TESTS=1`:
86+
87+
```
88+
IMAGE_MAPPER_RUN_INTEGRATION_TESTS=1 go test ./...
89+
```
90+
91+
This identifies regressions in the mapping logic or the catalog data by
92+
recording known matches.

image-mapper/internal/mapper/mapper.go

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
package mapper
22

33
import (
4-
"bytes"
54
"context"
6-
"encoding/json"
75
"fmt"
8-
"net/http"
96
"slices"
107
"strings"
118

@@ -44,46 +41,6 @@ func NewMapper(ctx context.Context, opts ...Option) (*Mapper, error) {
4441
return m, nil
4542
}
4643

47-
// Repo describes a repo in the catalog
48-
type Repo struct {
49-
Name string `json:"name"`
50-
CatalogTier string `json:"catalogTier"`
51-
Aliases []string `json:"aliases"`
52-
}
53-
54-
func listRepos(ctx context.Context) ([]Repo, error) {
55-
c := &http.Client{}
56-
57-
buf := bytes.NewReader([]byte(`{"query":"query OrganizationImageCatalog($organization: ID!) {\n repos(filter: {uidp: {childrenOf: $organization}}) {\n name\n aliases\n catalogTier\n }\n}","variables":{"excludeDates":true,"excludeEpochs":true,"organization":"ce2d1984a010471142503340d670612d63ffb9f6"}}`))
58-
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "https://data.chainguard.dev/query?id=PrivateImageCatalog", buf)
59-
if err != nil {
60-
return nil, fmt.Errorf("constructing request: %w", err)
61-
}
62-
req.Header.Add("Content-Type", "application/json")
63-
req.Header.Add("User-Agent", "image-mapper")
64-
65-
resp, err := c.Do(req)
66-
if err != nil {
67-
return nil, fmt.Errorf("making request: %w", err)
68-
}
69-
defer resp.Body.Close()
70-
71-
if resp.StatusCode != http.StatusOK {
72-
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
73-
}
74-
75-
var data struct {
76-
Data struct {
77-
Repos []Repo `json:"repos"`
78-
} `json:"data"`
79-
}
80-
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
81-
return nil, fmt.Errorf("unmarshaling body: %w", err)
82-
}
83-
84-
return data.Data.Repos, nil
85-
}
86-
8744
// MapAll returns mappings for all the images returned by the iterator
8845
func (m *Mapper) MapAll(it Iterator) ([]*Mapping, error) {
8946
mapped := make(map[string]struct{})
@@ -145,6 +102,7 @@ func (m *Mapper) Map(image string) (*Mapping, error) {
145102
for match := range matches {
146103
results = append(results, match)
147104
}
105+
slices.Sort(results)
148106

149107
return &Mapping{
150108
Image: image,

0 commit comments

Comments
 (0)