Skip to content

Commit b8a2f8c

Browse files
committed
Add Docker Auth Wrapper to check for auth entries for all Docker Hub domains
1 parent 91b834d commit b8a2f8c

4 files changed

Lines changed: 64 additions & 8 deletions

File tree

internal/ocidocker/dockerhub.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
11
package ocidocker
22

3-
var DockerHubHosts = map[string]struct{}{
4-
"": {},
5-
"docker.io": {},
6-
"index.docker.io": {},
7-
"registry-1.docker.io": {},
8-
"registry.hub.docker.com": {},
9-
}
3+
import (
4+
"sync"
5+
)
6+
7+
var (
8+
DockerHubHosts = map[string]byte{
9+
"index.docker.io": 0,
10+
"registry-1.docker.io": 1,
11+
"docker.io": 2,
12+
"registry.hub.docker.com": 3,
13+
"": 4,
14+
}
15+
DockerHubHostsSorted = sync.OnceValue(func() []string {
16+
sorted := make([]string, len(DockerHubHosts))
17+
for host, rank := range DockerHubHosts {
18+
sorted[rank] = host
19+
}
20+
return sorted
21+
})
22+
)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package ocidocker
2+
3+
import "testing"
4+
5+
func TestHostsSorted(t *testing.T) {
6+
sorted := DockerHubHostsSorted()
7+
for i, host := range sorted {
8+
if i != int(DockerHubHosts[host]) {
9+
t.Errorf("host %s not sorted", host)
10+
}
11+
}
12+
}

ociauth/auth.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ func (r *registry) setAuthorizationFromChallenge(ctx context.Context, req *http.
293293
// the outer context is cancelled, but we'll ignore that. We probably shouldn't.
294294
func (r *registry) init() error {
295295
inner := func() error {
296-
info, err := r.config.EntryForRegistry(r.host)
296+
info, err := dockerWrapper{r.config}.EntryForRegistry(r.host)
297297
if err != nil {
298298
return fmt.Errorf("cannot acquire auth info for registry %q: %v", r.host, err)
299299
}

ociauth/docker.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package ociauth
2+
3+
import (
4+
"github.com/docker/oci/internal/ocidocker"
5+
)
6+
7+
// DockerWrapper is an ociauth.Config implementation that wraps an underlying ociauth.Config in order to check
8+
// credentials for every Docker Hub domain when credentials for any Hub domain are requested.
9+
type dockerWrapper struct {
10+
Config
11+
}
12+
13+
// EntryForRegistry returns credentials for a given host.
14+
func (w dockerWrapper) EntryForRegistry(host string) (ConfigEntry, error) {
15+
var zero ConfigEntry // "EntryForRegistry" doesn't return an error on a miss - it just returns an empty object (so we create this to have something to trivially compare against for our fallback)
16+
if entry, err := w.Config.EntryForRegistry(host); err == nil && entry != zero {
17+
return entry, err
18+
} else if _, ok := ocidocker.DockerHubHosts[host]; ok {
19+
for _, dockerHubHost := range ocidocker.DockerHubHostsSorted() {
20+
if dockerHubHost == "" {
21+
continue
22+
}
23+
if entry, err = w.Config.EntryForRegistry(dockerHubHost); err == nil && entry != zero {
24+
return entry, err
25+
}
26+
}
27+
return entry, err
28+
} else {
29+
return entry, err
30+
}
31+
}

0 commit comments

Comments
 (0)