Skip to content

Commit 6f0e3ea

Browse files
feat!: implement the referrers route in the v2 package (#32)
Implement the `referrers` route in the `registry/api/v2` package. Path with filtering on `ArtifactType` is also implemented. Unit tests are included. The next pr will implement `referrersHandler` but probably will not implement filtering yet. Part 5 of #21 Signed-off-by: wangxiaoxuan273 <wangxiaoxuan119@gmail.com>
1 parent 0e64ff7 commit 6f0e3ea

5 files changed

Lines changed: 169 additions & 0 deletions

File tree

registry/api/v2/descriptors.go

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,6 +1595,134 @@ var routeDescriptors = []RouteDescriptor{
15951595
},
15961596
},
15971597
},
1598+
{
1599+
Name: RouteNameReferrers,
1600+
Path: "/v2/{name:" + reference.NameRegexp.String() + "}/referrers/{digest:" + digest.DigestRegexp.String() + "}",
1601+
Entity: "Referrers",
1602+
Description: `Retrieve information about referrers.`,
1603+
Methods: []MethodDescriptor{
1604+
{
1605+
Method: "GET",
1606+
Description: "Fetch the referrers of the artifact identified by `digest`.",
1607+
Requests: []RequestDescriptor{
1608+
{
1609+
Name: "Referrers",
1610+
Description: "Request an unabridged list of referrers.",
1611+
Successes: []ResponseDescriptor{
1612+
{
1613+
Description: "Returns an image index containing all referrers as a json response.",
1614+
StatusCode: http.StatusOK,
1615+
Headers: []ParameterDescriptor{
1616+
{
1617+
Name: "Content-Length",
1618+
Type: "integer",
1619+
Description: "Length of the JSON response body.",
1620+
Format: "<length>",
1621+
},
1622+
linkHeader,
1623+
},
1624+
Body: BodyDescriptor{
1625+
ContentType: "application/vnd.oci.image.index.v1+json",
1626+
Format: `{
1627+
"schemaVersion": 2,
1628+
"mediaType": "application/vnd.oci.image.index.v1+json",
1629+
"manifests": [
1630+
<manifest>,
1631+
...
1632+
]
1633+
}`,
1634+
},
1635+
},
1636+
},
1637+
Failures: []ResponseDescriptor{
1638+
{
1639+
Description: "The registry does not support referrers API.",
1640+
StatusCode: http.StatusNotFound,
1641+
},
1642+
{
1643+
Description: "There was a problem with the request that needs to be addressed by the client, such as an invalid `name` or `digest`.",
1644+
StatusCode: http.StatusBadRequest,
1645+
ErrorCodes: []errcode.ErrorCode{
1646+
ErrorCodeDigestInvalid,
1647+
},
1648+
Body: BodyDescriptor{
1649+
ContentType: "application/json",
1650+
Format: errorsBody,
1651+
},
1652+
},
1653+
deniedResponseDescriptor,
1654+
tooManyRequestsDescriptor,
1655+
},
1656+
},
1657+
{
1658+
// may need to change to accommodate multiple filters applied.
1659+
// spec is not clear regarding applying multiple filters
1660+
Name: "referrers with filtering",
1661+
Description: "Request a list of referrers filtered on artifact type.",
1662+
QueryParameters: []ParameterDescriptor{
1663+
{
1664+
Name: "artifactType",
1665+
Type: "string",
1666+
Description: "This is the artifact type to be appied on the filter.",
1667+
Format: "<string>",
1668+
Required: false,
1669+
},
1670+
},
1671+
Successes: []ResponseDescriptor{
1672+
{
1673+
Description: "Returns an image index containing all referrers as a json response with the filter applied.",
1674+
StatusCode: http.StatusOK,
1675+
Headers: []ParameterDescriptor{
1676+
{
1677+
Name: "Content-Length",
1678+
Type: "integer",
1679+
Description: "Length of the JSON response body.",
1680+
Format: "<length>",
1681+
},
1682+
linkHeader,
1683+
},
1684+
Body: BodyDescriptor{
1685+
ContentType: "application/vnd.oci.image.index.v1+json",
1686+
Format: `{
1687+
"schemaVersion": 2,
1688+
"mediaType": "application/vnd.oci.image.index.v1+json",
1689+
"manifests": [
1690+
<manifest>,
1691+
...
1692+
],
1693+
"annotations": {
1694+
"org.opencontainers.referrers.filtersApplied": <filter>,
1695+
...
1696+
}
1697+
}`,
1698+
},
1699+
},
1700+
},
1701+
Failures: []ResponseDescriptor{
1702+
{
1703+
Description: "The registry does not support referrers API.",
1704+
StatusCode: http.StatusNotFound,
1705+
},
1706+
{
1707+
Description: "There was a problem with the request that needs to be addressed by the client, such as an invalid `name` or `digest`.",
1708+
StatusCode: http.StatusBadRequest,
1709+
ErrorCodes: []errcode.ErrorCode{
1710+
ErrorCodeDigestInvalid,
1711+
},
1712+
Body: BodyDescriptor{
1713+
ContentType: "application/json",
1714+
Format: errorsBody,
1715+
},
1716+
},
1717+
repositoryNotFoundResponseDescriptor,
1718+
deniedResponseDescriptor,
1719+
tooManyRequestsDescriptor,
1720+
},
1721+
},
1722+
},
1723+
},
1724+
},
1725+
},
15981726
}
15991727

