diff options
Diffstat (limited to 'pkg/api/handlers/libpod/pods.go')
-rw-r--r-- | pkg/api/handlers/libpod/pods.go | 65 |
1 files changed, 58 insertions, 7 deletions
diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go index ff105bc48..3d6cf093b 100644 --- a/pkg/api/handlers/libpod/pods.go +++ b/pkg/api/handlers/libpod/pods.go @@ -1,11 +1,15 @@ package libpod import ( + "context" "encoding/json" "fmt" "net/http" "strings" + "github.com/containers/common/libimage" + "github.com/containers/common/pkg/config" + "github.com/containers/image/v5/transports/alltransports" "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/pkg/api/handlers" @@ -14,6 +18,7 @@ import ( "github.com/containers/podman/v3/pkg/domain/infra/abi" "github.com/containers/podman/v3/pkg/specgen" "github.com/containers/podman/v3/pkg/specgen/generate" + "github.com/containers/podman/v3/pkg/specgenutil" "github.com/containers/podman/v3/pkg/util" "github.com/gorilla/schema" "github.com/pkg/errors" @@ -25,24 +30,70 @@ func PodCreate(w http.ResponseWriter, r *http.Request) { runtime = r.Context().Value("runtime").(*libpod.Runtime) err error ) - var psg specgen.PodSpecGenerator + psg := specgen.PodSpecGenerator{InfraContainerSpec: &specgen.SpecGenerator{}} if err := json.NewDecoder(r.Body).Decode(&psg); err != nil { - utils.Error(w, "failed to decode specgen", http.StatusInternalServerError, errors.Wrap(err, "failed to decode specgen")) + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to decode specgen")) return } - // parse userns so we get the valid default value of userns - psg.Userns, err = specgen.ParseUserNamespace(psg.Userns.String()) if err != nil { - utils.Error(w, "failed to parse userns", http.StatusInternalServerError, errors.Wrap(err, "failed to parse userns")) + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to decode specgen")) return } - pod, err := generate.MakePod(&psg, runtime) + if !psg.NoInfra { + infraOptions := &entities.ContainerCreateOptions{ImageVolume: "bind", IsInfra: true, Net: &entities.NetOptions{}} // options for pulling the image and FillOutSpec + err = specgenutil.FillOutSpecGen(psg.InfraContainerSpec, infraOptions, []string{}) // necessary for default values in many cases (userns, idmappings) + if err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error filling out specgen")) + return + } + out, err := json.Marshal(psg) // marshal our spec so the matching options can be unmarshaled into infra + if err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to decode specgen")) + return + } + tempSpec := &specgen.SpecGenerator{} // temporary spec since infra cannot be decoded into + err = json.Unmarshal(out, tempSpec) // unmarhal matching options + if err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to decode specgen")) + return + } + psg.InfraContainerSpec = tempSpec // set infra spec equal to temp + // a few extra that do not have the same json tags + psg.InfraContainerSpec.Name = psg.InfraName + psg.InfraContainerSpec.ConmonPidFile = psg.InfraConmonPidFile + psg.InfraContainerSpec.ContainerCreateCommand = psg.InfraCommand + imageName := psg.InfraImage + rawImageName := psg.InfraImage + if imageName == "" { + imageName = config.DefaultInfraImage + rawImageName = config.DefaultInfraImage + } + curr := infraOptions.Quiet + infraOptions.Quiet = true + pullOptions := &libimage.PullOptions{} + pulledImages, err := runtime.LibimageRuntime().Pull(context.Background(), imageName, config.PullPolicyMissing, pullOptions) + if err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "could not pull image")) + return + } + if _, err := alltransports.ParseImageName(imageName); err == nil { + if len(pulledImages) != 0 { + imageName = pulledImages[0].ID() + } + } + infraOptions.Quiet = curr + psg.InfraImage = imageName + psg.InfraContainerSpec.Image = imageName + psg.InfraContainerSpec.RawImageName = rawImageName + } + podSpecComplete := entities.PodSpec{PodSpecGen: psg} + pod, err := generate.MakePod(&podSpecComplete, runtime) if err != nil { httpCode := http.StatusInternalServerError if errors.Cause(err) == define.ErrPodExists { httpCode = http.StatusConflict } - utils.Error(w, "Something went wrong.", httpCode, err) + utils.Error(w, "Something went wrong.", httpCode, errors.Wrap(err, "failed to make pod")) return } utils.WriteResponse(w, http.StatusCreated, handlers.IDResponse{ID: pod.ID()}) |