// PullImage waits for an image to be available on the docker registry so it
// can be pulled (if it does not exist locally).
13907
func (l *RegistryListener) PullImage(cancel <-chan time.Time, image string) error {
	imageID, err := commons.ParseImageID(image)
	if err != nil {
		return err
	}
	rImage := &registry.Image{
		Library: imageID.User,
		Repo:    imageID.Repo,
		Tag:     imageID.Tag,
	}
	if imageID.IsLatest() {
		rImage.Tag = docker.Latest
	}
	idpath := path.Join(zkregistrytags, rImage.ID())
	regaddr := path.Join(l.address, rImage.String())

	done := make(chan struct{})
	defer func(channel *chan struct{}) { close(*channel) }(&done)
	for {
		var node RegistryImageNode
		evt, err := l.conn.GetW(idpath, &node, done)
		if err != nil {
			if err == client.ErrNoNode {
				glog.Errorf("Image %s not found", regaddr)
			}
			return err
		}
		// check if the image exists locally
		glog.Infof("Looking up image %s", regaddr)
		if err := l.docker.TagImage(node.Image.UUID, regaddr); docker.IsImageNotFound(err) {
			// cannot find the image, so let's try to pull
			glog.Infof("Pulling image %s from the docker registry", regaddr)
			if err := l.docker.PullImage(regaddr); err != nil && !docker.IsImageNotFound(err) {
				glog.Errorf("Could not pull %s: %s", regaddr, err)
				return err
			}
			// was the pull successful?
			if err := l.docker.TagImage(node.Image.UUID, regaddr); docker.IsImageNotFound(err) {
				glog.Infof("Image %s not found by ID (%s), comparing hashes", regaddr, node.Image.UUID)
				//IDs may not match, so lets compare hashes
				if localHash, err := l.docker.GetImageHash(regaddr); err != nil {
					glog.Warningf("Error building hash of image: %s: %s", regaddr, err)
				} else {
					glog.V(2).Infof("For image %s, comparing local hash (%s) to master's hash (%s)", regaddr, localHash, node.Image.Hash)
					if localHash == node.Image.Hash {
						//if the match, the image we have is current, just return
						return nil
					}
				}

				if node.PushedAt.Unix() > 0 {
					// the image is definitely not in the registry, so lets
					// get that push started.
					// also, more than one client may try to update this node
					// at the same time, so there might be a version conflict
					// error; let's just ignore those here.
					node.PushedAt = time.Unix(0, 0)
					if err := l.conn.Set(idpath, &node); err != nil && err != client.ErrBadVersion {
						glog.Errorf("Image %s not found in the docker registry: %s", regaddr, err)
						return err
					}
				}
			} else if err != nil {
				glog.Errorf("Could not update tag %s for image %s: %s", regaddr, node.Image.UUID, err)
				return err
			} else {
				return nil
			}
		} else if err != nil {
			glog.Errorf("Could not update tag %s for image %s: %s", regaddr, node.Image.UUID, err)
			return err
		} else {
			return nil
		}
		glog.Infof("Waiting for image %s to be uploaded into the docker registry (idpath=%s)", regaddr, idpath)
		select {
		case e := <-evt:
			glog.Infof("Got an event: %s", e)
		case <-cancel:
			return ErrOpTimeout
		}

		close(done)
		done = make(chan struct{})
	}
}
591181
func (i *ImageService) GetImage(refOrID string) (*image.Image, error) {
	ref, err := reference.ParseAnyReference(refOrID)
	if err != nil {
		return nil, errdefs.InvalidParameter(err)
	}
	namedRef, ok := ref.(reference.Named)
	if !ok {
		digested, ok := ref.(reference.Digested)
		if !ok {
			return nil, ErrImageDoesNotExist{ref}
		}
		id := image.IDFromDigest(digested.Digest())
		if img, err := i.imageStore.Get(id); err == nil {
			return img, nil
		}
		return nil, ErrImageDoesNotExist{ref}
	}

	if digest, err := i.referenceStore.Get(namedRef); err == nil {
		// Search the image stores to get the operating system, defaulting to host OS.
		id := image.IDFromDigest(digest)
		if img, err := i.imageStore.Get(id); err == nil {
			return img, nil
		}
	}

	// Search based on ID
	if id, err := i.imageStore.Search(refOrID); err == nil {
		img, err := i.imageStore.Get(id)
		if err != nil {
			return nil, ErrImageDoesNotExist{ref}
		}
		return img, nil
	}

	return nil, ErrImageDoesNotExist{ref}
}
184143
func PullImage(name string, d Docker, policy api.PullPolicy) (*PullResult, error) {
	if len(policy) == 0 {
		return nil, errors.New("the policy for pull image must be set")
	}

	var (
		image *api.Image
		err   error
	)
	switch policy {
	case api.PullIfNotPresent:
		image, err = d.CheckAndPullImage(name)
	case api.PullAlways:
		glog.Infof("Pulling image %q ...", name)
		image, err = d.PullImage(name)
	case api.PullNever:
		glog.Infof("Checking if image %q is available locally ...", name)
		image, err = d.CheckImage(name)
	}
	return &PullResult{Image: image, OnBuild: d.IsImageOnBuild(name)}, err
}
169368
func (c *CloudAPI) GetImage(imageID string) (*cloudapi.Image, error) {
	if err := c.ProcessFunctionHook(c, imageID); err != nil {
		return nil, err
	}

	for _, image := range c.images {
		if image.Id == imageID {
			return &image, nil
		}
	}

	return nil, fmt.Errorf("Image %s not found", imageID)
}
1018550
func (d *stiDocker) PullImage(name string) (*api.Image, error) {
	name = getImageName(name)

	// RegistryAuth is the base64 encoded credentials for the registry
	base64Auth, err := base64EncodeAuth(d.pullAuth)
	if err != nil {
		return nil, s2ierr.NewPullImageError(name, err)
	}
	var retriableError = false

	for retries := 0; retries <= DefaultPullRetryCount; retries++ {
		err = util.TimeoutAfter(DefaultDockerTimeout, fmt.Sprintf("pulling image %q", name), func(timer *time.Timer) error {
			resp, pullErr := d.client.ImagePull(context.Background(), name, dockertypes.ImagePullOptions{RegistryAuth: base64Auth})
			if pullErr != nil {
				return pullErr
			}
			defer resp.Close()

			decoder := json.NewDecoder(resp)
			for {
				if !timer.Stop() {
					return &util.TimeoutError{}
				}
				timer.Reset(DefaultDockerTimeout)

				var msg dockermessage.JSONMessage
				pullErr = decoder.Decode(&msg)
				if pullErr == io.EOF {
					return nil
				}
				if pullErr != nil {
					return pullErr
				}

				if msg.Error != nil {
					return msg.Error
				}
				if msg.Progress != nil {
					glog.V(4).Infof("pulling image %s: %s", name, msg.Progress.String())
				}
			}
		})
		if err == nil {
			break
		}
		glog.V(0).Infof("pulling image error : %v", err)
		errMsg := fmt.Sprintf("%s", err)
		for _, errorString := range RetriableErrors {
			if strings.Contains(errMsg, errorString) {
				retriableError = true
				break
			}
		}

		if !retriableError {
			return nil, s2ierr.NewPullImageError(name, err)
		}

		glog.V(0).Infof("retrying in %s ...", DefaultPullRetryDelay)
		time.Sleep(DefaultPullRetryDelay)
	}

	inspectResp, err := d.InspectImage(name)
	if err != nil {
		return nil, s2ierr.NewPullImageError(name, err)
	}
	if inspectResp != nil {
		image := &api.Image{}
		updateImageWithInspect(image, inspectResp)
		return image, nil
	}
	return nil, nil
}
1000754
func (s *Server) PullImage(ctx context.Context, req *pb.PullImageRequest) (resp *pb.PullImageResponse, err error) {
	const operation = "pull_image"
	defer func() {
		recordOperation(operation, time.Now())
		recordError(operation, err)
	}()

	logrus.Debugf("PullImageRequest: %+v", req)
	// TODO: what else do we need here? (Signatures when the story isn't just pulling from docker://)
	image := ""
	img := req.GetImage()
	if img != nil {
		image = img.Image
	}

	var (
		images []string
		pulled string
	)
	images, err = s.StorageImageServer().ResolveNames(image)
	if err != nil {
		return nil, err
	}
	for _, img := range images {
		var (
			username string
			password string
		)
		if req.GetAuth() != nil {
			username = req.GetAuth().Username
			password = req.GetAuth().Password
			if req.GetAuth().Auth != "" {
				username, password, err = decodeDockerAuth(req.GetAuth().Auth)
				if err != nil {
					logrus.Debugf("error decoding authentication for image %s: %v", img, err)
					continue
				}
			}
		}
		options := &copy.Options{
			SourceCtx: &types.SystemContext{
				DockerRegistryUserAgent: useragent.Get(ctx),
				SignaturePolicyPath:     s.ImageContext().SignaturePolicyPath,
			},
		}

		// Specifying a username indicates the user intends to send authentication to the registry.
		if username != "" {
			options.SourceCtx = &types.SystemContext{
				DockerAuthConfig: &types.DockerAuthConfig{
					Username: username,
					Password: password,
				},
			}
		}

		var tmpImg types.Image
		tmpImg, err = s.StorageImageServer().PrepareImage(img, options)
		if err != nil {
			logrus.Debugf("error preparing image %s: %v", img, err)
			continue
		}

		var storedImage *storage.ImageResult
		storedImage, err = s.StorageImageServer().ImageStatus(s.ImageContext(), img)
		if err == nil {
			tmpImgConfigDigest := tmpImg.ConfigInfo().Digest
			if tmpImgConfigDigest.String() == "" {
				// this means we are playing with a schema1 image, in which
				// case, we're going to repull the image in any case
				logrus.Debugf("image config digest is empty, re-pulling image")
			} else if tmpImgConfigDigest.String() == storedImage.ConfigDigest.String() {
				logrus.Debugf("image %s already in store, skipping pull", img)
				pulled = img
				break
			}
			logrus.Debugf("image in store has different ID, re-pulling %s", img)
		}

		_, err = s.StorageImageServer().PullImage(s.ImageContext(), img, options)
		if err != nil {
			logrus.Debugf("error pulling image %s: %v", img, err)
			continue
		}
		pulled = img
		break
	}
	if pulled == "" && err != nil {
		return nil, err
	}
	status, err := s.StorageImageServer().ImageStatus(s.ImageContext(), pulled)
	if err != nil {
		return nil, err
	}
	imageRef := status.ID
	if len(status.RepoDigests) > 0 {
		imageRef = status.RepoDigests[0]
	}
	resp = &pb.PullImageResponse{
		ImageRef: imageRef,
	}
	logrus.Debugf("PullImageResponse: %+v", resp)
	return resp, nil
}
921738
func ImportImage(repotag, filename string) error {
	dc, err := getDockerClient()
	if err != nil {
		return err
	}
	glog.V(1).Infof("importing image %s from %s", repotag, filename)
	f, err := os.Open(filename)
	if err != nil {
		return err
	}
	defer f.Close()

	iid, err := commons.ParseImageID(repotag)
	if err != nil {
		return err
	}

	opts := dockerclient.ImportImageOptions{
		Repository:  iid.BaseName(),
		Source:      "-",
		InputStream: f,
		Tag:         iid.Tag,
	}

	if err = dc.ImportImage(opts); err != nil {
		glog.V(1).Infof("unable to import %s: %v", repotag, err)
		return err
	}
	return err
}
1324706
func (c *Cluster) PullImage(opts docker.PullImageOptions, auth docker.AuthConfiguration, nodes ...string) error {
	var w safe.Buffer
	if opts.OutputStream != nil {
		mw := io.MultiWriter(&w, opts.OutputStream)
		opts.OutputStream = mw
	} else {
		opts.OutputStream = &w
	}
	key := imageKey(opts.Repository, opts.Tag)
	_, err := c.runOnNodes(func(n node) (interface{}, error) {
		n.setPersistentClient()
		err := n.PullImage(opts, auth)
		if err != nil {
			return nil, err
		}
		img, err := n.InspectImage(key)
		if err != nil {
			return nil, err
		}
		return nil, c.storage().StoreImage(key, img.ID, n.addr)
	}, docker.ErrNoSuchImage, true, nodes...)
	if err != nil {
		return err
	}
	digest, _ := fix.GetImageDigest(w.String())
	return c.storage().SetImageDigest(key, digest)
}
255635
func (client *Client) CopyImage(args *CopyImageArgs) (string, error) {
	response := &CopyImageResponse{}
	err := client.Invoke("CopyImage", args, &response)
	if err != nil {
		return "", err
	}
	return response.ImageId, nil
}
335083
func (d *dockerAPI) tagImage(imageID string, ref string) error {
	glog.V(4).Infof("docker tag for image %q, tag %q", imageID, ref)

	ctx := context.Background()
	options := types.ImageTagOptions{}
	err := d.client.ImageTag(ctx, imageID, ref, options)
	if err != nil {
		return fmt.Errorf("error tagging image %q with tag %q: %v", imageID, ref, err)
	}
	return nil
}
1114303
func (d *Docker) RunImage(ctx context.Context, config *dockerclient.Config,
	hostCfg *dockerclient.HostConfig, takeFiles []string) <-chan ContainerResponse {

	// TODO (m0sth8): rewrite this, please
	ch := make(chan ContainerResponse, 2)
	go func(ch chan<- ContainerResponse, config *dockerclient.Config, hostCfg *dockerclient.HostConfig) {
		resp := ContainerResponse{}
		// pull container
		if err := d.PullImage(config.Image); err != nil {
			logrus.Errorf("Failed: %v", err)
			resp.Err = err
			ch <- resp
			return
		}
		// Create a container
		logrus.Infof("Create container %s: %v", config.Image, config.Cmd)
		opts := dockerclient.CreateContainerOptions{
			Config:     config,
			HostConfig: hostCfg,
		}
		container, err := d.Client.CreateContainer(opts)
		if err != nil {
			logrus.Errorf("Failed: %v", err)
			resp.Err = err
			ch <- resp
			return
		}

		cprint := func(format string, opt ...interface{}) {
			logrus.Infof("[%s] %s", container.ID[:6], fmt.Sprintf(format, opt...))
		}
		cprint("Created")

		removeContainer := func() {
			cprint("Remove container")
			d.Client.RemoveContainer(dockerclient.RemoveContainerOptions{
				ID: container.ID,
			})
			cprint("Removed")
		}

		defer removeContainer()

		// Start the container
		err = d.Client.StartContainer(container.ID, opts.HostConfig)
		if err != nil {
			resp.Err = stackerr.Wrap(err)
			ch <- resp
			return
		}
		cprint("Started")

		stopContainer := func() {
			cprint("Stop container")
			d.Client.StopContainer(container.ID, 2)
			cprint("Stopped")
		}
		defer stopContainer()
		container, err = d.Client.InspectContainer(container.ID)
		if err != nil {
			logrus.Errorf("Failed: %v", err)
			resp.Err = err
			ch <- resp
			return
		}

		resp.Container = container
		ch <- resp

		respCh := make(chan ContainerResponse, 1)
		go func(respCh chan<- ContainerResponse) {
			resp := ContainerResponse{}
			cprint("Waiting for log")
			stdout := bytes.NewBuffer(nil)
			stderr := bytes.NewBuffer(nil)
			err := d.Client.Logs(dockerclient.LogsOptions{
				OutputStream: stdout,
				ErrorStream:  stderr,
				Container:    container.ID,
				Follow:       true,
				Stdout:       true,
				Stderr:       true,
				RawTerminal:  true,
			})
			if err != nil {
				resp.Err = stackerr.Wrap(err)
				respCh <- resp
				return
			}
			serr := stderr.Bytes()
			sout := stdout.Bytes()
			if serr != nil {
				cprint("STDERR: %s", string(serr))
			}
			if sout != nil {
				cprint("STDOUT: %s", string(sout))
			}
			resp.Log = sout
			respCh <- resp
		}(respCh)
		select {
		case <-ctx.Done():
			cprint("Context done, stop and remove container")
			resp.Err = ctx.Err()
			stopContainer()
			removeContainer()
		case tmpResp := <-respCh:
			resp.Err = tmpResp.Err
			resp.Log = tmpResp.Log
		}
		if resp.Err == nil && takeFiles != nil && len(takeFiles) > 0 {
			files := map[string]io.Reader{}
			for _, fPath := range takeFiles {
				cprint("take file %s from container", fPath)
				// try to copy files from container
				buf := new(bytes.Buffer)
				err := d.Client.CopyFromContainer(dockerclient.CopyFromContainerOptions{
					Container:    container.ID,
					Resource:     fPath,
					OutputStream: buf,
				})
				if err != nil {
					logrus.Error(stackerr.Wrap(err))
					continue
				}
				tr := tar.NewReader(buf)
				// Iterate through the files in the archive.
				fName := path.Base(fPath)
				for {
					hdr, err := tr.Next()
					if err == io.EOF {
						// end of tar archive
						break
					}
					if err != nil {
						logrus.Error(stackerr.Wrap(err))
						break
					}
					if hdr.Typeflag != tar.TypeReg {
						continue
					}
					if hdr.Name != fName {
						continue
					}
					fBuf := new(bytes.Buffer)
					_, err = io.Copy(fBuf, tr)
					if err != nil {
						logrus.Error(stackerr.Wrap(err))
						break
					}
					files[fPath] = fBuf
				}
			}
			if len(files) > 0 {
				resp.Files = files
			}
		}

		ch <- resp
		return

	}(ch, config, hostCfg)
	return ch
}
1221751
func (f *RemoteRuntime) RemoveImage(ctx context.Context, req *kubeapi.RemoveImageRequest) (*kubeapi.RemoveImageResponse, error) {
	err := f.ImageService.RemoveImage(req.Image)
	if err != nil {
		return nil, err
	}

	return &kubeapi.RemoveImageResponse{}, nil
}
85143
func PullImage(ctx context.Context, client client.ImageAPIClient, serviceName string, authLookup auth.Lookup, image string) error {
	fmt.Fprintf(os.Stderr, "Pulling %s (%s)...\n", serviceName, image)
	distributionRef, err := reference.ParseNormalizedNamed(image)
	if err != nil {
		return err
	}

	repoInfo, err := registry.ParseRepositoryInfo(distributionRef)
	if err != nil {
		return err
	}

	authConfig := authLookup.Lookup(repoInfo)

	// Use ConfigFile.SaveToWriter to not re-define encodeAuthToBase64
	encodedAuth, err := encodeAuthToBase64(authConfig)
	if err != nil {
		return err
	}

	options := types.ImagePullOptions{
		RegistryAuth: encodedAuth,
	}
	responseBody, err := client.ImagePull(ctx, distributionRef.String(), options)
	if err != nil {
		logrus.Errorf("Failed to pull image %s: %v", image, err)
		return err
	}
	defer responseBody.Close()

	var writeBuff io.Writer = os.Stderr

	outFd, isTerminalOut := term.GetFdInfo(os.Stderr)

	err = jsonmessage.DisplayJSONMessagesStream(responseBody, writeBuff, outFd, isTerminalOut, nil)
	if err != nil {
		if jerr, ok := err.(*jsonmessage.JSONError); ok {
			// If no error code is set, default to 1
			if jerr.Code == 0 {
				jerr.Code = 1
			}
			fmt.Fprintf(os.Stderr, "%s", writeBuff)
			return fmt.Errorf("Status: %s, Code: %d", jerr.Message, jerr.Code)
		}
	}
	return err
}
215399
func (s *Service) Pull(ctx context.Context) error {
	if s.Config().Image == "" {
		return nil
	}

	return image.PullImage(ctx, s.clientFactory.Create(s), s.name, s.authLookup, s.Config().Image)
}
129903
func (d *stiDocker) BuildImage(opts BuildImageOptions) error {
	dockerOpts := dockertypes.ImageBuildOptions{
		Tags:           []string{opts.Name},
		NoCache:        true,
		SuppressOutput: false,
		Remove:         true,
		ForceRemove:    true,
	}
	if opts.CGroupLimits != nil {
		dockerOpts.Memory = opts.CGroupLimits.MemoryLimitBytes
		dockerOpts.MemorySwap = opts.CGroupLimits.MemorySwap
		dockerOpts.CgroupParent = opts.CGroupLimits.Parent
	}
	glog.V(2).Infof("Building container using config: %+v", dockerOpts)
	resp, err := d.client.ImageBuild(context.Background(), opts.Stdin, dockerOpts)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	// since can't pass in output stream to engine-api, need to copy contents of
	// the output stream they create into our output stream
	_, err = io.Copy(opts.Stdout, resp.Body)
	if opts.Stdout != nil {
		opts.Stdout.Close()
	}
	return err
}
1196678
func (dh *Client) PushImage(name string, opts *PushImageOptions) error {
	if name == "" {
		return fmt.Errorf("no image name given")
	}

	if opts == nil {
		opts = &PushImageOptions{Callback: HandlePullImageMessage}
	}

	registry, image, tag := splitImageName(name)
	if registry == "" {
		return fmt.Errorf("no registry given")
	}

	buf := &bytes.Buffer{}
	buf.WriteString(FAKE_AUTH)
	url := dh.Address + "/images/" + registry + "/" + image + "/push?tag=" + tag

	rsp, e := dh.postWithReader(url, buf)
	if e != nil {
		return e
	}
	defer rsp.Body.Close()

	return handleJSONStream(rsp.Body, opts.Callback)
}
451657
func (i *Image) Pull() error {
	resp, err := i.pullReq()
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode == http.StatusUnauthorized {
		i.Token, err = i.requestToken(resp)
		io.Copy(ioutil.Discard, resp.Body)
		if err != nil {
			return err
		}
		// try again
		resp, err = i.pullReq()
		if err != nil {
			return err
		}
		defer resp.Body.Close()
	}
	if contentType := resp.Header.Get("Content-Type"); contentType == "application/vnd.docker.distribution.manifest.list.v2+json" {
		err = parseManifestResponse(resp, i)
		if err != nil {
			return err
		}
		// pull actual manifest instead of manifestlist
		resp, err = i.pullReq()
		if err != nil {
			return err
		}
		defer resp.Body.Close()
	}
	return parseImageResponse(resp, i)
}