github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/pkg/api/handlers/compat/containers_create.go (about) 1 package compat 2 3 import ( 4 "encoding/json" 5 "net/http" 6 7 "github.com/containers/podman/v2/cmd/podman/common" 8 "github.com/containers/podman/v2/libpod" 9 "github.com/containers/podman/v2/libpod/define" 10 "github.com/containers/podman/v2/pkg/api/handlers" 11 "github.com/containers/podman/v2/pkg/api/handlers/utils" 12 "github.com/containers/podman/v2/pkg/domain/entities" 13 "github.com/containers/podman/v2/pkg/domain/infra/abi" 14 "github.com/containers/podman/v2/pkg/specgen" 15 "github.com/gorilla/schema" 16 "github.com/pkg/errors" 17 ) 18 19 func CreateContainer(w http.ResponseWriter, r *http.Request) { 20 runtime := r.Context().Value("runtime").(*libpod.Runtime) 21 decoder := r.Context().Value("decoder").(*schema.Decoder) 22 query := struct { 23 Name string `schema:"name"` 24 }{ 25 // override any golang type defaults 26 } 27 if err := decoder.Decode(&query, r.URL.Query()); err != nil { 28 utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, 29 errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) 30 return 31 } 32 33 // compatible configuration 34 body := handlers.CreateContainerConfig{} 35 if err := json.NewDecoder(r.Body).Decode(&body); err != nil { 36 utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()")) 37 return 38 } 39 40 // Override the container name in the body struct 41 body.Name = query.Name 42 43 if len(body.HostConfig.Links) > 0 { 44 utils.Error(w, utils.ErrLinkNotSupport.Error(), http.StatusBadRequest, errors.Wrapf(utils.ErrLinkNotSupport, "bad parameter")) 45 return 46 } 47 rtc, err := runtime.GetConfig() 48 if err != nil { 49 utils.Error(w, "unable to obtain runtime config", http.StatusInternalServerError, errors.Wrap(err, "unable to get runtime config")) 50 } 51 52 newImage, err := runtime.ImageRuntime().NewFromLocal(body.Config.Image) 53 if err != nil { 54 if errors.Cause(err) == define.ErrNoSuchImage { 55 utils.Error(w, "No such image", http.StatusNotFound, err) 56 return 57 } 58 59 utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "NewFromLocal()")) 60 return 61 } 62 63 // Take body structure and convert to cliopts 64 cliOpts, args, err := common.ContainerCreateToContainerCLIOpts(body, rtc.Engine.CgroupManager) 65 if err != nil { 66 utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "make cli opts()")) 67 return 68 } 69 sg := specgen.NewSpecGenerator(newImage.ID(), cliOpts.RootFS) 70 if err := common.FillOutSpecGen(sg, cliOpts, args); err != nil { 71 utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "fill out specgen")) 72 return 73 } 74 75 ic := abi.ContainerEngine{Libpod: runtime} 76 report, err := ic.ContainerCreate(r.Context(), sg) 77 if err != nil { 78 utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "container create")) 79 return 80 } 81 createResponse := entities.ContainerCreateResponse{ 82 ID: report.Id, 83 Warnings: []string{}, 84 } 85 utils.WriteResponse(w, http.StatusCreated, createResponse) 86 }