diff options
author | baude <bbaude@redhat.com> | 2020-10-14 13:53:12 -0500 |
---|---|---|
committer | baude <bbaude@redhat.com> | 2020-10-20 12:06:59 -0500 |
commit | eb91d66c4aa0d2d75a5787ab7013cef88d8c9f4f (patch) | |
tree | 1dc9988ebc7470e05bd80622982ab9a5926d0d5b /pkg/api | |
parent | 35b4cb196545eee3b072083e716ad4588e0bb486 (diff) | |
download | podman-eb91d66c4aa0d2d75a5787ab7013cef88d8c9f4f.tar.gz podman-eb91d66c4aa0d2d75a5787ab7013cef88d8c9f4f.tar.bz2 podman-eb91d66c4aa0d2d75a5787ab7013cef88d8c9f4f.zip |
refactor api compatibility container creation to specgen
when using the compatibility layer to create containers, it used code paths to the pkg/spec which is the old implementation of containers. it is error prone and no longer being maintained. rather that fixing things in spec, migrating to specgen usage seems to make the most sense. furthermore, any fixes to the compat create will not need to be ported later.
Signed-off-by: baude <bbaude@redhat.com>
Diffstat (limited to 'pkg/api')
-rw-r--r-- | pkg/api/handlers/compat/containers_create.go | 237 |
1 files changed, 18 insertions, 219 deletions
diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go index 8a0b3c922..87c95a24c 100644 --- a/pkg/api/handlers/compat/containers_create.go +++ b/pkg/api/handlers/compat/containers_create.go @@ -1,27 +1,19 @@ package compat import ( - "context" "encoding/json" - "fmt" "net/http" - "strings" - "github.com/containers/common/pkg/config" + "github.com/containers/podman/v2/cmd/podman/common" "github.com/containers/podman/v2/libpod" "github.com/containers/podman/v2/libpod/define" - image2 "github.com/containers/podman/v2/libpod/image" "github.com/containers/podman/v2/pkg/api/handlers" "github.com/containers/podman/v2/pkg/api/handlers/utils" - "github.com/containers/podman/v2/pkg/namespaces" - "github.com/containers/podman/v2/pkg/rootless" - "github.com/containers/podman/v2/pkg/signal" - createconfig "github.com/containers/podman/v2/pkg/spec" + "github.com/containers/podman/v2/pkg/domain/entities" + "github.com/containers/podman/v2/pkg/domain/infra/abi" "github.com/containers/podman/v2/pkg/specgen" - "github.com/containers/storage" "github.com/gorilla/schema" "github.com/pkg/errors" - "golang.org/x/sys/unix" ) func CreateContainer(w http.ResponseWriter, r *http.Request) { @@ -56,220 +48,27 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "NewFromLocal()")) return } - containerConfig, err := runtime.GetConfig() + + // Take input structure and convert to cliopts + cliOpts, args, err := common.ContainerCreateToContainerCLIOpts(input) if err != nil { - utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "GetConfig()")) + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "make cli opts()")) return } - cc, err := makeCreateConfig(r.Context(), containerConfig, input, newImage) - if err != nil { - utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "makeCreatConfig()")) + sg := specgen.NewSpecGenerator(newImage.ID(), cliOpts.RootFS) + if err := common.FillOutSpecGen(sg, cliOpts, args); err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "fill out specgen")) return } - cc.Name = query.Name - utils.CreateContainer(r.Context(), w, runtime, &cc) -} - -func makeCreateConfig(ctx context.Context, containerConfig *config.Config, input handlers.CreateContainerConfig, newImage *image2.Image) (createconfig.CreateConfig, error) { - var ( - err error - init bool - ) - env := make(map[string]string) - stopSignal := unix.SIGTERM - if len(input.StopSignal) > 0 { - stopSignal, err = signal.ParseSignal(input.StopSignal) - if err != nil { - return createconfig.CreateConfig{}, err - } - } - - workDir, err := newImage.WorkingDir(ctx) + ic := abi.ContainerEngine{Libpod: runtime} + report, err := ic.ContainerCreate(r.Context(), sg) if err != nil { - return createconfig.CreateConfig{}, err - } - if workDir == "" { - workDir = "/" - } - if len(input.WorkingDir) > 0 { - workDir = input.WorkingDir - } - - // Only use image's Cmd when the user does not set the entrypoint - if input.Entrypoint == nil && len(input.Cmd) == 0 { - cmdSlice, err := newImage.Cmd(ctx) - if err != nil { - return createconfig.CreateConfig{}, err - } - input.Cmd = cmdSlice - } - - if input.Entrypoint == nil { - entrypointSlice, err := newImage.Entrypoint(ctx) - if err != nil { - return createconfig.CreateConfig{}, err - } - input.Entrypoint = entrypointSlice - } - - stopTimeout := containerConfig.Engine.StopTimeout - if input.StopTimeout != nil { - stopTimeout = uint(*input.StopTimeout) - } - c := createconfig.CgroupConfig{ - Cgroups: "", // podman - Cgroupns: "", // podman - CgroupParent: "", // podman - CgroupMode: "", // podman - } - security := createconfig.SecurityConfig{ - CapAdd: input.HostConfig.CapAdd, - CapDrop: input.HostConfig.CapDrop, - LabelOpts: nil, // podman - NoNewPrivs: false, // podman - ApparmorProfile: "", // podman - SeccompProfilePath: "", - SecurityOpts: input.HostConfig.SecurityOpt, - Privileged: input.HostConfig.Privileged, - ReadOnlyRootfs: input.HostConfig.ReadonlyRootfs, - ReadOnlyTmpfs: false, // podman-only - Sysctl: input.HostConfig.Sysctls, - } - - var netmode namespaces.NetworkMode - if rootless.IsRootless() { - netmode = namespaces.NetworkMode(specgen.Slirp) - } - - network := createconfig.NetworkConfig{ - DNSOpt: input.HostConfig.DNSOptions, - DNSSearch: input.HostConfig.DNSSearch, - DNSServers: input.HostConfig.DNS, - ExposedPorts: input.ExposedPorts, - HTTPProxy: false, // podman - IP6Address: "", - IPAddress: "", - LinkLocalIP: nil, // docker-only - MacAddress: input.MacAddress, - NetMode: netmode, - Network: input.HostConfig.NetworkMode.NetworkName(), - NetworkAlias: nil, // docker-only now - PortBindings: input.HostConfig.PortBindings, - Publish: nil, // podmanseccompPath - PublishAll: input.HostConfig.PublishAllPorts, - } - - uts := createconfig.UtsConfig{ - UtsMode: namespaces.UTSMode(input.HostConfig.UTSMode), - NoHosts: false, //podman - HostAdd: input.HostConfig.ExtraHosts, - Hostname: input.Hostname, - } - - z := createconfig.UserConfig{ - GroupAdd: input.HostConfig.GroupAdd, - IDMappings: &storage.IDMappingOptions{}, // podman //TODO <--- fix this, - UsernsMode: namespaces.UsernsMode(input.HostConfig.UsernsMode), - User: input.User, - } - pidConfig := createconfig.PidConfig{PidMode: namespaces.PidMode(input.HostConfig.PidMode)} - // TODO: We should check that these binds are all listed in the `Volumes` - // key since it doesn't make sense to define a `Binds` element for a - // container path which isn't defined as a volume - volumes := input.HostConfig.Binds - - // Docker is more flexible about its input where podman throws - // away incorrectly formatted variables so we cannot reuse the - // parsing of the env input - // [Foo Other=one Blank=] - imgEnv, err := newImage.Env(ctx) - if err != nil { - return createconfig.CreateConfig{}, err - } - input.Env = append(imgEnv, input.Env...) - for _, e := range input.Env { - splitEnv := strings.Split(e, "=") - switch len(splitEnv) { - case 0: - continue - case 1: - env[splitEnv[0]] = "" - default: - env[splitEnv[0]] = strings.Join(splitEnv[1:], "=") - } - } - - // format the tmpfs mounts into a []string from map - tmpfs := make([]string, 0, len(input.HostConfig.Tmpfs)) - for k, v := range input.HostConfig.Tmpfs { - tmpfs = append(tmpfs, fmt.Sprintf("%s:%s", k, v)) - } - - if input.HostConfig.Init != nil && *input.HostConfig.Init { - init = true - } - - m := createconfig.CreateConfig{ - Annotations: nil, // podman - Args: nil, - Cgroup: c, - CidFile: "", - ConmonPidFile: "", // podman - Command: input.Cmd, - UserCommand: input.Cmd, // podman - Detach: false, // - // Devices: input.HostConfig.Devices, - Entrypoint: input.Entrypoint, - Env: env, - HealthCheck: nil, // - Init: init, - InitPath: "", // tbd - Image: input.Image, - ImageID: newImage.ID(), - BuiltinImgVolumes: nil, // podman - ImageVolumeType: "", // podman - Interactive: input.OpenStdin, - // IpcMode: input.HostConfig.IpcMode, - Labels: input.Labels, - LogDriver: input.HostConfig.LogConfig.Type, // is this correct - // LogDriverOpt: input.HostConfig.LogConfig.Config, - Name: input.Name, - Network: network, - Pod: "", // podman - PodmanPath: "", // podman - Quiet: false, // front-end only - Resources: createconfig.CreateResourceConfig{MemorySwappiness: -1}, - RestartPolicy: input.HostConfig.RestartPolicy.Name, - Rm: input.HostConfig.AutoRemove, - StopSignal: stopSignal, - StopTimeout: stopTimeout, - Systemd: false, // podman - Tmpfs: tmpfs, - User: z, - Uts: uts, - Tty: input.Tty, - Mounts: nil, // we populate - // MountsFlag: input.HostConfig.Mounts, - NamedVolumes: nil, // we populate - Volumes: volumes, - VolumesFrom: input.HostConfig.VolumesFrom, - WorkDir: workDir, - Rootfs: "", // podman - Security: security, - Syslog: false, // podman - - Pid: pidConfig, + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "container create")) + return } - - fullCmd := append(input.Entrypoint, input.Cmd...) - if len(fullCmd) > 0 { - m.PodmanPath = fullCmd[0] - if len(fullCmd) == 1 { - m.Args = fullCmd - } else { - m.Args = fullCmd[1:] - } + createResponse := entities.ContainerCreateResponse{ + ID: report.Id, + Warnings: []string{}, } - - return m, nil + utils.WriteResponse(w, http.StatusCreated, createResponse) } |