// PullImage pulls a image from registry
PullImage pulls a image from registry
// PullImage pulls a image from registry
func (c *Client) PullImage(image, tag string, auth *types.AuthConfig, out io.Writer) error {
	ctx, cancel := getContextWithCancel()
	defer cancel()
	request := types.ImagePullRequest{
		Image: image,
		Tag:   tag,
		Auth:  auth,
	}
	stream, err := c.client.ImagePull(ctx, &request)
	if err != nil {
		return err
	}
	errC := make(chan error)
	progressC := make(chan struct{})
	ticker := time.NewTicker(defaultImagePullingStuckTimeout)
	defer ticker.Stop()
	go func() {
		for {
			res, err := stream.Recv()
			if err == io.EOF {
				errC <- nil
				return
			}
			if err != nil {
				errC <- err
				return
			}
			progressC <- struct{}{}
			if out != nil {
				n, err := out.Write(res.Data)
				if err != nil {
					errC <- err
					return
				}
				if n != len(res.Data) {
					errC <- io.ErrShortWrite
					return
				}
			}
		}
	}()
	for {
		select {
		case <-ticker.C:
			return fmt.Errorf("Cancel pulling image %q because of no progress for %v", image, defaultImagePullingStuckTimeout)
		case err = <-errC:
			return err
		case <-progressC:
			ticker.Stop()
			ticker = time.NewTicker(defaultImagePullingStuckTimeout)
		}
	}
}
func ( c * Client ) PullImage ( image , tag string , auth * types . AuthConfig , out io . Writer ) error { ctx , cancel := getContextWithCancel ( ) defer cancel ( ) request := types . ImagePullRequest { Image : image , Tag : tag , Auth : auth , } stream , err := c . client . ImagePull ( ctx , & request ) if err != nil { return err } errC := make ( chan error ) progressC := make ( chan struct { } ) ticker := time . NewTicker ( defaultImagePullingStuckTimeout ) defer ticker . Stop ( ) go func ( ) { for { res , err := stream . Recv ( ) if err == io . EOF { errC <- nil return } if err != nil { errC <- err return } progressC <- struct { } { } if out != nil { n , err := out . Write ( res . Data ) if err != nil { errC <- err return } if n != len ( res . Data ) { errC <- io . ErrShortWrite return } } } } ( ) for { select { case <- ticker . C : return fmt . Errorf ( " " , image , defaultImagePullingStuckTimeout ) case err = <- errC : return err case <- progressC : ticker . Stop ( ) ticker = time . NewTicker ( defaultImagePullingStuckTimeout ) } } }
PullImage pulls a image from registry
PullImage pulls a image from registry
// pulling image timeout, cancel it // if nil, got EOF, session finished // else return err // got progress from pulling image, reset the clock