// GetRegistryImage returns information about an image that is stored in the
// docker registry index.
// e.g. GetRegistryImage(ctx, "library/reponame:tagname")
331938
func (f *Facade) GetRegistryImage(ctx datastore.Context, image string) (*registry.Image, error) {
	defer ctx.Metrics().Stop(ctx.Metrics().Start("Facade.GetRegistryImage"))
	rImage, err := f.registryStore.Get(ctx, image)
	if err != nil {
		return nil, err
	}
	return rImage, nil
}
135428
func GetTag(image string) string {
	if !strings.Contains(image, ":") {
		return DefaultVersion
	}

	parts := strings.Split(image, ":")
	if len(parts) != 2 {
		return WrongVersion
	}

	return parts[len(parts)-1]
}
209007
func (client *RegistryIndexClient) FindImage(image string) (*registry.Image, error) {
	image, err := client.parseImage(image)
	if err != nil {
		return nil, err
	}
	rImage, err := client.facade.GetRegistryImage(client.ctx, image)
	if datastore.IsErrNoSuchEntity(err) {
		return nil, ErrImageNotFound
	}
	return rImage, err
}
1081925
func SetRegistryImage(conn client.Connection, rImage registry.Image) error {
	leaderpath := path.Join(zkregistryrepos, rImage.Library, rImage.Repo)
	leadernode := &RegistryImageLeader{HostID: "master"}
	if err := conn.CreateDir(leaderpath); err != nil && err != client.ErrNodeExists {
		glog.Errorf("Could not create repo path %s: %s", leaderpath, err)
		return err
	}
	imagepath := path.Join(zkregistrytags, rImage.ID())
	node := &RegistryImageNode{Image: rImage, PushedAt: time.Unix(0, 0)}
	if err := conn.Create(imagepath, node); err == client.ErrNodeExists {
		leader, err := conn.NewLeader(leaderpath)
		if err != nil {
			glog.Errorf("Could not establish leader at path %s: %s", leaderpath, err)
			return err
		}
		leaderDone := make(chan struct{})
		defer close(leaderDone)
		_, err = leader.TakeLead(leadernode, leaderDone)
		if err != nil {
			return err
		}
		defer leader.ReleaseLead()
		if err := conn.Get(imagepath, node); err != nil {
			return err
		}
		node.Image = rImage
		node.PushedAt = time.Unix(0, 0)
		return conn.Set(imagepath, node)
	} else if err != nil {
		glog.Errorf("Could not create tag path %s: %s", imagepath, err)
		return err
	}
	return nil

}
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{})
	}
}
290690
func (f *FakeDocker) PullImage(imageName string) (*api.Image, error) {
	if f.PullResult {
		return &api.Image{}, nil
	}
	return nil, f.PullError
}
383339
func GetRegistry(c context.Context) Registry {
	ret, _ := c.Value(&regKey).(Registry)
	return ret
}
662288
func (f *FakeDocker) GetImageID(image string) (string, error) {
	f.GetImageIDImage = image
	return f.GetImageIDResult, f.GetImageIDError
}
997308
func (f *FakeDocker) GetImageEntrypoint(image string) ([]string, error) {
	return f.GetImageEntrypointResult, f.GetImageEntrypointError
}
40708
func (d *stiDocker) IsImageInLocalRegistry(name string) (bool, error) {
	name = getImageName(name)
	resp, err := d.InspectImage(name)
	if resp != nil {
		return true, nil
	}
	if err != nil && !dockerapi.IsErrNotFound(err) {
		return false, s2ierr.NewInspectImageError(name, err)
	}
	return false, nil
}
640531
func GetRegistryPath(browser string) (string, error) {
	path, found := registryPaths[browser]
	if !found {
		return "", fmt.Errorf("browser %s on %s is currently not supported", browser, runtime.GOOS)
	}
	return path, nil
}
705634
func (f *Facade) getImageUUID(ctx datastore.Context, imageName string) (string, error) {
	logger := plog.WithField("imagename", imageName)

	if imageName == "" {
		logger.Debug("Image name not specified")
		return "", nil
	}

	imageID, err := commons.ParseImageID(imageName)
	if err != nil {
		logger.WithError(err).Debug("Could not parse service image")
		return "", err
	}
	imageID.Tag = docker.Latest
	logger = logger.WithField("imagename", imageID.String())
	logger.Debug("Parsed service image")

	imageData, err := f.registryStore.Get(ctx, imageID.String())
	if err != nil {
		logger.WithError(err).Debug("Could not look up service image in image registry")
		return "", err
	}

	logger.WithField("imageuuid", imageData.UUID).Debug("Loaded image uuid")
	return imageData.UUID, nil
}
1237391
func (client *RegistryIndexClient) PushImage(image, uuid string, hash string) error {
	imageID, err := commons.ParseImageID(image)
	if err != nil {
		return err
	}
	if imageID.IsLatest() {
		imageID.Tag = docker.Latest
	}

	rImage := &registry.Image{
		Library: imageID.User,
		Repo:    imageID.Repo,
		Tag:     imageID.Tag,
		UUID:    uuid,
		Hash:    hash,
	}
	return client.facade.SetRegistryImage(client.ctx, rImage)
}
208226
func (c *connection) ImageByTag(namespace, name, tag string) (*Image, error) {
	if len(namespace) == 0 && reference.IsRegistryDockerHub(c.url.Host) {
		namespace = "library"
	}
	if len(name) == 0 {
		return nil, fmt.Errorf("image name must be specified")
	}
	searchTag := tag
	if len(searchTag) == 0 {
		searchTag = "latest"
	}

	repo, err := c.getCachedRepository(fmt.Sprintf("%s/%s", namespace, name))
	if err != nil {
		return nil, err
	}

	image, _, err := repo.getTaggedImage(c, searchTag, tag)
	return image, err
}
927253
func getImageManifestByIDFromRegistry(registry *url.URL, repositoryName, imageID, username, password string, insecure bool) ([]byte, error) {
	ctx := context.Background()

	credentials := registryclient.NewBasicCredentials()
	credentials.Add(registry, username, password)

	insecureRT, err := rest.TransportFor(&rest.Config{TLSClientConfig: rest.TLSClientConfig{Insecure: true}})
	if err != nil {
		return nil, err
	}

	repo, err := registryclient.NewContext(http.DefaultTransport, insecureRT).
		WithCredentials(credentials).
		Repository(ctx, registry, repositoryName, insecure)
	if err != nil {
		return nil, err
	}

	manifests, err := repo.Manifests(ctx, nil)
	if err != nil {
		return nil, err
	}

	manifest, err := manifests.Get(ctx, godigest.Digest(imageID))
	if err != nil {
		return nil, err
	}
	_, manifestPayload, err := manifest.Payload()
	if err != nil {
		return nil, err
	}

	return manifestPayload, nil
}
1151281
func (d *Driver) pullImage(task *drivers.TaskConfig, driverConfig *TaskConfig, client *docker.Client, repo, tag string) (id string, err error) {
	authOptions, err := d.resolveRegistryAuthentication(driverConfig, repo)
	if err != nil {
		if driverConfig.AuthSoftFail {
			d.logger.Warn("Failed to find docker repo auth", "repo", repo, "error", err)
		} else {
			return "", fmt.Errorf("Failed to find docker auth for repo %q: %v", repo, err)
		}
	}

	if authIsEmpty(authOptions) {
		d.logger.Debug("did not find docker auth for repo", "repo", repo)
	}

	d.eventer.EmitEvent(&drivers.TaskEvent{
		TaskID:    task.ID,
		AllocID:   task.AllocID,
		TaskName:  task.Name,
		Timestamp: time.Now(),
		Message:   "Downloading image",
		Annotations: map[string]string{
			"image": dockerImageRef(repo, tag),
		},
	})

	return d.coordinator.PullImage(driverConfig.Image, authOptions, task.ID, d.emitEventFunc(task))
}
492355
func GetImage(name, registryURL string) (*Image, int, error) {
	if name == "" {
		return nil, -1, errors.New("image name is empty")
	}

	var ru *url.URL
	var err error
	if len(registryURL) != 0 {
		ru, err = url.Parse(registryURL)
	} else {
		ru, err = url.Parse(DockerHubRegistryURL)
		registryURL = DockerHubRegistryURL
	}
	if err != nil {
		return nil, -1, err
	}

	// In order to get layers from Docker CDN we need to hit 'images' endpoint
	// and request the token. Client should also accept and store cookies, as
	// they are needed to fetch the layer data later.
	imagesURL := fmt.Sprintf("%s/v1/repositories/%s/images", registryURL, name)

	req, err := http.NewRequest("GET", imagesURL, nil)
	if err != nil {
		return nil, -1, err
	}

	// FIXME: Send 'Connection: close' header on HTTP requests
	// as reusing the connection is still prone to EOF/Connection reset errors
	// in certain network environments...
	// See: ENGT-9670
	// https://stackoverflow.com/questions/17714494/golang-http-request-results-in-eof-errors
	req.Close = true

	req.Header.Set("X-Docker-Token", "true")

	client := &http.Client{
		Transport: &http.Transport{
			Proxy: http.ProxyFromEnvironment,
		},
	}
	client.Jar, err = cookiejar.New(nil) // Docker repo API sets and uses cookies for CDN.
	if err != nil {
		return nil, -1, err
	}

	res, err := client.Do(req)
	if err != nil {
		return nil, -1, err
	}
	defer res.Body.Close()
	switch res.StatusCode {
	case http.StatusOK:
		// Fall through.
	case http.StatusNotFound:
		return nil, res.StatusCode, fmt.Errorf("image %q not found", name)
	default:
		return nil, res.StatusCode, fmt.Errorf("HTTP %d ", res.StatusCode)
	}

	token := res.Header.Get("X-Docker-Token")
	endpoints := strings.Split(res.Header.Get("X-Docker-Endpoints"), ",")

	if len(endpoints) == 0 {
		return nil, res.StatusCode, errors.New("Docker index response didn't contain any endpoints")
	}
	for i := range endpoints {
		endpoints[i] = strings.Trim(endpoints[i], " ")
	}

	img := &Image{
		Name:      name,
		client:    client,
		endpoints: endpoints,
		token:     token,
		scheme:    ru.Scheme,
	}

	img.tags, err = img.fetchTags()
	if err != nil {
		return nil, res.StatusCode, err
	}

	return img, res.StatusCode, nil
}