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  }