16001728
var routeDescriptorsMap map[string]RouteDescriptor

registry/api/v2/routes.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const (
1616
RouteNameBlobUpload = "blob-upload"
1717
RouteNameBlobUploadChunk = "blob-upload-chunk"
1818
RouteNameCatalog = "catalog"
19+
RouteNameReferrers = "referrers"
1920
)
2021

2122
var (

registry/api/v2/routes_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,14 @@ func TestRouter(t *testing.T) {
170170
"reference": "tag",
171171
},
172172
},
173+
{
174+
RouteName: RouteNameReferrers,
175+
RequestURI: "/v2/foo/referrers/sha256:abcdef0919234",
176+
Vars: map[string]string{
177+
"name": "foo",
178+
"digest": "sha256:abcdef0919234",
179+
},
180+
},
173181
}
174182

175183
checkTestRouter(t, testCases, "", true)

registry/api/v2/urls.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,18 @@ func (ub *URLBuilder) BuildManifestURL(ref reference.Named) (string, error) {
162162
return manifestURL.String(), nil
163163
}
164164

165+
// BuildReferrersURL constructs the url to fetch a list of referrers
166+
func (ub *URLBuilder) BuildReferrersURL(ref reference.Canonical, values ...url.Values) (string, error) {
167+
route := ub.cloneRoute(RouteNameReferrers)
168+
169+
referrersURL, err := route.URL("name", ref.Name(), "digest", ref.Digest().String())
170+
if err != nil {
171+
return "", err
172+
}
173+
174+
return appendValuesURL(referrersURL, values...).String(), nil
175+
}
176+
165177
// BuildBlobURL constructs the url for the blob identified by name and dgst.
166178
func (ub *URLBuilder) BuildBlobURL(ref reference.Canonical) (string, error) {
167179
route := ub.cloneRoute(RouteNameBlob)

registry/api/v2/urls_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,26 @@ func makeURLBuilderTestCases(urlBuilder *URLBuilder) []urlBuilderTestCase {
118118
})
119119
},
120120
},
121+
{
122+
description: "build referrers url",
123+
expectedPath: "/v2/foo/bar/referrers/sha256:3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d5",
124+
expectedErr: nil,
125+
build: func() (string, error) {
126+
ref, _ := reference.WithDigest(fooBarRef, "sha256:3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d5")
127+
return urlBuilder.BuildReferrersURL(ref)
128+
},
129+
},
130+
{
131+
description: "build referrers url with artifact type parameter",
132+
expectedPath: "/v2/foo/bar/referrers/sha256:3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d5?artifactType=example.test.type",
133+
expectedErr: nil,
134+
build: func() (string, error) {
135+
ref, _ := reference.WithDigest(fooBarRef, "sha256:3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d5")
136+
return urlBuilder.BuildReferrersURL(ref, url.Values{
137+
"artifactType": []string{"example.test.type"},
138+
})
139+
},
140+
},
121141
}
122142
}
123143

0 commit comments

Comments
 (0)