github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/pkg/api/handlers/compat/images_push.go (about) 1 package compat 2 3 import ( 4 "context" 5 "net/http" 6 "os" 7 "strings" 8 9 "github.com/containers/podman/v2/libpod" 10 "github.com/containers/podman/v2/libpod/image" 11 "github.com/containers/podman/v2/pkg/api/handlers/utils" 12 "github.com/containers/podman/v2/pkg/auth" 13 "github.com/gorilla/schema" 14 "github.com/pkg/errors" 15 ) 16 17 // PushImage is the handler for the compat http endpoint for pushing images. 18 func PushImage(w http.ResponseWriter, r *http.Request) { 19 decoder := r.Context().Value("decoder").(*schema.Decoder) 20 runtime := r.Context().Value("runtime").(*libpod.Runtime) 21 22 query := struct { 23 Tag string `schema:"tag"` 24 }{ 25 // This is where you can override the golang default value for one of fields 26 } 27 28 if err := decoder.Decode(&query, r.URL.Query()); err != nil { 29 utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) 30 return 31 } 32 33 // Note that Docker's docs state "Image name or ID" to be in the path 34 // parameter but it really must be a name as Docker does not allow for 35 // pushing an image by ID. 36 imageName := strings.TrimSuffix(utils.GetName(r), "/push") // GetName returns the entire path 37 if query.Tag != "" { 38 imageName += ":" + query.Tag 39 } 40 if _, err := utils.ParseStorageReference(imageName); err != nil { 41 utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, 42 errors.Wrapf(err, "image source %q is not a containers-storage-transport reference", imageName)) 43 return 44 } 45 46 newImage, err := runtime.ImageRuntime().NewFromLocal(imageName) 47 if err != nil { 48 utils.ImageNotFound(w, imageName, errors.Wrapf(err, "failed to find image %s", imageName)) 49 return 50 } 51 52 authConf, authfile, key, err := auth.GetCredentials(r) 53 if err != nil { 54 utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse %q header for %s", key, r.URL.String())) 55 return 56 } 57 defer auth.RemoveAuthfile(authfile) 58 59 dockerRegistryOptions := &image.DockerRegistryOptions{DockerRegistryCreds: authConf} 60 if sys := runtime.SystemContext(); sys != nil { 61 dockerRegistryOptions.DockerCertPath = sys.DockerCertPath 62 dockerRegistryOptions.RegistriesConfPath = sys.SystemRegistriesConfPath 63 } 64 65 err = newImage.PushImageToHeuristicDestination( 66 context.Background(), 67 imageName, 68 "", // manifest type 69 authfile, 70 "", // digest file 71 "", // signature policy 72 os.Stderr, 73 false, // force compression 74 image.SigningOptions{}, 75 dockerRegistryOptions, 76 nil, // additional tags 77 ) 78 if err != nil { 79 utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "error pushing image %q", imageName)) 80 return 81 } 82 83 utils.WriteResponse(w, http.StatusOK, "") 84 85 }