summaryrefslogtreecommitdiff
path: root/pkg/api/handlers
diff options
context:
space:
mode:
authorcdoern <cdoern@redhat.com>2021-07-14 16:30:28 -0400
committercdoern <cdoern@redhat.com>2021-08-26 16:05:16 -0400
commitd28e85741fedb89be48a03d4f05687e970eb71b9 (patch)
tree0b79a6757b0fc7ad3caa33ad94f721d8296d9c1a /pkg/api/handlers
parent94c37d7d470871f9d63b32c97094f5faab1e8a08 (diff)
downloadpodman-d28e85741fedb89be48a03d4f05687e970eb71b9.tar.gz
podman-d28e85741fedb89be48a03d4f05687e970eb71b9.tar.bz2
podman-d28e85741fedb89be48a03d4f05687e970eb71b9.zip
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>
Diffstat (limited to 'pkg/api/handlers')
-rw-r--r--pkg/api/handlers/compat/containers_create.go3
-rw-r--r--pkg/api/handlers/libpod/containers_create.go7
-rw-r--r--pkg/api/handlers/libpod/pods.go65
-rw-r--r--pkg/api/handlers/types/types.go4
4 files changed, 67 insertions, 12 deletions
diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go
index 0b5cbd343..9df35697a 100644
--- a/pkg/api/handlers/compat/containers_create.go
+++ b/pkg/api/handlers/compat/containers_create.go
@@ -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
}
diff --git a/pkg/api/handlers/libpod/containers_create.go b/pkg/api/handlers/libpod/containers_create.go
index 65951861b..0e2163d5c 100644
--- a/pkg/api/handlers/libpod/containers_create.go
+++ b/pkg/api/handlers/libpod/containers_create.go
@@ -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
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()})
diff --git a/pkg/api/handlers/types/types.go b/pkg/api/handlers/types/types.go
index 71165364f..e7920047e 100644
--- a/pkg/api/handlers/types/types.go
+++ b/pkg/api/handlers/types/types.go
@@ -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.