mirror of
https://github.com/containers/podman.git
synced 2025-08-06 19:44:14 +08:00
compat API: allow enforcing short-names resolution to Docker Hub
The Docker-compatible REST API has historically behaved just as the rest of Podman and Buildah (and the atomic Docker in older RHEL/Fedora) where `containers-registries.conf` is centrally controlling which registries a short name may resolve to during pull or local image lookups. Please refer to a blog for more details [1]. Docker, however, is only resolving short names to docker.io which has been reported (see #12320) to break certain clients who rely on this behavior. In order to support this scenario, `containers.conf(5)` received a new option to control whether Podman's compat API resolves to docker.io only or behaves as before. Most endpoints allow for directly normalizing parameters that represent an image. If set in containers.conf, Podman will then normalize the references directly to docker.io. The build endpoint is an outlier since images are also referenced in Dockerfiles. The Buildah API, however, supports specifying a custom `types.SystemContext` in which we can set a field that enforces short-name resolution to docker.io in `c/image/pkg/shortnames`. Notice that this a "hybrid" approach of doing the normalization directly in the compat endpoints *and* in `pkg/shortnames` by passing a system context. Doing such a hybrid approach is neccessary since the compat and the libpod endpoints share the same `libimage.Runtime` which makes a global enforcement via the `libimage.Runtime.systemContext` impossible. Having two separate runtimes for the compat and the libpod endpoints seems risky and not generally applicable to all endpoints. [1] https://www.redhat.com/sysadmin/container-image-short-names Fixes: #12320 Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
This commit is contained in:
@ -52,6 +52,13 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
imageName, err := utils.NormalizeToDockerHub(r, body.Config.Image)
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error normalizing image"))
|
||||
return
|
||||
}
|
||||
body.Config.Image = imageName
|
||||
|
||||
newImage, resolvedName, err := runtime.LibimageRuntime().LookupImage(body.Config.Image, nil)
|
||||
if err != nil {
|
||||
if errors.Cause(err) == storage.ErrImageUnknown {
|
||||
|
@ -12,7 +12,6 @@ import (
|
||||
"github.com/containers/common/libimage"
|
||||
"github.com/containers/common/pkg/config"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/image/v5/pkg/shortnames"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/podman/v3/libpod"
|
||||
"github.com/containers/podman/v3/pkg/api/handlers"
|
||||
@ -56,6 +55,12 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
|
||||
defer os.Remove(tmpfile.Name())
|
||||
|
||||
name := utils.GetName(r)
|
||||
possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, name)
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error normalizing image"))
|
||||
return
|
||||
}
|
||||
|
||||
imageEngine := abi.ImageEngine{Libpod: runtime}
|
||||
|
||||
saveOptions := entities.ImageSaveOptions{
|
||||
@ -63,7 +68,7 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
|
||||
Output: tmpfile.Name(),
|
||||
}
|
||||
|
||||
if err := imageEngine.Save(r.Context(), name, nil, saveOptions); err != nil {
|
||||
if err := imageEngine.Save(r.Context(), possiblyNormalizedName, nil, saveOptions); err != nil {
|
||||
if errors.Cause(err) == storage.ErrImageUnknown {
|
||||
utils.ImageNotFound(w, name, errors.Wrapf(err, "failed to find image %s", name))
|
||||
return
|
||||
@ -87,9 +92,6 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func CommitContainer(w http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
destImage string
|
||||
)
|
||||
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
|
||||
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
|
||||
|
||||
@ -98,12 +100,12 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) {
|
||||
Changes string `schema:"changes"`
|
||||
Comment string `schema:"comment"`
|
||||
Container string `schema:"container"`
|
||||
Pause bool `schema:"pause"`
|
||||
Repo string `schema:"repo"`
|
||||
Tag string `schema:"tag"`
|
||||
// fromSrc string # fromSrc is currently unused
|
||||
Pause bool `schema:"pause"`
|
||||
Repo string `schema:"repo"`
|
||||
Tag string `schema:"tag"`
|
||||
}{
|
||||
// This is where you can override the golang default value for one of fields
|
||||
Tag: "latest",
|
||||
}
|
||||
|
||||
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
|
||||
@ -116,7 +118,6 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
sc := runtime.SystemContext()
|
||||
tag := "latest"
|
||||
options := libpod.ContainerCommitOptions{
|
||||
Pause: true,
|
||||
}
|
||||
@ -133,9 +134,6 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if len(query.Tag) > 0 {
|
||||
tag = query.Tag
|
||||
}
|
||||
options.Message = query.Comment
|
||||
options.Author = query.Author
|
||||
options.Pause = query.Pause
|
||||
@ -146,9 +144,15 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// I know mitr hates this ... but doing for now
|
||||
var destImage string
|
||||
if len(query.Repo) > 1 {
|
||||
destImage = fmt.Sprintf("%s:%s", query.Repo, tag)
|
||||
destImage = fmt.Sprintf("%s:%s", query.Repo, query.Tag)
|
||||
possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, destImage)
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error normalizing image"))
|
||||
return
|
||||
}
|
||||
destImage = possiblyNormalizedName
|
||||
}
|
||||
|
||||
commitImage, err := ctr.Commit(r.Context(), destImage, options)
|
||||
@ -156,7 +160,7 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) {
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "CommitFailure"))
|
||||
return
|
||||
}
|
||||
utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: commitImage.ID()}) // nolint
|
||||
utils.WriteResponse(w, http.StatusCreated, handlers.IDResponse{ID: commitImage.ID()}) // nolint
|
||||
}
|
||||
|
||||
func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) {
|
||||
@ -195,12 +199,22 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
reference := query.Repo
|
||||
if query.Repo != "" {
|
||||
possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, reference)
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error normalizing image"))
|
||||
return
|
||||
}
|
||||
reference = possiblyNormalizedName
|
||||
}
|
||||
|
||||
platformSpecs := strings.Split(query.Platform, "/")
|
||||
opts := entities.ImageImportOptions{
|
||||
Source: source,
|
||||
Changes: query.Changes,
|
||||
Message: query.Message,
|
||||
Reference: query.Repo,
|
||||
Reference: reference,
|
||||
OS: platformSpecs[0],
|
||||
}
|
||||
if len(platformSpecs) > 1 {
|
||||
@ -250,13 +264,9 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
fromImage := mergeNameAndTagOrDigest(query.FromImage, query.Tag)
|
||||
|
||||
// without this early check this function would return 200 but reported error via body stream soon after
|
||||
// it's better to let caller know early via HTTP status code that request cannot be processed
|
||||
_, err := shortnames.Resolve(runtime.SystemContext(), fromImage)
|
||||
possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, mergeNameAndTagOrDigest(query.FromImage, query.Tag))
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrap(err, "failed to resolve image name"))
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error normalizing image"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -291,7 +301,7 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
pullResChan := make(chan pullResult)
|
||||
go func() {
|
||||
pulledImages, err := runtime.LibimageRuntime().Pull(r.Context(), fromImage, config.PullPolicyAlways, pullOptions)
|
||||
pulledImages, err := runtime.LibimageRuntime().Pull(r.Context(), possiblyNormalizedName, config.PullPolicyAlways, pullOptions)
|
||||
pullResChan <- pullResult{images: pulledImages, err: err}
|
||||
}()
|
||||
|
||||
@ -371,7 +381,13 @@ func GetImage(w http.ResponseWriter, r *http.Request) {
|
||||
// 404 no such
|
||||
// 500 internal
|
||||
name := utils.GetName(r)
|
||||
newImage, err := utils.GetImage(r, name)
|
||||
possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, name)
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error normalizing image"))
|
||||
return
|
||||
}
|
||||
|
||||
newImage, err := utils.GetImage(r, possiblyNormalizedName)
|
||||
if err != nil {
|
||||
// Here we need to fiddle with the error message because docker-py is looking for "No
|
||||
// such image" to determine on how to raise the correct exception.
|
||||
@ -483,7 +499,16 @@ func ExportImages(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
images := query.Names
|
||||
images := make([]string, len(query.Names))
|
||||
for i, img := range query.Names {
|
||||
possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, img)
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error normalizing image"))
|
||||
return
|
||||
}
|
||||
images[i] = possiblyNormalizedName
|
||||
}
|
||||
|
||||
tmpfile, err := ioutil.TempFile("", "api.tar")
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to create tempfile"))
|
||||
|
@ -118,7 +118,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
|
||||
SecurityOpt string `schema:"securityopt"`
|
||||
ShmSize int `schema:"shmsize"`
|
||||
Squash bool `schema:"squash"`
|
||||
Tag []string `schema:"t"`
|
||||
Tags []string `schema:"t"`
|
||||
Target string `schema:"target"`
|
||||
Timestamp int64 `schema:"timestamp"`
|
||||
Ulimits string `schema:"ulimits"`
|
||||
@ -144,6 +144,9 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
// convert tag formats
|
||||
tags := query.Tags
|
||||
|
||||
// convert addcaps formats
|
||||
var addCaps = []string{}
|
||||
if _, found := r.URL.Query()["addcaps"]; found {
|
||||
@ -240,8 +243,13 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
var output string
|
||||
if len(query.Tag) > 0 {
|
||||
output = query.Tag[0]
|
||||
if len(tags) > 0 {
|
||||
possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, tags[0])
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error normalizing image"))
|
||||
return
|
||||
}
|
||||
output = possiblyNormalizedName
|
||||
}
|
||||
format := buildah.Dockerv2ImageManifest
|
||||
registry := query.Registry
|
||||
@ -257,9 +265,14 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
}
|
||||
var additionalTags []string
|
||||
if len(query.Tag) > 1 {
|
||||
additionalTags = query.Tag[1:]
|
||||
var additionalTags []string // nolint
|
||||
for i := 1; i < len(tags); i++ {
|
||||
possiblyNormalizedTag, err := utils.NormalizeToDockerHub(r, tags[i])
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error normalizing image"))
|
||||
return
|
||||
}
|
||||
additionalTags = append(additionalTags, possiblyNormalizedTag)
|
||||
}
|
||||
|
||||
var buildArgs = map[string]string{}
|
||||
@ -404,6 +417,22 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer auth.RemoveAuthfile(authfile)
|
||||
|
||||
fromImage := query.From
|
||||
if fromImage != "" {
|
||||
possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, fromImage)
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error normalizing image"))
|
||||
return
|
||||
}
|
||||
fromImage = possiblyNormalizedName
|
||||
}
|
||||
|
||||
systemContext := &types.SystemContext{
|
||||
AuthFilePath: authfile,
|
||||
DockerAuthConfig: creds,
|
||||
}
|
||||
utils.PossiblyEnforceDockerHub(r, systemContext)
|
||||
|
||||
// Channels all mux'ed in select{} below to follow API build protocol
|
||||
stdout := channel.NewWriter(make(chan []byte))
|
||||
defer stdout.Close()
|
||||
@ -458,7 +487,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
|
||||
Err: auxout,
|
||||
Excludes: excludes,
|
||||
ForceRmIntermediateCtrs: query.ForceRm,
|
||||
From: query.From,
|
||||
From: fromImage,
|
||||
IgnoreUnrecognizedInstructions: query.Ignore,
|
||||
Isolation: isolation,
|
||||
Jobs: &jobs,
|
||||
@ -481,10 +510,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
|
||||
RusageLogFile: query.RusageLogFile,
|
||||
Squash: query.Squash,
|
||||
Target: query.Target,
|
||||
SystemContext: &types.SystemContext{
|
||||
AuthFilePath: authfile,
|
||||
DockerAuthConfig: creds,
|
||||
},
|
||||
SystemContext: systemContext,
|
||||
}
|
||||
|
||||
for _, platformSpec := range query.Platform {
|
||||
@ -590,7 +616,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
|
||||
logrus.Warnf("Failed to json encode error %v", err)
|
||||
}
|
||||
flush()
|
||||
for _, tag := range query.Tag {
|
||||
for _, tag := range tags {
|
||||
m.Stream = fmt.Sprintf("Successfully tagged %s\n", tag)
|
||||
if err := enc.Encode(m); err != nil {
|
||||
logrus.Warnf("Failed to json encode error %v", err)
|
||||
|
@ -14,9 +14,15 @@ func HistoryImage(w http.ResponseWriter, r *http.Request) {
|
||||
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
|
||||
name := utils.GetName(r)
|
||||
|
||||
newImage, _, err := runtime.LibimageRuntime().LookupImage(name, nil)
|
||||
possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, name)
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusNotFound, errors.Wrapf(err, "failed to find image %s", name))
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error normalizing image"))
|
||||
return
|
||||
}
|
||||
|
||||
newImage, _, err := runtime.LibimageRuntime().LookupImage(possiblyNormalizedName, nil)
|
||||
if err != nil {
|
||||
utils.ImageNotFound(w, possiblyNormalizedName, errors.Wrapf(err, "failed to find image %s", possiblyNormalizedName))
|
||||
return
|
||||
}
|
||||
history, err := newImage.History(r.Context())
|
||||
|
@ -61,12 +61,24 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
|
||||
if query.Tag != "" {
|
||||
imageName += ":" + query.Tag
|
||||
}
|
||||
|
||||
if _, err := utils.ParseStorageReference(imageName); err != nil {
|
||||
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
|
||||
errors.Wrapf(err, "image source %q is not a containers-storage-transport reference", imageName))
|
||||
return
|
||||
}
|
||||
|
||||
possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, imageName)
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error normalizing image"))
|
||||
return
|
||||
}
|
||||
imageName = possiblyNormalizedName
|
||||
if _, _, err := runtime.LibimageRuntime().LookupImage(possiblyNormalizedName, nil); err != nil {
|
||||
utils.ImageNotFound(w, imageName, errors.Wrapf(err, "failed to find image %s", imageName))
|
||||
return
|
||||
}
|
||||
|
||||
authconf, authfile, key, err := auth.GetCredentials(r)
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse %q header for %s", key, r.URL.String()))
|
||||
|
@ -34,12 +34,18 @@ func RemoveImage(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
name := utils.GetName(r)
|
||||
possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, name)
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error normalizing image"))
|
||||
return
|
||||
}
|
||||
|
||||
imageEngine := abi.ImageEngine{Libpod: runtime}
|
||||
|
||||
options := entities.ImageRemoveOptions{
|
||||
Force: query.Force,
|
||||
}
|
||||
report, rmerrors := imageEngine.Remove(r.Context(), []string{name}, options)
|
||||
report, rmerrors := imageEngine.Remove(r.Context(), []string{possiblyNormalizedName}, options)
|
||||
if len(rmerrors) > 0 && rmerrors[0] != nil {
|
||||
err := rmerrors[0]
|
||||
if errors.Cause(err) == storage.ErrImageUnknown {
|
||||
|
@ -14,12 +14,16 @@ import (
|
||||
func TagImage(w http.ResponseWriter, r *http.Request) {
|
||||
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
|
||||
|
||||
// /v1.xx/images/(name)/tag
|
||||
name := utils.GetName(r)
|
||||
possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, name)
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error normalizing image"))
|
||||
return
|
||||
}
|
||||
|
||||
// Allow tagging manifest list instead of resolving instances from manifest
|
||||
lookupOptions := &libimage.LookupImageOptions{ManifestList: true}
|
||||
newImage, _, err := runtime.LibimageRuntime().LookupImage(name, lookupOptions)
|
||||
newImage, _, err := runtime.LibimageRuntime().LookupImage(possiblyNormalizedName, lookupOptions)
|
||||
if err != nil {
|
||||
utils.ImageNotFound(w, name, errors.Wrapf(err, "failed to find image %s", name))
|
||||
return
|
||||
@ -35,7 +39,14 @@ func TagImage(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
repo := r.Form.Get("repo")
|
||||
tagName := fmt.Sprintf("%s:%s", repo, tag)
|
||||
if err := newImage.Tag(tagName); err != nil {
|
||||
|
||||
possiblyNormalizedTag, err := utils.NormalizeToDockerHub(r, tagName)
|
||||
if err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error normalizing image"))
|
||||
return
|
||||
}
|
||||
|
||||
if err := newImage.Tag(possiblyNormalizedTag); err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
@ -3,19 +3,61 @@ package utils
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/common/libimage"
|
||||
"github.com/containers/common/pkg/filters"
|
||||
"github.com/containers/image/v5/docker"
|
||||
"github.com/containers/image/v5/storage"
|
||||
storageTransport "github.com/containers/image/v5/storage"
|
||||
"github.com/containers/image/v5/transports/alltransports"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/podman/v3/libpod"
|
||||
api "github.com/containers/podman/v3/pkg/api/types"
|
||||
"github.com/containers/podman/v3/pkg/util"
|
||||
"github.com/containers/storage"
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/gorilla/schema"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// NormalizeToDockerHub normalizes the specified nameOrID to Docker Hub if the
|
||||
// request is for the compat API and if containers.conf set the specific mode.
|
||||
// If nameOrID is a (short) ID for a local image, the full ID will be returned.
|
||||
func NormalizeToDockerHub(r *http.Request, nameOrID string) (string, error) {
|
||||
if IsLibpodRequest(r) || !util.DefaultContainerConfig().Engine.CompatAPIEnforceDockerHub {
|
||||
return nameOrID, nil
|
||||
}
|
||||
|
||||
// Try to lookup the input to figure out if it was an ID or not.
|
||||
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
|
||||
img, _, err := runtime.LibimageRuntime().LookupImage(nameOrID, nil)
|
||||
if err != nil {
|
||||
if errors.Cause(err) != storage.ErrImageUnknown {
|
||||
return "", fmt.Errorf("normalizing name for compat API: %v", err)
|
||||
}
|
||||
} else if strings.HasPrefix(img.ID(), nameOrID) {
|
||||
return img.ID(), nil
|
||||
}
|
||||
|
||||
// No ID, so we can normalize.
|
||||
named, err := reference.ParseNormalizedNamed(nameOrID)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("normalizing name for compat API: %v", err)
|
||||
}
|
||||
|
||||
return named.String(), nil
|
||||
}
|
||||
|
||||
// PossiblyEnforceDockerHub sets fields in the system context to enforce
|
||||
// resolving short names to Docker Hub if the request is for the compat API and
|
||||
// if containers.conf set the specific mode.
|
||||
func PossiblyEnforceDockerHub(r *http.Request, sys *types.SystemContext) {
|
||||
if IsLibpodRequest(r) || !util.DefaultContainerConfig().Engine.CompatAPIEnforceDockerHub {
|
||||
return
|
||||
}
|
||||
sys.PodmanOnlyShortNamesIgnoreRegistriesConfAndForceDockerHub = true
|
||||
}
|
||||
|
||||
// IsRegistryReference checks if the specified name points to the "docker://"
|
||||
// transport. If it points to no supported transport, we'll assume a
|
||||
// non-transport reference pointing to an image (e.g., "fedora:latest").
|
||||
@ -35,13 +77,13 @@ func IsRegistryReference(name string) error {
|
||||
// `types.ImageReference` and enforces it to refer to a
|
||||
// containers-storage-transport reference.
|
||||
func ParseStorageReference(name string) (types.ImageReference, error) {
|
||||
storagePrefix := fmt.Sprintf("%s:", storage.Transport.Name())
|
||||
storagePrefix := storageTransport.Transport.Name()
|
||||
imageRef, err := alltransports.ParseImageName(name)
|
||||
if err == nil && imageRef.Transport().Name() != docker.Transport.Name() {
|
||||
return nil, errors.Errorf("reference %q must be a storage reference", name)
|
||||
} else if err != nil {
|
||||
origErr := err
|
||||
imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", storagePrefix, name))
|
||||
imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s:%s", storagePrefix, name))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(origErr, "reference %q must be a storage reference", name)
|
||||
}
|
||||
|
Reference in New Issue
Block a user