// PullImage pulls the Docker image specified by name taking the pull policy
// into the account.
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
}
417310
func PushImage(repotag string) error {
	iid, err := commons.ParseImageID(repotag)
	if err != nil {
		return err
	}

	return pushImage(iid.BaseName(), iid.Registry(), iid.Tag)
}
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
}
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)
}
683909
func (api *API) GetImage(img_id string) (*Image, error) {
	result := new(Image)
	url := createUrl(api, imagePathSegment, img_id)
	err := api.Client.Get(url, &result, http.StatusOK)
	if err != nil {
		return nil, err
	}
	result.api = api
	return result, nil
}
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)
}
755731
func GetImageRegistryAuth(auths *AuthConfigurations, imageName string) api.AuthConfig {
	glog.V(5).Infof("Getting docker credentials for %s", imageName)
	if auths == nil {
		return api.AuthConfig{}
	}
	ref, err := parseNamedDockerImageReference(imageName)
	if err != nil {
		glog.V(0).Infof("error: Failed to parse docker reference %s", imageName)
		return api.AuthConfig{}
	}
	if ref.Registry != "" {
		if auth, ok := auths.Configs[ref.Registry]; ok {
			glog.V(5).Infof("Using %s[%s] credentials for pulling %s", auth.Email, ref.Registry, imageName)
			return auth
		}
	}
	if auth, ok := auths.Configs[defaultRegistry]; ok {
		glog.V(5).Infof("Using %s credentials for pulling %s", auth.Email, imageName)
		return auth
	}
	return api.AuthConfig{}
}
1009727
func (c *Client) TagImage(name string, opts TagImageOptions) error {
	if name == "" {
		return ErrNoSuchImage
	}
	resp, err := c.do("POST", "/images/"+name+"/tag?"+queryString(&opts), doOptions{
		context: opts.Context,
	})

	if err != nil {
		return err
	}

	defer resp.Body.Close()

	if resp.StatusCode == http.StatusNotFound {
		return ErrNoSuchImage
	}

	return err
}
141014
func (runtime *DockerRuntime) PullImage(image string) error {
	out, err := runtime.exec.Command("docker", "pull", image).CombinedOutput()
	if err != nil {
		return errors.Wrapf(err, "output: %s, error", string(out))
	}
	return nil
}
456172
func ParseImageName(image string) (string, string, string, error) {
	named, err := dockerref.ParseNormalizedNamed(image)
	if err != nil {
		return "", "", "", fmt.Errorf("couldn't parse image name: %v", err)
	}

	repoToPull := named.Name()
	var tag, digest string

	tagged, ok := named.(dockerref.Tagged)
	if ok {
		tag = tagged.Tag()
	}

	digested, ok := named.(dockerref.Digested)
	if ok {
		digest = digested.Digest().String()
	}
	// If no tag was specified, use the default "latest".
	if len(tag) == 0 && len(digest) == 0 {
		tag = DefaultImageTag
	}
	return repoToPull, tag, digest, nil
}
1363354
func (d *Driver) loadImage(task *drivers.TaskConfig, driverConfig *TaskConfig, client *docker.Client) (id string, err error) {

	archive := filepath.Join(task.TaskDir().LocalDir, driverConfig.LoadImage)
	d.logger.Debug("loading image from disk", "archive", archive)

	f, err := os.Open(archive)
	if err != nil {
		return "", fmt.Errorf("unable to open image archive: %v", err)
	}

	if err := client.LoadImage(docker.LoadImageOptions{InputStream: f}); err != nil {
		return "", err
	}
	f.Close()

	dockerImage, err := client.InspectImage(driverConfig.Image)
	if err != nil {
		return "", recoverableErrTimeouts(err)
	}

	d.coordinator.IncrementImageReference(dockerImage.ID, driverConfig.Image, task.ID)
	return dockerImage.ID, 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
}
290690
func (f *FakeDocker) PullImage(imageName string) (*api.Image, error) {
	if f.PullResult {
		return &api.Image{}, nil
	}
	return nil, f.PullError
}
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{})
	}
}
328713
func (c *Cluster) TagImage(name string, opts docker.TagImageOptions) error {
	img, err := c.storage().RetrieveImage(name)
	if err != nil {
		return err
	}
	node, err := c.getNodeByAddr(img.LastNode)
	if err != nil {
		return err
	}
	err = node.TagImage(name, opts)
	if err != nil {
		return wrapError(node, err)
	}
	key := imageKey(opts.Repo, opts.Tag)
	return c.storage().StoreImage(key, img.LastId, node.addr)
}
376491
func (e *ClientExecutor) LoadImage(from string) (*docker.Image, error) {
	image, err := e.Client.InspectImage(from)
	if err == nil {
		return image, nil
	}
	if err != docker.ErrNoSuchImage {
		return nil, err
	}

	if !e.AllowPull {
		glog.V(4).Infof("image %s did not exist", from)
		return nil, docker.ErrNoSuchImage
	}

	repository, tag := docker.ParseRepositoryTag(from)
	if len(tag) == 0 {
		tag = "latest"
	}

	glog.V(4).Infof("attempting to pull %s with auth from repository %s:%s", from, repository, tag)

	// TODO: we may want to abstract looping over multiple credentials
	auth, _ := e.AuthFn(repository)
	if len(auth) == 0 {
		auth = append(auth, dockertypes.AuthConfig{})
	}

	if e.LogFn != nil {
		e.LogFn("Image %s was not found, pulling ...", from)
	}

	var lastErr error
	outputProgress := func(s string) {
		e.LogFn("%s", s)
	}
	for _, config := range auth {
		// TODO: handle IDs?
		var pullErr error
		func() { // A scope for defer
			pullWriter := imageprogress.NewPullWriter(outputProgress)
			defer func() {
				err := pullWriter.Close()
				if pullErr == nil {
					pullErr = err
				}
			}()

			pullImageOptions := docker.PullImageOptions{
				Repository:    repository,
				Tag:           tag,
				OutputStream:  pullWriter,
				RawJSONStream: true,
			}
			if glog.V(5) {
				pullImageOptions.OutputStream = os.Stderr
				pullImageOptions.RawJSONStream = false
			}
			authConfig := docker.AuthConfiguration{Username: config.Username, ServerAddress: config.ServerAddress, Password: config.Password}
			pullErr = e.Client.PullImage(pullImageOptions, authConfig)
		}()
		if pullErr == nil {
			break
		}
		lastErr = pullErr
		continue
	}
	if lastErr != nil {
		return nil, fmt.Errorf("unable to pull image (from: %s, tag: %s): %v", repository, tag, lastErr)
	}

	return e.Client.InspectImage(from)
}
404859
func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (Image, error) {
	pullCtx := defaultRemoteContext()
	for _, o := range opts {
		if err := o(c, pullCtx); err != nil {
			return nil, err
		}
	}

	if pullCtx.PlatformMatcher == nil {
		if len(pullCtx.Platforms) > 1 {
			return nil, errors.New("cannot pull multiplatform image locally, try Fetch")
		} else if len(pullCtx.Platforms) == 0 {
			pullCtx.PlatformMatcher = platforms.Default()
		} else {
			p, err := platforms.Parse(pullCtx.Platforms[0])
			if err != nil {
				return nil, errors.Wrapf(err, "invalid platform %s", pullCtx.Platforms[0])
			}

			pullCtx.PlatformMatcher = platforms.Only(p)
		}
	}

	ctx, done, err := c.WithLease(ctx)
	if err != nil {
		return nil, err
	}
	defer done(ctx)

	img, err := c.fetch(ctx, pullCtx, ref, 1)
	if err != nil {
		return nil, err
	}

	i := NewImageWithPlatform(c, img, pullCtx.PlatformMatcher)

	if pullCtx.Unpack {
		if err := i.Unpack(ctx, pullCtx.Snapshotter); err != nil {
			return nil, errors.Wrapf(err, "failed to unpack image on snapshotter %s", pullCtx.Snapshotter)
		}
	}

	return i, nil
}