mirror of
https://github.com/containers/podman.git
synced 2025-06-03 12:17:13 +08:00
InfraContainer Rework
InfraContainer should go through the same creation process as regular containers. This change was from the cmd level down, involving new container CLI opts and specgen creating functions. What now happens is that both container and pod cli options are populated in cmd and used to create a podSpecgen and a containerSpecgen. The process then goes as follows FillOutSpecGen (infra) -> MapSpec (podOpts -> infraOpts) -> PodCreate -> MakePod -> createPodOptions -> NewPod -> CompleteSpec (infra) -> MakeContainer -> NewContainer -> newContainer -> AddInfra (to pod state) Signed-off-by: cdoern <cdoern@redhat.com>
This commit is contained in:
@ -11,6 +11,7 @@ import (
|
||||
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||
"github.com/containers/podman/v3/pkg/domain/infra/abi"
|
||||
"github.com/containers/podman/v3/pkg/specgen"
|
||||
"github.com/containers/podman/v3/pkg/specgenutil"
|
||||
"github.com/containers/storage"
|
||||
"github.com/gorilla/schema"
|
||||
"github.com/pkg/errors"
|
||||
@ -80,7 +81,7 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
sg := specgen.NewSpecGenerator(imgNameOrID, cliOpts.RootFS)
|
||||
if err := common.FillOutSpecGen(sg, cliOpts, args); err != nil {
|
||||
if err := specgenutil.FillOutSpecGen(sg, cliOpts, args); err != nil {
|
||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "fill out specgen"))
|
||||
return
|
||||
}
|
||||
|
@ -28,7 +28,12 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
|
||||
utils.InternalServerError(w, err)
|
||||
return
|
||||
}
|
||||
ctr, err := generate.MakeContainer(context.Background(), runtime, &sg)
|
||||
rtSpec, spec, opts, err := generate.MakeContainer(context.Background(), runtime, &sg)
|
||||
if err != nil {
|
||||
utils.InternalServerError(w, err)
|
||||
return
|
||||
}
|
||||
ctr, err := generate.ExecuteCreate(context.Background(), runtime, rtSpec, spec, false, opts...)
|
||||
if err != nil {
|
||||
utils.InternalServerError(w, err)
|
||||
return
|
||||
|
@ -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()})
|
||||
|
@ -1,8 +1,6 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||
)
|
||||
import "github.com/containers/podman/v3/pkg/domain/entities"
|
||||
|
||||
// LibpodImagesRemoveReport is the return type for image removal via the rest
|
||||
// api.
|
||||
|
Reference in New Issue
Block a user