mirror of
https://github.com/clearlinux/docker.git
synced 2026-10-04 07:48:44 +00:00
Add daemon flag to specify public registry mirrors
Adds support for a --registry-mirror=scheme://<host>[:port] daemon flag. The flag may be present multiple times. If provided, mirrors are prepended to the list of endpoints used for image pull. Note that only mirrors of the public index.docker.io registry are supported, and image/tag resolution is still performed via the official index. Docker-DCO-1.1-Signed-off-by: Tim Smith <timbot@google.com> (github: timbot)
This commit is contained in:
+30
-12
@@ -25,6 +25,7 @@ func (s *TagStore) CmdPull(job *engine.Job) engine.Status {
|
||||
sf = utils.NewStreamFormatter(job.GetenvBool("json"))
|
||||
authConfig = ®istry.AuthConfig{}
|
||||
metaHeaders map[string][]string
|
||||
mirrors []string
|
||||
)
|
||||
if len(job.Args) > 1 {
|
||||
tag = job.Args[1]
|
||||
@@ -64,16 +65,19 @@ func (s *TagStore) CmdPull(job *engine.Job) engine.Status {
|
||||
if endpoint == registry.IndexServerAddress() {
|
||||
// If pull "index.docker.io/foo/bar", it's stored locally under "foo/bar"
|
||||
localName = remoteName
|
||||
|
||||
// Use provided mirrors, if any
|
||||
mirrors = s.mirrors
|
||||
}
|
||||
|
||||
if err = s.pullRepository(r, job.Stdout, localName, remoteName, tag, sf, job.GetenvBool("parallel")); err != nil {
|
||||
if err = s.pullRepository(r, job.Stdout, localName, remoteName, tag, sf, job.GetenvBool("parallel"), mirrors); err != nil {
|
||||
return job.Error(err)
|
||||
}
|
||||
|
||||
return engine.StatusOK
|
||||
}
|
||||
|
||||
func (s *TagStore) pullRepository(r *registry.Session, out io.Writer, localName, remoteName, askedTag string, sf *utils.StreamFormatter, parallel bool) error {
|
||||
func (s *TagStore) pullRepository(r *registry.Session, out io.Writer, localName, remoteName, askedTag string, sf *utils.StreamFormatter, parallel bool, mirrors []string) error {
|
||||
out.Write(sf.FormatStatus("", "Pulling repository %s", localName))
|
||||
|
||||
repoData, err := r.GetRepositoryData(remoteName)
|
||||
@@ -153,17 +157,31 @@ func (s *TagStore) pullRepository(r *registry.Session, out io.Writer, localName,
|
||||
out.Write(sf.FormatProgress(utils.TruncateID(img.ID), fmt.Sprintf("Pulling image (%s) from %s", img.Tag, localName), nil))
|
||||
success := false
|
||||
var lastErr error
|
||||
for _, ep := range repoData.Endpoints {
|
||||
out.Write(sf.FormatProgress(utils.TruncateID(img.ID), fmt.Sprintf("Pulling image (%s) from %s, endpoint: %s", img.Tag, localName, ep), nil))
|
||||
if err := s.pullImage(r, out, img.ID, ep, repoData.Tokens, sf); err != nil {
|
||||
// It's not ideal that only the last error is returned, it would be better to concatenate the errors.
|
||||
// As the error is also given to the output stream the user will see the error.
|
||||
lastErr = err
|
||||
out.Write(sf.FormatProgress(utils.TruncateID(img.ID), fmt.Sprintf("Error pulling image (%s) from %s, endpoint: %s, %s", img.Tag, localName, ep, err), nil))
|
||||
continue
|
||||
if mirrors != nil {
|
||||
for _, ep := range mirrors {
|
||||
out.Write(sf.FormatProgress(utils.TruncateID(img.ID), fmt.Sprintf("Pulling image (%s) from %s, mirror: %s", img.Tag, localName, ep), nil))
|
||||
if err := s.pullImage(r, out, img.ID, ep, repoData.Tokens, sf); err != nil {
|
||||
// Don't report errors when pulling from mirrors.
|
||||
log.Debugf("Error pulling image (%s) from %s, mirror: %s, %s", img.Tag, localName, ep, err)
|
||||
continue
|
||||
}
|
||||
success = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !success {
|
||||
for _, ep := range repoData.Endpoints {
|
||||
out.Write(sf.FormatProgress(utils.TruncateID(img.ID), fmt.Sprintf("Pulling image (%s) from %s, endpoint: %s", img.Tag, localName, ep), nil))
|
||||
if err := s.pullImage(r, out, img.ID, ep, repoData.Tokens, sf); err != nil {
|
||||
// It's not ideal that only the last error is returned, it would be better to concatenate the errors.
|
||||
// As the error is also given to the output stream the user will see the error.
|
||||
lastErr = err
|
||||
out.Write(sf.FormatProgress(utils.TruncateID(img.ID), fmt.Sprintf("Error pulling image (%s) from %s, endpoint: %s, %s", img.Tag, localName, ep, err), nil))
|
||||
continue
|
||||
}
|
||||
success = true
|
||||
break
|
||||
}
|
||||
success = true
|
||||
break
|
||||
}
|
||||
if !success {
|
||||
err := fmt.Errorf("Error pulling image (%s) from %s, %v", img.Tag, localName, lastErr)
|
||||
|
||||
+3
-1
@@ -20,6 +20,7 @@ const DEFAULTTAG = "latest"
|
||||
type TagStore struct {
|
||||
path string
|
||||
graph *Graph
|
||||
mirrors []string
|
||||
Repositories map[string]Repository
|
||||
sync.Mutex
|
||||
// FIXME: move push/pull-related fields
|
||||
@@ -48,7 +49,7 @@ func (r Repository) Contains(u Repository) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func NewTagStore(path string, graph *Graph) (*TagStore, error) {
|
||||
func NewTagStore(path string, graph *Graph, mirrors []string) (*TagStore, error) {
|
||||
abspath, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -56,6 +57,7 @@ func NewTagStore(path string, graph *Graph) (*TagStore, error) {
|
||||
store := &TagStore{
|
||||
path: abspath,
|
||||
graph: graph,
|
||||
mirrors: mirrors,
|
||||
Repositories: make(map[string]Repository),
|
||||
pullingPool: make(map[string]chan struct{}),
|
||||
pushingPool: make(map[string]chan struct{}),
|
||||
|
||||
@@ -52,7 +52,7 @@ func mkTestTagStore(root string, t *testing.T) *TagStore {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
store, err := NewTagStore(path.Join(root, "tags"), graph)
|
||||
store, err := NewTagStore(path.Join(root, "tags"), graph, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user