github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/api/handlers/utils/images.go (about) 1 package utils 2 3 import ( 4 "fmt" 5 "net/http" 6 "strings" 7 8 "github.com/containers/common/libimage" 9 "github.com/containers/image/v5/docker" 10 storageTransport "github.com/containers/image/v5/storage" 11 "github.com/containers/image/v5/transports/alltransports" 12 "github.com/containers/image/v5/types" 13 "github.com/hanks177/podman/v4/libpod" 14 api "github.com/hanks177/podman/v4/pkg/api/types" 15 "github.com/hanks177/podman/v4/pkg/util" 16 "github.com/containers/storage" 17 "github.com/docker/distribution/reference" 18 "github.com/pkg/errors" 19 ) 20 21 // NormalizeToDockerHub normalizes the specified nameOrID to Docker Hub if the 22 // request is for the compat API and if containers.conf set the specific mode. 23 // If nameOrID is a (short) ID for a local image, the full ID will be returned. 24 func NormalizeToDockerHub(r *http.Request, nameOrID string) (string, error) { 25 if IsLibpodRequest(r) || !util.DefaultContainerConfig().Engine.CompatAPIEnforceDockerHub { 26 return nameOrID, nil 27 } 28 29 runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) 30 31 // The candidate may resolve to a local non-Docker Hub image, such as 32 // 'busybox' -> 'registry.com/busybox'. 33 img, candidate, err := runtime.LibimageRuntime().LookupImage(nameOrID, nil) 34 if err != nil { 35 if errors.Cause(err) != storage.ErrImageUnknown { 36 return "", fmt.Errorf("normalizing name for compat API: %v", err) 37 } 38 // If the image could not be resolved locally, set the 39 // candidate back to the input. 40 candidate = nameOrID 41 } else if strings.HasPrefix(img.ID(), strings.TrimPrefix(nameOrID, "sha256:")) { 42 return img.ID(), nil 43 } 44 45 // No ID, so we can normalize. 46 named, err := reference.ParseNormalizedNamed(candidate) 47 if err != nil { 48 return "", fmt.Errorf("normalizing name %q (orig: %q) for compat API: %v", candidate, nameOrID, err) 49 } 50 51 return named.String(), nil 52 } 53 54 // PossiblyEnforceDockerHub sets fields in the system context to enforce 55 // resolving short names to Docker Hub if the request is for the compat API and 56 // if containers.conf set the specific mode. 57 func PossiblyEnforceDockerHub(r *http.Request, sys *types.SystemContext) { 58 if IsLibpodRequest(r) || !util.DefaultContainerConfig().Engine.CompatAPIEnforceDockerHub { 59 return 60 } 61 sys.PodmanOnlyShortNamesIgnoreRegistriesConfAndForceDockerHub = true 62 } 63 64 // IsRegistryReference checks if the specified name points to the "docker://" 65 // transport. If it points to no supported transport, we'll assume a 66 // non-transport reference pointing to an image (e.g., "fedora:latest"). 67 func IsRegistryReference(name string) error { 68 imageRef, err := alltransports.ParseImageName(name) 69 if err != nil { 70 // No supported transport -> assume a docker-stype reference. 71 return nil // nolint: nilerr 72 } 73 if imageRef.Transport().Name() == docker.Transport.Name() { 74 return nil 75 } 76 return errors.Errorf("unsupported transport %s in %q: only docker transport is supported", imageRef.Transport().Name(), name) 77 } 78 79 // ParseStorageReference parses the specified image name to a 80 // `types.ImageReference` and enforces it to refer to a 81 // containers-storage-transport reference. 82 func ParseStorageReference(name string) (types.ImageReference, error) { 83 storagePrefix := storageTransport.Transport.Name() 84 imageRef, err := alltransports.ParseImageName(name) 85 if err == nil && imageRef.Transport().Name() != docker.Transport.Name() { 86 return nil, errors.Errorf("reference %q must be a storage reference", name) 87 } else if err != nil { 88 origErr := err 89 imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s:%s", storagePrefix, name)) 90 if err != nil { 91 return nil, errors.Wrapf(origErr, "reference %q must be a storage reference", name) 92 } 93 } 94 return imageRef, nil 95 } 96 97 func GetImage(r *http.Request, name string) (*libimage.Image, error) { 98 runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) 99 image, _, err := runtime.LibimageRuntime().LookupImage(name, nil) 100 if err != nil { 101 return nil, err 102 } 103 return image, err 104 }