github.com/kim0/docker@v0.6.2-0.20161130212042-4addda3f07e7/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/api/types"
     9  	"github.com/docker/docker/builder"
    10  	"github.com/docker/docker/distribution"
    11  	"github.com/docker/docker/pkg/progress"
    12  	"github.com/docker/docker/reference"
    13  	"github.com/docker/docker/registry"
    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  }