forked from TrueCloudLab/distribution
Enable proxying registries to downgrade fetched manifests to Schema 1.
Ensure Accept headers are sent with TagService.Get (which hits manifest endpoints). Add support for remote Get and Put for the proxied blobstore. Signed-off-by: Richard Scothern <richard.scothern@gmail.com>
This commit is contained in:
parent
16445b6767
commit
36936218c2
3 changed files with 77 additions and 7 deletions
|
@ -257,9 +257,18 @@ func (t *tags) Get(ctx context.Context, tag string) (distribution.Descriptor, er
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return distribution.Descriptor{}, err
|
return distribution.Descriptor{}, err
|
||||||
}
|
}
|
||||||
var attempts int
|
|
||||||
resp, err := t.client.Head(u)
|
|
||||||
|
|
||||||
|
req, err := http.NewRequest("HEAD", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return distribution.Descriptor{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, t := range distribution.ManifestMediaTypes() {
|
||||||
|
req.Header.Add("Accept", t)
|
||||||
|
}
|
||||||
|
|
||||||
|
var attempts int
|
||||||
|
resp, err := t.client.Do(req)
|
||||||
check:
|
check:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return distribution.Descriptor{}, err
|
return distribution.Descriptor{}, err
|
||||||
|
@ -269,7 +278,16 @@ check:
|
||||||
case resp.StatusCode >= 200 && resp.StatusCode < 400:
|
case resp.StatusCode >= 200 && resp.StatusCode < 400:
|
||||||
return descriptorFromResponse(resp)
|
return descriptorFromResponse(resp)
|
||||||
case resp.StatusCode == http.StatusMethodNotAllowed:
|
case resp.StatusCode == http.StatusMethodNotAllowed:
|
||||||
resp, err = t.client.Get(u)
|
req, err = http.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
return distribution.Descriptor{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, t := range distribution.ManifestMediaTypes() {
|
||||||
|
req.Header.Add("Accept", t)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err = t.client.Do(req)
|
||||||
attempts++
|
attempts++
|
||||||
if attempts > 1 {
|
if attempts > 1 {
|
||||||
return distribution.Descriptor{}, err
|
return distribution.Descriptor{}, err
|
||||||
|
|
|
@ -174,6 +174,28 @@ func (pbs *proxyBlobStore) Stat(ctx context.Context, dgst digest.Digest) (distri
|
||||||
return pbs.remoteStore.Stat(ctx, dgst)
|
return pbs.remoteStore.Stat(ctx, dgst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pbs *proxyBlobStore) Get(ctx context.Context, dgst digest.Digest) ([]byte, error) {
|
||||||
|
blob, err := pbs.localStore.Get(ctx, dgst)
|
||||||
|
if err == nil {
|
||||||
|
return blob, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := pbs.authChallenger.tryEstablishChallenges(ctx); err != nil {
|
||||||
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
blob, err = pbs.remoteStore.Get(ctx, dgst)
|
||||||
|
if err != nil {
|
||||||
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = pbs.localStore.Put(ctx, "", blob)
|
||||||
|
if err != nil {
|
||||||
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
return blob, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Unsupported functions
|
// Unsupported functions
|
||||||
func (pbs *proxyBlobStore) Put(ctx context.Context, mediaType string, p []byte) (distribution.Descriptor, error) {
|
func (pbs *proxyBlobStore) Put(ctx context.Context, mediaType string, p []byte) (distribution.Descriptor, error) {
|
||||||
return distribution.Descriptor{}, distribution.ErrUnsupported
|
return distribution.Descriptor{}, distribution.ErrUnsupported
|
||||||
|
@ -195,10 +217,6 @@ func (pbs *proxyBlobStore) Open(ctx context.Context, dgst digest.Digest) (distri
|
||||||
return nil, distribution.ErrUnsupported
|
return nil, distribution.ErrUnsupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pbs *proxyBlobStore) Get(ctx context.Context, dgst digest.Digest) ([]byte, error) {
|
|
||||||
return nil, distribution.ErrUnsupported
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pbs *proxyBlobStore) Delete(ctx context.Context, dgst digest.Digest) error {
|
func (pbs *proxyBlobStore) Delete(ctx context.Context, dgst digest.Digest) error {
|
||||||
return distribution.ErrUnsupported
|
return distribution.ErrUnsupported
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,6 +218,40 @@ func populate(t *testing.T, te *testEnv, blobCount, size, numUnique int) {
|
||||||
te.inRemote = inRemote
|
te.inRemote = inRemote
|
||||||
te.numUnique = numUnique
|
te.numUnique = numUnique
|
||||||
}
|
}
|
||||||
|
func TestProxyStoreGet(t *testing.T) {
|
||||||
|
te := makeTestEnv(t, "foo/bar")
|
||||||
|
|
||||||
|
localStats := te.LocalStats()
|
||||||
|
remoteStats := te.RemoteStats()
|
||||||
|
|
||||||
|
populate(t, te, 1, 10, 1)
|
||||||
|
_, err := te.store.Get(te.ctx, te.inRemote[0].Digest)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*localStats)["get"] != 1 && (*localStats)["put"] != 1 {
|
||||||
|
t.Errorf("Unexpected local counts")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*remoteStats)["get"] != 1 {
|
||||||
|
t.Errorf("Unexpected remote get count")
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = te.store.Get(te.ctx, te.inRemote[0].Digest)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*localStats)["get"] != 2 && (*localStats)["put"] != 1 {
|
||||||
|
t.Errorf("Unexpected local counts")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*remoteStats)["get"] != 1 {
|
||||||
|
t.Errorf("Unexpected remote get count")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func TestProxyStoreStat(t *testing.T) {
|
func TestProxyStoreStat(t *testing.T) {
|
||||||
te := makeTestEnv(t, "foo/bar")
|
te := makeTestEnv(t, "foo/bar")
|
||||||
|
|
Loading…
Reference in a new issue