// Get retrieves the manifest with digest `dgst`. func (r *repository) Get(ctx context.Context, dgst digest.Digest, options ...distribution.ManifestServiceOption) (distribution.Manifest, error) { if err := r.checkPendingErrors(ctx); err != nil { return nil, err } if _, err := r.getImageStreamImage(dgst); err != nil { context.GetLogger(r.ctx).Errorf("error retrieving ImageStreamImage %s/%s@%s: %v", r.namespace, r.name, dgst.String(), err) return nil, err } image, err := r.getImage(dgst) if err != nil { context.GetLogger(r.ctx).Errorf("error retrieving image %s: %v", dgst.String(), err) return nil, err } ref := imageapi.DockerImageReference{Namespace: r.namespace, Name: r.name, Registry: r.registryAddr} if managed := image.Annotations[imageapi.ManagedByOpenShiftAnnotation]; managed == "true" { // Repository without a registry part is refers to repository containing locally managed images. // Such an entry is retrieved, checked and set by blobDescriptorService operating only on local blobs. ref.Registry = "" } else { // Repository with a registry points to remote repository. This is used by pullthrough middleware. ref = ref.DockerClientDefaults().AsRepository() } manifest, err := r.manifestFromImageWithCachedLayers(image, ref.Exact()) return manifest, err }
// Resolve converts an image reference into a resolved image or returns an error. Only images located in the internal // registry or those with a digest can be resolved - all other scenarios will return an error. func (c *imageResolutionCache) resolveImageReference(ref imageapi.DockerImageReference) (*rules.ImagePolicyAttributes, error) { // images by ID can be checked for policy if len(ref.ID) > 0 { now := now() if value, ok := c.cache.Get(ref.ID); ok { cached := value.(imageCacheEntry) if now.Before(cached.expires) { return &rules.ImagePolicyAttributes{Name: ref, Image: cached.image}, nil } } image, err := c.images.Get(ref.ID) if err != nil { return nil, err } c.cache.Add(ref.ID, imageCacheEntry{expires: now.Add(c.expiration), image: image}) return &rules.ImagePolicyAttributes{Name: ref, Image: image}, nil } if !c.integrated.Matches(ref.Registry) { return nil, fmt.Errorf("only images imported into the registry are allowed (%s)", ref.Exact()) } tag := ref.Tag if len(tag) == 0 { tag = imageapi.DefaultImageTag } return c.resolveImageStreamTag(ref.Namespace, ref.Name, tag) }
// proxyStat attempts to locate the digest in the provided remote repository or returns an error. If the digest is found, // r.digestToStore saves the store. func (r *pullthroughBlobStore) proxyStat(ctx context.Context, retriever importer.RepositoryRetriever, ref imageapi.DockerImageReference, dgst digest.Digest) (distribution.Descriptor, error) { context.GetLogger(r.repo.ctx).Infof("Trying to stat %q from %q", dgst, ref.Exact()) repo, err := retriever.Repository(ctx, ref.RegistryURL(), ref.RepositoryName(), false) if err != nil { context.GetLogger(r.repo.ctx).Errorf("Error getting remote repository for image %q: %v", ref.Exact(), err) return distribution.Descriptor{}, err } pullthroughBlobStore := repo.Blobs(ctx) desc, err := pullthroughBlobStore.Stat(r.repo.ctx, dgst) if err != nil { if err != distribution.ErrBlobUnknown { context.GetLogger(r.repo.ctx).Errorf("Error getting pullthroughBlobStore for image %q: %v", ref.Exact(), err) } return distribution.Descriptor{}, err } r.digestToStore[dgst.String()] = pullthroughBlobStore return desc, nil }