github.com/portworx/docker@v1.12.1/daemon/image_pull.go (about) 1 package daemon 2 3 import ( 4 "io" 5 "strings" 6 7 "github.com/docker/distribution/digest" 8 "github.com/docker/docker/builder" 9 "github.com/docker/docker/distribution" 10 "github.com/docker/docker/pkg/progress" 11 "github.com/docker/docker/reference" 12 "github.com/docker/docker/registry" 13 "github.com/docker/engine-api/types" 14 "golang.org/x/net/context" 15 ) 16 17 // PullImage initiates a pull operation. image is the repository name to pull, and 18 // tag may be either empty, or indicate a specific tag to pull. 19 func (daemon *Daemon) PullImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error { 20 // Special case: "pull -a" may send an image name with a 21 // trailing :. This is ugly, but let's not break API 22 // compatibility. 23 image = strings.TrimSuffix(image, ":") 24 25 ref, err := reference.ParseNamed(image) 26 if err != nil { 27 return err 28 } 29 30 if tag != "" { 31 // The "tag" could actually be a digest. 32 var dgst digest.Digest 33 dgst, err = digest.ParseDigest(tag) 34 if err == nil { 35 ref, err = reference.WithDigest(ref, dgst) 36 } else { 37 ref, err = reference.WithTag(ref, tag) 38 } 39 if err != nil { 40 return err 41 } 42 } 43 44 return daemon.pullImageWithReference(ctx, ref, metaHeaders, authConfig, outStream) 45 } 46 47 // PullOnBuild tells Docker to pull image referenced by `name`. 48 func (daemon *Daemon) PullOnBuild(ctx context.Context, name string, authConfigs map[string]types.AuthConfig, output io.Writer) (builder.Image, error) { 49 ref, err := reference.ParseNamed(name) 50 if err != nil { 51 return nil, err 52 } 53 ref = reference.WithDefaultTag(ref) 54 55 pullRegistryAuth := &types.AuthConfig{} 56 if len(authConfigs) > 0 { 57 // The request came with a full auth config file, we prefer to use that 58 repoInfo, err := daemon.RegistryService.ResolveRepository(ref) 59 if err != nil { 60 return nil, err 61 } 62 63 resolvedConfig := registry.ResolveAuthConfig( 64 authConfigs, 65 repoInfo.Index, 66 ) 67 pullRegistryAuth = &resolvedConfig 68 } 69 70 if err := daemon.pullImageWithReference(ctx, ref, nil, pullRegistryAuth, output); err != nil { 71 return nil, err 72 } 73 return daemon.GetImage(name) 74 } 75 76 func (daemon *Daemon) pullImageWithReference(ctx context.Context, ref reference.Named, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error { 77 // Include a buffer so that slow client connections don't affect 78 // transfer performance. 79 progressChan := make(chan progress.Progress, 100) 80 81 writesDone := make(chan struct{}) 82 83 ctx, cancelFunc := context.WithCancel(ctx) 84 85 go func() { 86 writeDistributionProgress(cancelFunc, outStream, progressChan) 87 close(writesDone) 88 }() 89 90 imagePullConfig := &distribution.ImagePullConfig{ 91 MetaHeaders: metaHeaders, 92 AuthConfig: authConfig, 93 ProgressOutput: progress.ChanOutput(progressChan), 94 RegistryService: daemon.RegistryService, 95 ImageEventLogger: daemon.LogImageEvent, 96 MetadataStore: daemon.distributionMetadataStore, 97 ImageStore: daemon.imageStore, 98 ReferenceStore: daemon.referenceStore, 99 DownloadManager: daemon.downloadManager, 100 } 101 102 err := distribution.Pull(ctx, ref, imagePullConfig) 103 close(progressChan) 104 <-writesDone 105 return err 106 }