Skip to content

Commit 045989e

Browse files
author
shin-
committed
Use basic auth for private registries when over HTTPS.
RequestFactory is no longer a singleton (can be different for different instances of Registry) Registry now has an indexEndpoint member Registry methods that needed the indexEndpoint parameter no longer do so Registry methods will only use token auth where applicable if basic auth is not enabled.
1 parent bbf9135 commit 045989e

File tree

3 files changed

+70
-44
lines changed

3 files changed

+70
-44
lines changed

registry/registry.go

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,9 @@ func (r *Registry) GetRemoteHistory(imgID, registry string, token []string) ([]s
160160
if err != nil {
161161
return nil, err
162162
}
163-
req.Header.Set("Authorization", "Token "+strings.Join(token, ", "))
163+
if req.Header.Get("Authorization") == "" { // Don't override
164+
req.Header.Set("Authorization", "Token "+strings.Join(token, ","))
165+
}
164166
res, err := doWithCookies(r.client, req)
165167
if err != nil {
166168
return nil, err
@@ -193,7 +195,9 @@ func (r *Registry) LookupRemoteImage(imgID, registry string, token []string) boo
193195
if err != nil {
194196
return false
195197
}
196-
req.Header.Set("Authorization", "Token "+strings.Join(token, ", "))
198+
if req.Header.Get("Authorization") == "" { // Don't override
199+
req.Header.Set("Authorization", "Token "+strings.Join(token, ","))
200+
}
197201
res, err := doWithCookies(r.client, req)
198202
if err != nil {
199203
return false
@@ -209,7 +213,9 @@ func (r *Registry) GetRemoteImageJSON(imgID, registry string, token []string) ([
209213
if err != nil {
210214
return nil, -1, fmt.Errorf("Failed to download json: %s", err)
211215
}
212-
req.Header.Set("Authorization", "Token "+strings.Join(token, ", "))
216+
if req.Header.Get("Authorization") == "" { // Don't override
217+
req.Header.Set("Authorization", "Token "+strings.Join(token, ","))
218+
}
213219
res, err := doWithCookies(r.client, req)
214220
if err != nil {
215221
return nil, -1, fmt.Errorf("Failed to download json: %s", err)
@@ -236,7 +242,9 @@ func (r *Registry) GetRemoteImageLayer(imgID, registry string, token []string) (
236242
if err != nil {
237243
return nil, fmt.Errorf("Error while getting from the server: %s\n", err)
238244
}
239-
req.Header.Set("Authorization", "Token "+strings.Join(token, ", "))
245+
if req.Header.Get("Authorization") == "" { // Don't override
246+
req.Header.Set("Authorization", "Token "+strings.Join(token, ","))
247+
}
240248
res, err := doWithCookies(r.client, req)
241249
if err != nil {
242250
return nil, err
@@ -262,7 +270,9 @@ func (r *Registry) GetRemoteTags(registries []string, repository string, token [
262270
if err != nil {
263271
return nil, err
264272
}
265-
req.Header.Set("Authorization", "Token "+strings.Join(token, ", "))
273+
if req.Header.Get("Authorization") == "" { // Don't override
274+
req.Header.Set("Authorization", "Token "+strings.Join(token, ","))
275+
}
266276
res, err := doWithCookies(r.client, req)
267277
if err != nil {
268278
return nil, err
@@ -290,7 +300,8 @@ func (r *Registry) GetRemoteTags(registries []string, repository string, token [
290300
return nil, fmt.Errorf("Could not reach any registry endpoint")
291301
}
292302

293-
func (r *Registry) GetRepositoryData(indexEp, remote string) (*RepositoryData, error) {
303+
func (r *Registry) GetRepositoryData(remote string) (*RepositoryData, error) {
304+
indexEp := r.indexEndpoint
294305
repositoryTarget := fmt.Sprintf("%srepositories/%s/images", indexEp, remote)
295306

296307
utils.Debugf("[registry] Calling GET %s", repositoryTarget)
@@ -364,7 +375,9 @@ func (r *Registry) PushImageChecksumRegistry(imgData *ImgData, registry string,
364375
if err != nil {
365376
return err
366377
}
367-
req.Header.Set("Authorization", "Token "+strings.Join(token, ","))
378+
if req.Header.Get("Authorization") == "" { // Don't override
379+
req.Header.Set("Authorization", "Token "+strings.Join(token, ","))
380+
}
368381
req.Header.Set("X-Docker-Checksum", imgData.Checksum)
369382

370383
res, err := doWithCookies(r.client, req)
@@ -401,7 +414,9 @@ func (r *Registry) PushImageJSONRegistry(imgData *ImgData, jsonRaw []byte, regis
401414
return err
402415
}
403416
req.Header.Add("Content-type", "application/json")
404-
req.Header.Set("Authorization", "Token "+strings.Join(token, ","))
417+
if req.Header.Get("Authorization") == "" { // Don't override
418+
req.Header.Set("Authorization", "Token "+strings.Join(token, ","))
419+
}
405420

406421
res, err := doWithCookies(r.client, req)
407422
if err != nil {
@@ -436,7 +451,9 @@ func (r *Registry) PushImageLayerRegistry(imgID string, layer io.Reader, registr
436451
}
437452
req.ContentLength = -1
438453
req.TransferEncoding = []string{"chunked"}
439-
req.Header.Set("Authorization", "Token "+strings.Join(token, ","))
454+
if req.Header.Get("Authorization") == "" { // Don't override
455+
req.Header.Set("Authorization", "Token "+strings.Join(token, ","))
456+
}
440457
res, err := doWithCookies(r.client, req)
441458
if err != nil {
442459
return "", fmt.Errorf("Failed to upload layer: %s", err)
@@ -465,7 +482,9 @@ func (r *Registry) PushRegistryTag(remote, revision, tag, registry string, token
465482
return err
466483
}
467484
req.Header.Add("Content-type", "application/json")
468-
req.Header.Set("Authorization", "Token "+strings.Join(token, ","))
485+
if req.Header.Get("Authorization") == "" { // Don't override
486+
req.Header.Set("Authorization", "Token "+strings.Join(token, ","))
487+
}
469488
req.ContentLength = int64(len(revision))
470489
res, err := doWithCookies(r.client, req)
471490
if err != nil {
@@ -478,8 +497,9 @@ func (r *Registry) PushRegistryTag(remote, revision, tag, registry string, token
478497
return nil
479498
}
480499

481-
func (r *Registry) PushImageJSONIndex(indexEp, remote string, imgList []*ImgData, validate bool, regs []string) (*RepositoryData, error) {
500+
func (r *Registry) PushImageJSONIndex(remote string, imgList []*ImgData, validate bool, regs []string) (*RepositoryData, error) {
482501
cleanImgList := []*ImgData{}
502+
indexEp := r.indexEndpoint
483503

484504
if validate {
485505
for _, elem := range imgList {
@@ -583,6 +603,7 @@ func (r *Registry) PushImageJSONIndex(indexEp, remote string, imgList []*ImgData
583603
}
584604

585605
func (r *Registry) SearchRepositories(term string) (*SearchResults, error) {
606+
utils.Debugf("Index server: %s", r.indexEndpoint)
586607
u := auth.IndexServerAddress() + "search?q=" + url.QueryEscape(term)
587608
req, err := r.reqFactory.NewRequest("GET", u, nil)
588609
if err != nil {
@@ -644,12 +665,13 @@ type ImgData struct {
644665
}
645666

646667
type Registry struct {
647-
client *http.Client
648-
authConfig *auth.AuthConfig
649-
reqFactory *utils.HTTPRequestFactory
668+
client *http.Client
669+
authConfig *auth.AuthConfig
670+
reqFactory *utils.HTTPRequestFactory
671+
indexEndpoint string
650672
}
651673

652-
func NewRegistry(root string, authConfig *auth.AuthConfig, factory *utils.HTTPRequestFactory) (r *Registry, err error) {
674+
func NewRegistry(authConfig *auth.AuthConfig, factory *utils.HTTPRequestFactory, indexEndpoint string) (r *Registry, err error) {
653675
httpTransport := &http.Transport{
654676
DisableKeepAlives: true,
655677
Proxy: http.ProxyFromEnvironment,
@@ -660,12 +682,22 @@ func NewRegistry(root string, authConfig *auth.AuthConfig, factory *utils.HTTPRe
660682
client: &http.Client{
661683
Transport: httpTransport,
662684
},
685+
indexEndpoint: indexEndpoint,
663686
}
664687
r.client.Jar, err = cookiejar.New(nil)
665688
if err != nil {
666689
return nil, err
667690
}
668691

692+
// If we're working with a private registry over HTTPS, send Basic Auth headers
693+
// alongside our requests.
694+
if indexEndpoint != auth.IndexServerAddress() && strings.HasPrefix(indexEndpoint, "https://") {
695+
utils.Debugf("Endpoint %s is eligible for private registry auth. Enabling decorator.", indexEndpoint)
696+
dec := utils.NewHTTPAuthDecorator(authConfig.Username, authConfig.Password)
697+
factory.AddDecorator(dec)
698+
}
699+
669700
r.reqFactory = factory
670701
return r, nil
671702
}
703+

registry/registry_test.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ var (
1515

1616
func spawnTestRegistry(t *testing.T) *Registry {
1717
authConfig := &auth.AuthConfig{}
18-
r, err := NewRegistry("", authConfig, utils.NewHTTPRequestFactory())
18+
r, err := NewRegistry(authConfig, utils.NewHTTPRequestFactory(), makeURL("/v1/"))
1919
if err != nil {
2020
t.Fatal(err)
2121
}
@@ -99,7 +99,7 @@ func TestGetRemoteTags(t *testing.T) {
9999

100100
func TestGetRepositoryData(t *testing.T) {
101101
r := spawnTestRegistry(t)
102-
data, err := r.GetRepositoryData(makeURL("/v1/"), "foo42/bar")
102+
data, err := r.GetRepositoryData("foo42/bar")
103103
if err != nil {
104104
t.Fatal(err)
105105
}
@@ -168,15 +168,14 @@ func TestPushImageJSONIndex(t *testing.T) {
168168
Checksum: "sha256:bea7bf2e4bacd479344b737328db47b18880d09096e6674165533aa994f5e9f2",
169169
},
170170
}
171-
ep := makeURL("/v1/")
172-
repoData, err := r.PushImageJSONIndex(ep, "foo42/bar", imgData, false, nil)
171+
repoData, err := r.PushImageJSONIndex("foo42/bar", imgData, false, nil)
173172
if err != nil {
174173
t.Fatal(err)
175174
}
176175
if repoData == nil {
177176
t.Fatal("Expected RepositoryData object")
178177
}
179-
repoData, err = r.PushImageJSONIndex(ep, "foo42/bar", imgData, true, []string{ep})
178+
repoData, err = r.PushImageJSONIndex("foo42/bar", imgData, true, []string{r.indexEndpoint})
180179
if err != nil {
181180
t.Fatal(err)
182181
}

server.go

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ func (srv *Server) recursiveLoad(address, tmpImageDir string) error {
425425
}
426426

427427
func (srv *Server) ImagesSearch(term string) ([]registry.SearchResult, error) {
428-
r, err := registry.NewRegistry(srv.runtime.config.Root, nil, srv.HTTPRequestFactory(nil))
428+
r, err := registry.NewRegistry(nil, srv.HTTPRequestFactory(nil), auth.IndexServerAddress())
429429
if err != nil {
430430
return nil, err
431431
}
@@ -816,10 +816,10 @@ func (srv *Server) pullImage(r *registry.Registry, out io.Writer, imgID, endpoin
816816
return nil
817817
}
818818

819-
func (srv *Server) pullRepository(r *registry.Registry, out io.Writer, localName, remoteName, askedTag, indexEp string, sf *utils.StreamFormatter, parallel bool) error {
819+
func (srv *Server) pullRepository(r *registry.Registry, out io.Writer, localName, remoteName, askedTag string, sf *utils.StreamFormatter, parallel bool) error {
820820
out.Write(sf.FormatStatus("", "Pulling repository %s", localName))
821821

822-
repoData, err := r.GetRepositoryData(indexEp, remoteName)
822+
repoData, err := r.GetRepositoryData(remoteName)
823823
if err != nil {
824824
return err
825825
}
@@ -989,11 +989,6 @@ func (srv *Server) poolRemove(kind, key string) error {
989989
}
990990

991991
func (srv *Server) ImagePull(localName string, tag string, out io.Writer, sf *utils.StreamFormatter, authConfig *auth.AuthConfig, metaHeaders map[string][]string, parallel bool) error {
992-
r, err := registry.NewRegistry(srv.runtime.config.Root, authConfig, srv.HTTPRequestFactory(metaHeaders))
993-
if err != nil {
994-
return err
995-
}
996-
997992
out = utils.NewWriteFlusher(out)
998993

999994
c, err := srv.poolAdd("pull", localName+":"+tag)
@@ -1014,12 +1009,17 @@ func (srv *Server) ImagePull(localName string, tag string, out io.Writer, sf *ut
10141009
return err
10151010
}
10161011

1012+
r, err := registry.NewRegistry(authConfig, srv.HTTPRequestFactory(metaHeaders), endpoint)
1013+
if err != nil {
1014+
return err
1015+
}
1016+
10171017
if endpoint == auth.IndexServerAddress() {
10181018
// If pull "index.docker.io/foo/bar", it's stored locally under "foo/bar"
10191019
localName = remoteName
10201020
}
10211021

1022-
if err = srv.pullRepository(r, out, localName, remoteName, tag, endpoint, sf, parallel); err != nil {
1022+
if err = srv.pullRepository(r, out, localName, remoteName, tag, sf, parallel); err != nil {
10231023
return err
10241024
}
10251025

@@ -1081,7 +1081,7 @@ func flatten(slc [][]*registry.ImgData) []*registry.ImgData {
10811081
return result
10821082
}
10831083

1084-
func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, localName, remoteName string, localRepo map[string]string, indexEp string, sf *utils.StreamFormatter) error {
1084+
func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, localName, remoteName string, localRepo map[string]string, sf *utils.StreamFormatter) error {
10851085
out = utils.NewWriteFlusher(out)
10861086
imgList, err := srv.getImageList(localRepo)
10871087
if err != nil {
@@ -1091,7 +1091,7 @@ func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, localName
10911091
out.Write(sf.FormatStatus("", "Sending image list"))
10921092

10931093
var repoData *registry.RepositoryData
1094-
repoData, err = r.PushImageJSONIndex(indexEp, remoteName, flattenedImgList, false, nil)
1094+
repoData, err = r.PushImageJSONIndex(remoteName, flattenedImgList, false, nil)
10951095
if err != nil {
10961096
return err
10971097
}
@@ -1137,7 +1137,7 @@ func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, localName
11371137
}
11381138
}
11391139

1140-
if _, err := r.PushImageJSONIndex(indexEp, remoteName, flattenedImgList, true, repoData.Endpoints); err != nil {
1140+
if _, err := r.PushImageJSONIndex(remoteName, flattenedImgList, true, repoData.Endpoints); err != nil {
11411141
return err
11421142
}
11431143

@@ -1203,7 +1203,7 @@ func (srv *Server) ImagePush(localName string, out io.Writer, sf *utils.StreamFo
12031203

12041204
out = utils.NewWriteFlusher(out)
12051205
img, err := srv.runtime.graph.Get(localName)
1206-
r, err2 := registry.NewRegistry(srv.runtime.config.Root, authConfig, srv.HTTPRequestFactory(metaHeaders))
1206+
r, err2 := registry.NewRegistry(authConfig, srv.HTTPRequestFactory(metaHeaders), endpoint)
12071207
if err2 != nil {
12081208
return err2
12091209
}
@@ -1213,7 +1213,7 @@ func (srv *Server) ImagePush(localName string, out io.Writer, sf *utils.StreamFo
12131213
out.Write(sf.FormatStatus("", "The push refers to a repository [%s] (len: %d)", localName, reposLen))
12141214
// If it fails, try to get the repository
12151215
if localRepo, exists := srv.runtime.repositories.Repositories[localName]; exists {
1216-
if err := srv.pushRepository(r, out, localName, remoteName, localRepo, endpoint, sf); err != nil {
1216+
if err := srv.pushRepository(r, out, localName, remoteName, localRepo, sf); err != nil {
12171217
return err
12181218
}
12191219
return nil
@@ -1852,7 +1852,6 @@ func NewServer(eng *engine.Engine, config *DaemonConfig) (*Server, error) {
18521852
pushingPool: make(map[string]chan struct{}),
18531853
events: make([]utils.JSONMessage, 0, 64), //only keeps the 64 last events
18541854
listeners: make(map[string]chan utils.JSONMessage),
1855-
reqFactory: nil,
18561855
}
18571856
runtime.srv = srv
18581857
return srv, nil
@@ -1861,15 +1860,12 @@ func NewServer(eng *engine.Engine, config *DaemonConfig) (*Server, error) {
18611860
func (srv *Server) HTTPRequestFactory(metaHeaders map[string][]string) *utils.HTTPRequestFactory {
18621861
srv.Lock()
18631862
defer srv.Unlock()
1864-
if srv.reqFactory == nil {
1865-
ud := utils.NewHTTPUserAgentDecorator(srv.versionInfos()...)
1866-
md := &utils.HTTPMetaHeadersDecorator{
1867-
Headers: metaHeaders,
1868-
}
1869-
factory := utils.NewHTTPRequestFactory(ud, md)
1870-
srv.reqFactory = factory
1863+
ud := utils.NewHTTPUserAgentDecorator(srv.versionInfos()...)
1864+
md := &utils.HTTPMetaHeadersDecorator{
1865+
Headers: metaHeaders,
18711866
}
1872-
return srv.reqFactory
1867+
factory := utils.NewHTTPRequestFactory(ud, md)
1868+
return factory
18731869
}
18741870

18751871
func (srv *Server) LogEvent(action, id, from string) *utils.JSONMessage {
@@ -1904,6 +1900,5 @@ type Server struct {
19041900
pushingPool map[string]chan struct{}
19051901
events []utils.JSONMessage
19061902
listeners map[string]chan utils.JSONMessage
1907-
reqFactory *utils.HTTPRequestFactory
19081903
Eng *engine.Engine
19091904
}

0 commit comments

Comments
 (0)