func imageExists(reg registry.Registry, imageID image.Ref) (bool, error) {
	_, err := reg.GetImage(imageID)
	if err != nil {
		return false, nil
	}
	return true, nil
}
Checks whether the given image exists in the repository.
Return true if exist, false otherwise.
FIXME(michael): never returns an error; should it?
package update
import (
	"fmt"
	"strings"
	"github.com/go-kit/kit/log"
	"github.com/pkg/errors"
	fluxerr "github.com/fluxcd/flux/pkg/errors"
	"github.com/fluxcd/flux/pkg/image"
	"github.com/fluxcd/flux/pkg/policy"
	"github.com/fluxcd/flux/pkg/registry"
	"github.com/fluxcd/flux/pkg/resource"
)
type imageReposMap map[image.CanonicalName]image.RepositoryMetadata
type ImageRepos struct {
	imageRepos imageReposMap
}
func (r ImageRepos) GetRepositoryMetadata(repo image.Name) image.RepositoryMetadata {
	if metadata, ok := r.imageRepos[repo.CanonicalName()]; ok {
		tagsCopy := make([]string, len(metadata.Tags))
		copy(tagsCopy, metadata.Tags)
		imagesCopy := make(map[string]image.Info, len(metadata.Images))
		for tag, info := range metadata.Images {
			info.ID = repo.ToRef(info.ID.Tag)
			imagesCopy[tag] = info
		}
		return image.RepositoryMetadata{tagsCopy, imagesCopy}
	}
	return image.RepositoryMetadata{}
}
type SortedImageInfos []image.Info
func FilterImages(images []image.Info, pattern policy.Pattern) []image.Info {
	return filterImages(images, pattern)
}
func SortImages(images []image.Info, pattern policy.Pattern) SortedImageInfos {
	return sortImages(images, pattern)
}
func FilterAndSortRepositoryMetadata(rm image.RepositoryMetadata, pattern policy.Pattern) (SortedImageInfos, error) {
	filteredMetadata := image.RepositoryMetadata{
		Tags:   filterTags(rm.Tags, pattern),
		Images: rm.Images,
	}
	filteredImages, err := filteredMetadata.GetImageTagInfo()
	if err != nil {
		return nil, err
	}
	return SortImages(filteredImages, pattern), nil
}
func (sii SortedImageInfos) Latest() (image.Info, bool) {
	if len(sii) > 0 {
		return sii[0], true
	}
	return image.Info{}, false
}
func sortImages(images []image.Info, pattern policy.Pattern) SortedImageInfos {
	var sorted SortedImageInfos
	for _, i := range images {
		sorted = append(sorted, i)
	}
	image.Sort(sorted, pattern.Newer)
	return sorted
}
func matchWithLatest(pattern policy.Pattern, tag string) bool {
	if pattern != policy.PatternLatest && strings.EqualFold(tag, "latest") {
		return false
	}
	return pattern.Matches(tag)
}
func filterTags(tags []string, pattern policy.Pattern) []string {
	var filtered []string
	for _, tag := range tags {
		if matchWithLatest(pattern, tag) {
			filtered = append(filtered, tag)
		}
	}
	return filtered
}
func filterImages(images []image.Info, pattern policy.Pattern) []image.Info {
	var filtered []image.Info
	for _, i := range images {
		tag := i.ID.Tag
		if matchWithLatest(pattern, tag) {
			filtered = append(filtered, i)
		}
	}
	return filtered
}
type containers interface {
	Len() int
	Containers(i int) []resource.Container
}
type workloadContainers []*WorkloadUpdate
func (cs workloadContainers) Len() int {
	return len(cs)
}
func (cs workloadContainers) Containers(i int) []resource.Container {
	return cs[i].Workload.ContainersOrNil()
}
func fetchUpdatableImageRepos(registry registry.Registry, updateable []*WorkloadUpdate, logger log.Logger) (ImageRepos, error) {
	return FetchImageRepos(registry, workloadContainers(updateable), logger)
}
func FetchImageRepos(reg registry.Registry, cs containers, logger log.Logger) (ImageRepos, error) {
	imageRepos := imageReposMap{}
	for i := 0; i < cs.Len(); i++ {
		for _, container := range cs.Containers(i) {
			imageRepos[container.Image.CanonicalName()] = image.RepositoryMetadata{}
		}
	}
	for repo := range imageRepos {
		images, err := reg.GetImageRepositoryMetadata(repo.Name)
		if err != nil {
			if !fluxerr.IsMissing(err) {
				logger.Log("err", errors.Wrapf(err, "fetching image metadata for %s", repo))
				continue
			}
		}
		imageRepos[repo] = images
	}
	return ImageRepos{imageRepos}, nil
}
func exactImageRepos(reg registry.Registry, images []image.Ref) (ImageRepos, error) {
	m := imageReposMap{}
	for _, id := range images {
		exist, err := imageExists(reg, id)
		if err != nil {
			return ImageRepos{}, errors.Wrap(image.ErrInvalidImageID, err.Error())
		}
		if !exist {
			return ImageRepos{}, errors.Wrap(image.ErrInvalidImageID, fmt.Sprintf("image %q does not exist", id))
		}
		m[id.CanonicalName()] = image.RepositoryMetadata{
			Tags: []string{id.Tag},
			Images: map[string]image.Info{
				id.Tag: {ID: id},
			},
		}
	}
	return ImageRepos{m}, nil
}